e - rewrite randr code entirely. core and dialog. dialog is basic atm

the dialog for now is simple and lets you just raw edit the properties
per screen in a dialog. nothing fancy. not user firendly. but it works.

the randr core has been totally rewritten and tested against a range
of drivers and setups before even getting a commit. it works solidly
and configures screens reliably now. drivers tested:

nvidia
intel
radeon

some drivers still are unreliable in terms of delivering plug/unplug
events for outputs (both intel and radeon are flakey - nvidia is solid
and reliable). so to fix this there is now a screen redo action you
can bind to a hotkey or something and have e re-evaluate current
screen setup and apply ny pending config if needed.

also to make reconfiguring prettier the screen is faded to black
first, then configured, then faded back in. some drivers work
flawlessly with this, others still flicker some garbage.

i admit - i haven't tested nouveau, but my general take on this is the
randr code is now in far better shape than where it was (minus pretty
and easy dialog). the dialog can be done next, but i'd like to get the
core in now for more testing.

@fix
This commit is contained in:
Carsten Haitzler 2015-01-25 22:43:33 +09:00
parent ab975cc349
commit 33d4531f1d
14 changed files with 2541 additions and 61 deletions

View File

@ -138,7 +138,7 @@ src/bin/e_place.h \
src/bin/e_pointer.h \
src/bin/e_powersave.h \
src/bin/e_prefix.h \
src/bin/e_randr.h \
src/bin/e_randr2.h \
src/bin/e_remember.h \
src/bin/e_resist.h \
src/bin/e_scale.h \
@ -364,7 +364,7 @@ $(ENLIGHTENMENTHEADERS)
if ! HAVE_WAYLAND_ONLY
enlightenment_src += \
src/bin/e_comp_x.c \
src/bin/e_randr.c \
src/bin/e_randr2.c \
src/bin/e_xsettings.c
endif

View File

@ -2899,6 +2899,13 @@ ACT_FN_GO(module_toggle, )
else e_module_enable(m);
}
ACT_FN_GO(screen_redo, __UNUSED__)
{
printf("REDOOOOOOOOOOOOOOOOOOOOOOOOOOO\n");
e_randr2_screeninfo_update();
e_randr2_config_apply();
}
/* local subsystem globals */
static Eina_Hash *actions = NULL;
static Eina_List *action_list = NULL;
@ -3240,6 +3247,12 @@ e_actions_init(void)
e_action_predef_name_set(N_("Screen"), N_("Backlight Down"), "backlight_adjust",
"-10", NULL, 0);
/* screen setup */
ACT_GO(screen_redo);
e_action_predef_name_set(N_("Screen"),
N_("Update and re-apply screen setup"),
"screen_redo", NULL, NULL, 0);
/* window_move_to_center */
ACT_GO(window_move_to_center);
e_action_predef_name_set(N_("Window : Actions"), N_("Move To Center"),
@ -3426,6 +3439,7 @@ e_actions_init(void)
e_action_predef_name_set(N_("Keyboard Layouts"),
N_("Previous keyboard layout"), "kbd_layout_prev",
NULL, NULL, 0);
return 1;
}

View File

