E: Add start of new RandR dialog.

NB: IT IS NOT COMPLETE, DOES NOT APPLY SETTINGS, AND STILL NEEDS LOTS
OF WORK. Don't bother reporting bugs for it just yet, until it is
fully functional. Just adding it to svn in the hopes (hahahaha) that
others may want to jump in and help speed things along.



SVN revision: 77140
This commit is contained in:
Christopher Michael 2012-09-27 09:22:05 +00:00
parent ed7d617e66
commit 28eac48e9c
15 changed files with 1364 additions and 2455 deletions

View File

@ -22,12 +22,12 @@ pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH
pkg_LTLIBRARIES = module.la
module_la_SOURCES = e_mod_main.c \
e_mod_main.h \
e_int_config_randr_orientation.c \
e_int_config_randr_resolution.c \
e_int_config_randr_arrangement.c \
e_int_config_randr_policy.c \
e_int_config_randr.h \
e_int_config_randr.c \
e_int_config_randr.h
e_smart_randr.h \
e_smart_randr.c \
e_smart_monitor.h \
e_smart_monitor.c
module_la_LIBADD = @e_libs@ @dlopen_libs@
module_la_LDFLAGS = -module -avoid-version

View File

@ -1,441 +1,172 @@
#include "e.h"
#include "e_randr.h"
#include "e_mod_main.h"
#include "e_int_config_randr.h"
#include "e_smart_randr.h"
#include "e_smart_monitor.h"
/*
* BUGS:
* - ethumb sometimes returns garbage objects leading to a segv
*
* TODO:
* - write 1.2 per monitor configuration
* - write Smart object, so crtcs representations can be properly freed (events,
* etc.)
*
* IMPROVABLE:
* See comments starting with 'IMPROVABLE'
*/
#ifndef ECORE_X_RANDR_1_2
#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
#endif
#ifndef ECORE_X_RANDR_1_3
#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
#endif
#ifdef Ecore_X_Randr_None
#undef Ecore_X_Randr_None
#define Ecore_X_Randr_None 0
#else
#define Ecore_X_Randr_None 0
#endif
#ifdef Ecore_X_Randr_Unset
#undef Ecore_X_Randr_Unset
#define Ecore_X_Randr_Unset -1
#else
#define Ecore_X_Randr_Unset -1
#endif
#define THEME_FILENAME "/e-module-conf_randr.edj"
#define TOOLBAR_ICONSIZE 16
#define E_RANDR_12 (e_randr_screen_info.rrvd_info.randr_info_12)
static void *create_data(E_Config_Dialog *cfd);
static void free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static int basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static int basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static Evas_Object *basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
static Eina_Bool _deferred_noxrandr_error(void *data);
static void _e_conf_randr_confirmation_dialog_discard_cb(void *data, E_Dialog *dia);
/* actual module specifics */
E_Config_Dialog_Data *e_config_runtime_info = NULL;
extern E_Module *conf_randr_module;
char _theme_file_path[PATH_MAX];
E_Config_Randr_Dialog_Output_Dialog_Data *
_dialog_output_dialog_data_new(E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info)
/* local structures */
typedef struct _Randr_Info Randr_Info;
struct _Randr_Info
{
E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
E_Win *win;
Evas_Object *o_bg;
Evas_Object *o_scroll;
};
EINA_SAFETY_ON_NULL_RETURN_VAL(output_info, NULL);
/* local function prototypes */
static Randr_Info *_randr_info_new(E_Container *con);
static void _randr_info_free(void);
static void _win_cb_resize(E_Win *win);
static void _win_cb_delete(E_Win *win __UNUSED__);
static void _close_cb_click(void *data __UNUSED__, void *data2 __UNUSED__);
dialog_data = E_NEW(E_Config_Randr_Dialog_Output_Dialog_Data, 1);
fprintf(stderr, "CONF_RANDR: Added output data struct for Output %d/CRTC %d.\n", output_info->xid, (output_info->crtc ? output_info->crtc->xid : Ecore_X_Randr_None));
if (crtc_info)
{
//already enabled screen, output info is already available in crtc
//struct
dialog_data->crtc = crtc_info;
}
else
{
//disabled monitor
dialog_data->output = output_info;
}
return dialog_data;
}
static void *
create_data(E_Config_Dialog *cfd)
{
Eina_List *iter;
E_Randr_Output_Info *output_info;
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
// Prove we got all things to get going
EINA_SAFETY_ON_TRUE_RETURN_VAL(!E_RANDR_12, NULL);
//e_randr_screen_info_refresh();
e_config_runtime_info = E_NEW(E_Config_Dialog_Data, 1);
e_config_runtime_info->cfd = cfd;
//Compose theme's file path and name
snprintf(_theme_file_path, sizeof(_theme_file_path), "%s%s", conf_randr_module->dir, THEME_FILENAME);
e_config_runtime_info->manager = e_manager_current_get();
e_config_runtime_info->output_dialog_data_list = NULL;
EINA_LIST_FOREACH(e_randr_screen_info.rrvd_info.randr_info_12->outputs, iter, output_info)
{
if (!output_info)
{
fprintf(stderr, "CONF_RANDR: WWWWWWWWWWWWOOOOOOOOOOOOOTTTT an output_info of the central struct is NULL!\n");
continue;
}
if ((odd = _dialog_output_dialog_data_new(output_info->crtc, output_info)))
e_config_runtime_info->output_dialog_data_list = eina_list_append(e_config_runtime_info->output_dialog_data_list, odd);
}
//FIXME: Properly (stack-like) free data when creation fails
EINA_SAFETY_ON_FALSE_GOTO(resolution_widget_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
EINA_SAFETY_ON_FALSE_GOTO(arrangement_widget_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
EINA_SAFETY_ON_FALSE_GOTO(policy_widget_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
EINA_SAFETY_ON_FALSE_GOTO(orientation_widget_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
return e_config_runtime_info;
_e_conf_randr_create_data_failed_free_data:
free(e_config_runtime_info);
return NULL;
}
static void
free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
EINA_SAFETY_ON_TRUE_RETURN(!E_RANDR_12);
arrangement_widget_free_cfdata(cfd, cfdata);
policy_widget_free_cfdata(cfd, cfdata);
resolution_widget_free_cfdata(cfd, cfdata);
orientation_widget_free_cfdata(cfd, cfdata);
/*
evas_object_del(cfdata->gui.widgets.arrangement.widget);
evas_object_del(cfdata->gui.widgets.policy.widget);
evas_object_del(cfdata->gui.widgets.resolution.widget);
evas_object_del(cfdata->gui.widgets.orientation.widget);
*/
EINA_LIST_FREE(cfdata->output_dialog_data_list, dialog_data)
{
free(dialog_data);
}
cfdata->output_dialog_data_list = NULL;
free(cfdata);
}
static Eina_Bool
_e_conf_randr_confirmation_dialog_timer_cb(void *data)
{
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data *)data;
char buf[4096];
if (!cdd) return ECORE_CALLBACK_CANCEL;
--cdd->countdown;
if (cdd->countdown > 0)
{
snprintf(buf, sizeof(buf),
_("Does this look OK? Click <hilight>Keep</hilight> if it does, or Restore if not.<ps>"
"If you do not press a button, the previous settings will be<ps>"
"restored in %d seconds."), cdd->countdown);
}
else
{
snprintf(buf, sizeof(buf),
_("Does this look OK? Click <hilight>Keep</hilight> if it does, or Restore if not.<ps>"
"If you do not press a button, the previous settings will be<ps>"
"restored <highlight>IMMEDIATELY</highlight>."));
}
e_dialog_text_set(cdd->dialog, buf);
if (cdd->countdown == 0)
{
_e_conf_randr_confirmation_dialog_discard_cb(cdd, cdd->dialog);
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_RENEW;
}
static void
_e_conf_randr_confirmation_dialog_delete_cb(E_Win *win)
{
E_Dialog *dia;
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd;
E_Config_Dialog *cfd;
dia = win->data;
cd = dia->data;
cd->cfdata->gui.confirmation_dialog = NULL;
cfd = cd->cfdata->cfd;
if (cd->timer) ecore_timer_del(cd->timer);
cd->timer = NULL;
free(cd);
e_object_del(E_OBJECT(dia));
e_object_unref(E_OBJECT(cfd));
}
static void
_e_conf_randr_confirmation_dialog_keep_cb(void *data, E_Dialog *dia)
{
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data *)data;
if (!cdd) return;
//ordinary "keep" functionality
arrangement_widget_keep_changes(cdd->cfdata);
orientation_widget_keep_changes(cdd->cfdata);
policy_widget_keep_changes(cdd->cfdata);
resolution_widget_keep_changes(cdd->cfdata);
//cleanup dialog
_e_conf_randr_confirmation_dialog_delete_cb(dia->win);
}
static void
_e_conf_randr_confirmation_dialog_discard_cb(void *data, E_Dialog *dia)
{
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data *)data;
if (!cdd) return;
arrangement_widget_discard_changes(cdd->cfdata);
orientation_widget_discard_changes(cdd->cfdata);
policy_widget_discard_changes(cdd->cfdata);
resolution_widget_discard_changes(cdd->cfdata);
_e_conf_randr_confirmation_dialog_delete_cb(dia->win);
}
static void
_e_conf_randr_confirmation_dialog_store_cb(void *data, E_Dialog *dia)
{
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data *)data;
E_Randr_Configuration_Store_Modifier modifier = 0;
if (!cdd) return;
//Create modifier
if (policy_widget_basic_check_changed(NULL, e_config_runtime_info))
modifier |= E_RANDR_CONFIGURATION_STORE_POLICIES;
if (resolution_widget_basic_check_changed(NULL, e_config_runtime_info))
modifier |= E_RANDR_CONFIGURATION_STORE_RESOLUTIONS;
if (arrangement_widget_basic_check_changed(NULL, e_config_runtime_info))
modifier |= E_RANDR_CONFIGURATION_STORE_ARRANGEMENT;
if (orientation_widget_basic_check_changed(NULL, e_config_runtime_info))
modifier |= E_RANDR_CONFIGURATION_STORE_ORIENTATIONS;
_e_conf_randr_confirmation_dialog_keep_cb(data, dia);
//but actually trigger saving the stuff
e_randr_store_configuration(modifier);
}
static void
_e_conf_randr_confirmation_dialog_new(E_Config_Dialog *cfd)
{
E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd = E_NEW(E_Config_Randr_Dialog_Confirmation_Dialog_Data, 1);
char buf[4096];
if (!cd) return;
cd->cfd = cfd;
if ((cd->dialog = e_dialog_new(cfd->con, "E", "e_randr_confirmation_dialog")))
{
e_dialog_title_set(cd->dialog, _("New settings confirmation"));
cd->cfdata = cfd->cfdata;
cd->timer = ecore_timer_add(1.0, _e_conf_randr_confirmation_dialog_timer_cb, cd);
cd->countdown = 15;
cd->dialog->data = cd;
e_dialog_icon_set(cd->dialog, "preferences-system-screen-resolution", 48);
e_win_delete_callback_set(cd->dialog->win, _e_conf_randr_confirmation_dialog_delete_cb);
snprintf(buf, sizeof(buf),
_("Does this look OK? Click <hilight>Keep</hilight> if it does, or Restore if not.<ps>"
"If you do not press a button, the previous settings will be<ps>"
"restored in %d seconds."), cd->countdown);
e_dialog_text_set(cd->dialog, buf);
e_dialog_button_add(cd->dialog, _("Keep"), NULL, _e_conf_randr_confirmation_dialog_keep_cb, cd);
e_dialog_button_add(cd->dialog, _("Store Permanently"), NULL, _e_conf_randr_confirmation_dialog_store_cb, cd);
e_dialog_button_add(cd->dialog, _("Restore"), NULL, _e_conf_randr_confirmation_dialog_discard_cb, cd);
e_dialog_button_focus_num(cd->dialog, 1);
e_win_centered_set(cd->dialog->win, 1);
e_win_borderless_set(cd->dialog->win, 1);
e_win_layer_set(cd->dialog->win, 6);
e_win_sticky_set(cd->dialog->win, 1);
e_dialog_show(cd->dialog);
e_object_ref(E_OBJECT(cfd));
}
}
static Evas_Object *
basic_create_widgets(E_Config_Dialog *cfd, Evas *canvas, E_Config_Dialog_Data *cfdata)
{
Evas_Object *table = NULL, *wl = NULL;
EINA_SAFETY_ON_TRUE_RETURN_VAL (!E_RANDR_12 || (e_randr_screen_info.randr_version < ECORE_X_RANDR_1_2), NULL);
EINA_SAFETY_ON_TRUE_RETURN_VAL((!canvas || !cfdata), NULL);
e_config_runtime_info->gui.canvas = canvas;
if (!(cfdata->gui.widgets.arrangement.widget = arrangement_widget_basic_create_widgets(canvas))) goto _dialog_create_widget_arrangement_fail;
if (!(cfdata->gui.widgets.policy.widget = policy_widget_basic_create_widgets(canvas))) goto _dialog_create_widget_policies_fail;
if (!(cfdata->gui.widgets.resolution.widget = resolution_widget_basic_create_widgets(canvas))) goto _dialog_create_widget_resolutions_fail;
if (!(cfdata->gui.widgets.orientation.widget = orientation_widget_basic_create_widgets(canvas))) goto _dialog_create_widget_orientation_fail;
EINA_SAFETY_ON_FALSE_GOTO((table = e_widget_table_add(canvas, EINA_FALSE)), _dialog_create_widgets_fail);
EINA_SAFETY_ON_FALSE_GOTO((wl = e_widget_list_add(canvas, EINA_FALSE, EINA_TRUE)), _dialog_create_widget_list_fail);
//e_widget_table_object_append(Evas_Object *obj, Evas_Object *sobj, int col, int row, int colspan, int rowspan, int fill_w, int fill_h, int expand_w, int expand_h);
e_widget_table_object_append(table, cfdata->gui.widgets.arrangement.widget, 1, 1, 1, 1, 1, 1, 1, 1);
/*
e_widget_table_object_append(table, cfdata->gui.widgets.policy.widget, 1, 2, 1, 1, 0, 0, 0, 0);
e_widget_table_object_append(table, cfdata->gui.widgets.orientation.widget, 2, 2, 1, 1, 0, 0, 0, 0);
e_widget_table_object_append(table, cfdata->gui.widgets.resolution.widget, 3, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
*/
//e_widget_list_object_append(Evas_Object *obj, Evas_Object *sobj, int fill, int expand, double align);
e_widget_list_object_append(wl, cfdata->gui.widgets.policy.widget, 0, 0, 0.0);
e_widget_list_object_append(wl, cfdata->gui.widgets.orientation.widget, 0, 0, 0.0);
e_widget_list_object_append(wl, cfdata->gui.widgets.resolution.widget, EVAS_HINT_FILL, EVAS_HINT_EXPAND, 1.0);
e_widget_table_object_append(table, wl, 1, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
cfdata->gui.widget_list = wl;
cfdata->gui.dialog = table;
e_dialog_resizable_set(cfd->dia, EINA_TRUE);
return cfdata->gui.dialog;
_dialog_create_widget_list_fail:
evas_object_del(table);
_dialog_create_widgets_fail:
evas_object_del(cfdata->gui.widgets.orientation.widget);
_dialog_create_widget_orientation_fail:
evas_object_del(cfdata->gui.widgets.resolution.widget);
_dialog_create_widget_resolutions_fail:
evas_object_del(cfdata->gui.widgets.policy.widget);
_dialog_create_widget_policies_fail:
evas_object_del(cfdata->gui.widgets.arrangement.widget);
_dialog_create_widget_arrangement_fail:
return NULL;
}
static int
basic_apply_data
(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
{
Eina_Bool ret = EINA_TRUE;
fprintf(stderr, "CONF_RANDR: New configuration is beeing applied.\n");
//this is a special case, where the function is called, before the
//configuration data is created.
if (!cfdata) return EINA_FALSE;
//the order matters except for policies!
if (policy_widget_basic_check_changed(cfd, cfdata))
{
ret &= policy_widget_basic_apply_data(cfd, cfdata);
if (!ret) return EINA_FALSE;
}
if (resolution_widget_basic_check_changed(cfd, cfdata))
{
ret &= resolution_widget_basic_apply_data(cfd, cfdata);
if (!ret) return EINA_FALSE;
}
if (arrangement_widget_basic_check_changed(cfd, cfdata))
{
ret &= arrangement_widget_basic_apply_data(cfd, cfdata);
if (!ret) return EINA_FALSE;
}
if (orientation_widget_basic_check_changed(cfd, cfdata))
ret &= orientation_widget_basic_apply_data(cfd, cfdata);
_e_conf_randr_confirmation_dialog_new(cfd);
return ret;
}
/* local variables */
static Randr_Info *_randr_info = NULL;
E_Config_Dialog *
e_int_config_randr(E_Container *con, const char *params __UNUSED__){
E_Config_Dialog *cfd;
E_Config_Dialog_View *v;
e_int_config_randr(E_Container *con, const char *params __UNUSED__)
{
if (e_randr_screen_info.randr_version < ECORE_X_RANDR_1_2)
return NULL;
if (!E_RANDR_12 || (e_randr_screen_info.randr_version < ECORE_X_RANDR_1_2))
if (_randr_info)
{
ecore_timer_add(0.5, _deferred_noxrandr_error, NULL);
fprintf(stderr, "CONF_RANDR: XRandR version >= 1.2 necessary to work.\n");
/* already have an existing window, show it */
e_win_show(_randr_info->win);
e_win_raise(_randr_info->win);
return NULL;
}
//Dialog already opened?
if (e_config_dialog_find("E", "screen/screen_setup")) return NULL;
/* create new window */
_randr_info = _randr_info_new(con);
v = E_NEW(E_Config_Dialog_View, 1);
v->create_cfdata = create_data;
v->free_cfdata = free_cfdata;
v->basic.apply_cfdata = basic_apply_data;
v->basic.create_widgets = basic_create_widgets;
v->basic.check_changed = basic_check_changed;
//v->override_auto_apply = 0;
cfd = e_config_dialog_new(con, _("Screen Setup"),
"E", "screen/screen_setup",
"preferences-system-screen-setup", 0, v, NULL);
return cfd;
return NULL;
}
static Eina_Bool
_deferred_noxrandr_error(void *data __UNUSED__)
/* local functions */
static Randr_Info *
_randr_info_new(E_Container *con)
{
e_util_dialog_show(_("Missing Features"),
_("Your X Display Server is missing support for<ps>"
"the <hilight>XRandR</hilight> (X Resize and Rotate) extension version 1.2 or above.<ps>"
"You cannot change screen resolutions without<ps>"
"the support of this extension. It could also be<ps>"
"that at the time <hilight>ecore</hilight> was built, there<ps>"
"was no XRandR support detected."));
return ECORE_CALLBACK_CANCEL;
Eina_List *l;
E_Randr_Crtc_Info *crtc;
Randr_Info *info = NULL;
Evas *evas;
Evas_Object *ob;
int mw = 0, mh = 0;
if (!(info = calloc(1, sizeof(Randr_Info)))) return NULL;
/* create window */
if (!(info->win = e_win_new(con)))
{
free(info);
return NULL;
}
info->win->data = info;
/* set window properties */
e_win_dialog_set(info->win, EINA_FALSE);
e_win_title_set(info->win, _("Screen Setup"));
e_win_name_class_set(info->win, "E", "_config::screen/screen_setup");
e_win_resize_callback_set(info->win, _win_cb_resize);
e_win_delete_callback_set(info->win, _win_cb_delete);
evas = e_win_evas_get(info->win);
/* create background */
info->o_bg = edje_object_add(evas);
e_theme_edje_object_set(info->o_bg, "base/theme/widgets",
"e/conf/randr/main/window"))
evas_object_move(info->o_bg, 0, 0);
evas_object_show(info->o_bg);
printf("Max Size: %d %d\n", E_RANDR_12->max_size.width,
E_RANDR_12->max_size.height);
/* create scrolling widget */
info->o_scroll = e_smart_randr_add(evas);
e_smart_randr_virtual_size_set(info->o_scroll,
E_RANDR_12->max_size.width,
E_RANDR_12->max_size.height);
edje_object_part_swallow(info->o_bg, "e.swallow.content", info->o_scroll);
/* create monitors based on 'CRTCS' */
/* int i = 0; */
EINA_LIST_FOREACH(E_RANDR_12->crtcs, l, crtc)
{
Evas_Object *m;
/* if (i > 0) break; */
if (!crtc) continue;
printf("ADD CRTC %d\n", crtc->xid);
if (!(m = e_smart_monitor_add(evas))) continue;
e_smart_monitor_crtc_set(m, crtc);
e_smart_randr_monitor_add(info->o_scroll, m);
evas_object_show(m);
/* i++; */
}
/* create close button */
ob = e_widget_button_add(evas, _("Close"), NULL,
_close_cb_click, info->win, NULL);
// e_widget_on_focus_hook_set(ob, _close_cb_focus, win);
e_widget_size_min_get(ob, &mw, &mh);
edje_extern_object_min_size_set(ob, mw, mh);
edje_object_part_swallow(info->o_bg, "e.swallow.button", ob);
/* set window minimum size */
edje_object_size_min_calc(info->o_bg, &mw, &mh);
e_win_size_min_set(info->win, mw, mh);
e_util_win_auto_resize_fill(info->win);
e_win_centered_set(info->win, EINA_TRUE);
e_win_show(info->win);
e_win_border_icon_set(info->win, "preferences-system-screen-resolution");
return info;
}
static int
basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
static void
_randr_info_free(void)
{
if (!cfdata)
return EINA_FALSE;
if (!_randr_info) return;
return (arrangement_widget_basic_check_changed(cfd, cfdata)
|| policy_widget_basic_check_changed(cfd, cfdata)
|| orientation_widget_basic_check_changed(cfd, cfdata)
|| resolution_widget_basic_check_changed(cfd, cfdata));
/* delete scroller */
if (_randr_info->o_scroll) evas_object_del(_randr_info->o_scroll);
_randr_info->o_scroll = NULL;
/* delete background */
if (_randr_info->o_bg) evas_object_del(_randr_info->o_bg);
_randr_info->o_bg = NULL;
/* delete window */
if (_randr_info->win) e_object_del(E_OBJECT(_randr_info->win));
_randr_info->win = NULL;
/* free structure */
E_FREE(_randr_info);
}
static void
_win_cb_resize(E_Win *win)
{
Randr_Info *info = NULL;
if (!(info = win->data)) return;
evas_object_resize(info->o_bg, win->w, win->h);
}
static void
_win_cb_delete(E_Win *win __UNUSED__)
{
_randr_info_free();
}
static void
_close_cb_click(void *data __UNUSED__, void *data2 __UNUSED__)
{
_randr_info_free();
}

View File

@ -1,121 +1,9 @@
#ifdef E_TYPEDEFS
#else
#ifndef E_INT_CONFIG_RANDR_H
#define E_INT_CONFIG_RANDR_H
#include "e.h"
typedef struct _E_Config_Randr_Dialog_Output_Dialog_Data E_Config_Randr_Dialog_Output_Dialog_Data;
typedef struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data E_Config_Randr_Dialog_Confirmation_Dialog_Data;
typedef struct _Config Config;
struct _E_Config_Dialog_Data
{
E_Config_Dialog *cfd;
//list of E_Config_Randr_Dialog_Output_Dialog_Data
Eina_List *output_dialog_data_list;
E_Manager *manager;
struct {
Evas *canvas;
Evas_Object *dialog, *widget_list;
E_Config_Randr_Dialog_Output_Dialog_Data *selected_output_dd;
E_Config_Randr_Dialog_Confirmation_Dialog_Data *confirmation_dialog;
struct {
struct {
Evas_Object *widget, *scrollframe, *area, *widget_list, *swallowing_edje, *suggestion, *check_display_disconnected_outputs;
int suggestion_dist_max, check_val_display_disconnected_outputs;
Evas_Coord_Point sel_rep_previous_pos;
Eina_Rectangle dummy_geo;
} arrangement;
struct {
Evas_Object *widget;
//Evas_Object *swallowing_edje;
Evas_Object *radio_above, *radio_right, *radio_below, *radio_left, *radio_clone, *radio_none, *radio_ask;
int radio_val;
//Evas_Object *current_displays_setup, *current_displays_setup_background, *new_display, *new_display_background;
} policy;
struct {
Evas_Object *widget;
} resolution;
struct {
Evas_Object *widget;
//Evas_Object *swallowing_edje;
Evas_Object *radio_normal, *radio_rot90, *radio_rot180, *radio_rot270, *radio_reflect_horizontal, *radio_reflect_vertical;
int radio_val;
} orientation;
} widgets;
} gui;
};
struct _E_Config_Randr_Dialog_Output_Dialog_Data
{
E_Randr_Crtc_Info *crtc;
E_Randr_Output_Info *output;
Ecore_X_Randr_Mode_Info *previous_mode, *new_mode, *preferred_mode;
Ecore_X_Randr_Orientation previous_orientation, new_orientation;
Ecore_X_Randr_Output_Policy previous_policy, new_policy;
Evas_Coord_Point previous_pos, new_pos;
Evas_Object *bg, *rep;
};
struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data
{
E_Config_Dialog *cfd;
E_Config_Dialog_Data *cfdata;
E_Dialog *dialog;
Ecore_Timer *timer;
int countdown;
};
struct _Config
{
Eina_Bool display_disconnected_outputs;
};
# ifndef E_INT_CONFIG_RANDR_H
# define E_INT_CONFIG_RANDR_H
E_Config_Dialog *e_int_config_randr(E_Container *con, const char *params __UNUSED__);
// Functions for the arrangement widget interaction
Eina_Bool arrangement_widget_create_data(E_Config_Dialog_Data *cfdata);
Evas_Object *arrangement_widget_basic_create_widgets(Evas *canvas);
Eina_Bool arrangement_widget_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
Eina_Bool arrangement_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void arrangement_widget_free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void arrangement_widget_keep_changes(E_Config_Dialog_Data *cfdata);
void arrangement_widget_discard_changes(E_Config_Dialog_Data *cfdata);
void arrangement_widget_rep_update(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
// Functions for the policies widget interaction
Eina_Bool policy_widget_create_data(E_Config_Dialog_Data *cfdata);
Evas_Object *policy_widget_basic_create_widgets(Evas *canvas);
Eina_Bool policy_widget_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
Eina_Bool policy_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void policy_widget_free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void policy_widget_keep_changes(E_Config_Dialog_Data *cfdata);
void policy_widget_discard_changes(E_Config_Dialog_Data *cfdata);
void policy_widget_update_radio_buttons(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
// Functions for the resolutions widget interaction
Eina_Bool resolution_widget_create_data(E_Config_Dialog_Data *cfdata);
Evas_Object *resolution_widget_basic_create_widgets(Evas *canvas);
Eina_Bool resolution_widget_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
Eina_Bool resolution_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void resolution_widget_free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void resolution_widget_keep_changes(E_Config_Dialog_Data *cfdata);
void resolution_widget_discard_changes(E_Config_Dialog_Data *cfdata);
void resolution_widget_update_list(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
// Functions for the orientation widget interaction
Eina_Bool orientation_widget_create_data(E_Config_Dialog_Data *cfdata);
Evas_Object *orientation_widget_basic_create_widgets(Evas *canvas);
Eina_Bool orientation_widget_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
Eina_Bool orientation_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void orientation_widget_free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
void orientation_widget_update_radio_buttons(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
void orientation_widget_update_edje(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
void orientation_widget_keep_changes(E_Config_Dialog_Data *cfdata);
void orientation_widget_discard_changes(E_Config_Dialog_Data *cfdata);
#endif
# endif
#endif

View File

@ -1,876 +0,0 @@
#include "e_int_config_randr.h"
#include "e_randr.h"
#include "Ecore_X.h"
#ifndef ECORE_X_RANDR_1_2
#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
#endif
#ifndef ECORE_X_RANDR_1_3
#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
#endif
#ifdef Ecore_X_Randr_Unset
#undef Ecore_X_Randr_Unset
#endif
#define Ecore_X_Randr_Unset -1
#define DOUBLECLICK_TIMEOUT 0.2
#define CRTC_THUMB_SIZE_W 300
#define CRTC_THUMB_SIZE_H 300
/*
*
* TOP_TOP
* ************************************************
* * TOP_BOTTOM *
* * *
* * *
* * *
* LEFT_LEFT * LEFT_RIGHT RIGHT_LEFT * RIGHT_RIGHT
* * *
* * *
* * *
* * BOTTOM_TOP *
* ************************************************
* BOTTOM_BOTTOM
*
*/
typedef enum {
EVAS_OBJECT_REL_POS_NONE = 0,
EVAS_OBJECT_REL_POS_TOP_TOP = (1 << 0),
EVAS_OBJECT_REL_POS_TOP_BOTTOM = (1 << 1),
EVAS_OBJECT_REL_POS_RIGHT_LEFT = (1 << 2),
EVAS_OBJECT_REL_POS_RIGHT_RIGHT = (1 << 3),
EVAS_OBJECT_REL_POS_BOTTOM_TOP = (1 << 4),
EVAS_OBJECT_REL_POS_BOTTOM_BOTTOM = (1 << 5),
EVAS_OBJECT_REL_POS_LEFT_LEFT = (1 << 6),
EVAS_OBJECT_REL_POS_LEFT_RIGHT = (1 << 7),
EVAS_OBJECT_REL_POS_X_ZERO = (1 << 8),
EVAS_OBJECT_REL_POS_Y_ZERO = (1 << 9),
EVAS_OBJECT_REL_POS_INSIDE = (
EVAS_OBJECT_REL_POS_TOP_BOTTOM |
EVAS_OBJECT_REL_POS_RIGHT_LEFT |
EVAS_OBJECT_REL_POS_BOTTOM_TOP |
EVAS_OBJECT_REL_POS_LEFT_RIGHT),
EVAS_OBJECT_REL_POS_OUTSIDE = (
EVAS_OBJECT_REL_POS_TOP_TOP |
EVAS_OBJECT_REL_POS_RIGHT_RIGHT |
EVAS_OBJECT_REL_POS_BOTTOM_BOTTOM |
EVAS_OBJECT_REL_POS_LEFT_LEFT),
EVAS_OBJECT_REL_POS_ALL = (
EVAS_OBJECT_REL_POS_INSIDE |
EVAS_OBJECT_REL_POS_OUTSIDE)
} Evas_Object_Rel_Pos;
typedef enum {
EVAS_OBJECT_DIRECTION_TOP = (1 << 0),
EVAS_OBJECT_DIRECTION_RIGHT = (1 << 1),
EVAS_OBJECT_DIRECTION_BOTTOM = (1 << 2),
EVAS_OBJECT_DIRECTION_LEFT = (1 << 3)
} Evas_Object_Direction;
typedef struct {
struct {
Evas_Object *x, *y;
struct {
Evas_Object_Rel_Pos x, y;
} pos_rel;
} closest_objects;
Evas_Coord_Point pos;
int distance;
} Position_Suggestion;
//static inline E_Config_Randr_Dialog_Output_Dialog_Data *_arrangement_widget_rep_dialog_data_new (E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info);
static inline Evas_Object *_arrangement_widget_suggestion_add(Evas *evas);
static inline void _arrangement_widget_make_suggestion(Evas_Object *obj);
static Evas_Object *_arrangement_widget_rep_add(Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data);
static void _arrangement_widget_rep_del(E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data);
static void _arrangement_widget_rep_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _arrangement_widget_rep_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _arrangement_widget_rep_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _arrangement_widget_check_changed_cb(void *data, Evas_Object *obj, void *event_info);
static void _arrangement_widget_update(void);
static Position_Suggestion *e_layout_pos_sug_from_children_get(Evas_Object *child, Eina_List *children, int max_distance, Evas_Object_Rel_Pos allowed_pos);
Eina_Bool _arrangemnet_rep_illegal_overlapping(E_Config_Randr_Dialog_Output_Dialog_Data *odd);
extern E_Config_Dialog_Data *e_config_runtime_info;
extern Config *randr_dialog_config;
extern char _theme_file_path[];
static void
_arrangement_widget_rep_dialog_data_fill(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
if (!odd) return;
odd->new_pos.x = Ecore_X_Randr_Unset;
odd->new_pos.y = Ecore_X_Randr_Unset;
if (odd->crtc)
{
//already enabled screen
odd->previous_pos.x = odd->crtc->geometry.x;
odd->previous_pos.y = odd->crtc->geometry.y;
}
else
{
odd->previous_pos.x = Ecore_X_Randr_Unset;
odd->previous_pos.y = Ecore_X_Randr_Unset;
}
}
void
arrangement_widget_rep_update(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Eina_Rectangle geo = {.x = 0, .y = 0, .w = 0, .h = 0};
Ecore_X_Randr_Orientation orientation = Ecore_X_Randr_Unset;
//Get width, height
if (odd->new_mode)
{
geo.w = odd->new_mode->width;
geo.h = odd->new_mode->height;
}
else if (odd->crtc)
{
geo.w = odd->crtc->geometry.w;
geo.h = odd->crtc->geometry.h;
}
else if (odd->preferred_mode)
{
geo.w = odd->preferred_mode->width;
geo.h = odd->preferred_mode->height;
}
else
{
geo.w = e_config_runtime_info->gui.widgets.arrangement.dummy_geo.w;
geo.h = e_config_runtime_info->gui.widgets.arrangement.dummy_geo.h;
}
//Get x, y
if ((odd->new_pos.x != Ecore_X_Randr_Unset) && (odd->new_pos.y != Ecore_X_Randr_Unset))
{
geo.x = odd->new_pos.x;
geo.y = odd->new_pos.y;
}
else if (odd->crtc && odd->crtc->current_mode)
{
geo.x = odd->crtc->geometry.x;
geo.y = odd->crtc->geometry.y;
}
else
{
geo.x = e_config_runtime_info->gui.widgets.arrangement.dummy_geo.x;
geo.y = e_config_runtime_info->gui.widgets.arrangement.dummy_geo.y;
}
if (odd->crtc)
{
orientation = (odd->new_orientation != (Ecore_X_Randr_Orientation) Ecore_X_Randr_Unset) ? odd->new_orientation : odd->previous_orientation;
}
switch (orientation)
{
case ECORE_X_RANDR_ORIENTATION_ROT_90:
case ECORE_X_RANDR_ORIENTATION_ROT_270:
e_layout_child_resize(odd->rep, geo.h, geo.w);
break;
default:
e_layout_child_resize(odd->rep, geo.w, geo.h);
break;
}
e_layout_child_move(odd->rep, geo.x, geo.y);
e_layout_child_raise(odd->rep);
fprintf(stderr, "CONF_RANDR: Representation (%p) updated with geo %d.%d %dx%d.\n", odd->rep, geo.x, geo.y, geo.w, geo.h);
}
void
_arrangement_widget_update(void)
{
static Evas_Object *area = NULL;
E_Config_Randr_Dialog_Output_Dialog_Data *odd = NULL;
Eina_List *iter;
area = e_config_runtime_info->gui.widgets.arrangement.area;
if (!e_config_runtime_info || !e_config_runtime_info->gui.canvas || !e_config_runtime_info->output_dialog_data_list || !area) return;
fprintf(stderr, "CONF_RANDR: Display disconnected outputs: %s\n", (randr_dialog_config->display_disconnected_outputs ? "YES" : "NO"));
e_layout_freeze(area);
e_layout_unpack(area);
e_layout_virtual_size_set(area, e_randr_screen_info.rrvd_info.randr_info_12->max_size.width, e_randr_screen_info.rrvd_info.randr_info_12->max_size.height);
fprintf(stderr, "CONF_RANDR: Set virtual size of arrangement e_layout to %dx%d\n", e_randr_screen_info.rrvd_info.randr_info_12->max_size.width, e_randr_screen_info.rrvd_info.randr_info_12->max_size.height);
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, odd)
{
_arrangement_widget_rep_del(odd);
if(!odd->crtc &&
(!odd->output->monitor && (randr_dialog_config && !randr_dialog_config->display_disconnected_outputs)))
continue;
if(!(odd->rep = _arrangement_widget_rep_add(e_config_runtime_info->gui.canvas, odd)))
{
fprintf(stderr, "CONF_RANDR: Could not add rep for CRTC %p/ output %p.\n", odd->crtc, odd->output);
continue;
}
e_layout_pack(area, odd->rep);
arrangement_widget_rep_update(odd);
evas_object_data_set(odd->rep, "rep_info", odd);
evas_object_show(odd->rep);
}
if (e_config_runtime_info->gui.widgets.arrangement.suggestion)
{
e_layout_pack(area, e_config_runtime_info->gui.widgets.arrangement.suggestion);
}
e_layout_thaw(area);
}
Eina_Bool
arrangement_widget_create_data(E_Config_Dialog_Data *data)
{
Eina_List *iter;
E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
char *theme_data_item = NULL;
Eina_Rectangle dummy_geo;
int max_dist = 0;
EINA_LIST_FOREACH(data->output_dialog_data_list, iter, dialog_data)
_arrangement_widget_rep_dialog_data_fill(dialog_data);
//Read in maximum distance of objects before a position is suggested
if ((theme_data_item = edje_file_data_get(_theme_file_path, "distance_max")))
max_dist = atoi(theme_data_item);
else
max_dist = 100;
e_config_runtime_info->gui.widgets.arrangement.suggestion_dist_max = max_dist;
//Read in size used for disabled outputs
theme_data_item = edje_file_data_get(_theme_file_path, "disabled_output_width");
dummy_geo.w = theme_data_item ? atoi(theme_data_item) : 1024;
theme_data_item = edje_file_data_get(_theme_file_path, "disabled_output_height");
dummy_geo.h = theme_data_item ? atoi(theme_data_item) : 768;
dummy_geo.x = e_randr_screen_info.rrvd_info.randr_info_12->max_size.width - dummy_geo.w;
dummy_geo.y = 0;
memcpy(&e_config_runtime_info->gui.widgets.arrangement.dummy_geo, &dummy_geo, sizeof(e_config_runtime_info->gui.widgets.arrangement.dummy_geo));
return EINA_TRUE;
}
Evas_Object *
arrangement_widget_basic_create_widgets(Evas *canvas)
{
Evas_Object *widget, *scrollframe, *area, *check;
if (!canvas || !e_config_runtime_info || !e_config_runtime_info->output_dialog_data_list) return NULL;
widget = e_widget_list_add(canvas, 0, 0);
fprintf(stderr, "CONF_RANDR: Arrangement widget added (%p).\n", widget);
//Add checkbox
check = e_widget_check_add(canvas, _("Display disconnected outputs"), &e_config_runtime_info->gui.widgets.arrangement.check_val_display_disconnected_outputs);
if (randr_dialog_config)
e_widget_check_checked_set(check, randr_dialog_config->display_disconnected_outputs);
evas_object_smart_callback_add(check, "changed", _arrangement_widget_check_changed_cb, NULL);
e_config_runtime_info->gui.widgets.arrangement.check_display_disconnected_outputs = check;
area = e_layout_add(canvas);
e_config_runtime_info->gui.widgets.arrangement.area = area;
e_layout_virtual_size_set(area, e_randr_screen_info.rrvd_info.randr_info_12->max_size.width, e_randr_screen_info.rrvd_info.randr_info_12->max_size.height);
evas_object_resize(area, 500, 500);
evas_object_show(area);
// Add suggestion element, hidden
e_config_runtime_info->gui.widgets.arrangement.suggestion = _arrangement_widget_suggestion_add(canvas);
_arrangement_widget_update();
scrollframe = e_scrollframe_add(canvas);
e_scrollframe_child_set(scrollframe, area);
e_config_runtime_info->gui.widgets.arrangement.scrollframe = scrollframe;
// Append both objects to widget list
e_widget_list_object_append(widget, scrollframe, 1, 1, 0.0);
e_widget_list_object_append(widget, check, 0, 0, 1.0);
e_config_runtime_info->gui.widgets.arrangement.widget_list = widget;
return widget;
}
static Evas_Object *
_arrangement_widget_rep_add(Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data)
{
E_Randr_Output_Info *output_info;
Evas_Object *rep;
const char *output_name = NULL, *state_signal;
if (!canvas || !output_dialog_data || !e_config_runtime_info) return NULL;
rep = edje_object_add(canvas);
//set theme for monitor representation
EINA_SAFETY_ON_FALSE_GOTO(edje_object_file_set(rep, _theme_file_path, "e/conf/randr/dialog/widget/arrangement/output"), _arrangement_widget_rep_add_edje_set_fail);
//indicate monitor state
if (!(output_dialog_data->crtc && output_dialog_data->crtc->current_mode))
state_signal = "disabled";
else
state_signal = "enabled";
edje_object_signal_emit(rep, state_signal, "e");
//for now use deskpreview widget as background of rep, maybe change this to
//live image from comp module
output_dialog_data->bg = e_widget_deskpreview_add(canvas, 1, 1);
//output_dialog_data->bg = e_livethumb_add(canvas);
edje_object_part_swallow(rep, "e.swallow.content", output_dialog_data->bg);
//Try to get the name of the monitor connected to the CRTC's first output via edid
//else use the output's name
if (output_dialog_data->crtc)
output_info = (E_Randr_Output_Info *)eina_list_data_get(output_dialog_data->crtc->outputs);
else
output_info = output_dialog_data->output;
if (output_info)
{
if (output_info->monitor)
output_name = ecore_x_randr_edid_display_name_get(output_info->monitor->edid, output_info->monitor->edid_length);
if (!output_name && output_info->name)
output_name = output_info->name;
}
if (output_name)
edje_object_part_text_set(rep, "output_txt", output_name);
evas_object_event_callback_add(rep, EVAS_CALLBACK_MOUSE_DOWN, _arrangement_widget_rep_mouse_down_cb, NULL);
evas_object_event_callback_add(rep, EVAS_CALLBACK_MOUSE_MOVE, _arrangement_widget_rep_mouse_move_cb, NULL);
evas_object_event_callback_add(rep, EVAS_CALLBACK_MOUSE_UP, _arrangement_widget_rep_mouse_up_cb, NULL);
return rep;
_arrangement_widget_rep_add_edje_set_fail:
evas_object_del(rep);
return NULL;
}
static void
_arrangement_widget_rep_del(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
if (!odd)
return;
evas_object_hide(odd->rep);
evas_object_event_callback_del(odd->rep, EVAS_CALLBACK_MOUSE_DOWN, _arrangement_widget_rep_mouse_down_cb);
evas_object_event_callback_del(odd->rep, EVAS_CALLBACK_MOUSE_MOVE, _arrangement_widget_rep_mouse_move_cb);
evas_object_event_callback_del(odd->rep, EVAS_CALLBACK_MOUSE_UP, _arrangement_widget_rep_mouse_up_cb);
//get instance data for output
edje_object_part_unswallow(odd->rep, odd->bg);
evas_object_del(odd->bg);
odd->bg = NULL;
//update output orientation
orientation_widget_update_radio_buttons(NULL);
evas_object_del(odd->rep);
odd->rep = NULL;
}
static void
_arrangement_widget_check_changed_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
randr_dialog_config->display_disconnected_outputs = e_config_runtime_info->gui.widgets.arrangement.check_val_display_disconnected_outputs;
_arrangement_widget_update();
}
static void
_arrangement_widget_rep_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd = NULL;
Eina_List *iter;
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, odd)
{
if (odd->rep == obj)
continue;
edje_object_signal_emit(odd->rep, "deselect", "e");
}
edje_object_signal_emit(obj, "select", "e");
e_layout_child_geometry_get(obj, &e_config_runtime_info->gui.widgets.arrangement.sel_rep_previous_pos.x, &e_config_runtime_info->gui.widgets.arrangement.sel_rep_previous_pos.y, NULL, NULL);
//update data for other logs
e_config_runtime_info->gui.selected_output_dd = (E_Config_Randr_Dialog_Output_Dialog_Data*)evas_object_data_get(obj, "rep_info");
//update resolutions list
resolution_widget_update_list(e_config_runtime_info->gui.selected_output_dd);
//update orientation radio buttons
orientation_widget_update_radio_buttons(e_config_runtime_info->gui.selected_output_dd);
//update policy radio buttons
policy_widget_update_radio_buttons(e_config_runtime_info->gui.selected_output_dd);
}
static void
_arrangement_widget_rep_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
{
Evas_Event_Mouse_Move *ev = event_info;
Eina_Rectangle geo, parent;
Evas_Coord_Point delta, new;
if (ev->buttons != 1) return;
evas_object_geometry_get(e_config_runtime_info->gui.widgets.arrangement.area, &parent.x, &parent.y, NULL, NULL);
e_layout_virtual_size_get(e_config_runtime_info->gui.widgets.arrangement.area, &parent.w, &parent.h);
delta.x = ev->cur.canvas.x - ev->prev.canvas.x;
delta.y = ev->cur.canvas.y - ev->prev.canvas.y;
//add parent.x and parent.y to delta, as they are subtraced in the e_layouts'
//coord transformation
e_layout_coord_canvas_to_virtual(e_config_runtime_info->gui.widgets.arrangement.area, (parent.x + delta.x), (parent.y + delta.y), &new.x, &new.y);
e_layout_child_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
new.x += geo.x;
new.y += geo.y;
//respect container borders
if (new.x < parent.x + 1)
new.x = parent.x + 1;
else if (new.x > parent.x + parent.w - geo.w)
new.x = parent.x + parent.w - geo.w;
if (new.y < parent.y + 1)
new.y = parent.y + 1;
else if (new.y > parent.y + parent.h - geo.h)
new.y = parent.y + parent.h - geo.h;
//only take action if position changed
if ((geo.x != new.x) || (geo.y != new.y))
{
e_layout_child_move(obj, new.x, new.y);
_arrangement_widget_make_suggestion(obj);
}
}
static void
_arrangement_widget_rep_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
Evas_Coord_Point coords;
if (evas_object_visible_get(e_config_runtime_info->gui.widgets.arrangement.suggestion))
{
edje_object_signal_emit(e_config_runtime_info->gui.widgets.arrangement.suggestion, "hide", "e");
evas_object_hide(e_config_runtime_info->gui.widgets.arrangement.suggestion);
e_layout_child_geometry_get(e_config_runtime_info->gui.widgets.arrangement.suggestion, &coords.x, &coords.y, NULL, NULL);
}
else
{
coords.x = e_config_runtime_info->gui.widgets.arrangement.sel_rep_previous_pos.x;
coords.y = e_config_runtime_info->gui.widgets.arrangement.sel_rep_previous_pos.y;
}
e_layout_child_move(obj, coords.x, coords.y);
}
Evas_Object *
_arrangement_widget_suggestion_add(Evas *evas)
{
Evas_Object *sug = NULL;
sug = edje_object_add(evas);
edje_object_file_set(sug, _theme_file_path, "e/conf/randr/dialog/widget/arrangement/suggestion");
return sug;
}
void
_arrangement_widget_make_suggestion(Evas_Object *obj)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd = NULL;
Eina_List *possible_reps = NULL, *li;
Position_Suggestion *ps;
int max_dist;
Eina_Bool visible;
Eina_Rectangle o_geo;
const Evas_Object_Rel_Pos allowed_pos = (EVAS_OBJECT_REL_POS_ALL | EVAS_OBJECT_REL_POS_X_ZERO | EVAS_OBJECT_REL_POS_Y_ZERO);
if (!obj) return;
max_dist = e_config_runtime_info->gui.widgets.arrangement.suggestion_dist_max;
//iterate rep list
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, li, odd)
{
if (!odd || !odd->rep || (odd->rep == obj) || !(odd->crtc) || !(odd->crtc->current_mode))
continue;
possible_reps = eina_list_append(possible_reps, odd->rep);
}
ps = e_layout_pos_sug_from_children_get(obj, possible_reps, max_dist, allowed_pos);
visible = evas_object_visible_get(e_config_runtime_info->gui.widgets.arrangement.suggestion);
if (!ps)
{
if (visible)
{
edje_object_signal_emit(e_config_runtime_info->gui.widgets.arrangement.suggestion, "hide", "e");
evas_object_hide(e_config_runtime_info->gui.widgets.arrangement.suggestion);
}
goto _mk_sug_free_ret;
}
/*
fprintf(stderr, "CONF_RANDR: Suggestion:\n"
"\tpos.x: %d\n"
"\tpos.y: %d\n"
"\tclsst.x: %p\n"
"\tclsst.y: %p\n",
ps->pos.x, ps->pos.y, ps->closest_objects.x, ps->closest_objects.y);
*/
odd = evas_object_data_get(obj, "rep_info");
e_layout_child_geometry_get(obj, &o_geo.x, &o_geo.y, &o_geo.w, &o_geo.h);
if (ps->pos.x != Ecore_X_Randr_Unset)
{
odd->new_pos.x = ps->pos.x;
if ((odd->new_pos.x + o_geo.w) > e_randr_screen_info.rrvd_info.randr_info_12->max_size.width) //FIXME:Rotation
odd->new_pos.x = Ecore_X_Randr_Unset;
else if (odd->new_pos.x < 0)
odd->new_pos.x = 0;
}
if (ps->pos.y != Ecore_X_Randr_Unset)
{
odd->new_pos.y = ps->pos.y;
if ((odd->new_pos.y + o_geo.h) > e_randr_screen_info.rrvd_info.randr_info_12->max_size.height) //FIXME: Rotation
odd->new_pos.y = Ecore_X_Randr_Unset;
else if (odd->new_pos.y < 0)
odd->new_pos.y = 0;
}
if (_arrangemnet_rep_illegal_overlapping(odd) || ps->distance > max_dist)
odd->new_pos.x = odd->new_pos.y = Ecore_X_Randr_Unset;
if ((odd->new_pos.x != Ecore_X_Randr_Unset) && (odd->new_pos.y != Ecore_X_Randr_Unset))
{
if (!visible)
{
evas_object_show(e_config_runtime_info->gui.widgets.arrangement.suggestion);
edje_object_signal_emit(e_config_runtime_info->gui.widgets.arrangement.suggestion, "show", "e");
}
e_layout_child_move(e_config_runtime_info->gui.widgets.arrangement.suggestion, odd->new_pos.x, odd->new_pos.y);
e_layout_child_resize(e_config_runtime_info->gui.widgets.arrangement.suggestion, o_geo.w, o_geo.h);
e_layout_child_raise(e_config_runtime_info->gui.widgets.arrangement.suggestion);
}
else if (visible)
{
edje_object_signal_emit(e_config_runtime_info->gui.widgets.arrangement.suggestion, "hide", "e");
evas_object_hide(e_config_runtime_info->gui.widgets.arrangement.suggestion);
}
_mk_sug_free_ret:
free(ps);
}
void
arrangement_widget_free_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
Eina_List *iter;
EINA_SAFETY_ON_NULL_RETURN(cfdata);
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, dialog_data)
{
if (dialog_data->bg)
{
evas_object_del(dialog_data->bg);
dialog_data->bg = NULL;
}
}
}
Eina_Bool
arrangement_widget_basic_apply_data(E_Config_Dialog *cfd __UNUSED__ , E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_Bool success = EINA_TRUE;
Eina_List *iter;
//create list of all evas objects we concern
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd->crtc || !odd->crtc->current_mode || (odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))
continue;
fprintf(stderr, "CONF_RANDR: Rearranging CRTC %d to %d,%d\n", odd->crtc->xid, odd->new_pos.x, odd->new_pos.y);
#define EQL(c) (odd->new_pos.c == odd->crtc->geometry.c)
if (!EQL(x) || !EQL(y))
{
if (!ecore_x_randr_crtc_pos_set(cfd->con->manager->root, odd->crtc->xid, odd->new_pos.x, odd->new_pos.y))
success = EINA_FALSE;
}
#undef EQL
}
ecore_x_randr_screen_reset(cfd->con->manager->root);
return success;
}
Eina_Bool
arrangement_widget_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd = NULL;
Eina_List *iter;
/*
* This assumes that only positions for elements are allowed, that have been
* previously suggested. Thus every element has its position already assigned.
*/
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
fprintf(stderr, "CONF_RANDR: Checking coord of odd %p. new_pos is: %d,%d\n", odd, odd->new_pos.x, odd->new_pos.y);
if (!odd->crtc || !odd->crtc->current_mode || (odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))
continue;
#define EQL(c) (odd->new_pos.c == odd->crtc->geometry.c)
if (!EQL(x) || !EQL(y))
return EINA_TRUE;
#undef EQL
}
return EINA_FALSE;
}
void
arrangement_widget_keep_changes(E_Config_Dialog_Data *cfdata __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd = NULL;
Eina_List *iter;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd->crtc || !odd->crtc->current_mode || (odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))
continue;
//FIXME Rely on RandRR events to update data!
odd->previous_pos.x = odd->new_pos.x;
odd->previous_pos.y = odd->new_pos.y;
odd->new_pos.x = odd->new_pos.y = Ecore_X_Randr_Unset;
}
}
void
arrangement_widget_discard_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd->crtc || ((odd->previous_pos.x == Ecore_X_Randr_Unset) || (odd->previous_pos.y == Ecore_X_Randr_Unset))) continue;
#define EQL(c) (odd->previous_pos.c == odd->crtc->geometry.c)
if (!EQL(x) || !EQL(y))
ecore_x_randr_crtc_pos_set(cfdata->manager->root, odd->crtc->xid, odd->previous_pos.x, odd->previous_pos.y);
#undef EQL
}
ecore_x_randr_screen_reset(cfdata->manager->root);
}
/**
* @brief suggests a position for an e_layout child @p child based on positions of objects in @p list.
* @param child The object for which a suggestion should be made
* @param children A list of e_layout children on whose positions the suggestion will be
* base
* @param max_distance The maximum distance a border is allowed to be away form
* @p obj border
* @param allowed_pos A mask defining which positions are allowed to be
* suggested.
* @return a suggested position together with the closest children
*/
static Position_Suggestion
*e_layout_pos_sug_from_children_get(Evas_Object *child, Eina_List *children, int max_distance, Evas_Object_Rel_Pos allowed_pos)
{
Position_Suggestion *ps = NULL;
Evas_Object *io = NULL;
Eina_Rectangle og, ig;
Evas_Coord_Point cd, d;
Eina_List *iter;
if (!child || !children || !allowed_pos)
return NULL;
//General initialization
e_layout_child_geometry_get(child, &og.x, &og.y, &og.w, &og.h);
cd.x = d.x = INT_MAX;
cd.y = d.y = INT_MAX;
//initialize returned object
ps = E_NEW(Position_Suggestion, 1);
ps->closest_objects.pos_rel.x = ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_NONE;
ps->pos.x = ps->pos.y = Ecore_X_Randr_Unset;
EINA_LIST_FOREACH(children, iter, io)
{
if (!io)
continue;
e_layout_child_geometry_get(io, &ig.x, &ig.y, &ig.w, &ig.h);
// Top
if (allowed_pos & EVAS_OBJECT_REL_POS_TOP_TOP)
{
cd.y = abs((og.y + og.h) - ig.y);
if ((cd.y <= max_distance) && (cd.y < d.y))
{
d.y = cd.y;
ps->pos.y = ig.y - og.h;
ps->closest_objects.y = io;
ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_TOP_TOP;
}
}
if (allowed_pos & EVAS_OBJECT_REL_POS_TOP_BOTTOM)
{
cd.y = abs(og.y - ig.y);
if ((cd.y <= max_distance) && (cd.y < d.y))
{
d.y = cd.y;
ps->pos.y = ig.y;
ps->closest_objects.y = io;
ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_TOP_BOTTOM;
}
}
// Right
if (allowed_pos & EVAS_OBJECT_REL_POS_RIGHT_RIGHT)
{
cd.x = abs(og.x - (ig.x + ig.w));
if ((cd.x <= max_distance) && (cd.x < d.x))
{
d.x = cd.x;
ps->pos.x = ig.x + ig.w;
ps->closest_objects.x = io;
ps->closest_objects.pos_rel.x = EVAS_OBJECT_REL_POS_RIGHT_RIGHT;
}
}
if (allowed_pos & EVAS_OBJECT_REL_POS_RIGHT_LEFT)
{
cd.x = abs((og.x + og.w) - (ig.x + ig.w));
if ((cd.x <= max_distance) && (cd.x < d.x))
{
d.x = cd.x;
ps->pos.x = (ig.x + ig.w) - og.w;
ps->closest_objects.x = io;
ps->closest_objects.pos_rel.x = EVAS_OBJECT_REL_POS_RIGHT_LEFT;
}
}
// BOTTOM
if (allowed_pos & EVAS_OBJECT_REL_POS_BOTTOM_BOTTOM)
{
cd.y = abs(og.y - (ig.y + ig.h));
if ((cd.y <= max_distance) && (cd.y < d.y))
{
d.y = cd.y;
ps->pos.y = ig.y + ig.h;
ps->closest_objects.y = io;
ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_BOTTOM_BOTTOM;
}
}
if (allowed_pos & EVAS_OBJECT_REL_POS_BOTTOM_TOP)
{
cd.y = abs((ig.y + ig.h) - (og.y + og.h));
if ((cd.y <= max_distance) && (cd.y < d.y))
{
d.y = cd.y;
ps->pos.y = (ig.y + ig.h) - og.h;
ps->closest_objects.y = io;
ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_BOTTOM_TOP;
}
}
// Left
if (allowed_pos & EVAS_OBJECT_REL_POS_LEFT_LEFT)
{
cd.x = abs((og.x + og.w) - ig.x);
if ((cd.x <= max_distance) && (cd.x < d.x))
{
d.x = cd.x;
ps->pos.x = (ig.x - og.w);
ps->closest_objects.x = io;
ps->closest_objects.pos_rel.x = EVAS_OBJECT_REL_POS_LEFT_LEFT;
}
}
if (allowed_pos & EVAS_OBJECT_REL_POS_LEFT_RIGHT)
{
cd.x = abs(og.x - ig.x);
if ((cd.x <= max_distance) && (cd.x < d.x))
{
d.x = cd.x;
ps->pos.x = ig.x;
ps->closest_objects.x = io;
ps->closest_objects.pos_rel.x = EVAS_OBJECT_REL_POS_LEFT_RIGHT;
}
}
}
//FIXME: these are copied from the loop above, thus dupclicated code!
if (allowed_pos & EVAS_OBJECT_REL_POS_X_ZERO)
{
io = NULL;
ig.x = 0;
cd.x = abs(og.x - ig.x);
if ((cd.x <= max_distance) && (cd.x < d.x))
{
d.x = cd.x;
ps->pos.x = ig.x;
ps->closest_objects.x = io;
ps->closest_objects.pos_rel.x = EVAS_OBJECT_REL_POS_X_ZERO;
}
}
if (allowed_pos & EVAS_OBJECT_REL_POS_Y_ZERO)
{
io = NULL;
ig.y = 0;
cd.y = abs(og.y - ig.y);
if ((cd.y <= max_distance) && (cd.y < d.y))
{
d.y = cd.y;
ps->pos.y = ig.y;
ps->closest_objects.y = io;
ps->closest_objects.pos_rel.y = EVAS_OBJECT_REL_POS_Y_ZERO;
}
}
ps->distance = MIN(d.x, d.y);
return ps;
}
/*
* E17 does not allow CRTCs (or rather zones) to overlap.
* This functions evaluates whether a new position does interfere with already
* available zones.
*/
Eina_Bool
_arrangemnet_rep_illegal_overlapping(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
E_Config_Randr_Dialog_Output_Dialog_Data *r_odd = NULL;
Eina_List *it;
Eina_Rectangle o_geo, r_geo;
e_layout_child_geometry_get(odd->rep, &o_geo.x, &o_geo.y, &o_geo.w, &o_geo.h);
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, r_odd)
{
if (!odd || (r_odd == odd))
continue;
e_layout_child_geometry_get(r_odd->rep, &r_geo.x, &r_geo.y, &r_geo.w, &r_geo.h);
if (eina_rectangles_intersect(&o_geo, &r_geo)
&& memcmp(&o_geo, &r_geo, sizeof(Eina_Rectangle)))
return EINA_TRUE;
}
return EINA_FALSE;
}

