5 * Give list some icons.
8 #define RANDR_11 ((1 << 16) | 1)
10 static void _fill_data (E_Config_Dialog_Data *cfdata);
11 static void *_create_data (E_Config_Dialog *cfd);
12 static void _free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
13 static int _basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
14 static int _basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
15 static Evas_Object *_basic_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
16 static void _load_resolutions (E_Config_Dialog_Data *cfdata);
17 static void _load_rates (E_Config_Dialog_Data *cfdata);
18 static void _ilist_item_change (void *data);
19 static Eina_Bool _deferred_noxrandr_error (void *data);
20 static Eina_Bool _deferred_norates_error (void *data);
21 static int _sort_resolutions (const void *d1, const void *d2);
23 typedef struct _Resolution Resolution;
24 typedef struct _SureBox SureBox;
29 Ecore_X_Randr_Screen_Size size;
40 E_Config_Dialog_Data *cfdata;
43 struct _E_Config_Dialog_Data
46 Eina_List *resolutions;
47 Ecore_X_Randr_Screen_Size orig_size;
49 Ecore_X_Randr_Refresh_Rate orig_rate;
61 Evas_Object *rate_list;
62 Evas_Object *res_list;
67 _surebox_dialog_cb_delete(E_Win *win)
75 sb->cfdata->surebox = NULL;
76 cfd = sb->cfdata->cfd;
77 if (sb->timer) ecore_timer_del(sb->timer);
80 e_object_del(E_OBJECT(dia));
81 e_object_unref(E_OBJECT(cfd));
85 _surebox_dialog_cb_yes(void *data, E_Dialog *dia)
91 if (sb->cfdata->restore)
92 e_randr_11_store_configuration(E_RANDR_CONFIGURATION_STORE_ALL);
94 _fill_data(sb->cfdata);
95 _load_resolutions(sb->cfdata);
96 /* No need to load rates as the currently selected resolution has not been
97 * changed since last selection. */
98 if (dia) _surebox_dialog_cb_delete(dia->win);
102 _surebox_dialog_cb_no(void *data, E_Dialog *dia)
107 ecore_x_randr_screen_primary_output_refresh_rate_set(sb->dia->win->container->manager->root,
108 sb->cfdata->orig_size_index, sb->cfdata->orig_rate);
109 _load_resolutions(sb->cfdata);
110 _load_rates(sb->cfdata);
111 _surebox_dialog_cb_delete(dia->win);
115 _surebox_text_fill(SureBox *sb)
119 if (!sb->dia) return;
120 if (sb->iterations > 1)
122 if (sb->cfdata->has_rates)
123 snprintf(buf, sizeof(buf),
124 P_("Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
125 "If you do not press a button, the old resolution of<br>"
126 "%d×%d at %d Hz will be restored in %d second.",
127 "Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
128 "If you do not press a button, the old resolution of<br>"
129 "%d×%d at %d Hz will be restored in %d seconds.", sb->iterations),
130 sb->cfdata->orig_size.width, sb->cfdata->orig_size.height,
131 sb->cfdata->orig_rate, sb->iterations);
133 snprintf(buf, sizeof(buf),
134 P_("Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
135 "If you do not press a button, the old resolution of<br>"
136 "%d×%d will be restored in %d second.",
137 "Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
138 "If you do not press a button, the old resolution of<br>"
139 "%d×%d will be restored in %d seconds.", sb->iterations),
140 sb->cfdata->orig_size.width, sb->cfdata->orig_size.height,
145 if (sb->cfdata->has_rates)
146 snprintf(buf, sizeof(buf),
147 _("Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
148 "If you do not press a button, the old resolution of<br>"
149 "%d×%d at %d Hz will be restored <hilight>IMMEDIATELY</hilight>."),
150 sb->cfdata->orig_size.width, sb->cfdata->orig_size.height,
151 sb->cfdata->orig_rate);
153 snprintf(buf, sizeof(buf),
154 _("Does this look OK? <hilight>Save</hilight> if it does, or Restore if not.<br>"
155 "If you do not press a button, the old resolution of<br>"
156 "%d×%d will be restored <hilight>IMMEDIATELY</hilight>."),
157 sb->cfdata->orig_size.width, sb->cfdata->orig_size.height);
159 e_dialog_text_set(sb->dia, buf);
163 _surebox_timer_cb(void *data)
169 _surebox_text_fill(sb);
170 if (sb->iterations == 0)
172 _surebox_dialog_cb_no(sb, sb->dia);
173 return ECORE_CALLBACK_CANCEL;
175 return ECORE_CALLBACK_RENEW;
179 _surebox_new(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
183 sb = E_NEW(SureBox, 1);
184 sb->dia = e_dialog_new(cfd->con, "E", "_display_res_sure_dialog");
185 sb->timer = ecore_timer_add(1.0, _surebox_timer_cb, sb);
189 cfdata->surebox = sb;
191 e_dialog_title_set(sb->dia, _("Resolution change"));
192 e_dialog_icon_set(sb->dia, "preferences-system-screen-resolution", 48);
193 _surebox_text_fill(sb);
194 e_win_delete_callback_set(sb->dia->win, _surebox_dialog_cb_delete);
195 e_dialog_button_add(sb->dia, _("Save"), NULL, _surebox_dialog_cb_yes, sb);
196 e_dialog_button_add(sb->dia, _("Restore"), NULL, _surebox_dialog_cb_no, sb);
197 e_dialog_button_focus_num(sb->dia, 1);
198 e_win_centered_set(sb->dia->win, 1);
199 e_win_borderless_set(sb->dia->win, 1);
200 e_win_layer_set(sb->dia->win, 6);
201 e_win_sticky_set(sb->dia->win, 1);
202 e_dialog_show(sb->dia);
203 e_object_ref(E_OBJECT(cfd));
208 e_int_config_display(E_Container *con, const char *params __UNUSED__)
210 E_Config_Dialog *cfd;
211 E_Config_Dialog_View *v;
213 if (!ecore_x_randr_query())
215 ecore_timer_add(0.5, _deferred_noxrandr_error, NULL);
216 fprintf(stderr, "XRandR not present on this display.\n");
220 if (e_config_dialog_find("E", "screen/screen_resolution")) return NULL;
221 v = E_NEW(E_Config_Dialog_View, 1);
222 v->create_cfdata = _create_data;
223 v->free_cfdata = _free_data;
224 v->basic.apply_cfdata = _basic_apply_data;
225 v->basic.create_widgets = _basic_create_widgets;
226 v->basic.check_changed = _basic_check_changed;
227 v->override_auto_apply = 1;
229 cfd = e_config_dialog_new(con, _("Screen Resolution Settings"),
230 "E", "screen/screen_resolution",
231 "preferences-system-screen-resolution", 0, v, NULL);
236 _fill_data(E_Config_Dialog_Data *cfdata)
241 man = e_manager_current_get();
242 ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index);
243 cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
245 rots = ecore_x_randr_screen_primary_output_orientations_get(man->root);
246 if ((rots) && (rots != ECORE_X_RANDR_ORIENTATION_ROT_0))
248 cfdata->orientation = ecore_x_randr_screen_primary_output_orientation_get(man->root);
249 cfdata->can_flip = rots & (ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y);
250 cfdata->flip = cfdata->orientation &
251 (ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y);
252 cfdata->orig_flip = cfdata->flip;
254 if (cfdata->orientation & (ECORE_X_RANDR_ORIENTATION_FLIP_X))
256 if (cfdata->orientation & (ECORE_X_RANDR_ORIENTATION_FLIP_Y))
260 rots & (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 |
261 ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270);
262 cfdata->orientation =
263 cfdata->orientation &
264 (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 |
265 ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270);
266 cfdata->orig_orientation = cfdata->orientation;
271 _create_data(E_Config_Dialog *cfd)
273 E_Config_Dialog_Data *cfdata;
275 cfdata = E_NEW(E_Config_Dialog_Data, 1);
282 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
287 _surebox_dialog_cb_delete(cfdata->surebox->dia->win);
289 EINA_LIST_FREE(cfdata->resolutions, r)
291 Ecore_X_Randr_Refresh_Rate *rt;
293 EINA_LIST_FREE(r->rates, rt)
302 _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
306 Ecore_X_Randr_Refresh_Rate *rt;
308 r = e_widget_ilist_selected_get(cfdata->res_list);
310 res = eina_list_nth(cfdata->resolutions, r);
312 r = e_widget_ilist_selected_get(cfdata->rate_list);
314 rt = eina_list_nth(res->rates, r);
317 return ((res->size.width != cfdata->orig_size.width) ||
318 (res->size.height != cfdata->orig_size.height) ||
319 (cfdata->has_rates && (*rt != cfdata->orig_rate)) ||
320 (cfdata->can_rotate &&
321 (cfdata->orig_orientation != cfdata->orientation)) ||
323 (((!(cfdata->orig_flip & ECORE_X_RANDR_ORIENTATION_FLIP_X)) !=
324 (!cfdata->flip_x)) ||
325 ((!(cfdata->orig_flip & ECORE_X_RANDR_ORIENTATION_FLIP_Y)) !=
326 (!cfdata->flip_y)))));
330 _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
334 Ecore_X_Randr_Refresh_Rate *rate;
337 r = e_widget_ilist_selected_get(cfdata->res_list);
338 res = eina_list_nth(cfdata->resolutions, r);
339 r = e_widget_ilist_selected_get(cfdata->rate_list);
340 rate = eina_list_nth(res->rates, r);
342 man = e_manager_current_get();
344 if (!((cfdata->orig_size.width == res->size.width) &&
345 (cfdata->orig_size.height == res->size.height) &&
346 (cfdata->orig_rate == *rate || !cfdata->has_rates)))
348 if (cfdata->has_rates)
349 ecore_x_randr_screen_primary_output_refresh_rate_set(man->root, res->size_index, *rate);
351 ecore_x_randr_screen_primary_output_size_set(man->root, res->size_index);
353 if (e_config->cnfmdlg_disabled)
357 sb = E_NEW(SureBox, 1);
360 _surebox_dialog_cb_yes (sb, NULL);
363 _surebox_new(cfd, cfdata);
366 if ((cfdata->can_rotate) || (cfdata->can_flip))
368 cfdata->flip = cfdata->orientation;
370 cfdata->flip = (cfdata->flip | ECORE_X_RANDR_ORIENTATION_FLIP_X);
372 cfdata->flip = (cfdata->flip | ECORE_X_RANDR_ORIENTATION_FLIP_Y);
374 ecore_x_randr_screen_primary_output_orientation_set(man->root,
375 (cfdata->orientation | cfdata->flip));
376 cfdata->orig_orientation = cfdata->orientation;
377 cfdata->orig_flip = cfdata->flip;
384 _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
386 Evas_Object *o, *of, *ob, *ot;
389 Ecore_X_Randr_Screen_Size_MM *sizes;
392 o = e_widget_table_add(evas, 0);
394 of = e_widget_framelist_add(evas, _("Resolution"), 0);
395 ob = e_widget_ilist_add(evas, 16, 16, NULL);
396 cfdata->res_list = ob;
397 e_widget_size_min_set(ob, 170, 215);
398 e_widget_framelist_object_append(of, ob);
399 e_widget_table_object_append(o, of, 0, 0, 1, 1, 1, 1, 1, 1);
401 ob = e_widget_check_add(evas, _("Restore on login"), &cfdata->restore);
402 e_widget_table_object_append(o, ob, 0, 1, 2, 1, 1, 1, 0, 0);
404 ot = e_widget_table_add(evas, 0);
405 of = e_widget_framelist_add(evas, _("Refresh"), 0);
406 ob = e_widget_ilist_add(evas, 16, 16, NULL);
407 cfdata->rate_list = ob;
408 e_widget_size_min_set(ob, 100, 80);
409 e_widget_framelist_object_append(of, ob);
410 e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
412 man = e_manager_current_get();
413 sizes = ecore_x_randr_screen_primary_output_sizes_get(man->root, &s);
414 cfdata->has_rates = EINA_FALSE;
416 if ((!sizes) || (s == 0))
417 ecore_timer_add(0.5, _deferred_noxrandr_error, NULL);
420 ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index);
421 cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
423 for (i = 0; i < (s - 1); i++)
426 Ecore_X_Randr_Refresh_Rate * rates;
429 res = E_NEW(Resolution, 1);
432 res->size.width = sizes[i].width;
433 res->size.height = sizes[i].height;
435 rates = ecore_x_randr_screen_primary_output_refresh_rates_get(man->root, i, &r);
436 for (j = 0; j < r; j++)
438 Ecore_X_Randr_Refresh_Rate * rt;
440 cfdata->has_rates = EINA_TRUE;
441 rt = E_NEW(Ecore_X_Randr_Refresh_Rate, 1);
444 res->rates = eina_list_append(res->rates, rt);
446 if (rates) E_FREE(rates);
447 cfdata->resolutions = eina_list_append(cfdata->resolutions, res);
450 cfdata->resolutions = eina_list_sort(cfdata->resolutions,
451 eina_list_count(cfdata->resolutions), _sort_resolutions);
452 cfdata->resolutions = eina_list_reverse(cfdata->resolutions);
454 _load_resolutions(cfdata);
455 if (!cfdata->has_rates)
456 ecore_timer_add(0.5, _deferred_norates_error, NULL);
463 if (cfdata->can_rotate)
465 of = e_widget_framelist_add(evas, _("Rotation"), 0);
466 rg = e_widget_radio_group_new(&(cfdata->orientation));
467 ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-normal", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_0, rg);
468 e_widget_framelist_object_append(of, ob);
469 if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_0)) e_widget_disabled_set(ob, 1);
470 ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-left", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_90, rg);
471 e_widget_framelist_object_append(of, ob);
472 if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_90)) e_widget_disabled_set(ob, 1);
473 ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-around", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_180, rg);
474 e_widget_framelist_object_append(of, ob);
475 if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_180)) e_widget_disabled_set(ob, 1);
476 ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-right", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_270, rg);
477 e_widget_framelist_object_append(of, ob);
478 if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_270)) e_widget_disabled_set(ob, 1);
479 e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 0, 1, 0);
482 if (cfdata->can_flip)
484 of = e_widget_framelist_add(evas, _("Mirroring"), 0);
485 ob = e_widget_check_icon_add(evas, NULL, "preferences-screen-hflip", 24, 24, &(cfdata->flip_x));
486 e_widget_framelist_object_append(of, ob);
487 if (!(cfdata->can_flip & ECORE_X_RANDR_ORIENTATION_FLIP_X)) e_widget_disabled_set(ob, 1);
488 ob = e_widget_check_icon_add(evas, NULL, "preferences-screen-vflip", 24, 24, &(cfdata->flip_y));
489 e_widget_framelist_object_append(of, ob);
490 if (!(cfdata->can_flip & ECORE_X_RANDR_ORIENTATION_FLIP_Y))
491 e_widget_disabled_set(ob, 1);
492 e_widget_table_object_append(ot, of, 0, 2, 1, 1, 1, 0, 1, 0);
495 e_widget_table_object_append(o, ot, 1, 0, 1, 1, 1, 1, 1, 1);
496 e_dialog_resizable_set(cfd->dia, 1);
501 _sort_resolutions(const void *d1, const void *d2)
503 const Resolution *r1 = d1;
504 const Resolution *r2 = d2;
506 if (r1->size.width > r2->size.width) return 1;
507 if (r1->size.width < r2->size.width) return -1;
508 if (r1->size.height > r2->size.height) return 1;
514 _load_resolutions(E_Config_Dialog_Data *cfdata)
520 evas = evas_object_evas_get(cfdata->res_list);
521 if (e_widget_ilist_count(cfdata->res_list) !=
522 (int) eina_list_count(cfdata->resolutions))
524 evas_event_freeze(evas);
526 e_widget_ilist_freeze(cfdata->res_list);
527 e_widget_ilist_clear(cfdata->res_list);
529 for (l = cfdata->resolutions, i = 0; l; l = l->next, i++)
532 Resolution *res = l->data;
533 Evas_Object *ob = NULL;
536 snprintf(buf, sizeof(buf), _("%i×%i"), res->size.width, res->size.height);
538 if ((res->size.width == cfdata->orig_size.width) &&
539 (res->size.height == cfdata->orig_size.height))
541 ob = e_icon_add(evas);
542 e_util_icon_theme_set(ob, "dialog-ok-apply");
545 e_widget_ilist_append(cfdata->res_list, ob, buf,
546 _ilist_item_change, cfdata, NULL);
549 e_widget_ilist_go(cfdata->res_list);
550 e_widget_ilist_selected_set(cfdata->res_list, sel);
551 e_widget_ilist_thaw(cfdata->res_list);
553 evas_event_thaw(evas);
557 for (l = cfdata->resolutions; l; l = l->next)
559 Resolution *res = l->data;
560 Evas_Object *ob = NULL;
562 if ((res->size.width == cfdata->orig_size.width) &&
563 (res->size.height == cfdata->orig_size.height))
565 ob = e_icon_add(evas);
566 e_util_icon_theme_set(ob, "dialog-ok-apply");
568 e_widget_ilist_nth_icon_set(cfdata->res_list, res->id, ob);
574 _load_rates(E_Config_Dialog_Data *cfdata)
576 int r, k = 0, sel = 0;
582 evas = evas_object_evas_get(cfdata->rate_list);
583 evas_event_freeze(evas);
585 e_widget_ilist_freeze(cfdata->rate_list);
586 e_widget_ilist_clear(cfdata->rate_list);
588 r = e_widget_ilist_selected_get(cfdata->res_list);
590 EINA_LIST_FOREACH(cfdata->resolutions, l, res)
593 Ecore_X_Randr_Refresh_Rate *rt;
596 EINA_LIST_FOREACH(res->rates, ll, rt)
598 Evas_Object *ob = NULL;
600 snprintf(buf, sizeof(buf), "%i Hz", (int)*rt);
602 if (*rt == cfdata->orig_rate)
604 ob = e_icon_add(evas);
605 e_util_icon_theme_set(ob, "dialog-ok-apply");
608 e_widget_ilist_append(cfdata->rate_list, ob, buf, NULL, NULL, NULL);
614 e_widget_ilist_go(cfdata->rate_list);
615 e_widget_ilist_selected_set(cfdata->rate_list, sel);
616 e_widget_ilist_thaw(cfdata->rate_list);
618 evas_event_thaw(evas);
622 _ilist_item_change(void *data)
628 _deferred_noxrandr_error(void *data __UNUSED__)
630 e_util_dialog_show(_("Missing Features"),
631 _("Your X Display Server is missing support for<br>"
632 "the <hilight>XRandR</hilight> (X Resize and Rotate) extension.<br>"
633 "You cannot change screen resolutions without<br>"
634 "the support of this extension. It could also be<br>"
635 "that at the time <hilight>ecore</hilight> was built, there<br>"
636 "was no XRandR support detected."));
637 return ECORE_CALLBACK_CANCEL;
641 _deferred_norates_error(void *data __UNUSED__)
643 e_util_dialog_show(_("No Refresh Rates Found"),
644 _("No refresh rates were reported by your X Display Server.<br>"
645 "If you are running a nested X Display Server, then<br>"
646 "this is to be expected. However, if you are not, then<br>"
647 "the current refresh rate will be used when setting<br>"
648 "the resolution, which may cause <hilight>damage</hilight> to your screen."));
649 return ECORE_CALLBACK_CANCEL;