@ -657,7 +657,7 @@ static void
_e_comp_object_setup(E_Comp_Object *cw)
{
cw->clip = evas_object_rectangle_add(cw->comp->evas);
evas_object_resize(cw->clip, cw->comp->man->w, cw->comp->man->h);
evas_object_resize(cw->clip, 999999, 999999);
evas_object_smart_member_add(cw->clip, cw->smart_obj);
cw->effect_obj = edje_object_add(cw->comp->evas);
evas_object_move(cw->effect_obj, cw->x, cw->y);

View File

@ -1334,7 +1334,8 @@ _e_comp_x_configure(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_
c = e_comp_find_by_window(ev->win);
if (c)
{
e_manager_resize(c->man, ev->w, ev->h);
// do not handle this here - use randr events
//e_manager_resize(c->man, ev->w, ev->h);
return ECORE_CALLBACK_RENEW;
}
ec = _e_comp_x_client_find_by_window(ev->win);
@ -4565,14 +4566,32 @@ _e_comp_x_pre_swap(void *data, Evas *e EINA_UNUSED)
static Eina_Bool
_e_comp_x_xinerama_setup(int rw, int rh)
{
int n, i;
int i;
E_Screen *screen;
Eina_List *all_screens = NULL;
Eina_List *l;
E_Randr2_Screen *s;
/* first (and only) root window */
/* get number of xinerama screens */
n = ecore_x_xinerama_screen_count_get();
if (n < 2)
i = 0;
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
if ((s->config.enabled) &&
(s->config.geom.w > 0) &&
(s->config.geom.h > 0))
{
screen = E_NEW(E_Screen, 1);
screen->escreen = screen->screen = i;
screen->x = s->config.geom.x;
screen->y = s->config.geom.y;
screen->w = s->config.geom.w;
screen->h = s->config.geom.h;
all_screens = eina_list_append(all_screens, screen);
INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i",
i, i, screen->w, screen->h, screen->x, screen->y);
i++;
}
}
if (i == 0)
{
screen = E_NEW(E_Screen, 1);
screen->escreen = screen->screen = 0;
@ -4582,32 +4601,35 @@ _e_comp_x_xinerama_setup(int rw, int rh)
screen->h = rh;
all_screens = eina_list_append(all_screens, screen);
}
else
{
for (i = 0; i < n; i++)
{
int x, y, w, h;
/* get each xinerama screen geometry */
if (ecore_x_xinerama_screen_geometry_get(i, &x, &y, &w, &h))
{
INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i",
i, i, w, h, x, y);
/* add it to our list */
screen = E_NEW(E_Screen, 1);
screen->escreen = screen->screen = i;
screen->x = x;
screen->y = y;
screen->w = w;
screen->h = h;
all_screens = eina_list_append(all_screens, screen);
}
}
}
e_xinerama_screens_set(all_screens);
return EINA_TRUE;
}
static Eina_Bool
_e_comp_x_randr_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event_info EINA_UNUSED)
{
if ((e_comp->man->w != e_randr2->w) ||
(e_comp->man->h != e_randr2->h))
{
e_manager_resize(e_comp->man, e_randr2->w, e_randr2->h);
}
else
{
E_Client *ec;
ecore_x_netwm_desk_size_set(e_comp->man->root, e_comp->man->w, e_comp->man->h);
_e_comp_x_xinerama_setup(e_comp->man->w, e_comp->man->h);
e_comp_canvas_update();
E_CLIENT_FOREACH(e_comp, ec)
{
if (!e_client_util_ignored_get(ec))
_e_comp_x_client_zone_geometry_set(ec);
}
}
return ECORE_CALLBACK_RENEW;
}
static void
_e_comp_x_ee_resize(Ecore_Evas *ee EINA_UNUSED)
{
@ -5251,7 +5273,10 @@ e_comp_x_init(void)
e_desklock_show_hook_add(_e_comp_x_desklock_show);
e_desklock_hide_hook_add(_e_comp_x_desklock_hide);
if (!e_randr_init()) return 0;
if (!e_randr2_init()) return 0;
E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE, _e_comp_x_randr_change, NULL);
if (!e_atoms_init()) return 0;
if (!_e_comp_x_screens_setup()) return EINA_FALSE;
if (!e_xsettings_init())
@ -5274,7 +5299,7 @@ e_comp_x_shutdown(void)
ecore_x_screensaver_custom_blanking_disable();
if (x_fatal) return;
e_atoms_shutdown();
e_randr_shutdown();
e_randr2_shutdown();
/* ecore_x_ungrab(); */
ecore_x_focus_reset();
ecore_x_events_allow_all();

View File

@ -10,7 +10,7 @@
#include "e_auth.h"
#ifdef NEED_X
# include "e_comp_x.h"
# include "e_randr.h"
# include "e_randr2.h"
#endif
#include "e_pixmap.h"
#include "e_comp_object.h"

View File

@ -64,7 +64,6 @@ e_init_show(void)
evas_object_name_set(o, "_e_init_extra_screen");
}
evas_object_clip_set(o, zone->bg_clip_object);
fprintf(stderr, "zone %p: %i %i %ix%i\n", zone, zone->x, zone->y, zone->w, zone->h);
evas_object_move(o, zone->x, zone->y);
evas_object_resize(o, zone->w, zone->h);
evas_object_layer_set(o, E_LAYER_MAX);

1581
src/bin/e_randr2.c Normal file

File diff suppressed because it is too large Load Diff

121
src/bin/e_randr2.h Normal file
View File

