diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c')
-rw-r--r-- | libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c | 2360 |
1 files changed, 0 insertions, 2360 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c deleted file mode 100644 index ec23b3c..0000000 --- a/libraries/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c +++ /dev/null | |||
@@ -1,2360 +0,0 @@ | |||
1 | /* | ||
2 | * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 | ||
3 | */ | ||
4 | |||
5 | #ifdef HAVE_CONFIG_H | ||
6 | # include <config.h> | ||
7 | #endif | ||
8 | |||
9 | #include "ecore_x_private.h" | ||
10 | #include "ecore_x_randr.h" | ||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <unistd.h> | ||
14 | #include <string.h> | ||
15 | |||
16 | #define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0 | ||
17 | #define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1 | ||
18 | |||
19 | #ifdef ECORE_XRANDR | ||
20 | |||
21 | #define RANDR_1_2 ((1 << 16) | 2) | ||
22 | |||
23 | #define RANDR_VALIDATE_ROOT(screen, root) \ | ||
24 | ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1) | ||
25 | |||
26 | #define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \ | ||
27 | return ret | ||
28 | |||
29 | #define RANDR_PROPERTY_EDID "EDID" | ||
30 | #define RANDR_PROPERTY_BACKLIGHT "Backlight" | ||
31 | #define RANDR_PROPERTY_SIGNAL_FORMAT "SignalFormat" | ||
32 | #define RANDR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" | ||
33 | #define RANDR_PROPERTY_CONNECTOR_TYPE "ConnectorType" | ||
34 | #define RANDR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" | ||
35 | #define RANDR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" | ||
36 | #define RANDR_PROPERTY_CLONE_LIST "CloneList" | ||
37 | |||
38 | extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * | ||
39 | dpy, | ||
40 | Window | ||
41 | window); | ||
42 | extern int _randr_version; | ||
43 | #endif | ||
44 | |||
45 | /** | ||
46 | * @brief enable event selection. This enables basic interaction with | ||
47 | * output/crtc events and requires RRandR >= 1.2. | ||
48 | * @param win select this window's properties for RandRR events | ||
49 | * @param on enable/disable selecting | ||
50 | */ | ||
51 | EAPI void | ||
52 | ecore_x_randr_events_select(Ecore_X_Window win, | ||
53 | Eina_Bool on) | ||
54 | { | ||
55 | #ifdef ECORE_XRANDR | ||
56 | int mask; | ||
57 | |||
58 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
59 | if (!on) | ||
60 | mask = 0; | ||
61 | else | ||
62 | { | ||
63 | mask = RRScreenChangeNotifyMask; | ||
64 | if (_randr_version >= RANDR_1_2) | ||
65 | mask |= (RRCrtcChangeNotifyMask | | ||
66 | RROutputChangeNotifyMask | | ||
67 | RROutputPropertyNotifyMask); | ||
68 | } | ||
69 | |||
70 | XRRSelectInput(_ecore_x_disp, win, mask); | ||
71 | #endif | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * @brief validates a CRTC for a given root window's screen. | ||
76 | * @param root the window which's default display will be queried | ||
77 | * @param crtc the CRTC to be validated. | ||
78 | * @return in case it is found EINA_TRUE will be returned. Else EINA_FALSE is returned. | ||
79 | */ | ||
80 | static inline Eina_Bool | ||
81 | _ecore_x_randr_crtc_validate(Ecore_X_Window root, | ||
82 | Ecore_X_Randr_Crtc crtc) | ||
83 | { | ||
84 | #ifdef ECORE_XRANDR | ||
85 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
86 | |||
87 | XRRScreenResources *res = NULL; | ||
88 | int i; | ||
89 | Eina_Bool ret = EINA_FALSE; | ||
90 | |||
91 | if ((crtc == Ecore_X_Randr_None) || | ||
92 | (crtc == Ecore_X_Randr_Unset)) | ||
93 | return ret; | ||
94 | |||
95 | if (_ecore_x_randr_root_validate(root) && crtc && | ||
96 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
97 | { | ||
98 | for (i = 0; i < res->ncrtc; i++) | ||
99 | { | ||
100 | if (res->crtcs[i] == crtc) | ||
101 | { | ||
102 | ret = EINA_TRUE; | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | XRRFreeScreenResources(res); | ||
107 | } | ||
108 | |||
109 | return ret; | ||
110 | #else | ||
111 | return EINA_FALSE; | ||
112 | #endif | ||
113 | } | ||
114 | |||
115 | Eina_Bool | ||
116 | _ecore_x_randr_output_validate(Ecore_X_Window root, | ||
117 | Ecore_X_Randr_Output output) | ||
118 | { | ||
119 | #ifdef ECORE_XRANDR | ||
120 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
121 | |||
122 | Eina_Bool ret = EINA_FALSE; | ||
123 | XRRScreenResources *res = NULL; | ||
124 | int i; | ||
125 | |||
126 | if (_ecore_x_randr_root_validate(root) && output && | ||
127 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
128 | { | ||
129 | for (i = 0; i < res->noutput; i++) | ||
130 | { | ||
131 | if (res->outputs[i] == output) | ||
132 | { | ||
133 | ret = EINA_TRUE; | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | XRRFreeScreenResources(res); | ||
138 | } | ||
139 | |||
140 | return ret; | ||
141 | #else | ||
142 | return EINA_FALSE; | ||
143 | #endif | ||
144 | } | ||
145 | |||
146 | static inline Eina_Bool | ||
147 | _ecore_x_randr_mode_validate(Ecore_X_Window root, | ||
148 | Ecore_X_Randr_Mode mode) | ||
149 | { | ||
150 | #ifdef ECORE_XRANDR | ||
151 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
152 | |||
153 | Eina_Bool ret = EINA_FALSE; | ||
154 | XRRScreenResources *res = NULL; | ||
155 | int i; | ||
156 | |||
157 | if (_ecore_x_randr_root_validate(root) && mode && | ||
158 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
159 | { | ||
160 | for (i = 0; i < res->nmode; i++) | ||
161 | { | ||
162 | if (res->modes[i].id == mode) | ||
163 | { | ||
164 | ret = EINA_TRUE; | ||
165 | break; | ||
166 | } | ||
167 | } | ||
168 | XRRFreeScreenResources(res); | ||
169 | } | ||
170 | |||
171 | return ret; | ||
172 | #else | ||
173 | return EINA_FALSE; | ||
174 | #endif | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * @param w width of screen in px | ||
179 | * @param h height of screen in px | ||
180 | */ | ||
181 | EAPI void | ||
182 | ecore_x_randr_screen_current_size_get(Ecore_X_Window root, | ||
183 | int *w, | ||
184 | int *h, | ||
185 | int *w_mm, | ||
186 | int *h_mm) | ||
187 | { | ||
188 | #ifdef ECORE_XRANDR | ||
189 | RANDR_CHECK_1_2_RET(); | ||
190 | Ecore_X_Randr_Screen scr; | ||
191 | |||
192 | if (!RANDR_VALIDATE_ROOT(scr, root)) | ||
193 | return; | ||
194 | |||
195 | if (w) | ||
196 | *w = DisplayWidth(_ecore_x_disp, scr); | ||
197 | |||
198 | if (h) | ||
199 | *h = DisplayHeight(_ecore_x_disp, scr); | ||
200 | |||
201 | if (w_mm) | ||
202 | *w_mm = DisplayWidthMM(_ecore_x_disp, scr); | ||
203 | |||
204 | if (h_mm) | ||
205 | *h_mm = DisplayHeightMM(_ecore_x_disp, scr); | ||
206 | |||
207 | #endif | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * @param root window which's screen will be queried | ||
212 | * @param wmin minimum width the screen can be set to | ||
213 | * @param hmin minimum height the screen can be set to | ||
214 | * @param wmax maximum width the screen can be set to | ||
215 | * @param hmax maximum height the screen can be set to | ||
216 | */ | ||
217 | EAPI void | ||
218 | ecore_x_randr_screen_size_range_get(Ecore_X_Window root, | ||
219 | int *wmin, | ||
220 | int *hmin, | ||
221 | int *wmax, | ||
222 | int *hmax) | ||
223 | { | ||
224 | #ifdef ECORE_XRANDR | ||
225 | RANDR_CHECK_1_2_RET(); | ||
226 | int twmin, thmin, twmax, thmax; | ||
227 | if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax, | ||
228 | &thmax)) | ||
229 | { | ||
230 | if (wmin) | ||
231 | *wmin = twmin; | ||
232 | |||
233 | if (hmin) | ||
234 | *hmin = thmin; | ||
235 | |||
236 | if (wmax) | ||
237 | *wmax = twmax; | ||
238 | |||
239 | if (hmax) | ||
240 | *hmax = thmax; | ||
241 | } | ||
242 | |||
243 | #endif | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * @param root window which's screen's size should be set. If invalid (e.g. NULL) no action is taken. | ||
248 | * @param w width in px the screen should be set to. If out of valid boundaries, current value is assumed. | ||
249 | * @param h height in px the screen should be set to. If out of valid boundaries, current value is assumed. | ||
250 | * @param w_mm width in mm the screen should be set to. If 0, current aspect is assumed. | ||
251 | * @param h_mm height in mm the screen should be set to. If 0, current aspect is assumed. | ||
252 | * @return EINA_TRUE if request was successfully sent or screen is already in | ||
253 | * requested size, EINA_FALSE if parameters are invalid | ||
254 | */ | ||
255 | EAPI Eina_Bool | ||
256 | ecore_x_randr_screen_current_size_set(Ecore_X_Window root, | ||
257 | int w, | ||
258 | int h, | ||
259 | int w_mm, | ||
260 | int h_mm) | ||
261 | { | ||
262 | #ifdef ECORE_XRANDR | ||
263 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
264 | |||
265 | Ecore_X_Randr_Screen scr; | ||
266 | int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax; | ||
267 | |||
268 | if (!RANDR_VALIDATE_ROOT(scr, root)) | ||
269 | return EINA_FALSE; | ||
270 | |||
271 | ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c); | ||
272 | if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm)) | ||
273 | return EINA_TRUE; | ||
274 | |||
275 | ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax); | ||
276 | |||
277 | if (((w != Ecore_X_Randr_None) && | ||
278 | ((w < twmin) || | ||
279 | (w > twmax))) || | ||
280 | ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax)))) | ||
281 | return EINA_FALSE; | ||
282 | |||
283 | if (w <= 0) | ||
284 | w = DisplayWidth(_ecore_x_disp, scr); | ||
285 | |||
286 | if (h <= 0) | ||
287 | h = DisplayHeight(_ecore_x_disp, scr); | ||
288 | |||
289 | if (w_mm <= 0) | ||
290 | w_mm = | ||
291 | (int)(((double)(DisplayWidthMM(_ecore_x_disp, | ||
292 | scr) / | ||
293 | (double)DisplayWidth(_ecore_x_disp, | ||
294 | scr))) * (double)w); | ||
295 | |||
296 | if (h_mm <= 0) | ||
297 | h_mm = | ||
298 | (int)(((double)(DisplayHeightMM(_ecore_x_disp, | ||
299 | scr) / | ||
300 | (double)DisplayHeight(_ecore_x_disp, | ||
301 | scr))) * (double)h); | ||
302 | |||
303 | XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm); | ||
304 | return EINA_TRUE; | ||
305 | #else | ||
306 | return EINA_FALSE; | ||
307 | #endif | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * @brief get detailed information for all modes related to a root window's screen | ||
312 | * @param root window which's screen's ressources are queried | ||
313 | * @param num number of modes returned | ||
314 | * @return modes' information | ||
315 | */ | ||
316 | EAPI Ecore_X_Randr_Mode_Info ** | ||
317 | ecore_x_randr_modes_info_get(Ecore_X_Window root, | ||
318 | int *num) | ||
319 | { | ||
320 | #ifdef ECORE_XRANDR | ||
321 | RANDR_CHECK_1_2_RET(NULL); | ||
322 | XRRScreenResources *res = NULL; | ||
323 | Ecore_X_Randr_Mode_Info **ret = NULL; | ||
324 | int i; | ||
325 | |||
326 | if (_ecore_x_randr_root_validate(root) && | ||
327 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
328 | { | ||
329 | if ((ret = | ||
330 | (Ecore_X_Randr_Mode_Info **)malloc(sizeof( | ||
331 | Ecore_X_Randr_Mode_Info *) | ||
332 | * | ||
333 | res->nmode))) | ||
334 | { | ||
335 | for (i = 0; i < res->nmode; i++) | ||
336 | { | ||
337 | if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
338 | { | ||
339 | ret[i]->xid = res->modes[i].id; | ||
340 | ret[i]->width = res->modes[i].width; | ||
341 | ret[i]->height = res->modes[i].height; | ||
342 | ret[i]->dotClock = res->modes[i].dotClock; | ||
343 | ret[i]->hSyncStart = res->modes[i].hSyncStart; | ||
344 | ret[i]->hSyncEnd = res->modes[i].hSyncEnd; | ||
345 | ret[i]->hTotal = res->modes[i].hTotal; | ||
346 | ret[i]->hSkew = res->modes[i].hSkew; | ||
347 | ret[i]->vSyncStart = res->modes[i].vSyncStart; | ||
348 | ret[i]->vSyncEnd = res->modes[i].vSyncEnd; | ||
349 | ret[i]->vTotal = res->modes[i].vTotal; | ||
350 | if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1)))) | ||
351 | strncpy(ret[i]->name, res->modes[i].name, | ||
352 | (res->modes[i].nameLength + 1)); | ||
353 | else | ||
354 | ret[i]->name = NULL; | ||
355 | |||
356 | ret[i]->nameLength = res->modes[i].nameLength; | ||
357 | ret[i]->modeFlags = res->modes[i].modeFlags; | ||
358 | } | ||
359 | else | ||
360 | { | ||
361 | while (i > 0) | ||
362 | free(ret[--i]); | ||
363 | free(ret); | ||
364 | ret = NULL; | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | |||
370 | if (ret && num) | ||
371 | *num = res->nmode; | ||
372 | |||
373 | XRRFreeScreenResources(res); | ||
374 | } | ||
375 | |||
376 | return ret; | ||
377 | #else | ||
378 | return NULL; | ||
379 | #endif | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * @brief add a mode to a display | ||
384 | * @param root window to which's screen's ressources are added | ||
385 | * @param mode_info | ||
386 | * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode | ||
387 | * adding failed. | ||
388 | * @since 1.2.0 | ||
389 | */ | ||
390 | EAPI Ecore_X_Randr_Mode | ||
391 | ecore_x_randr_mode_info_add(Ecore_X_Window root, | ||
392 | Ecore_X_Randr_Mode_Info *mode_info) | ||
393 | { | ||
394 | #ifdef ECORE_XRANDR | ||
395 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
396 | Ecore_X_Randr_Mode mode = Ecore_X_Randr_None; | ||
397 | |||
398 | if (_ecore_x_randr_root_validate(root) && mode_info) | ||
399 | mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info); | ||
400 | |||
401 | return mode; | ||
402 | #else | ||
403 | return Ecore_X_Randr_None; | ||
404 | #endif | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * @brief delete a mode from the display | ||
409 | * @param mode_info | ||
410 | * @since 1.2.0 | ||
411 | */ | ||
412 | EAPI void | ||
413 | ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode) | ||
414 | { | ||
415 | #ifdef ECORE_XRANDR | ||
416 | RANDR_CHECK_1_2_RET(); | ||
417 | |||
418 | XRRDestroyMode(_ecore_x_disp, mode); | ||
419 | #else | ||
420 | return; | ||
421 | #endif | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * @brief get detailed information for a given mode id | ||
426 | * @param root window which's screen's ressources are queried | ||
427 | * @param mode the XID which identifies the mode of interest | ||
428 | * @return mode's detailed information | ||
429 | */ | ||
430 | EAPI Ecore_X_Randr_Mode_Info * | ||
431 | ecore_x_randr_mode_info_get(Ecore_X_Window root, | ||
432 | Ecore_X_Randr_Mode mode) | ||
433 | { | ||
434 | #ifdef ECORE_XRANDR | ||
435 | RANDR_CHECK_1_2_RET(NULL); | ||
436 | XRRScreenResources *res = NULL; | ||
437 | Ecore_X_Randr_Mode_Info *ret = NULL; | ||
438 | int i; | ||
439 | |||
440 | if (_ecore_x_randr_root_validate(root) && | ||
441 | (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
442 | { | ||
443 | for (i = 0; i < res->nmode; i++) | ||
444 | { | ||
445 | if ((res->modes[i].id == mode) && | ||
446 | (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) | ||
447 | { | ||
448 | ret->xid = res->modes[i].id; | ||
449 | ret->width = res->modes[i].width; | ||
450 | ret->height = res->modes[i].height; | ||
451 | ret->dotClock = res->modes[i].dotClock; | ||
452 | ret->hSyncStart = res->modes[i].hSyncStart; | ||
453 | ret->hSyncEnd = res->modes[i].hSyncEnd; | ||
454 | ret->hTotal = res->modes[i].hTotal; | ||
455 | ret->hSkew = res->modes[i].hSkew; | ||
456 | ret->vSyncStart = res->modes[i].vSyncStart; | ||
457 | ret->vSyncEnd = res->modes[i].vSyncEnd; | ||
458 | ret->vTotal = res->modes[i].vTotal; | ||
459 | ret->name = NULL; | ||
460 | ret->nameLength = 0; | ||
461 | if (res->modes[i].nameLength > 0) | ||
462 | { | ||
463 | ret->nameLength = res->modes[i].nameLength; | ||
464 | ret->name = malloc(res->modes[i].nameLength + 1); | ||
465 | if (ret->name) | ||
466 | memcpy(ret->name, res->modes[i].name, | ||
467 | res->modes[i].nameLength + 1); | ||
468 | } | ||
469 | ret->modeFlags = res->modes[i].modeFlags; | ||
470 | break; | ||
471 | } | ||
472 | } | ||
473 | XRRFreeScreenResources(res); | ||
474 | } | ||
475 | |||
476 | return ret; | ||
477 | #else | ||
478 | return NULL; | ||
479 | #endif | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * @brief free detailed mode information. The pointer handed in will be set to | ||
484 | * NULL after freeing the memory. | ||
485 | * @param mode_info the mode information that should be freed | ||
486 | */ | ||
487 | EAPI void | ||
488 | ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) | ||
489 | { | ||
490 | #ifdef ECORE_XRANDR | ||
491 | RANDR_CHECK_1_2_RET(); | ||
492 | if (!mode_info) | ||
493 | return; | ||
494 | |||
495 | if (mode_info->name) | ||
496 | free(mode_info->name); | ||
497 | |||
498 | free(mode_info); | ||
499 | mode_info = NULL; | ||
500 | #endif | ||
501 | } | ||
502 | |||
503 | /* | ||
504 | * @brief get all known CRTCs related to a root window's screen | ||
505 | * @param root window which's screen's ressources are queried | ||
506 | * @param num number of CRTCs returned | ||
507 | * @return CRTC IDs | ||
508 | */ | ||
509 | EAPI Ecore_X_Randr_Crtc * | ||
510 | ecore_x_randr_crtcs_get(Ecore_X_Window root, | ||
511 | int *num) | ||
512 | { | ||
513 | #ifdef ECORE_XRANDR | ||
514 | RANDR_CHECK_1_2_RET(NULL); | ||
515 | XRRScreenResources *res = NULL; | ||
516 | Ecore_X_Randr_Crtc *ret = NULL; | ||
517 | |||
518 | if (num && root && | ||
519 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
520 | { | ||
521 | if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc))) | ||
522 | { | ||
523 | memcpy(ret, res->crtcs, (sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)); | ||
524 | *num = res->ncrtc; | ||
525 | } | ||
526 | |||
527 | XRRFreeScreenResources(res); | ||
528 | } | ||
529 | |||
530 | return ret; | ||
531 | #else | ||
532 | return NULL; | ||
533 | #endif | ||
534 | } | ||
535 | |||
536 | /* | ||
537 | * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead. | ||
538 | * @brief get the CRTCs, which display a certain window | ||
539 | * @param window window the displaying crtcs shall be found for | ||
540 | * @param num the number of crtcs displaying the window | ||
541 | * @return array of crtcs that display a certain window. NULL if no crtcs | ||
542 | * was found that displays the specified window. | ||
543 | */ | ||
544 | EAPI Ecore_X_Randr_Crtc * | ||
545 | ecore_x_randr_current_crtc_get(Ecore_X_Window window, | ||
546 | int *num) | ||
547 | { | ||
548 | return ecore_x_randr_window_crtcs_get(window, num); | ||
549 | } | ||
550 | |||
551 | /* | ||
552 | * @brief get the CRTCs, which display a certain window | ||
553 | * @param window window the displaying crtcs shall be found for | ||
554 | * @param num the number of crtcs displaying the window | ||
555 | * @return array of crtcs that display a certain window. NULL if no crtcs | ||
556 | * was found that displays the specified window. | ||
557 | * @since 1.2.0 | ||
558 | */ | ||
559 | EAPI Ecore_X_Randr_Crtc * | ||
560 | ecore_x_randr_window_crtcs_get(Ecore_X_Window window, | ||
561 | int *num) | ||
562 | { | ||
563 | #ifdef ECORE_XRANDR | ||
564 | Ecore_X_Window root; | ||
565 | Eina_Rectangle w_geo, c_geo; | ||
566 | Ecore_X_Randr_Crtc *crtcs; | ||
567 | Ecore_X_Randr_Mode mode; | ||
568 | Ecore_X_Randr_Output *ret = NULL; | ||
569 | Window tw; | ||
570 | int ncrtcs, i, nret = 0, rx = 0, ry = 0; | ||
571 | |||
572 | if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail; | ||
573 | |||
574 | ecore_x_window_geometry_get(window, | ||
575 | &w_geo.x, &w_geo.y, | ||
576 | &w_geo.w, &w_geo.h); | ||
577 | |||
578 | root = ecore_x_window_root_get(window); | ||
579 | crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); | ||
580 | if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail; | ||
581 | |||
582 | /* now get window RELATIVE to root window - thats what matters. */ | ||
583 | XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw); | ||
584 | w_geo.x = rx; | ||
585 | w_geo.y = ry; | ||
586 | |||
587 | for (i = 0, nret = 0; i < ncrtcs; i++) | ||
588 | { | ||
589 | /* if crtc is not enabled, don't bother about it any further */ | ||
590 | mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); | ||
591 | if (mode == Ecore_X_Randr_None) continue; | ||
592 | |||
593 | ecore_x_randr_crtc_geometry_get(root, crtcs[i], | ||
594 | &c_geo.x, &c_geo.y, | ||
595 | &c_geo.w, &c_geo.h); | ||
596 | if (eina_rectangles_intersect(&w_geo, &c_geo)) | ||
597 | { | ||
598 | ret = realloc(ret, (sizeof(Ecore_X_Randr_Crtc) * ++nret)); | ||
599 | ret[nret] = crtcs[i]; | ||
600 | } | ||
601 | } | ||
602 | free(crtcs); | ||
603 | |||
604 | if (num) *num = nret; | ||
605 | return ret; | ||
606 | |||
607 | _ecore_x_randr_window_crtcs_get_fail: | ||
608 | #endif | ||
609 | if (num) *num = 0; | ||
610 | return NULL; | ||
611 | } | ||
612 | |||
613 | EAPI Ecore_X_Randr_Output * | ||
614 | ecore_x_randr_outputs_get(Ecore_X_Window root, | ||
615 | int *num) | ||
616 | { | ||
617 | #ifdef ECORE_XRANDR | ||
618 | RANDR_CHECK_1_2_RET(NULL); | ||
619 | XRRScreenResources *res = NULL; | ||
620 | Ecore_X_Randr_Output *ret = NULL; | ||
621 | |||
622 | if (num && root && | ||
623 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
624 | { | ||
625 | if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput))) | ||
626 | { | ||
627 | memcpy(ret, res->outputs, | ||
628 | (sizeof(Ecore_X_Randr_Output) * res->noutput)); | ||
629 | if (num) | ||
630 | *num = res->noutput; | ||
631 | } | ||
632 | |||
633 | if (res) | ||
634 | XRRFreeScreenResources(res); | ||
635 | } | ||
636 | |||
637 | return ret; | ||
638 | #else | ||
639 | return NULL; | ||
640 | #endif | ||
641 | } | ||
642 | |||
643 | //Per Crtc | ||
644 | /* | ||
645 | * @brief get a CRTC's outputs. | ||
646 | * @param root the root window which's screen will be queried | ||
647 | * @param num number of outputs referenced by given CRTC | ||
648 | */ | ||
649 | EAPI Ecore_X_Randr_Output * | ||
650 | ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, | ||
651 | Ecore_X_Randr_Crtc crtc, | ||
652 | int *num) | ||
653 | { | ||
654 | #ifdef ECORE_XRANDR | ||
655 | RANDR_CHECK_1_2_RET(NULL); | ||
656 | XRRScreenResources *res = NULL; | ||
657 | Ecore_X_Randr_Output *ret = NULL; | ||
658 | XRRCrtcInfo *crtc_info = NULL; | ||
659 | |||
660 | if (_ecore_x_randr_crtc_validate(root, | ||
661 | crtc) && | ||
662 | (res = | ||
663 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, | ||
664 | root)) && | ||
665 | (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
666 | { | ||
667 | if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput))) | ||
668 | { | ||
669 | memcpy(ret, crtc_info->outputs, | ||
670 | (sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)); | ||
671 | if (num) | ||
672 | *num = crtc_info->noutput; | ||
673 | } | ||
674 | |||
675 | if (crtc_info) | ||
676 | XRRFreeCrtcInfo(crtc_info); | ||
677 | |||
678 | if (res) | ||
679 | XRRFreeScreenResources(res); | ||
680 | } | ||
681 | |||
682 | return ret; | ||
683 | #else | ||
684 | return NULL; | ||
685 | #endif | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * @brief get a CRTC's possible outputs. | ||
690 | * @param root the root window which's screen will be queried | ||
691 | * @param num number of possible outputs referenced by given CRTC | ||
692 | */ | ||
693 | EAPI Ecore_X_Randr_Output * | ||
694 | ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, | ||
695 | Ecore_X_Randr_Crtc crtc, | ||
696 | int *num) | ||
697 | { | ||
698 | #ifdef ECORE_XRANDR | ||
699 | RANDR_CHECK_1_2_RET(NULL); | ||
700 | XRRScreenResources *res = NULL; | ||
701 | Ecore_X_Randr_Output *ret = NULL; | ||
702 | XRRCrtcInfo *crtc_info = NULL; | ||
703 | |||
704 | if (_ecore_x_randr_crtc_validate(root, | ||
705 | crtc) && | ||
706 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
707 | { | ||
708 | if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
709 | { | ||
710 | if ((ret = | ||
711 | malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible))) | ||
712 | { | ||
713 | memcpy(ret, crtc_info->possible, | ||
714 | (sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)); | ||
715 | if (num) | ||
716 | *num = res->ncrtc; | ||
717 | } | ||
718 | |||
719 | XRRFreeCrtcInfo(crtc_info); | ||
720 | } | ||
721 | |||
722 | XRRFreeScreenResources(res); | ||
723 | } | ||
724 | |||
725 | return ret; | ||
726 | #else | ||
727 | return NULL; | ||
728 | #endif | ||
729 | } | ||
730 | |||
731 | EAPI void | ||
732 | ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, | ||
733 | Ecore_X_Randr_Crtc crtc, | ||
734 | int *x, | ||
735 | int *y, | ||
736 | int *w, | ||
737 | int *h) | ||
738 | { | ||
739 | #ifdef ECORE_XRANDR | ||
740 | RANDR_CHECK_1_2_RET(); | ||
741 | XRRScreenResources *res = NULL; | ||
742 | XRRCrtcInfo *crtc_info = NULL; | ||
743 | |||
744 | if (_ecore_x_randr_crtc_validate(root, | ||
745 | crtc) && | ||
746 | (res = | ||
747 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, | ||
748 | root)) && | ||
749 | (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
750 | { | ||
751 | if (x) | ||
752 | *x = crtc_info->x; | ||
753 | |||
754 | if (y) | ||
755 | *y = crtc_info->y; | ||
756 | |||
757 | if (w) | ||
758 | *w = crtc_info->width; | ||
759 | |||
760 | if (h) | ||
761 | *h = crtc_info->height; | ||
762 | |||
763 | XRRFreeCrtcInfo(crtc_info); | ||
764 | XRRFreeScreenResources(res); | ||
765 | } | ||
766 | |||
767 | #endif | ||
768 | } | ||
769 | |||
770 | /* | ||
771 | * @brief sets the position of given CRTC within root window's screen | ||
772 | * @param root the window's screen to be queried | ||
773 | * @param crtc the CRTC which's position within the mentioned screen is to be altered | ||
774 | * @param x position on the x-axis (0 == left) of the screen. if x < 0 current value will be kept. | ||
775 | * @param y position on the y-ayis (0 == top) of the screen. if y < 0, current value will be kept. | ||
776 | * @return EINA_TRUE if position could be successfully be altered. | ||
777 | */ | ||
778 | EAPI Eina_Bool | ||
779 | ecore_x_randr_crtc_pos_set(Ecore_X_Window root, | ||
780 | Ecore_X_Randr_Crtc crtc, | ||
781 | int x, | ||
782 | int y) | ||
783 | { | ||
784 | #ifdef ECORE_XRANDR | ||
785 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
786 | int w_c, h_c, w_new = 0, h_new = 0; | ||
787 | Eina_Rectangle crtc_geo; | ||
788 | |||
789 | ecore_x_randr_crtc_geometry_get(root, | ||
790 | crtc, | ||
791 | &crtc_geo.x, | ||
792 | &crtc_geo.y, | ||
793 | &crtc_geo.w, | ||
794 | &crtc_geo.h); | ||
795 | ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL); | ||
796 | if (x < 0) | ||
797 | x = crtc_geo.x; | ||
798 | |||
799 | if (y < 0) | ||
800 | y = crtc_geo.y; | ||
801 | |||
802 | if ((x + crtc_geo.w) > w_c) | ||
803 | w_new = x + crtc_geo.w; | ||
804 | |||
805 | if ((y + crtc_geo.h) > h_c) | ||
806 | h_new = y + crtc_geo.h; | ||
807 | |||
808 | if ((w_new != 0) || (h_new != 0)) | ||
809 | if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0)) | ||
810 | return EINA_FALSE; | ||
811 | |||
812 | return ecore_x_randr_crtc_settings_set(root, | ||
813 | crtc, | ||
814 | NULL, | ||
815 | Ecore_X_Randr_Unset, | ||
816 | x, | ||
817 | y, | ||
818 | Ecore_X_Randr_Unset, | ||
819 | Ecore_X_Randr_Unset); | ||
820 | #else | ||
821 | return EINA_FALSE; | ||
822 | #endif | ||
823 | } | ||
824 | |||
825 | /** | ||
826 | * @brief Get the current set mode of a given CRTC | ||
827 | * @param root the window's screen to be queried | ||
828 | * @param crtc the CRTC which's should be queried | ||
829 | * @return currently set mode or - in case parameters are invalid - | ||
830 | * Ecore_X_Randr_Unset | ||
831 | */ | ||
832 | EAPI Ecore_X_Randr_Mode | ||
833 | ecore_x_randr_crtc_mode_get(Ecore_X_Window root, | ||
834 | Ecore_X_Randr_Crtc crtc) | ||
835 | { | ||
836 | #ifdef ECORE_XRANDR | ||
837 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); | ||
838 | XRRScreenResources *res = NULL; | ||
839 | XRRCrtcInfo *crtc_info = NULL; | ||
840 | Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; | ||
841 | if (_ecore_x_randr_root_validate(root) && | ||
842 | _ecore_x_randr_crtc_validate(root, | ||
843 | crtc) && | ||
844 | (res = | ||
845 | _ecore_x_randr_get_screen_resources(_ecore_x_disp, | ||
846 | root)) && | ||
847 | (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
848 | { | ||
849 | ret = crtc_info->mode; | ||
850 | XRRFreeCrtcInfo(crtc_info); | ||
851 | XRRFreeScreenResources(res); | ||
852 | } | ||
853 | |||
854 | return ret; | ||
855 | #else | ||
856 | return Ecore_X_Randr_Unset; | ||
857 | #endif | ||
858 | } | ||
859 | |||
860 | /** | ||
861 | * @brief sets a mode for a CRTC and the outputs attached to it | ||
862 | * @param root the window's screen to be queried | ||
863 | * @param crtc the CRTC which shall be set | ||
864 | * @param outputs array of outputs which have to be compatible with the mode. If | ||
865 | * NULL CRTC will be disabled. | ||
866 | * @param noutputs number of outputs in array to be used. Use | ||
867 | * Ecore_X_Randr_Unset (or -1) to use currently used outputs. | ||
868 | * @param mode XID of the mode to be set. If set to 0 the CRTC will be disabled. | ||
869 | * If set to -1 the call will fail. | ||
870 | * @return EINA_TRUE if mode setting was successful. Else EINA_FALSE | ||
871 | */ | ||
872 | EAPI Eina_Bool | ||
873 | ecore_x_randr_crtc_mode_set(Ecore_X_Window root, | ||
874 | Ecore_X_Randr_Crtc crtc, | ||
875 | Ecore_X_Randr_Output *outputs, | ||
876 | int noutputs, | ||
877 | Ecore_X_Randr_Mode mode) | ||
878 | { | ||
879 | #ifdef ECORE_XRANDR | ||
880 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
881 | |||
882 | if (mode == Ecore_X_Randr_Unset) | ||
883 | return EINA_FALSE; | ||
884 | |||
885 | return ecore_x_randr_crtc_settings_set(root, | ||
886 | crtc, | ||
887 | outputs, | ||
888 | noutputs, | ||
889 | Ecore_X_Randr_Unset, | ||
890 | Ecore_X_Randr_Unset, | ||
891 | mode, | ||
892 | Ecore_X_Randr_Unset); | ||
893 | #else | ||
894 | return EINA_FALSE; | ||
895 | #endif | ||
896 | } | ||
897 | |||
898 | EAPI void | ||
899 | ecore_x_randr_crtc_size_get(Ecore_X_Window root, | ||
900 | Ecore_X_Randr_Crtc crtc, | ||
901 | int *w, | ||
902 | int *h) | ||
903 | { | ||
904 | #ifdef ECORE_XRANDR | ||
905 | RANDR_CHECK_1_2_RET(); | ||
906 | ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); | ||
907 | #endif | ||
908 | } | ||
909 | |||
910 | EAPI Ecore_X_Randr_Refresh_Rate | ||
911 | ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, | ||
912 | Ecore_X_Randr_Crtc crtc, | ||
913 | Ecore_X_Randr_Mode mode) | ||
914 | { | ||
915 | #ifdef ECORE_XRANDR | ||
916 | RANDR_CHECK_1_2_RET(0.0); | ||
917 | XRRScreenResources *res = NULL; | ||
918 | XRRCrtcInfo *crtc_info = NULL; | ||
919 | Ecore_X_Randr_Refresh_Rate ret = 0.0; | ||
920 | int i; | ||
921 | |||
922 | if (_ecore_x_randr_crtc_validate(root, | ||
923 | crtc) && | ||
924 | (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
925 | { | ||
926 | for (i = 0; i < res->nmode; i++) | ||
927 | if (res->modes[i].id == mode) | ||
928 | { | ||
929 | if (res->modes[i].hTotal && res->modes[i].vTotal) | ||
930 | ret = ((double)res->modes[i].dotClock / | ||
931 | ((double)res->modes[i].hTotal * | ||
932 | (double)res->modes[i].vTotal)); | ||
933 | |||
934 | break; | ||
935 | } | ||
936 | } | ||
937 | |||
938 | if (crtc_info) | ||
939 | XRRFreeCrtcInfo(crtc_info); | ||
940 | |||
941 | if (res) | ||
942 | XRRFreeScreenResources(res); | ||
943 | |||
944 | return ret; | ||
945 | #else | ||
946 | return 0.0; | ||
947 | #endif | ||
948 | } | ||
949 | |||
950 | EAPI Ecore_X_Randr_Orientation | ||
951 | ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, | ||
952 | Ecore_X_Randr_Crtc crtc) | ||
953 | { | ||
954 | #ifdef ECORE_XRANDR | ||
955 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
956 | XRRCrtcInfo *crtc_info = NULL; | ||
957 | XRRScreenResources *res = NULL; | ||
958 | Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; | ||
959 | |||
960 | if (_ecore_x_randr_crtc_validate(root, | ||
961 | crtc) && | ||
962 | (res = | ||
963 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, | ||
964 | root)) && | ||
965 | (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
966 | { | ||
967 | ret = crtc_info->rotations; | ||
968 | } | ||
969 | if (crtc_info) | ||
970 | XRRFreeCrtcInfo(crtc_info); | ||
971 | |||
972 | if (res) | ||
973 | XRRFreeScreenResources(res); | ||
974 | |||
975 | return ret; | ||
976 | #else | ||
977 | return Ecore_X_Randr_None; | ||
978 | #endif | ||
979 | } | ||
980 | |||
981 | EAPI Ecore_X_Randr_Orientation | ||
982 | ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, | ||
983 | Ecore_X_Randr_Crtc crtc) | ||
984 | { | ||
985 | #ifdef ECORE_XRANDR | ||
986 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
987 | XRRCrtcInfo *crtc_info = NULL; | ||
988 | XRRScreenResources *res = NULL; | ||
989 | Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; | ||
990 | |||
991 | if (_ecore_x_randr_crtc_validate(root, | ||
992 | crtc) && | ||
993 | (res = | ||
994 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, | ||
995 | root)) && | ||
996 | (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
997 | { | ||
998 | ret = crtc_info->rotation; | ||
999 | } | ||
1000 | if (crtc_info) | ||
1001 | XRRFreeCrtcInfo(crtc_info); | ||
1002 | |||
1003 | if (res) | ||
1004 | XRRFreeScreenResources(res); | ||
1005 | |||
1006 | return ret; | ||
1007 | #else | ||
1008 | return Ecore_X_Randr_None; | ||
1009 | #endif | ||
1010 | } | ||
1011 | |||
1012 | EAPI Eina_Bool | ||
1013 | ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, | ||
1014 | Ecore_X_Randr_Crtc crtc, | ||
1015 | Ecore_X_Randr_Orientation orientation) | ||
1016 | { | ||
1017 | #ifdef ECORE_XRANDR | ||
1018 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1019 | Eina_Bool ret = EINA_FALSE; | ||
1020 | |||
1021 | if (orientation != Ecore_X_Randr_None) | ||
1022 | { | ||
1023 | ret = ecore_x_randr_crtc_settings_set(root, | ||
1024 | crtc, | ||
1025 | NULL, | ||
1026 | Ecore_X_Randr_Unset, | ||
1027 | Ecore_X_Randr_Unset, | ||
1028 | Ecore_X_Randr_Unset, | ||
1029 | Ecore_X_Randr_Unset, | ||
1030 | orientation); | ||
1031 | } | ||
1032 | |||
1033 | return ret; | ||
1034 | #else | ||
1035 | return EINA_FALSE; | ||
1036 | #endif | ||
1037 | } | ||
1038 | |||
1039 | EAPI void | ||
1040 | ecore_x_randr_crtc_pos_get(Ecore_X_Window root, | ||
1041 | Ecore_X_Randr_Crtc crtc, | ||
1042 | int *x, | ||
1043 | int *y) | ||
1044 | { | ||
1045 | #ifdef ECORE_XRANDR | ||
1046 | RANDR_CHECK_1_2_RET(); | ||
1047 | |||
1048 | ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); | ||
1049 | #endif | ||
1050 | } | ||
1051 | |||
1052 | EAPI Eina_Bool | ||
1053 | ecore_x_randr_crtc_clone_set(Ecore_X_Window root, | ||
1054 | Ecore_X_Randr_Crtc original, | ||
1055 | Ecore_X_Randr_Crtc clon) | ||
1056 | { | ||
1057 | #ifdef ECORE_XRANDR | ||
1058 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1059 | |||
1060 | XRRScreenResources *res = NULL; | ||
1061 | XRRCrtcInfo *clone_crtc_info = NULL; | ||
1062 | Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None; | ||
1063 | Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None; | ||
1064 | Eina_Bool ret = EINA_FALSE; | ||
1065 | int x, y; | ||
1066 | |||
1067 | if (_ecore_x_randr_root_validate(root) && | ||
1068 | _ecore_x_randr_crtc_validate(root, | ||
1069 | original) && | ||
1070 | _ecore_x_randr_crtc_validate(root, | ||
1071 | clon) && | ||
1072 | (res = | ||
1073 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, | ||
1074 | root)) && | ||
1075 | (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon))) | ||
1076 | { | ||
1077 | ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL); | ||
1078 | original_mode = ecore_x_randr_crtc_mode_get(root, original); | ||
1079 | original_orientation = ecore_x_randr_crtc_orientation_get(root, | ||
1080 | original); | ||
1081 | ret = ecore_x_randr_crtc_settings_set(root, | ||
1082 | clon, | ||
1083 | NULL, | ||
1084 | Ecore_X_Randr_Unset, | ||
1085 | x, | ||
1086 | y, | ||
1087 | original_mode, | ||
1088 | original_orientation); | ||
1089 | XRRFreeCrtcInfo(clone_crtc_info); | ||
1090 | XRRFreeScreenResources(res); | ||
1091 | } | ||
1092 | |||
1093 | return ret; | ||
1094 | #else | ||
1095 | return EINA_FALSE; | ||
1096 | #endif | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is | ||
1101 | * auto enabled in it's preferred mode, when it was disabled before. | ||
1102 | * @param root the root window which's default display will be queried | ||
1103 | * @param crtc the CRTC which's configuration should be altered | ||
1104 | * @param outputs an array of outputs, that should display this CRTC's content. | ||
1105 | * @param noutputs number of outputs in the array of outputs. | ||
1106 | * If set to Ecore_X_Randr_Unset, current outputs and number of outputs will be used. | ||
1107 | * If set to Ecore_X_Randr_None, CRTC will be disabled | ||
1108 | * @param x new x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x | ||
1109 | * corrdinate will be assumed. | ||
1110 | * @param y new y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y | ||
1111 | * corrdinate will be assumed. | ||
1112 | * @param mode the new mode to be set. If Ecore_X_Randr_None is passed, the | ||
1113 | * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is assumed. | ||
1114 | * @param orientation the new orientation to be set. If Ecore_X_Randr_Unset is used, | ||
1115 | * the current mode is assumed. | ||
1116 | * @return EINA_TRUE if the configuration alteration was successful, else | ||
1117 | * EINA_FALSE | ||
1118 | */ | ||
1119 | EAPI Eina_Bool | ||
1120 | ecore_x_randr_crtc_settings_set(Ecore_X_Window root, | ||
1121 | Ecore_X_Randr_Crtc crtc, | ||
1122 | Ecore_X_Randr_Output *outputs, | ||
1123 | int noutputs, | ||
1124 | int x, | ||
1125 | int y, | ||
1126 | Ecore_X_Randr_Mode mode, | ||
1127 | Ecore_X_Randr_Orientation orientation) | ||
1128 | { | ||
1129 | #ifdef ECORE_XRANDR | ||
1130 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1131 | XRRScreenResources *res = NULL; | ||
1132 | XRRCrtcInfo *crtc_info = NULL; | ||
1133 | Eina_Bool ret = EINA_FALSE; | ||
1134 | |||
1135 | if (_ecore_x_randr_crtc_validate(root, | ||
1136 | crtc) && | ||
1137 | (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1138 | { | ||
1139 | if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) | ||
1140 | { | ||
1141 | if ((mode == Ecore_X_Randr_None) || | ||
1142 | (noutputs == Ecore_X_Randr_None)) | ||
1143 | { | ||
1144 | outputs = NULL; | ||
1145 | noutputs = 0; | ||
1146 | } | ||
1147 | else if (noutputs == (int)Ecore_X_Randr_Unset) | ||
1148 | { | ||
1149 | outputs = (Ecore_X_Randr_Output *)crtc_info->outputs; | ||
1150 | noutputs = crtc_info->noutput; | ||
1151 | } | ||
1152 | |||
1153 | if (mode == Ecore_X_Randr_Unset) | ||
1154 | mode = crtc_info->mode; | ||
1155 | |||
1156 | if (x < 0) | ||
1157 | x = crtc_info->x; | ||
1158 | |||
1159 | if (y < 0) | ||
1160 | y = crtc_info->y; | ||
1161 | |||
1162 | if (orientation == Ecore_X_Randr_Unset) | ||
1163 | orientation = crtc_info->rotation; | ||
1164 | |||
1165 | if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime, | ||
1166 | x, y, mode, orientation, (RROutput *)outputs, | ||
1167 | noutputs)) | ||
1168 | ret = EINA_TRUE; | ||
1169 | |||
1170 | XRRFreeCrtcInfo(crtc_info); | ||
1171 | } | ||
1172 | |||
1173 | XRRFreeScreenResources(res); | ||
1174 | } | ||
1175 | |||
1176 | return ret; | ||
1177 | #else | ||
1178 | return EINA_FALSE; | ||
1179 | #endif | ||
1180 | } | ||
1181 | |||
1182 | /** | ||
1183 | * @brief sets a CRTC relative to another one. | ||
1184 | * @param crtc_r1 the CRTC to be positioned. | ||
1185 | * @param crtc_r2 the CRTC the position should be relative to | ||
1186 | * @param policy the relation between the crtcs | ||
1187 | * @param alignment in case CRTCs size differ, aligns CRTC1 accordingly at CRTC2's | ||
1188 | * borders | ||
1189 | * @return EINA_TRUE if crtc could be successfully positioned. EINA_FALSE if | ||
1190 | * repositioning failed or if position of new crtc would be out of given screen's min/max bounds. | ||
1191 | */ | ||
1192 | EAPI Eina_Bool | ||
1193 | ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, | ||
1194 | Ecore_X_Randr_Crtc crtc_r1, | ||
1195 | Ecore_X_Randr_Crtc crtc_r2, | ||
1196 | Ecore_X_Randr_Output_Policy policy, | ||
1197 | Ecore_X_Randr_Relative_Alignment alignment) | ||
1198 | { | ||
1199 | #ifdef ECORE_XRANDR | ||
1200 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1201 | |||
1202 | Eina_Rectangle r1_geo, r2_geo; | ||
1203 | int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n = | ||
1204 | Ecore_X_Randr_Unset; | ||
1205 | /* | ||
1206 | int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h; | ||
1207 | Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs; | ||
1208 | Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode; | ||
1209 | Eina_Bool ret; | ||
1210 | */ | ||
1211 | |||
1212 | if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None) | ||
1213 | || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None)) | ||
1214 | return EINA_FALSE; | ||
1215 | |||
1216 | if (!_ecore_x_randr_crtc_validate(root, crtc_r1) || | ||
1217 | (!(crtc_r1 != crtc_r2) && | ||
1218 | !_ecore_x_randr_crtc_validate(root, crtc_r2))) | ||
1219 | return EINA_FALSE; | ||
1220 | |||
1221 | ecore_x_randr_crtc_geometry_get(root, | ||
1222 | crtc_r1, | ||
1223 | &r1_geo.x, | ||
1224 | &r1_geo.y, | ||
1225 | &r1_geo.w, | ||
1226 | &r1_geo.h); | ||
1227 | ecore_x_randr_crtc_geometry_get(root, | ||
1228 | crtc_r2, | ||
1229 | &r2_geo.x, | ||
1230 | &r2_geo.y, | ||
1231 | &r2_geo.w, | ||
1232 | &r2_geo.h); | ||
1233 | ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); | ||
1234 | ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); | ||
1235 | |||
1236 | switch (policy) | ||
1237 | { | ||
1238 | case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: | ||
1239 | //set r1 right of r2 | ||
1240 | x_n = r2_geo.x + r2_geo.w; | ||
1241 | |||
1242 | switch (alignment) | ||
1243 | { | ||
1244 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: | ||
1245 | y_n = Ecore_X_Randr_Unset; | ||
1246 | break; | ||
1247 | |||
1248 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: | ||
1249 | y_n = | ||
1250 | ((int)(((double)r2_geo.h / | ||
1251 | 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0))); | ||
1252 | break; | ||
1253 | |||
1254 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: | ||
1255 | y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0)); | ||
1256 | break; | ||
1257 | } | ||
1258 | break; | ||
1259 | |||
1260 | case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: | ||
1261 | //set r1 left of r2 | ||
1262 | x_n = r2_geo.x - r1_geo.w; | ||
1263 | |||
1264 | switch (alignment) | ||
1265 | { | ||
1266 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: | ||
1267 | y_n = Ecore_X_Randr_Unset; | ||
1268 | break; | ||
1269 | |||
1270 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: | ||
1271 | y_n = | ||
1272 | ((int)(((double)r2_geo.h / | ||
1273 | 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0))); | ||
1274 | break; | ||
1275 | |||
1276 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: | ||
1277 | y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0))); | ||
1278 | break; | ||
1279 | } | ||
1280 | break; | ||
1281 | |||
1282 | case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: | ||
1283 | //set r1 below r2 | ||
1284 | y_n = r2_geo.y + r2_geo.h; | ||
1285 | |||
1286 | switch (alignment) | ||
1287 | { | ||
1288 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: | ||
1289 | x_n = Ecore_X_Randr_Unset; | ||
1290 | break; | ||
1291 | |||
1292 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: | ||
1293 | x_n = | ||
1294 | ((int)((((double)r2_geo.x + | ||
1295 | (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); | ||
1296 | break; | ||
1297 | |||
1298 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: | ||
1299 | x_n = ((int)((double)cw / 2.0)); | ||
1300 | break; | ||
1301 | } | ||
1302 | break; | ||
1303 | |||
1304 | case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: | ||
1305 | y_n = r2_geo.y - r1_geo.h; | ||
1306 | |||
1307 | //set r1 above r2 | ||
1308 | switch (alignment) | ||
1309 | { | ||
1310 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: | ||
1311 | x_n = Ecore_X_Randr_Unset; | ||
1312 | break; | ||
1313 | |||
1314 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: | ||
1315 | x_n = | ||
1316 | ((int)((((double)r2_geo.x + | ||
1317 | (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); | ||
1318 | break; | ||
1319 | |||
1320 | case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: | ||
1321 | x_n = ((int)((double)cw / 2.0)); | ||
1322 | break; | ||
1323 | } | ||
1324 | break; | ||
1325 | |||
1326 | case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: | ||
1327 | return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y); | ||
1328 | |||
1329 | /* entire cloning (including modesetting) | ||
1330 | //all outputs of crtc1 capable of crtc2's current mode? | ||
1331 | r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); | ||
1332 | if (!(r1_outputs = | ||
1333 | ecore_x_randr_crtc_outputs_get(root, crtc_r1, | ||
1334 | &r1_noutputs)) || | ||
1335 | (r1_noutputs == 0)) | ||
1336 | return EINA_FALSE; | ||
1337 | |||
1338 | for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) | ||
1339 | { | ||
1340 | if (!(r1_modes = | ||
1341 | ecore_x_randr_output_modes_get(root, r1_outputs[i], | ||
1342 | &r1_nmodes, NULL))) | ||
1343 | { | ||
1344 | free(r1_outputs); | ||
1345 | return EINA_FALSE; | ||
1346 | } | ||
1347 | |||
1348 | for (j = 0; j < r1_nmodes; j++) | ||
1349 | { | ||
1350 | ecore_x_randr_mode_size_get(root, | ||
1351 | r1_modes[j], | ||
1352 | &mode_w, | ||
1353 | &mode_h); | ||
1354 | if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h)) | ||
1355 | { | ||
1356 | r1_mode = r1_modes[j]; | ||
1357 | ++outputs_mode_found; | ||
1358 | free(r1_modes); | ||
1359 | r1_modes = NULL; | ||
1360 | break; | ||
1361 | } | ||
1362 | } | ||
1363 | if (r1_modes) | ||
1364 | free(r1_modes); | ||
1365 | |||
1366 | if (outputs_mode_found <= i) | ||
1367 | { | ||
1368 | //an output doesn't support the set mode, cancel! | ||
1369 | free(r1_outputs); | ||
1370 | return EINA_FALSE; | ||
1371 | } | ||
1372 | } | ||
1373 | free (r1_outputs); | ||
1374 | //CRTC 1's outputs support a mode of same geometry as CRTC 2. | ||
1375 | ret = | ||
1376 | (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None, | ||
1377 | Ecore_X_Randr_None, | ||
1378 | r1_mode) && | ||
1379 | ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y)); | ||
1380 | return ret; | ||
1381 | */ | ||
1382 | |||
1383 | /* entire cloning on same CRTC | ||
1384 | //all outputs of crtc1 capable of crtc2's current mode? | ||
1385 | r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); | ||
1386 | if (!(r1_outputs = | ||
1387 | ecore_x_randr_crtc_outputs_get(root, crtc_r1, | ||
1388 | &r1_noutputs)) || | ||
1389 | (r1_noutputs == 0)) | ||
1390 | return EINA_FALSE; | ||
1391 | |||
1392 | for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) | ||
1393 | { | ||
1394 | if (!(r1_modes = | ||
1395 | ecore_x_randr_output_modes_get(root, r1_outputs[i], | ||
1396 | &r1_nmodes, NULL))) | ||
1397 | { | ||
1398 | free(r1_outputs); | ||
1399 | return EINA_FALSE; | ||
1400 | } | ||
1401 | |||
1402 | for (j = 0; j < r1_nmodes; j++) | ||
1403 | { | ||
1404 | if (r1_modes[j] == r2_mode) | ||
1405 | { | ||
1406 | ++outputs_mode_found; | ||
1407 | free(r1_modes); | ||
1408 | r1_modes = NULL; | ||
1409 | break; | ||
1410 | } | ||
1411 | } | ||
1412 | if (r1_modes) | ||
1413 | free(r1_modes); | ||
1414 | |||
1415 | if (outputs_mode_found <= i) | ||
1416 | { | ||
1417 | //an output doesn't support the set mode, cancel! | ||
1418 | free(r1_outputs); | ||
1419 | return EINA_FALSE; | ||
1420 | } | ||
1421 | } | ||
1422 | //check whether crtc r2 can use all outputs of r1. | ||
1423 | if (!(r2_outputs = | ||
1424 | ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2, | ||
1425 | &r2_noutputs)) || | ||
1426 | (r2_noutputs == 0)) | ||
1427 | { | ||
1428 | free(r1_outputs); | ||
1429 | return EINA_FALSE; | ||
1430 | } | ||
1431 | |||
1432 | for (i = 0; i < r1_noutputs; i++) | ||
1433 | { | ||
1434 | for (j = 0; j < r2_noutputs; ) | ||
1435 | { | ||
1436 | if (r1_outputs[i] == r2_outputs[j]) | ||
1437 | break; | ||
1438 | |||
1439 | j++; | ||
1440 | } | ||
1441 | if (j == r2_noutputs) | ||
1442 | { | ||
1443 | //didn't find the output! | ||
1444 | free (r1_outputs); | ||
1445 | free (r2_outputs); | ||
1446 | return EINA_FALSE; | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | //apparently crtc2 supports all outputs of r1 | ||
1451 | //TODO: check with the compatible list of outputs (property in RR1.3) | ||
1452 | r2_r1_outputs = | ||
1453 | malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs)); | ||
1454 | for (i = 0; i < r1_noutputs; i++) | ||
1455 | { | ||
1456 | r2_r1_outputs[i] = r1_outputs[i]; | ||
1457 | } | ||
1458 | free(r1_outputs); | ||
1459 | for (; i < r2_noutputs; i++) | ||
1460 | { | ||
1461 | r2_r1_outputs[i] = r2_outputs[i]; | ||
1462 | } | ||
1463 | free(r2_outputs); | ||
1464 | ret = | ||
1465 | ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs, | ||
1466 | (r1_noutputs + r1_noutputs), r2_mode); | ||
1467 | free (r2_r1_outputs); | ||
1468 | return ret; | ||
1469 | */ | ||
1470 | case ECORE_X_RANDR_OUTPUT_POLICY_NONE: | ||
1471 | break; | ||
1472 | } | ||
1473 | if ((x_n == r1_geo.x) && (y_n == r1_geo.x)) | ||
1474 | return EINA_TRUE; | ||
1475 | |||
1476 | //out of possible bounds? | ||
1477 | if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max)) | ||
1478 | return EINA_FALSE; | ||
1479 | |||
1480 | return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n); | ||
1481 | #else | ||
1482 | return EINA_FALSE; | ||
1483 | #endif | ||
1484 | } | ||
1485 | |||
1486 | /* | ||
1487 | * @brief add given mode to given output | ||
1488 | * @param output the output the mode is added to | ||
1489 | * @param mode the mode added to the output | ||
1490 | * @return EINA_FALSE if output or mode equal Ecore_X_Randr_None, else EINA_TRUE | ||
1491 | * Additionally, if xcb backend is used, the success of the addition is reported | ||
1492 | * back directly. | ||
1493 | * @since 1.2.0 | ||
1494 | */ | ||
1495 | EAPI Eina_Bool | ||
1496 | ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, | ||
1497 | Ecore_X_Randr_Mode mode) | ||
1498 | { | ||
1499 | #ifdef ECORE_XRANDR | ||
1500 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1501 | |||
1502 | if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) | ||
1503 | return EINA_FALSE; | ||
1504 | |||
1505 | XRRAddOutputMode(_ecore_x_disp, output, mode); | ||
1506 | return EINA_TRUE; | ||
1507 | #else | ||
1508 | return EINA_FALSE; | ||
1509 | #endif | ||
1510 | } | ||
1511 | |||
1512 | /* | ||
1513 | * @brief delete given mode from given output | ||
1514 | * @param output the output the mode is removed from | ||
1515 | * @param mode the mode removed from the output | ||
1516 | * @since 1.2.0 | ||
1517 | */ | ||
1518 | EAPI void | ||
1519 | ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, | ||
1520 | Ecore_X_Randr_Mode mode) | ||
1521 | { | ||
1522 | #ifdef ECORE_XRANDR | ||
1523 | RANDR_CHECK_1_2_RET(); | ||
1524 | |||
1525 | if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) | ||
1526 | return; | ||
1527 | |||
1528 | XRRDeleteOutputMode(_ecore_x_disp, output, mode); | ||
1529 | #else | ||
1530 | return; | ||
1531 | #endif | ||
1532 | } | ||
1533 | |||
1534 | EAPI Ecore_X_Randr_Mode * | ||
1535 | ecore_x_randr_output_modes_get(Ecore_X_Window root, | ||
1536 | Ecore_X_Randr_Output output, | ||
1537 | int *num, | ||
1538 | int *npreferred) | ||
1539 | { | ||
1540 | #ifdef ECORE_XRANDR | ||
1541 | RANDR_CHECK_1_2_RET(NULL); | ||
1542 | XRRScreenResources *res = NULL; | ||
1543 | XRROutputInfo *output_info = NULL; | ||
1544 | Ecore_X_Randr_Mode *modes = NULL; | ||
1545 | |||
1546 | if ((output != Ecore_X_Randr_None) | ||
1547 | && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) | ||
1548 | && (output_info = | ||
1549 | XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) | ||
1550 | { | ||
1551 | if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode))) | ||
1552 | { | ||
1553 | memcpy(modes, output_info->modes, | ||
1554 | (sizeof(Ecore_X_Randr_Mode) * output_info->nmode)); | ||
1555 | if (num) | ||
1556 | *num = output_info->nmode; | ||
1557 | |||
1558 | if (npreferred) | ||
1559 | *npreferred = output_info->npreferred; | ||
1560 | } | ||
1561 | } | ||
1562 | |||
1563 | if (output_info) | ||
1564 | XRRFreeOutputInfo(output_info); | ||
1565 | |||
1566 | if (res) | ||
1567 | XRRFreeScreenResources(res); | ||
1568 | |||
1569 | return modes; | ||
1570 | #else | ||
1571 | return NULL; | ||
1572 | #endif | ||
1573 | } | ||
1574 | |||
1575 | EAPI Ecore_X_Randr_Crtc * | ||
1576 | ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, | ||
1577 | Ecore_X_Randr_Output output, | ||
1578 | int *num) | ||
1579 | { | ||
1580 | #ifdef ECORE_XRANDR | ||
1581 | RANDR_CHECK_1_2_RET(NULL); | ||
1582 | XRRScreenResources *res = NULL; | ||
1583 | XRROutputInfo *output_info = NULL; | ||
1584 | Ecore_X_Randr_Crtc *crtcs = NULL; | ||
1585 | |||
1586 | if ((output != Ecore_X_Randr_None)) | ||
1587 | { | ||
1588 | if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1589 | { | ||
1590 | if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) | ||
1591 | { | ||
1592 | if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc))) | ||
1593 | { | ||
1594 | memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)); | ||
1595 | if (num) *num = output_info->ncrtc; | ||
1596 | } | ||
1597 | XRRFreeOutputInfo(output_info); | ||
1598 | } | ||
1599 | XRRFreeScreenResources(res); | ||
1600 | } | ||
1601 | } | ||
1602 | return crtcs; | ||
1603 | #else | ||
1604 | return Ecore_X_Randr_None; | ||
1605 | #endif | ||
1606 | } | ||
1607 | |||
1608 | /** | ||
1609 | * @brief gets the the outputs which might be used simultenously on the same | ||
1610 | * CRTC. | ||
1611 | * @param root window that this information should be queried for. | ||
1612 | * @param output the output which's clones we concern | ||
1613 | * @param num number of possible clones | ||
1614 | */ | ||
1615 | EAPI Ecore_X_Randr_Output * | ||
1616 | ecore_x_randr_output_clones_get(Ecore_X_Window root, | ||
1617 | Ecore_X_Randr_Output output, | ||
1618 | int *num) | ||
1619 | { | ||
1620 | #ifdef ECORE_XRANDR | ||
1621 | RANDR_CHECK_1_2_RET(NULL); | ||
1622 | XRRScreenResources *res = NULL; | ||
1623 | XRROutputInfo *output_info = NULL; | ||
1624 | Ecore_X_Randr_Output *outputs = NULL; | ||
1625 | |||
1626 | if ((output != Ecore_X_Randr_None)) | ||
1627 | { | ||
1628 | if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1629 | { | ||
1630 | if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) | ||
1631 | { | ||
1632 | if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone))) | ||
1633 | { | ||
1634 | memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone)); | ||
1635 | if (num) *num = output_info->nclone; | ||
1636 | } | ||
1637 | XRRFreeOutputInfo(output_info); | ||
1638 | } | ||
1639 | XRRFreeScreenResources(res); | ||
1640 | } | ||
1641 | } | ||
1642 | return outputs; | ||
1643 | #else | ||
1644 | return Ecore_X_Randr_None; | ||
1645 | #endif | ||
1646 | } | ||
1647 | |||
1648 | EAPI Ecore_X_Randr_Crtc | ||
1649 | ecore_x_randr_output_crtc_get(Ecore_X_Window root, | ||
1650 | Ecore_X_Randr_Output output) | ||
1651 | { | ||
1652 | #ifdef ECORE_XRANDR | ||
1653 | RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); | ||
1654 | XRRScreenResources *res = NULL; | ||
1655 | XRROutputInfo *output_info = NULL; | ||
1656 | Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; | ||
1657 | |||
1658 | if ((output != Ecore_X_Randr_None)) | ||
1659 | { | ||
1660 | if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1661 | { | ||
1662 | if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) | ||
1663 | { | ||
1664 | ret = output_info->crtc; | ||
1665 | XRRFreeOutputInfo(output_info); | ||
1666 | } | ||
1667 | XRRFreeScreenResources(res); | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | return ret; | ||
1672 | #else | ||
1673 | return Ecore_X_Randr_None; | ||
1674 | #endif | ||
1675 | } | ||
1676 | |||
1677 | /** | ||
1678 | * @brief gets the given output's name as reported by X | ||
1679 | * @param root the window which's screen will be queried | ||
1680 | * @param len length of returned c-string. | ||
1681 | * @return name of the output as reported by X | ||
1682 | */ | ||
1683 | EAPI char * | ||
1684 | ecore_x_randr_output_name_get(Ecore_X_Window root, | ||
1685 | Ecore_X_Randr_Output output, | ||
1686 | int *len) | ||
1687 | { | ||
1688 | #ifdef ECORE_XRANDR | ||
1689 | RANDR_CHECK_1_2_RET(NULL); | ||
1690 | XRRScreenResources *res = NULL; | ||
1691 | XRROutputInfo *output_info = NULL; | ||
1692 | char *ret = NULL; | ||
1693 | |||
1694 | if ((output != Ecore_X_Randr_None) | ||
1695 | && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) | ||
1696 | && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) | ||
1697 | { | ||
1698 | /* | ||
1699 | * Actually the below command is correct, but due to a bug in libXrandr | ||
1700 | * it doesn't work. Therefore we stick with strlen(). | ||
1701 | * Replace the line below with the following once this bug is | ||
1702 | * fixed within libXrandr. | ||
1703 | * | ||
1704 | * *len = output_info->nameLen; | ||
1705 | * | ||
1706 | */ | ||
1707 | if ((ret = strdup(output_info->name)) && len) | ||
1708 | *len = strlen(ret); | ||
1709 | |||
1710 | XRRFreeOutputInfo(output_info); | ||
1711 | } | ||
1712 | |||
1713 | if (res) | ||
1714 | XRRFreeScreenResources(res); | ||
1715 | |||
1716 | return ret; | ||
1717 | #else | ||
1718 | return NULL; | ||
1719 | #endif | ||
1720 | } | ||
1721 | |||
1722 | /** | ||
1723 | * @brief gets the width and hight of a given mode | ||
1724 | * @param mode the mode which's size is to be looked up | ||
1725 | * @param w width of given mode in px | ||
1726 | * @param h height of given mode in px | ||
1727 | */ | ||
1728 | EAPI void | ||
1729 | ecore_x_randr_mode_size_get(Ecore_X_Window root, | ||
1730 | Ecore_X_Randr_Mode mode, | ||
1731 | int *w, | ||
1732 | int *h) | ||
1733 | { | ||
1734 | #ifdef ECORE_XRANDR | ||
1735 | RANDR_CHECK_1_2_RET(); | ||
1736 | XRRScreenResources *res = NULL; | ||
1737 | int i; | ||
1738 | |||
1739 | if ((mode != Ecore_X_Randr_None) | ||
1740 | && (w || h) | ||
1741 | && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1742 | { | ||
1743 | for (i = 0; i < res->nmode; i++) | ||
1744 | { | ||
1745 | if (res->modes[i].id == mode) | ||
1746 | { | ||
1747 | if (w) | ||
1748 | *w = res->modes[i].width; | ||
1749 | |||
1750 | if (h) | ||
1751 | *h = res->modes[i].height; | ||
1752 | |||
1753 | break; | ||
1754 | } | ||
1755 | } | ||
1756 | } | ||
1757 | |||
1758 | if (res) | ||
1759 | XRRFreeScreenResources(res); | ||
1760 | |||
1761 | #endif | ||
1762 | } | ||
1763 | |||
1764 | /** | ||
1765 | * @brief gets the EDID information of an attached output if available. | ||
1766 | * Note that this information is not to be compared using ordinary string | ||
1767 | * comparison functions, since it includes 0-bytes. | ||
1768 | * @param root window this information should be queried from | ||
1769 | * @param output the XID of the output | ||
1770 | * @param length length of the byte-array. If NULL, request will fail. | ||
1771 | */ | ||
1772 | EAPI unsigned char * | ||
1773 | ecore_x_randr_output_edid_get(Ecore_X_Window root, | ||
1774 | Ecore_X_Randr_Output output, | ||
1775 | unsigned long *length) | ||
1776 | { | ||
1777 | #ifdef ECORE_XRANDR | ||
1778 | RANDR_CHECK_1_2_RET(NULL); | ||
1779 | Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False); | ||
1780 | unsigned char *prop_data, *ret = NULL; | ||
1781 | int actual_format; | ||
1782 | unsigned long nitems, bytes_after; | ||
1783 | Atom actual_type; | ||
1784 | |||
1785 | if (!length || !_ecore_x_randr_output_validate(root, output)) | ||
1786 | return NULL; | ||
1787 | |||
1788 | if (XRRGetOutputProperty (_ecore_x_disp, output, name, | ||
1789 | 0, 100, False, False, | ||
1790 | AnyPropertyType, | ||
1791 | &actual_type, &actual_format, | ||
1792 | &nitems, &bytes_after, &prop_data) == Success) | ||
1793 | { | ||
1794 | if (actual_type == XA_INTEGER && actual_format == 8) | ||
1795 | { | ||
1796 | if ((ret = malloc(nitems * sizeof(unsigned char)))) | ||
1797 | { | ||
1798 | if (length && | ||
1799 | (memcpy(ret, prop_data, (nitems * sizeof(unsigned char))))) | ||
1800 | *length = nitems; | ||
1801 | |||
1802 | return ret; | ||
1803 | } | ||
1804 | } | ||
1805 | } | ||
1806 | |||
1807 | return NULL; | ||
1808 | #else | ||
1809 | return NULL; | ||
1810 | #endif | ||
1811 | } | ||
1812 | |||
1813 | EAPI Ecore_X_Randr_Connection_Status | ||
1814 | ecore_x_randr_output_connection_status_get(Ecore_X_Window root, | ||
1815 | Ecore_X_Randr_Output output) | ||
1816 | { | ||
1817 | #ifdef ECORE_XRANDR | ||
1818 | RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); | ||
1819 | XRRScreenResources *res = NULL; | ||
1820 | XRROutputInfo *output_info = NULL; | ||
1821 | Ecore_X_Randr_Connection_Status ret = | ||
1822 | ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
1823 | |||
1824 | if ((output != Ecore_X_Randr_None) | ||
1825 | && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) | ||
1826 | && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) | ||
1827 | { | ||
1828 | ret = output_info->connection; | ||
1829 | } | ||
1830 | |||
1831 | if (output_info) | ||
1832 | XRRFreeOutputInfo(output_info); | ||
1833 | |||
1834 | if (res) | ||
1835 | XRRFreeScreenResources(res); | ||
1836 | |||
1837 | return ret; | ||
1838 | #else | ||
1839 | return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; | ||
1840 | #endif | ||
1841 | } | ||
1842 | |||
1843 | EAPI void | ||
1844 | ecore_x_randr_output_size_mm_get(Ecore_X_Window root, | ||
1845 | Ecore_X_Randr_Output output, | ||
1846 | int *w_mm, | ||
1847 | int *h_mm) | ||
1848 | { | ||
1849 | #ifdef ECORE_XRANDR | ||
1850 | RANDR_CHECK_1_2_RET(); | ||
1851 | XRRScreenResources *res = NULL; | ||
1852 | XRROutputInfo *output_info = NULL; | ||
1853 | |||
1854 | if ((output != Ecore_X_Randr_None) | ||
1855 | && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
1856 | { | ||
1857 | if ((output_info = | ||
1858 | XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) | ||
1859 | { | ||
1860 | if (w_mm) | ||
1861 | *w_mm = output_info->mm_width; | ||
1862 | |||
1863 | if (h_mm) | ||
1864 | *h_mm = output_info->mm_height; | ||
1865 | |||
1866 | XRRFreeOutputInfo(output_info); | ||
1867 | } | ||
1868 | |||
1869 | XRRFreeScreenResources(res); | ||
1870 | } | ||
1871 | |||
1872 | #endif | ||
1873 | } | ||
1874 | |||
1875 | EAPI Eina_Bool | ||
1876 | ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, | ||
1877 | const Ecore_X_Randr_Crtc *not_moved, | ||
1878 | int nnot_moved, | ||
1879 | int dx, | ||
1880 | int dy) | ||
1881 | { | ||
1882 | #ifdef ECORE_XRANDR | ||
1883 | Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL; | ||
1884 | XRRScreenResources *res = NULL; | ||
1885 | int i, j, k, n; | ||
1886 | Eina_Bool ret; | ||
1887 | |||
1888 | if ((nnot_moved <= 0) || (!not_moved) | ||
1889 | || !_ecore_x_randr_root_validate(root) | ||
1890 | || !(res = | ||
1891 | _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
1892 | return EINA_FALSE; | ||
1893 | |||
1894 | n = (res->ncrtc - nnot_moved); | ||
1895 | if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n))) | ||
1896 | { | ||
1897 | for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++) | ||
1898 | { | ||
1899 | for (j = 0; j < nnot_moved; j++) | ||
1900 | { | ||
1901 | if (res->crtcs[i] == not_moved[j]) | ||
1902 | break; | ||
1903 | } | ||
1904 | if (j == nnot_moved) | ||
1905 | //crtcs[i] is not in the 'not to move'-list | ||
1906 | crtcs_to_be_moved[k++] = res->crtcs[i]; | ||
1907 | } | ||
1908 | } | ||
1909 | |||
1910 | XRRFreeScreenResources(res); | ||
1911 | ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy); | ||
1912 | free(crtcs_to_be_moved); | ||
1913 | return ret; | ||
1914 | #else | ||
1915 | return EINA_FALSE; | ||
1916 | #endif | ||
1917 | } | ||
1918 | |||
1919 | /* | ||
1920 | * @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. | ||
1921 | * @param root window which's screen's resources are used | ||
1922 | * @param crtcs list of CRTCs to be moved | ||
1923 | * @param ncrtc number of CRTCs in array | ||
1924 | * @param dx amount of pixels the CRTCs should be moved in x direction | ||
1925 | * @param dy amount of pixels the CRTCs should be moved in y direction | ||
1926 | * @return EINA_TRUE if all crtcs could be moved successfully. | ||
1927 | */ | ||
1928 | EAPI Eina_Bool | ||
1929 | ecore_x_randr_move_crtcs(Ecore_X_Window root, | ||
1930 | const Ecore_X_Randr_Crtc *crtcs, | ||
1931 | int ncrtc, | ||
1932 | int dx, | ||
1933 | int dy) | ||
1934 | { | ||
1935 | #ifdef ECORE_XRANDR | ||
1936 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
1937 | XRRScreenResources *res = NULL; | ||
1938 | XRRCrtcInfo **crtc_info = NULL; | ||
1939 | Eina_Bool ret = EINA_TRUE; | ||
1940 | int i, cw, ch, w_max, h_max, nw, nh; | ||
1941 | |||
1942 | crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc); | ||
1943 | memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc); | ||
1944 | if (_ecore_x_randr_root_validate(root) | ||
1945 | && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) | ||
1946 | { | ||
1947 | ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); | ||
1948 | ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); | ||
1949 | nw = cw; | ||
1950 | nh = ch; | ||
1951 | |||
1952 | for (i = 0; | ||
1953 | (i < ncrtc) && | ||
1954 | (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])); | ||
1955 | i++) | ||
1956 | { | ||
1957 | if (((crtc_info[i]->x + dx) < 0) || | ||
1958 | ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max) | ||
1959 | || ((crtc_info[i]->y + dy) < 0) || | ||
1960 | ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max) | ||
1961 | ) | ||
1962 | goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; | ||
1963 | |||
1964 | nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw); | ||
1965 | nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh); | ||
1966 | } | ||
1967 | //not out of bounds | ||
1968 | |||
1969 | //resize if necessary | ||
1970 | if (!(((nw > cw) || | ||
1971 | (nh > ch)) || | ||
1972 | ecore_x_randr_screen_current_size_set(root, nw, nh, | ||
1973 | Ecore_X_Randr_Unset, | ||
1974 | Ecore_X_Randr_Unset))) | ||
1975 | goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; | ||
1976 | |||
1977 | //actually move all the crtcs, keep their rotation and mode. | ||
1978 | for (i = 0; (i < ncrtc) && crtc_info[i]; i++) | ||
1979 | { | ||
1980 | if ((crtc_info[i]) && | ||
1981 | (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, | ||
1982 | Ecore_X_Randr_Unset, | ||
1983 | (crtc_info[i]->x + dx), | ||
1984 | (crtc_info[i]->y + dy), | ||
1985 | crtc_info[i]->mode, | ||
1986 | crtc_info[i]->rotation))) | ||
1987 | { | ||
1988 | ret = EINA_FALSE; | ||
1989 | break; | ||
1990 | } | ||
1991 | } | ||
1992 | if (i < ncrtc) | ||
1993 | { | ||
1994 | //something went wrong, let's try to move the already moved crtcs | ||
1995 | //back. | ||
1996 | while ((i--) >= 0) | ||
1997 | { | ||
1998 | if (crtc_info[i]) | ||
1999 | ecore_x_randr_crtc_settings_set(root, | ||
2000 | crtcs[i], | ||
2001 | NULL, | ||
2002 | Ecore_X_Randr_Unset, | ||
2003 | (crtc_info[i]->x - dx), | ||
2004 | (crtc_info[i]->y - dy), | ||
2005 | crtc_info[i]->mode, | ||
2006 | crtc_info[i]->rotation); | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | for (i = 0; i < ncrtc; i++) | ||
2011 | { | ||
2012 | if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]); | ||
2013 | } | ||
2014 | } | ||
2015 | |||
2016 | XRRFreeScreenResources(res); | ||
2017 | |||
2018 | return ret; | ||
2019 | _ecore_x_randr_move_crtcs_fail_free_crtc_info: | ||
2020 | while (i-- > 0) | ||
2021 | XRRFreeCrtcInfo(crtc_info[i]); | ||
2022 | XRRFreeScreenResources(res); | ||
2023 | return EINA_FALSE; | ||
2024 | #else | ||
2025 | return EINA_FALSE; | ||
2026 | #endif | ||
2027 | } | ||
2028 | |||
2029 | /** | ||
2030 | * @brief removes unused screen space. The most upper left CRTC is set to 0x0 | ||
2031 | * and all other CRTCs dx,dy respectively. | ||
2032 | * @param root the window's screen which will be reset. | ||
2033 | */ | ||
2034 | EAPI void | ||
2035 | ecore_x_randr_screen_reset(Ecore_X_Window root) | ||
2036 | { | ||
2037 | #ifdef ECORE_XRANDR | ||
2038 | XRRCrtcInfo *crtc_info = NULL; | ||
2039 | XRRScreenResources *res = NULL; | ||
2040 | //the 100000 are just a random huge number. | ||
2041 | int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0; | ||
2042 | |||
2043 | if (!_ecore_x_randr_root_validate(root) || | ||
2044 | !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) | ||
2045 | return; | ||
2046 | |||
2047 | Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc]; | ||
2048 | |||
2049 | for (i = 0; i < res->ncrtc; i++) | ||
2050 | { | ||
2051 | if (!(crtc_info = | ||
2052 | XRRGetCrtcInfo(_ecore_x_disp, res, | ||
2053 | res->crtcs[i])) || | ||
2054 | (crtc_info->mode == Ecore_X_Randr_None) || | ||
2055 | (crtc_info->mode == Ecore_X_Randr_Unset) | ||
2056 | || ((crtc_info->noutput == 0))) | ||
2057 | continue; | ||
2058 | |||
2059 | enabled_crtcs[nenabled_crtcs++] = res->crtcs[i]; | ||
2060 | |||
2061 | if ((int)(crtc_info->x + crtc_info->width) > w_n) | ||
2062 | w_n = (crtc_info->x + crtc_info->width); | ||
2063 | |||
2064 | if ((int)(crtc_info->y + crtc_info->height) > h_n) | ||
2065 | h_n = (crtc_info->y + crtc_info->height); | ||
2066 | |||
2067 | if (crtc_info->x < dx_min) | ||
2068 | dx_min = crtc_info->x; | ||
2069 | if (crtc_info->y < dy_min) | ||
2070 | dy_min = crtc_info->y; | ||
2071 | |||
2072 | XRRFreeCrtcInfo(crtc_info); | ||
2073 | } | ||
2074 | if ((dx_min > 0) || (dy_min > 0)) | ||
2075 | { | ||
2076 | if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min)) | ||
2077 | { | ||
2078 | w_n -= dx_min; | ||
2079 | h_n -= dy_min; | ||
2080 | } | ||
2081 | } | ||
2082 | ecore_x_randr_screen_current_size_set(root, | ||
2083 | w_n, | ||
2084 | h_n, | ||
2085 | Ecore_X_Randr_Unset, | ||
2086 | Ecore_X_Randr_Unset); | ||
2087 | #endif | ||
2088 | } | ||
2089 | |||
2090 | /** | ||
2091 | * @brief set up the backlight level to the given level. | ||
2092 | * @param root the window's screen which will be set. | ||
2093 | * @param level of the backlight between 0 and 1 | ||
2094 | */ | ||
2095 | |||
2096 | EAPI void | ||
2097 | ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, | ||
2098 | double level) | ||
2099 | { | ||
2100 | #ifdef ECORE_XRANDR | ||
2101 | RANDR_CHECK_1_2_RET(); | ||
2102 | Atom _backlight; | ||
2103 | XRRScreenResources *resources = NULL; | ||
2104 | Ecore_X_Randr_Output output; | ||
2105 | int o; | ||
2106 | |||
2107 | if ((level < 0) || (level > 1)) | ||
2108 | { | ||
2109 | ERR("Wrong value for the backlight level. It should be between 0 and 1."); | ||
2110 | return; | ||
2111 | } | ||
2112 | |||
2113 | /* | ||
2114 | * To make sure that the _backlight atomic property still exists. | ||
2115 | */ | ||
2116 | _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); | ||
2117 | if (_backlight == None) | ||
2118 | { | ||
2119 | WRN("Backlight setting is not supported on this server or driver"); | ||
2120 | return; | ||
2121 | } | ||
2122 | |||
2123 | /* get the ressources */ | ||
2124 | resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root); | ||
2125 | if (!resources) return; | ||
2126 | |||
2127 | for (o = 0; o < resources->noutput; o++) | ||
2128 | { | ||
2129 | output = resources->outputs[o]; | ||
2130 | if (ecore_x_randr_output_backlight_level_get(root, output) >= 0) | ||
2131 | { | ||
2132 | ecore_x_randr_output_backlight_level_set(root, output, level); | ||
2133 | } | ||
2134 | } | ||
2135 | XRRFreeScreenResources(resources); | ||
2136 | #endif | ||
2137 | } | ||
2138 | |||
2139 | /* | ||
2140 | * @brief check if a backlight is available | ||
2141 | * @return whether a blacklight is available | ||
2142 | */ | ||
2143 | |||
2144 | EAPI Eina_Bool | ||
2145 | ecore_x_randr_output_backlight_available(void) | ||
2146 | { | ||
2147 | #ifdef ECORE_XRANDR | ||
2148 | RANDR_CHECK_1_2_RET(-1); | ||
2149 | Atom _backlight; | ||
2150 | |||
2151 | _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); | ||
2152 | |||
2153 | return (_backlight == None) ? EINA_FALSE : EINA_TRUE; | ||
2154 | |||
2155 | #endif | ||
2156 | return EINA_FALSE; | ||
2157 | } | ||
2158 | |||
2159 | /* | ||
2160 | * @brief get the backlight level of the given output | ||
2161 | * @param root window which's screen should be queried | ||
2162 | * @param output from which the backlight level should be retrieved | ||
2163 | * @return the backlight level | ||
2164 | */ | ||
2165 | |||
2166 | EAPI double | ||
2167 | ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, | ||
2168 | Ecore_X_Randr_Output output) | ||
2169 | { | ||
2170 | #ifdef ECORE_XRANDR | ||
2171 | RANDR_CHECK_1_2_RET(-1); | ||
2172 | Atom actual_type; | ||
2173 | Atom _backlight; | ||
2174 | XRRPropertyInfo *info = NULL; | ||
2175 | double dvalue; | ||
2176 | int actual_format; | ||
2177 | long value, max, min; | ||
2178 | unsigned long nitems; | ||
2179 | unsigned long bytes_after; | ||
2180 | unsigned char *prop = NULL; | ||
2181 | |||
2182 | /* set backlight variable if not already done */ | ||
2183 | |||
2184 | _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); | ||
2185 | if (_backlight == None) | ||
2186 | { | ||
2187 | ERR("Backlight property is not suppported on this server or driver"); | ||
2188 | return -1; | ||
2189 | } | ||
2190 | |||
2191 | if (!_ecore_x_randr_output_validate(root, output)) | ||
2192 | { | ||
2193 | ERR("Invalid output"); | ||
2194 | return -1; | ||
2195 | } | ||
2196 | |||
2197 | if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight, | ||
2198 | 0, 4, False, False, None, | ||
2199 | &actual_type, &actual_format, | ||
2200 | &nitems, &bytes_after, &prop) != Success) | ||
2201 | { | ||
2202 | WRN("Backlight not supported on this output"); | ||
2203 | return -1; | ||
2204 | } | ||
2205 | |||
2206 | if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1; | ||
2207 | |||
2208 | value = *((long *)prop); | ||
2209 | free (prop); | ||
2210 | |||
2211 | /* I have the current value of the backlight */ | ||
2212 | /* Now retrieve the min and max intensities of the output */ | ||
2213 | info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); | ||
2214 | if (info) | ||
2215 | { | ||
2216 | dvalue = -1; | ||
2217 | if ((info->range) && (info->num_values == 2)) | ||
2218 | { | ||
2219 | /* finally convert the current value in the interval [0..1] */ | ||
2220 | min = info->values[0]; | ||
2221 | max = info->values[1]; | ||
2222 | dvalue = ((double)(value - min)) / ((double)(max - min)); | ||
2223 | } | ||
2224 | free(info); | ||
2225 | return dvalue; | ||
2226 | } | ||
2227 | #endif | ||
2228 | return -1; | ||
2229 | } | ||
2230 | |||
2231 | /* | ||
2232 | * @brief set the backlight level of a given output | ||
2233 | * @param root window which's screen should be queried | ||
2234 | * @param output that should be set | ||
2235 | * @param level for which the backlight should be set | ||
2236 | * @return EINA_TRUE in case of success | ||
2237 | */ | ||
2238 | |||
2239 | EAPI Eina_Bool | ||
2240 | ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, | ||
2241 | Ecore_X_Randr_Output output, | ||
2242 | double level) | ||
2243 | { | ||
2244 | #ifdef ECORE_XRANDR | ||
2245 | RANDR_CHECK_1_2_RET(EINA_FALSE); | ||
2246 | Atom _backlight; | ||
2247 | XRRPropertyInfo *info = NULL; | ||
2248 | double min, max, tmp; | ||
2249 | long new; | ||
2250 | |||
2251 | if ((level < 0) || (level > 1)) | ||
2252 | { | ||
2253 | ERR("Backlight level should be between 0 and 1"); | ||
2254 | return EINA_FALSE; | ||
2255 | } | ||
2256 | |||
2257 | if (!_ecore_x_randr_output_validate(root, output)) | ||
2258 | { | ||
2259 | ERR("Wrong output value"); | ||
2260 | return EINA_FALSE; | ||
2261 | } | ||
2262 | |||
2263 | _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); | ||
2264 | if (_backlight == None) | ||
2265 | { | ||
2266 | WRN("Backlight property is not suppported on this server or driver"); | ||
2267 | return EINA_FALSE; | ||
2268 | } | ||
2269 | |||
2270 | info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); | ||
2271 | if (info) | ||
2272 | { | ||
2273 | if ((info->range) && (info->num_values == 2)) | ||
2274 | { | ||
2275 | min = info->values[0]; | ||
2276 | max = info->values[1]; | ||
2277 | tmp = (level * (max - min)) + min; | ||
2278 | new = tmp; | ||
2279 | if (new > max) new = max; | ||
2280 | if (new < min) new = min; | ||
2281 | XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32, | ||
2282 | PropModeReplace, (unsigned char *)&new, 1); | ||
2283 | XFlush(_ecore_x_disp); | ||
2284 | } | ||
2285 | free(info); | ||
2286 | return EINA_TRUE; | ||
2287 | } | ||
2288 | #endif | ||
2289 | return EINA_FALSE; | ||
2290 | } | ||
2291 | |||
2292 | /* | ||
2293 | * @brief get the outputs, which display a certain window | ||
2294 | * @param window window the displaying outputs shall be found for | ||
2295 | * @param num the number of outputs displaying the window | ||
2296 | * @return array of outputs that display a certain window. NULL if no outputs | ||
2297 | * was found that displays the specified window. | ||
2298 | */ | ||
2299 | |||
2300 | EAPI Ecore_X_Randr_Output * | ||
2301 | ecore_x_randr_window_outputs_get(Ecore_X_Window window, | ||
2302 | int *num) | ||
2303 | { | ||
2304 | #ifdef ECORE_XRANDR | ||
2305 | Ecore_X_Window root; | ||
2306 | Ecore_X_Randr_Crtc *crtcs; | ||
2307 | Ecore_X_Randr_Output *outputs, *ret = NULL; | ||
2308 | int ncrtcs, noutputs, i, nret = 0; | ||
2309 | |||
2310 | if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail; | ||
2311 | |||
2312 | root = ecore_x_window_root_get(window); | ||
2313 | if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs))) | ||
2314 | goto _ecore_x_randr_current_output_get_fail; | ||
2315 | |||
2316 | for (i = 0, nret = 0; i < ncrtcs; i++) | ||
2317 | { | ||
2318 | |||
2319 | outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i], | ||
2320 | &noutputs); | ||
2321 | if (!outputs) | ||
2322 | goto _ecore_x_randr_current_output_get_fail_free; | ||
2323 | nret += noutputs; | ||
2324 | ret = realloc(ret, (nret * sizeof(Ecore_X_Randr_Output))); | ||
2325 | memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output))); | ||
2326 | free(outputs); | ||
2327 | } | ||
2328 | free(crtcs); | ||
2329 | |||
2330 | if (num) | ||
2331 | *num = nret; | ||
2332 | |||
2333 | return ret; | ||
2334 | |||
2335 | _ecore_x_randr_current_output_get_fail_free: | ||
2336 | free(outputs); | ||
2337 | free(crtcs); | ||
2338 | free(ret); | ||
2339 | _ecore_x_randr_current_output_get_fail: | ||
2340 | #endif | ||
2341 | if (num) *num = 0; | ||
2342 | return NULL; | ||
2343 | } | ||
2344 | |||
2345 | /* | ||
2346 | * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead. | ||
2347 | * @brief get the outputs, which display a certain window | ||
2348 | * @param window window the displaying outputs shall be found for | ||
2349 | * @param num the number of outputs displaying the window | ||
2350 | * @return array of outputs that display a certain window. NULL if no outputs | ||
2351 | * was found that displays the specified window. | ||
2352 | */ | ||
2353 | |||
2354 | EAPI Ecore_X_Randr_Output * | ||
2355 | ecore_x_randr_current_output_get(Ecore_X_Window window, | ||
2356 | int *num) | ||
2357 | { | ||
2358 | return ecore_x_randr_window_outputs_get(window, num); | ||
2359 | } | ||
2360 | |||