diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c | 3474 |
1 files changed, 3474 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c new file mode 100644 index 0000000..510da49 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c | |||
@@ -0,0 +1,3474 @@ | |||
1 | /* TODO: List of missing functions | ||
2 | * | ||
3 | * ecore_x_randr_crtc_clone_set | ||
4 | * ecore_x_randr_output_size_mm_get | ||
5 | * ecore_x_randr_output_crtc_set | ||
6 | * ecore_x_randr_edid_version_get | ||
7 | * ecore_x_randr_edid_info_has_valid_checksum | ||
8 | * ecore_x_randr_edid_manufacturer_name_get | ||
9 | * ecore_x_randr_edid_display_ascii_get | ||
10 | * ecore_x_randr_edid_display_serial_get | ||
11 | * ecore_x_randr_edid_model_get | ||
12 | * ecore_x_randr_edid_manufacturer_serial_number_get | ||
13 | * ecore_x_randr_edid_manufacturer_model_get | ||
14 | * ecore_x_randr_edid_dpms_available_get | ||
15 | * ecore_x_randr_edid_dpms_standby_available_get | ||
16 | * ecore_x_randr_edid_dpms_suspend_available_get | ||
17 | * ecore_x_randr_edid_dpms_off_available_get | ||
18 | * ecore_x_randr_edid_display_aspect_ratio_preferred_get | ||
19 | * ecore_x_randr_edid_display_aspect_ratios_get | ||
20 | * ecore_x_randr_edid_display_colorscheme_get | ||
21 | * ecore_x_randr_edid_display_type_digital_get | ||
22 | * ecore_x_randr_edid_display_interface_type_get | ||
23 | * ecore_x_randr_screen_backlight_level_set | ||
24 | * ecore_x_randr_output_subpixel_order_get | ||
25 | * ecore_x_randr_output_wired_clones_get | ||
26 | * ecore_x_randr_output_compatibility_list_get | ||
27 | * ecore_x_randr_output_signal_formats_get | ||
28 | * ecore_x_randr_output_signal_format_set | ||
29 | * ecore_x_randr_output_signal_properties_get | ||
30 | * ecore_x_randr_output_connector_number_get | ||
31 | * ecore_x_randr_output_connector_type_get | ||
32 | * ecore_x_randr_crtc_panning_area_get | ||
33 | * ecore_x_randr_crtc_panning_area_set | ||
34 | * ecore_x_randr_crtc_tracking_area_get | ||
35 | * ecore_x_randr_crtc_tracking_area_set | ||
36 | * ecore_x_randr_crtc_border_area_get | ||
37 | * ecore_x_randr_crtc_border_area_set | ||
38 | */ | ||
39 | |||
40 | #include "ecore_xcb_private.h" | ||
41 | # ifdef ECORE_XCB_RANDR | ||
42 | # include <xcb/randr.h> | ||
43 | # endif | ||
44 | |||
45 | #define Ecore_X_Randr_None 0 | ||
46 | #define Ecore_X_Randr_Unset -1 | ||
47 | |||
48 | #define RANDR_1_1 ((1 << 16) | 1) | ||
49 | #define RANDR_1_2 ((1 << 16) | 2) | ||
50 | #define RANDR_1_3 ((1 << 16) | 3) | ||
51 | |||
52 | #define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) return ret | ||
53 | #define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) return ret | ||
54 | #define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) return ret | ||
55 | |||
56 | #define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) | ||
57 | #define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 | ||
58 | #define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 | ||
59 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 | ||
60 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 | ||
61 | #define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 | ||
62 | #define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 | ||
63 | |||
64 | #define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ | ||
65 | for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) | ||
66 | |||
67 | #define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ | ||
68 | _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ | ||
69 | if ((block[0] == 0) && (block[1] == 0)) | ||
70 | |||
71 | /* local function prototypes */ | ||
72 | static Eina_Bool _ecore_xcb_randr_output_validate(Ecore_X_Window root, | ||
73 | Ecore_X_Randr_Output output); | ||
74 | static Eina_Bool _ecore_xcb_randr_crtc_validate(Ecore_X_Window root, | ||
75 | Ecore_X_Randr_Crtc crtc); | ||
76 | static Eina_Bool _ecore_xcb_randr_root_validate(Ecore_X_Window root); | ||
77 | static int _ecore_xcb_randr_root_to_screen(Ecore_X_Window root); | ||
78 | static xcb_randr_get_screen_resources_reply_t *_ecore_xcb_randr_12_get_resources(Ecore_X_Window win); | ||
79 | static xcb_randr_get_screen_resources_current_reply_t *_ecore_xcb_randr_13_get_resources(Ecore_X_Window win); | ||
80 | static xcb_timestamp_t _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win); | ||
81 | static xcb_timestamp_t _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win); | ||
82 | |||
83 | static Ecore_X_Randr_Mode *_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, | ||
84 | Ecore_X_Randr_Output output, | ||
85 | int *num, | ||
86 | int *npreferred); | ||
87 | static Ecore_X_Randr_Mode *_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, | ||
88 | Ecore_X_Randr_Output output, | ||
89 | int *num, | ||
90 | int *npreferred); | ||
91 | static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, | ||
92 | Ecore_X_Randr_Mode mode); | ||
93 | static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, | ||
94 | Ecore_X_Randr_Mode mode); | ||
95 | static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, | ||
96 | int *num); | ||
97 | static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, | ||
98 | int *num); | ||
99 | static void _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, | ||
100 | Ecore_X_Randr_Mode mode, | ||
101 | int *w, | ||
102 | int *h); | ||
103 | static void _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, | ||
104 | Ecore_X_Randr_Mode mode, | ||
105 | int *w, | ||
106 | int *h); | ||
107 | static Ecore_X_Randr_Output *_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, | ||
108 | Ecore_X_Randr_Output output, | ||
109 | int *num); | ||
110 | static Ecore_X_Randr_Output *_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, | ||
111 | Ecore_X_Randr_Output output, | ||
112 | int *num); | ||
113 | static Ecore_X_Randr_Crtc *_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, | ||
114 | Ecore_X_Randr_Output output, | ||
115 | int *num); | ||
116 | static Ecore_X_Randr_Crtc *_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, | ||
117 | Ecore_X_Randr_Output output, | ||
118 | int *num); | ||
119 | static char *_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, | ||
120 | Ecore_X_Randr_Output output, | ||
121 | int *len); | ||
122 | static char *_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, | ||
123 | Ecore_X_Randr_Output output, | ||
124 | int *len); | ||
125 | static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, | ||
126 | Ecore_X_Randr_Output output); | ||
127 | static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, | ||
128 | Ecore_X_Randr_Output output); | ||
129 | static Ecore_X_Randr_Output *_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, | ||
130 | int *num); | ||
131 | static Ecore_X_Randr_Output *_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, | ||
132 | int *num); | ||
133 | static Ecore_X_Randr_Crtc _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, | ||
134 | Ecore_X_Randr_Output output); | ||
135 | static Ecore_X_Randr_Crtc _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, | ||
136 | Ecore_X_Randr_Output output); | ||
137 | |||
138 | /* local variables */ | ||
139 | static Eina_Bool _randr_avail = EINA_FALSE; | ||
140 | static int _randr_version = -1; | ||
141 | |||
142 | /* external variables */ | ||
143 | int _ecore_xcb_event_randr = -1; | ||
144 | |||
145 | void | ||
146 | _ecore_xcb_randr_init(void) | ||
147 | { | ||
148 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
149 | |||
150 | #ifdef ECORE_XCB_RANDR | ||
151 | xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id); | ||
152 | #endif | ||
153 | } | ||
154 | |||
155 | void | ||
156 | _ecore_xcb_randr_finalize(void) | ||
157 | { | ||
158 | #ifdef ECORE_XCB_RANDR | ||
159 | const xcb_query_extension_reply_t *ext_reply; | ||
160 | #endif | ||
161 | |||
162 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
163 | |||
164 | #ifdef ECORE_XCB_RANDR | ||
165 | ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id); | ||
166 | if ((ext_reply) && (ext_reply->present)) | ||
167 | { | ||
168 | xcb_randr_query_version_cookie_t cookie; | ||
169 | xcb_randr_query_version_reply_t *reply; | ||
170 | |||
171 | cookie = | ||
172 | xcb_randr_query_version_unchecked(_ecore_xcb_conn, | ||
173 | XCB_RANDR_MAJOR_VERSION, | ||
174 | XCB_RANDR_MINOR_VERSION); | ||
175 | reply = xcb_randr_query_version_reply(_ecore_xcb_conn, cookie, NULL); | ||
176 | if (reply) | ||
177 | { | ||
178 | if ((reply->major_version >= XCB_RANDR_MAJOR_VERSION) && | ||
179 | (reply->minor_version >= XCB_RANDR_MINOR_VERSION)) | ||
180 | _randr_avail = EINA_TRUE; | ||
181 | |||
182 | _randr_version = | ||
183 | ((reply->major_version << 16) | reply->minor_version); | ||
184 | |||
185 | free(reply); | ||
186 | } | ||
187 | |||
188 | if (_randr_avail) | ||
189 | _ecore_xcb_event_randr = ext_reply->first_event; | ||
190 | } | ||
191 | #endif | ||
192 | } | ||
193 | |||
194 | static Eina_Bool | ||
195 | _ecore_xcb_randr_root_validate(Ecore_X_Window root) | ||
196 | { | ||
197 | #ifdef ECORE_XCB_RANDR | ||
198 | Ecore_X_Randr_Screen scr = -1; | ||
199 | # define RANDR_VALIDATE_ROOT(screen, root) \ | ||
200 | ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) | ||
201 | #endif | ||
202 | |||
203 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
204 | |||
205 | #ifdef ECORE_XCB_RANDR | ||
206 | if ((root) && RANDR_VALIDATE_ROOT(scr, root)) | ||
207 | return EINA_TRUE; | ||
208 | #endif | ||
209 | |||
210 | return EINA_FALSE; | ||
211 | } | ||
212 | |||
213 | static int | ||
214 | _ecore_xcb_randr_root_to_screen(Ecore_X_Window root) | ||
215 | { | ||
216 | int count = 0, num = 0; | ||
217 | |||
218 | CHECK_XCB_CONN; | ||
219 | |||
220 | count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); | ||
221 | for (num = 0; num < count; num++) | ||
222 | if (_ecore_xcb_window_root_of_screen_get(num) == root) | ||
223 | return num; | ||
224 | |||
225 | return -1; | ||
226 | } | ||
227 | |||
228 | /* public functions */ | ||
229 | |||
230 | /* | ||
231 | * @brief query whether randr is available or not | ||
232 | * @return EINA_TRUE, if extension is available, else EINA_FALSE | ||
233 | */ | ||
234 | EAPI Eina_Bool | ||
235 | ecore_x_randr_query(void) | ||
236 | { | ||
237 | return _randr_avail; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * @return version of the RandRR extension supported by the server or, | ||
242 | * in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1). | ||
243 | * bit version information: 31 MAJOR 16 | 15 MINOR 0 | ||
244 | */ | ||
245 | EAPI int | ||
246 | ecore_x_randr_version_get(void) | ||
247 | { | ||
248 | return _randr_version; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * @param root window which's primary output will be queried | ||
253 | */ | ||
254 | EAPI Ecore_X_Randr_Orientation | ||
255 | ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) | ||
256 | { | ||
257 | int ret = Ecore_X_Randr_None; | ||
258 | #ifdef ECORE_XCB_RANDR | ||
259 | xcb_randr_get_screen_info_cookie_t cookie; | ||
260 | xcb_randr_get_screen_info_reply_t *reply; | ||
261 | #endif | ||
262 | |||
263 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
264 | CHECK_XCB_CONN; | ||
265 | |||
266 | #ifdef ECORE_XCB_RANDR | ||
267 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
268 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
269 | if (reply) | ||
270 | { | ||
271 | ret = reply->rotations; | ||
272 | free(reply); | ||
273 | } | ||
274 | #endif | ||
275 | |||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * @param root window which's primary output will be queried | ||
281 | * @return the current orientation of the root window's screen primary output | ||
282 | */ | ||
283 | EAPI Ecore_X_Randr_Orientation | ||
284 | ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) | ||
285 | { | ||
286 | int ret = Ecore_X_Randr_None; | ||
287 | #ifdef ECORE_XCB_RANDR | ||
288 | xcb_randr_get_screen_info_cookie_t cookie; | ||
289 | xcb_randr_get_screen_info_reply_t *reply; | ||
290 | #endif | ||
291 | |||
292 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
293 | CHECK_XCB_CONN; | ||
294 | |||
295 | #ifdef ECORE_XCB_RANDR | ||
296 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
297 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
298 | if (reply) | ||
299 | { | ||
300 | ret = reply->rotation; | ||
301 | free(reply); | ||
302 | } | ||
303 | #endif | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * @brief sets a given screen's primary output's orientation | ||
310 | * @param root window which's screen's primary output will be queried | ||
311 | * @param orientation orientation which should be set for the root window's screen primary output | ||
312 | * @return EINA_TRUE if the primary output's orientation could be successfully altered | ||
313 | */ | ||
314 | EAPI Eina_Bool | ||
315 | ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, | ||
316 | Ecore_X_Randr_Orientation orientation) | ||
317 | { | ||
318 | int ret = EINA_FALSE; | ||
319 | #ifdef ECORE_XCB_RANDR | ||
320 | xcb_randr_get_screen_info_cookie_t cookie; | ||
321 | xcb_randr_get_screen_info_reply_t *reply; | ||
322 | #endif | ||
323 | |||
324 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
325 | CHECK_XCB_CONN; | ||
326 | |||
327 | #ifdef ECORE_XCB_RANDR | ||
328 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
329 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
330 | if (reply) | ||
331 | { | ||
332 | xcb_randr_set_screen_config_cookie_t scookie; | ||
333 | xcb_randr_set_screen_config_reply_t *sreply; | ||
334 | |||
335 | scookie = | ||
336 | xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, | ||
337 | XCB_CURRENT_TIME, | ||
338 | reply->config_timestamp, | ||
339 | reply->sizeID, orientation, | ||
340 | reply->rate); | ||
341 | sreply = | ||
342 | xcb_randr_set_screen_config_reply(_ecore_xcb_conn, scookie, NULL); | ||
343 | if (!sreply) | ||
344 | ret = EINA_FALSE; | ||
345 | else | ||
346 | { | ||
347 | ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? | ||
348 | EINA_TRUE : EINA_FALSE; | ||
349 | free(sreply); | ||
350 | } | ||
351 | free(reply); | ||
352 | } | ||
353 | #endif | ||
354 | |||
355 | return ret; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * @brief gets a screen's primary output's possible sizes | ||
360 | * @param root window which's primary output will be queried | ||
361 | * @param num number of sizes reported as supported by the screen's primary output | ||
362 | * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL | ||
363 | */ | ||
364 | EAPI Ecore_X_Randr_Screen_Size_MM * | ||
365 | ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, | ||
366 | int *num) | ||
367 | { | ||
368 | #ifdef ECORE_XCB_RANDR | ||
369 | xcb_randr_get_screen_info_cookie_t cookie; | ||
370 | xcb_randr_get_screen_info_reply_t *reply; | ||
371 | Ecore_X_Randr_Screen_Size_MM *ret = NULL; | ||
372 | #endif | ||
373 | |||
374 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
375 | CHECK_XCB_CONN; | ||
376 | |||
377 | #ifdef ECORE_XCB_RANDR | ||
378 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
379 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
380 | if (reply) | ||
381 | { | ||
382 | int len = 0, i = 0; | ||
383 | xcb_randr_screen_size_t *sizes; | ||
384 | |||
385 | len = xcb_randr_get_screen_info_sizes_length(reply); | ||
386 | sizes = xcb_randr_get_screen_info_sizes(reply); | ||
387 | if ((!sizes) || (len <= 0)) | ||
388 | { | ||
389 | free(reply); | ||
390 | return NULL; | ||
391 | } | ||
392 | if (num) *num = len; | ||
393 | ret = calloc(len, sizeof(Ecore_X_Randr_Screen_Size_MM)); | ||
394 | if (!ret) | ||
395 | { | ||
396 | free(reply); | ||
397 | return NULL; | ||
398 | } | ||
399 | for (i = 0; i < len; i++) | ||
400 | { | ||
401 | ret[i].width = sizes[i].width; | ||
402 | ret[i].height = sizes[i].height; | ||
403 | ret[i].width_mm = sizes[i].mwidth; | ||
404 | ret[i].height_mm = sizes[i].mheight; | ||
405 | } | ||
406 | |||
407 | free(reply); | ||
408 | } | ||
409 | |||
410 | return ret; | ||
411 | #else | ||
412 | return NULL; | ||
413 | #endif | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * @brief get the current set size of a given screen's primary output | ||
418 | * @param root window which's primary output will be queried | ||
419 | * @param w the current size's width | ||
420 | * @param h the current size's height | ||
421 | * @param w_mm the current size's width in mm | ||
422 | * @param h_mm the current size's height in mm | ||
423 | * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() | ||
424 | */ | ||
425 | EAPI void | ||
426 | ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, | ||
427 | int *w, | ||
428 | int *h, | ||
429 | int *w_mm, | ||
430 | int *h_mm, | ||
431 | int *size_index) | ||
432 | { | ||
433 | #ifdef ECORE_XCB_RANDR | ||
434 | xcb_randr_get_screen_info_cookie_t cookie; | ||
435 | xcb_randr_get_screen_info_reply_t *reply; | ||
436 | #endif | ||
437 | |||
438 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
439 | CHECK_XCB_CONN; | ||
440 | |||
441 | #ifdef ECORE_XCB_RANDR | ||
442 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
443 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
444 | if (reply) | ||
445 | { | ||
446 | int len = 0, idx = 0; | ||
447 | xcb_randr_screen_size_t *sizes; | ||
448 | |||
449 | len = xcb_randr_get_screen_info_sizes_length(reply); | ||
450 | sizes = xcb_randr_get_screen_info_sizes(reply); | ||
451 | if ((!sizes) || (len <= 0)) | ||
452 | { | ||
453 | free(reply); | ||
454 | return; | ||
455 | } | ||
456 | idx = reply->sizeID; | ||
457 | if ((idx < len) && (idx >= 0)) | ||
458 | { | ||
459 | if (w) *w = sizes[idx].width; | ||
460 | if (h) *h = sizes[idx].height; | ||
461 | if (w_mm) *w_mm = sizes[idx].mwidth; | ||
462 | if (h_mm) *h_mm = sizes[idx].mheight; | ||
463 | if (size_index) *size_index = idx; | ||
464 | } | ||
465 | |||
466 | free(reply); | ||
467 | } | ||
468 | #endif | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * @brief sets a given screen's primary output size, but disables all other outputs at the same time | ||
473 | * @param root window which's primary output will be queried | ||
474 | * @param size_index within the list of sizes reported as supported by the root window's screen primary output | ||
475 | * @return EINA_TRUE on success, EINA_FALSE on failure due to e.g. invalid times | ||
476 | */ | ||
477 | EAPI Eina_Bool | ||
478 | ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, | ||
479 | int size_index) | ||
480 | { | ||
481 | Eina_Bool ret = EINA_FALSE; | ||
482 | #ifdef ECORE_XCB_RANDR | ||
483 | xcb_randr_get_screen_info_cookie_t cookie; | ||
484 | xcb_randr_get_screen_info_reply_t *reply; | ||
485 | #endif | ||
486 | |||
487 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
488 | CHECK_XCB_CONN; | ||
489 | |||
490 | #ifdef ECORE_XCB_RANDR | ||
491 | if (!((size_index >= 0) && (_ecore_xcb_randr_root_validate(root)))) | ||
492 | return EINA_FALSE; | ||
493 | |||
494 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
495 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
496 | if (reply) | ||
497 | { | ||
498 | int len = 0; | ||
499 | |||
500 | len = xcb_randr_get_screen_info_sizes_length(reply); | ||
501 | if (len <= 0) | ||
502 | { | ||
503 | free(reply); | ||
504 | return EINA_FALSE; | ||
505 | } | ||
506 | if ((size_index < len) && (size_index >= 0)) | ||
507 | { | ||
508 | xcb_randr_set_screen_config_cookie_t scookie; | ||
509 | xcb_randr_set_screen_config_reply_t *sreply; | ||
510 | |||
511 | scookie = | ||
512 | xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, | ||
513 | XCB_CURRENT_TIME, | ||
514 | reply->config_timestamp, | ||
515 | size_index, | ||
516 | reply->rotation, | ||
517 | reply->rate); | ||
518 | sreply = | ||
519 | xcb_randr_set_screen_config_reply(_ecore_xcb_conn, | ||
520 | scookie, NULL); | ||
521 | if (!sreply) | ||
522 | ret = EINA_FALSE; | ||
523 | else | ||
524 | { | ||
525 | ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? | ||
526 | EINA_TRUE : EINA_FALSE; | ||
527 | free(sreply); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | free(reply); | ||
532 | } | ||
533 | #endif | ||
534 | return ret; | ||
535 | } | ||
536 | |||
537 | /* | ||
538 | * @param root window which's primary output will be queried | ||
539 | * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 | ||
540 | */ | ||
541 | EAPI Ecore_X_Randr_Refresh_Rate | ||
542 | ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root) | ||
543 | { | ||
544 | #ifdef ECORE_XCB_RANDR | ||
545 | xcb_randr_get_screen_info_cookie_t cookie; | ||
546 | xcb_randr_get_screen_info_reply_t *reply; | ||
547 | Ecore_X_Randr_Refresh_Rate ret = 0.0; | ||
548 | #endif | ||
549 | |||
550 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
551 | CHECK_XCB_CONN; | ||
552 | |||
553 | #ifdef ECORE_XCB_RANDR | ||
554 | if (!_ecore_xcb_randr_root_validate(root)) return ret; | ||
555 | |||
556 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
557 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
558 | if (reply) | ||
559 | { | ||
560 | ret = reply->rate; | ||
561 | free(reply); | ||
562 | } | ||
563 | |||
564 | return ret; | ||
565 | #else | ||
566 | return 0.0; | ||
567 | #endif | ||
568 | } | ||
569 | |||
570 | /* | ||
571 | * @param root window which's primary output will be queried | ||
572 | * @param size_index referencing the size to query valid refresh rates for | ||
573 | * @return currently used refresh rate or - if request failed or RandRR is not available - NULL | ||
574 | */ | ||
575 | EAPI Ecore_X_Randr_Refresh_Rate * | ||
576 | ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, | ||
577 | int size_index, | ||
578 | int *num) | ||
579 | { | ||
580 | #ifdef ECORE_XCB_RANDR | ||
581 | xcb_randr_get_screen_info_cookie_t cookie; | ||
582 | xcb_randr_get_screen_info_reply_t *reply; | ||
583 | Ecore_X_Randr_Refresh_Rate *ret = NULL; | ||
584 | #endif | ||
585 | |||
586 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
587 | CHECK_XCB_CONN; | ||
588 | |||
589 | #ifdef ECORE_XCB_RANDR | ||
590 | if (!_ecore_xcb_randr_root_validate(root)) return ret; | ||
591 | |||
592 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
593 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
594 | if (reply) | ||
595 | { | ||
596 | int len = 0; | ||
597 | |||
598 | len = xcb_randr_get_screen_info_rates_length(reply); | ||
599 | if (num) *num = len; | ||
600 | |||
601 | ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len); | ||
602 | if (ret) | ||
603 | { | ||
604 | xcb_randr_refresh_rates_iterator_t iter; | ||
605 | int i = 0; | ||
606 | |||
607 | iter = xcb_randr_get_screen_info_rates_iterator(reply); | ||
608 | while (i++ < size_index) | ||
609 | xcb_randr_refresh_rates_next(&iter); | ||
610 | |||
611 | memcpy(ret, xcb_randr_refresh_rates_rates(iter.data), | ||
612 | sizeof(Ecore_X_Randr_Refresh_Rate) * len); | ||
613 | } | ||
614 | free(reply); | ||
615 | } | ||
616 | |||
617 | return ret; | ||
618 | #else | ||
619 | return NULL; | ||
620 | #endif | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | * @brief sets the current primary output's refresh rate | ||
625 | * @param root window which's primary output will be queried | ||
626 | * @param size_index referencing the size to be set | ||
627 | * @param rate the refresh rate to be set | ||
628 | * @return EINA_TRUE on success else EINA_FALSE | ||
629 | */ | ||
630 | EAPI Eina_Bool | ||
631 | ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, | ||
632 | int size_index, | ||
633 | Ecore_X_Randr_Refresh_Rate rate) | ||
634 | { | ||
635 | Eina_Bool ret = EINA_FALSE; | ||
636 | #ifdef ECORE_XCB_RANDR | ||
637 | xcb_randr_get_screen_info_cookie_t cookie; | ||
638 | xcb_randr_get_screen_info_reply_t *reply; | ||
639 | #endif | ||
640 | |||
641 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
642 | CHECK_XCB_CONN; | ||
643 | |||
644 | #ifdef ECORE_XCB_RANDR | ||
645 | if (_randr_version < RANDR_1_1) return EINA_FALSE; | ||
646 | |||
647 | cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); | ||
648 | reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); | ||
649 | if (reply) | ||
650 | { | ||
651 | xcb_randr_set_screen_config_cookie_t scookie; | ||
652 | xcb_randr_set_screen_config_reply_t *sreply; | ||
653 | |||
654 | scookie = | ||
655 | xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, | ||
656 | XCB_CURRENT_TIME, | ||
657 | reply->config_timestamp, | ||
658 | size_index, | ||
659 | reply->rotation, rate); | ||
660 | sreply = | ||
661 | xcb_randr_set_screen_config_reply(_ecore_xcb_conn, | ||
662 | scookie, NULL); | ||
663 | if (!sreply) | ||
664 | ret = EINA_FALSE; | ||
665 | else | ||
666 | { | ||
667 | ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? | ||
668 | EINA_TRUE : EINA_FALSE; | ||
669 | free(sreply); | ||
670 | } | ||
671 | free(reply); | ||
672 | } | ||
673 | #endif | ||
674 | |||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | /* | ||
679 | * @brief free detailed mode information. The pointer handed in will be set to | ||
680 | * NULL after freeing the memory. | ||
681 | * @param mode_info the mode information that should be freed | ||
682 | */ | ||
683 | EAPI void | ||
684 | ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) | ||
685 | { | ||
686 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
687 | CHECK_XCB_CONN; | ||
688 | |||
689 | RANDR_CHECK_1_2_RET(); | ||
690 | |||
691 | if (!mode_info) return; | ||
692 | |||
693 | if (mode_info->name) free(mode_info->name); | ||
694 | free(mode_info); | ||
695 | mode_info = NULL; | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * @param root window which's screen should be queried | ||
700 | * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None | ||
701 | */ | ||
702 | EAPI Ecore_X_Randr_Output | ||
703 | ecore_x_randr_primary_output_get(Ecore_X_Window root) | ||
704 | { | ||
705 | Ecore_X_Randr_Output ret = Ecore_X_Randr_None; | ||
706 | #ifdef ECORE_XCB_RANDR | ||
707 | xcb_randr_get_output_primary_cookie_t cookie; | ||
708 | xcb_randr_get_output_primary_reply_t *reply; | ||
709 | #endif | ||
710 | |||
711 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
712 | CHECK_XCB_CONN; | ||
713 | |||
714 | #ifdef ECORE_XCB_RANDR | ||
715 | RANDR_CHECK_1_3_RET(Ecore_X_Randr_None); | ||
716 | |||
717 | if (!_ecore_xcb_randr_root_validate(root)) | ||
718 | return Ecore_X_Randr_None; | ||
719 | |||
720 | cookie = xcb_randr_get_output_primary_unchecked(_ecore_xcb_conn, root); | ||
721 | reply = xcb_randr_get_output_primary_reply(_ecore_xcb_conn, cookie, NULL); | ||
722 | if (reply) | ||
723 | { | ||
724 | ret = reply->output; | ||
725 | free(reply); | ||
726 | } | ||
727 | #endif | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | /* | ||
732 | * @param root window which's screen should be queried | ||
733 | * @param output that should be set as given root window's screen primary output | ||
734 | */ | ||
735 | EAPI void | ||
736 | ecore_x_randr_primary_output_set(Ecore_X_Window root, | ||
737 | Ecore_X_Randr_Output output) | ||
738 | { | ||
739 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
740 | CHECK_XCB_CONN; | ||
741 | |||
742 | #ifdef ECORE_XCB_RANDR | ||
743 | RANDR_CHECK_1_3_RET(); | ||
744 | |||
745 | if ((output) && (_ecore_xcb_randr_root_validate(root))) | ||
746 | xcb_randr_set_output_primary(_ecore_xcb_conn, root, output); | ||
747 | #endif | ||
748 | } | ||
749 | |||
750 | EAPI Ecore_X_Randr_Mode * | ||
751 | ecore_x_randr_output_modes_get(Ecore_X_Window root, | ||
752 | Ecore_X_Randr_Output output, | ||
753 | int *num, | ||
754 | int *npreferred) | ||
755 | { | ||
756 | Ecore_X_Randr_Mode *modes = NULL; | ||
757 | |||
758 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
759 | CHECK_XCB_CONN; | ||
760 | |||
761 | #ifdef ECORE_XCB_RANDR | ||
762 | RANDR_CHECK_1_2_RET(NULL); | ||
763 | |||
764 | if (_randr_version >= RANDR_1_3) | ||
765 | { | ||
766 | modes = | ||
767 | _ecore_xcb_randr_13_output_modes_get(root, output, num, npreferred); | ||
768 | } | ||
769 | else if (_randr_version == RANDR_1_2) | ||
770 | { | ||
771 | modes = | ||
772 | _ecore_xcb_randr_12_output_modes_get(root, output, num, npreferred); | ||
773 | } | ||
774 | #endif | ||
775 | |||
776 | return modes; | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * @brief get detailed information for a given mode id | ||
781 | * @param root window which's screen's ressources are queried | ||
782 | * @param mode the XID which identifies the mode of interest | ||
783 | * @return mode's detailed information | ||
784 | */ | ||
785 | EAPI Ecore_X_Randr_Mode_Info * | ||
786 | ecore_x_randr_mode_info_get(Ecore_X_Window root, | ||
787 | Ecore_X_Randr_Mode mode) | ||
788 | { | ||
789 | Ecore_X_Randr_Mode_Info *ret = NULL; | ||
790 | |||
791 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
792 | CHECK_XCB_CONN; | ||
793 | |||
794 | #ifdef ECORE_XCB_RANDR | ||
795 | RANDR_CHECK_1_2_RET(NULL); | ||
796 | |||
797 | if (!_ecore_xcb_randr_root_validate(root)) return NULL; | ||
798 | |||
799 | if (_randr_version >= RANDR_1_3) | ||
800 | ret = _ecore_xcb_randr_13_mode_info_get(root, mode); | ||
801 | else if (_randr_version == RANDR_1_2) | ||
802 | ret = _ecore_xcb_randr_12_mode_info_get(root, mode); | ||
803 | #endif | ||
804 | return ret; | ||
805 | } | ||
806 | |||
807 | /* | ||
808 | * @brief get detailed information for all modes related to a root window's screen | ||
809 | * @param root window which's screen's ressources are queried | ||
810 | * @param num number of modes returned | ||
811 | * @return modes' information | ||
812 | */ | ||
813 | EAPI Ecore_X_Randr_Mode_Info ** | ||
814 | ecore_x_randr_modes_info_get(Ecore_X_Window root, | ||
815 | int *num) | ||
816 | { | ||
817 | Ecore_X_Randr_Mode_Info **ret = NULL; | ||
818 | |||
819 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
820 | CHECK_XCB_CONN; | ||
821 | |||
822 | if (num) *num = 0; | ||
823 | |||
824 | #ifdef ECORE_XCB_RANDR | ||
825 | RANDR_CHECK_1_2_RET(NULL); | ||
826 | |||
827 | if (!_ecore_xcb_randr_root_validate(root)) return NULL; | ||
828 | |||
829 | if (_randr_version >= RANDR_1_3) | ||
830 | ret = _ecore_xcb_randr_13_modes_info_get(root, num); | ||
831 | else if (_randr_version == RANDR_1_2) | ||
832 | ret = _ecore_xcb_randr_12_modes_info_get(root, num); | ||
833 | #endif | ||
834 | return ret; | ||
835 | } | ||
836 | |||
837 | /** | ||
838 | * @brief gets the width and hight of a given mode | ||
839 | * @param mode the mode which's size is to be looked up | ||
840 | * @param w width of given mode in px | ||
841 | * @param h height of given mode in px | ||
842 | */ | ||
843 | EAPI void | ||
844 | ecore_x_randr_mode_size_get(Ecore_X_Window root, | ||
845 | Ecore_X_Randr_Mode mode, | ||
846 | int *w, | ||
847 | int *h) | ||
848 | { | ||
849 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
850 | CHECK_XCB_CONN; | ||
851 | |||
852 | #ifdef ECORE_XCB_RANDR | ||
853 | RANDR_CHECK_1_2_RET(); | ||
854 | |||
855 | if (mode == Ecore_X_Randr_None) return; | ||
856 | |||
857 | if (_randr_version >= RANDR_1_3) | ||
858 | _ecore_xcb_randr_13_mode_size_get(root, mode, w, h); | ||
859 | else if (_randr_version == RANDR_1_2) | ||
860 | _ecore_xcb_randr_12_mode_size_get(root, mode, w, h); | ||
861 | #endif | ||
862 | } | ||
863 | |||
864 | /** | ||
865 | * @brief gets the EDID information of an attached output if available. | ||
866 | * Note that this information is not to be compared using ordinary string | ||
867 | * comparison functions, since it includes 0-bytes. | ||
868 | * @param root window this information should be queried from | ||
869 | * @param output the XID of the output | ||
870 | * @param length length of the byte-array. If NULL, request will fail. | ||
871 | */ | ||
872 | EAPI unsigned char * | ||
873 | ecore_x_randr_output_edid_get(Ecore_X_Window root, | ||
874 | Ecore_X_Randr_Output output, | ||
875 | unsigned long *length) | ||
876 | { | ||
877 | unsigned char *ret = NULL; | ||
878 | #ifdef ECORE_XCB_RANDR | ||
879 | xcb_randr_get_output_property_cookie_t cookie; | ||
880 | xcb_randr_get_output_property_reply_t *reply; | ||
881 | Ecore_X_Atom atom; | ||
882 | #endif | ||
883 | |||
884 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
885 | CHECK_XCB_CONN; | ||
886 | |||
887 | #ifdef ECORE_XCB_RANDR | ||
888 | RANDR_CHECK_1_2_RET(NULL); | ||
889 | |||
890 | if ((!length) || (!_ecore_xcb_randr_output_validate(root, output))) | ||
891 | return NULL; | ||
892 | |||
893 | atom = ecore_x_atom_get("EDID"); | ||
894 | cookie = | ||
895 | xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, output, atom, | ||
896 | XCB_GET_PROPERTY_TYPE_ANY, | ||
897 | 0, 100, 0, 0); | ||
898 | reply = | ||
899 | xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); | ||
900 | if (reply) | ||
901 | { | ||
902 | if ((reply->type == XCB_ATOM_INTEGER) && (reply->format == 8)) | ||
903 | { | ||
904 | if (length) *length = reply->num_items; | ||
905 | if ((ret = malloc(reply->num_items * sizeof(unsigned char)))) | ||
906 | { | ||
907 | memcpy(ret, xcb_randr_get_output_property_data(reply), | ||
908 | (reply->num_items * sizeof(unsigned char))); | ||
909 | } | ||
910 | } | ||
911 | free(reply); | ||
912 | } | ||
913 | #endif | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | /** | ||
918 | * @brief gets the the outputs which might be used simultenously on the same | ||
919 | * CRTC. | ||
920 | * @param root window that this information should be queried for. | ||
921 | * @param output the output which's clones we concern | ||
922 | * @param num number of possible clones | ||
923 | */ | ||
924 | EAPI Ecore_X_Randr_Output * | ||
925 | ecore_x_randr_output_clones_get(Ecore_X_Window root, | ||
926 | Ecore_X_Randr_Output output, | ||
927 | int *num) | ||
928 | { | ||
929 | Ecore_X_Randr_Output *outputs = NULL; | ||
930 | |||
931 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
932 | CHECK_XCB_CONN; | ||
933 | |||
934 | #ifdef ECORE_XCB_RANDR | ||
935 | RANDR_CHECK_1_2_RET(NULL); | ||
936 | |||
937 | if (output == Ecore_X_Randr_None) return NULL; | ||
938 | |||
939 | if (_randr_version >= RANDR_1_3) | ||
940 | outputs = _ecore_xcb_randr_13_output_clones_get(root, output, num); | ||
941 | else if (_randr_version == RANDR_1_2) | ||
942 | outputs = _ecore_xcb_randr_12_output_clones_get(root, output, num); | ||
943 | #endif | ||
944 | return outputs; | ||
945 | } | ||
946 | |||
947 | EAPI Ecore_X_Randr_Crtc * | ||
948 | ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, | ||
949 | Ecore_X_Randr_Output output, | ||
950 | int *num) | ||
951 | { | ||
952 | Ecore_X_Randr_Crtc *crtcs = NULL; | ||
953 | |||
954 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
955 | CHECK_XCB_CONN; | ||
956 | |||
957 | #ifdef ECORE_XCB_RANDR | ||
958 | RANDR_CHECK_1_2_RET(NULL); | ||
959 | |||
960 | if (output == Ecore_X_Randr_None) return NULL; | ||
961 | |||
962 | if (_randr_version >= RANDR_1_3) | ||
963 | crtcs = _ecore_xcb_randr_13_output_possible_crtcs_get(root, output, num); | ||
964 | else if (_randr_version == RANDR_1_2) | ||
965 | crtcs = _ecore_xcb_randr_12_output_possible_crtcs_get(root, output, num); | ||
966 | #endif | ||
967 | return crtcs; | ||
968 | } | ||
969 | |||
970 | /** | ||
971 | * @brief gets the given output's name as reported by X | ||
972 | * @param root the window which's screen will be queried | ||
973 | * @param len length of returned c-string. | ||
974 | * @return name of the output as reported by X | ||
975 | */ | ||
976 | EAPI char * | ||
977 | ecore_x_randr_output_name_get(Ecore_X_Window root, | ||
978 | Ecore_X_Randr_Output output, | ||
979 | int *len) | ||
980 | { | ||
981 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
982 | CHECK_XCB_CONN; | ||
983 | |||
984 | #ifdef ECORE_XCB_RANDR | ||
985 | RANDR_CHECK_1_2_RET(NULL); | ||
986 | |||
987 | if (output == Ecore_X_Randr_None) return NULL; | ||
988 | |||
989 | if (_randr_version >= RANDR_1_3) | ||
990 | return _ecore_xcb_randr_13_output_name_get(root, output, len); | ||
991 | else if (_randr_version == RANDR_1_2) | ||
992 | return _ecore_xcb_randr_12_output_name_get(root, output, len); | ||
993 | #endif | ||
994 | |||
995 | return NULL; | ||
996 | } | ||
997 | |||
998 | EAPI Ecore_X_Randr_Connection_Status | ||
999 | ecore_x_randr_output_connection_status_get(Ecore_X_Window root, | ||
1000 | Ecore_X_Randr_Output output) | ||
1001 | { | ||
1002 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1003 | CHECK_XCB_CONN; | ||
1004 | |||
1005 | #ifdef ECORE_XCB_RANDR | ||
1006 | RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); | ||
1007 | |||
1008 | if (output == Ecore_X_Randr_None) | ||
1009 | return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
1010 | |||
1011 | if (_randr_version >= RANDR_1_3) | ||
1012 | return _ecore_xcb_randr_13_output_connection_status_get(root, output); | ||
1013 | else if (_randr_version == RANDR_1_2) | ||
1014 | return _ecore_xcb_randr_12_output_connection_status_get(root, output); | ||
1015 | #endif | ||
1016 | |||
1017 | return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
1018 | } | ||
1019 | |||
1020 | EAPI Ecore_X_Randr_Output * | ||
1021 | ecore_x_randr_outputs_get(Ecore_X_Window root, | ||
1022 | int *num) | ||
1023 | { | ||
1024 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1025 | CHECK_XCB_CONN; | ||
1026 | |||
1027 | #ifdef ECORE_XCB_RANDR | ||
1028 | RANDR_CHECK_1_2_RET(NULL); | ||
1029 | |||
1030 | if (_randr_version >= RANDR_1_3) | ||
1031 | return _ecore_xcb_randr_13_outputs_get(root, num); | ||
1032 | else if (_randr_version == RANDR_1_2) | ||
1033 | return _ecore_xcb_randr_12_outputs_get(root, num); | ||
1034 | #endif | ||
1035 | |||
1036 | return NULL; | ||
1037 | } | ||
1038 | |||
1039 | EAPI Ecore_X_Randr_Crtc | ||
1040 | ecore_x_randr_output_crtc_get(Ecore_X_Window root, | ||
1041 | Ecore_X_Randr_Output output) | ||
1042 | { | ||
1043 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1044 | CHECK_XCB_CONN; | ||
1045 | |||
1046 | #ifdef ECORE_XCB_RANDR | ||
1047 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
1048 | |||
1049 | if (output == Ecore_X_Randr_None) return Ecore_X_Randr_None; | ||
1050 | |||
1051 | if (_randr_version >= RANDR_1_3) | ||
1052 | return _ecore_xcb_randr_13_output_crtc_get(root, output); | ||
1053 | else if (_randr_version == RANDR_1_2) | ||
1054 | return _ecore_xcb_randr_12_output_crtc_get(root, output); | ||
1055 | #endif | ||
1056 | |||
1057 | return Ecore_X_Randr_None; | ||
1058 | } | ||
1059 | |||
1060 | /** | ||
1061 | * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is | ||
1062 | * auto enabled in it's preferred mode, when it was disabled before. | ||
1063 | * @param root the root window which's default display will be queried | ||
1064 | * @param crtc the CRTC which's configuration should be altered | ||
1065 | * @param outputs an array of outputs, that should display this CRTC's content. | ||
1066 | * @param noutputs number of outputs in the array of outputs. | ||
1067 | * If set to Ecore_X_Randr_Unset, current outputs and number of outputs will be used. | ||
1068 | * If set to Ecore_X_Randr_None, CRTC will be disabled | ||
1069 | * @param x new x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x | ||
1070 | * corrdinate will be assumed. | ||
1071 | * @param y new y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y | ||
1072 | * corrdinate will be assumed. | ||
1073 | * @param mode the new mode to be set. If Ecore_X_Randr_None is passed, the | ||
1074 | * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is assumed. | ||
1075 | * @param orientation the new orientation to be set. If Ecore_X_Randr_Unset is used, | ||
1076 | * the current mode is assumed. | ||
1077 | * @return EINA_TRUE if the configuration alteration was successful, else | ||
1078 | * EINA_FALSE | ||
1079 | */ | ||
1080 | EAPI Eina_Bool | ||
1081 | ecore_x_randr_crtc_settings_set(Ecore_X_Window root, | ||
1082 | Ecore_X_Randr_Crtc crtc, | ||
1083 | Ecore_X_Randr_Output *outputs, | ||
1084 | int num, | ||
1085 | int x, | ||
1086 | int y, | ||
1087 | Ecore_X_Randr_Mode mode, | ||
1088 | Ecore_X_Randr_Orientation orientation) | ||
1089 | { | ||
1090 | Eina_Bool ret = EINA_FALSE; | ||
1091 | #ifdef ECORE_XCB_RANDR | ||
1092 | xcb_timestamp_t stamp = 0; | ||
1093 | xcb_randr_get_crtc_info_cookie_t ccookie; | ||
1094 | xcb_randr_get_crtc_info_reply_t *creply; | ||
1095 | #endif | ||
1096 | |||
1097 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1098 | CHECK_XCB_CONN; | ||
1099 | |||
1100 | #ifdef ECORE_XCB_RANDR | ||
1101 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1102 | |||
1103 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1104 | |||
1105 | if (_randr_version >= RANDR_1_3) | ||
1106 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1107 | else if (_randr_version == RANDR_1_2) | ||
1108 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1109 | |||
1110 | ccookie = | ||
1111 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1112 | creply = | ||
1113 | xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ccookie, NULL); | ||
1114 | if (creply) | ||
1115 | { | ||
1116 | xcb_randr_set_crtc_config_cookie_t scookie; | ||
1117 | xcb_randr_set_crtc_config_reply_t *sreply; | ||
1118 | |||
1119 | if ((mode == Ecore_X_Randr_None) || | ||
1120 | (num == Ecore_X_Randr_None)) | ||
1121 | { | ||
1122 | outputs = NULL; | ||
1123 | num = 0; | ||
1124 | } | ||
1125 | else if (num == (int)Ecore_X_Randr_Unset) | ||
1126 | { | ||
1127 | outputs = xcb_randr_get_crtc_info_outputs(creply); | ||
1128 | num = creply->num_outputs; | ||
1129 | } | ||
1130 | if ((int)mode == Ecore_X_Randr_Unset) mode = creply->mode; | ||
1131 | if (x < 0) x = creply->x; | ||
1132 | if (y < 0) y = creply->y; | ||
1133 | if ((int)orientation == Ecore_X_Randr_Unset) | ||
1134 | orientation = creply->rotation; | ||
1135 | |||
1136 | scookie = | ||
1137 | xcb_randr_set_crtc_config_unchecked(_ecore_xcb_conn, | ||
1138 | crtc, XCB_CURRENT_TIME, stamp, | ||
1139 | x, y, mode, orientation, | ||
1140 | num, outputs); | ||
1141 | sreply = | ||
1142 | xcb_randr_set_crtc_config_reply(_ecore_xcb_conn, scookie, NULL); | ||
1143 | if (sreply) | ||
1144 | { | ||
1145 | ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? | ||
1146 | EINA_TRUE : EINA_FALSE; | ||
1147 | free(sreply); | ||
1148 | } | ||
1149 | free(creply); | ||
1150 | } | ||
1151 | #endif | ||
1152 | |||
1153 | return ret; | ||
1154 | } | ||
1155 | |||
1156 | /** | ||
1157 | * @brief sets a mode for a CRTC and the outputs attached to it | ||
1158 | * @param root the window's screen to be queried | ||
1159 | * @param crtc the CRTC which shall be set | ||
1160 | * @param outputs array of outputs which have to be compatible with the mode. If | ||
1161 | * NULL CRTC will be disabled. | ||
1162 | * @param noutputs number of outputs in array to be used. Use | ||
1163 | * Ecore_X_Randr_Unset (or -1) to use currently used outputs. | ||
1164 | * @param mode XID of the mode to be set. If set to 0 the CRTC will be disabled. | ||
1165 | * If set to -1 the call will fail. | ||
1166 | * @return EINA_TRUE if mode setting was successful. Else EINA_FALSE | ||
1167 | */ | ||
1168 | EAPI Eina_Bool | ||
1169 | ecore_x_randr_crtc_mode_set(Ecore_X_Window root, | ||
1170 | Ecore_X_Randr_Crtc crtc, | ||
1171 | Ecore_X_Randr_Output *outputs, | ||
1172 | int num, | ||
1173 | Ecore_X_Randr_Mode mode) | ||
1174 | { | ||
1175 | Eina_Bool ret = EINA_FALSE; | ||
1176 | |||
1177 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1178 | CHECK_XCB_CONN; | ||
1179 | |||
1180 | #ifdef ECORE_XCB_RANDR | ||
1181 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1182 | |||
1183 | if ((int)mode == Ecore_X_Randr_Unset) return ret; | ||
1184 | ret = | ||
1185 | ecore_x_randr_crtc_settings_set(root, crtc, outputs, num, | ||
1186 | Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, | ||
1187 | mode, Ecore_X_Randr_Unset); | ||
1188 | #endif | ||
1189 | |||
1190 | return ret; | ||
1191 | } | ||
1192 | |||
1193 | /** | ||
1194 | * @brief Get the current set mode of a given CRTC | ||
1195 | * @param root the window's screen to be queried | ||
1196 | * @param crtc the CRTC which's should be queried | ||
1197 | * @return currently set mode or - in case parameters are invalid - | ||
1198 | * Ecore_X_Randr_Unset | ||
1199 | */ | ||
1200 | EAPI Ecore_X_Randr_Mode | ||
1201 | ecore_x_randr_crtc_mode_get(Ecore_X_Window root, | ||
1202 | Ecore_X_Randr_Crtc crtc) | ||
1203 | { | ||
1204 | Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; | ||
1205 | #ifdef ECORE_XCB_RANDR | ||
1206 | xcb_timestamp_t stamp = 0; | ||
1207 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1208 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1209 | #endif | ||
1210 | |||
1211 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1212 | CHECK_XCB_CONN; | ||
1213 | |||
1214 | #ifdef ECORE_XCB_RANDR | ||
1215 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); | ||
1216 | |||
1217 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1218 | |||
1219 | if (_randr_version >= RANDR_1_3) | ||
1220 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1221 | else if (_randr_version == RANDR_1_2) | ||
1222 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1223 | |||
1224 | ocookie = | ||
1225 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1226 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1227 | if (oreply) | ||
1228 | { | ||
1229 | ret = oreply->mode; | ||
1230 | free(oreply); | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | EAPI Ecore_X_Randr_Orientation | ||
1238 | ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, | ||
1239 | Ecore_X_Randr_Crtc crtc) | ||
1240 | { | ||
1241 | Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; | ||
1242 | #ifdef ECORE_XCB_RANDR | ||
1243 | xcb_timestamp_t stamp = 0; | ||
1244 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1245 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1246 | #endif | ||
1247 | |||
1248 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1249 | CHECK_XCB_CONN; | ||
1250 | |||
1251 | #ifdef ECORE_XCB_RANDR | ||
1252 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
1253 | |||
1254 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1255 | |||
1256 | if (_randr_version >= RANDR_1_3) | ||
1257 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1258 | else if (_randr_version == RANDR_1_2) | ||
1259 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1260 | |||
1261 | ocookie = | ||
1262 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1263 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1264 | if (oreply) | ||
1265 | { | ||
1266 | ret = oreply->rotation; | ||
1267 | free(oreply); | ||
1268 | } | ||
1269 | #endif | ||
1270 | |||
1271 | return ret; | ||
1272 | } | ||
1273 | |||
1274 | EAPI Eina_Bool | ||
1275 | ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, | ||
1276 | Ecore_X_Randr_Crtc crtc, | ||
1277 | Ecore_X_Randr_Orientation orientation) | ||
1278 | { | ||
1279 | Eina_Bool ret = EINA_FALSE; | ||
1280 | |||
1281 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1282 | CHECK_XCB_CONN; | ||
1283 | |||
1284 | #ifdef ECORE_XCB_RANDR | ||
1285 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1286 | |||
1287 | if (orientation != Ecore_X_Randr_None) | ||
1288 | { | ||
1289 | ret = | ||
1290 | ecore_x_randr_crtc_settings_set(root, crtc, NULL, | ||
1291 | Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, | ||
1292 | Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, | ||
1293 | orientation); | ||
1294 | } | ||
1295 | #endif | ||
1296 | return ret; | ||
1297 | } | ||
1298 | |||
1299 | EAPI Ecore_X_Randr_Orientation | ||
1300 | ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, | ||
1301 | Ecore_X_Randr_Crtc crtc) | ||
1302 | { | ||
1303 | Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; | ||
1304 | #ifdef ECORE_XCB_RANDR | ||
1305 | xcb_timestamp_t stamp = 0; | ||
1306 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1307 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1308 | #endif | ||
1309 | |||
1310 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1311 | CHECK_XCB_CONN; | ||
1312 | |||
1313 | #ifdef ECORE_XCB_RANDR | ||
1314 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
1315 | |||
1316 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1317 | |||
1318 | if (_randr_version >= RANDR_1_3) | ||
1319 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1320 | else if (_randr_version == RANDR_1_2) | ||
1321 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1322 | |||
1323 | ocookie = | ||
1324 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1325 | oreply = | ||
1326 | xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1327 | if (oreply) | ||
1328 | { | ||
1329 | ret = oreply->rotations; | ||
1330 | free(oreply); | ||
1331 | } | ||
1332 | #endif | ||
1333 | |||
1334 | return ret; | ||
1335 | } | ||
1336 | |||
1337 | /* | ||
1338 | * @brief get a CRTC's possible outputs. | ||
1339 | * @param root the root window which's screen will be queried | ||
1340 | * @param num number of possible outputs referenced by given CRTC | ||
1341 | */ | ||
1342 | EAPI Ecore_X_Randr_Output * | ||
1343 | ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, | ||
1344 | Ecore_X_Randr_Crtc crtc, | ||
1345 | int *num) | ||
1346 | { | ||
1347 | Ecore_X_Randr_Output *ret = NULL; | ||
1348 | #ifdef ECORE_XCB_RANDR | ||
1349 | xcb_timestamp_t stamp = 0; | ||
1350 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1351 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1352 | #endif | ||
1353 | |||
1354 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1355 | CHECK_XCB_CONN; | ||
1356 | |||
1357 | #ifdef ECORE_XCB_RANDR | ||
1358 | RANDR_CHECK_1_2_RET(NULL); | ||
1359 | |||
1360 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1361 | |||
1362 | if (_randr_version >= RANDR_1_3) | ||
1363 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1364 | else if (_randr_version == RANDR_1_2) | ||
1365 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1366 | |||
1367 | ocookie = | ||
1368 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1369 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1370 | if (oreply) | ||
1371 | { | ||
1372 | if (num) *num = oreply->num_possible_outputs; | ||
1373 | ret = malloc(sizeof(Ecore_X_Randr_Output) * | ||
1374 | oreply->num_possible_outputs); | ||
1375 | if (ret) | ||
1376 | { | ||
1377 | memcpy(ret, xcb_randr_get_crtc_info_possible(oreply), | ||
1378 | sizeof(Ecore_X_Randr_Output) * | ||
1379 | oreply->num_possible_outputs); | ||
1380 | } | ||
1381 | free(oreply); | ||
1382 | } | ||
1383 | #endif | ||
1384 | |||
1385 | return ret; | ||
1386 | } | ||
1387 | |||
1388 | /* | ||
1389 | * @brief get all known CRTCs related to a root window's screen | ||
1390 | * @param root window which's screen's ressources are queried | ||
1391 | * @param num number of CRTCs returned | ||
1392 | * @return CRTC IDs | ||
1393 | */ | ||
1394 | EAPI Ecore_X_Randr_Crtc * | ||
1395 | ecore_x_randr_crtcs_get(Ecore_X_Window root, | ||
1396 | int *num) | ||
1397 | { | ||
1398 | Ecore_X_Randr_Crtc *ret = NULL; | ||
1399 | |||
1400 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1401 | CHECK_XCB_CONN; | ||
1402 | |||
1403 | #ifdef ECORE_XCB_RANDR | ||
1404 | RANDR_CHECK_1_2_RET(NULL); | ||
1405 | |||
1406 | if (_randr_version >= RANDR_1_3) | ||
1407 | { | ||
1408 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
1409 | |||
1410 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
1411 | if (reply) | ||
1412 | { | ||
1413 | if (num) *num = reply->num_crtcs; | ||
1414 | ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); | ||
1415 | if (ret) | ||
1416 | memcpy(ret, xcb_randr_get_screen_resources_current_crtcs(reply), | ||
1417 | sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); | ||
1418 | free(reply); | ||
1419 | } | ||
1420 | } | ||
1421 | else if (_randr_version == RANDR_1_2) | ||
1422 | { | ||
1423 | xcb_randr_get_screen_resources_reply_t *reply; | ||
1424 | |||
1425 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
1426 | if (reply) | ||
1427 | { | ||
1428 | if (num) *num = reply->num_crtcs; | ||
1429 | ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); | ||
1430 | if (ret) | ||
1431 | memcpy(ret, xcb_randr_get_screen_resources_crtcs(reply), | ||
1432 | sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); | ||
1433 | free(reply); | ||
1434 | } | ||
1435 | } | ||
1436 | #endif | ||
1437 | |||
1438 | return ret; | ||
1439 | } | ||
1440 | |||
1441 | /* | ||
1442 | * @brief get a CRTC's outputs. | ||
1443 | * @param root the root window which's screen will be queried | ||
1444 | * @param num number of outputs referenced by given CRTC | ||
1445 | */ | ||
1446 | EAPI Ecore_X_Randr_Output * | ||
1447 | ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, | ||
1448 | Ecore_X_Randr_Crtc crtc, | ||
1449 | int *num) | ||
1450 | { | ||
1451 | Ecore_X_Randr_Output *ret = NULL; | ||
1452 | #ifdef ECORE_XCB_RANDR | ||
1453 | xcb_timestamp_t stamp = 0; | ||
1454 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1455 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1456 | #endif | ||
1457 | |||
1458 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1459 | CHECK_XCB_CONN; | ||
1460 | |||
1461 | #ifdef ECORE_XCB_RANDR | ||
1462 | RANDR_CHECK_1_2_RET(NULL); | ||
1463 | |||
1464 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; | ||
1465 | |||
1466 | if (_randr_version >= RANDR_1_3) | ||
1467 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1468 | else if (_randr_version == RANDR_1_2) | ||
1469 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1470 | |||
1471 | ocookie = | ||
1472 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1473 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1474 | if (oreply) | ||
1475 | { | ||
1476 | if (num) *num = oreply->num_outputs; | ||
1477 | ret = malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); | ||
1478 | if (ret) | ||
1479 | memcpy(ret, xcb_randr_get_crtc_info_outputs(oreply), | ||
1480 | sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); | ||
1481 | free(oreply); | ||
1482 | } | ||
1483 | #endif | ||
1484 | |||
1485 | return ret; | ||
1486 | } | ||
1487 | |||
1488 | EAPI void | ||
1489 | ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, | ||
1490 | Ecore_X_Randr_Crtc crtc, | ||
1491 | int *x, | ||
1492 | int *y, | ||
1493 | int *w, | ||
1494 | int *h) | ||
1495 | { | ||
1496 | #ifdef ECORE_XCB_RANDR | ||
1497 | xcb_timestamp_t stamp = 0; | ||
1498 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1499 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
1500 | #endif | ||
1501 | |||
1502 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1503 | CHECK_XCB_CONN; | ||
1504 | |||
1505 | #ifdef ECORE_XCB_RANDR | ||
1506 | RANDR_CHECK_1_2_RET(); | ||
1507 | |||
1508 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return; | ||
1509 | |||
1510 | if (_randr_version >= RANDR_1_3) | ||
1511 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1512 | else if (_randr_version == RANDR_1_2) | ||
1513 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1514 | |||
1515 | ocookie = | ||
1516 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); | ||
1517 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
1518 | if (oreply) | ||
1519 | { | ||
1520 | if (x) *x = oreply->x; | ||
1521 | if (y) *y = oreply->y; | ||
1522 | if (w) *w = oreply->width; | ||
1523 | if (h) *h = oreply->height; | ||
1524 | free(oreply); | ||
1525 | } | ||
1526 | #endif | ||
1527 | } | ||
1528 | |||
1529 | /** | ||
1530 | * @brief sets a CRTC relative to another one. | ||
1531 | * @param crtc_r1 the CRTC to be positioned. | ||
1532 | * @param crtc_r2 the CRTC the position should be relative to | ||
1533 | * @param position the relation between the crtcs | ||
1534 | * @param alignment in case CRTCs size differ, aligns CRTC1 accordingly at CRTC2's | ||
1535 | * borders | ||
1536 | * @return EINA_TRUE if crtc could be successfully positioned. EINA_FALSE if | ||
1537 | * repositioning failed or if position of new crtc would be out of given screen's min/max bounds. | ||
1538 | */ | ||
1539 | EAPI Eina_Bool | ||
1540 | ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, | ||
1541 | Ecore_X_Randr_Crtc crtc1, | ||
1542 | Ecore_X_Randr_Crtc crtc2, | ||
1543 | Ecore_X_Randr_Output_Policy policy, | ||
1544 | Ecore_X_Randr_Relative_Alignment alignment) | ||
1545 | { | ||
1546 | #ifdef ECORE_XCB_RANDR | ||
1547 | Eina_Rectangle r1, r2; | ||
1548 | int w_max = 0, h_max = 0, cw = 0, ch = 0, xn = -1, yn = -1; | ||
1549 | #endif | ||
1550 | |||
1551 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1552 | CHECK_XCB_CONN; | ||
1553 | |||
1554 | #ifdef ECORE_XCB_RANDR | ||
1555 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1556 | |||
1557 | if ((ecore_x_randr_crtc_mode_get(root, crtc1) == 0) || | ||
1558 | (ecore_x_randr_crtc_mode_get(root, crtc2) == 0)) | ||
1559 | return EINA_FALSE; | ||
1560 | |||
1561 | if ((!_ecore_xcb_randr_crtc_validate(root, crtc1) || | ||
1562 | (!(crtc1 != crtc2) && (!_ecore_xcb_randr_crtc_validate(root, crtc2))))) | ||
1563 | return EINA_FALSE; | ||
1564 | |||
1565 | ecore_x_randr_crtc_geometry_get(root, crtc1, &r1.x, &r1.y, &r1.w, &r1.h); | ||
1566 | ecore_x_randr_crtc_geometry_get(root, crtc2, &r2.x, &r2.y, &r2.w, &r2.h); | ||
1567 | ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); | ||
1568 | ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); | ||
1569 | |||
1570 | switch (policy) | ||
1571 | { | ||
1572 | case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: | ||
1573 | xn = (r2.x + r2.w); | ||
1574 | if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) | ||
1575 | yn = -1; | ||
1576 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) | ||
1577 | yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); | ||
1578 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) | ||
1579 | yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); | ||
1580 | break; | ||
1581 | |||
1582 | case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: | ||
1583 | xn = (r2.x - r1.w); | ||
1584 | if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) | ||
1585 | yn = -1; | ||
1586 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) | ||
1587 | yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); | ||
1588 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) | ||
1589 | yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); | ||
1590 | break; | ||
1591 | |||
1592 | case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: | ||
1593 | yn = (r2.y + r2.h); | ||
1594 | if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) | ||
1595 | xn = -1; | ||
1596 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) | ||
1597 | xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); | ||
1598 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) | ||
1599 | xn = ((int)((double)cw / 2.0)); | ||
1600 | break; | ||
1601 | |||
1602 | case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: | ||
1603 | yn = (r2.y - r1.h); | ||
1604 | if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) | ||
1605 | xn = -1; | ||
1606 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) | ||
1607 | xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); | ||
1608 | else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) | ||
1609 | xn = ((int)((double)cw / 2.0)); | ||
1610 | break; | ||
1611 | |||
1612 | case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: | ||
1613 | return ecore_x_randr_crtc_pos_set(root, crtc1, r2.x, r2.y); | ||
1614 | break; | ||
1615 | |||
1616 | case ECORE_X_RANDR_OUTPUT_POLICY_NONE: | ||
1617 | break; | ||
1618 | } | ||
1619 | |||
1620 | if ((xn == r1.x) && (yn == r1.x)) return EINA_TRUE; | ||
1621 | if (((yn + r1.h) > h_max) || ((xn + r1.w) > w_max)) | ||
1622 | return EINA_FALSE; | ||
1623 | |||
1624 | return ecore_x_randr_crtc_pos_set(root, crtc1, xn, yn); | ||
1625 | #endif | ||
1626 | |||
1627 | return EINA_FALSE; | ||
1628 | } | ||
1629 | |||
1630 | EAPI Eina_Bool | ||
1631 | ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, | ||
1632 | const Ecore_X_Randr_Crtc *not_moved, | ||
1633 | int num, | ||
1634 | int dx, | ||
1635 | int dy) | ||
1636 | { | ||
1637 | Eina_Bool ret = EINA_FALSE; | ||
1638 | #ifdef ECORE_XCB_RANDR | ||
1639 | Ecore_X_Randr_Crtc *crtcs = NULL, *move = NULL; | ||
1640 | int i = 0, j = 0, k = 0, n = 0, total = 0; | ||
1641 | #endif | ||
1642 | |||
1643 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1644 | CHECK_XCB_CONN; | ||
1645 | |||
1646 | #ifdef ECORE_XCB_RANDR | ||
1647 | if ((num <= 0) || (!not_moved) || (!_ecore_xcb_randr_root_validate(root))) | ||
1648 | return EINA_FALSE; | ||
1649 | |||
1650 | crtcs = ecore_x_randr_crtcs_get(root, &total); | ||
1651 | n = (total - num); | ||
1652 | move = malloc(sizeof(Ecore_X_Randr_Crtc) * n); | ||
1653 | if (move) | ||
1654 | { | ||
1655 | for (i = 0, k = 0; (i < total) && (k < n); i++) | ||
1656 | { | ||
1657 | for (j = 0; j < num; j++) | ||
1658 | if (crtcs[i] == not_moved[j]) break; | ||
1659 | if (j == num) | ||
1660 | move[k++] = crtcs[i]; | ||
1661 | } | ||
1662 | ret = ecore_x_randr_move_crtcs(root, move, n, dx, dy); | ||
1663 | free(move); | ||
1664 | free(crtcs); | ||
1665 | } | ||
1666 | #endif | ||
1667 | |||
1668 | return ret; | ||
1669 | } | ||
1670 | |||
1671 | EAPI void | ||
1672 | ecore_x_randr_crtc_pos_get(Ecore_X_Window root, | ||
1673 | Ecore_X_Randr_Crtc crtc, | ||
1674 | int *x, | ||
1675 | int *y) | ||
1676 | { | ||
1677 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1678 | CHECK_XCB_CONN; | ||
1679 | |||
1680 | #ifdef ECORE_XCB_RANDR | ||
1681 | RANDR_CHECK_1_2_RET(); | ||
1682 | |||
1683 | ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); | ||
1684 | #endif | ||
1685 | } | ||
1686 | |||
1687 | /* | ||
1688 | * @brief sets the position of given CRTC within root window's screen | ||
1689 | * @param root the window's screen to be queried | ||
1690 | * @param crtc the CRTC which's position within the mentioned screen is to be altered | ||
1691 | * @param x position on the x-axis (0 == left) of the screen. if x < 0 current value will be kept. | ||
1692 | * @param y position on the y-ayis (0 == top) of the screen. if y < 0, current value will be kept. | ||
1693 | * @return EINA_TRUE if position could be successfully be altered. | ||
1694 | */ | ||
1695 | EAPI Eina_Bool | ||
1696 | ecore_x_randr_crtc_pos_set(Ecore_X_Window root, | ||
1697 | Ecore_X_Randr_Crtc crtc, | ||
1698 | int x, | ||
1699 | int y) | ||
1700 | { | ||
1701 | Eina_Bool ret = EINA_FALSE; | ||
1702 | #ifdef ECORE_XCB_RANDR | ||
1703 | int w = 0, h = 0, nw = 0, nh = 0; | ||
1704 | Eina_Rectangle rect; | ||
1705 | #endif | ||
1706 | |||
1707 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1708 | CHECK_XCB_CONN; | ||
1709 | |||
1710 | #ifdef ECORE_XCB_RANDR | ||
1711 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1712 | |||
1713 | ecore_x_randr_crtc_geometry_get(root, crtc, | ||
1714 | &rect.x, &rect.y, &rect.w, &rect.h); | ||
1715 | ecore_x_randr_screen_current_size_get(root, &w, &h, NULL, NULL); | ||
1716 | if (x < 0) x = rect.x; | ||
1717 | if (y < 0) y = rect.y; | ||
1718 | if ((x + rect.w) > w) | ||
1719 | nw = (x + rect.w); | ||
1720 | if ((y + rect.h) > h) | ||
1721 | nh = (y + rect.h); | ||
1722 | |||
1723 | if ((nw != 0) || (nh != 0)) | ||
1724 | { | ||
1725 | if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0)) | ||
1726 | return EINA_FALSE; | ||
1727 | } | ||
1728 | |||
1729 | ret = ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1); | ||
1730 | #endif | ||
1731 | |||
1732 | return ret; | ||
1733 | } | ||
1734 | |||
1735 | EAPI void | ||
1736 | ecore_x_randr_crtc_size_get(Ecore_X_Window root, | ||
1737 | Ecore_X_Randr_Crtc crtc, | ||
1738 | int *w, | ||
1739 | int *h) | ||
1740 | { | ||
1741 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1742 | CHECK_XCB_CONN; | ||
1743 | |||
1744 | #ifdef ECORE_XCB_RANDR | ||
1745 | RANDR_CHECK_1_2_RET(); | ||
1746 | ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); | ||
1747 | #endif | ||
1748 | } | ||
1749 | |||
1750 | EAPI Ecore_X_Randr_Refresh_Rate | ||
1751 | ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, | ||
1752 | Ecore_X_Randr_Crtc crtc, | ||
1753 | Ecore_X_Randr_Mode mode) | ||
1754 | { | ||
1755 | Ecore_X_Randr_Refresh_Rate ret = 0.0; | ||
1756 | |||
1757 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1758 | CHECK_XCB_CONN; | ||
1759 | |||
1760 | #ifdef ECORE_XCB_RANDR | ||
1761 | RANDR_CHECK_1_2_RET(0.0); | ||
1762 | |||
1763 | if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return 0.0; | ||
1764 | |||
1765 | if (_randr_version >= RANDR_1_3) | ||
1766 | { | ||
1767 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
1768 | |||
1769 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
1770 | if (reply) | ||
1771 | { | ||
1772 | xcb_randr_mode_info_iterator_t miter; | ||
1773 | |||
1774 | miter = | ||
1775 | xcb_randr_get_screen_resources_current_modes_iterator(reply); | ||
1776 | while (miter.rem) | ||
1777 | { | ||
1778 | xcb_randr_mode_info_t *minfo; | ||
1779 | |||
1780 | minfo = miter.data; | ||
1781 | if (minfo->id == mode) | ||
1782 | { | ||
1783 | if ((minfo->htotal) && (minfo->vtotal)) | ||
1784 | { | ||
1785 | ret = ((double)minfo->dot_clock / | ||
1786 | ((double)minfo->htotal * | ||
1787 | (double)minfo->vtotal)); | ||
1788 | } | ||
1789 | break; | ||
1790 | } | ||
1791 | xcb_randr_mode_info_next(&miter); | ||
1792 | } | ||
1793 | free(reply); | ||
1794 | } | ||
1795 | } | ||
1796 | else if (_randr_version == RANDR_1_2) | ||
1797 | { | ||
1798 | xcb_randr_get_screen_resources_reply_t *reply; | ||
1799 | |||
1800 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
1801 | if (reply) | ||
1802 | { | ||
1803 | xcb_randr_mode_info_iterator_t miter; | ||
1804 | |||
1805 | miter = xcb_randr_get_screen_resources_modes_iterator(reply); | ||
1806 | while (miter.rem) | ||
1807 | { | ||
1808 | xcb_randr_mode_info_t *minfo; | ||
1809 | |||
1810 | minfo = miter.data; | ||
1811 | if (minfo->id == mode) | ||
1812 | { | ||
1813 | if ((minfo->htotal) && (minfo->vtotal)) | ||
1814 | { | ||
1815 | ret = ((double)minfo->dot_clock / | ||
1816 | ((double)minfo->htotal * | ||
1817 | (double)minfo->vtotal)); | ||
1818 | } | ||
1819 | break; | ||
1820 | } | ||
1821 | xcb_randr_mode_info_next(&miter); | ||
1822 | } | ||
1823 | free(reply); | ||
1824 | } | ||
1825 | } | ||
1826 | #endif | ||
1827 | return ret; | ||
1828 | } | ||
1829 | |||
1830 | /* | ||
1831 | * @brief move given CRTCs belonging to the given root window's screen dx/dy pixels relative to their current position. The screen size will be automatically adjusted if necessary and possible. | ||
1832 | * @param root window which's screen's resources are used | ||
1833 | * @param crtcs list of CRTCs to be moved | ||
1834 | * @param ncrtc number of CRTCs in array | ||
1835 | * @param dx amount of pixels the CRTCs should be moved in x direction | ||
1836 | * @param dy amount of pixels the CRTCs should be moved in y direction | ||
1837 | * @return EINA_TRUE if all crtcs could be moved successfully. | ||
1838 | */ | ||
1839 | EAPI Eina_Bool | ||
1840 | ecore_x_randr_move_crtcs(Ecore_X_Window root, | ||
1841 | const Ecore_X_Randr_Crtc *crtcs, | ||
1842 | int num, | ||
1843 | int dx, | ||
1844 | int dy) | ||
1845 | { | ||
1846 | Eina_Bool ret = EINA_TRUE; | ||
1847 | #ifdef ECORE_XCB_RANDR | ||
1848 | xcb_timestamp_t stamp = 0; | ||
1849 | xcb_randr_get_crtc_info_reply_t *oreply[num]; | ||
1850 | int i = 0, cw = 0, ch = 0; | ||
1851 | int mw = 0, mh = 0, nw = 0, nh = 0; | ||
1852 | #endif | ||
1853 | |||
1854 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1855 | CHECK_XCB_CONN; | ||
1856 | |||
1857 | #ifdef ECORE_XCB_RANDR | ||
1858 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1859 | |||
1860 | if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE; | ||
1861 | |||
1862 | if (_randr_version >= RANDR_1_3) | ||
1863 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1864 | else if (_randr_version == RANDR_1_2) | ||
1865 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1866 | |||
1867 | ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh); | ||
1868 | ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); | ||
1869 | nw = cw; | ||
1870 | nh = ch; | ||
1871 | |||
1872 | for (i = 0; i < num; i++) | ||
1873 | { | ||
1874 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
1875 | |||
1876 | ocookie = | ||
1877 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], | ||
1878 | stamp); | ||
1879 | oreply[i] = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, | ||
1880 | ocookie, NULL); | ||
1881 | if (oreply[i]) | ||
1882 | { | ||
1883 | if (((oreply[i]->x + dx) < 0) || | ||
1884 | ((oreply[i]->y + dy) < 0) || | ||
1885 | ((oreply[i]->x + oreply[i]->width + dx) > mw) || | ||
1886 | ((oreply[i]->y + oreply[i]->height + dy) > mh)) | ||
1887 | { | ||
1888 | continue; | ||
1889 | } | ||
1890 | nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw); | ||
1891 | nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh); | ||
1892 | } | ||
1893 | } | ||
1894 | |||
1895 | if ((nw > cw) || (nh > ch)) | ||
1896 | { | ||
1897 | if (!ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)) | ||
1898 | { | ||
1899 | for (i = 0; i < num; i++) | ||
1900 | if (oreply[i]) free(oreply[i]); | ||
1901 | |||
1902 | return EINA_FALSE; | ||
1903 | } | ||
1904 | } | ||
1905 | |||
1906 | for (i = 0; ((i < num) && (oreply[i])); i++) | ||
1907 | { | ||
1908 | if (!oreply[i]) continue; | ||
1909 | if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, | ||
1910 | (oreply[i]->x + dx), | ||
1911 | (oreply[i]->y + dy), | ||
1912 | oreply[i]->mode, | ||
1913 | oreply[i]->rotation)) | ||
1914 | { | ||
1915 | ret = EINA_FALSE; | ||
1916 | break; | ||
1917 | } | ||
1918 | } | ||
1919 | |||
1920 | if (i < num) | ||
1921 | { | ||
1922 | while (i-- >= 0) | ||
1923 | { | ||
1924 | if (oreply[i]) | ||
1925 | ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, | ||
1926 | (oreply[i]->x - dx), | ||
1927 | (oreply[i]->y - dy), | ||
1928 | oreply[i]->mode, | ||
1929 | oreply[i]->rotation); | ||
1930 | } | ||
1931 | } | ||
1932 | |||
1933 | for (i = 0; i < num; i++) | ||
1934 | if (oreply[i]) free(oreply[i]); | ||
1935 | #endif | ||
1936 | |||
1937 | return ret; | ||
1938 | } | ||
1939 | |||
1940 | /** | ||
1941 | * @brief enable event selection. This enables basic interaction with | ||
1942 | * output/crtc events and requires RRandR >= 1.2. | ||
1943 | * @param win select this window's properties for RandRR events | ||
1944 | * @param on enable/disable selecting | ||
1945 | */ | ||
1946 | EAPI void | ||
1947 | ecore_x_randr_events_select(Ecore_X_Window win, | ||
1948 | Eina_Bool on) | ||
1949 | { | ||
1950 | #ifdef ECORE_XCB_RANDR | ||
1951 | uint16_t mask = 0; | ||
1952 | #endif | ||
1953 | |||
1954 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1955 | CHECK_XCB_CONN; | ||
1956 | |||
1957 | #ifdef ECORE_XCB_RANDR | ||
1958 | if (on) | ||
1959 | { | ||
1960 | mask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE; | ||
1961 | if (_randr_version >= ((1 << 16) | 2)) | ||
1962 | { | ||
1963 | mask |= (XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | | ||
1964 | XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | | ||
1965 | XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); | ||
1966 | } | ||
1967 | } | ||
1968 | |||
1969 | xcb_randr_select_input(_ecore_xcb_conn, win, mask); | ||
1970 | #endif | ||
1971 | } | ||
1972 | |||
1973 | /** | ||
1974 | * @brief removes unused screen space. The most upper left CRTC is set to 0x0 | ||
1975 | * and all other CRTCs dx,dy respectively. | ||
1976 | * @param root the window's screen which will be reset. | ||
1977 | */ | ||
1978 | EAPI void | ||
1979 | ecore_x_randr_screen_reset(Ecore_X_Window root) | ||
1980 | { | ||
1981 | #ifdef ECORE_XCB_RANDR | ||
1982 | xcb_timestamp_t stamp = 0; | ||
1983 | Ecore_X_Randr_Crtc *crtcs = NULL; | ||
1984 | int total = 0, i = 0, w = 0, h = 0; | ||
1985 | int dx = 100000, dy = 100000, num = 0; | ||
1986 | #endif | ||
1987 | |||
1988 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
1989 | CHECK_XCB_CONN; | ||
1990 | |||
1991 | #ifdef ECORE_XCB_RANDR | ||
1992 | if (!_ecore_xcb_randr_root_validate(root)) return; | ||
1993 | crtcs = ecore_x_randr_crtcs_get(root, &total); | ||
1994 | |||
1995 | if (_randr_version >= RANDR_1_3) | ||
1996 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
1997 | else if (_randr_version == RANDR_1_2) | ||
1998 | stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); | ||
1999 | |||
2000 | /* I hate declaring variables inside code like this, but we need the | ||
2001 | * value of 'total' before we can */ | ||
2002 | Ecore_X_Randr_Crtc enabled[total]; | ||
2003 | |||
2004 | for (i = 0; i < total; i++) | ||
2005 | { | ||
2006 | xcb_randr_get_crtc_info_cookie_t ocookie; | ||
2007 | xcb_randr_get_crtc_info_reply_t *oreply; | ||
2008 | |||
2009 | ocookie = | ||
2010 | xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], stamp); | ||
2011 | oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, | ||
2012 | ocookie, NULL); | ||
2013 | if (!oreply) continue; | ||
2014 | if ((oreply->mode <= 0) || (oreply->num_outputs == 0)) | ||
2015 | { | ||
2016 | free(oreply); | ||
2017 | continue; | ||
2018 | } | ||
2019 | |||
2020 | enabled[num++] = crtcs[i]; | ||
2021 | if ((int)(oreply->x + oreply->width) > w) | ||
2022 | w = (oreply->x + oreply->width); | ||
2023 | if ((int)(oreply->y + oreply->height) > h) | ||
2024 | h = (oreply->y + oreply->height); | ||
2025 | |||
2026 | if (oreply->x < dx) dx = oreply->x; | ||
2027 | if (oreply->y < dy) dy = oreply->y; | ||
2028 | |||
2029 | free(oreply); | ||
2030 | } | ||
2031 | free(crtcs); | ||
2032 | |||
2033 | if ((dx > 0) || (dy > 0)) | ||
2034 | { | ||
2035 | if (ecore_x_randr_move_crtcs(root, enabled, num, -dx, -dy)) | ||
2036 | { | ||
2037 | w -= dx; | ||
2038 | h -= dy; | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | ecore_x_randr_screen_current_size_set(root, w, h, -1, -1); | ||
2043 | #endif | ||
2044 | } | ||
2045 | |||
2046 | /* | ||
2047 | * @param root window which's screen will be queried | ||
2048 | * @param wmin minimum width the screen can be set to | ||
2049 | * @param hmin minimum height the screen can be set to | ||
2050 | * @param wmax maximum width the screen can be set to | ||
2051 | * @param hmax maximum height the screen can be set to | ||
2052 | */ | ||
2053 | EAPI void | ||
2054 | ecore_x_randr_screen_size_range_get(Ecore_X_Window root, | ||
2055 | int *minw, | ||
2056 | int *minh, | ||
2057 | int *maxw, | ||
2058 | int *maxh) | ||
2059 | { | ||
2060 | #ifdef ECORE_XCB_RANDR | ||
2061 | xcb_randr_get_screen_size_range_cookie_t cookie; | ||
2062 | xcb_randr_get_screen_size_range_reply_t *reply; | ||
2063 | #endif | ||
2064 | |||
2065 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2066 | CHECK_XCB_CONN; | ||
2067 | |||
2068 | #ifdef ECORE_XCB_RANDR | ||
2069 | RANDR_CHECK_1_2_RET(); | ||
2070 | |||
2071 | cookie = xcb_randr_get_screen_size_range_unchecked(_ecore_xcb_conn, root); | ||
2072 | reply = xcb_randr_get_screen_size_range_reply(_ecore_xcb_conn, cookie, NULL); | ||
2073 | if (reply) | ||
2074 | { | ||
2075 | if (minw) *minw = reply->min_width; | ||
2076 | if (minh) *minh = reply->min_height; | ||
2077 | if (maxw) *maxw = reply->max_width; | ||
2078 | if (maxh) *maxh = reply->max_height; | ||
2079 | free(reply); | ||
2080 | } | ||
2081 | #endif | ||
2082 | } | ||
2083 | |||
2084 | /* | ||
2085 | * @param w width of screen in px | ||
2086 | * @param h height of screen in px | ||
2087 | */ | ||
2088 | EAPI void | ||
2089 | ecore_x_randr_screen_current_size_get(Ecore_X_Window root, | ||
2090 | int *w, | ||
2091 | int *h, | ||
2092 | int *w_mm, | ||
2093 | int *h_mm) | ||
2094 | { | ||
2095 | #ifdef ECORE_XCB_RANDR | ||
2096 | Ecore_X_Randr_Screen scr = 0; | ||
2097 | xcb_screen_t *s; | ||
2098 | # define RANDR_VALIDATE_ROOT(screen, root) \ | ||
2099 | ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) | ||
2100 | #endif | ||
2101 | |||
2102 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2103 | CHECK_XCB_CONN; | ||
2104 | |||
2105 | #ifdef ECORE_XCB_RANDR | ||
2106 | RANDR_CHECK_1_2_RET(); | ||
2107 | |||
2108 | if (!RANDR_VALIDATE_ROOT(scr, root)) return; | ||
2109 | |||
2110 | s = ecore_x_screen_get(scr); | ||
2111 | if (w) *w = s->width_in_pixels; | ||
2112 | if (h) *h = s->height_in_pixels; | ||
2113 | if (w_mm) *w_mm = s->width_in_millimeters; | ||
2114 | if (h_mm) *h_mm = s->height_in_millimeters; | ||
2115 | #endif | ||
2116 | } | ||
2117 | |||
2118 | /* | ||
2119 | * @param root window which's screen's size should be set. If invalid (e.g. NULL) no action is taken. | ||
2120 | * @param w width in px the screen should be set to. If out of valid boundaries, current value is assumed. | ||
2121 | * @param h height in px the screen should be set to. If out of valid boundaries, current value is assumed. | ||
2122 | * @param w_mm width in mm the screen should be set to. If 0, current aspect is assumed. | ||
2123 | * @param h_mm height in mm the screen should be set to. If 0, current aspect is assumed. | ||
2124 | * @return EINA_TRUE if request was successfully sent or screen is already in | ||
2125 | * requested size, EINA_FALSE if parameters are invalid | ||
2126 | */ | ||
2127 | EAPI Eina_Bool | ||
2128 | ecore_x_randr_screen_current_size_set(Ecore_X_Window root, | ||
2129 | int w, | ||
2130 | int h, | ||
2131 | int w_mm, | ||
2132 | int h_mm) | ||
2133 | { | ||
2134 | Eina_Bool ret = EINA_TRUE; | ||
2135 | #ifdef ECORE_XCB_RANDR | ||
2136 | Ecore_X_Randr_Screen scr; | ||
2137 | int wc = 0, hc = 0, w_mm_c = 0, h_mm_c = 0; | ||
2138 | int mw = 0, mh = 0, xw = 0, xh = 0; | ||
2139 | # define RANDR_VALIDATE_ROOT(screen, root) \ | ||
2140 | ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) | ||
2141 | #endif | ||
2142 | |||
2143 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2144 | CHECK_XCB_CONN; | ||
2145 | |||
2146 | #ifdef ECORE_XCB_RANDR | ||
2147 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
2148 | |||
2149 | if (!RANDR_VALIDATE_ROOT(scr, root)) return EINA_FALSE; | ||
2150 | ecore_x_randr_screen_current_size_get(root, &wc, &hc, &w_mm_c, &h_mm_c); | ||
2151 | if ((w == wc) && (h == hc) && (w_mm == w_mm_c) && (h_mm == h_mm_c)) | ||
2152 | return EINA_TRUE; | ||
2153 | ecore_x_randr_screen_size_range_get(root, &mw, &mh, &xw, &xh); | ||
2154 | if (((w != 1) && ((w < mw) || (w > xw))) || | ||
2155 | ((h != -1) && ((h < mh) || (h > xh)))) return EINA_FALSE; | ||
2156 | |||
2157 | if (w <= 0) | ||
2158 | w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; | ||
2159 | if (h <= 0) | ||
2160 | h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; | ||
2161 | |||
2162 | /* NB: Hmmmm, xlib version divides w_mm by width ... that seems wrong */ | ||
2163 | if (w_mm <= 0) | ||
2164 | w_mm = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; | ||
2165 | if (h_mm <= 0) | ||
2166 | h_mm = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_millimeters; | ||
2167 | |||
2168 | xcb_randr_set_screen_size(_ecore_xcb_conn, root, w, h, w_mm, h_mm); | ||
2169 | #endif | ||
2170 | |||
2171 | return ret; | ||
2172 | } | ||
2173 | |||
2174 | /* | ||
2175 | * @brief get the outputs, which display a certain window | ||
2176 | * @param window window the displaying outputs shall be found for | ||
2177 | * @param num the number of outputs displaying the window | ||
2178 | * @return array of outputs that display a certain window. NULL if no outputs | ||
2179 | * was found that displays the specified window. | ||
2180 | */ | ||
2181 | EAPI Ecore_X_Randr_Output * | ||
2182 | ecore_x_randr_window_outputs_get(Ecore_X_Window window, | ||
2183 | int *num) | ||
2184 | { | ||
2185 | #ifdef ECORE_XCB_RANDR | ||
2186 | Ecore_X_Window root; | ||
2187 | Eina_Rectangle w_geo, c_geo; | ||
2188 | Ecore_X_Randr_Crtc *crtcs; | ||
2189 | Ecore_X_Randr_Mode mode; | ||
2190 | Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; | ||
2191 | int ncrtcs, noutputs, i, nret = 0; | ||
2192 | xcb_translate_coordinates_cookie_t cookie; | ||
2193 | xcb_translate_coordinates_reply_t *trans; | ||
2194 | #endif | ||
2195 | |||
2196 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2197 | CHECK_XCB_CONN; | ||
2198 | |||
2199 | if (num) *num = 0; | ||
2200 | |||
2201 | #ifdef ECORE_XCB_RANDR | ||
2202 | RANDR_CHECK_1_2_RET(NULL); | ||
2203 | |||
2204 | ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h); | ||
2205 | |||
2206 | root = ecore_x_window_root_get(window); | ||
2207 | crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); | ||
2208 | if (!crtcs) return NULL; | ||
2209 | |||
2210 | /* now get window RELATIVE to root window - thats what matters. */ | ||
2211 | cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0); | ||
2212 | trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); | ||
2213 | w_geo.x = trans->dst_x; | ||
2214 | w_geo.y = trans->dst_y; | ||
2215 | free(trans); | ||
2216 | |||
2217 | for (i = 0; i < ncrtcs; i++) | ||
2218 | { | ||
2219 | /* if crtc is not enabled, don't bother about it any further */ | ||
2220 | mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); | ||
2221 | if (mode == Ecore_X_Randr_None) continue; | ||
2222 | |||
2223 | ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y, | ||
2224 | &c_geo.w, &c_geo.h); | ||
2225 | if (eina_rectangles_intersect(&w_geo, &c_geo)) | ||
2226 | { | ||
2227 | outputs = | ||
2228 | ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs); | ||
2229 | /* The case below should be impossible, but for safety reasons | ||
2230 | * remains */ | ||
2231 | if (!outputs) | ||
2232 | { | ||
2233 | if (num) *num = 0; | ||
2234 | free(ret); | ||
2235 | free(crtcs); | ||
2236 | return NULL; | ||
2237 | } | ||
2238 | tret = realloc(ret, ((nret + noutputs) * | ||
2239 | sizeof(Ecore_X_Randr_Output))); | ||
2240 | if (!tret) | ||
2241 | { | ||
2242 | if (num) *num = 0; | ||
2243 | free(outputs); | ||
2244 | free(ret); | ||
2245 | free(crtcs); | ||
2246 | return NULL; | ||
2247 | } | ||
2248 | ret = tret; | ||
2249 | memcpy(&ret[nret], outputs, | ||
2250 | (noutputs * sizeof(Ecore_X_Randr_Output))); | ||
2251 | nret += noutputs; | ||
2252 | free(outputs); | ||
2253 | } | ||
2254 | } | ||
2255 | free(crtcs); | ||
2256 | |||
2257 | if (num) *num = nret; | ||
2258 | return ret; | ||
2259 | |||
2260 | #endif | ||
2261 | if (num) *num = 0; | ||
2262 | return NULL; | ||
2263 | } | ||
2264 | |||
2265 | /* | ||
2266 | * @brief get the backlight level of the given output | ||
2267 | * @param root window which's screen should be queried | ||
2268 | * @param output from which the backlight level should be retrieved | ||
2269 | * @return the backlight level | ||
2270 | */ | ||
2271 | EAPI double | ||
2272 | ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, | ||
2273 | Ecore_X_Randr_Output output) | ||
2274 | { | ||
2275 | #ifdef ECORE_XCB_RANDR | ||
2276 | Ecore_X_Atom _backlight; | ||
2277 | xcb_intern_atom_cookie_t acookie; | ||
2278 | xcb_intern_atom_reply_t *areply; | ||
2279 | xcb_randr_get_output_property_cookie_t cookie; | ||
2280 | xcb_randr_get_output_property_reply_t *reply; | ||
2281 | xcb_randr_query_output_property_cookie_t qcookie; | ||
2282 | xcb_randr_query_output_property_reply_t *qreply; | ||
2283 | double dvalue; | ||
2284 | long value, max, min; | ||
2285 | #endif | ||
2286 | |||
2287 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2288 | CHECK_XCB_CONN; | ||
2289 | |||
2290 | #ifdef ECORE_XCB_RANDR | ||
2291 | RANDR_CHECK_1_2_RET(-1); | ||
2292 | |||
2293 | acookie = | ||
2294 | xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, | ||
2295 | strlen("Backlight"), "Backlight"); | ||
2296 | areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); | ||
2297 | |||
2298 | if (!areply) | ||
2299 | { | ||
2300 | ERR("Backlight property is not suppported on this server or driver"); | ||
2301 | return -1; | ||
2302 | } | ||
2303 | else | ||
2304 | { | ||
2305 | _backlight = areply->atom; | ||
2306 | free(areply); | ||
2307 | } | ||
2308 | |||
2309 | if (!_ecore_xcb_randr_output_validate(root, output)) | ||
2310 | { | ||
2311 | ERR("Invalid output"); | ||
2312 | return -1; | ||
2313 | } | ||
2314 | |||
2315 | cookie = | ||
2316 | xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, | ||
2317 | output, _backlight, | ||
2318 | XCB_ATOM_NONE, 0, 4, 0, 0); | ||
2319 | reply = | ||
2320 | xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); | ||
2321 | if (!reply) | ||
2322 | { | ||
2323 | WRN("Backlight not supported on this output"); | ||
2324 | return -1; | ||
2325 | } | ||
2326 | |||
2327 | if ((reply->format != 32) || (reply->num_items != 1) || | ||
2328 | (reply->type != XCB_ATOM_INTEGER)) | ||
2329 | { | ||
2330 | free(reply); | ||
2331 | return -1; | ||
2332 | } | ||
2333 | |||
2334 | value = *((long *)xcb_randr_get_output_property_data(reply)); | ||
2335 | free (reply); | ||
2336 | |||
2337 | /* I have the current value of the backlight */ | ||
2338 | /* Now retrieve the min and max intensities of the output */ | ||
2339 | qcookie = | ||
2340 | xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, | ||
2341 | output, _backlight); | ||
2342 | qreply = | ||
2343 | xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); | ||
2344 | if (qreply) | ||
2345 | { | ||
2346 | dvalue = -1; | ||
2347 | if ((qreply->range) && | ||
2348 | (xcb_randr_query_output_property_valid_values_length(qreply) == 2)) | ||
2349 | { | ||
2350 | int32_t *vals; | ||
2351 | |||
2352 | vals = xcb_randr_query_output_property_valid_values(qreply); | ||
2353 | /* finally convert the current value in the interval [0..1] */ | ||
2354 | min = vals[0]; | ||
2355 | max = vals[1]; | ||
2356 | dvalue = ((double)(value - min)) / ((double)(max - min)); | ||
2357 | } | ||
2358 | free(qreply); | ||
2359 | return dvalue; | ||
2360 | } | ||
2361 | #endif | ||
2362 | return -1; | ||
2363 | } | ||
2364 | |||
2365 | /* | ||
2366 | * @brief set the backlight level of a given output | ||
2367 | * @param root window which's screen should be queried | ||
2368 | * @param output that should be set | ||
2369 | * @param level for which the backlight should be set | ||
2370 | * @return EINA_TRUE in case of success | ||
2371 | */ | ||
2372 | EAPI Eina_Bool | ||
2373 | ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, | ||
2374 | Ecore_X_Randr_Output output, | ||
2375 | double level) | ||
2376 | { | ||
2377 | #ifdef ECORE_XCB_RANDR | ||
2378 | Ecore_X_Atom _backlight; | ||
2379 | xcb_intern_atom_cookie_t acookie; | ||
2380 | xcb_intern_atom_reply_t *areply; | ||
2381 | xcb_randr_query_output_property_cookie_t qcookie; | ||
2382 | xcb_randr_query_output_property_reply_t *qreply; | ||
2383 | #endif | ||
2384 | |||
2385 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2386 | CHECK_XCB_CONN; | ||
2387 | |||
2388 | #ifdef ECORE_XCB_RANDR | ||
2389 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
2390 | |||
2391 | if ((level < 0) || (level > 1)) | ||
2392 | { | ||
2393 | ERR("Backlight level should be between 0 and 1"); | ||
2394 | return EINA_FALSE; | ||
2395 | } | ||
2396 | |||
2397 | if (!_ecore_xcb_randr_output_validate(root, output)) | ||
2398 | { | ||
2399 | ERR("Wrong output value"); | ||
2400 | return EINA_FALSE; | ||
2401 | } | ||
2402 | |||
2403 | acookie = | ||
2404 | xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, | ||
2405 | strlen("Backlight"), "Backlight"); | ||
2406 | areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); | ||
2407 | if (!areply) | ||
2408 | { | ||
2409 | WRN("Backlight property is not suppported on this server or driver"); | ||
2410 | return EINA_FALSE; | ||
2411 | } | ||
2412 | else | ||
2413 | { | ||
2414 | _backlight = areply->atom; | ||
2415 | free(areply); | ||
2416 | } | ||
2417 | |||
2418 | qcookie = | ||
2419 | xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, | ||
2420 | output, _backlight); | ||
2421 | qreply = | ||
2422 | xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); | ||
2423 | if (qreply) | ||
2424 | { | ||
2425 | if ((qreply->range) && (qreply->length == 2)) | ||
2426 | { | ||
2427 | int32_t *vals; | ||
2428 | double min, max, tmp; | ||
2429 | long n; | ||
2430 | |||
2431 | vals = xcb_randr_query_output_property_valid_values(qreply); | ||
2432 | min = vals[0]; | ||
2433 | max = vals[1]; | ||
2434 | tmp = (level * (max - min)) + min; | ||
2435 | n = tmp; | ||
2436 | if (n > max) n = max; | ||
2437 | if (n < min) n = min; | ||
2438 | xcb_randr_change_output_property(_ecore_xcb_conn, output, | ||
2439 | _backlight, XCB_ATOM_INTEGER, | ||
2440 | 32, XCB_PROP_MODE_REPLACE, | ||
2441 | 1, (unsigned char *)&n); | ||
2442 | ecore_x_flush(); // needed | ||
2443 | } | ||
2444 | |||
2445 | free(qreply); | ||
2446 | return EINA_TRUE; | ||
2447 | } | ||
2448 | #endif | ||
2449 | return EINA_FALSE; | ||
2450 | } | ||
2451 | |||
2452 | EAPI int | ||
2453 | ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length) | ||
2454 | { | ||
2455 | if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && | ||
2456 | (ecore_x_randr_edid_has_valid_header(edid, edid_length))) | ||
2457 | return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | | ||
2458 | edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; | ||
2459 | return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; | ||
2460 | } | ||
2461 | |||
2462 | EAPI char * | ||
2463 | ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length) | ||
2464 | { | ||
2465 | unsigned char *block = NULL; | ||
2466 | int version = 0; | ||
2467 | |||
2468 | version = ecore_x_randr_edid_version_get(edid, edid_length); | ||
2469 | if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; | ||
2470 | |||
2471 | _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) | ||
2472 | { | ||
2473 | if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) | ||
2474 | { | ||
2475 | char *name, *p; | ||
2476 | const char *edid_name; | ||
2477 | |||
2478 | edid_name = (const char *)block + | ||
2479 | _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; | ||
2480 | name = | ||
2481 | malloc(sizeof(char) * | ||
2482 | _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); | ||
2483 | if (!name) return NULL; | ||
2484 | |||
2485 | strncpy(name, edid_name, | ||
2486 | (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); | ||
2487 | name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; | ||
2488 | for (p = name; *p; p++) | ||
2489 | if ((*p < ' ') || (*p > '~')) *p = 0; | ||
2490 | |||
2491 | return name; | ||
2492 | } | ||
2493 | } | ||
2494 | return NULL; | ||
2495 | } | ||
2496 | |||
2497 | EAPI Eina_Bool | ||
2498 | ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length) | ||
2499 | { | ||
2500 | const unsigned char header[] = | ||
2501 | { | ||
2502 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 | ||
2503 | }; | ||
2504 | |||
2505 | if ((!edid) || (edid_length < 8)) return EINA_FALSE; | ||
2506 | if (!memcmp(edid, header, 8)) return EINA_TRUE; | ||
2507 | return EINA_FALSE; | ||
2508 | } | ||
2509 | |||
2510 | /* local functions */ | ||
2511 | static Eina_Bool | ||
2512 | _ecore_xcb_randr_output_validate(Ecore_X_Window root, | ||
2513 | Ecore_X_Randr_Output output) | ||
2514 | { | ||
2515 | Eina_Bool ret = EINA_FALSE; | ||
2516 | |||
2517 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2518 | CHECK_XCB_CONN; | ||
2519 | |||
2520 | #ifdef ECORE_XCB_RANDR | ||
2521 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
2522 | |||
2523 | if ((output) && (_ecore_xcb_randr_root_validate(root))) | ||
2524 | { | ||
2525 | if (_randr_version >= RANDR_1_3) | ||
2526 | { | ||
2527 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
2528 | |||
2529 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
2530 | if (reply) | ||
2531 | { | ||
2532 | int len = 0, i = 0; | ||
2533 | xcb_randr_output_t *outputs; | ||
2534 | |||
2535 | len = | ||
2536 | xcb_randr_get_screen_resources_current_outputs_length(reply); | ||
2537 | outputs = | ||
2538 | xcb_randr_get_screen_resources_current_outputs(reply); | ||
2539 | for (i = 0; i < len; i++) | ||
2540 | { | ||
2541 | if (outputs[i] == output) | ||
2542 | { | ||
2543 | ret = EINA_TRUE; | ||
2544 | break; | ||
2545 | } | ||
2546 | } | ||
2547 | free(reply); | ||
2548 | } | ||
2549 | } | ||
2550 | else if (_randr_version == RANDR_1_2) | ||
2551 | { | ||
2552 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2553 | |||
2554 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2555 | if (reply) | ||
2556 | { | ||
2557 | int len = 0, i = 0; | ||
2558 | xcb_randr_output_t *outputs; | ||
2559 | |||
2560 | len = xcb_randr_get_screen_resources_outputs_length(reply); | ||
2561 | outputs = xcb_randr_get_screen_resources_outputs(reply); | ||
2562 | for (i = 0; i < len; i++) | ||
2563 | { | ||
2564 | if (outputs[i] == output) | ||
2565 | { | ||
2566 | ret = EINA_TRUE; | ||
2567 | break; | ||
2568 | } | ||
2569 | } | ||
2570 | free(reply); | ||
2571 | } | ||
2572 | } | ||
2573 | } | ||
2574 | #endif | ||
2575 | return ret; | ||
2576 | } | ||
2577 | |||
2578 | /** | ||
2579 | * @brief validates a CRTC for a given root window's screen. | ||
2580 | * @param root the window which's default display will be queried | ||
2581 | * @param crtc the CRTC to be validated. | ||
2582 | * @return in case it is found EINA_TRUE will be returned. Else EINA_FALSE is returned. | ||
2583 | */ | ||
2584 | static Eina_Bool | ||
2585 | _ecore_xcb_randr_crtc_validate(Ecore_X_Window root, | ||
2586 | Ecore_X_Randr_Crtc crtc) | ||
2587 | { | ||
2588 | Eina_Bool ret = EINA_FALSE; | ||
2589 | |||
2590 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
2591 | CHECK_XCB_CONN; | ||
2592 | |||
2593 | #ifdef ECORE_XCB_RANDR | ||
2594 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
2595 | |||
2596 | if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset)) | ||
2597 | return ret; | ||
2598 | |||
2599 | if ((crtc) && (_ecore_xcb_randr_root_validate(root))) | ||
2600 | { | ||
2601 | if (_randr_version >= RANDR_1_3) | ||
2602 | { | ||
2603 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
2604 | |||
2605 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
2606 | if (reply) | ||
2607 | { | ||
2608 | int i = 0; | ||
2609 | xcb_randr_crtc_t *crtcs; | ||
2610 | |||
2611 | crtcs = xcb_randr_get_screen_resources_current_crtcs(reply); | ||
2612 | for (i = 0; i < reply->num_crtcs; i++) | ||
2613 | { | ||
2614 | if (crtcs[i] == crtc) | ||
2615 | { | ||
2616 | ret = EINA_TRUE; | ||
2617 | break; | ||
2618 | } | ||
2619 | } | ||
2620 | free(reply); | ||
2621 | } | ||
2622 | } | ||
2623 | else if (_randr_version == RANDR_1_2) | ||
2624 | { | ||
2625 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2626 | |||
2627 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2628 | if (reply) | ||
2629 | { | ||
2630 | int i = 0; | ||
2631 | xcb_randr_crtc_t *crtcs; | ||
2632 | |||
2633 | crtcs = xcb_randr_get_screen_resources_crtcs(reply); | ||
2634 | for (i = 0; i < reply->num_crtcs; i++) | ||
2635 | { | ||
2636 | if (crtcs[i] == crtc) | ||
2637 | { | ||
2638 | ret = EINA_TRUE; | ||
2639 | break; | ||
2640 | } | ||
2641 | } | ||
2642 | free(reply); | ||
2643 | } | ||
2644 | } | ||
2645 | } | ||
2646 | #endif | ||
2647 | |||
2648 | return ret; | ||
2649 | } | ||
2650 | |||
2651 | static Ecore_X_Randr_Mode * | ||
2652 | _ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, | ||
2653 | Ecore_X_Randr_Output output, | ||
2654 | int *num, | ||
2655 | int *npreferred) | ||
2656 | { | ||
2657 | Ecore_X_Randr_Mode *modes = NULL; | ||
2658 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2659 | |||
2660 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2661 | if (reply) | ||
2662 | { | ||
2663 | xcb_randr_get_output_info_cookie_t ocookie; | ||
2664 | xcb_randr_get_output_info_reply_t *oreply; | ||
2665 | |||
2666 | ocookie = | ||
2667 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
2668 | reply->config_timestamp); | ||
2669 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
2670 | ocookie, NULL); | ||
2671 | if (oreply) | ||
2672 | { | ||
2673 | if (num) *num = oreply->num_modes; | ||
2674 | if (npreferred) *npreferred = oreply->num_preferred; | ||
2675 | |||
2676 | modes = malloc(sizeof(Ecore_X_Randr_Mode) * | ||
2677 | oreply->num_modes); | ||
2678 | if (modes) | ||
2679 | { | ||
2680 | xcb_randr_mode_t *rmodes; | ||
2681 | int len = 0; | ||
2682 | |||
2683 | len = xcb_randr_get_output_info_modes_length(oreply); | ||
2684 | rmodes = xcb_randr_get_output_info_modes(oreply); | ||
2685 | memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); | ||
2686 | } | ||
2687 | free(oreply); | ||
2688 | } | ||
2689 | free(reply); | ||
2690 | } | ||
2691 | |||
2692 | return modes; | ||
2693 | } | ||
2694 | |||
2695 | static Ecore_X_Randr_Mode * | ||
2696 | _ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, | ||
2697 | Ecore_X_Randr_Output output, | ||
2698 | int *num, | ||
2699 | int *npreferred) | ||
2700 | { | ||
2701 | Ecore_X_Randr_Mode *modes = NULL; | ||
2702 | xcb_timestamp_t stamp = 0; | ||
2703 | xcb_randr_get_output_info_cookie_t ocookie; | ||
2704 | xcb_randr_get_output_info_reply_t *oreply; | ||
2705 | |||
2706 | stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); | ||
2707 | |||
2708 | ocookie = | ||
2709 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, stamp); | ||
2710 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL); | ||
2711 | if (oreply) | ||
2712 | { | ||
2713 | if (num) *num = oreply->num_modes; | ||
2714 | if (npreferred) *npreferred = oreply->num_preferred; | ||
2715 | |||
2716 | modes = malloc(sizeof(Ecore_X_Randr_Mode) * oreply->num_modes); | ||
2717 | if (modes) | ||
2718 | { | ||
2719 | xcb_randr_mode_t *rmodes; | ||
2720 | int len = 0; | ||
2721 | |||
2722 | len = xcb_randr_get_output_info_modes_length(oreply); | ||
2723 | rmodes = xcb_randr_get_output_info_modes(oreply); | ||
2724 | memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); | ||
2725 | } | ||
2726 | free(oreply); | ||
2727 | } | ||
2728 | |||
2729 | return modes; | ||
2730 | } | ||
2731 | |||
2732 | static Ecore_X_Randr_Mode_Info * | ||
2733 | _ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, | ||
2734 | Ecore_X_Randr_Mode mode) | ||
2735 | { | ||
2736 | Ecore_X_Randr_Mode_Info *ret = NULL; | ||
2737 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2738 | |||
2739 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2740 | if (reply) | ||
2741 | { | ||
2742 | if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
2743 | { | ||
2744 | uint8_t *nbuf; | ||
2745 | xcb_randr_mode_info_iterator_t miter; | ||
2746 | |||
2747 | nbuf = xcb_randr_get_screen_resources_names(reply); | ||
2748 | miter = xcb_randr_get_screen_resources_modes_iterator(reply); | ||
2749 | while (miter.rem) | ||
2750 | { | ||
2751 | xcb_randr_mode_info_t *minfo; | ||
2752 | |||
2753 | minfo = miter.data; | ||
2754 | nbuf += minfo->name_len; | ||
2755 | |||
2756 | if (minfo->id == mode) | ||
2757 | { | ||
2758 | ret->xid = minfo->id; | ||
2759 | ret->width = minfo->width; | ||
2760 | ret->height = minfo->height; | ||
2761 | ret->dotClock = minfo->dot_clock; | ||
2762 | ret->hSyncStart = minfo->hsync_start; | ||
2763 | ret->hSyncEnd = minfo->hsync_end; | ||
2764 | ret->hTotal = minfo->htotal; | ||
2765 | ret->vSyncStart = minfo->vsync_start; | ||
2766 | ret->vSyncEnd = minfo->vsync_end; | ||
2767 | ret->vTotal = minfo->vtotal; | ||
2768 | ret->modeFlags = minfo->mode_flags; | ||
2769 | |||
2770 | ret->name = NULL; | ||
2771 | ret->nameLength = minfo->name_len; | ||
2772 | if (ret->nameLength > 0) | ||
2773 | { | ||
2774 | ret->name = malloc(ret->nameLength + 1); | ||
2775 | if (ret->name) | ||
2776 | memcpy(ret->name, nbuf, ret->nameLength + 1); | ||
2777 | } | ||
2778 | |||
2779 | break; | ||
2780 | } | ||
2781 | xcb_randr_mode_info_next(&miter); | ||
2782 | } | ||
2783 | } | ||
2784 | |||
2785 | free(reply); | ||
2786 | } | ||
2787 | return ret; | ||
2788 | } | ||
2789 | |||
2790 | static Ecore_X_Randr_Mode_Info * | ||
2791 | _ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, | ||
2792 | Ecore_X_Randr_Mode mode) | ||
2793 | { | ||
2794 | Ecore_X_Randr_Mode_Info *ret = NULL; | ||
2795 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
2796 | |||
2797 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
2798 | if (reply) | ||
2799 | { | ||
2800 | if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
2801 | { | ||
2802 | uint8_t *nbuf; | ||
2803 | xcb_randr_mode_info_iterator_t miter; | ||
2804 | |||
2805 | nbuf = xcb_randr_get_screen_resources_current_names(reply); | ||
2806 | miter = | ||
2807 | xcb_randr_get_screen_resources_current_modes_iterator(reply); | ||
2808 | while (miter.rem) | ||
2809 | { | ||
2810 | xcb_randr_mode_info_t *minfo; | ||
2811 | |||
2812 | minfo = miter.data; | ||
2813 | nbuf += minfo->name_len; | ||
2814 | |||
2815 | if (minfo->id == mode) | ||
2816 | { | ||
2817 | ret->xid = minfo->id; | ||
2818 | ret->width = minfo->width; | ||
2819 | ret->height = minfo->height; | ||
2820 | ret->dotClock = minfo->dot_clock; | ||
2821 | ret->hSyncStart = minfo->hsync_start; | ||
2822 | ret->hSyncEnd = minfo->hsync_end; | ||
2823 | ret->hTotal = minfo->htotal; | ||
2824 | ret->vSyncStart = minfo->vsync_start; | ||
2825 | ret->vSyncEnd = minfo->vsync_end; | ||
2826 | ret->vTotal = minfo->vtotal; | ||
2827 | ret->modeFlags = minfo->mode_flags; | ||
2828 | |||
2829 | ret->name = NULL; | ||
2830 | ret->nameLength = minfo->name_len; | ||
2831 | if (ret->nameLength > 0) | ||
2832 | { | ||
2833 | ret->name = malloc(ret->nameLength + 1); | ||
2834 | if (ret->name) | ||
2835 | memcpy(ret->name, nbuf, ret->nameLength + 1); | ||
2836 | } | ||
2837 | |||
2838 | break; | ||
2839 | } | ||
2840 | xcb_randr_mode_info_next(&miter); | ||
2841 | } | ||
2842 | } | ||
2843 | |||
2844 | free(reply); | ||
2845 | } | ||
2846 | return ret; | ||
2847 | } | ||
2848 | |||
2849 | static Ecore_X_Randr_Mode_Info ** | ||
2850 | _ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, | ||
2851 | int *num) | ||
2852 | { | ||
2853 | Ecore_X_Randr_Mode_Info **ret = NULL; | ||
2854 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2855 | |||
2856 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2857 | if (reply) | ||
2858 | { | ||
2859 | if (num) *num = reply->num_modes; | ||
2860 | ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); | ||
2861 | if (ret) | ||
2862 | { | ||
2863 | xcb_randr_mode_info_iterator_t miter; | ||
2864 | int i = 0; | ||
2865 | uint8_t *nbuf; | ||
2866 | |||
2867 | nbuf = xcb_randr_get_screen_resources_names(reply); | ||
2868 | miter = xcb_randr_get_screen_resources_modes_iterator(reply); | ||
2869 | while (miter.rem) | ||
2870 | { | ||
2871 | xcb_randr_mode_info_t *minfo; | ||
2872 | |||
2873 | minfo = miter.data; | ||
2874 | nbuf += minfo->name_len; | ||
2875 | if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
2876 | { | ||
2877 | ret[i]->xid = minfo->id; | ||
2878 | ret[i]->width = minfo->width; | ||
2879 | ret[i]->height = minfo->height; | ||
2880 | ret[i]->dotClock = minfo->dot_clock; | ||
2881 | ret[i]->hSyncStart = minfo->hsync_start; | ||
2882 | ret[i]->hSyncEnd = minfo->hsync_end; | ||
2883 | ret[i]->hTotal = minfo->htotal; | ||
2884 | ret[i]->vSyncStart = minfo->vsync_start; | ||
2885 | ret[i]->vSyncEnd = minfo->vsync_end; | ||
2886 | ret[i]->vTotal = minfo->vtotal; | ||
2887 | ret[i]->modeFlags = minfo->mode_flags; | ||
2888 | |||
2889 | ret[i]->name = NULL; | ||
2890 | ret[i]->nameLength = minfo->name_len; | ||
2891 | if (ret[i]->nameLength > 0) | ||
2892 | { | ||
2893 | ret[i]->name = malloc(ret[i]->nameLength + 1); | ||
2894 | if (ret[i]->name) | ||
2895 | memcpy(ret[i]->name, nbuf, | ||
2896 | ret[i]->nameLength + 1); | ||
2897 | } | ||
2898 | } | ||
2899 | else | ||
2900 | { | ||
2901 | while (i > 0) | ||
2902 | free(ret[--i]); | ||
2903 | free(ret); | ||
2904 | ret = NULL; | ||
2905 | break; | ||
2906 | } | ||
2907 | i++; | ||
2908 | xcb_randr_mode_info_next(&miter); | ||
2909 | } | ||
2910 | } | ||
2911 | free(reply); | ||
2912 | } | ||
2913 | return ret; | ||
2914 | } | ||
2915 | |||
2916 | static Ecore_X_Randr_Mode_Info ** | ||
2917 | _ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, | ||
2918 | int *num) | ||
2919 | { | ||
2920 | Ecore_X_Randr_Mode_Info **ret = NULL; | ||
2921 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
2922 | |||
2923 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
2924 | if (reply) | ||
2925 | { | ||
2926 | if (num) *num = reply->num_modes; | ||
2927 | ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); | ||
2928 | if (ret) | ||
2929 | { | ||
2930 | xcb_randr_mode_info_iterator_t miter; | ||
2931 | int i = 0; | ||
2932 | uint8_t *nbuf; | ||
2933 | |||
2934 | nbuf = xcb_randr_get_screen_resources_current_names(reply); | ||
2935 | miter = | ||
2936 | xcb_randr_get_screen_resources_current_modes_iterator(reply); | ||
2937 | while (miter.rem) | ||
2938 | { | ||
2939 | xcb_randr_mode_info_t *minfo; | ||
2940 | |||
2941 | minfo = miter.data; | ||
2942 | nbuf += minfo->name_len; | ||
2943 | if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
2944 | { | ||
2945 | ret[i]->xid = minfo->id; | ||
2946 | ret[i]->width = minfo->width; | ||
2947 | ret[i]->height = minfo->height; | ||
2948 | ret[i]->dotClock = minfo->dot_clock; | ||
2949 | ret[i]->hSyncStart = minfo->hsync_start; | ||
2950 | ret[i]->hSyncEnd = minfo->hsync_end; | ||
2951 | ret[i]->hTotal = minfo->htotal; | ||
2952 | ret[i]->vSyncStart = minfo->vsync_start; | ||
2953 | ret[i]->vSyncEnd = minfo->vsync_end; | ||
2954 | ret[i]->vTotal = minfo->vtotal; | ||
2955 | ret[i]->modeFlags = minfo->mode_flags; | ||
2956 | |||
2957 | ret[i]->name = NULL; | ||
2958 | ret[i]->nameLength = minfo->name_len; | ||
2959 | if (ret[i]->nameLength > 0) | ||
2960 | { | ||
2961 | ret[i]->name = malloc(ret[i]->nameLength + 1); | ||
2962 | if (ret[i]->name) | ||
2963 | memcpy(ret[i]->name, nbuf, | ||
2964 | ret[i]->nameLength + 1); | ||
2965 | } | ||
2966 | } | ||
2967 | else | ||
2968 | { | ||
2969 | while (i > 0) | ||
2970 | free(ret[--i]); | ||
2971 | free(ret); | ||
2972 | ret = NULL; | ||
2973 | break; | ||
2974 | } | ||
2975 | i++; | ||
2976 | xcb_randr_mode_info_next(&miter); | ||
2977 | } | ||
2978 | } | ||
2979 | free(reply); | ||
2980 | } | ||
2981 | return ret; | ||
2982 | } | ||
2983 | |||
2984 | static void | ||
2985 | _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, | ||
2986 | Ecore_X_Randr_Mode mode, | ||
2987 | int *w, | ||
2988 | int *h) | ||
2989 | { | ||
2990 | xcb_randr_get_screen_resources_reply_t *reply; | ||
2991 | |||
2992 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
2993 | if (reply) | ||
2994 | { | ||
2995 | xcb_randr_mode_info_iterator_t miter; | ||
2996 | |||
2997 | miter = xcb_randr_get_screen_resources_modes_iterator(reply); | ||
2998 | while (miter.rem) | ||
2999 | { | ||
3000 | xcb_randr_mode_info_t *minfo; | ||
3001 | |||
3002 | minfo = miter.data; | ||
3003 | if (minfo->id == mode) | ||
3004 | { | ||
3005 | if (w) *w = minfo->width; | ||
3006 | if (h) *h = minfo->height; | ||
3007 | break; | ||
3008 | } | ||
3009 | xcb_randr_mode_info_next(&miter); | ||
3010 | } | ||
3011 | free(reply); | ||
3012 | } | ||
3013 | } | ||
3014 | |||
3015 | static void | ||
3016 | _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, | ||
3017 | Ecore_X_Randr_Mode mode, | ||
3018 | int *w, | ||
3019 | int *h) | ||
3020 | { | ||
3021 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3022 | |||
3023 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3024 | if (reply) | ||
3025 | { | ||
3026 | xcb_randr_mode_info_iterator_t miter; | ||
3027 | |||
3028 | miter = xcb_randr_get_screen_resources_current_modes_iterator(reply); | ||
3029 | while (miter.rem) | ||
3030 | { | ||
3031 | xcb_randr_mode_info_t *minfo; | ||
3032 | |||
3033 | minfo = miter.data; | ||
3034 | if (minfo->id == mode) | ||
3035 | { | ||
3036 | if (w) *w = minfo->width; | ||
3037 | if (h) *h = minfo->height; | ||
3038 | break; | ||
3039 | } | ||
3040 | xcb_randr_mode_info_next(&miter); | ||
3041 | } | ||
3042 | free(reply); | ||
3043 | } | ||
3044 | } | ||
3045 | |||
3046 | static Ecore_X_Randr_Output * | ||
3047 | _ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, | ||
3048 | Ecore_X_Randr_Output output, | ||
3049 | int *num) | ||
3050 | { | ||
3051 | Ecore_X_Randr_Output *outputs = NULL; | ||
3052 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3053 | |||
3054 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3055 | if (reply) | ||
3056 | { | ||
3057 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3058 | xcb_randr_get_output_info_reply_t *oreply; | ||
3059 | |||
3060 | ocookie = | ||
3061 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3062 | reply->config_timestamp); | ||
3063 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3064 | ocookie, NULL); | ||
3065 | if (oreply) | ||
3066 | { | ||
3067 | if (num) *num = oreply->num_clones; | ||
3068 | |||
3069 | outputs = | ||
3070 | malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); | ||
3071 | if (outputs) | ||
3072 | { | ||
3073 | memcpy(outputs, xcb_randr_get_output_info_clones(oreply), | ||
3074 | sizeof(Ecore_X_Randr_Output) * oreply->num_clones); | ||
3075 | } | ||
3076 | free(oreply); | ||
3077 | } | ||
3078 | free(reply); | ||
3079 | } | ||
3080 | return outputs; | ||
3081 | } | ||
3082 | |||
3083 | static Ecore_X_Randr_Output * | ||
3084 | _ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, | ||
3085 | Ecore_X_Randr_Output output, | ||
3086 | int *num) | ||
3087 | { | ||
3088 | Ecore_X_Randr_Output *outputs = NULL; | ||
3089 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3090 | |||
3091 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3092 | if (reply) | ||
3093 | { | ||
3094 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3095 | xcb_randr_get_output_info_reply_t *oreply; | ||
3096 | |||
3097 | ocookie = | ||
3098 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3099 | reply->config_timestamp); | ||
3100 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3101 | ocookie, NULL); | ||
3102 | if (oreply) | ||
3103 | { | ||
3104 | if (num) *num = oreply->num_clones; | ||
3105 | |||
3106 | outputs = | ||
3107 | malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); | ||
3108 | if (outputs) | ||
3109 | { | ||
3110 | memcpy(outputs, xcb_randr_get_output_info_clones(oreply), | ||
3111 | sizeof(Ecore_X_Randr_Output) * oreply->num_clones); | ||
3112 | } | ||
3113 | free(oreply); | ||
3114 | } | ||
3115 | free(reply); | ||
3116 | } | ||
3117 | return outputs; | ||
3118 | } | ||
3119 | |||
3120 | static Ecore_X_Randr_Crtc * | ||
3121 | _ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, | ||
3122 | Ecore_X_Randr_Output output, | ||
3123 | int *num) | ||
3124 | { | ||
3125 | Ecore_X_Randr_Crtc *crtcs = NULL; | ||
3126 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3127 | |||
3128 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3129 | if (reply) | ||
3130 | { | ||
3131 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3132 | xcb_randr_get_output_info_reply_t *oreply; | ||
3133 | |||
3134 | ocookie = | ||
3135 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3136 | reply->config_timestamp); | ||
3137 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3138 | ocookie, NULL); | ||
3139 | if (oreply) | ||
3140 | { | ||
3141 | if (num) *num = oreply->num_crtcs; | ||
3142 | |||
3143 | crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); | ||
3144 | if (crtcs) | ||
3145 | { | ||
3146 | memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), | ||
3147 | sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); | ||
3148 | } | ||
3149 | free(oreply); | ||
3150 | } | ||
3151 | free(reply); | ||
3152 | } | ||
3153 | return crtcs; | ||
3154 | } | ||
3155 | |||
3156 | static Ecore_X_Randr_Crtc * | ||
3157 | _ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, | ||
3158 | Ecore_X_Randr_Output output, | ||
3159 | int *num) | ||
3160 | { | ||
3161 | Ecore_X_Randr_Crtc *crtcs = NULL; | ||
3162 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3163 | |||
3164 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3165 | if (reply) | ||
3166 | { | ||
3167 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3168 | xcb_randr_get_output_info_reply_t *oreply; | ||
3169 | |||
3170 | ocookie = | ||
3171 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3172 | reply->config_timestamp); | ||
3173 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3174 | ocookie, NULL); | ||
3175 | if (oreply) | ||
3176 | { | ||
3177 | if (num) *num = oreply->num_crtcs; | ||
3178 | |||
3179 | crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); | ||
3180 | if (crtcs) | ||
3181 | { | ||
3182 | memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), | ||
3183 | sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); | ||
3184 | } | ||
3185 | free(oreply); | ||
3186 | } | ||
3187 | free(reply); | ||
3188 | } | ||
3189 | return crtcs; | ||
3190 | } | ||
3191 | |||
3192 | static char * | ||
3193 | _ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, | ||
3194 | Ecore_X_Randr_Output output, | ||
3195 | int *len) | ||
3196 | { | ||
3197 | char *ret = NULL; | ||
3198 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3199 | |||
3200 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3201 | if (reply) | ||
3202 | { | ||
3203 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3204 | xcb_randr_get_output_info_reply_t *oreply; | ||
3205 | |||
3206 | ocookie = | ||
3207 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3208 | reply->config_timestamp); | ||
3209 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3210 | ocookie, NULL); | ||
3211 | if (oreply) | ||
3212 | { | ||
3213 | uint8_t *nbuf; | ||
3214 | |||
3215 | nbuf = xcb_randr_get_output_info_name(oreply); | ||
3216 | nbuf += oreply->name_len; | ||
3217 | |||
3218 | if (len) *len = oreply->name_len; | ||
3219 | if (oreply->name_len > 0) | ||
3220 | { | ||
3221 | ret = malloc(oreply->name_len + 1); | ||
3222 | if (ret) | ||
3223 | memcpy(ret, nbuf, oreply->name_len + 1); | ||
3224 | } | ||
3225 | |||
3226 | free(oreply); | ||
3227 | } | ||
3228 | free(reply); | ||
3229 | } | ||
3230 | return ret; | ||
3231 | } | ||
3232 | |||
3233 | static char * | ||
3234 | _ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, | ||
3235 | Ecore_X_Randr_Output output, | ||
3236 | int *len) | ||
3237 | { | ||
3238 | char *ret = NULL; | ||
3239 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3240 | |||
3241 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3242 | if (reply) | ||
3243 | { | ||
3244 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3245 | xcb_randr_get_output_info_reply_t *oreply; | ||
3246 | |||
3247 | ocookie = | ||
3248 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3249 | reply->config_timestamp); | ||
3250 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3251 | ocookie, NULL); | ||
3252 | if (oreply) | ||
3253 | { | ||
3254 | uint8_t *nbuf; | ||
3255 | |||
3256 | nbuf = xcb_randr_get_output_info_name(oreply); | ||
3257 | nbuf += oreply->name_len; | ||
3258 | |||
3259 | if (len) *len = oreply->name_len; | ||
3260 | if (oreply->name_len > 0) | ||
3261 | { | ||
3262 | ret = malloc(oreply->name_len + 1); | ||
3263 | if (ret) | ||
3264 | memcpy(ret, nbuf, oreply->name_len + 1); | ||
3265 | } | ||
3266 | |||
3267 | free(oreply); | ||
3268 | } | ||
3269 | free(reply); | ||
3270 | } | ||
3271 | return ret; | ||
3272 | } | ||
3273 | |||
3274 | static Ecore_X_Randr_Connection_Status | ||
3275 | _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, | ||
3276 | Ecore_X_Randr_Output output) | ||
3277 | { | ||
3278 | Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
3279 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3280 | |||
3281 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3282 | if (reply) | ||
3283 | { | ||
3284 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3285 | xcb_randr_get_output_info_reply_t *oreply; | ||
3286 | |||
3287 | ocookie = | ||
3288 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3289 | reply->config_timestamp); | ||
3290 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3291 | ocookie, NULL); | ||
3292 | if (oreply) | ||
3293 | { | ||
3294 | ret = oreply->connection; | ||
3295 | free(oreply); | ||
3296 | } | ||
3297 | free(reply); | ||
3298 | } | ||
3299 | return ret; | ||
3300 | } | ||
3301 | |||
3302 | static Ecore_X_Randr_Connection_Status | ||
3303 | _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, | ||
3304 | Ecore_X_Randr_Output output) | ||
3305 | { | ||
3306 | Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
3307 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3308 | |||
3309 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3310 | if (reply) | ||
3311 | { | ||
3312 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3313 | xcb_randr_get_output_info_reply_t *oreply; | ||
3314 | |||
3315 | ocookie = | ||
3316 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3317 | reply->config_timestamp); | ||
3318 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3319 | ocookie, NULL); | ||
3320 | if (oreply) | ||
3321 | { | ||
3322 | ret = oreply->connection; | ||
3323 | free(oreply); | ||
3324 | } | ||
3325 | free(reply); | ||
3326 | } | ||
3327 | return ret; | ||
3328 | } | ||
3329 | |||
3330 | static Ecore_X_Randr_Output * | ||
3331 | _ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, | ||
3332 | int *num) | ||
3333 | { | ||
3334 | Ecore_X_Randr_Output *ret = NULL; | ||
3335 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3336 | |||
3337 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3338 | if (reply) | ||
3339 | { | ||
3340 | if (num) *num = reply->num_outputs; | ||
3341 | ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); | ||
3342 | if (ret) | ||
3343 | memcpy(ret, xcb_randr_get_screen_resources_outputs(reply), | ||
3344 | sizeof(Ecore_X_Randr_Output) * reply->num_outputs); | ||
3345 | free(reply); | ||
3346 | } | ||
3347 | return ret; | ||
3348 | } | ||
3349 | |||
3350 | static Ecore_X_Randr_Output * | ||
3351 | _ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, | ||
3352 | int *num) | ||
3353 | { | ||
3354 | Ecore_X_Randr_Output *ret = NULL; | ||
3355 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3356 | |||
3357 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3358 | if (reply) | ||
3359 | { | ||
3360 | if (num) *num = reply->num_outputs; | ||
3361 | ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); | ||
3362 | if (ret) | ||
3363 | memcpy(ret, xcb_randr_get_screen_resources_current_outputs(reply), | ||
3364 | sizeof(Ecore_X_Randr_Output) * reply->num_outputs); | ||
3365 | free(reply); | ||
3366 | } | ||
3367 | return ret; | ||
3368 | } | ||
3369 | |||
3370 | static Ecore_X_Randr_Crtc | ||
3371 | _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, | ||
3372 | Ecore_X_Randr_Output output) | ||
3373 | { | ||
3374 | Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; | ||
3375 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3376 | |||
3377 | reply = _ecore_xcb_randr_12_get_resources(root); | ||
3378 | if (reply) | ||
3379 | { | ||
3380 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3381 | xcb_randr_get_output_info_reply_t *oreply; | ||
3382 | |||
3383 | ocookie = | ||
3384 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3385 | reply->config_timestamp); | ||
3386 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3387 | ocookie, NULL); | ||
3388 | if (oreply) | ||
3389 | { | ||
3390 | ret = oreply->crtc; | ||
3391 | free(oreply); | ||
3392 | } | ||
3393 | free(reply); | ||
3394 | } | ||
3395 | return ret; | ||
3396 | } | ||
3397 | |||
3398 | static Ecore_X_Randr_Crtc | ||
3399 | _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, | ||
3400 | Ecore_X_Randr_Output output) | ||
3401 | { | ||
3402 | Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; | ||
3403 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3404 | |||
3405 | reply = _ecore_xcb_randr_13_get_resources(root); | ||
3406 | if (reply) | ||
3407 | { | ||
3408 | xcb_randr_get_output_info_cookie_t ocookie; | ||
3409 | xcb_randr_get_output_info_reply_t *oreply; | ||
3410 | |||
3411 | ocookie = | ||
3412 | xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, | ||
3413 | reply->config_timestamp); | ||
3414 | oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, | ||
3415 | ocookie, NULL); | ||
3416 | if (oreply) | ||
3417 | { | ||
3418 | ret = oreply->crtc; | ||
3419 | free(oreply); | ||
3420 | } | ||
3421 | free(reply); | ||
3422 | } | ||
3423 | return ret; | ||
3424 | } | ||
3425 | |||
3426 | static xcb_randr_get_screen_resources_reply_t * | ||
3427 | _ecore_xcb_randr_12_get_resources(Ecore_X_Window win) | ||
3428 | { | ||
3429 | xcb_randr_get_screen_resources_cookie_t cookie; | ||
3430 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3431 | |||
3432 | cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, win); | ||
3433 | reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); | ||
3434 | return reply; | ||
3435 | } | ||
3436 | |||
3437 | static xcb_randr_get_screen_resources_current_reply_t * | ||
3438 | _ecore_xcb_randr_13_get_resources(Ecore_X_Window win) | ||
3439 | { | ||
3440 | xcb_randr_get_screen_resources_current_cookie_t cookie; | ||
3441 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3442 | |||
3443 | cookie = | ||
3444 | xcb_randr_get_screen_resources_current_unchecked(_ecore_xcb_conn, win); | ||
3445 | reply = | ||
3446 | xcb_randr_get_screen_resources_current_reply(_ecore_xcb_conn, | ||
3447 | cookie, NULL); | ||
3448 | return reply; | ||
3449 | } | ||
3450 | |||
3451 | static xcb_timestamp_t | ||
3452 | _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win) | ||
3453 | { | ||
3454 | xcb_timestamp_t stamp = 0; | ||
3455 | xcb_randr_get_screen_resources_reply_t *reply; | ||
3456 | |||
3457 | reply = _ecore_xcb_randr_12_get_resources(win); | ||
3458 | stamp = reply->config_timestamp; | ||
3459 | free(reply); | ||
3460 | return stamp; | ||
3461 | } | ||
3462 | |||
3463 | static xcb_timestamp_t | ||
3464 | _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win) | ||
3465 | { | ||
3466 | xcb_timestamp_t stamp = 0; | ||
3467 | xcb_randr_get_screen_resources_current_reply_t *reply; | ||
3468 | |||
3469 | reply = _ecore_xcb_randr_13_get_resources(win); | ||
3470 | stamp = reply->config_timestamp; | ||
3471 | free(reply); | ||
3472 | return stamp; | ||
3473 | } | ||
3474 | |||