2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
21 # define alloca __builtin_alloca
23 # define alloca __alloca
24 # elif defined _MSC_VER
26 # define alloca _alloca
27 # elif !defined HAVE_ALLOCA
31 void *alloca (size_t);
35 #include "ecore_x_private.h"
36 #include "ecore_x_randr.h"
42 #define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0
43 #define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1
47 #define RANDR_1_2 ((1 << 16) | 2)
49 #define RANDR_VALIDATE_ROOT(screen, root) \
50 ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1)
52 #define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \
55 #define RANDR_PROPERTY_EDID "EDID"
56 #define RANDR_PROPERTY_BACKLIGHT "Backlight"
57 #define RANDR_PROPERTY_SIGNAL_FORMAT "SignalFormat"
58 #define RANDR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties"
59 #define RANDR_PROPERTY_CONNECTOR_TYPE "ConnectorType"
60 #define RANDR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber"
61 #define RANDR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList"
62 #define RANDR_PROPERTY_CLONE_LIST "CloneList"
64 extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
68 extern int _randr_version;
72 * @brief Enable event selection. This enables basic interaction with
73 * output/crtc events and requires RandR >= 1.2.
75 * @param win Select this window's properties for RandR events.
76 * @param on Enable/disable selecting.
79 ecore_x_randr_events_select(Ecore_X_Window win,
85 LOGFN(__FILE__, __LINE__, __FUNCTION__);
90 mask = RRScreenChangeNotifyMask;
91 if (_randr_version >= RANDR_1_2)
92 mask |= (RRCrtcChangeNotifyMask |
93 RROutputChangeNotifyMask |
94 RROutputPropertyNotifyMask);
97 XRRSelectInput(_ecore_x_disp, win, mask);
102 * @brief Validates a CRTC for a given root window's screen.
104 * @param root The window which's default display will be queried.
105 * @param crtc The CRTC to be validated.
106 * @return In case it is found, @c EINA_TRUE will be returned, @c EINA_FALSE
109 static inline Eina_Bool
110 _ecore_x_randr_crtc_validate(Ecore_X_Window root,
111 Ecore_X_Randr_Crtc crtc)
114 RANDR_CHECK_1_2_RET(EINA_FALSE);
116 XRRScreenResources *res = NULL;
118 Eina_Bool ret = EINA_FALSE;
120 if ((crtc == Ecore_X_Randr_None) ||
121 (crtc == Ecore_X_Randr_Unset))
124 if (_ecore_x_randr_root_validate(root) && crtc &&
125 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
127 for (i = 0; i < res->ncrtc; i++)
129 if (res->crtcs[i] == crtc)
135 XRRFreeScreenResources(res);
145 _ecore_x_randr_output_validate(Ecore_X_Window root,
146 Ecore_X_Randr_Output output)
149 RANDR_CHECK_1_2_RET(EINA_FALSE);
151 Eina_Bool ret = EINA_FALSE;
152 XRRScreenResources *res = NULL;
155 if (_ecore_x_randr_root_validate(root) && output &&
156 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
158 for (i = 0; i < res->noutput; i++)
160 if (res->outputs[i] == output)
166 XRRFreeScreenResources(res);
175 static inline Eina_Bool
176 _ecore_x_randr_mode_validate(Ecore_X_Window root,
177 Ecore_X_Randr_Mode mode)
180 RANDR_CHECK_1_2_RET(EINA_FALSE);
182 Eina_Bool ret = EINA_FALSE;
183 XRRScreenResources *res = NULL;
186 if (_ecore_x_randr_root_validate(root) && mode &&
187 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
189 for (i = 0; i < res->nmode; i++)
191 if (res->modes[i].id == mode)
197 XRRFreeScreenResources(res);
207 * @param w width of screen in px
208 * @param h height of screen in px
211 ecore_x_randr_screen_current_size_get(Ecore_X_Window root,
218 RANDR_CHECK_1_2_RET();
219 Ecore_X_Randr_Screen scr;
221 if (!RANDR_VALIDATE_ROOT(scr, root))
225 *w = DisplayWidth(_ecore_x_disp, scr);
228 *h = DisplayHeight(_ecore_x_disp, scr);
231 *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
234 *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
240 * @param root window which's screen will be queried
241 * @param wmin minimum width the screen can be set to
242 * @param hmin minimum height the screen can be set to
243 * @param wmax maximum width the screen can be set to
244 * @param hmax maximum height the screen can be set to
247 ecore_x_randr_screen_size_range_get(Ecore_X_Window root,
254 RANDR_CHECK_1_2_RET();
255 int twmin, thmin, twmax, thmax;
256 if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax,
276 * @param root Window which's screen's size should be set. If invalid (e.g.
277 * @c NULL) no action is taken.
278 * @param w Width in px the screen should be set to. If out of valid
279 * boundaries, current value is assumed.
280 * @param h Height in px the screen should be set to. If out of valid
281 * boundaries, current value is assumed.
282 * @param w_mm Width in mm the screen should be set to. If @c 0, current
284 * @param h_mm Height in mm the screen should be set to. If @c 0, current
286 * @return @c EINA_TRUE if request was successfully sent or screen is already
287 * in requested size, @c EINA_FALSE if parameters are invalid.
290 ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
297 RANDR_CHECK_1_2_RET(EINA_FALSE);
299 Ecore_X_Randr_Screen scr;
300 int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax;
302 if (!RANDR_VALIDATE_ROOT(scr, root))
305 ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c);
306 if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm))
309 ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax);
311 if (((w != Ecore_X_Randr_None) &&
314 ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax))))
318 w = DisplayWidth(_ecore_x_disp, scr);
321 h = DisplayHeight(_ecore_x_disp, scr);
325 (int)(((double)(DisplayWidthMM(_ecore_x_disp,
327 (double)DisplayWidth(_ecore_x_disp,
332 (int)(((double)(DisplayHeightMM(_ecore_x_disp,
334 (double)DisplayHeight(_ecore_x_disp,
337 XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm);
345 * @brief get detailed information for all modes related to a root window's screen
346 * @param root window which's screen's ressources are queried
347 * @param num number of modes returned
348 * @return modes' information
350 EAPI Ecore_X_Randr_Mode_Info **
351 ecore_x_randr_modes_info_get(Ecore_X_Window root,
355 RANDR_CHECK_1_2_RET(NULL);
356 XRRScreenResources *res = NULL;
357 Ecore_X_Randr_Mode_Info **ret = NULL;
360 if (_ecore_x_randr_root_validate(root) &&
361 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
364 (Ecore_X_Randr_Mode_Info **)malloc(sizeof(
365 Ecore_X_Randr_Mode_Info *)
369 for (i = 0; i < res->nmode; i++)
371 if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
373 ret[i]->xid = res->modes[i].id;
374 ret[i]->width = res->modes[i].width;
375 ret[i]->height = res->modes[i].height;
376 ret[i]->dotClock = res->modes[i].dotClock;
377 ret[i]->hSyncStart = res->modes[i].hSyncStart;
378 ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
379 ret[i]->hTotal = res->modes[i].hTotal;
380 ret[i]->hSkew = res->modes[i].hSkew;
381 ret[i]->vSyncStart = res->modes[i].vSyncStart;
382 ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
383 ret[i]->vTotal = res->modes[i].vTotal;
384 if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1))))
385 strncpy(ret[i]->name, res->modes[i].name,
386 (res->modes[i].nameLength + 1));
390 ret[i]->nameLength = res->modes[i].nameLength;
391 ret[i]->modeFlags = res->modes[i].modeFlags;
407 XRRFreeScreenResources(res);
417 * @brief Add a mode to a display.
419 * @param root Window to which's screen's ressources are added.
421 * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
425 EAPI Ecore_X_Randr_Mode
426 ecore_x_randr_mode_info_add(Ecore_X_Window root,
427 Ecore_X_Randr_Mode_Info *mode_info)
430 RANDR_CHECK_1_2_RET(EINA_FALSE);
431 Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
433 if (_ecore_x_randr_root_validate(root) && mode_info)
434 mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info);
438 return Ecore_X_Randr_None;
443 * @brief Delete a mode from the display.
449 ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode)
452 RANDR_CHECK_1_2_RET();
454 XRRDestroyMode(_ecore_x_disp, mode);
461 * @brief get detailed information for a given mode id
462 * @param root window which's screen's ressources are queried
463 * @param mode the XID which identifies the mode of interest
464 * @return mode's detailed information
466 EAPI Ecore_X_Randr_Mode_Info *
467 ecore_x_randr_mode_info_get(Ecore_X_Window root,
468 Ecore_X_Randr_Mode mode)
471 RANDR_CHECK_1_2_RET(NULL);
472 XRRScreenResources *res = NULL;
473 Ecore_X_Randr_Mode_Info *ret = NULL;
476 if (_ecore_x_randr_root_validate(root) &&
477 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
479 for (i = 0; i < res->nmode; i++)
481 if ((res->modes[i].id == mode) &&
482 (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
484 ret->xid = res->modes[i].id;
485 ret->width = res->modes[i].width;
486 ret->height = res->modes[i].height;
487 ret->dotClock = res->modes[i].dotClock;
488 ret->hSyncStart = res->modes[i].hSyncStart;
489 ret->hSyncEnd = res->modes[i].hSyncEnd;
490 ret->hTotal = res->modes[i].hTotal;
491 ret->hSkew = res->modes[i].hSkew;
492 ret->vSyncStart = res->modes[i].vSyncStart;
493 ret->vSyncEnd = res->modes[i].vSyncEnd;
494 ret->vTotal = res->modes[i].vTotal;
497 if (res->modes[i].nameLength > 0)
499 ret->nameLength = res->modes[i].nameLength;
500 ret->name = malloc(res->modes[i].nameLength + 1);
502 memcpy(ret->name, res->modes[i].name,
503 res->modes[i].nameLength + 1);
505 ret->modeFlags = res->modes[i].modeFlags;
509 XRRFreeScreenResources(res);
519 * @brief Free detailed mode information. The pointer handed in will be set to
520 * @c NULL after freeing the memory.
522 * @param mode_info The mode information that should be freed.
525 ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
528 RANDR_CHECK_1_2_RET();
533 free(mode_info->name);
541 * @brief Get all known CRTCs related to a root window's screen.
543 * @param root Window which's screen's ressources are queried.
544 * @param num Number of CRTCs returned.
547 EAPI Ecore_X_Randr_Crtc *
548 ecore_x_randr_crtcs_get(Ecore_X_Window root,
552 RANDR_CHECK_1_2_RET(NULL);
553 XRRScreenResources *res = NULL;
554 Ecore_X_Randr_Crtc *ret = NULL;
557 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
559 if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)))
563 if (num) *num = res->ncrtc;
565 for (i = 0; i < res->ncrtc; i++)
566 ret[i] = res->crtcs[i];
569 XRRFreeScreenResources(res);
579 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
580 * @brief get the CRTCs, which display a certain window
581 * @param window window the displaying crtcs shall be found for
582 * @param num the number of crtcs displaying the window
583 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
584 * was found that displays the specified window.
586 EAPI Ecore_X_Randr_Crtc *
587 ecore_x_randr_current_crtc_get(Ecore_X_Window window,
590 return ecore_x_randr_window_crtcs_get(window, num);
594 * @brief get the CRTCs, which display a certain window
595 * @param window window the displaying crtcs shall be found for
596 * @param num the number of crtcs displaying the window
597 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
598 * was found that displays the specified window.
601 EAPI Ecore_X_Randr_Crtc *
602 ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
607 Eina_Rectangle w_geo, c_geo;
608 Ecore_X_Randr_Crtc *crtcs;
609 Ecore_X_Randr_Mode mode;
610 Ecore_X_Randr_Output *ret = NULL;
612 int ncrtcs, i, nret = 0, rx = 0, ry = 0;
614 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail;
616 ecore_x_window_geometry_get(window,
620 root = ecore_x_window_root_get(window);
621 crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs);
622 if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail;
624 /* now get window RELATIVE to root window - thats what matters. */
625 XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw);
629 ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc));
633 goto _ecore_x_randr_window_crtcs_get_fail;
635 for (i = 0, nret = 0; i < ncrtcs; i++)
637 /* if crtc is not enabled, don't bother about it any further */
638 mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
639 if (mode == Ecore_X_Randr_None) continue;
641 ecore_x_randr_crtc_geometry_get(root, crtcs[i],
644 if (eina_rectangles_intersect(&w_geo, &c_geo))
646 ret[nret] = crtcs[i];
652 if (num) *num = nret;
655 _ecore_x_randr_window_crtcs_get_fail:
661 EAPI Ecore_X_Randr_Output *
662 ecore_x_randr_outputs_get(Ecore_X_Window root,
666 RANDR_CHECK_1_2_RET(NULL);
667 XRRScreenResources *res = NULL;
668 Ecore_X_Randr_Output *ret = NULL;
671 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
673 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput)))
677 if (num) *num = res->noutput;
679 for (i = 0; i < res->noutput; i++)
680 ret[i] = res->outputs[i];
684 XRRFreeScreenResources(res);
695 * @brief get a CRTC's outputs.
696 * @param root the root window which's screen will be queried
697 * @param num number of outputs referenced by given CRTC
699 EAPI Ecore_X_Randr_Output *
700 ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
701 Ecore_X_Randr_Crtc crtc,
705 RANDR_CHECK_1_2_RET(NULL);
706 XRRScreenResources *res = NULL;
707 Ecore_X_Randr_Output *ret = NULL;
708 XRRCrtcInfo *crtc_info = NULL;
710 if (_ecore_x_randr_crtc_validate(root, crtc) &&
712 _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) &&
713 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
715 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)))
719 if (num) *num = crtc_info->noutput;
721 for (i = 0; i < crtc_info->noutput; i++)
722 ret[i] = crtc_info->outputs[i];
726 XRRFreeCrtcInfo(crtc_info);
729 XRRFreeScreenResources(res);
739 * @brief get a CRTC's possible outputs.
740 * @param root the root window which's screen will be queried
741 * @param num number of possible outputs referenced by given CRTC
743 EAPI Ecore_X_Randr_Output *
744 ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root,
745 Ecore_X_Randr_Crtc crtc,
749 RANDR_CHECK_1_2_RET(NULL);
750 XRRScreenResources *res = NULL;
751 Ecore_X_Randr_Output *ret = NULL;
752 XRRCrtcInfo *crtc_info = NULL;
754 if (_ecore_x_randr_crtc_validate(root, crtc) &&
755 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
757 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
760 malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)))
764 if (num) *num = crtc_info->npossible;
766 for (i = 0; i < crtc_info->npossible; i++)
767 ret[i] = crtc_info->possible[i];
770 XRRFreeCrtcInfo(crtc_info);
773 XRRFreeScreenResources(res);
783 ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
784 Ecore_X_Randr_Crtc crtc,
791 RANDR_CHECK_1_2_RET();
792 XRRScreenResources *res = NULL;
793 XRRCrtcInfo *crtc_info = NULL;
795 if (_ecore_x_randr_crtc_validate(root,
798 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
800 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
809 *w = crtc_info->width;
812 *h = crtc_info->height;
814 XRRFreeCrtcInfo(crtc_info);
815 XRRFreeScreenResources(res);
822 * @brief Sets the position of given CRTC within root window's screen.
824 * @param root The window's screen to be queried.
825 * @param crtc The CRTC which's position within the mentioned screen is to be
827 * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
828 * value will be kept.
829 * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
830 * value will be kept.
831 * @return @c EINA_TRUE if position could successfully be altered.
834 ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
835 Ecore_X_Randr_Crtc crtc,
840 RANDR_CHECK_1_2_RET(EINA_FALSE);
841 int w_c, h_c, w_new = 0, h_new = 0;
842 Eina_Rectangle crtc_geo;
844 ecore_x_randr_crtc_geometry_get(root,
850 ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL);
857 if ((x + crtc_geo.w) > w_c)
858 w_new = x + crtc_geo.w;
860 if ((y + crtc_geo.h) > h_c)
861 h_new = y + crtc_geo.h;
863 if ((w_new != 0) || (h_new != 0))
864 if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0))
867 return ecore_x_randr_crtc_settings_set(root,
874 Ecore_X_Randr_Unset);
881 * @brief Get the current set mode of a given CRTC
882 * @param root the window's screen to be queried
883 * @param crtc the CRTC which's should be queried
884 * @return currently set mode or - in case parameters are invalid -
885 * Ecore_X_Randr_Unset
887 EAPI Ecore_X_Randr_Mode
888 ecore_x_randr_crtc_mode_get(Ecore_X_Window root,
889 Ecore_X_Randr_Crtc crtc)
892 RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
893 XRRScreenResources *res = NULL;
894 XRRCrtcInfo *crtc_info = NULL;
895 Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
896 if (_ecore_x_randr_root_validate(root) &&
897 _ecore_x_randr_crtc_validate(root,
900 _ecore_x_randr_get_screen_resources(_ecore_x_disp,
902 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
904 ret = crtc_info->mode;
905 XRRFreeCrtcInfo(crtc_info);
906 XRRFreeScreenResources(res);
911 return Ecore_X_Randr_Unset;
916 * @brief Sets a mode for a CRTC and the outputs attached to it.
918 * @param root The window's screen to be queried.
919 * @param crtc The CRTC which shall be set.
920 * @param outputs Array of outputs which have to be compatible with the mode.
921 * If @c NULL, CRTC will be disabled.
922 * @param noutputs Number of outputs in array to be used. Use
923 * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
924 * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
925 * disabled. If set to @c -1 the call will fail.
926 * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
930 ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
931 Ecore_X_Randr_Crtc crtc,
932 Ecore_X_Randr_Output *outputs,
934 Ecore_X_Randr_Mode mode)
937 RANDR_CHECK_1_2_RET(EINA_FALSE);
939 if (mode == Ecore_X_Randr_Unset)
942 return ecore_x_randr_crtc_settings_set(root,
949 Ecore_X_Randr_Unset);
956 ecore_x_randr_crtc_size_get(Ecore_X_Window root,
957 Ecore_X_Randr_Crtc crtc,
962 RANDR_CHECK_1_2_RET();
963 ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
967 EAPI Ecore_X_Randr_Refresh_Rate
968 ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
969 Ecore_X_Randr_Crtc crtc,
970 Ecore_X_Randr_Mode mode)
973 RANDR_CHECK_1_2_RET(0.0);
974 XRRScreenResources *res = NULL;
975 XRRCrtcInfo *crtc_info = NULL;
976 Ecore_X_Randr_Refresh_Rate ret = 0.0;
979 if (_ecore_x_randr_crtc_validate(root,
981 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
983 for (i = 0; i < res->nmode; i++)
984 if (res->modes[i].id == mode)
986 if (res->modes[i].hTotal && res->modes[i].vTotal)
987 ret = ((double)res->modes[i].dotClock /
988 ((double)res->modes[i].hTotal *
989 (double)res->modes[i].vTotal));
996 XRRFreeCrtcInfo(crtc_info);
999 XRRFreeScreenResources(res);
1007 EAPI Ecore_X_Randr_Orientation
1008 ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
1009 Ecore_X_Randr_Crtc crtc)
1012 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1013 XRRCrtcInfo *crtc_info = NULL;
1014 XRRScreenResources *res = NULL;
1015 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
1017 if (_ecore_x_randr_crtc_validate(root,
1020 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1022 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1024 ret = crtc_info->rotations;
1027 XRRFreeCrtcInfo(crtc_info);
1030 XRRFreeScreenResources(res);
1034 return Ecore_X_Randr_None;
1038 EAPI Ecore_X_Randr_Orientation
1039 ecore_x_randr_crtc_orientation_get(Ecore_X_Window root,
1040 Ecore_X_Randr_Crtc crtc)
1043 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1044 XRRCrtcInfo *crtc_info = NULL;
1045 XRRScreenResources *res = NULL;
1046 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
1048 if (_ecore_x_randr_crtc_validate(root,
1051 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1053 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1055 ret = crtc_info->rotation;
1058 XRRFreeCrtcInfo(crtc_info);
1061 XRRFreeScreenResources(res);
1065 return Ecore_X_Randr_None;
1070 ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
1071 Ecore_X_Randr_Crtc crtc,
1072 Ecore_X_Randr_Orientation orientation)
1075 RANDR_CHECK_1_2_RET(EINA_FALSE);
1076 Eina_Bool ret = EINA_FALSE;
1078 if (orientation != Ecore_X_Randr_None)
1080 ret = ecore_x_randr_crtc_settings_set(root,
1083 Ecore_X_Randr_Unset,
1084 Ecore_X_Randr_Unset,
1085 Ecore_X_Randr_Unset,
1086 Ecore_X_Randr_Unset,
1097 ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
1098 Ecore_X_Randr_Crtc crtc,
1103 RANDR_CHECK_1_2_RET();
1105 ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
1110 ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
1111 Ecore_X_Randr_Crtc original,
1112 Ecore_X_Randr_Crtc clon)
1115 RANDR_CHECK_1_2_RET(EINA_FALSE);
1117 XRRScreenResources *res = NULL;
1118 XRRCrtcInfo *clone_crtc_info = NULL;
1119 Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None;
1120 Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None;
1121 Eina_Bool ret = EINA_FALSE;
1124 if (_ecore_x_randr_root_validate(root) &&
1125 _ecore_x_randr_crtc_validate(root,
1127 _ecore_x_randr_crtc_validate(root,
1130 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1132 (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon)))
1134 ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL);
1135 original_mode = ecore_x_randr_crtc_mode_get(root, original);
1136 original_orientation = ecore_x_randr_crtc_orientation_get(root,
1138 ret = ecore_x_randr_crtc_settings_set(root,
1141 Ecore_X_Randr_Unset,
1145 original_orientation);
1146 XRRFreeCrtcInfo(clone_crtc_info);
1147 XRRFreeScreenResources(res);
1157 * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
1158 * auto enabled in it's preferred mode, when it was disabled before.
1160 * @param root The root window which's default display will be queried.
1161 * @param crtc The CRTC which's configuration should be altered.
1162 * @param outputs An array of outputs, that should display this CRTC's content.
1163 * @param noutputs Number of outputs in the array of outputs. If set to
1164 * Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
1165 * If set to Ecore_X_Randr_None, CRTC will be disabled.
1166 * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
1167 * corrdinate will be assumed.
1168 * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
1169 * corrdinate will be assumed.
1170 * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
1171 * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
1173 * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
1174 * used, the current mode is assumed.
1175 * @return @c EINA_TRUE if the configuration alteration was successful,
1176 * @c EINA_FALSE otherwise.
1179 ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
1180 Ecore_X_Randr_Crtc crtc,
1181 Ecore_X_Randr_Output *outputs,
1185 Ecore_X_Randr_Mode mode,
1186 Ecore_X_Randr_Orientation orientation)
1189 RANDR_CHECK_1_2_RET(EINA_FALSE);
1190 XRRScreenResources *res = NULL;
1191 XRRCrtcInfo *crtc_info = NULL;
1192 Eina_Bool ret = EINA_FALSE;
1194 if (_ecore_x_randr_crtc_validate(root,
1196 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1198 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1200 if ((mode == Ecore_X_Randr_None) ||
1201 (noutputs == Ecore_X_Randr_None))
1206 else if (noutputs == (int)Ecore_X_Randr_Unset)
1208 outputs = (Ecore_X_Randr_Output *)crtc_info->outputs;
1209 noutputs = crtc_info->noutput;
1212 if (mode == Ecore_X_Randr_Unset)
1213 mode = crtc_info->mode;
1221 if (orientation == Ecore_X_Randr_Unset)
1222 orientation = crtc_info->rotation;
1224 if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime,
1225 x, y, mode, orientation, (RROutput *)outputs,
1229 XRRFreeCrtcInfo(crtc_info);
1232 XRRFreeScreenResources(res);
1242 * @brief Sets a CRTC relative to another one.
1244 * @param root The root window which's default display will be set.
1245 * @param crtc_r1 The CRTC to be positioned.
1246 * @param crtc_r2 The CRTC the position should be relative to.
1247 * @param policy The relation between the crtcs.
1248 * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
1250 * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
1251 * if repositioning failed or if position of new crtc would be out of given
1252 * screen's min/max bounds.
1255 ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root,
1256 Ecore_X_Randr_Crtc crtc_r1,
1257 Ecore_X_Randr_Crtc crtc_r2,
1258 Ecore_X_Randr_Output_Policy policy,
1259 Ecore_X_Randr_Relative_Alignment alignment)
1262 RANDR_CHECK_1_2_RET(EINA_FALSE);
1264 Eina_Rectangle r1_geo, r2_geo;
1265 int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n =
1266 Ecore_X_Randr_Unset;
1268 int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h;
1269 Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs;
1270 Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode;
1274 if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None)
1275 || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None))
1278 if (!_ecore_x_randr_crtc_validate(root, crtc_r1) ||
1279 (!(crtc_r1 != crtc_r2) &&
1280 !_ecore_x_randr_crtc_validate(root, crtc_r2)))
1283 ecore_x_randr_crtc_geometry_get(root,
1289 ecore_x_randr_crtc_geometry_get(root,
1295 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
1296 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
1300 case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
1301 //set r1 right of r2
1302 x_n = r2_geo.x + r2_geo.w;
1306 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1307 y_n = Ecore_X_Randr_Unset;
1310 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1312 ((int)(((double)r2_geo.h /
1313 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0)));
1316 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1317 y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0));
1322 case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
1324 x_n = r2_geo.x - r1_geo.w;
1328 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1329 y_n = Ecore_X_Randr_Unset;
1332 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1334 ((int)(((double)r2_geo.h /
1335 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0)));
1338 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1339 y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0)));
1344 case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
1346 y_n = r2_geo.y + r2_geo.h;
1350 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1351 x_n = Ecore_X_Randr_Unset;
1354 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1356 ((int)((((double)r2_geo.x +
1357 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1360 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1361 x_n = ((int)((double)cw / 2.0));
1366 case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
1367 y_n = r2_geo.y - r1_geo.h;
1372 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1373 x_n = Ecore_X_Randr_Unset;
1376 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1378 ((int)((((double)r2_geo.x +
1379 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1382 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1383 x_n = ((int)((double)cw / 2.0));
1388 case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
1389 return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y);
1391 /* entire cloning (including modesetting)
1392 //all outputs of crtc1 capable of crtc2's current mode?
1393 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1395 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1400 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1403 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1410 for (j = 0; j < r1_nmodes; j++)
1412 ecore_x_randr_mode_size_get(root,
1416 if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h))
1418 r1_mode = r1_modes[j];
1419 ++outputs_mode_found;
1428 if (outputs_mode_found <= i)
1430 //an output doesn't support the set mode, cancel!
1436 //CRTC 1's outputs support a mode of same geometry as CRTC 2.
1438 (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None,
1441 ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y));
1445 /* entire cloning on same CRTC
1446 //all outputs of crtc1 capable of crtc2's current mode?
1447 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1449 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1454 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1457 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1464 for (j = 0; j < r1_nmodes; j++)
1466 if (r1_modes[j] == r2_mode)
1468 ++outputs_mode_found;
1477 if (outputs_mode_found <= i)
1479 //an output doesn't support the set mode, cancel!
1484 //check whether crtc r2 can use all outputs of r1.
1486 ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2,
1494 for (i = 0; i < r1_noutputs; i++)
1496 for (j = 0; j < r2_noutputs; )
1498 if (r1_outputs[i] == r2_outputs[j])
1503 if (j == r2_noutputs)
1505 //didn't find the output!
1512 //apparently crtc2 supports all outputs of r1
1513 //TODO: check with the compatible list of outputs (property in RR1.3)
1515 malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs));
1516 for (i = 0; i < r1_noutputs; i++)
1518 r2_r1_outputs[i] = r1_outputs[i];
1521 for (; i < r2_noutputs; i++)
1523 r2_r1_outputs[i] = r2_outputs[i];
1527 ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs,
1528 (r1_noutputs + r1_noutputs), r2_mode);
1529 free (r2_r1_outputs);
1532 case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
1537 if ((x_n == r1_geo.x) && (y_n == r1_geo.x))
1540 //out of possible bounds?
1541 if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max))
1544 return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n);
1551 * @brief Add given mode to given output.
1553 * @param output The output the mode is added to.
1554 * @param mode The mode added to the output.
1555 * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
1557 * Additionally, if xcb backend is used, the success of the addition is
1558 * reported back directly.
1562 ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output,
1563 Ecore_X_Randr_Mode mode)
1566 RANDR_CHECK_1_2_RET(EINA_FALSE);
1568 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1571 XRRAddOutputMode(_ecore_x_disp, output, mode);
1579 * @brief delete given mode from given output
1580 * @param output the output the mode is removed from
1581 * @param mode the mode removed from the output
1585 ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output,
1586 Ecore_X_Randr_Mode mode)
1589 RANDR_CHECK_1_2_RET();
1591 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1594 XRRDeleteOutputMode(_ecore_x_disp, output, mode);
1600 EAPI Ecore_X_Randr_Mode *
1601 ecore_x_randr_output_modes_get(Ecore_X_Window root,
1602 Ecore_X_Randr_Output output,
1607 RANDR_CHECK_1_2_RET(NULL);
1608 XRRScreenResources *res = NULL;
1609 XRROutputInfo *output_info = NULL;
1610 Ecore_X_Randr_Mode *modes = NULL;
1612 if ((output != Ecore_X_Randr_None)
1613 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1615 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1617 if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode)))
1621 if (num) *num = output_info->nmode;
1622 if (npreferred) *npreferred = output_info->npreferred;
1624 for (i = 0; i < output_info->nmode; i++)
1625 modes[i] = output_info->modes[i];
1630 XRRFreeOutputInfo(output_info);
1633 XRRFreeScreenResources(res);
1641 EAPI Ecore_X_Randr_Crtc *
1642 ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root,
1643 Ecore_X_Randr_Output output,
1647 RANDR_CHECK_1_2_RET(NULL);
1648 XRRScreenResources *res = NULL;
1649 XRROutputInfo *output_info = NULL;
1650 Ecore_X_Randr_Crtc *crtcs = NULL;
1652 if ((output != Ecore_X_Randr_None))
1654 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1656 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1658 if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)))
1660 memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc));
1661 if (num) *num = output_info->ncrtc;
1663 XRRFreeOutputInfo(output_info);
1665 XRRFreeScreenResources(res);
1670 return Ecore_X_Randr_None;
1675 * @brief gets the the outputs which might be used simultenously on the same
1677 * @param root window that this information should be queried for.
1678 * @param output the output which's clones we concern
1679 * @param num number of possible clones
1681 EAPI Ecore_X_Randr_Output *
1682 ecore_x_randr_output_clones_get(Ecore_X_Window root,
1683 Ecore_X_Randr_Output output,
1687 RANDR_CHECK_1_2_RET(NULL);
1688 XRRScreenResources *res = NULL;
1689 XRROutputInfo *output_info = NULL;
1690 Ecore_X_Randr_Output *outputs = NULL;
1692 if ((output != Ecore_X_Randr_None))
1694 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1696 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1698 if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone)))
1700 memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone));
1701 if (num) *num = output_info->nclone;
1703 XRRFreeOutputInfo(output_info);
1705 XRRFreeScreenResources(res);
1710 return Ecore_X_Randr_None;
1714 EAPI Ecore_X_Randr_Crtc
1715 ecore_x_randr_output_crtc_get(Ecore_X_Window root,
1716 Ecore_X_Randr_Output output)
1719 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1720 XRRScreenResources *res = NULL;
1721 XRROutputInfo *output_info = NULL;
1722 Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
1724 if ((output != Ecore_X_Randr_None))
1726 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1728 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1730 ret = output_info->crtc;
1731 XRRFreeOutputInfo(output_info);
1733 XRRFreeScreenResources(res);
1739 return Ecore_X_Randr_None;
1744 * @brief gets the given output's name as reported by X
1745 * @param root the window which's screen will be queried
1746 * @param output The output for which the name will be reported.
1747 * @param len length of returned c-string.
1748 * @return name of the output as reported by X
1751 ecore_x_randr_output_name_get(Ecore_X_Window root,
1752 Ecore_X_Randr_Output output,
1756 RANDR_CHECK_1_2_RET(NULL);
1757 XRRScreenResources *res = NULL;
1758 XRROutputInfo *output_info = NULL;
1761 if ((output != Ecore_X_Randr_None)
1762 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1763 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1766 * Actually the below command is correct, but due to a bug in libXrandr
1767 * it doesn't work. Therefore we stick with strlen().
1768 * Replace the line below with the following once this bug is
1769 * fixed within libXrandr.
1771 * *len = output_info->nameLen;
1774 if ((ret = strdup(output_info->name)) && len)
1777 XRRFreeOutputInfo(output_info);
1781 XRRFreeScreenResources(res);
1790 * @brief gets the width and hight of a given mode
1791 * @param mode the mode which's size is to be looked up
1792 * @param w width of given mode in px
1793 * @param h height of given mode in px
1796 ecore_x_randr_mode_size_get(Ecore_X_Window root,
1797 Ecore_X_Randr_Mode mode,
1802 RANDR_CHECK_1_2_RET();
1803 XRRScreenResources *res = NULL;
1806 if ((mode != Ecore_X_Randr_None)
1808 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1810 for (i = 0; i < res->nmode; i++)
1812 if (res->modes[i].id == mode)
1815 *w = res->modes[i].width;
1818 *h = res->modes[i].height;
1826 XRRFreeScreenResources(res);
1832 * @brief gets the EDID information of an attached output if available.
1833 * Note that this information is not to be compared using ordinary string
1834 * comparison functions, since it includes 0-bytes.
1835 * @param root window this information should be queried from
1836 * @param output the XID of the output
1837 * @param length length of the byte-array. If NULL, request will fail.
1839 EAPI unsigned char *
1840 ecore_x_randr_output_edid_get(Ecore_X_Window root,
1841 Ecore_X_Randr_Output output,
1842 unsigned long *length)
1845 RANDR_CHECK_1_2_RET(NULL);
1846 Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False);
1847 unsigned char *prop_data, *ret = NULL;
1849 unsigned long nitems, bytes_after;
1852 if (!length || !_ecore_x_randr_output_validate(root, output))
1855 if (XRRGetOutputProperty (_ecore_x_disp, output, name,
1856 0, 128, False, False,
1858 &actual_type, &actual_format,
1859 &nitems, &bytes_after, &prop_data) == Success)
1861 if (actual_type == XA_INTEGER && actual_format == 8)
1863 if ((ret = malloc(nitems * sizeof(unsigned char))))
1866 (memcpy(ret, prop_data, (nitems * sizeof(unsigned char)))))
1880 EAPI Ecore_X_Randr_Connection_Status
1881 ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
1882 Ecore_X_Randr_Output output)
1885 RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
1886 XRRScreenResources *res = NULL;
1887 XRROutputInfo *output_info = NULL;
1888 Ecore_X_Randr_Connection_Status ret =
1889 ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1891 if ((output != Ecore_X_Randr_None)
1892 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1893 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1895 ret = output_info->connection;
1899 XRRFreeOutputInfo(output_info);
1902 XRRFreeScreenResources(res);
1906 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1911 ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
1912 Ecore_X_Randr_Output output,
1917 RANDR_CHECK_1_2_RET();
1918 XRRScreenResources *res = NULL;
1919 XRROutputInfo *output_info = NULL;
1921 if ((output != Ecore_X_Randr_None)
1922 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1925 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1928 *w_mm = output_info->mm_width;
1931 *h_mm = output_info->mm_height;
1933 XRRFreeOutputInfo(output_info);
1936 XRRFreeScreenResources(res);
1943 ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root,
1944 const Ecore_X_Randr_Crtc *not_moved,
1950 Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL;
1951 XRRScreenResources *res = NULL;
1955 if ((nnot_moved <= 0) || (!not_moved)
1956 || !_ecore_x_randr_root_validate(root)
1958 _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
1961 n = (res->ncrtc - nnot_moved);
1962 if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n)))
1964 for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
1966 for (j = 0; j < nnot_moved; j++)
1968 if (res->crtcs[i] == not_moved[j])
1971 if (j == nnot_moved)
1972 //crtcs[i] is not in the 'not to move'-list
1973 crtcs_to_be_moved[k++] = res->crtcs[i];
1977 XRRFreeScreenResources(res);
1978 ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy);
1979 free(crtcs_to_be_moved);
1987 * @brief Move given CRTCs belonging to the given root window's screen dx/dy
1988 * pixels relative to their current position. The screen size will be
1989 * automatically adjusted if necessary and possible.
1991 * @param root Window which's screen's resources are used.
1992 * @param crtcs List of CRTCs to be moved.
1993 * @param ncrtc Number of CRTCs in array.
1994 * @param dx Amount of pixels the CRTCs should be moved in x direction.
1995 * @param dy Amount of pixels the CRTCs should be moved in y direction.
1996 * @return @c EINA_TRUE if all crtcs could be moved successfully.
1999 ecore_x_randr_move_crtcs(Ecore_X_Window root,
2000 const Ecore_X_Randr_Crtc *crtcs,
2006 RANDR_CHECK_1_2_RET(EINA_FALSE);
2007 XRRScreenResources *res = NULL;
2008 XRRCrtcInfo **crtc_info = NULL;
2009 Eina_Bool ret = EINA_TRUE;
2010 int i, cw, ch, w_max, h_max, nw, nh;
2012 crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc);
2013 memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc);
2014 if (_ecore_x_randr_root_validate(root)
2015 && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
2017 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
2018 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
2024 (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i]));
2027 if (((crtc_info[i]->x + dx) < 0) ||
2028 ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max)
2029 || ((crtc_info[i]->y + dy) < 0) ||
2030 ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max)
2032 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2034 nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw);
2035 nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh);
2039 //resize if necessary
2042 ecore_x_randr_screen_current_size_set(root, nw, nh,
2043 Ecore_X_Randr_Unset,
2044 Ecore_X_Randr_Unset)))
2045 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2047 //actually move all the crtcs, keep their rotation and mode.
2048 for (i = 0; (i < ncrtc) && crtc_info[i]; i++)
2050 if ((crtc_info[i]) &&
2051 (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL,
2052 Ecore_X_Randr_Unset,
2053 (crtc_info[i]->x + dx),
2054 (crtc_info[i]->y + dy),
2056 crtc_info[i]->rotation)))
2064 //something went wrong, let's try to move the already moved crtcs
2069 ecore_x_randr_crtc_settings_set(root,
2072 Ecore_X_Randr_Unset,
2073 (crtc_info[i]->x - dx),
2074 (crtc_info[i]->y - dy),
2076 crtc_info[i]->rotation);
2080 for (i = 0; i < ncrtc; i++)
2082 if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]);
2086 XRRFreeScreenResources(res);
2089 _ecore_x_randr_move_crtcs_fail_free_crtc_info:
2091 XRRFreeCrtcInfo(crtc_info[i]);
2092 XRRFreeScreenResources(res);
2100 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
2101 * and all other CRTCs dx,dy respectively.
2102 * @param root the window's screen which will be reset.
2105 ecore_x_randr_screen_reset(Ecore_X_Window root)
2108 XRRCrtcInfo *crtc_info = NULL;
2109 XRRScreenResources *res = NULL;
2110 //the 100000 are just a random huge number.
2111 int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0;
2113 if (!_ecore_x_randr_root_validate(root) ||
2114 !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
2117 Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc];
2119 for (i = 0; i < res->ncrtc; i++)
2122 XRRGetCrtcInfo(_ecore_x_disp, res,
2124 (crtc_info->mode == Ecore_X_Randr_None) ||
2125 (crtc_info->mode == Ecore_X_Randr_Unset)
2126 || ((crtc_info->noutput == 0)))
2129 enabled_crtcs[nenabled_crtcs++] = res->crtcs[i];
2131 if ((int)(crtc_info->x + crtc_info->width) > w_n)
2132 w_n = (crtc_info->x + crtc_info->width);
2134 if ((int)(crtc_info->y + crtc_info->height) > h_n)
2135 h_n = (crtc_info->y + crtc_info->height);
2137 if (crtc_info->x < dx_min)
2138 dx_min = crtc_info->x;
2139 if (crtc_info->y < dy_min)
2140 dy_min = crtc_info->y;
2142 XRRFreeCrtcInfo(crtc_info);
2144 if ((dx_min > 0) || (dy_min > 0))
2146 if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min))
2152 ecore_x_randr_screen_current_size_set(root,
2155 Ecore_X_Randr_Unset,
2156 Ecore_X_Randr_Unset);
2161 * @brief Set up the backlight level to the given level.
2163 * @param root The window's screen which will be set.
2164 * @param level Of the backlight between @c 0 and @c 1.
2168 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root,
2172 RANDR_CHECK_1_2_RET();
2174 XRRScreenResources *resources = NULL;
2175 Ecore_X_Randr_Output output;
2178 if ((level < 0) || (level > 1))
2180 ERR("Wrong value for the backlight level. It should be between 0 and 1.");
2185 * To make sure that the _backlight atomic property still exists.
2187 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2188 if (_backlight == None)
2190 WRN("Backlight setting is not supported on this server or driver");
2194 /* get the ressources */
2195 resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root);
2196 if (!resources) return;
2198 for (o = 0; o < resources->noutput; o++)
2200 output = resources->outputs[o];
2201 if (ecore_x_randr_output_backlight_level_get(root, output) >= 0)
2203 ecore_x_randr_output_backlight_level_set(root, output, level);
2206 XRRFreeScreenResources(resources);
2211 * @brief Check if a backlight is available.
2212 * @return Whether a backlight is available.
2216 ecore_x_randr_output_backlight_available(void)
2219 RANDR_CHECK_1_2_RET(-1);
2222 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2224 return (_backlight == None) ? EINA_FALSE : EINA_TRUE;
2231 * @brief Get the backlight level of the given output.
2233 * @param root Window which's screen should be queried.
2234 * @param output From which the backlight level should be retrieved.
2235 * @return The backlight level.
2239 ecore_x_randr_output_backlight_level_get(Ecore_X_Window root,
2240 Ecore_X_Randr_Output output)
2243 RANDR_CHECK_1_2_RET(-1);
2246 XRRPropertyInfo *info = NULL;
2249 long value, max, min;
2250 unsigned long nitems;
2251 unsigned long bytes_after;
2252 unsigned char *prop = NULL;
2254 /* set backlight variable if not already done */
2256 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2257 if (_backlight == None)
2259 ERR("Backlight property is not suppported on this server or driver");
2263 if (!_ecore_x_randr_output_validate(root, output))
2265 ERR("Invalid output");
2269 if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight,
2270 0, 4, False, False, None,
2271 &actual_type, &actual_format,
2272 &nitems, &bytes_after, &prop) != Success)
2274 WRN("Backlight not supported on this output");
2278 if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1;
2280 value = *((long *)prop);
2283 /* I have the current value of the backlight */
2284 /* Now retrieve the min and max intensities of the output */
2285 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2289 if ((info->range) && (info->num_values == 2))
2291 /* finally convert the current value in the interval [0..1] */
2292 min = info->values[0];
2293 max = info->values[1];
2294 dvalue = ((double)(value - min)) / ((double)(max - min));
2304 * @brief Set the backlight level of a given output.
2306 * @param root Window which's screen should be queried.
2307 * @param output That should be set.
2308 * @param level For which the backlight should be set.
2309 * @return @c EINA_TRUE in case of success.
2313 ecore_x_randr_output_backlight_level_set(Ecore_X_Window root,
2314 Ecore_X_Randr_Output output,
2318 RANDR_CHECK_1_2_RET(EINA_FALSE);
2320 XRRPropertyInfo *info = NULL;
2321 double min, max, tmp;
2324 if ((level < 0) || (level > 1))
2326 ERR("Backlight level should be between 0 and 1");
2330 if (!_ecore_x_randr_output_validate(root, output))
2332 ERR("Wrong output value");
2336 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2337 if (_backlight == None)
2339 WRN("Backlight property is not suppported on this server or driver");
2343 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2346 if ((info->range) && (info->num_values == 2))
2348 min = info->values[0];
2349 max = info->values[1];
2350 tmp = (level * (max - min)) + min;
2352 if (new > max) new = max;
2353 if (new < min) new = min;
2354 XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32,
2355 PropModeReplace, (unsigned char *)&new, 1);
2356 XFlush(_ecore_x_disp);
2366 * @brief Get the outputs, which display a certain window.
2368 * @param window Window the displaying outputs shall be found for
2369 * @param num The number of outputs displaying the window
2370 * @return Array of outputs that display a certain window. @c NULL if no
2371 * outputs was found that displays the specified window.
2374 EAPI Ecore_X_Randr_Output *
2375 ecore_x_randr_window_outputs_get(Ecore_X_Window window,
2379 Ecore_X_Window root;
2380 Ecore_X_Randr_Crtc *crtcs;
2381 Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
2382 int ncrtcs, noutputs, i, nret = 0;
2384 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
2386 root = ecore_x_window_root_get(window);
2387 if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
2388 goto _ecore_x_randr_current_output_get_fail;
2390 for (i = 0, nret = 0; i < ncrtcs; i++)
2393 outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
2396 goto _ecore_x_randr_current_output_get_fail_free;
2397 tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output)));
2398 if (!tret) goto _ecore_x_randr_current_output_get_fail_free;
2400 memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
2412 _ecore_x_randr_current_output_get_fail_free:
2416 _ecore_x_randr_current_output_get_fail:
2423 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
2424 * @brief Get the outputs, which display a certain window.
2426 * @param window Window the displaying outputs shall be found for.
2427 * @param num The number of outputs displaying the window.
2428 * @return Array of outputs that display a certain window. @c NULL if no
2429 * outputs was found that displays the specified window.
2432 EAPI Ecore_X_Randr_Output *
2433 ecore_x_randr_current_output_get(Ecore_X_Window window,
2436 return ecore_x_randr_window_outputs_get(window, num);