2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
9 #include "ecore_x_private.h"
10 #include "ecore_x_randr.h"
16 #define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0
17 #define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1
21 #define RANDR_1_2 ((1 << 16) | 2)
23 #define RANDR_VALIDATE_ROOT(screen, root) \
24 ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1)
26 #define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \
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"
38 extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
42 extern int _randr_version;
46 * @brief Enable event selection. This enables basic interaction with
47 * output/crtc events and requires RandR >= 1.2.
49 * @param win Select this window's properties for RandR events.
50 * @param on Enable/disable selecting.
53 ecore_x_randr_events_select(Ecore_X_Window win,
59 LOGFN(__FILE__, __LINE__, __FUNCTION__);
64 mask = RRScreenChangeNotifyMask;
65 if (_randr_version >= RANDR_1_2)
66 mask |= (RRCrtcChangeNotifyMask |
67 RROutputChangeNotifyMask |
68 RROutputPropertyNotifyMask);
71 XRRSelectInput(_ecore_x_disp, win, mask);
76 * @brief Validates a CRTC for a given root window's screen.
78 * @param root The window which's default display will be queried.
79 * @param crtc The CRTC to be validated.
80 * @return In case it is found, @c EINA_TRUE will be returned, @c EINA_FALSE
83 static inline Eina_Bool
84 _ecore_x_randr_crtc_validate(Ecore_X_Window root,
85 Ecore_X_Randr_Crtc crtc)
88 RANDR_CHECK_1_2_RET(EINA_FALSE);
90 XRRScreenResources *res = NULL;
92 Eina_Bool ret = EINA_FALSE;
94 if ((crtc == Ecore_X_Randr_None) ||
95 (crtc == Ecore_X_Randr_Unset))
98 if (_ecore_x_randr_root_validate(root) && crtc &&
99 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
101 for (i = 0; i < res->ncrtc; i++)
103 if (res->crtcs[i] == crtc)
109 XRRFreeScreenResources(res);
119 _ecore_x_randr_output_validate(Ecore_X_Window root,
120 Ecore_X_Randr_Output output)
123 RANDR_CHECK_1_2_RET(EINA_FALSE);
125 Eina_Bool ret = EINA_FALSE;
126 XRRScreenResources *res = NULL;
129 if (_ecore_x_randr_root_validate(root) && output &&
130 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
132 for (i = 0; i < res->noutput; i++)
134 if (res->outputs[i] == output)
140 XRRFreeScreenResources(res);
149 static inline Eina_Bool
150 _ecore_x_randr_mode_validate(Ecore_X_Window root,
151 Ecore_X_Randr_Mode mode)
154 RANDR_CHECK_1_2_RET(EINA_FALSE);
156 Eina_Bool ret = EINA_FALSE;
157 XRRScreenResources *res = NULL;
160 if (_ecore_x_randr_root_validate(root) && mode &&
161 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
163 for (i = 0; i < res->nmode; i++)
165 if (res->modes[i].id == mode)
171 XRRFreeScreenResources(res);
181 * @param w width of screen in px
182 * @param h height of screen in px
185 ecore_x_randr_screen_current_size_get(Ecore_X_Window root,
192 RANDR_CHECK_1_2_RET();
193 Ecore_X_Randr_Screen scr;
195 if (!RANDR_VALIDATE_ROOT(scr, root))
199 *w = DisplayWidth(_ecore_x_disp, scr);
202 *h = DisplayHeight(_ecore_x_disp, scr);
205 *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
208 *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
214 * @param root window which's screen will be queried
215 * @param wmin minimum width the screen can be set to
216 * @param hmin minimum height the screen can be set to
217 * @param wmax maximum width the screen can be set to
218 * @param hmax maximum height the screen can be set to
221 ecore_x_randr_screen_size_range_get(Ecore_X_Window root,
228 RANDR_CHECK_1_2_RET();
229 int twmin, thmin, twmax, thmax;
230 if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax,
250 * @param root Window which's screen's size should be set. If invalid (e.g.
251 * @c NULL) no action is taken.
252 * @param w Width in px the screen should be set to. If out of valid
253 * boundaries, current value is assumed.
254 * @param h Height in px the screen should be set to. If out of valid
255 * boundaries, current value is assumed.
256 * @param w_mm Width in mm the screen should be set to. If @c 0, current
258 * @param h_mm Height in mm the screen should be set to. If @c 0, current
260 * @return @c EINA_TRUE if request was successfully sent or screen is already
261 * in requested size, @c EINA_FALSE if parameters are invalid.
264 ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
271 RANDR_CHECK_1_2_RET(EINA_FALSE);
273 Ecore_X_Randr_Screen scr;
274 int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax;
276 if (!RANDR_VALIDATE_ROOT(scr, root))
279 ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c);
280 if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm))
283 ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax);
285 if (((w != Ecore_X_Randr_None) &&
288 ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax))))
292 w = DisplayWidth(_ecore_x_disp, scr);
295 h = DisplayHeight(_ecore_x_disp, scr);
299 (int)(((double)(DisplayWidthMM(_ecore_x_disp,
301 (double)DisplayWidth(_ecore_x_disp,
306 (int)(((double)(DisplayHeightMM(_ecore_x_disp,
308 (double)DisplayHeight(_ecore_x_disp,
311 XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm);
319 * @brief get detailed information for all modes related to a root window's screen
320 * @param root window which's screen's ressources are queried
321 * @param num number of modes returned
322 * @return modes' information
324 EAPI Ecore_X_Randr_Mode_Info **
325 ecore_x_randr_modes_info_get(Ecore_X_Window root,
329 RANDR_CHECK_1_2_RET(NULL);
330 XRRScreenResources *res = NULL;
331 Ecore_X_Randr_Mode_Info **ret = NULL;
334 if (_ecore_x_randr_root_validate(root) &&
335 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
338 (Ecore_X_Randr_Mode_Info **)malloc(sizeof(
339 Ecore_X_Randr_Mode_Info *)
343 for (i = 0; i < res->nmode; i++)
345 if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
347 ret[i]->xid = res->modes[i].id;
348 ret[i]->width = res->modes[i].width;
349 ret[i]->height = res->modes[i].height;
350 ret[i]->dotClock = res->modes[i].dotClock;
351 ret[i]->hSyncStart = res->modes[i].hSyncStart;
352 ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
353 ret[i]->hTotal = res->modes[i].hTotal;
354 ret[i]->hSkew = res->modes[i].hSkew;
355 ret[i]->vSyncStart = res->modes[i].vSyncStart;
356 ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
357 ret[i]->vTotal = res->modes[i].vTotal;
358 if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1))))
359 strncpy(ret[i]->name, res->modes[i].name,
360 (res->modes[i].nameLength + 1));
364 ret[i]->nameLength = res->modes[i].nameLength;
365 ret[i]->modeFlags = res->modes[i].modeFlags;
381 XRRFreeScreenResources(res);
391 * @brief Add a mode to a display.
393 * @param root Window to which's screen's ressources are added.
395 * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
399 EAPI Ecore_X_Randr_Mode
400 ecore_x_randr_mode_info_add(Ecore_X_Window root,
401 Ecore_X_Randr_Mode_Info *mode_info)
404 RANDR_CHECK_1_2_RET(EINA_FALSE);
405 Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
407 if (_ecore_x_randr_root_validate(root) && mode_info)
408 mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info);
412 return Ecore_X_Randr_None;
417 * @brief Delete a mode from the display.
423 ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode)
426 RANDR_CHECK_1_2_RET();
428 XRRDestroyMode(_ecore_x_disp, mode);
435 * @brief get detailed information for a given mode id
436 * @param root window which's screen's ressources are queried
437 * @param mode the XID which identifies the mode of interest
438 * @return mode's detailed information
440 EAPI Ecore_X_Randr_Mode_Info *
441 ecore_x_randr_mode_info_get(Ecore_X_Window root,
442 Ecore_X_Randr_Mode mode)
445 RANDR_CHECK_1_2_RET(NULL);
446 XRRScreenResources *res = NULL;
447 Ecore_X_Randr_Mode_Info *ret = NULL;
450 if (_ecore_x_randr_root_validate(root) &&
451 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
453 for (i = 0; i < res->nmode; i++)
455 if ((res->modes[i].id == mode) &&
456 (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
458 ret->xid = res->modes[i].id;
459 ret->width = res->modes[i].width;
460 ret->height = res->modes[i].height;
461 ret->dotClock = res->modes[i].dotClock;
462 ret->hSyncStart = res->modes[i].hSyncStart;
463 ret->hSyncEnd = res->modes[i].hSyncEnd;
464 ret->hTotal = res->modes[i].hTotal;
465 ret->hSkew = res->modes[i].hSkew;
466 ret->vSyncStart = res->modes[i].vSyncStart;
467 ret->vSyncEnd = res->modes[i].vSyncEnd;
468 ret->vTotal = res->modes[i].vTotal;
471 if (res->modes[i].nameLength > 0)
473 ret->nameLength = res->modes[i].nameLength;
474 ret->name = malloc(res->modes[i].nameLength + 1);
476 memcpy(ret->name, res->modes[i].name,
477 res->modes[i].nameLength + 1);
479 ret->modeFlags = res->modes[i].modeFlags;
483 XRRFreeScreenResources(res);
493 * @brief Free detailed mode information. The pointer handed in will be set to
494 * @c NULL after freeing the memory.
496 * @param mode_info The mode information that should be freed.
499 ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
502 RANDR_CHECK_1_2_RET();
507 free(mode_info->name);
515 * @brief Get all known CRTCs related to a root window's screen.
517 * @param root Window which's screen's ressources are queried.
518 * @param num Number of CRTCs returned.
521 EAPI Ecore_X_Randr_Crtc *
522 ecore_x_randr_crtcs_get(Ecore_X_Window root,
526 RANDR_CHECK_1_2_RET(NULL);
527 XRRScreenResources *res = NULL;
528 Ecore_X_Randr_Crtc *ret = NULL;
531 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
533 if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)))
535 memcpy(ret, res->crtcs, (sizeof(Ecore_X_Randr_Crtc) * res->ncrtc));
539 XRRFreeScreenResources(res);
549 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
550 * @brief get the CRTCs, which display a certain window
551 * @param window window the displaying crtcs shall be found for
552 * @param num the number of crtcs displaying the window
553 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
554 * was found that displays the specified window.
556 EAPI Ecore_X_Randr_Crtc *
557 ecore_x_randr_current_crtc_get(Ecore_X_Window window,
560 return ecore_x_randr_window_crtcs_get(window, num);
564 * @brief get the CRTCs, which display a certain window
565 * @param window window the displaying crtcs shall be found for
566 * @param num the number of crtcs displaying the window
567 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
568 * was found that displays the specified window.
571 EAPI Ecore_X_Randr_Crtc *
572 ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
577 Eina_Rectangle w_geo, c_geo;
578 Ecore_X_Randr_Crtc *crtcs;
579 Ecore_X_Randr_Mode mode;
580 Ecore_X_Randr_Output *ret = NULL;
582 int ncrtcs, i, nret = 0, rx = 0, ry = 0;
584 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail;
586 ecore_x_window_geometry_get(window,
590 root = ecore_x_window_root_get(window);
591 crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs);
592 if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail;
594 /* now get window RELATIVE to root window - thats what matters. */
595 XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw);
599 ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc));
603 goto _ecore_x_randr_window_crtcs_get_fail;
605 for (i = 0, nret = 0; i < ncrtcs; i++)
607 /* if crtc is not enabled, don't bother about it any further */
608 mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
609 if (mode == Ecore_X_Randr_None) continue;
611 ecore_x_randr_crtc_geometry_get(root, crtcs[i],
614 if (eina_rectangles_intersect(&w_geo, &c_geo))
616 ret[nret] = crtcs[i];
622 if (num) *num = nret;
625 _ecore_x_randr_window_crtcs_get_fail:
631 EAPI Ecore_X_Randr_Output *
632 ecore_x_randr_outputs_get(Ecore_X_Window root,
636 RANDR_CHECK_1_2_RET(NULL);
637 XRRScreenResources *res = NULL;
638 Ecore_X_Randr_Output *ret = NULL;
641 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
643 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput)))
645 memcpy(ret, res->outputs,
646 (sizeof(Ecore_X_Randr_Output) * res->noutput));
652 XRRFreeScreenResources(res);
663 * @brief get a CRTC's outputs.
664 * @param root the root window which's screen will be queried
665 * @param num number of outputs referenced by given CRTC
667 EAPI Ecore_X_Randr_Output *
668 ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
669 Ecore_X_Randr_Crtc crtc,
673 RANDR_CHECK_1_2_RET(NULL);
674 XRRScreenResources *res = NULL;
675 Ecore_X_Randr_Output *ret = NULL;
676 XRRCrtcInfo *crtc_info = NULL;
678 if (_ecore_x_randr_crtc_validate(root,
681 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
683 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
685 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)))
687 memcpy(ret, crtc_info->outputs,
688 (sizeof(Ecore_X_Randr_Output) * crtc_info->noutput));
690 *num = crtc_info->noutput;
694 XRRFreeCrtcInfo(crtc_info);
697 XRRFreeScreenResources(res);
707 * @brief get a CRTC's possible outputs.
708 * @param root the root window which's screen will be queried
709 * @param num number of possible outputs referenced by given CRTC
711 EAPI Ecore_X_Randr_Output *
712 ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root,
713 Ecore_X_Randr_Crtc crtc,
717 RANDR_CHECK_1_2_RET(NULL);
718 XRRScreenResources *res = NULL;
719 Ecore_X_Randr_Output *ret = NULL;
720 XRRCrtcInfo *crtc_info = NULL;
722 if (_ecore_x_randr_crtc_validate(root,
724 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
726 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
729 malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)))
731 memcpy(ret, crtc_info->possible,
732 (sizeof(Ecore_X_Randr_Output) * crtc_info->npossible));
737 XRRFreeCrtcInfo(crtc_info);
740 XRRFreeScreenResources(res);
750 ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
751 Ecore_X_Randr_Crtc crtc,
758 RANDR_CHECK_1_2_RET();
759 XRRScreenResources *res = NULL;
760 XRRCrtcInfo *crtc_info = NULL;
762 if (_ecore_x_randr_crtc_validate(root,
765 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
767 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
776 *w = crtc_info->width;
779 *h = crtc_info->height;
781 XRRFreeCrtcInfo(crtc_info);
782 XRRFreeScreenResources(res);
789 * @brief Sets the position of given CRTC within root window's screen.
791 * @param root The window's screen to be queried.
792 * @param crtc The CRTC which's position within the mentioned screen is to be
794 * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
795 * value will be kept.
796 * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
797 * value will be kept.
798 * @return @c EINA_TRUE if position could successfully be altered.
801 ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
802 Ecore_X_Randr_Crtc crtc,
807 RANDR_CHECK_1_2_RET(EINA_FALSE);
808 int w_c, h_c, w_new = 0, h_new = 0;
809 Eina_Rectangle crtc_geo;
811 ecore_x_randr_crtc_geometry_get(root,
817 ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL);
824 if ((x + crtc_geo.w) > w_c)
825 w_new = x + crtc_geo.w;
827 if ((y + crtc_geo.h) > h_c)
828 h_new = y + crtc_geo.h;
830 if ((w_new != 0) || (h_new != 0))
831 if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0))
834 return ecore_x_randr_crtc_settings_set(root,
841 Ecore_X_Randr_Unset);
848 * @brief Get the current set mode of a given CRTC
849 * @param root the window's screen to be queried
850 * @param crtc the CRTC which's should be queried
851 * @return currently set mode or - in case parameters are invalid -
852 * Ecore_X_Randr_Unset
854 EAPI Ecore_X_Randr_Mode
855 ecore_x_randr_crtc_mode_get(Ecore_X_Window root,
856 Ecore_X_Randr_Crtc crtc)
859 RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
860 XRRScreenResources *res = NULL;
861 XRRCrtcInfo *crtc_info = NULL;
862 Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
863 if (_ecore_x_randr_root_validate(root) &&
864 _ecore_x_randr_crtc_validate(root,
867 _ecore_x_randr_get_screen_resources(_ecore_x_disp,
869 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
871 ret = crtc_info->mode;
872 XRRFreeCrtcInfo(crtc_info);
873 XRRFreeScreenResources(res);
878 return Ecore_X_Randr_Unset;
883 * @brief Sets a mode for a CRTC and the outputs attached to it.
885 * @param root The window's screen to be queried.
886 * @param crtc The CRTC which shall be set.
887 * @param outputs Array of outputs which have to be compatible with the mode.
888 * If @c NULL, CRTC will be disabled.
889 * @param noutputs Number of outputs in array to be used. Use
890 * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
891 * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
892 * disabled. If set to @c -1 the call will fail.
893 * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
897 ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
898 Ecore_X_Randr_Crtc crtc,
899 Ecore_X_Randr_Output *outputs,
901 Ecore_X_Randr_Mode mode)
904 RANDR_CHECK_1_2_RET(EINA_FALSE);
906 if (mode == Ecore_X_Randr_Unset)
909 return ecore_x_randr_crtc_settings_set(root,
916 Ecore_X_Randr_Unset);
923 ecore_x_randr_crtc_size_get(Ecore_X_Window root,
924 Ecore_X_Randr_Crtc crtc,
929 RANDR_CHECK_1_2_RET();
930 ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
934 EAPI Ecore_X_Randr_Refresh_Rate
935 ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
936 Ecore_X_Randr_Crtc crtc,
937 Ecore_X_Randr_Mode mode)
940 RANDR_CHECK_1_2_RET(0.0);
941 XRRScreenResources *res = NULL;
942 XRRCrtcInfo *crtc_info = NULL;
943 Ecore_X_Randr_Refresh_Rate ret = 0.0;
946 if (_ecore_x_randr_crtc_validate(root,
948 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
950 for (i = 0; i < res->nmode; i++)
951 if (res->modes[i].id == mode)
953 if (res->modes[i].hTotal && res->modes[i].vTotal)
954 ret = ((double)res->modes[i].dotClock /
955 ((double)res->modes[i].hTotal *
956 (double)res->modes[i].vTotal));
963 XRRFreeCrtcInfo(crtc_info);
966 XRRFreeScreenResources(res);
974 EAPI Ecore_X_Randr_Orientation
975 ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
976 Ecore_X_Randr_Crtc crtc)
979 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
980 XRRCrtcInfo *crtc_info = NULL;
981 XRRScreenResources *res = NULL;
982 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
984 if (_ecore_x_randr_crtc_validate(root,
987 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
989 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
991 ret = crtc_info->rotations;
994 XRRFreeCrtcInfo(crtc_info);
997 XRRFreeScreenResources(res);
1001 return Ecore_X_Randr_None;
1005 EAPI Ecore_X_Randr_Orientation
1006 ecore_x_randr_crtc_orientation_get(Ecore_X_Window root,
1007 Ecore_X_Randr_Crtc crtc)
1010 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1011 XRRCrtcInfo *crtc_info = NULL;
1012 XRRScreenResources *res = NULL;
1013 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
1015 if (_ecore_x_randr_crtc_validate(root,
1018 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1020 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1022 ret = crtc_info->rotation;
1025 XRRFreeCrtcInfo(crtc_info);
1028 XRRFreeScreenResources(res);
1032 return Ecore_X_Randr_None;
1037 ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
1038 Ecore_X_Randr_Crtc crtc,
1039 Ecore_X_Randr_Orientation orientation)
1042 RANDR_CHECK_1_2_RET(EINA_FALSE);
1043 Eina_Bool ret = EINA_FALSE;
1045 if (orientation != Ecore_X_Randr_None)
1047 ret = ecore_x_randr_crtc_settings_set(root,
1050 Ecore_X_Randr_Unset,
1051 Ecore_X_Randr_Unset,
1052 Ecore_X_Randr_Unset,
1053 Ecore_X_Randr_Unset,
1064 ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
1065 Ecore_X_Randr_Crtc crtc,
1070 RANDR_CHECK_1_2_RET();
1072 ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
1077 ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
1078 Ecore_X_Randr_Crtc original,
1079 Ecore_X_Randr_Crtc clon)
1082 RANDR_CHECK_1_2_RET(EINA_FALSE);
1084 XRRScreenResources *res = NULL;
1085 XRRCrtcInfo *clone_crtc_info = NULL;
1086 Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None;
1087 Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None;
1088 Eina_Bool ret = EINA_FALSE;
1091 if (_ecore_x_randr_root_validate(root) &&
1092 _ecore_x_randr_crtc_validate(root,
1094 _ecore_x_randr_crtc_validate(root,
1097 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1099 (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon)))
1101 ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL);
1102 original_mode = ecore_x_randr_crtc_mode_get(root, original);
1103 original_orientation = ecore_x_randr_crtc_orientation_get(root,
1105 ret = ecore_x_randr_crtc_settings_set(root,
1108 Ecore_X_Randr_Unset,
1112 original_orientation);
1113 XRRFreeCrtcInfo(clone_crtc_info);
1114 XRRFreeScreenResources(res);
1124 * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
1125 * auto enabled in it's preferred mode, when it was disabled before.
1127 * @param root The root window which's default display will be queried.
1128 * @param crtc The CRTC which's configuration should be altered.
1129 * @param outputs An array of outputs, that should display this CRTC's content.
1130 * @param noutputs Number of outputs in the array of outputs. If set to
1131 * Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
1132 * If set to Ecore_X_Randr_None, CRTC will be disabled.
1133 * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
1134 * corrdinate will be assumed.
1135 * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
1136 * corrdinate will be assumed.
1137 * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
1138 * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
1140 * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
1141 * used, the current mode is assumed.
1142 * @return @c EINA_TRUE if the configuration alteration was successful,
1143 * @c EINA_FALSE otherwise.
1146 ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
1147 Ecore_X_Randr_Crtc crtc,
1148 Ecore_X_Randr_Output *outputs,
1152 Ecore_X_Randr_Mode mode,
1153 Ecore_X_Randr_Orientation orientation)
1156 RANDR_CHECK_1_2_RET(EINA_FALSE);
1157 XRRScreenResources *res = NULL;
1158 XRRCrtcInfo *crtc_info = NULL;
1159 Eina_Bool ret = EINA_FALSE;
1161 if (_ecore_x_randr_crtc_validate(root,
1163 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1165 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1167 if ((mode == Ecore_X_Randr_None) ||
1168 (noutputs == Ecore_X_Randr_None))
1173 else if (noutputs == (int)Ecore_X_Randr_Unset)
1175 outputs = (Ecore_X_Randr_Output *)crtc_info->outputs;
1176 noutputs = crtc_info->noutput;
1179 if (mode == Ecore_X_Randr_Unset)
1180 mode = crtc_info->mode;
1188 if (orientation == Ecore_X_Randr_Unset)
1189 orientation = crtc_info->rotation;
1191 if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime,
1192 x, y, mode, orientation, (RROutput *)outputs,
1196 XRRFreeCrtcInfo(crtc_info);
1199 XRRFreeScreenResources(res);
1209 * @brief Sets a CRTC relative to another one.
1211 * @param root The root window which's default display will be set.
1212 * @param crtc_r1 The CRTC to be positioned.
1213 * @param crtc_r2 The CRTC the position should be relative to.
1214 * @param policy The relation between the crtcs.
1215 * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
1217 * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
1218 * if repositioning failed or if position of new crtc would be out of given
1219 * screen's min/max bounds.
1222 ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root,
1223 Ecore_X_Randr_Crtc crtc_r1,
1224 Ecore_X_Randr_Crtc crtc_r2,
1225 Ecore_X_Randr_Output_Policy policy,
1226 Ecore_X_Randr_Relative_Alignment alignment)
1229 RANDR_CHECK_1_2_RET(EINA_FALSE);
1231 Eina_Rectangle r1_geo, r2_geo;
1232 int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n =
1233 Ecore_X_Randr_Unset;
1235 int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h;
1236 Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs;
1237 Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode;
1241 if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None)
1242 || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None))
1245 if (!_ecore_x_randr_crtc_validate(root, crtc_r1) ||
1246 (!(crtc_r1 != crtc_r2) &&
1247 !_ecore_x_randr_crtc_validate(root, crtc_r2)))
1250 ecore_x_randr_crtc_geometry_get(root,
1256 ecore_x_randr_crtc_geometry_get(root,
1262 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
1263 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
1267 case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
1268 //set r1 right of r2
1269 x_n = r2_geo.x + r2_geo.w;
1273 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1274 y_n = Ecore_X_Randr_Unset;
1277 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1279 ((int)(((double)r2_geo.h /
1280 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0)));
1283 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1284 y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0));
1289 case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
1291 x_n = r2_geo.x - r1_geo.w;
1295 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1296 y_n = Ecore_X_Randr_Unset;
1299 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1301 ((int)(((double)r2_geo.h /
1302 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0)));
1305 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1306 y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0)));
1311 case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
1313 y_n = r2_geo.y + r2_geo.h;
1317 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1318 x_n = Ecore_X_Randr_Unset;
1321 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1323 ((int)((((double)r2_geo.x +
1324 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1327 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1328 x_n = ((int)((double)cw / 2.0));
1333 case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
1334 y_n = r2_geo.y - r1_geo.h;
1339 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1340 x_n = Ecore_X_Randr_Unset;
1343 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1345 ((int)((((double)r2_geo.x +
1346 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1349 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1350 x_n = ((int)((double)cw / 2.0));
1355 case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
1356 return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y);
1358 /* entire cloning (including modesetting)
1359 //all outputs of crtc1 capable of crtc2's current mode?
1360 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1362 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1367 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1370 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1377 for (j = 0; j < r1_nmodes; j++)
1379 ecore_x_randr_mode_size_get(root,
1383 if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h))
1385 r1_mode = r1_modes[j];
1386 ++outputs_mode_found;
1395 if (outputs_mode_found <= i)
1397 //an output doesn't support the set mode, cancel!
1403 //CRTC 1's outputs support a mode of same geometry as CRTC 2.
1405 (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None,
1408 ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y));
1412 /* entire cloning on same CRTC
1413 //all outputs of crtc1 capable of crtc2's current mode?
1414 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1416 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1421 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1424 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1431 for (j = 0; j < r1_nmodes; j++)
1433 if (r1_modes[j] == r2_mode)
1435 ++outputs_mode_found;
1444 if (outputs_mode_found <= i)
1446 //an output doesn't support the set mode, cancel!
1451 //check whether crtc r2 can use all outputs of r1.
1453 ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2,
1461 for (i = 0; i < r1_noutputs; i++)
1463 for (j = 0; j < r2_noutputs; )
1465 if (r1_outputs[i] == r2_outputs[j])
1470 if (j == r2_noutputs)
1472 //didn't find the output!
1479 //apparently crtc2 supports all outputs of r1
1480 //TODO: check with the compatible list of outputs (property in RR1.3)
1482 malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs));
1483 for (i = 0; i < r1_noutputs; i++)
1485 r2_r1_outputs[i] = r1_outputs[i];
1488 for (; i < r2_noutputs; i++)
1490 r2_r1_outputs[i] = r2_outputs[i];
1494 ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs,
1495 (r1_noutputs + r1_noutputs), r2_mode);
1496 free (r2_r1_outputs);
1499 case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
1504 if ((x_n == r1_geo.x) && (y_n == r1_geo.x))
1507 //out of possible bounds?
1508 if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max))
1511 return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n);
1518 * @brief Add given mode to given output.
1520 * @param output The output the mode is added to.
1521 * @param mode The mode added to the output.
1522 * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
1524 * Additionally, if xcb backend is used, the success of the addition is
1525 * reported back directly.
1529 ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output,
1530 Ecore_X_Randr_Mode mode)
1533 RANDR_CHECK_1_2_RET(EINA_FALSE);
1535 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1538 XRRAddOutputMode(_ecore_x_disp, output, mode);
1546 * @brief delete given mode from given output
1547 * @param output the output the mode is removed from
1548 * @param mode the mode removed from the output
1552 ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output,
1553 Ecore_X_Randr_Mode mode)
1556 RANDR_CHECK_1_2_RET();
1558 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1561 XRRDeleteOutputMode(_ecore_x_disp, output, mode);
1567 EAPI Ecore_X_Randr_Mode *
1568 ecore_x_randr_output_modes_get(Ecore_X_Window root,
1569 Ecore_X_Randr_Output output,
1574 RANDR_CHECK_1_2_RET(NULL);
1575 XRRScreenResources *res = NULL;
1576 XRROutputInfo *output_info = NULL;
1577 Ecore_X_Randr_Mode *modes = NULL;
1579 if ((output != Ecore_X_Randr_None)
1580 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1582 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1584 if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode)))
1586 memcpy(modes, output_info->modes,
1587 (sizeof(Ecore_X_Randr_Mode) * output_info->nmode));
1589 *num = output_info->nmode;
1592 *npreferred = output_info->npreferred;
1597 XRRFreeOutputInfo(output_info);
1600 XRRFreeScreenResources(res);
1608 EAPI Ecore_X_Randr_Crtc *
1609 ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root,
1610 Ecore_X_Randr_Output output,
1614 RANDR_CHECK_1_2_RET(NULL);
1615 XRRScreenResources *res = NULL;
1616 XRROutputInfo *output_info = NULL;
1617 Ecore_X_Randr_Crtc *crtcs = NULL;
1619 if ((output != Ecore_X_Randr_None))
1621 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1623 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1625 if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)))
1627 memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc));
1628 if (num) *num = output_info->ncrtc;
1630 XRRFreeOutputInfo(output_info);
1632 XRRFreeScreenResources(res);
1637 return Ecore_X_Randr_None;
1642 * @brief gets the the outputs which might be used simultenously on the same
1644 * @param root window that this information should be queried for.
1645 * @param output the output which's clones we concern
1646 * @param num number of possible clones
1648 EAPI Ecore_X_Randr_Output *
1649 ecore_x_randr_output_clones_get(Ecore_X_Window root,
1650 Ecore_X_Randr_Output output,
1654 RANDR_CHECK_1_2_RET(NULL);
1655 XRRScreenResources *res = NULL;
1656 XRROutputInfo *output_info = NULL;
1657 Ecore_X_Randr_Output *outputs = NULL;
1659 if ((output != Ecore_X_Randr_None))
1661 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1663 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1665 if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone)))
1667 memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone));
1668 if (num) *num = output_info->nclone;
1670 XRRFreeOutputInfo(output_info);
1672 XRRFreeScreenResources(res);
1677 return Ecore_X_Randr_None;
1681 EAPI Ecore_X_Randr_Crtc
1682 ecore_x_randr_output_crtc_get(Ecore_X_Window root,
1683 Ecore_X_Randr_Output output)
1686 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1687 XRRScreenResources *res = NULL;
1688 XRROutputInfo *output_info = NULL;
1689 Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
1691 if ((output != Ecore_X_Randr_None))
1693 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1695 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1697 ret = output_info->crtc;
1698 XRRFreeOutputInfo(output_info);
1700 XRRFreeScreenResources(res);
1706 return Ecore_X_Randr_None;
1711 * @brief gets the given output's name as reported by X
1712 * @param root the window which's screen will be queried
1713 * @param output The output for which the name will be reported.
1714 * @param len length of returned c-string.
1715 * @return name of the output as reported by X
1718 ecore_x_randr_output_name_get(Ecore_X_Window root,
1719 Ecore_X_Randr_Output output,
1723 RANDR_CHECK_1_2_RET(NULL);
1724 XRRScreenResources *res = NULL;
1725 XRROutputInfo *output_info = NULL;
1728 if ((output != Ecore_X_Randr_None)
1729 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1730 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1733 * Actually the below command is correct, but due to a bug in libXrandr
1734 * it doesn't work. Therefore we stick with strlen().
1735 * Replace the line below with the following once this bug is
1736 * fixed within libXrandr.
1738 * *len = output_info->nameLen;
1741 if ((ret = strdup(output_info->name)) && len)
1744 XRRFreeOutputInfo(output_info);
1748 XRRFreeScreenResources(res);
1757 * @brief gets the width and hight of a given mode
1758 * @param mode the mode which's size is to be looked up
1759 * @param w width of given mode in px
1760 * @param h height of given mode in px
1763 ecore_x_randr_mode_size_get(Ecore_X_Window root,
1764 Ecore_X_Randr_Mode mode,
1769 RANDR_CHECK_1_2_RET();
1770 XRRScreenResources *res = NULL;
1773 if ((mode != Ecore_X_Randr_None)
1775 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1777 for (i = 0; i < res->nmode; i++)
1779 if (res->modes[i].id == mode)
1782 *w = res->modes[i].width;
1785 *h = res->modes[i].height;
1793 XRRFreeScreenResources(res);
1799 * @brief gets the EDID information of an attached output if available.
1800 * Note that this information is not to be compared using ordinary string
1801 * comparison functions, since it includes 0-bytes.
1802 * @param root window this information should be queried from
1803 * @param output the XID of the output
1804 * @param length length of the byte-array. If NULL, request will fail.
1806 EAPI unsigned char *
1807 ecore_x_randr_output_edid_get(Ecore_X_Window root,
1808 Ecore_X_Randr_Output output,
1809 unsigned long *length)
1812 RANDR_CHECK_1_2_RET(NULL);
1813 Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False);
1814 unsigned char *prop_data, *ret = NULL;
1816 unsigned long nitems, bytes_after;
1819 if (!length || !_ecore_x_randr_output_validate(root, output))
1822 if (XRRGetOutputProperty (_ecore_x_disp, output, name,
1823 0, 100, False, False,
1825 &actual_type, &actual_format,
1826 &nitems, &bytes_after, &prop_data) == Success)
1828 if (actual_type == XA_INTEGER && actual_format == 8)
1830 if ((ret = malloc(nitems * sizeof(unsigned char))))
1833 (memcpy(ret, prop_data, (nitems * sizeof(unsigned char)))))
1847 EAPI Ecore_X_Randr_Connection_Status
1848 ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
1849 Ecore_X_Randr_Output output)
1852 RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
1853 XRRScreenResources *res = NULL;
1854 XRROutputInfo *output_info = NULL;
1855 Ecore_X_Randr_Connection_Status ret =
1856 ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1858 if ((output != Ecore_X_Randr_None)
1859 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1860 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1862 ret = output_info->connection;
1866 XRRFreeOutputInfo(output_info);
1869 XRRFreeScreenResources(res);
1873 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1878 ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
1879 Ecore_X_Randr_Output output,
1884 RANDR_CHECK_1_2_RET();
1885 XRRScreenResources *res = NULL;
1886 XRROutputInfo *output_info = NULL;
1888 if ((output != Ecore_X_Randr_None)
1889 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1892 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1895 *w_mm = output_info->mm_width;
1898 *h_mm = output_info->mm_height;
1900 XRRFreeOutputInfo(output_info);
1903 XRRFreeScreenResources(res);
1910 ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root,
1911 const Ecore_X_Randr_Crtc *not_moved,
1917 Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL;
1918 XRRScreenResources *res = NULL;
1922 if ((nnot_moved <= 0) || (!not_moved)
1923 || !_ecore_x_randr_root_validate(root)
1925 _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
1928 n = (res->ncrtc - nnot_moved);
1929 if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n)))
1931 for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
1933 for (j = 0; j < nnot_moved; j++)
1935 if (res->crtcs[i] == not_moved[j])
1938 if (j == nnot_moved)
1939 //crtcs[i] is not in the 'not to move'-list
1940 crtcs_to_be_moved[k++] = res->crtcs[i];
1944 XRRFreeScreenResources(res);
1945 ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy);
1946 free(crtcs_to_be_moved);
1954 * @brief Move given CRTCs belonging to the given root window's screen dx/dy
1955 * pixels relative to their current position. The screen size will be
1956 * automatically adjusted if necessary and possible.
1958 * @param root Window which's screen's resources are used.
1959 * @param crtcs List of CRTCs to be moved.
1960 * @param ncrtc Number of CRTCs in array.
1961 * @param dx Amount of pixels the CRTCs should be moved in x direction.
1962 * @param dy Amount of pixels the CRTCs should be moved in y direction.
1963 * @return @c EINA_TRUE if all crtcs could be moved successfully.
1966 ecore_x_randr_move_crtcs(Ecore_X_Window root,
1967 const Ecore_X_Randr_Crtc *crtcs,
1973 RANDR_CHECK_1_2_RET(EINA_FALSE);
1974 XRRScreenResources *res = NULL;
1975 XRRCrtcInfo **crtc_info = NULL;
1976 Eina_Bool ret = EINA_TRUE;
1977 int i, cw, ch, w_max, h_max, nw, nh;
1979 crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc);
1980 memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc);
1981 if (_ecore_x_randr_root_validate(root)
1982 && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
1984 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
1985 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
1991 (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i]));
1994 if (((crtc_info[i]->x + dx) < 0) ||
1995 ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max)
1996 || ((crtc_info[i]->y + dy) < 0) ||
1997 ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max)
1999 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2001 nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw);
2002 nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh);
2006 //resize if necessary
2009 ecore_x_randr_screen_current_size_set(root, nw, nh,
2010 Ecore_X_Randr_Unset,
2011 Ecore_X_Randr_Unset)))
2012 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2014 //actually move all the crtcs, keep their rotation and mode.
2015 for (i = 0; (i < ncrtc) && crtc_info[i]; i++)
2017 if ((crtc_info[i]) &&
2018 (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL,
2019 Ecore_X_Randr_Unset,
2020 (crtc_info[i]->x + dx),
2021 (crtc_info[i]->y + dy),
2023 crtc_info[i]->rotation)))
2031 //something went wrong, let's try to move the already moved crtcs
2036 ecore_x_randr_crtc_settings_set(root,
2039 Ecore_X_Randr_Unset,
2040 (crtc_info[i]->x - dx),
2041 (crtc_info[i]->y - dy),
2043 crtc_info[i]->rotation);
2047 for (i = 0; i < ncrtc; i++)
2049 if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]);
2053 XRRFreeScreenResources(res);
2056 _ecore_x_randr_move_crtcs_fail_free_crtc_info:
2058 XRRFreeCrtcInfo(crtc_info[i]);
2059 XRRFreeScreenResources(res);
2067 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
2068 * and all other CRTCs dx,dy respectively.
2069 * @param root the window's screen which will be reset.
2072 ecore_x_randr_screen_reset(Ecore_X_Window root)
2075 XRRCrtcInfo *crtc_info = NULL;
2076 XRRScreenResources *res = NULL;
2077 //the 100000 are just a random huge number.
2078 int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0;
2080 if (!_ecore_x_randr_root_validate(root) ||
2081 !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
2084 Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc];
2086 for (i = 0; i < res->ncrtc; i++)
2089 XRRGetCrtcInfo(_ecore_x_disp, res,
2091 (crtc_info->mode == Ecore_X_Randr_None) ||
2092 (crtc_info->mode == Ecore_X_Randr_Unset)
2093 || ((crtc_info->noutput == 0)))
2096 enabled_crtcs[nenabled_crtcs++] = res->crtcs[i];
2098 if ((int)(crtc_info->x + crtc_info->width) > w_n)
2099 w_n = (crtc_info->x + crtc_info->width);
2101 if ((int)(crtc_info->y + crtc_info->height) > h_n)
2102 h_n = (crtc_info->y + crtc_info->height);
2104 if (crtc_info->x < dx_min)
2105 dx_min = crtc_info->x;
2106 if (crtc_info->y < dy_min)
2107 dy_min = crtc_info->y;
2109 XRRFreeCrtcInfo(crtc_info);
2111 if ((dx_min > 0) || (dy_min > 0))
2113 if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min))
2119 ecore_x_randr_screen_current_size_set(root,
2122 Ecore_X_Randr_Unset,
2123 Ecore_X_Randr_Unset);
2128 * @brief Set up the backlight level to the given level.
2130 * @param root The window's screen which will be set.
2131 * @param level Of the backlight between @c 0 and @c 1.
2135 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root,
2139 RANDR_CHECK_1_2_RET();
2141 XRRScreenResources *resources = NULL;
2142 Ecore_X_Randr_Output output;
2145 if ((level < 0) || (level > 1))
2147 ERR("Wrong value for the backlight level. It should be between 0 and 1.");
2152 * To make sure that the _backlight atomic property still exists.
2154 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2155 if (_backlight == None)
2157 WRN("Backlight setting is not supported on this server or driver");
2161 /* get the ressources */
2162 resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root);
2163 if (!resources) return;
2165 for (o = 0; o < resources->noutput; o++)
2167 output = resources->outputs[o];
2168 if (ecore_x_randr_output_backlight_level_get(root, output) >= 0)
2170 ecore_x_randr_output_backlight_level_set(root, output, level);
2173 XRRFreeScreenResources(resources);
2178 * @brief Check if a backlight is available.
2179 * @return Whether a backlight is available.
2183 ecore_x_randr_output_backlight_available(void)
2186 RANDR_CHECK_1_2_RET(-1);
2189 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2191 return (_backlight == None) ? EINA_FALSE : EINA_TRUE;
2198 * @brief Get the backlight level of the given output.
2200 * @param root Window which's screen should be queried.
2201 * @param output From which the backlight level should be retrieved.
2202 * @return The backlight level.
2206 ecore_x_randr_output_backlight_level_get(Ecore_X_Window root,
2207 Ecore_X_Randr_Output output)
2210 RANDR_CHECK_1_2_RET(-1);
2213 XRRPropertyInfo *info = NULL;
2216 long value, max, min;
2217 unsigned long nitems;
2218 unsigned long bytes_after;
2219 unsigned char *prop = NULL;
2221 /* set backlight variable if not already done */
2223 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2224 if (_backlight == None)
2226 ERR("Backlight property is not suppported on this server or driver");
2230 if (!_ecore_x_randr_output_validate(root, output))
2232 ERR("Invalid output");
2236 if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight,
2237 0, 4, False, False, None,
2238 &actual_type, &actual_format,
2239 &nitems, &bytes_after, &prop) != Success)
2241 WRN("Backlight not supported on this output");
2245 if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1;
2247 value = *((long *)prop);
2250 /* I have the current value of the backlight */
2251 /* Now retrieve the min and max intensities of the output */
2252 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2256 if ((info->range) && (info->num_values == 2))
2258 /* finally convert the current value in the interval [0..1] */
2259 min = info->values[0];
2260 max = info->values[1];
2261 dvalue = ((double)(value - min)) / ((double)(max - min));
2271 * @brief Set the backlight level of a given output.
2273 * @param root Window which's screen should be queried.
2274 * @param output That should be set.
2275 * @param level For which the backlight should be set.
2276 * @return @c EINA_TRUE in case of success.
2280 ecore_x_randr_output_backlight_level_set(Ecore_X_Window root,
2281 Ecore_X_Randr_Output output,
2285 RANDR_CHECK_1_2_RET(EINA_FALSE);
2287 XRRPropertyInfo *info = NULL;
2288 double min, max, tmp;
2291 if ((level < 0) || (level > 1))
2293 ERR("Backlight level should be between 0 and 1");
2297 if (!_ecore_x_randr_output_validate(root, output))
2299 ERR("Wrong output value");
2303 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2304 if (_backlight == None)
2306 WRN("Backlight property is not suppported on this server or driver");
2310 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2313 if ((info->range) && (info->num_values == 2))
2315 min = info->values[0];
2316 max = info->values[1];
2317 tmp = (level * (max - min)) + min;
2319 if (new > max) new = max;
2320 if (new < min) new = min;
2321 XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32,
2322 PropModeReplace, (unsigned char *)&new, 1);
2323 XFlush(_ecore_x_disp);
2333 * @brief Get the outputs, which display a certain window.
2335 * @param window Window the displaying outputs shall be found for
2336 * @param num The number of outputs displaying the window
2337 * @return Array of outputs that display a certain window. @c NULL if no
2338 * outputs was found that displays the specified window.
2341 EAPI Ecore_X_Randr_Output *
2342 ecore_x_randr_window_outputs_get(Ecore_X_Window window,
2346 Ecore_X_Window root;
2347 Ecore_X_Randr_Crtc *crtcs;
2348 Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
2349 int ncrtcs, noutputs, i, nret = 0;
2351 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
2353 root = ecore_x_window_root_get(window);
2354 if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
2355 goto _ecore_x_randr_current_output_get_fail;
2357 for (i = 0, nret = 0; i < ncrtcs; i++)
2360 outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
2363 goto _ecore_x_randr_current_output_get_fail_free;
2364 tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output)));
2365 if (!tret) goto _ecore_x_randr_current_output_get_fail_free;
2367 memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
2379 _ecore_x_randr_current_output_get_fail_free:
2383 _ecore_x_randr_current_output_get_fail:
2390 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
2391 * @brief Get the outputs, which display a certain window.
2393 * @param window Window the displaying outputs shall be found for.
2394 * @param num The number of outputs displaying the window.
2395 * @return Array of outputs that display a certain window. @c NULL if no
2396 * outputs was found that displays the specified window.
2399 EAPI Ecore_X_Randr_Output *
2400 ecore_x_randr_current_output_get(Ecore_X_Window window,
2403 return ecore_x_randr_window_outputs_get(window, num);