View File

@ -1,359 +0,0 @@
#include "e_int_config_randr.h"
#include "e_randr.h"
#ifndef Ecore_X_Randr_Unset
#define Ecore_X_Randr_Unset -1
#endif
static void _orientation_widget_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _orientation_widget_radio_add_callbacks(void);
extern E_Config_Dialog_Data *e_config_runtime_info;
extern char _theme_file_path[];
/*
static const char *_ORIENTATION_STRINGS[] = {
"Normal",
"Rotated, 90°",
"Rotated, 180°",
"Rotated, 270°",
"Flipped, Horizontally",
"Flipped, Vertically" };
*/
Eina_Bool
orientation_widget_create_data(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
odd->new_orientation = Ecore_X_Randr_Unset;
odd->previous_orientation = odd->crtc ? odd->crtc->current_orientation : (Ecore_X_Randr_Orientation) Ecore_X_Randr_Unset;
}
return EINA_TRUE;
}
void
orientation_widget_free_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_reflect_vertical, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_reflect_horizontal, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_rot270, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_rot180, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_rot90, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
evas_object_event_callback_del(cfdata->gui.widgets.orientation.radio_normal, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb);
}
Evas_Object *
orientation_widget_basic_create_widgets(Evas *canvas)
{
Evas_Object *widget;
E_Radio_Group *rg;
//char signal[29];
if (!canvas || !e_config_runtime_info) return NULL;
if (e_config_runtime_info->gui.widgets.orientation.widget) return e_config_runtime_info->gui.widgets.orientation.widget;
if (!(widget = e_widget_framelist_add(canvas, _("Display Orientation"), EINA_FALSE))) return NULL;
// Add radio buttons
if (!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.widgets.orientation.radio_val))) goto _orientation_widget_radio_add_fail;
//IMPROVABLE: use enum to determine objects via 'switch'-statement
e_config_runtime_info->gui.widgets.orientation.radio_normal = e_widget_radio_add(canvas, _("Normal"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_normal);
e_config_runtime_info->gui.widgets.orientation.radio_rot90 = e_widget_radio_add(canvas, _("Rotated, 90°"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_rot90);
e_config_runtime_info->gui.widgets.orientation.radio_rot180 = e_widget_radio_add(canvas, _("Rotated, 180°"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_rot180);
e_config_runtime_info->gui.widgets.orientation.radio_rot270 = e_widget_radio_add(canvas, _("Rotated, 270°"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_rot270);
e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal = e_widget_radio_add(canvas, _("Flipped, horizontally"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal);
e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical = e_widget_radio_add(canvas, _("Flipped, vertically"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
e_widget_framelist_object_append(widget, e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical);
_orientation_widget_radio_add_callbacks();
/*
// Add orientation demonstration edje
if (!(e_config_runtime_info->gui.widgets.orientation.swallowing_edje = edje_object_add(canvas)))
goto _orientation_widget_edje_add_fail;
if (!edje_object_file_set(e_config_runtime_info->gui.widgets.orientation.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/widget/orientation"))
goto _orientation_widget_edje_set_fail;
e_widget_table_object_align_append(widget, e_config_runtime_info->gui.widgets.orientation.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
*/
//disable widgets, if no CRTC is selected
orientation_widget_update_radio_buttons(e_config_runtime_info->gui.selected_output_dd);
//evas_object_show(e_config_runtime_info->gui.widgets.orientation.swallowing_edje);
return widget;
/*
_orientation_widget_edje_set_fail:
evas_object_del(ol);
evas_object_del(e_config_runtime_info->gui.widgets.orientation.swallowing_edje);
_orientation_widget_edje_add_fail:
fprintf(stderr, "CONF_RANDR: Couldn't set edj for orientation widget!\n");
evas_object_del(widget);
return NULL;
*/
_orientation_widget_radio_add_fail:
evas_object_del(widget);
fprintf(stderr, "CONF_RANDR: Could not add radio group!\n");
return NULL;
}
static void
_orientation_widget_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
//char signal[40];
int orientation = Ecore_X_Randr_Unset;
if (!e_config_runtime_info->gui.selected_output_dd)
return;
/*
* IMPROVABLE:
* "sadly" the evas callbacks are called before radio_val is set to its new
* value. If that is ever changed, remove the used code below and just use the
* 1-liner below.
* snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,%d", e_config_runtime_info->gui.widgets.orientation.radio_val);
*/
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_normal) orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_rot90) orientation = ECORE_X_RANDR_ORIENTATION_ROT_90;
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_rot180) orientation = ECORE_X_RANDR_ORIENTATION_ROT_180;
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_rot270) orientation = ECORE_X_RANDR_ORIENTATION_ROT_270;
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_X;
if (obj == e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_Y;
e_config_runtime_info->gui.selected_output_dd->new_orientation = orientation;
arrangement_widget_rep_update(e_config_runtime_info->gui.selected_output_dd);
//edje_object_signal_emit(e_config_runtime_info->gui.widgets.orientation.swallowing_edje, signal, "e");
//fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to orientation: %s\n", signal);
}
void
orientation_widget_update_radio_buttons(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Ecore_X_Randr_Orientation supported_oris, ori;
//disable widgets, if no crtc is selected
if (!odd)
{
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_normal, EINA_TRUE);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot90, EINA_TRUE);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot180, EINA_TRUE);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot270, EINA_TRUE);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal, EINA_TRUE);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical, EINA_TRUE);
return;
}
if (odd->crtc)
{
//enabled monitor
supported_oris = odd->crtc->orientations;
ori = (odd->new_orientation != (Ecore_X_Randr_Orientation) Ecore_X_Randr_Unset) ? odd->new_orientation : odd->crtc->current_orientation;
}
else
{
//disabled monitor
//assume all orientations are supported
supported_oris = Ecore_X_Randr_Unset;
ori = Ecore_X_Randr_Unset;
}
if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_0)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_normal, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_normal, EINA_TRUE);
if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_90)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot90, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot90, EINA_TRUE);
if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_180)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot180, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot180, EINA_TRUE);
if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_270)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot270, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_rot270, EINA_TRUE);
if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_X)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal, EINA_TRUE);
if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_Y)
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical, EINA_FALSE);
else
e_widget_disabled_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical, EINA_TRUE);
//toggle the switch of the currently used orientation
switch (ori)
{
case ECORE_X_RANDR_ORIENTATION_ROT_0:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_normal, EINA_TRUE);
break;
case ECORE_X_RANDR_ORIENTATION_ROT_90:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_rot90, EINA_TRUE);
break;
case ECORE_X_RANDR_ORIENTATION_ROT_180:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_rot180, EINA_TRUE);
break;
case ECORE_X_RANDR_ORIENTATION_ROT_270:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_rot270, EINA_TRUE);
break;
case ECORE_X_RANDR_ORIENTATION_FLIP_X:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal, EINA_TRUE);
break;
case ECORE_X_RANDR_ORIENTATION_FLIP_Y:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical, EINA_TRUE);
break;
default:
break;
}
}
/*
void
orientation_widget_update_edje(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Ecore_X_Randr_Orientation supported_oris, ori;
char signal[40];
if (!odd)
return;
if (odd->crtc)
{
//enabled monitor
supported_oris = odd->crtc->orientations;
ori = odd->crtc->current_orientation;
}
else
{
//disabled monitor
//assume all orientations are supported
//#define RANDR_DIALOG_ORIENTATION_ALL (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 | ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y)
supported_oris = RANDR_DIALOG_ORIENTATION_ALL;
ori = ECORE_X_RANDR_ORIENTATION_ROT_0;
}
//Send signal to the edje, to represent the supported and current set orientation
snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,supported,%d", supported_oris);
edje_object_signal_emit(crtc, signal, "e");
snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,current,%d", ori);
edje_object_signal_emit(crtc, signal, "e");
}
*/
Eina_Bool
orientation_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
Eina_Bool success = EINA_TRUE;
if (!cfdata) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd || !odd->crtc || ((int)odd->new_orientation == Ecore_X_Randr_Unset))
continue;
fprintf(stderr, "CONF_RANDR: Change orientation of crtc %d to %d.\n", odd->crtc->xid, odd->new_orientation);
if (!ecore_x_randr_crtc_orientation_set(cfd->con->manager->root, odd->crtc->xid, odd->new_orientation))
success = EINA_FALSE;
}
return success;
}
Eina_Bool
orientation_widget_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd || !odd->crtc || ((int)odd->previous_orientation == Ecore_X_Randr_Unset) || ((int)odd->new_orientation == Ecore_X_Randr_Unset))
continue;
if (odd->previous_orientation != odd->new_orientation)
return EINA_TRUE;
}
return EINA_FALSE;
}
void
orientation_widget_keep_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd || ((int)odd->previous_orientation == Ecore_X_Randr_Unset))
continue;
odd->previous_orientation = odd->new_orientation;
odd->new_orientation = Ecore_X_Randr_Unset;
}
}
void
orientation_widget_discard_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd->crtc || ((int)odd->previous_orientation == Ecore_X_Randr_Unset))
continue;
ecore_x_randr_crtc_orientation_set(cfdata->manager->root, odd->crtc->xid, odd->previous_orientation);
odd->new_orientation = Ecore_X_Randr_Unset;
}
}
static void
_orientation_widget_radio_add_callbacks(void)
{
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_reflect_vertical, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_reflect_horizontal, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_rot270, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_rot180, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_rot90, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
evas_object_event_callback_add(e_config_runtime_info->gui.widgets.orientation.radio_normal, EVAS_CALLBACK_MOUSE_UP, _orientation_widget_mouse_up_cb, NULL);
}