@ -0,0 +1,121 @@
#ifdef E_TYPEDEFS
typedef struct _E_Randr2 E_Randr2;
typedef struct _E_Randr2_Screen E_Randr2_Screen;
typedef struct _E_Randr2_Mode E_Randr2_Mode;
typedef struct _E_Config_Randr2 E_Config_Randr2;
typedef struct _E_Config_Randr2_Screen E_Config_Randr2_Screen;
#else
#ifndef E_RANDR2_H
#define E_RAND2R_H
#define E_RANDR_VERSION_1_1 ((1 << 16) | 1)
#define E_RANDR_VERSION_1_2 ((1 << 16) | 2)
#define E_RANDR_VERSION_1_3 ((1 << 16) | 3)
#define E_RANDR_VERSION_1_4 ((1 << 16) | 4)
typedef enum _E_Randr2_Relative
{
E_RANDR2_RELATIVE_UNKNOWN,
E_RANDR2_RELATIVE_NONE,
E_RANDR2_RELATIVE_CLONE,
E_RANDR2_RELATIVE_TO_LEFT,
E_RANDR2_RELATIVE_TO_RIGHT,
E_RANDR2_RELATIVE_TO_ABOVE,
E_RANDR2_RELATIVE_TO_BELOW
} E_Randr2_Relative;
typedef enum _E_Randr2_Connector
{
E_RANDR2_CONNECTOR_UNDEFINED,
E_RANDR2_CONNECTOR_DVI,
E_RANDR2_CONNECTOR_HDMI_A,
E_RANDR2_CONNECTOR_HDMI_B,
E_RANDR2_CONNECTOR_MDDI,
E_RANDR2_CONNECTOR_DISPLAY_PORT
} E_Randr2_Connector;
struct _E_Randr2
{
Eina_List *screens; // available screens
int w, h; // virtual resolution needed for screens (calculated)
};
struct _E_Randr2_Mode
{
int w, h; // resolution width and height
double refresh; // refresh in hz
Eina_Bool preferred : 1; // is this the preferred mode for the device?
};
struct _E_Randr2_Screen
{
char *id; // string id which is "name/edid";
struct {
char *screen; // name of the screen device attached
char *name; // name of the output itself
char *edid; // full edid data
E_Randr2_Connector connector; // the connector type
Eina_Bool is_lid : 1; // is an internal screen
Eina_Bool connected : 1; // some screen is plugged in or not
Eina_Bool backlight : 1; // does it have backlight controls?
Eina_Bool can_rot_0 : 1; // can it do this rotation?
Eina_Bool can_rot_90 : 1; // can it do this rotation?
Eina_Bool can_rot_180 : 1; // can it do this rotation?
Eina_Bool can_rot_270 : 1; // can it do this rotation?
Eina_List *modes; // available screen modes here
struct {
int w, h; // physical width and height in mm
} size;
} info;
struct {
struct {
E_Randr2_Relative mode; // what relative mode to the screen below
char *to; // what screen this one is relative to
double align; // alignment along the edge
} relative;
Eina_Rectangle geom; // the geometry that is set (as a result)
E_Randr2_Mode mode; // screen res/refresh to use
int rotation; // 0, 90, 180, 270
int priority; // larger num == more important
Eina_Bool enabled : 1; // should this monitor be enabled?
Eina_Bool configured : 1; // has screen been configured by e?
} config;
};
struct _E_Config_Randr2
{
int version;
Eina_List *screens;
unsigned char restore;
};
struct _E_Config_Randr2_Screen
{
const char *id;
const char *rel_to;
double rel_align;
double mode_refresh;
int mode_w;
int mode_h;
int rotation;
int priority;
unsigned char rel_mode;
unsigned char enabled;
};
extern EAPI E_Config_Randr2 *e_randr2_cfg;
extern EAPI E_Randr2 *e_randr2;
extern EAPI int E_EVENT_RANDR_CHANGE;
EINTERN Eina_Bool e_randr2_init(void);
EINTERN int e_randr2_shutdown(void);
EAPI Eina_Bool e_randr2_config_save(void);
EAPI void e_randr2_config_apply(void);
EAPI void e_randr2_screeninfo_update(void);
#endif
#endif

View File

