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