View File

@ -1,340 +0,0 @@
#include "e_int_config_randr.h"
#include "e_randr.h"
#ifndef ECORE_X_RANDR_1_2
#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
#endif
#ifndef ECORE_X_RANDR_1_3
#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
#endif
#ifndef Ecore_X_Randr_Unset
#define Ecore_X_Randr_Unset -1
#endif
#define E_RANDR_12 (e_randr_screen_info.rrvd_info.randr_info_12)
static void _policy_widget_mouse_up_cb(void *data, Evas_Object *obj, void *event_info);
extern E_Config_Dialog_Data *e_config_runtime_info;
extern char _theme_file_path[];
static const char *_POLICIES_STRINGS[] = {
"ABOVE",
"RIGHT",
"BELOW",
"LEFT",
"CLONE",
"NONE",
"ASK"};
Eina_Bool
policy_widget_create_data(E_Config_Dialog_Data *data)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
E_Randr_Output_Info *oi = NULL;
Eina_List *iter;
if (!data || !data->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(data->output_dialog_data_list, iter, odd)
{
if (odd->crtc)
oi = eina_list_data_get(odd->crtc->outputs);
else
oi = odd->output;
odd->previous_policy = oi ? oi->policy : (Ecore_X_Randr_Orientation) Ecore_X_Randr_Unset;
odd->new_policy = Ecore_X_Randr_Unset;
if (!oi) //Not of interest for dbg output
continue;
fprintf(stderr, "CONF_RANDR: Read in policy of %d as %s.\n", oi->xid, ((odd->previous_policy != (Ecore_X_Randr_Output_Policy) Ecore_X_Randr_Unset) ? _POLICIES_STRINGS[odd->previous_policy - 1] : "unset"));
}
return EINA_TRUE;
}
void
policy_widget_free_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
{
}
Evas_Object *
policy_widget_basic_create_widgets(Evas *canvas)
{
Evas_Object *widget, *ro;
E_Radio_Group *rg;
//char signal[29];
if (!canvas || !e_config_runtime_info) return NULL;
if (e_config_runtime_info->gui.widgets.policy.widget) return e_config_runtime_info->gui.widgets.policy.widget;
if (!(widget = e_widget_framelist_add(canvas, _("Screen attachement policy"), EINA_FALSE))) return NULL;
// Add radio buttons
if (!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.widgets.policy.radio_val))) goto _policy_widget_radio_add_fail;
//IMPROVABLE: use enum to determine objects via 'switch'-statement
ro = e_widget_radio_add(canvas, _("Ask"), ECORE_X_RANDR_OUTPUT_POLICY_ASK, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_ask = ro;
ro = e_widget_radio_add(canvas, _("Above"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_above = ro;
ro = e_widget_radio_add(canvas, _("Right"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_right = ro;
ro = e_widget_radio_add(canvas, _("Below"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_below = ro;
ro = e_widget_radio_add(canvas, _("Left"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_left = ro;
ro = e_widget_radio_add(canvas, _("Clone display content"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_clone = ro;
ro = e_widget_radio_add(canvas, _("No reaction"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
evas_object_smart_callback_add(ro, "changed", _policy_widget_mouse_up_cb, NULL);
e_widget_framelist_object_append(widget, ro);
e_config_runtime_info->gui.widgets.policy.radio_none = ro;
/*
// Add policies demonstration edje
if (!(e_config_runtime_info->gui.widgets.policy.swallowing_edje = edje_object_add(canvas)))
{
goto _policy_widget_edje_add_fail;
}
if (!edje_object_file_set(e_config_runtime_info->gui.widgets.policy.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/widget/policies"))
{
goto _policy_widget_edje_set_fail;
}
e_widget_table_object_align_append(widget, e_config_runtime_info->gui.widgets.policy.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
*/
/*
evas_object_show(e_config_runtime_info->gui.widgets.policy.swallowing_edje);
//emit signal to edje so a demonstration can be shown
snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_randr_screen_info->rrvd_info.randr_info_12->output_policy);
edje_object_signal_emit(e_config_runtime_info->gui.widgets.policy.swallowing_edje, signal, "e");
fprintf(stderr, "CONF_RANDR: Initial signal emitted to policy dialog: %s\n", signal);
//Use theme's background as screen representation
e_config_runtime_info->gui.widgets.policy.new_display = edje_object_add(canvas);
e_theme_edje_object_set(e_config_runtime_info->gui.widgets.policy.new_display, "base/theme/widgets", "e/widgets/frame");
e_config_runtime_info->gui.widgets.policy.new_display_background = edje_object_add(canvas);
e_theme_edje_object_set(e_config_runtime_info->gui.widgets.policy.new_display_background, "base/theme/background", "e/desktop/background");
edje_object_part_swallow(e_config_runtime_info->gui.widgets.policy.new_display, "e.swallow.content", e_config_runtime_info->gui.widgets.policy.new_display_background);
edje_object_part_text_set(e_config_runtime_info->gui.widgets.policy.new_display, "e.text.label", _("New display"));
edje_object_part_swallow(e_config_runtime_info->gui.widgets.policy.swallowing_edje, "new_display.swallow.content", e_config_runtime_info->gui.widgets.policy.new_display);
//add theme's frame
//for now use the theme's background for the new display as well
e_config_runtime_info->gui.widgets.policy.current_displays_setup = edje_object_add(canvas);
e_theme_edje_object_set(e_config_runtime_info->gui.widgets.policy.current_displays_setup, "base/theme/widgets", "e/widgets/frame");
e_config_runtime_info->gui.widgets.policy.current_displays_setup_background = edje_object_add(canvas);
e_theme_edje_object_set(e_config_runtime_info->gui.widgets.policy.current_displays_setup_background, "base/theme/background", "e/desktop/background");
edje_object_part_swallow(e_config_runtime_info->gui.widgets.policy.current_displays_setup, "e.swallow.content", e_config_runtime_info->gui.widgets.policy.current_displays_setup_background);
edje_object_part_text_set(e_config_runtime_info->gui.widgets.policy.current_displays_setup, "e.text.label", _("Used display"));
edje_object_part_swallow(e_config_runtime_info->gui.widgets.policy.swallowing_edje, "current_displays_setup.swallow.content", e_config_runtime_info->gui.widgets.policy.current_displays_setup);
*/
evas_object_show(widget);
return widget;
/*
_policy_widget_edje_set_fail:
evas_object_del(e_config_runtime_info->gui.widgets.policy.swallowing_edje);
_policy_widget_edje_add_fail:
fprintf(stderr, "CONF_RANDR: Couldn't set edj for policies widget!\n");
evas_object_del(widget);
return NULL;
*/
_policy_widget_radio_add_fail:
evas_object_del(widget);
return NULL;
}
static void
_policy_widget_mouse_up_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
//char signal[29];
if (!e_config_runtime_info->gui.selected_output_dd)
return;
e_config_runtime_info->gui.selected_output_dd->new_policy = e_config_runtime_info->gui.widgets.policy.radio_val;
/*
* The current dialog does not demonstrate what the policies mean, so disabled
* for now.
*
* snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_config_runtime_info->gui.widgets.policy.radio_val);
//edje_object_signal_emit(e_config_runtime_info->gui.widgets.policy.swallowing_edje, signal, "e");
fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to policy: %s\n", signal);
*/
}
Eina_Bool
policy_widget_basic_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it, *it2;
E_Randr_Output_Info *oi = NULL;
if (!E_RANDR_12 || !cfdata->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, it, odd)
{
if (odd->new_policy == (Ecore_X_Randr_Output_Policy) Ecore_X_Randr_Unset)
continue;
if (odd->crtc)
{
EINA_LIST_FOREACH(odd->crtc->outputs, it2, oi)
{
oi->policy = odd->new_policy;
fprintf(stderr, "CONF_RANDR: 'New display attached'-policy for output %d set to %s.\n", odd->output ? odd->output->xid : 0, _POLICIES_STRINGS[odd->new_policy - 1]);
}
}
else if (odd->output)
{
odd->output->policy = odd->new_policy;
fprintf(stderr, "CONF_RANDR: 'New display attached'-policy for output %d set to %s.\n", odd->output->xid, _POLICIES_STRINGS[odd->new_policy - 1]);
}
}
return EINA_TRUE;
}
Eina_Bool
policy_widget_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it;
if (!E_RANDR_12 || !cfdata->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, it, odd)
{
if ((odd->new_policy == (Ecore_X_Randr_Output_Policy) Ecore_X_Randr_Unset) ||
(odd->previous_policy == (Ecore_X_Randr_Output_Policy) Ecore_X_Randr_Unset))
continue;
if (odd->new_policy != odd->previous_policy)
return EINA_TRUE;
}
return EINA_FALSE;
}
void
policy_widget_update_radio_buttons(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Ecore_X_Randr_Output_Policy policy;
Eina_Bool enable = !odd;
//disable widgets, if no rep is selected
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_ask, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_above, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_right, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_below, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_left, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_clone, enable);
e_widget_disabled_set(e_config_runtime_info->gui.widgets.policy.radio_none, enable);
if (!odd) return;
policy = (odd->new_policy != (Ecore_X_Randr_Output_Policy) Ecore_X_Randr_Unset) ? odd->new_policy : odd->previous_policy;
//toggle the switch of the currently used policies
switch (policy)
{
case ECORE_X_RANDR_OUTPUT_POLICY_ASK:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_ask, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_right, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_below, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_left, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_clone, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_none, EINA_TRUE);
break;
case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
e_widget_radio_toggle_set(e_config_runtime_info->gui.widgets.policy.radio_above, EINA_TRUE);
break;
default:
break;
}
}
void
policy_widget_keep_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it;
if (!E_RANDR_12 || !cfdata->output_dialog_data_list)
return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, it, odd)
{
odd->previous_policy = odd->new_policy;
odd->new_policy = Ecore_X_Randr_Unset;
}
}
void
policy_widget_discard_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it, *it2;
E_Randr_Output_Info *oi = NULL;
if (!E_RANDR_12 || !cfdata->output_dialog_data_list)
return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, it, odd)
{
if (odd->crtc)
{
EINA_LIST_FOREACH(odd->crtc->outputs, it2, oi)
{
oi->policy = odd->previous_policy;
fprintf(stderr, "CONF_RANDR: 'New display attached'-policy for output %d restored to %s.\n", oi->xid, _POLICIES_STRINGS[odd->previous_policy - 1]);
}
}
else if (odd->output)
{
odd->output->policy = odd->previous_policy;
fprintf(stderr, "CONF_RANDR: 'New display attached'-policy for output %d restored to %s.\n", odd->output->xid, _POLICIES_STRINGS[odd->previous_policy - 1]);
}
}
return;
}

View File

@ -1,292 +0,0 @@
#include "e_int_config_randr.h"
#include "e_randr.h"
#include "e_widget_ilist.h"
#ifdef Ecore_X_Randr_Unset
#undef Ecore_X_Randr_Unset
#define Ecore_X_Randr_Unset -1
#else
#define Ecore_X_Randr_Unset -1
#endif
#ifdef Ecore_X_Randr_None
#undef Ecore_X_Randr_None
#endif
#define Ecore_X_Randr_None 0
#define ICON_WIDTH 10
#define ICON_HEIGHT 10
#define RESOLUTION_TXT_MAX_LENGTH 50
extern E_Config_Dialog_Data *e_config_runtime_info;
static Ecore_X_Randr_Mode_Info disabled_mode = {.xid = Ecore_X_Randr_None, .name = "Disabled"};
static void _resolution_widget_selected_cb(void *data);
Eina_Bool
resolution_widget_create_data(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (odd->crtc)
{
odd->preferred_mode = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(odd->crtc->outputs_common_modes);
odd->previous_mode = odd->crtc->current_mode ? odd->crtc->current_mode : &disabled_mode;
}
else if (odd->output && odd->output->monitor)
{
odd->previous_mode = NULL;
odd->preferred_mode = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(odd->output->monitor->preferred_modes);
}
odd->new_mode = NULL;
}
return EINA_TRUE;
}
void
resolution_widget_free_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
{
}
Evas_Object *
resolution_widget_basic_create_widgets(Evas *canvas)
{
Evas_Object *widget;
if (e_config_runtime_info->gui.widgets.resolution.widget)
return e_config_runtime_info->gui.widgets.resolution.widget;
else if (!canvas || !e_config_runtime_info || !(widget = e_widget_ilist_add(canvas, ICON_WIDTH * e_scale, ICON_HEIGHT * e_scale, NULL)))
return NULL;
e_widget_ilist_multi_select_set(widget, EINA_FALSE);
e_widget_disabled_set(widget, EINA_TRUE);
evas_object_show(widget);
return widget;
}
Eina_Bool
resolution_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Ecore_X_Randr_Output *outputs = NULL;
E_Randr_Crtc_Info *crtc_info = NULL;
Eina_List *it, *it2;
int noutputs = Ecore_X_Randr_Unset;
Eina_Bool success = EINA_TRUE, another_one_enabled = EINA_FALSE;
//make sure at least one other output is not disabled
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if ((!odd->new_mode && odd->previous_mode && (odd->previous_mode != &disabled_mode)) || (odd->new_mode && (odd->new_mode != &disabled_mode)))
{
another_one_enabled = EINA_TRUE;
break;
}
}
if (!another_one_enabled)
{
e_util_dialog_show("Invalid configuration!", "At least one monitor has to remain enabled!");
fprintf(stderr, "CONF_RANDR: No other monitor is enabled, aborting reconfiguration.\n");
return EINA_FALSE;
}
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if (!odd || !odd->new_mode || (odd->new_mode == odd->previous_mode))
continue;
if (odd->crtc)
crtc_info = odd->crtc; //CRTC is already asssigned, easy one!
else if (odd->output)
{
//CRTC not assigned yet. Let's try to find a non occupied one.
fprintf(stderr, "CONF_RANDR: Trying to find a CRTC for output %d, %d crtcs are possible.\n", odd->output->xid, eina_list_count(odd->output->possible_crtcs));
outputs = &odd->output->xid;
noutputs = 1;
EINA_LIST_FOREACH(odd->output->possible_crtcs, it2, crtc_info)
{
if (crtc_info->outputs)
crtc_info = NULL; //CRTC is not occupied yet
else
break;
}
}
if (!crtc_info)
{
fprintf(stderr, "CONF_RANDR: Changing mode failed, no unoccupied CRTC found!\n");
success = EINA_FALSE;
continue;
}
if (odd->new_mode == crtc_info->current_mode)
{
if (odd->output && (eina_list_data_find(crtc_info->outputs, odd->output)))
fprintf(stderr, "CONF_RANDR: Nothing to be done for output %s.\n", odd->output->name);
fprintf(stderr, "CONF_RANDR: Resolution remains unchanged for CRTC %d.\n", crtc_info->xid);
continue;
}
fprintf(stderr, "CONF_RANDR: Changing mode of crtc %d to %d.\n", crtc_info->xid, odd->new_mode->xid);
if (ecore_x_randr_crtc_mode_set(cfd->con->manager->root, crtc_info->xid, outputs, noutputs, odd->new_mode->xid))
{
//update information
odd->crtc = crtc_info;
}
}
return success;
}
Eina_Bool
resolution_widget_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it;
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if (!odd || !odd->new_mode)
continue;
if (odd->new_mode != odd->previous_mode)
return EINA_TRUE;
}
return EINA_FALSE;
}
void
resolution_widget_update_list(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Eina_List *iter, *modelist = NULL;
Ecore_X_Randr_Mode_Info *mode_info, *current_mode = NULL;
char resolution_text[RESOLUTION_TXT_MAX_LENGTH];
float rate;
Eina_Bool enable = EINA_FALSE;
int i = 0;
e_widget_ilist_freeze(e_config_runtime_info->gui.widgets.resolution.widget);
e_widget_ilist_clear(e_config_runtime_info->gui.widgets.resolution.widget);
if (!odd)
goto _go_and_return;
//select correct mode list
if (odd->new_mode)
current_mode = odd->new_mode;
else if (odd->crtc)
{
if (!odd->crtc->current_mode)
current_mode = &disabled_mode;
else
current_mode = odd->crtc->current_mode;
}
if (odd->crtc)
modelist = odd->crtc->outputs_common_modes;
else if (odd->output && odd->output->monitor)
modelist = odd->output->monitor->modes;
if (!modelist)
goto _go_and_return;
EINA_LIST_FOREACH(modelist, iter, mode_info)
{
//calculate refresh rate
if (!mode_info) continue;
if (mode_info->hTotal && mode_info->vTotal)
rate = ((float)mode_info->dotClock /
((float)mode_info->hTotal * (float)mode_info->vTotal));
else
rate = 0.0;
if (mode_info->name)
snprintf(resolution_text, (RESOLUTION_TXT_MAX_LENGTH - 1), _("%s@%.1fHz"), mode_info->name, rate);
else
snprintf(resolution_text, (RESOLUTION_TXT_MAX_LENGTH - 1), _("%d×%d@%.1fHz"), mode_info->width, mode_info->height, rate);
e_widget_ilist_append(e_config_runtime_info->gui.widgets.resolution.widget, NULL, resolution_text, _resolution_widget_selected_cb, mode_info, NULL);
if (mode_info != current_mode)
i++;
else
e_widget_ilist_selected_set(e_config_runtime_info->gui.widgets.resolution.widget, i);
}
//append 'disabled' mode
e_widget_ilist_append(e_config_runtime_info->gui.widgets.resolution.widget, NULL, _("Disabled"), NULL, &disabled_mode, NULL);
if (current_mode == &disabled_mode) //select currently enabled mode
{
i = eina_list_count(modelist);
e_widget_ilist_selected_set(e_config_runtime_info->gui.widgets.resolution.widget, i);
}
//reenable widget
enable = EINA_TRUE;
_go_and_return:
e_widget_disabled_set(e_config_runtime_info->gui.widgets.resolution.widget, enable);
e_widget_ilist_go(e_config_runtime_info->gui.widgets.resolution.widget);
e_widget_ilist_thaw(e_config_runtime_info->gui.widgets.resolution.widget);
}
void
resolution_widget_keep_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd || !odd->new_mode || (odd->new_mode == odd->previous_mode))
continue;
odd->previous_mode = (odd->new_mode == &disabled_mode) ? NULL : odd->new_mode;
odd->new_mode = NULL;
}
}
void
resolution_widget_discard_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
//for now, there is no way to redisable an output during discartion
if (!odd->crtc || !odd->previous_mode) continue;
//use currently used outputs (noutputs == Ecore_X_Randr_Unset)
ecore_x_randr_crtc_mode_set(cfdata->manager->root, odd->crtc->xid, NULL, Ecore_X_Randr_Unset, odd->previous_mode->xid);
}
ecore_x_randr_screen_reset(cfdata->manager->root);
}
static void
_resolution_widget_selected_cb(void *data)
{
Ecore_X_Randr_Mode_Info *selected_mode = (Ecore_X_Randr_Mode_Info*)data;
if (!selected_mode)
return;
if (!e_config_runtime_info->gui.selected_output_dd)
{
fprintf(stderr, "CONF_RANDR: Can't set newly selected resolution, because no odd was set \"selected\" yet!\n");
return;
}
e_config_runtime_info->gui.selected_output_dd->new_mode = selected_mode;
fprintf(stderr, "CONF_RANDR: Mode %s was selected for crtc/output %d!\n", (selected_mode ? selected_mode->name : "None"), (e_config_runtime_info->gui.selected_output_dd->crtc ? e_config_runtime_info->gui.selected_output_dd->crtc->xid : e_config_runtime_info->gui.selected_output_dd->output->xid));
arrangement_widget_rep_update(e_config_runtime_info->gui.selected_output_dd);
}