@ -132,6 +132,7 @@ _e_xinerama_update(void)
INF("======================= screens:");
EINA_LIST_FOREACH(chosen_screens, l, scr)
{
scr->screen = n;
scr->escreen = n;
INF("E INIT: XINERAMA CHOSEN: [%i][%i], %ix%i+%i+%i",
scr->screen, scr->escreen, scr->w, scr->h, scr->x, scr->y);

View File

@ -14,12 +14,8 @@ src_modules_conf_randr_module_la_CPPFLAGS = $(MOD_CPPFLAGS) -DNEED_X=1
src_modules_conf_randr_module_la_LDFLAGS = $(MOD_LDFLAGS)
src_modules_conf_randr_module_la_SOURCES = src/modules/conf_randr/e_mod_main.c \
src/modules/conf_randr/e_mod_main.h \
src/modules/conf_randr/e_int_config_randr.c \
src/modules/conf_randr/e_int_config_randr.h \
src/modules/conf_randr/e_smart_randr.c \
src/modules/conf_randr/e_smart_randr.h \
src/modules/conf_randr/e_smart_monitor.c \
src/modules/conf_randr/e_smart_monitor.h
src/modules/conf_randr/e_int_config_randr2.c \
src/modules/conf_randr/e_int_config_randr2.h
PHONIES += conf_randr install-conf_randr
conf_randr: $(conf_randrpkg_LTLIBRARIES) $(conf_randr_DATA)

View File

@ -0,0 +1,744 @@
#include "e.h"
#include "e_mod_main.h"
#include "e_int_config_randr2.h"
/* local structures */
struct _E_Config_Dialog_Data
{
E_Config_Dialog *cfd;
Eina_List *screen_items;
Eina_List *screen_items2;
Eina_List *screens;
Eina_List *freelist;
Evas_Object *name_obj;
Evas_Object *screen_obj;
Evas_Object *lid_obj;
Evas_Object *backlight_obj;
Evas_Object *size_obj;
Evas_Object *modes_obj;
Evas_Object *rotations_obj;
Evas_Object *enabled_obj;
Evas_Object *priority_obj;
Evas_Object *rel_mode_obj;
Evas_Object *rel_to_obj;
Evas_Object *rel_align_obj;
int restore;
int screen;
};
typedef struct
{
E_Config_Dialog_Data *cfdata;
E_Randr2_Mode mode;
} Mode_CBData;
typedef struct
{
E_Config_Dialog_Data *cfdata;
int rot;
} Rot_CBData;
/* local function prototypes */
static void *_create_data(E_Config_Dialog *cfd);
static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
static int _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
static int _basic_check(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
/* public functions */
E_Config_Dialog *
e_int_config_randr2(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED)
{
E_Config_Dialog *cfd;
E_Config_Dialog_View *v;
if (e_config_dialog_find("E", "screen/screen_setup")) return NULL;
if (!(v = E_NEW(E_Config_Dialog_View, 1))) return NULL;
/* set dialog view functions & properties */
v->create_cfdata = _create_data;
v->free_cfdata = _free_data;
v->basic.create_widgets = _basic_create;
v->basic.apply_cfdata = _basic_apply;
v->basic.check_changed = _basic_check;
v->override_auto_apply = EINA_TRUE;
/* create new dialog */
cfd = e_config_dialog_new(NULL, _("Screen Setup"),
"E", "screen/screen_setup",
"preferences-system-screen-resolution",
0, v, NULL);
return cfd;
}
/* local functions */
static void *
_create_data(E_Config_Dialog *cfd EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata;
if (!(cfdata = E_NEW(E_Config_Dialog_Data, 1))) return NULL;
cfdata->restore = e_randr2_cfg->restore;
return cfdata;
}
static void
_free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
void *dt;
E_Config_Randr2_Screen *cs;
EINA_LIST_FREE(cfdata->screens, cs)
{
eina_stringshare_del(cs->id);
eina_stringshare_del(cs->rel_to);
free(cs);
}
eina_list_free(cfdata->screen_items);
eina_list_free(cfdata->screen_items2);
EINA_LIST_FREE(cfdata->freelist, dt) free(dt);
E_FREE(cfdata);
}
static void
_cb_restore_changed(void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
cfdata->restore = elm_check_state_get(obj);
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static E_Config_Randr2_Screen *
_config_screen_find(E_Config_Dialog_Data *cfdata)
{
return eina_list_nth(cfdata->screens, cfdata->screen);
}
static E_Config_Randr2_Screen *
_config_screen_n_find(E_Config_Dialog_Data *cfdata, int n)
{
return eina_list_nth(cfdata->screens, n);
}
static E_Randr2_Screen *
_screen_config_find(E_Config_Randr2_Screen *cs)
{
Eina_List *l;
E_Randr2_Screen *s;
if (!cs->id) return NULL;
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
if (!s->id) continue;
if (!strcmp(cs->id, s->id)) return s;
}
return NULL;
}
static E_Randr2_Screen *
_screen_config_id_find(const char *id)
{
Eina_List *l;
E_Randr2_Screen *s;
if (!id) return NULL;
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
if (!s->id) continue;
if (!strcmp(s->id, id)) return s;
}
return NULL;
}
static E_Config_Randr2_Screen *
_screen_config_randr_id_find(const char *id)
{
Eina_List *l;
E_Config_Randr2_Screen *cs;
if (!id) return NULL;
EINA_LIST_FOREACH(e_randr2_cfg->screens, l, cs)
{
if (!cs->id) continue;
if (!strcmp(cs->id, id)) return cs;
}
return NULL;
}
static void
_cb_mode_set(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Mode_CBData *dat = data;
E_Config_Dialog_Data *cfdata = dat->cfdata;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->mode_w = dat->mode.w;
cs->mode_h = dat->mode.h;
cs->mode_refresh = dat->mode.refresh;
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rot_set(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Rot_CBData *dat = data;
E_Config_Dialog_Data *cfdata = dat->cfdata;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rotation = dat->rot;
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_basic_screen_info_fill(E_Config_Dialog_Data *cfdata, E_Config_Randr2_Screen *cs, E_Randr2_Screen *s)
{
char buf[100];
Eina_List *l;
E_Randr2_Mode *m;
Elm_Object_Item *it, *it_sel;
void *dt;
if (!s) return;
// fill all the screen status info
elm_object_text_set(cfdata->name_obj, s->info.name);
elm_object_text_set(cfdata->screen_obj, s->info.screen);
elm_check_state_set(cfdata->lid_obj, s->info.is_lid);
elm_check_state_set(cfdata->backlight_obj, s->info.backlight);
snprintf(buf, sizeof(buf), "%imm x %imm", s->info.size.w, s->info.size.h);
elm_object_text_set(cfdata->size_obj, buf);
// XXX: connector
EINA_LIST_FREE(cfdata->freelist, dt) free(dt);
elm_list_clear(cfdata->modes_obj);
it_sel = NULL;
EINA_LIST_FOREACH(s->info.modes, l, m)
{
Mode_CBData *mode_cbdata = calloc(1, sizeof(Mode_CBData));
if (mode_cbdata)
{
mode_cbdata->cfdata = cfdata;
mode_cbdata->mode = *m;
snprintf(buf, sizeof(buf), "%ix%i @ %1.2fHz", m->w, m->h, m->refresh);
it = elm_list_item_append(cfdata->modes_obj, buf, NULL, NULL, _cb_mode_set, mode_cbdata);
cfdata->freelist = eina_list_append(cfdata->freelist, mode_cbdata);
printf("mode add %p %p %p\n", mode_cbdata, cfdata->modes_obj, it);
if ((cs->mode_w == m->w) && (cs->mode_h == m->h) &&
(cs->mode_refresh == m->refresh))
it_sel = it;
}
}
if (it_sel) elm_list_item_selected_set(it_sel, EINA_TRUE);
elm_list_go(cfdata->modes_obj);
elm_list_clear(cfdata->rotations_obj);
it_sel = NULL;
if (s->info.can_rot_0)
{
Rot_CBData *rot_cbdata = calloc(1, sizeof(Rot_CBData));
if (rot_cbdata)
{
rot_cbdata->cfdata = cfdata;
rot_cbdata->rot = 0;
it = elm_list_item_append(cfdata->rotations_obj, "0", NULL, NULL, _cb_rot_set, rot_cbdata);
cfdata->freelist = eina_list_append(cfdata->freelist, rot_cbdata);
if (cs->rotation == 0) it_sel = it;
}
}
if (s->info.can_rot_90)
{
Rot_CBData *rot_cbdata = calloc(1, sizeof(Rot_CBData));
if (rot_cbdata)
{
rot_cbdata->cfdata = cfdata;
rot_cbdata->rot = 90;
it = elm_list_item_append(cfdata->rotations_obj, "90", NULL, NULL, _cb_rot_set, rot_cbdata);
cfdata->freelist = eina_list_append(cfdata->freelist, rot_cbdata);
if (cs->rotation == 90) it_sel = it;
}
}
if (s->info.can_rot_180)
{
Rot_CBData *rot_cbdata = calloc(1, sizeof(Rot_CBData));
if (rot_cbdata)
{
rot_cbdata->cfdata = cfdata;
rot_cbdata->rot = 180;
it = elm_list_item_append(cfdata->rotations_obj, "180", NULL, NULL, _cb_rot_set, rot_cbdata);
cfdata->freelist = eina_list_append(cfdata->freelist, rot_cbdata);
if (cs->rotation == 180) it_sel = it;
}
}
if (s->info.can_rot_270)
{
Rot_CBData *rot_cbdata = calloc(1, sizeof(Rot_CBData));
if (rot_cbdata)
{
rot_cbdata->cfdata = cfdata;
rot_cbdata->rot = 270;
it = elm_list_item_append(cfdata->rotations_obj, "270", NULL, NULL, _cb_rot_set, rot_cbdata);
cfdata->freelist = eina_list_append(cfdata->freelist, rot_cbdata);
if (cs->rotation == 270) it_sel = it;
}
}
if (it_sel) elm_list_item_selected_set(it_sel, EINA_TRUE);
elm_list_go(cfdata->rotations_obj);
elm_check_state_set(cfdata->enabled_obj, cs->enabled);
elm_slider_value_set(cfdata->priority_obj, cs->priority);
if (cs->rel_mode == E_RANDR2_RELATIVE_NONE)
elm_object_text_set(cfdata->rel_mode_obj, "None");
else if (cs->rel_mode == E_RANDR2_RELATIVE_CLONE)
elm_object_text_set(cfdata->rel_mode_obj, "Clone");
else if (cs->rel_mode == E_RANDR2_RELATIVE_TO_LEFT)
elm_object_text_set(cfdata->rel_mode_obj, "Left of");
else if (cs->rel_mode == E_RANDR2_RELATIVE_TO_RIGHT)
elm_object_text_set(cfdata->rel_mode_obj, "Right of");
else if (cs->rel_mode == E_RANDR2_RELATIVE_TO_ABOVE)
elm_object_text_set(cfdata->rel_mode_obj, "Above");
else if (cs->rel_mode == E_RANDR2_RELATIVE_TO_BELOW)
elm_object_text_set(cfdata->rel_mode_obj, "Below");
else
elm_object_text_set(cfdata->rel_mode_obj, "???");
elm_slider_value_set(cfdata->rel_align_obj, cs->rel_align);
if (!cs->rel_to)
elm_object_text_set(cfdata->rel_to_obj, "");
else
{
char *str = strdup(cs->rel_to);
if (str)
{
char *p = strchr(str, '/');
if (p)
{
*p = 0;
elm_object_text_set(cfdata->rel_to_obj, str);
}
free(str);
}
}
}
static void
_cb_screen_select(void *data, Evas_Object *obj, void *event)
{
E_Config_Dialog_Data *cfdata = data;
Elm_Object_Item *it;
Eina_List *l;
int i = 0;
EINA_LIST_FOREACH(cfdata->screen_items, l, it)
{
if (it == event)
{
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
cfdata->screen = i;
if (cs)
{
E_Randr2_Screen *s = _screen_config_find(cs);
if (s)
{
elm_object_text_set(obj, s->info.name);
_basic_screen_info_fill(cfdata, cs, s);
}
}
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
return;
}
i++;
}
}
static void
_cb_rel_to_set(void *data, Evas_Object *obj, void *event)
{
E_Config_Dialog_Data *cfdata = data;
Elm_Object_Item *it;
Eina_List *l;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
int i = 0;
EINA_LIST_FOREACH(cfdata->screen_items2, l, it)
{
if (it == event)
{
E_Config_Randr2_Screen *cs2 = _config_screen_n_find(cfdata, i);
printf("find cs = %p\n", cs2);
printf("cs id = %s\n", cs2->id);
if (cs2 == cs) return;
if (cs2)
{
E_Randr2_Screen *s = _screen_config_id_find(cs2->id);
if (s)
{
printf("find s = %p\n", s);
printf("s id = %s\n", s->id);
elm_object_text_set(obj, s->info.name);
eina_stringshare_del(cs->rel_to);
cs->rel_to = eina_stringshare_add(s->id);
}
}
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
return;
}
i++;
}
}
static void
_cb_rel_align_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_align = elm_slider_value_get(obj);
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_none(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_NONE;
elm_object_text_set(obj, "None");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_clone(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_CLONE;
elm_object_text_set(obj, "Clone");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_left_of(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_TO_LEFT;
elm_object_text_set(obj, "Left of");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_right_of(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_TO_RIGHT;
elm_object_text_set(obj, "Right of");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_above(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_TO_ABOVE;
elm_object_text_set(obj, "Above");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_rel_mode_below(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->rel_mode = E_RANDR2_RELATIVE_TO_BELOW;
elm_object_text_set(obj, "Below");
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_priority_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->priority = elm_slider_value_get(obj);
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_enabled_changed(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->enabled = elm_check_state_get(obj);
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static Evas_Object *
_basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
Evas_Object *win = cfd->dia->win;
Evas_Object *o, *bx, *tb;
Eina_List *l;
E_Randr2_Screen *s, *first = NULL;
E_Config_Randr2_Screen *first_cfg = NULL;
int i;
e_dialog_resizable_set(cfd->dia, 1);
o = elm_box_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(o);
bx = o;
o = elm_table_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, o);
evas_object_show(o);
tb = o;
o = elm_hoversel_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Outputs");
cfdata->screens = NULL;
cfdata->screen_items = NULL;
i = 0;
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
Elm_Object_Item *it = NULL;
if (s->info.connected)
{
E_Config_Randr2_Screen *cs;
cs = calloc(1, sizeof(E_Config_Randr2_Screen));
if (cs)
{
if (s->id)
cs->id = eina_stringshare_add(s->id);
if (s->config.relative.to)
cs->rel_to = eina_stringshare_add(s->config.relative.to);
cs->rel_align = s->config.relative.align;
cs->mode_refresh = s->config.mode.refresh;
cs->mode_w = s->config.mode.w;
cs->mode_h = s->config.mode.h;
cs->rotation = s->config.rotation;
cs->priority = s->config.priority;
cs->rel_mode = s->config.relative.mode;
cs->enabled = s->config.enabled;
cfdata->screens = eina_list_append(cfdata->screens, cs);
it = elm_hoversel_item_add(o, s->info.name,
NULL, ELM_ICON_NONE,
_cb_screen_select, cfdata);
if (!first)
{
first = s;
first_cfg = cs;
cfdata->screen = i;
elm_object_text_set(o, s->info.name);
}
cfdata->screen_items = eina_list_append(cfdata->screen_items, it);
i++;
}
}
}
elm_table_pack(tb, o, 0, 0, 1, 1);
evas_object_show(o);
o = elm_entry_add(win);
elm_entry_scrollable_set(o, EINA_TRUE);
elm_entry_single_line_set(o, EINA_TRUE);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_table_pack(tb, o, 0, 1, 1, 1);
evas_object_show(o);
cfdata->name_obj = o;
o = elm_entry_add(win);
elm_entry_scrollable_set(o, EINA_TRUE);
elm_entry_single_line_set(o, EINA_TRUE);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_table_pack(tb, o, 0, 2, 1, 1);
evas_object_show(o);
cfdata->screen_obj = o;
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Laptop lid");
elm_table_pack(tb, o, 0, 3, 1, 1);
evas_object_show(o);
cfdata->lid_obj = o;
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Backlight");
elm_table_pack(tb, o, 0, 4, 1, 1);
evas_object_show(o);
cfdata->backlight_obj = o;
o = elm_label_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_table_pack(tb, o, 0, 5, 1, 1);
evas_object_show(o);
cfdata->size_obj = o;
o = elm_list_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_table_pack(tb, o, 1, 0, 1, 10);
evas_object_show(o);
cfdata->modes_obj = o;
o = elm_list_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_table_pack(tb, o, 2, 0, 1, 4);
evas_object_show(o);
cfdata->rotations_obj = o;
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "On");
elm_table_pack(tb, o, 2, 4, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_enabled_changed, cfdata);
cfdata->enabled_obj = o;
o = elm_slider_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Priority");
elm_slider_unit_format_set(o, "%3.0f");
elm_slider_span_size_set(o, 100);
elm_slider_min_max_set(o, 0, 100);
elm_table_pack(tb, o, 2, 5, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_priority_changed, cfdata);
cfdata->priority_obj = o;
o = elm_hoversel_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Relative");
elm_hoversel_item_add(o, "None", NULL, ELM_ICON_NONE, _cb_rel_mode_none, cfdata);
elm_hoversel_item_add(o, "Clone", NULL, ELM_ICON_NONE, _cb_rel_mode_clone, cfdata);
elm_hoversel_item_add(o, "Left of", NULL, ELM_ICON_NONE, _cb_rel_mode_left_of, cfdata);
elm_hoversel_item_add(o, "Right of", NULL, ELM_ICON_NONE, _cb_rel_mode_right_of, cfdata);
elm_hoversel_item_add(o, "Above", NULL, ELM_ICON_NONE, _cb_rel_mode_above, cfdata);
elm_hoversel_item_add(o, "Below", NULL, ELM_ICON_NONE, _cb_rel_mode_below, cfdata);
elm_table_pack(tb, o, 2, 6, 1, 1);
evas_object_show(o);
cfdata->rel_mode_obj = o;
o = elm_hoversel_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "To");
EINA_LIST_FOREACH(e_randr2->screens, l, s)
{
Elm_Object_Item *it = NULL;
if (s->info.connected)
{
it = elm_hoversel_item_add(o, s->info.name,
NULL, ELM_ICON_NONE,
_cb_rel_to_set, cfdata);
cfdata->screen_items2 = eina_list_append(cfdata->screen_items2, it);
}
}
elm_table_pack(tb, o, 2, 7, 1, 1);
evas_object_show(o);
cfdata->rel_to_obj = o;
o = elm_slider_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Align");
elm_slider_unit_format_set(o, "%1.1f");
elm_slider_span_size_set(o, 100);
elm_slider_min_max_set(o, 0.0, 1.0);
elm_table_pack(tb, o, 2, 8, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_rel_align_changed, cfdata);
cfdata->rel_align_obj = o;
_basic_screen_info_fill(cfdata, first_cfg, first);
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Restore setup on start");
elm_check_state_set(o, e_randr2_cfg->restore);
elm_box_pack_end(bx, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_restore_changed, cfdata);
evas_smart_objects_calculate(evas_object_evas_get(win));
e_util_win_auto_resize_fill(win);
elm_win_center(win, 1, 1);
cfdata->cfd = cfd;
return bx;
}
static int
_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
Eina_List *l;
E_Config_Randr2_Screen *cs, *cs2;
e_randr2_cfg->restore = cfdata->restore;
EINA_LIST_FOREACH(cfdata->screens, l, cs2)
{
if (!cs2->id) continue;
cs = _screen_config_randr_id_find(cs2->id);
if (!cs)
{
cs = calloc(1, sizeof(E_Config_Randr2_Screen));
cs->id = eina_stringshare_add(cs2->id);
e_randr2_cfg->screens = eina_list_append(e_randr2_cfg->screens, cs);
}
if (cs->rel_to) eina_stringshare_del(cs->rel_to);
cs->rel_to = NULL;
if (cs2->rel_to) cs->rel_to = eina_stringshare_add(cs2->rel_to);
cs->rel_align = cs2->rel_align;
cs->mode_refresh = cs2->mode_refresh;
cs->mode_w = cs2->mode_w;
cs->mode_h = cs2->mode_h;
cs->mode_refresh = cs2->mode_refresh;
cs->rotation = cs2->rotation;
cs->priority = cs2->priority;
cs->rel_mode = cs2->rel_mode;
cs->enabled = cs2->enabled;
}
e_randr2_config_save();
e_randr2_config_apply();
return 1;
}
static int
_basic_check(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata EINA_UNUSED)
{
return 1;
}

View File

@ -0,0 +1,9 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_INT_CONFIG_RANDR2_H
# define E_INT_CONFIG_RANDR2_H
E_Config_Dialog *e_int_config_randr2(Evas_Object *parent, const char *params);
# endif
#endif

View File

@ -1,8 +1,8 @@
#include "e.h"
#include "e_mod_main.h"
#include "e_int_config_randr.h"
#include "e_int_config_randr2.h"
EAPI E_Module_Api e_modapi =
EAPI E_Module_Api e_modapi =
{
E_MODULE_API_VERSION, "Settings - Screen Setup"
};
@ -13,43 +13,31 @@ e_modapi_init(E_Module *m)
/* create Screen configuration category
*
* NB: If the category already exists, this function just returns */
e_configure_registry_category_add("screen", 30, _("Screen"),
e_configure_registry_category_add("screen", 30, _("Screen"),
NULL, "preferences-desktop-display");
/* add the randr dialog to the screen category and provide
* the configure category with the function to call */
e_configure_registry_item_add("screen/screen_setup", 20, _("Screen Setup"),
NULL,
"preferences-system-screen-resolution",
e_int_config_randr);
/* return the module */
e_configure_registry_item_add("screen/screen_setup", 20, _("Screen Setup"),
NULL, "preferences-system-screen-resolution",
e_int_config_randr2);
return m;
}
EAPI int
EAPI int
e_modapi_shutdown(E_Module *m __UNUSED__)
{
E_Config_Dialog *cfd;
/* destroy existing dialogs */
while ((cfd = e_config_dialog_get("E", "screen/screen_setup")))
e_object_del(E_OBJECT(cfd));
/* remove randr dialog from the configuration category */
e_configure_registry_item_del("screen/screen_setup");
/* remove the screen configuration category
*
* NB: If there are other items in 'screen' then this function is a no-op */
e_configure_registry_category_del("screen");
/* return 1 for shutdown success */
return 1;
}
EAPI int
EAPI int
e_modapi_save(E_Module *m __UNUSED__)
{
return 1;

View File

@ -1,6 +1,7 @@
#ifndef E_MOD_MAIN_H
# define E_MOD_MAIN_H
#if 0
//# define LOGFNS 1
# ifdef LOGFNS
@ -29,3 +30,4 @@ EAPI int e_modapi_save(E_Module *m);
*/
#endif
#endif