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)))
537 if (num) *num = res->ncrtc;
539 for (i = 0; i < res->ncrtc; i++)
540 ret[i] = res->crtcs[i];
543 XRRFreeScreenResources(res);
553 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
554 * @brief get the CRTCs, which display a certain window
555 * @param window window the displaying crtcs shall be found for
556 * @param num the number of crtcs displaying the window
557 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
558 * was found that displays the specified window.
560 EAPI Ecore_X_Randr_Crtc *
561 ecore_x_randr_current_crtc_get(Ecore_X_Window window,
564 return ecore_x_randr_window_crtcs_get(window, num);
568 * @brief get the CRTCs, which display a certain window
569 * @param window window the displaying crtcs shall be found for
570 * @param num the number of crtcs displaying the window
571 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
572 * was found that displays the specified window.
575 EAPI Ecore_X_Randr_Crtc *
576 ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
581 Eina_Rectangle w_geo, c_geo;
582 Ecore_X_Randr_Crtc *crtcs;
583 Ecore_X_Randr_Mode mode;
584 Ecore_X_Randr_Output *ret = NULL;
586 int ncrtcs, i, nret = 0, rx = 0, ry = 0;
588 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail;
590 ecore_x_window_geometry_get(window,
594 root = ecore_x_window_root_get(window);
595 crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs);
596 if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail;
598 /* now get window RELATIVE to root window - thats what matters. */
599 XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw);
603 ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc));
607 goto _ecore_x_randr_window_crtcs_get_fail;
609 for (i = 0, nret = 0; i < ncrtcs; i++)
611 /* if crtc is not enabled, don't bother about it any further */
612 mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
613 if (mode == Ecore_X_Randr_None) continue;
615 ecore_x_randr_crtc_geometry_get(root, crtcs[i],
618 if (eina_rectangles_intersect(&w_geo, &c_geo))
620 ret[nret] = crtcs[i];
626 if (num) *num = nret;
629 _ecore_x_randr_window_crtcs_get_fail:
635 EAPI Ecore_X_Randr_Output *
636 ecore_x_randr_outputs_get(Ecore_X_Window root,
640 RANDR_CHECK_1_2_RET(NULL);
641 XRRScreenResources *res = NULL;
642 Ecore_X_Randr_Output *ret = NULL;
645 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
647 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput)))
651 if (num) *num = res->noutput;
653 for (i = 0; i < res->noutput; i++)
654 ret[i] = res->outputs[i];
658 XRRFreeScreenResources(res);
669 * @brief get a CRTC's outputs.
670 * @param root the root window which's screen will be queried
671 * @param num number of outputs referenced by given CRTC
673 EAPI Ecore_X_Randr_Output *
674 ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
675 Ecore_X_Randr_Crtc crtc,
679 RANDR_CHECK_1_2_RET(NULL);
680 XRRScreenResources *res = NULL;
681 Ecore_X_Randr_Output *ret = NULL;
682 XRRCrtcInfo *crtc_info = NULL;
684 if (_ecore_x_randr_crtc_validate(root, crtc) &&
686 _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) &&
687 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
689 if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)))
693 if (num) *num = crtc_info->noutput;
695 for (i = 0; i < crtc_info->noutput; i++)
696 ret[i] = crtc_info->outputs[i];
700 XRRFreeCrtcInfo(crtc_info);
703 XRRFreeScreenResources(res);
713 * @brief get a CRTC's possible outputs.
714 * @param root the root window which's screen will be queried
715 * @param num number of possible outputs referenced by given CRTC
717 EAPI Ecore_X_Randr_Output *
718 ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root,
719 Ecore_X_Randr_Crtc crtc,
723 RANDR_CHECK_1_2_RET(NULL);
724 XRRScreenResources *res = NULL;
725 Ecore_X_Randr_Output *ret = NULL;
726 XRRCrtcInfo *crtc_info = NULL;
728 if (_ecore_x_randr_crtc_validate(root, crtc) &&
729 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
731 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
734 malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)))
738 if (num) *num = crtc_info->npossible;
740 for (i = 0; i < crtc_info->npossible; i++)
741 ret[i] = crtc_info->possible[i];
744 XRRFreeCrtcInfo(crtc_info);
747 XRRFreeScreenResources(res);
757 ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
758 Ecore_X_Randr_Crtc crtc,
765 RANDR_CHECK_1_2_RET();
766 XRRScreenResources *res = NULL;
767 XRRCrtcInfo *crtc_info = NULL;
769 if (_ecore_x_randr_crtc_validate(root,
772 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
774 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
783 *w = crtc_info->width;
786 *h = crtc_info->height;
788 XRRFreeCrtcInfo(crtc_info);
789 XRRFreeScreenResources(res);
796 * @brief Sets the position of given CRTC within root window's screen.
798 * @param root The window's screen to be queried.
799 * @param crtc The CRTC which's position within the mentioned screen is to be
801 * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
802 * value will be kept.
803 * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
804 * value will be kept.
805 * @return @c EINA_TRUE if position could successfully be altered.
808 ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
809 Ecore_X_Randr_Crtc crtc,
814 RANDR_CHECK_1_2_RET(EINA_FALSE);
815 int w_c, h_c, w_new = 0, h_new = 0;
816 Eina_Rectangle crtc_geo;
818 ecore_x_randr_crtc_geometry_get(root,
824 ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL);
831 if ((x + crtc_geo.w) > w_c)
832 w_new = x + crtc_geo.w;
834 if ((y + crtc_geo.h) > h_c)
835 h_new = y + crtc_geo.h;
837 if ((w_new != 0) || (h_new != 0))
838 if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0))
841 return ecore_x_randr_crtc_settings_set(root,
848 Ecore_X_Randr_Unset);
855 * @brief Get the current set mode of a given CRTC
856 * @param root the window's screen to be queried
857 * @param crtc the CRTC which's should be queried
858 * @return currently set mode or - in case parameters are invalid -
859 * Ecore_X_Randr_Unset
861 EAPI Ecore_X_Randr_Mode
862 ecore_x_randr_crtc_mode_get(Ecore_X_Window root,
863 Ecore_X_Randr_Crtc crtc)
866 RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
867 XRRScreenResources *res = NULL;
868 XRRCrtcInfo *crtc_info = NULL;
869 Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
870 if (_ecore_x_randr_root_validate(root) &&
871 _ecore_x_randr_crtc_validate(root,
874 _ecore_x_randr_get_screen_resources(_ecore_x_disp,
876 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
878 ret = crtc_info->mode;
879 XRRFreeCrtcInfo(crtc_info);
880 XRRFreeScreenResources(res);
885 return Ecore_X_Randr_Unset;
890 * @brief Sets a mode for a CRTC and the outputs attached to it.
892 * @param root The window's screen to be queried.
893 * @param crtc The CRTC which shall be set.
894 * @param outputs Array of outputs which have to be compatible with the mode.
895 * If @c NULL, CRTC will be disabled.
896 * @param noutputs Number of outputs in array to be used. Use
897 * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
898 * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
899 * disabled. If set to @c -1 the call will fail.
900 * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
904 ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
905 Ecore_X_Randr_Crtc crtc,
906 Ecore_X_Randr_Output *outputs,
908 Ecore_X_Randr_Mode mode)
911 RANDR_CHECK_1_2_RET(EINA_FALSE);
913 if (mode == Ecore_X_Randr_Unset)
916 return ecore_x_randr_crtc_settings_set(root,
923 Ecore_X_Randr_Unset);
930 ecore_x_randr_crtc_size_get(Ecore_X_Window root,
931 Ecore_X_Randr_Crtc crtc,
936 RANDR_CHECK_1_2_RET();
937 ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
941 EAPI Ecore_X_Randr_Refresh_Rate
942 ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
943 Ecore_X_Randr_Crtc crtc,
944 Ecore_X_Randr_Mode mode)
947 RANDR_CHECK_1_2_RET(0.0);
948 XRRScreenResources *res = NULL;
949 XRRCrtcInfo *crtc_info = NULL;
950 Ecore_X_Randr_Refresh_Rate ret = 0.0;
953 if (_ecore_x_randr_crtc_validate(root,
955 (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
957 for (i = 0; i < res->nmode; i++)
958 if (res->modes[i].id == mode)
960 if (res->modes[i].hTotal && res->modes[i].vTotal)
961 ret = ((double)res->modes[i].dotClock /
962 ((double)res->modes[i].hTotal *
963 (double)res->modes[i].vTotal));
970 XRRFreeCrtcInfo(crtc_info);
973 XRRFreeScreenResources(res);
981 EAPI Ecore_X_Randr_Orientation
982 ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
983 Ecore_X_Randr_Crtc crtc)
986 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
987 XRRCrtcInfo *crtc_info = NULL;
988 XRRScreenResources *res = NULL;
989 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
991 if (_ecore_x_randr_crtc_validate(root,
994 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
996 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
998 ret = crtc_info->rotations;
1001 XRRFreeCrtcInfo(crtc_info);
1004 XRRFreeScreenResources(res);
1008 return Ecore_X_Randr_None;
1012 EAPI Ecore_X_Randr_Orientation
1013 ecore_x_randr_crtc_orientation_get(Ecore_X_Window root,
1014 Ecore_X_Randr_Crtc crtc)
1017 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1018 XRRCrtcInfo *crtc_info = NULL;
1019 XRRScreenResources *res = NULL;
1020 Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
1022 if (_ecore_x_randr_crtc_validate(root,
1025 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1027 (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1029 ret = crtc_info->rotation;
1032 XRRFreeCrtcInfo(crtc_info);
1035 XRRFreeScreenResources(res);
1039 return Ecore_X_Randr_None;
1044 ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
1045 Ecore_X_Randr_Crtc crtc,
1046 Ecore_X_Randr_Orientation orientation)
1049 RANDR_CHECK_1_2_RET(EINA_FALSE);
1050 Eina_Bool ret = EINA_FALSE;
1052 if (orientation != Ecore_X_Randr_None)
1054 ret = ecore_x_randr_crtc_settings_set(root,
1057 Ecore_X_Randr_Unset,
1058 Ecore_X_Randr_Unset,
1059 Ecore_X_Randr_Unset,
1060 Ecore_X_Randr_Unset,
1071 ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
1072 Ecore_X_Randr_Crtc crtc,
1077 RANDR_CHECK_1_2_RET();
1079 ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
1084 ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
1085 Ecore_X_Randr_Crtc original,
1086 Ecore_X_Randr_Crtc clon)
1089 RANDR_CHECK_1_2_RET(EINA_FALSE);
1091 XRRScreenResources *res = NULL;
1092 XRRCrtcInfo *clone_crtc_info = NULL;
1093 Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None;
1094 Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None;
1095 Eina_Bool ret = EINA_FALSE;
1098 if (_ecore_x_randr_root_validate(root) &&
1099 _ecore_x_randr_crtc_validate(root,
1101 _ecore_x_randr_crtc_validate(root,
1104 _ecore_x_randr_get_screen_resources (_ecore_x_disp,
1106 (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon)))
1108 ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL);
1109 original_mode = ecore_x_randr_crtc_mode_get(root, original);
1110 original_orientation = ecore_x_randr_crtc_orientation_get(root,
1112 ret = ecore_x_randr_crtc_settings_set(root,
1115 Ecore_X_Randr_Unset,
1119 original_orientation);
1120 XRRFreeCrtcInfo(clone_crtc_info);
1121 XRRFreeScreenResources(res);
1131 * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
1132 * auto enabled in it's preferred mode, when it was disabled before.
1134 * @param root The root window which's default display will be queried.
1135 * @param crtc The CRTC which's configuration should be altered.
1136 * @param outputs An array of outputs, that should display this CRTC's content.
1137 * @param noutputs Number of outputs in the array of outputs. If set to
1138 * Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
1139 * If set to Ecore_X_Randr_None, CRTC will be disabled.
1140 * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
1141 * corrdinate will be assumed.
1142 * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
1143 * corrdinate will be assumed.
1144 * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
1145 * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
1147 * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
1148 * used, the current mode is assumed.
1149 * @return @c EINA_TRUE if the configuration alteration was successful,
1150 * @c EINA_FALSE otherwise.
1153 ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
1154 Ecore_X_Randr_Crtc crtc,
1155 Ecore_X_Randr_Output *outputs,
1159 Ecore_X_Randr_Mode mode,
1160 Ecore_X_Randr_Orientation orientation)
1163 RANDR_CHECK_1_2_RET(EINA_FALSE);
1164 XRRScreenResources *res = NULL;
1165 XRRCrtcInfo *crtc_info = NULL;
1166 Eina_Bool ret = EINA_FALSE;
1168 if (_ecore_x_randr_crtc_validate(root,
1170 (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1172 if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1174 if ((mode == Ecore_X_Randr_None) ||
1175 (noutputs == Ecore_X_Randr_None))
1180 else if (noutputs == (int)Ecore_X_Randr_Unset)
1182 outputs = (Ecore_X_Randr_Output *)crtc_info->outputs;
1183 noutputs = crtc_info->noutput;
1186 if (mode == Ecore_X_Randr_Unset)
1187 mode = crtc_info->mode;
1195 if (orientation == Ecore_X_Randr_Unset)
1196 orientation = crtc_info->rotation;
1198 if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime,
1199 x, y, mode, orientation, (RROutput *)outputs,
1203 XRRFreeCrtcInfo(crtc_info);
1206 XRRFreeScreenResources(res);
1216 * @brief Sets a CRTC relative to another one.
1218 * @param root The root window which's default display will be set.
1219 * @param crtc_r1 The CRTC to be positioned.
1220 * @param crtc_r2 The CRTC the position should be relative to.
1221 * @param policy The relation between the crtcs.
1222 * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
1224 * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
1225 * if repositioning failed or if position of new crtc would be out of given
1226 * screen's min/max bounds.
1229 ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root,
1230 Ecore_X_Randr_Crtc crtc_r1,
1231 Ecore_X_Randr_Crtc crtc_r2,
1232 Ecore_X_Randr_Output_Policy policy,
1233 Ecore_X_Randr_Relative_Alignment alignment)
1236 RANDR_CHECK_1_2_RET(EINA_FALSE);
1238 Eina_Rectangle r1_geo, r2_geo;
1239 int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n =
1240 Ecore_X_Randr_Unset;
1242 int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h;
1243 Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs;
1244 Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode;
1248 if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None)
1249 || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None))
1252 if (!_ecore_x_randr_crtc_validate(root, crtc_r1) ||
1253 (!(crtc_r1 != crtc_r2) &&
1254 !_ecore_x_randr_crtc_validate(root, crtc_r2)))
1257 ecore_x_randr_crtc_geometry_get(root,
1263 ecore_x_randr_crtc_geometry_get(root,
1269 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
1270 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
1274 case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
1275 //set r1 right of r2
1276 x_n = r2_geo.x + r2_geo.w;
1280 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1281 y_n = Ecore_X_Randr_Unset;
1284 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1286 ((int)(((double)r2_geo.h /
1287 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0)));
1290 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1291 y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0));
1296 case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
1298 x_n = r2_geo.x - r1_geo.w;
1302 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1303 y_n = Ecore_X_Randr_Unset;
1306 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1308 ((int)(((double)r2_geo.h /
1309 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0)));
1312 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1313 y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0)));
1318 case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
1320 y_n = r2_geo.y + r2_geo.h;
1324 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1325 x_n = Ecore_X_Randr_Unset;
1328 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1330 ((int)((((double)r2_geo.x +
1331 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1334 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1335 x_n = ((int)((double)cw / 2.0));
1340 case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
1341 y_n = r2_geo.y - r1_geo.h;
1346 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1347 x_n = Ecore_X_Randr_Unset;
1350 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1352 ((int)((((double)r2_geo.x +
1353 (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
1356 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1357 x_n = ((int)((double)cw / 2.0));
1362 case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
1363 return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y);
1365 /* entire cloning (including modesetting)
1366 //all outputs of crtc1 capable of crtc2's current mode?
1367 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1369 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1374 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1377 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1384 for (j = 0; j < r1_nmodes; j++)
1386 ecore_x_randr_mode_size_get(root,
1390 if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h))
1392 r1_mode = r1_modes[j];
1393 ++outputs_mode_found;
1402 if (outputs_mode_found <= i)
1404 //an output doesn't support the set mode, cancel!
1410 //CRTC 1's outputs support a mode of same geometry as CRTC 2.
1412 (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None,
1415 ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y));
1419 /* entire cloning on same CRTC
1420 //all outputs of crtc1 capable of crtc2's current mode?
1421 r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
1423 ecore_x_randr_crtc_outputs_get(root, crtc_r1,
1428 for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
1431 ecore_x_randr_output_modes_get(root, r1_outputs[i],
1438 for (j = 0; j < r1_nmodes; j++)
1440 if (r1_modes[j] == r2_mode)
1442 ++outputs_mode_found;
1451 if (outputs_mode_found <= i)
1453 //an output doesn't support the set mode, cancel!
1458 //check whether crtc r2 can use all outputs of r1.
1460 ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2,
1468 for (i = 0; i < r1_noutputs; i++)
1470 for (j = 0; j < r2_noutputs; )
1472 if (r1_outputs[i] == r2_outputs[j])
1477 if (j == r2_noutputs)
1479 //didn't find the output!
1486 //apparently crtc2 supports all outputs of r1
1487 //TODO: check with the compatible list of outputs (property in RR1.3)
1489 malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs));
1490 for (i = 0; i < r1_noutputs; i++)
1492 r2_r1_outputs[i] = r1_outputs[i];
1495 for (; i < r2_noutputs; i++)
1497 r2_r1_outputs[i] = r2_outputs[i];
1501 ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs,
1502 (r1_noutputs + r1_noutputs), r2_mode);
1503 free (r2_r1_outputs);
1506 case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
1511 if ((x_n == r1_geo.x) && (y_n == r1_geo.x))
1514 //out of possible bounds?
1515 if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max))
1518 return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n);
1525 * @brief Add given mode to given output.
1527 * @param output The output the mode is added to.
1528 * @param mode The mode added to the output.
1529 * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
1531 * Additionally, if xcb backend is used, the success of the addition is
1532 * reported back directly.
1536 ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output,
1537 Ecore_X_Randr_Mode mode)
1540 RANDR_CHECK_1_2_RET(EINA_FALSE);
1542 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1545 XRRAddOutputMode(_ecore_x_disp, output, mode);
1553 * @brief delete given mode from given output
1554 * @param output the output the mode is removed from
1555 * @param mode the mode removed from the output
1559 ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output,
1560 Ecore_X_Randr_Mode mode)
1563 RANDR_CHECK_1_2_RET();
1565 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
1568 XRRDeleteOutputMode(_ecore_x_disp, output, mode);
1574 EAPI Ecore_X_Randr_Mode *
1575 ecore_x_randr_output_modes_get(Ecore_X_Window root,
1576 Ecore_X_Randr_Output output,
1581 RANDR_CHECK_1_2_RET(NULL);
1582 XRRScreenResources *res = NULL;
1583 XRROutputInfo *output_info = NULL;
1584 Ecore_X_Randr_Mode *modes = NULL;
1586 if ((output != Ecore_X_Randr_None)
1587 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1589 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1591 if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode)))
1595 if (num) *num = output_info->nmode;
1596 if (npreferred) *npreferred = output_info->npreferred;
1598 for (i = 0; i < output_info->nmode; i++)
1599 modes[i] = output_info->modes[i];
1604 XRRFreeOutputInfo(output_info);
1607 XRRFreeScreenResources(res);
1615 EAPI Ecore_X_Randr_Crtc *
1616 ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root,
1617 Ecore_X_Randr_Output output,
1621 RANDR_CHECK_1_2_RET(NULL);
1622 XRRScreenResources *res = NULL;
1623 XRROutputInfo *output_info = NULL;
1624 Ecore_X_Randr_Crtc *crtcs = NULL;
1626 if ((output != Ecore_X_Randr_None))
1628 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1630 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1632 if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)))
1634 memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc));
1635 if (num) *num = output_info->ncrtc;
1637 XRRFreeOutputInfo(output_info);
1639 XRRFreeScreenResources(res);
1644 return Ecore_X_Randr_None;
1649 * @brief gets the the outputs which might be used simultenously on the same
1651 * @param root window that this information should be queried for.
1652 * @param output the output which's clones we concern
1653 * @param num number of possible clones
1655 EAPI Ecore_X_Randr_Output *
1656 ecore_x_randr_output_clones_get(Ecore_X_Window root,
1657 Ecore_X_Randr_Output output,
1661 RANDR_CHECK_1_2_RET(NULL);
1662 XRRScreenResources *res = NULL;
1663 XRROutputInfo *output_info = NULL;
1664 Ecore_X_Randr_Output *outputs = NULL;
1666 if ((output != Ecore_X_Randr_None))
1668 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1670 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1672 if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone)))
1674 memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone));
1675 if (num) *num = output_info->nclone;
1677 XRRFreeOutputInfo(output_info);
1679 XRRFreeScreenResources(res);
1684 return Ecore_X_Randr_None;
1688 EAPI Ecore_X_Randr_Crtc
1689 ecore_x_randr_output_crtc_get(Ecore_X_Window root,
1690 Ecore_X_Randr_Output output)
1693 RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
1694 XRRScreenResources *res = NULL;
1695 XRROutputInfo *output_info = NULL;
1696 Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
1698 if ((output != Ecore_X_Randr_None))
1700 if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1702 if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1704 ret = output_info->crtc;
1705 XRRFreeOutputInfo(output_info);
1707 XRRFreeScreenResources(res);
1713 return Ecore_X_Randr_None;
1718 * @brief gets the given output's name as reported by X
1719 * @param root the window which's screen will be queried
1720 * @param output The output for which the name will be reported.
1721 * @param len length of returned c-string.
1722 * @return name of the output as reported by X
1725 ecore_x_randr_output_name_get(Ecore_X_Window root,
1726 Ecore_X_Randr_Output output,
1730 RANDR_CHECK_1_2_RET(NULL);
1731 XRRScreenResources *res = NULL;
1732 XRROutputInfo *output_info = NULL;
1735 if ((output != Ecore_X_Randr_None)
1736 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1737 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1740 * Actually the below command is correct, but due to a bug in libXrandr
1741 * it doesn't work. Therefore we stick with strlen().
1742 * Replace the line below with the following once this bug is
1743 * fixed within libXrandr.
1745 * *len = output_info->nameLen;
1748 if ((ret = strdup(output_info->name)) && len)
1751 XRRFreeOutputInfo(output_info);
1755 XRRFreeScreenResources(res);
1764 * @brief gets the width and hight of a given mode
1765 * @param mode the mode which's size is to be looked up
1766 * @param w width of given mode in px
1767 * @param h height of given mode in px
1770 ecore_x_randr_mode_size_get(Ecore_X_Window root,
1771 Ecore_X_Randr_Mode mode,
1776 RANDR_CHECK_1_2_RET();
1777 XRRScreenResources *res = NULL;
1780 if ((mode != Ecore_X_Randr_None)
1782 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1784 for (i = 0; i < res->nmode; i++)
1786 if (res->modes[i].id == mode)
1789 *w = res->modes[i].width;
1792 *h = res->modes[i].height;
1800 XRRFreeScreenResources(res);
1806 * @brief gets the EDID information of an attached output if available.
1807 * Note that this information is not to be compared using ordinary string
1808 * comparison functions, since it includes 0-bytes.
1809 * @param root window this information should be queried from
1810 * @param output the XID of the output
1811 * @param length length of the byte-array. If NULL, request will fail.
1813 EAPI unsigned char *
1814 ecore_x_randr_output_edid_get(Ecore_X_Window root,
1815 Ecore_X_Randr_Output output,
1816 unsigned long *length)
1819 RANDR_CHECK_1_2_RET(NULL);
1820 Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False);
1821 unsigned char *prop_data, *ret = NULL;
1823 unsigned long nitems, bytes_after;
1826 if (!length || !_ecore_x_randr_output_validate(root, output))
1829 if (XRRGetOutputProperty (_ecore_x_disp, output, name,
1830 0, 100, False, False,
1832 &actual_type, &actual_format,
1833 &nitems, &bytes_after, &prop_data) == Success)
1835 if (actual_type == XA_INTEGER && actual_format == 8)
1837 if ((ret = malloc(nitems * sizeof(unsigned char))))
1840 (memcpy(ret, prop_data, (nitems * sizeof(unsigned char)))))
1854 EAPI Ecore_X_Randr_Connection_Status
1855 ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
1856 Ecore_X_Randr_Output output)
1859 RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
1860 XRRScreenResources *res = NULL;
1861 XRROutputInfo *output_info = NULL;
1862 Ecore_X_Randr_Connection_Status ret =
1863 ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1865 if ((output != Ecore_X_Randr_None)
1866 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
1867 && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1869 ret = output_info->connection;
1873 XRRFreeOutputInfo(output_info);
1876 XRRFreeScreenResources(res);
1880 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
1885 ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
1886 Ecore_X_Randr_Output output,
1891 RANDR_CHECK_1_2_RET();
1892 XRRScreenResources *res = NULL;
1893 XRROutputInfo *output_info = NULL;
1895 if ((output != Ecore_X_Randr_None)
1896 && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
1899 XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
1902 *w_mm = output_info->mm_width;
1905 *h_mm = output_info->mm_height;
1907 XRRFreeOutputInfo(output_info);
1910 XRRFreeScreenResources(res);
1917 ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root,
1918 const Ecore_X_Randr_Crtc *not_moved,
1924 Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL;
1925 XRRScreenResources *res = NULL;
1929 if ((nnot_moved <= 0) || (!not_moved)
1930 || !_ecore_x_randr_root_validate(root)
1932 _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
1935 n = (res->ncrtc - nnot_moved);
1936 if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n)))
1938 for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
1940 for (j = 0; j < nnot_moved; j++)
1942 if (res->crtcs[i] == not_moved[j])
1945 if (j == nnot_moved)
1946 //crtcs[i] is not in the 'not to move'-list
1947 crtcs_to_be_moved[k++] = res->crtcs[i];
1951 XRRFreeScreenResources(res);
1952 ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy);
1953 free(crtcs_to_be_moved);
1961 * @brief Move given CRTCs belonging to the given root window's screen dx/dy
1962 * pixels relative to their current position. The screen size will be
1963 * automatically adjusted if necessary and possible.
1965 * @param root Window which's screen's resources are used.
1966 * @param crtcs List of CRTCs to be moved.
1967 * @param ncrtc Number of CRTCs in array.
1968 * @param dx Amount of pixels the CRTCs should be moved in x direction.
1969 * @param dy Amount of pixels the CRTCs should be moved in y direction.
1970 * @return @c EINA_TRUE if all crtcs could be moved successfully.
1973 ecore_x_randr_move_crtcs(Ecore_X_Window root,
1974 const Ecore_X_Randr_Crtc *crtcs,
1980 RANDR_CHECK_1_2_RET(EINA_FALSE);
1981 XRRScreenResources *res = NULL;
1982 XRRCrtcInfo **crtc_info = NULL;
1983 Eina_Bool ret = EINA_TRUE;
1984 int i, cw, ch, w_max, h_max, nw, nh;
1986 crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc);
1987 memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc);
1988 if (_ecore_x_randr_root_validate(root)
1989 && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
1991 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
1992 ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
1998 (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i]));
2001 if (((crtc_info[i]->x + dx) < 0) ||
2002 ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max)
2003 || ((crtc_info[i]->y + dy) < 0) ||
2004 ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max)
2006 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2008 nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw);
2009 nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh);
2013 //resize if necessary
2016 ecore_x_randr_screen_current_size_set(root, nw, nh,
2017 Ecore_X_Randr_Unset,
2018 Ecore_X_Randr_Unset)))
2019 goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
2021 //actually move all the crtcs, keep their rotation and mode.
2022 for (i = 0; (i < ncrtc) && crtc_info[i]; i++)
2024 if ((crtc_info[i]) &&
2025 (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL,
2026 Ecore_X_Randr_Unset,
2027 (crtc_info[i]->x + dx),
2028 (crtc_info[i]->y + dy),
2030 crtc_info[i]->rotation)))
2038 //something went wrong, let's try to move the already moved crtcs
2043 ecore_x_randr_crtc_settings_set(root,
2046 Ecore_X_Randr_Unset,
2047 (crtc_info[i]->x - dx),
2048 (crtc_info[i]->y - dy),
2050 crtc_info[i]->rotation);
2054 for (i = 0; i < ncrtc; i++)
2056 if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]);
2060 XRRFreeScreenResources(res);
2063 _ecore_x_randr_move_crtcs_fail_free_crtc_info:
2065 XRRFreeCrtcInfo(crtc_info[i]);
2066 XRRFreeScreenResources(res);
2074 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
2075 * and all other CRTCs dx,dy respectively.
2076 * @param root the window's screen which will be reset.
2079 ecore_x_randr_screen_reset(Ecore_X_Window root)
2082 XRRCrtcInfo *crtc_info = NULL;
2083 XRRScreenResources *res = NULL;
2084 //the 100000 are just a random huge number.
2085 int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0;
2087 if (!_ecore_x_randr_root_validate(root) ||
2088 !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
2091 Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc];
2093 for (i = 0; i < res->ncrtc; i++)
2096 XRRGetCrtcInfo(_ecore_x_disp, res,
2098 (crtc_info->mode == Ecore_X_Randr_None) ||
2099 (crtc_info->mode == Ecore_X_Randr_Unset)
2100 || ((crtc_info->noutput == 0)))
2103 enabled_crtcs[nenabled_crtcs++] = res->crtcs[i];
2105 if ((int)(crtc_info->x + crtc_info->width) > w_n)
2106 w_n = (crtc_info->x + crtc_info->width);
2108 if ((int)(crtc_info->y + crtc_info->height) > h_n)
2109 h_n = (crtc_info->y + crtc_info->height);
2111 if (crtc_info->x < dx_min)
2112 dx_min = crtc_info->x;
2113 if (crtc_info->y < dy_min)
2114 dy_min = crtc_info->y;
2116 XRRFreeCrtcInfo(crtc_info);
2118 if ((dx_min > 0) || (dy_min > 0))
2120 if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min))
2126 ecore_x_randr_screen_current_size_set(root,
2129 Ecore_X_Randr_Unset,
2130 Ecore_X_Randr_Unset);
2135 * @brief Set up the backlight level to the given level.
2137 * @param root The window's screen which will be set.
2138 * @param level Of the backlight between @c 0 and @c 1.
2142 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root,
2146 RANDR_CHECK_1_2_RET();
2148 XRRScreenResources *resources = NULL;
2149 Ecore_X_Randr_Output output;
2152 if ((level < 0) || (level > 1))
2154 ERR("Wrong value for the backlight level. It should be between 0 and 1.");
2159 * To make sure that the _backlight atomic property still exists.
2161 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2162 if (_backlight == None)
2164 WRN("Backlight setting is not supported on this server or driver");
2168 /* get the ressources */
2169 resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root);
2170 if (!resources) return;
2172 for (o = 0; o < resources->noutput; o++)
2174 output = resources->outputs[o];
2175 if (ecore_x_randr_output_backlight_level_get(root, output) >= 0)
2177 ecore_x_randr_output_backlight_level_set(root, output, level);
2180 XRRFreeScreenResources(resources);
2185 * @brief Check if a backlight is available.
2186 * @return Whether a backlight is available.
2190 ecore_x_randr_output_backlight_available(void)
2193 RANDR_CHECK_1_2_RET(-1);
2196 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2198 return (_backlight == None) ? EINA_FALSE : EINA_TRUE;
2205 * @brief Get the backlight level of the given output.
2207 * @param root Window which's screen should be queried.
2208 * @param output From which the backlight level should be retrieved.
2209 * @return The backlight level.
2213 ecore_x_randr_output_backlight_level_get(Ecore_X_Window root,
2214 Ecore_X_Randr_Output output)
2217 RANDR_CHECK_1_2_RET(-1);
2220 XRRPropertyInfo *info = NULL;
2223 long value, max, min;
2224 unsigned long nitems;
2225 unsigned long bytes_after;
2226 unsigned char *prop = NULL;
2228 /* set backlight variable if not already done */
2230 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2231 if (_backlight == None)
2233 ERR("Backlight property is not suppported on this server or driver");
2237 if (!_ecore_x_randr_output_validate(root, output))
2239 ERR("Invalid output");
2243 if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight,
2244 0, 4, False, False, None,
2245 &actual_type, &actual_format,
2246 &nitems, &bytes_after, &prop) != Success)
2248 WRN("Backlight not supported on this output");
2252 if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1;
2254 value = *((long *)prop);
2257 /* I have the current value of the backlight */
2258 /* Now retrieve the min and max intensities of the output */
2259 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2263 if ((info->range) && (info->num_values == 2))
2265 /* finally convert the current value in the interval [0..1] */
2266 min = info->values[0];
2267 max = info->values[1];
2268 dvalue = ((double)(value - min)) / ((double)(max - min));
2278 * @brief Set the backlight level of a given output.
2280 * @param root Window which's screen should be queried.
2281 * @param output That should be set.
2282 * @param level For which the backlight should be set.
2283 * @return @c EINA_TRUE in case of success.
2287 ecore_x_randr_output_backlight_level_set(Ecore_X_Window root,
2288 Ecore_X_Randr_Output output,
2292 RANDR_CHECK_1_2_RET(EINA_FALSE);
2294 XRRPropertyInfo *info = NULL;
2295 double min, max, tmp;
2298 if ((level < 0) || (level > 1))
2300 ERR("Backlight level should be between 0 and 1");
2304 if (!_ecore_x_randr_output_validate(root, output))
2306 ERR("Wrong output value");
2310 _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True);
2311 if (_backlight == None)
2313 WRN("Backlight property is not suppported on this server or driver");
2317 info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight);
2320 if ((info->range) && (info->num_values == 2))
2322 min = info->values[0];
2323 max = info->values[1];
2324 tmp = (level * (max - min)) + min;
2326 if (new > max) new = max;
2327 if (new < min) new = min;
2328 XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32,
2329 PropModeReplace, (unsigned char *)&new, 1);
2330 XFlush(_ecore_x_disp);
2340 * @brief Get the outputs, which display a certain window.
2342 * @param window Window the displaying outputs shall be found for
2343 * @param num The number of outputs displaying the window
2344 * @return Array of outputs that display a certain window. @c NULL if no
2345 * outputs was found that displays the specified window.
2348 EAPI Ecore_X_Randr_Output *
2349 ecore_x_randr_window_outputs_get(Ecore_X_Window window,
2353 Ecore_X_Window root;
2354 Ecore_X_Randr_Crtc *crtcs;
2355 Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
2356 int ncrtcs, noutputs, i, nret = 0;
2358 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
2360 root = ecore_x_window_root_get(window);
2361 if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
2362 goto _ecore_x_randr_current_output_get_fail;
2364 for (i = 0, nret = 0; i < ncrtcs; i++)
2367 outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
2370 goto _ecore_x_randr_current_output_get_fail_free;
2371 tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output)));
2372 if (!tret) goto _ecore_x_randr_current_output_get_fail_free;
2374 memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
2386 _ecore_x_randr_current_output_get_fail_free:
2390 _ecore_x_randr_current_output_get_fail:
2397 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
2398 * @brief Get the outputs, which display a certain window.
2400 * @param window Window the displaying outputs shall be found for.
2401 * @param num The number of outputs displaying the window.
2402 * @return Array of outputs that display a certain window. @c NULL if no
2403 * outputs was found that displays the specified window.
2406 EAPI Ecore_X_Randr_Output *
2407 ecore_x_randr_current_output_get(Ecore_X_Window window,
2410 return ecore_x_randr_window_outputs_get(window, num);