View File

@ -1,66 +1,47 @@
/*
* vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
#include "e_mod_main.h"
#include "e_int_config_randr.h"
/* actual module specifics */
E_Module *conf_randr_module = NULL;
const char *mod_dir = NULL;
Config *randr_dialog_config = NULL;
static E_Config_DD *conf_edd = NULL;
/* module setup */
EAPI E_Module_Api e_modapi =
EAPI E_Module_Api e_modapi =
{
E_MODULE_API_VERSION,
"Settings - Screen Setup"
E_MODULE_API_VERSION, "Settings - Screen Setup"
};
EAPI void *
e_modapi_init(E_Module *m)
{
e_configure_registry_category_add("screen", 30, _("Screen"), NULL, "preferences-desktop-display");
e_configure_registry_item_add("screen/randr", 20, _("Screen Setup"), NULL, "preferences-system-screen-resolution", e_int_config_randr);
conf_randr_module = m;
e_configure_registry_category_add("screen", 30, _("Screen"),
NULL, "preferences-desktop-display");
e_configure_registry_item_add("screen/randr", 20, _("Screen Setup"), NULL,
"preferences-system-screen-resolution",
e_int_config_randr);
e_module_delayed_set(m, 1);
conf_edd = E_CONFIG_DD_NEW("RandRR_Dialog_Config", Config);
#undef T
#undef D
#define T Config
#define D conf_edd
E_CONFIG_VAL(D, T, display_disconnected_outputs, UCHAR);
#undef T
#undef D
randr_dialog_config = e_config_domain_load("module.conf_randr", conf_edd);
if (!randr_dialog_config)
{
randr_dialog_config = E_NEW(Config, 1);
randr_dialog_config->display_disconnected_outputs = EINA_FALSE;
}
mod_dir = eina_stringshare_add(m->dir);
return m;
}
EAPI int
EAPI int
e_modapi_shutdown(E_Module *m __UNUSED__)
{
E_Config_Dialog *cfd;
if (mod_dir) eina_stringshare_del(mod_dir);
mod_dir = NULL;
while ((cfd = e_config_dialog_get("E", "screen/randr")))
e_object_del(E_OBJECT(cfd));
e_configure_registry_item_del("screen/randr");
e_configure_registry_category_del("screen");
conf_randr_module = NULL;
return 1;
}
EAPI int
EAPI int
e_modapi_save(E_Module *m __UNUSED__)
{
e_config_domain_save("module.conf_randr", conf_edd, randr_dialog_config);
return 1;
}

