1 #include "e_randr_private.h"
4 E_Randr_Monitor_Info *_monitor_info_new(E_Randr_Output_Info *output_info);
5 static int _modes_size_sort_cb(const void *d1, const void *d2);
8 _monitor_modes_refs_set(E_Randr_Monitor_Info *mi, Ecore_X_Randr_Output o)
10 Ecore_X_Randr_Mode *modes = NULL;
11 Ecore_X_Randr_Mode_Info *mode_info = NULL;
12 int nmodes = 0, npreferred = 0;
14 EINA_SAFETY_ON_NULL_RETURN(mi);
15 EINA_SAFETY_ON_TRUE_RETURN(o == Ecore_X_Randr_None);
17 // Add (preferred) modes
18 modes = ecore_x_randr_output_modes_get(e_randr_screen_info.root, o, &nmodes, &npreferred);
21 if (!modes[nmodes]) continue;
22 if (!(mode_info = _12_screen_info_mode_info_get(modes[nmodes])))
24 //Mode unknown to the global structure, so add it
25 mode_info = ecore_x_randr_mode_info_get(e_randr_screen_info.root, modes[nmodes]);
26 e_randr_screen_info.rrvd_info.randr_info_12->modes = eina_list_append(e_randr_screen_info.rrvd_info.randr_info_12->modes, mode_info);
28 mi->modes = eina_list_prepend(mi->modes, mode_info);
29 if (nmodes <= npreferred)
30 mi->preferred_modes = eina_list_prepend(mi->preferred_modes, mode_info);
36 * @brief Allocates a new E_Randr_Monitor_Info struct and initializes it with
38 * @return E_Randr_Monitor_Info element, or if it could not be
41 E_Randr_Monitor_Info *
42 _monitor_info_new(E_Randr_Output_Info *oi)
44 E_Randr_Monitor_Info *mi = NULL;
46 EINA_SAFETY_ON_NULL_RETURN_VAL(oi, NULL);
48 mi = E_NEW(E_Randr_Monitor_Info, 1);
50 // Set some default values
52 mi->preferred_modes = NULL;
53 mi->size_mm.width = Ecore_X_Randr_Unset;
54 mi->size_mm.height = Ecore_X_Randr_Unset;
57 mi->edid_hash.hash = 0;
58 mi->max_backlight = Ecore_X_Randr_Unset;
59 mi->backlight_level = 0.0;
61 _monitor_modes_refs_set(mi, oi->xid);
63 ecore_x_randr_output_size_mm_get(e_randr_screen_info.root, oi->xid, &mi->size_mm.width, &mi->size_mm.height);
64 mi->edid = ecore_x_randr_output_edid_get(e_randr_screen_info.root, oi->xid, &mi->edid_length);
65 if (mi->edid_length > 0)
66 mi->edid_hash.hash = eina_hash_superfast((char *)mi->edid, mi->edid_length);
72 * @brief Frees E_Randr_Monitor_Info structure
75 _monitor_info_free(E_Randr_Monitor_Info *monitor_info)
80 eina_list_free(monitor_info->modes);
81 eina_list_free(monitor_info->preferred_modes);
82 free(monitor_info->edid);
87 * @brief allocates a struct and fills it with default values.
88 * @param output the output the display is queried for. If Ecore_X_Randr_None is
89 * given, a struct with only the xid will be set
90 * @return E_Randr_Output_Info element
93 _output_info_new(Ecore_X_Randr_Output output)
95 E_Randr_Output_Info *output_info = NULL;
98 EINA_SAFETY_ON_TRUE_RETURN_VAL(E_RANDR_12_NO, NULL);
100 output_info = E_NEW(E_Randr_Output_Info, 1);
102 output_info->xid = output;
105 output_info->crtc = NULL;
106 output_info->wired_clones = NULL;
107 output_info->possible_crtcs = NULL;
108 output_info->signalformats = Ecore_X_Randr_Unset;
109 output_info->signalformat = Ecore_X_Randr_Unset;
110 output_info->connector_number = 0;
111 output_info->monitor = NULL;
112 output_info->connector_type = Ecore_X_Randr_Unset;
113 output_info->policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
114 output_info->compatibility_list = NULL;
115 output_info->subpixel_order = Ecore_X_Randr_Unset;
117 str = ecore_x_randr_output_name_get(e_randr_screen_info.root, output_info->xid, &output_info->name_length);
118 output_info->name = eina_stringshare_add(str);
120 output_info->connection_status = ecore_x_randr_output_connection_status_get(e_randr_screen_info.root, output_info->xid);
126 _output_info_free(E_Randr_Output_Info *output_info)
128 EINA_SAFETY_ON_NULL_RETURN(output_info);
130 eina_list_free(output_info->wired_clones);
131 eina_list_free(output_info->possible_crtcs);
132 eina_list_free(output_info->compatibility_list);
133 eina_stringshare_del(output_info->name);
134 _monitor_info_free(output_info->monitor);
135 output_info->monitor = NULL;
140 _output_refs_set(E_Randr_Output_Info *output_info)
142 Ecore_X_Randr_Crtc crtc, *crtcs = NULL;
143 E_Randr_Crtc_Info *crtc_info;
146 EINA_SAFETY_ON_TRUE_RETURN(E_RANDR_12_NO);
147 EINA_SAFETY_ON_NULL_RETURN(output_info);
149 eina_list_free(output_info->possible_crtcs);
152 crtcs = ecore_x_randr_output_possible_crtcs_get(e_randr_screen_info.root, output_info->xid, &ncrtcs);
153 while (--ncrtcs >= 0)
155 if (!(crtc_info = _12_screen_info_crtc_info_get(crtcs[ncrtcs])))
157 output_info->possible_crtcs = eina_list_append(output_info->possible_crtcs, crtc_info);
161 crtc = ecore_x_randr_output_crtc_get(e_randr_screen_info.root, output_info->xid);
162 output_info->crtc = _12_screen_info_crtc_info_get(crtc);
164 if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
165 output_info->monitor = _monitor_info_new(output_info);
167 output_info->monitor = NULL;
170 Ecore_X_Randr_Output *
171 _outputs_to_array(Eina_List *outputs_info)
173 Ecore_X_Randr_Output *ret = NULL;
174 E_Randr_Output_Info *output_info;
175 Eina_List *output_iter;
178 if (!outputs_info || !(ret = malloc(sizeof(Ecore_X_Randr_Output) * eina_list_count(outputs_info)))) return NULL;
179 EINA_LIST_FOREACH(outputs_info, output_iter, output_info)
180 /* output_info == NULL should _not_ be possible! */
181 ret[i++] = output_info ? output_info->xid : Ecore_X_Randr_None;
186 * returns a list of modes common ammongst the given outputs,
187 * optionally limited by max_size_mode. If none are found, NULL is returned.
190 *_outputs_common_modes_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode)
192 Eina_List *common_modes = NULL, *mode_iter, *output_iter, *mode_next, *output_next;
193 E_Randr_Output_Info *output_info;
194 Ecore_X_Randr_Mode_Info *mode_info;
196 EINA_SAFETY_ON_NULL_RETURN_VAL(outputs, NULL);
197 EINA_SAFETY_ON_NULL_RETURN_VAL(e_randr_screen_info.rrvd_info.randr_info_12->modes, NULL);
199 //create a list of all common modes
200 common_modes = eina_list_clone(e_randr_screen_info.rrvd_info.randr_info_12->modes);
201 common_modes = eina_list_sort(common_modes, 0, _modes_size_sort_cb);
203 EINA_LIST_FOREACH_SAFE(common_modes, mode_iter, mode_next, mode_info)
205 EINA_LIST_FOREACH_SAFE(outputs, output_iter, output_next, output_info)
207 if (!output_info || !output_info->monitor)
209 if (!eina_list_data_find(output_info->monitor->modes, mode_info))
210 common_modes = eina_list_remove(common_modes, mode_info);
216 //remove all modes that are larger than max_size_mode
217 EINA_LIST_FOREACH_SAFE(common_modes, mode_iter, mode_next, mode_info)
219 if (_modes_size_sort_cb((void *)max_size_mode, (void *)mode_info) < 0)
220 common_modes = eina_list_remove(common_modes, mode_info);
224 //sort modes desc. by their sizes
225 common_modes = eina_list_reverse(common_modes);
231 _modes_size_sort_cb(const void *d1, const void *d2)
233 Ecore_X_Randr_Mode_Info *mode1 = ((Ecore_X_Randr_Mode_Info *)d1), *mode2 = ((Ecore_X_Randr_Mode_Info *)d2);
238 return (mode1->width * mode1->height) - (mode2->width * mode2->height);