update for beta release
[framework/uifw/e17.git] / src / modules / conf_randr / e_int_config_randr_resolutions.c
1 #include "e_int_config_randr.h"
2 #include "e_randr.h"
3 #include "e_widget_ilist.h"
4
5 #ifdef  Ecore_X_Randr_Unset
6 #undef  Ecore_X_Randr_Unset
7 #define Ecore_X_Randr_Unset -1
8 #else
9 #define Ecore_X_Randr_Unset -1
10 #endif
11
12 #ifdef  Ecore_X_Randr_None
13 #undef  Ecore_X_Randr_None
14 #endif
15 #define Ecore_X_Randr_None        0
16
17 #define ICON_WIDTH                10
18 #define ICON_HEIGHT               10
19 #define RESOLUTION_TXT_MAX_LENGTH 50
20
21 Evas_Object *dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas);
22 Eina_Bool    dialog_subdialog_resolutions_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
23 Eina_Bool    dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
24 void         dialog_subdialog_resolutions_update_list(Evas_Object *crtc);
25 void         dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata);
26 void         dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata);
27
28 extern E_Config_Dialog_Data *e_config_runtime_info;
29
30 Eina_Bool
31 dialog_subdialog_resolutions_create_data(E_Config_Dialog_Data *cfdata)
32 {
33    E_Config_Randr_Dialog_Output_Dialog_Data *odd;
34    Ecore_X_Randr_Mode_Info *mi;
35    Eina_List *iter;
36
37    if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
38
39    EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
40      {
41         if (odd->previous_mode || odd->preferred_mode)
42           {
43              //this means, that mode info is already filled
44              //(by the display arrangement code)
45              break;
46           }
47         if (odd->crtc)
48           {
49              if (!(mi = odd->crtc->current_mode))
50                mi = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(eina_list_last(odd->crtc->outputs_common_modes));
51              odd->previous_mode = mi;
52           }
53         else if (odd->output)
54           {
55              odd->preferred_mode = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(eina_list_last(odd->output->preferred_modes));
56           }
57      }
58
59    return EINA_TRUE;
60 }
61
62 Evas_Object *
63 dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas)
64 {
65    Evas_Object *subdialog;
66
67    if (!canvas || !e_config_runtime_info || e_config_runtime_info->gui.subdialogs.resolutions.dialog || !(subdialog = e_widget_ilist_add(canvas, ICON_WIDTH * e_scale, ICON_HEIGHT * e_scale, NULL))) return NULL;
68
69    e_widget_ilist_multi_select_set(subdialog, EINA_FALSE);
70    e_widget_disabled_set(subdialog, EINA_TRUE);
71
72    evas_object_show(subdialog);
73
74    return subdialog;
75 }
76
77 Eina_Bool
78 dialog_subdialog_resolutions_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata __UNUSED__)
79 {
80    //Apply new mode
81    Ecore_X_Randr_Mode_Info *selected_mode;
82    Ecore_X_ID selected_mode_xid;
83    E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
84    Ecore_X_Randr_Output *output = NULL;
85    E_Randr_Crtc_Info *crtc_info = NULL, *crtc_iter;
86    Eina_List *iter;
87    int noutputs = Ecore_X_Randr_Unset;
88
89    if (!e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info")))
90      {
91         fprintf(stderr, "CONF_RADNR: no crtc was selected or no output info could be retrieved for the selected crtc element (%p).\n", e_config_runtime_info->gui.selected_eo);
92         return EINA_FALSE;
93      }
94
95    if (output_dialog_data->crtc)
96      {
97         //CRTC is already asssigned, easy one!
98         crtc_info = output_dialog_data->crtc;
99      }
100    else if (output_dialog_data->output)
101      {
102         //CRTC not assigned yet. Let's try to find a non occupied one.
103         fprintf(stderr, "CONF_RANDR: Trying to find a CRTC for output %x, %d crtcs are possible.\n", output_dialog_data->output->xid, eina_list_count(output_dialog_data->output->possible_crtcs));
104         output = &output_dialog_data->output->xid;
105         noutputs = 1;
106         EINA_LIST_FOREACH(output_dialog_data->output->possible_crtcs, iter, crtc_iter)
107           {
108              if (!crtc_iter->outputs)
109                {
110                   //CRTC is not occupied yet
111                   crtc_info = crtc_iter;
112                   break;
113                }
114           }
115      }
116    if (!crtc_info)
117      {
118         fprintf(stderr, "CONF_RANDR: Changing mode failed, no unoccupied CRTC found!\n");
119         return EINA_FALSE;
120      }
121    //get selected mode
122    if ((selected_mode = (Ecore_X_Randr_Mode_Info *)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)))
123      {
124         selected_mode_xid = selected_mode->xid;
125      }
126    else
127      {
128         selected_mode_xid = Ecore_X_Randr_None;
129      }
130
131    fprintf(stderr, "CONF_RANDR: Change mode of crtc %x to %x.\n", crtc_info->xid, selected_mode_xid);
132
133    if (ecore_x_randr_crtc_mode_set(cfd->con->manager->root, crtc_info->xid, output, noutputs, selected_mode_xid))
134      {
135         //remove unused space
136         ecore_x_randr_screen_reset(cfd->con->manager->root);
137         //update information
138         if (!output_dialog_data->crtc)
139           output_dialog_data->crtc = crtc_info;
140         output_dialog_data->new_mode = selected_mode;
141         return EINA_TRUE;
142      }
143
144    return EINA_FALSE;
145 }
146
147 Eina_Bool
148 dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
149 {
150    Ecore_X_Randr_Mode_Info *selected_mode;
151    E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
152
153    if (!e_config_runtime_info->gui.selected_eo || !(selected_mode = (Ecore_X_Randr_Mode_Info *)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)) || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info"))) return EINA_FALSE;
154
155    return selected_mode != output_dialog_data->previous_mode;
156 }
157
158 void
159 dialog_subdialog_resolutions_update_list(Evas_Object *crtc)
160 {
161    Eina_List *iter, *modelist = NULL;
162    E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
163    Ecore_X_Randr_Mode_Info *mode_info, *current_mode;
164    char resolution_text[RESOLUTION_TXT_MAX_LENGTH];
165    float rate;
166    int str_ret, i = 0;
167
168    e_widget_ilist_freeze(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
169    e_widget_ilist_clear(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
170    if (!crtc)
171      {
172         e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_TRUE);
173         return;
174      }
175    if (!(output_dialog_data = evas_object_data_get(crtc, "output_info")))
176      return;
177
178    //select correct mode list
179    if (output_dialog_data->crtc)
180      {
181         current_mode = output_dialog_data->crtc->current_mode;
182         modelist = output_dialog_data->crtc->outputs_common_modes;
183      }
184    else if (output_dialog_data->output)
185      {
186         current_mode = NULL;
187         if (output_dialog_data->output->modes)
188           modelist = output_dialog_data->output->modes;
189         else
190           modelist = output_dialog_data->output->modes;
191      }
192    EINA_LIST_FOREACH(modelist, iter, mode_info)
193      {
194         //calculate refresh rate
195         if (!mode_info) continue;
196         if (mode_info->hTotal && mode_info->vTotal)
197           rate = ((float)mode_info->dotClock /
198                   ((float)mode_info->hTotal * (float)mode_info->vTotal));
199         else
200           rate = 0.0;
201
202         str_ret = snprintf(resolution_text, RESOLUTION_TXT_MAX_LENGTH, "%dx%d@%.1fHz", mode_info->width, mode_info->height, rate);
203         if (str_ret < 0 || str_ret > (RESOLUTION_TXT_MAX_LENGTH - 1))
204           {
205              fprintf(stderr, "CONF_RANDR: Resolution text could not be created.");
206              continue;
207           }
208         e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, resolution_text, NULL, mode_info, NULL);
209
210         //select currently enabled mode
211         if (mode_info == current_mode)
212           e_widget_ilist_selected_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, i);
213         i++;
214      }
215
216    //append 'disabled' mode
217    e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, _("Disabled"), NULL, NULL, NULL);
218
219    //reenable widget
220    e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_FALSE);
221    e_widget_ilist_go(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
222    e_widget_ilist_thaw(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
223 }
224
225 void
226 dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata)
227 {
228    E_Config_Randr_Dialog_Output_Dialog_Data *odd;
229    Eina_List *iter;
230
231    if (!cfdata) return;
232
233    EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
234      {
235         if (odd && odd->new_mode && (odd->new_mode != odd->previous_mode))
236           {
237              odd->previous_mode = odd->new_mode;
238              odd->new_mode = NULL;
239           }
240      }
241 }
242
243 void
244 dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata)
245 {
246    E_Config_Randr_Dialog_Output_Dialog_Data *odd;
247    Eina_List *iter;
248
249    if (!cfdata) return;
250
251    EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
252      {
253         //for now, there is no way to redisable an output during discartion
254         if (!odd->crtc || !odd->previous_mode) continue;
255         //use currently used outputs (noutputs == Ecore_X_Randr_Unset)
256         if (ecore_x_randr_crtc_mode_set(cfdata->manager->root, odd->crtc->xid, NULL, Ecore_X_Randr_Unset, odd->previous_mode->xid))
257           {
258              odd->new_mode = odd->previous_mode;
259              odd->previous_mode = NULL;
260              ecore_x_randr_screen_reset(cfdata->manager->root);
261           }
262      }
263 }
264