View File

@ -1,20 +1,25 @@
/*
* vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
*/
#ifndef E_MOD_MAIN_H
#define E_MOD_MAIN_H
# define E_MOD_MAIN_H
#define E_TYPEDEFS 1
#include "e_int_config_randr.h"
#ifndef ECORE_X_RANDR_1_2
# define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
#endif
#undef E_TYPEDEFS
#include "e_int_config_randr.h"
#ifndef ECORE_X_RANDR_1_3
# define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
#endif
#ifndef E_RANDR_12
# define E_RANDR_12 (e_randr_screen_info.rrvd_info.randr_info_12)
#endif
EAPI extern E_Module_Api e_modapi;
EAPI void *e_modapi_init (E_Module *m);
EAPI int e_modapi_shutdown (E_Module *m);
EAPI int e_modapi_save (E_Module *m);
EAPI void *e_modapi_init(E_Module *m);
EAPI int e_modapi_shutdown(E_Module *m);
EAPI int e_modapi_save(E_Module *m);
extern const char *mod_dir;
/**
* @addtogroup Optional_Conf
@ -27,4 +32,5 @@ EAPI int e_modapi_save (E_Module *m);
*
* @}
*/
#endif

View File

@ -0,0 +1,839 @@
#include "e.h"
#include "e_mod_main.h"
#include "e_smart_monitor.h"
#define RESISTANCE_THRESHOLD 5
/* local structures */
typedef struct _E_Smart_Data E_Smart_Data;
struct _E_Smart_Data
{
/* object geometry */
Evas_Coord x, y, w, h;
/* visible flag */
Eina_Bool visible : 1;
/* changed flag */
Eina_Bool changed : 1;
/* resizing flag */
Eina_Bool resizing : 1;
/* snapped flag */
Eina_Bool snapped : 1;
/* rotating flag */
Eina_Bool rotating : 1;
/* layout object (this monitors parent) */
Evas_Object *o_layout;
/* base monitor object */
Evas_Object *o_base;
/* frame object */
Evas_Object *o_frame;
/* monitor stand object */
Evas_Object *o_stand;
/* livethumbnail for background image */
Evas_Object *o_thumb;
/* crtc information */
E_Randr_Crtc_Info *crtc;
/* list of event handlers */
Eina_List *hdls;
/* evas_maps for rotation */
Evas_Map *map[2];
/* container number (for bg preview) */
int con;
/* zone number (for bg preview) */
int zone;
/* list of available modes */
Eina_List *modes;
/* min & max resolution */
struct
{
int w, h;
} min, max;
};
/* local function prototypes */
static void _e_smart_add(Evas_Object *obj);
static void _e_smart_del(Evas_Object *obj);
static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
static void _e_smart_show(Evas_Object *obj);
static void _e_smart_hide(Evas_Object *obj);
static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
static void _e_smart_clip_unset(Evas_Object *obj);
static Eina_Bool _e_smart_cb_bg_update(void *data, int type __UNUSED__, void *event);
static void _e_smart_cb_resize_mouse_in(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_resize_mouse_out(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_resize_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_rotate_mouse_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_rotate_mouse_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_rotate_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_rotate_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
static void _e_smart_cb_frame_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event);
static int _e_smart_cb_modes_sort(const void *data1, const void *data2);
static void _e_smart_monitor_rotate(E_Smart_Data *sd, void *event);
static void _e_smart_monitor_resize(E_Smart_Data *sd, Evas_Object *mon, void *event);
static Ecore_X_Randr_Mode_Info *_e_smart_monitor_resolution_get(E_Smart_Data *sd, Evas_Coord width, Evas_Coord height, Eina_Bool smaller);
Evas_Object *
e_smart_monitor_add(Evas *evas)
{
static Evas_Smart *smart = NULL;
static const Evas_Smart_Class sc =
{
"smart_monitor", EVAS_SMART_CLASS_VERSION,
_e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize,
_e_smart_show, _e_smart_hide, NULL,
_e_smart_clip_set, _e_smart_clip_unset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
if (!smart)
if (!(smart = evas_smart_class_new(&sc)))
return NULL;
return evas_object_smart_add(evas, smart);
}
void
e_smart_monitor_layout_set(Evas_Object *obj, Evas_Object *layout)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
sd->o_layout = layout;
}
void
e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Info *crtc)
{
E_Smart_Data *sd;
Evas_Object *o;
const char *bg = NULL;
E_Container *con;
E_Desk *desk;
E_Zone *zone;
Evas_Coord w, h;
Eina_List *l;
E_Randr_Output_Info *output;
if (!(sd = evas_object_smart_data_get(obj)))
return;
sd->crtc = crtc;
if (!crtc) return;
EINA_LIST_FOREACH(crtc->outputs, l, output)
{
Eina_List *modes = NULL, *m = NULL;
Ecore_X_Randr_Mode_Info *mode = NULL;
E_Randr_Monitor_Info *monitor = NULL;
const char *name = NULL;
printf("Output: %d %s\n", output->xid, output->name);
if (output->crtc)
modes = output->crtc->outputs_common_modes;
else if (output->monitor)
modes = output->monitor->modes;
/* grab a copy of this monitor's modes,
* filtering out duplicate resolutions */
EINA_LIST_FOREACH(modes, m, mode)
{
Ecore_X_Randr_Mode_Info *nmode = NULL;
if ((nmode = eina_list_data_get(m->next)))
{
if (!strcmp(mode->name, nmode->name))
continue;
}
sd->modes = eina_list_append(sd->modes, mode);
}
/* sort the mode list */
sd->modes = eina_list_sort(sd->modes, 0, _e_smart_cb_modes_sort);
/* NB: This is just a development printf to list modes.
* Remove when dialog is complete */
EINA_LIST_FOREACH(sd->modes, m, mode)
{
double rate = 0.0;
if ((mode->hTotal) && (mode->vTotal))
rate = ((float)mode->dotClock /
((float)mode->hTotal * (float)mode->vTotal));
printf("\tMode: %d %dx%d @ %.1fHz\n", mode->xid,
mode->width, mode->height, rate);
}
/* get the min resolution for this monitor */
mode = eina_list_nth(sd->modes, 0);
sd->min.w = mode->width;
sd->min.h = mode->height;
/* get the max resolution for this monitor */
mode = eina_list_data_get(eina_list_last(sd->modes));
sd->max.w = mode->width;
sd->max.h = mode->height;
/* tell monitor object we are enabled/disabled */
if (output->connection_status ==
ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
edje_object_signal_emit(sd->o_base, "e,state,enabled", "e");
else
edje_object_signal_emit(sd->o_base, "e,state,disabled", "e");
/* get and display monitor name if available */
if ((monitor = output->monitor))
{
if (monitor->edid)
{
name =
ecore_x_randr_edid_display_name_get(monitor->edid,
monitor->edid_length);
}
}
if (!name) name = output->name;
edje_object_part_text_set(sd->o_frame, "e.text.name", name);
}
/* get which desk this is based on monitor geometry */
con = e_container_current_get(e_manager_current_get());
zone =
e_container_zone_at_point_get(con, crtc->geometry.x, crtc->geometry.y);
desk = e_desk_at_xy_get(zone, crtc->geometry.x, crtc->geometry.y);
if (!desk) desk = e_desk_current_get(zone);
sd->con = con->num;
sd->zone = zone->num;
/* get bg file for this screen */
bg = e_bg_file_get(con->num, zone->num, desk->x, desk->y);
w = zone->w;
h = (w * zone->h) / zone->w;
e_livethumb_vsize_set(sd->o_thumb, w, h);
o = e_livethumb_thumb_get(sd->o_thumb);
if (!o) o = edje_object_add(e_livethumb_evas_get(sd->o_thumb));
edje_object_file_set(o, bg, "e/desktop/background");
e_livethumb_thumb_set(sd->o_thumb, o);
}
E_Randr_Crtc_Info *
e_smart_monitor_crtc_get(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!obj) return NULL;
if (!(sd = evas_object_smart_data_get(obj)))
return NULL;
return sd->crtc;
}
void
e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if (x) *x = 0;
if (y) *y = 0;
if (w) *w = 0;
if (h) *h = 0;
if (!sd->crtc) return;
if (sd->crtc)
{
if (x) *x = sd->crtc->geometry.x;
if (y) *y = sd->crtc->geometry.y;
if (w) *w = sd->crtc->geometry.w;
if (h) *h = sd->crtc->geometry.h;
}
/* else */
/* { */
/* if (sd->crtc->monitor) */
/* { */
/* if (w) *w = sd->crtc->monitor->size_mm.width; */
/* if (h) *h = sd->crtc->monitor->size_mm.height; */
/* } */
/* } */
}
/* local functions */
static void
_e_smart_add(Evas_Object *obj)
{
E_Smart_Data *sd;
Evas *evas;
/* Evas_Object *o_resize; */
if (!(sd = calloc(1, sizeof(E_Smart_Data)))) return;
/* retrieve canvas once for reuse */
evas = evas_object_evas_get(obj);
/* create base object */
sd->o_base = edje_object_add(evas);
e_theme_edje_object_set(sd->o_base, "base/theme/widgets",
"e/conf/randr/main/monitor");
evas_object_smart_member_add(sd->o_base, obj);
/* create monitor frame with preview */
sd->o_frame = edje_object_add(evas);
e_theme_edje_object_set(sd->o_frame, "base/theme/widgets",
"e/conf/randr/main/frame");
edje_object_part_swallow(sd->o_base, "e.swallow.frame", sd->o_frame);
evas_object_smart_member_add(sd->o_frame, obj);
evas_object_event_callback_add(sd->o_frame, EVAS_CALLBACK_MOUSE_MOVE,
_e_smart_cb_frame_mouse_move, obj);
/* create bg preview */
sd->o_thumb = e_livethumb_add(evas);
edje_object_part_swallow(sd->o_frame, "e.swallow.preview", sd->o_thumb);
evas_object_smart_member_add(sd->o_thumb, obj);
evas_object_stack_below(sd->o_thumb, sd->o_frame);
/* create monitor stand */
sd->o_stand = edje_object_add(evas);
e_theme_edje_object_set(sd->o_stand, "base/theme/widgets",
"e/conf/randr/main/stand");
evas_object_smart_member_add(sd->o_stand, obj);
edje_object_part_swallow(sd->o_base, "e.swallow.stand", sd->o_stand);
evas_object_stack_below(sd->o_stand, sd->o_frame);
/* add callbacks for 'resize' edje signals */
edje_object_signal_callback_add(sd->o_frame, "e,action,resize,in", "e",
_e_smart_cb_resize_mouse_in, sd);
edje_object_signal_callback_add(sd->o_frame, "e,action,resize,out", "e",
_e_smart_cb_resize_mouse_out, sd);
edje_object_signal_callback_add(sd->o_frame, "e,action,resize,start", "e",
_e_smart_cb_resize_start, obj);
edje_object_signal_callback_add(sd->o_frame, "e,action,resize,stop", "e",
_e_smart_cb_resize_stop, obj);
/* add callbacks for 'rotate' edje signals */
edje_object_signal_callback_add(sd->o_frame, "e,action,rotate,in", "e",
_e_smart_cb_rotate_mouse_in, sd);
edje_object_signal_callback_add(sd->o_frame, "e,action,rotate,out", "e",
_e_smart_cb_rotate_mouse_out, sd);
edje_object_signal_callback_add(sd->o_frame, "e,action,rotate,start", "e",
_e_smart_cb_rotate_start, obj);
edje_object_signal_callback_add(sd->o_frame, "e,action,rotate,stop", "e",
_e_smart_cb_rotate_stop, obj);
/* create event handlers */
sd->hdls =
eina_list_append(sd->hdls,
ecore_event_handler_add(E_EVENT_BG_UPDATE,
_e_smart_cb_bg_update, sd));
evas_object_smart_data_set(obj, sd);
}
static void
_e_smart_del(Evas_Object *obj)
{
E_Smart_Data *sd;
Ecore_Event_Handler *hdl;
if (!(sd = evas_object_smart_data_get(obj)))
return;
/* delete callbacks for 'resize' edje signals */
edje_object_signal_callback_del(sd->o_frame, "e,action,resize,in", "e",
_e_smart_cb_resize_mouse_in);
edje_object_signal_callback_del(sd->o_frame, "e,action,resize,out", "e",
_e_smart_cb_resize_mouse_out);
edje_object_signal_callback_del(sd->o_frame, "e,action,resize,start", "e",
_e_smart_cb_resize_start);
edje_object_signal_callback_del(sd->o_frame, "e,action,resize,stop", "e",
_e_smart_cb_resize_stop);
/* delete callbacks for 'rotate' edje signals */
edje_object_signal_callback_del(sd->o_frame, "e,action,rotate,in", "e",
_e_smart_cb_rotate_mouse_in);
edje_object_signal_callback_del(sd->o_frame, "e,action,rotate,out", "e",
_e_smart_cb_rotate_mouse_out);
edje_object_signal_callback_del(sd->o_frame, "e,action,rotate,start", "e",
_e_smart_cb_rotate_start);
edje_object_signal_callback_del(sd->o_frame, "e,action,rotate,stop", "e",
_e_smart_cb_rotate_stop);
/* delete event handlers */
EINA_LIST_FREE(sd->hdls, hdl)
ecore_event_handler_del(hdl);
/* delete the list of modes */
if (sd->modes) eina_list_free(sd->modes);
/* delete the monitor objects */
if (sd->o_stand) evas_object_del(sd->o_stand);
if (sd->o_thumb) evas_object_del(sd->o_thumb);
if (sd->o_frame) evas_object_del(sd->o_frame);
if (sd->o_base) evas_object_del(sd->o_base);
E_FREE(sd);
evas_object_smart_data_set(obj, NULL);
}
static void
_e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if ((sd->x == x) && (sd->y == y)) return;
sd->x = x;
sd->y = y;
evas_object_move(sd->o_base, x, y);
}
static void
_e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if ((sd->w == w) && (sd->h == h)) return;
sd->w = w;
sd->h = h;
evas_object_resize(sd->o_base, w, h);
}
static void
_e_smart_show(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if (sd->visible) return;
evas_object_show(sd->o_base);
sd->visible = EINA_TRUE;
}
static void
_e_smart_hide(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if (!sd->visible) return;
evas_object_hide(sd->o_base);
sd->visible = EINA_FALSE;
}
static void
_e_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_clip_set(sd->o_thumb, clip);
evas_object_clip_set(sd->o_stand, clip);
evas_object_clip_set(sd->o_frame, clip);
evas_object_clip_set(sd->o_base, clip);
}
static void
_e_smart_clip_unset(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_clip_unset(sd->o_thumb);
evas_object_clip_unset(sd->o_stand);
evas_object_clip_unset(sd->o_frame);
evas_object_clip_unset(sd->o_base);
}
static Eina_Bool
_e_smart_cb_bg_update(void *data, int type, void *event)
{
E_Smart_Data *sd;
E_Event_Bg_Update *ev;
if (type != E_EVENT_BG_UPDATE) return ECORE_CALLBACK_PASS_ON;
if (!(sd = data)) return ECORE_CALLBACK_PASS_ON;
if (!sd->crtc) return ECORE_CALLBACK_PASS_ON;
ev = event;
if (((ev->container < 0) || (sd->con == ev->container)) &&
((ev->zone < 0) || (sd->zone == ev->zone)))
{
if (((ev->desk_x < 0) || (sd->crtc->geometry.x == ev->desk_x)) &&
((ev->desk_y < 0) || (sd->crtc->geometry.y == ev->desk_y)))
{
Evas_Object *o;
const char *bg = NULL;
/* background changed. grab new bg file and set thumbnail */
bg = e_bg_file_get(sd->con, sd->zone, ev->desk_x, ev->desk_y);
o = e_livethumb_thumb_get(sd->o_thumb);
if (!o) o = edje_object_add(e_livethumb_evas_get(sd->o_thumb));
edje_object_file_set(o, bg, "e/desktop/background");
e_livethumb_thumb_set(sd->o_thumb, o);
}
}
return ECORE_CALLBACK_PASS_ON;
}
static void
_e_smart_cb_resize_mouse_in(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Manager *man;
man = e_manager_current_get();
e_pointer_type_push(man->pointer, obj, "resize_br");
}
static void
_e_smart_cb_resize_mouse_out(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Manager *man;
man = e_manager_current_get();
e_pointer_type_pop(man->pointer, obj, "resize_br");
}
static void
_e_smart_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *mon;
E_Smart_Data *sd;
if (!(mon = data)) return;
if (!(sd = evas_object_smart_data_get(mon))) return;
sd->resizing = EINA_TRUE;
e_layout_child_raise(mon);
}
static void
_e_smart_cb_resize_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *mon;
E_Smart_Data *sd;
if (!(mon = data)) return;
if (!(sd = evas_object_smart_data_get(mon))) return;
sd->resizing = EINA_FALSE;
e_layout_child_lower(mon);
}
static void
_e_smart_cb_rotate_mouse_in(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Smart_Data *sd;
Ecore_Evas *ee;
Ecore_X_Window win;
Ecore_X_Cursor cur;
if (!(sd = data)) return;
/* changing cursors for rotate is done this way because e_pointer
* does not support all available X cursors */
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->o_frame));
win = (Ecore_X_Window)ecore_evas_window_get(ee);
cur = ecore_x_cursor_shape_get(ECORE_X_CURSOR_EXCHANGE);
ecore_x_window_cursor_set(win, cur);
ecore_x_cursor_free(cur);
}
static void
_e_smart_cb_rotate_mouse_out(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
E_Smart_Data *sd;
Ecore_Evas *ee;
Ecore_X_Window win;
if (!(sd = data)) return;
/* reset cursor back to default */
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->o_frame));
win = (Ecore_X_Window)ecore_evas_window_get(ee);
ecore_x_window_cursor_set(win, 0);
}
static void
_e_smart_cb_rotate_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *mon;
E_Smart_Data *sd;
if (!(mon = data)) return;
if (!(sd = evas_object_smart_data_get(mon))) return;
sd->rotating = EINA_TRUE;
e_layout_child_raise(mon);
/* NB: Dont' free these maps yet.
*
* They will be needed to handle Resize While Rotated */
/* create frame 'map' for rotation */
sd->map[0] = evas_map_new(4);
evas_map_smooth_set(sd->map[0], EINA_TRUE);
evas_map_alpha_set(sd->map[0], EINA_TRUE);
evas_map_util_points_populate_from_object(sd->map[0], sd->o_frame);
evas_object_map_set(sd->o_frame, sd->map[0]);
evas_object_map_enable_set(sd->o_frame, EINA_TRUE);
/* create livethumb 'map' for rotation */
sd->map[1] = evas_map_new(4);
evas_map_smooth_set(sd->map[1], EINA_TRUE);
evas_map_alpha_set(sd->map[1], EINA_TRUE);
evas_map_util_points_populate_from_object(sd->map[1], sd->o_thumb);
evas_object_map_set(sd->o_thumb, sd->map[1]);
evas_object_map_enable_set(sd->o_thumb, EINA_TRUE);
}
static void
_e_smart_cb_rotate_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
{
Evas_Object *mon;
E_Smart_Data *sd;
if (!(mon = data)) return;
if (!(sd = evas_object_smart_data_get(mon))) return;
sd->rotating = EINA_FALSE;
e_layout_child_lower(mon);
if (sd->map[0]) evas_map_free(sd->map[0]);
if (sd->map[1]) evas_map_free(sd->map[1]);
}
static void
_e_smart_cb_frame_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
{
Evas_Object *mon;
E_Smart_Data *sd;
if (!(mon = data)) return;
if (!(sd = evas_object_smart_data_get(mon))) return;
/* if we are not rotating or resizing, then we have nothing to do */
if ((!sd->rotating) && (!sd->resizing)) return;
if (sd->rotating)
_e_smart_monitor_rotate(sd, event);
else if (sd->resizing)
_e_smart_monitor_resize(sd, mon, event);
}
static int
_e_smart_cb_modes_sort(const void *data1, const void *data2)
{
const Ecore_X_Randr_Mode_Info *m1, *m2 = NULL;
if (!(m1 = data1)) return 1;
if (!(m2 = data2)) return -1;
/* second one compares to previous to determine position */
if (m2->width < m1->width) return 1;
if (m2->width > m1->width) return -1;
/* width are same, compare heights */
if ((m2->width == m1->width))
{
if (m2->height < m1->height) return 1;
if (m2->height > m1->height) return -1;
}
return 1;
}
static void
_e_smart_monitor_rotate(E_Smart_Data *sd, void *event)
{
Evas_Event_Mouse_Move *ev;
Evas_Coord mx;
Evas_Coord x, y, w, h;
const Evas_Map *m;
Evas_Map *m2;
ev = event;
mx = (ev->prev.output.x - ev->cur.output.x);
/* update map for frame object to reflect this rotation */
evas_object_geometry_get(sd->o_frame, &x, &y, &w, &h);
m = evas_object_map_get(sd->o_frame);
m2 = evas_map_dup(m);
evas_map_util_rotate(m2, mx, x + (w / 2), y + (h / 2));
evas_object_map_set(sd->o_frame, m2);
evas_map_free(m2);
/* update map for thumb object to reflect this rotation */
evas_object_geometry_get(sd->o_thumb, &x, &y, &w, &h);
m = evas_object_map_get(sd->o_thumb);
m2 = evas_map_dup(m);
evas_map_util_rotate(m2, mx, x + (w / 2), y + (h / 2));
evas_object_map_set(sd->o_thumb, m2);
evas_map_free(m2);
}
static void
_e_smart_monitor_resize(E_Smart_Data *sd, Evas_Object *mon, void *event)
{
Evas_Event_Mouse_Move *ev;
Evas_Coord w, h;
Evas_Coord mx, my;
Evas_Coord nrw, nrh;
ev = event;
/* FIXME: Ideally, this should use the evas_map to get geometry
* (for cases where the user has rotated the monitor and is now resizing) */
/* grab size of monitor object */
evas_object_geometry_get(mon, NULL, NULL, &w, &h);
/* calculate resize difference */
mx = (ev->cur.output.x - ev->prev.output.x);
my = (ev->cur.output.y - ev->prev.output.y);
/* printf("Resize Difference: %d %d\n", mx, my); */
/* determine what resolution this geometry would be */
e_layout_coord_canvas_to_virtual(sd->o_layout,
(w + mx), (h + my), &nrw, &nrh);
printf("\nNew Resolution: %d %d\n", nrw, nrh);
/* determine if this new size is below or above the
* available resolutions and stop resizing if so */
/* compare new size vs smallest size */
if ((nrw < sd->min.w) || (nrh < sd->min.h)) return;
/* compare new size vs largest size */
if ((nrw > sd->max.w) || (nrh > sd->max.h)) return;
/* if we are snapped to a resolution, provide some resistance to resize */
if (sd->snapped)
{
/* if the difference in movement is less than the
* threshold then we should not resize as we are 'snapped' and
* should provide the 'feel' of resistance */
if ((mx < RESISTANCE_THRESHOLD) || (my < RESISTANCE_THRESHOLD))
return;
else
{
/* movement is greater than the 'snap' threshold, so we should
* unsnap and allow resize */
sd->snapped = EINA_FALSE;
}
}
/* graphically resize the monitor */
evas_object_resize(mon, w + mx, h + my);
/* tell randr widget we resized this monitor so that it can
* update the layout for any monitors around this one */
evas_object_smart_callback_call(mon, "monitor_resized", NULL);
/* if we are not snapped yet, then let's see if there is a resolution
* within the threshold that we can snap to */
if (!sd->snapped)
{
/* if we are resizing smaller, find a resolution below */
if ((mx < 0) || (my < 0))
{
Ecore_X_Randr_Mode_Info *mode;
printf("Resizing Smaller\n");
if ((mode =
_e_smart_monitor_resolution_get(sd, nrw, nrh, EINA_TRUE)))
{
printf("\tFound Mode: %d %d\n", mode->width, mode->height);
}
else
printf("\tNO MODE FOUND\n");
}
/* if we are resizing larger, find a resolution greater */
else if ((mx > 0) || (my > 0))
{
Ecore_X_Randr_Mode_Info *mode;
printf("Resizing Larger\n");
if ((mode =
_e_smart_monitor_resolution_get(sd, nrw, nrh, EINA_FALSE)))
{
printf("\tFound Mode: %d %d\n", mode->width, mode->height);
}
else
printf("\tNO MODE FOUND\n");
}
}
}
static Ecore_X_Randr_Mode_Info *
_e_smart_monitor_resolution_get(E_Smart_Data *sd, Evas_Coord width, Evas_Coord height, Eina_Bool smaller)
{
Ecore_X_Randr_Mode_Info *mode;
Eina_List *l;
if (!sd) return NULL;
EINA_LIST_REVERSE_FOREACH(sd->modes, l, mode)
{
/* FIXME: These comparisons may need some 'fuzzy'-ness:
*
* That is to say, the width & height checks should probably not
* search for <=>, but rather "is the width/height Within 5/10 pixels"
* of the requested size */
if (smaller)
{
if (((int)mode->width < width) && ((int)mode->height < height))
return mode;
}
else
{
if (((int)mode->width > width) && ((int)mode->height > height))
return mode;
}
}
return NULL;
}

View File

@ -0,0 +1,13 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_SMART_MONITOR_H
Evas_Object *e_smart_monitor_add(Evas *evas);
void e_smart_monitor_layout_set(Evas_Object *obj, Evas_Object *layout);
void e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Info *crtc);
E_Randr_Crtc_Info *e_smart_monitor_crtc_get(Evas_Object *obj);
void e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
# define E_SMART_MONITOR_H
# endif
#endif

View File

@ -0,0 +1,307 @@
#include "e.h"
#include "e_mod_main.h"
#include "e_smart_randr.h"
#include "e_smart_monitor.h"
/* 'Smart' widget to wrap a pan and scroll into one */
typedef struct _E_Smart_Data E_Smart_Data;
struct _E_Smart_Data
{
/* visible flag */
Eina_Bool visible : 1;
/* objects in this widget */
Evas_Object *o_scroll, *o_layout;
/* list of monitors */
Eina_List *items;
};
/* local function prototypes */
static void _e_smart_add(Evas_Object *obj);
static void _e_smart_del(Evas_Object *obj);
static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
static void _e_smart_show(Evas_Object *obj);
static void _e_smart_hide(Evas_Object *obj);
static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
static void _e_smart_clip_unset(Evas_Object *obj);
static void _e_smart_reconfigure(E_Smart_Data *sd);
static void _e_smart_cb_monitor_resized(void *data, Evas_Object *obj, void *event __UNUSED__);
/* public functions */
Evas_Object *
e_smart_randr_add(Evas *evas)
{
static Evas_Smart *smart = NULL;
static const Evas_Smart_Class sc =
{
"smart_randr", EVAS_SMART_CLASS_VERSION,
_e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize,
_e_smart_show, _e_smart_hide, NULL,
_e_smart_clip_set, _e_smart_clip_unset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
if (!smart)
if (!(smart = evas_smart_class_new(&sc)))
return NULL;
return evas_object_smart_add(evas, smart);
}
void
e_smart_randr_virtual_size_set(Evas_Object *obj, Evas_Coord vw, Evas_Coord vh)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
/* set virutal size for layout */
e_layout_virtual_size_set(sd->o_layout, vw, vh);
}
void
e_smart_randr_monitor_add(Evas_Object *obj, Evas_Object *mon)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
/* tell monitor what layout it is in */
e_smart_monitor_layout_set(mon, sd->o_layout);
/* add listeners for when this monitor changes */
evas_object_smart_callback_add(mon, "monitor_resized",
_e_smart_cb_monitor_resized, sd);
/* pack this monitor into the layout */
e_layout_pack(sd->o_layout, mon);
e_layout_child_lower(mon);
/* append this monitor to our list */
sd->items = eina_list_append(sd->items, mon);
/* reconfigure the layout */
_e_smart_reconfigure(sd);
}
/* local functions */
static void
_e_smart_add(Evas_Object *obj)
{
E_Smart_Data *sd;
Evas *evas;
if (!(sd = calloc(1, sizeof(E_Smart_Data))))
return;
evas = evas_object_evas_get(obj);
/* add layout object */
sd->o_layout = e_layout_add(evas);
evas_object_resize(sd->o_layout,
E_RANDR_12->max_size.width / 8,
E_RANDR_12->max_size.height / 8);
evas_object_smart_member_add(sd->o_layout, obj);
/* add scroll object */
sd->o_scroll = e_scrollframe_add(evas);
/* e_scrollframe_custom_theme_set(sd->o_scroll, "base/theme/widgets", */
/* "e/conf/randr/main/scrollframe"); */
e_scrollframe_child_set(sd->o_scroll, sd->o_layout);
evas_object_smart_member_add(sd->o_scroll, obj);
evas_object_smart_data_set(obj, sd);
}
static void
_e_smart_del(Evas_Object *obj)
{
E_Smart_Data *sd;
Evas_Object *mon;
if (!(sd = evas_object_smart_data_get(obj)))
return;
/* delete the monitors */
EINA_LIST_FREE(sd->items, mon)
evas_object_del(mon);
/* delete objects */
evas_object_del(sd->o_layout);
evas_object_del(sd->o_scroll);
E_FREE(sd);
evas_object_smart_data_set(obj, NULL);
}
static void
_e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_move(sd->o_scroll, x, y);
_e_smart_reconfigure(sd);
}
static void
_e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_resize(sd->o_scroll, w, h);
_e_smart_reconfigure(sd);
}
static void
_e_smart_show(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if (sd->visible) return;
evas_object_show(sd->o_scroll);
sd->visible = EINA_TRUE;
}
static void
_e_smart_hide(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
if (!sd->visible) return;
evas_object_hide(sd->o_scroll);
sd->visible = EINA_FALSE;
}
static void
_e_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_clip_set(sd->o_scroll, clip);
}
static void
_e_smart_clip_unset(Evas_Object *obj)
{
E_Smart_Data *sd;
if (!(sd = evas_object_smart_data_get(obj)))
return;
evas_object_clip_unset(sd->o_scroll);
}
static void
_e_smart_reconfigure(E_Smart_Data *sd)
{
Eina_List *l;
Evas_Object *mon;
e_layout_freeze(sd->o_layout);
EINA_LIST_FOREACH(sd->items, l, mon)
{
Evas_Coord cx, cy, cw, ch;
e_smart_monitor_crtc_geometry_get(mon, &cx, &cy, &cw, &ch);
e_layout_child_move(mon, cx, cy);
e_layout_child_resize(mon, cw, ch);
e_layout_child_lower(mon);
}
e_layout_thaw(sd->o_layout);
}
/* callback received from the monitor object to let us know that it was
* resized, and we should adjust position of any adjacent monitors */
static void
_e_smart_cb_monitor_resized(void *data, Evas_Object *obj, void *event __UNUSED__)
{
E_Smart_Data *sd;
Evas_Coord w, h, nw, nh;
Eina_List *l;
/* E_Randr_Crtc_Info *crtc; */
if (!(sd = data)) return;
/* get randr output info for this monitor */
/* crtc = e_smart_monitor_crtc_get(obj); */
/* printf("Monitor Output Policy: %d\n", crtc->policy); */
/* grab size of this monitor object */
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
/* convert to layout coords */
e_layout_coord_canvas_to_virtual(sd->o_layout, w, h, &nw, &nh);
/* freeze layout */
e_layout_freeze(sd->o_layout);
/* search for this monitor */
// if ((l = eina_list_data_find_list(sd->items, obj)))
{
Evas_Object *mon;
Evas_Coord mx, my;
Eina_Rectangle rm;
e_layout_child_geometry_get(obj, &mx, &my, NULL, NULL);
/* printf("Monitor New Geom: %d %d %d %d\n", mx, my, nw, nh); */
EINA_RECTANGLE_SET(&rm, mx, my, nw, nh);
/* found monitor, check for one the will intersect */
EINA_LIST_FOREACH(sd->items, l, mon)
{
/* E_Randr_Crtc_Info *cinfo; */
Evas_Coord cx, cy, cw, ch;
Eina_Rectangle rc;
if ((mon == obj)) continue;
/* cinfo = e_smart_monitor_crtc_get(mon); */
/* printf("\tChild Policy: %d\n", cinfo->policy); */
e_layout_child_geometry_get(mon, &cx, &cy, &cw, &ch);
/* printf("\tNext Mon Geom: %d %d %d %d\n", cx, cy, cw, ch); */
EINA_RECTANGLE_SET(&rc, cx, cy, cw, ch);
if (eina_rectangles_intersect(&rm, &rc))
{
printf("\nMONITORS INTERSECT !!\n");
/* if position of new monitor overlaps the existing one's
* X position, we need to move the existing one over */
if ((mx + nw) >= cx)
cx = (mx + nw);
else if ((my + nh) >= cy)
cy = (my + nh);
/* update This monitors position based on new size
* of the previous one (that was resized) */
/* e_layout_child_geometry_get(mon, &cx, &cy, NULL, NULL); */
e_layout_child_move(mon, cx, cy);
}
}
}
/* thaw layout to allow redraw */
e_layout_thaw(sd->o_layout);
}

View File

@ -0,0 +1,11 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_SMART_RANDR_H
# define E_SMART_RANDR_H
Evas_Object *e_smart_randr_add(Evas *evas);
void e_smart_randr_virtual_size_set(Evas_Object *obj, Evas_Coord vw, Evas_Coord vh);
void e_smart_randr_monitor_add(Evas_Object *obj, Evas_Object *mon);
# endif
#endif

View File

@ -9,7 +9,7 @@ Name[fr]=Affichage
Name[hu]=Beállítások - Képernyő felbontása
Name[it]=Monitor
Name[ja]=
Name[pt]=Resolução de ecrã
Name[pt]=
Name[pt_BR]=
Name[tr]=Ayarlar - Ekran Çözünürlüğü
Name[zh_CN]=
@ -24,7 +24,7 @@ Comment[fr]=Pour configurer l'affichage des écrans.
Comment[hu]=Segítségével beállíthatod a képernyőd felbontását.
Comment[it]=Usato per configurare la risoluzione del vostro schermo.
Comment[ja]=
Comment[pt]=Configurar resolução do ecrã
Comment[pt]=
Comment[pt_BR]=
Comment[tr]=Ekranınızın çözünürlüğünü yapılandırır.
Comment[zh_CN]=