6 #include "ecore_x_private.h"
11 * A lot of this code uses XRRGetScreenInfo and then calls
12 * XRRFreeScreenConfigInfo. Typically this is not an Unheard of thing to do,
13 * however this process of getting config and freeing config does force a
14 * round-trip to the X server */
17 static Eina_Bool _randr_avail = EINA_FALSE;
19 static Ecore_X_Atom connector_type = 0;
20 static Ecore_X_Atom connector_number = 0;
24 # define RANDR_VERSION_1_1 ((1 << 16) | 1)
25 # define RANDR_VERSION_1_2 ((1 << 16) | 2)
26 # define RANDR_VERSION_1_3 ((1 << 16) | 3)
27 # define RANDR_VERSION_1_4 ((1 << 16) | 4)
29 # define RANDR_EDID_VERSION_1_3 ((1 << 8) | 3)
30 # define RANDR_EDID_VERSION_MAJOR 0x12
31 # define RANDR_EDID_VERSION_MINOR 0x13
33 # define RANDR_EDID_MANUFACTURER 0x08
34 # define RANDR_EDID_BLOCK 0x36
36 typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred
38 RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00,
39 RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01,
40 RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02,
41 RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03,
42 RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04
43 } Ecore_X_Randr_Edid_Aspect_Ratio_Preferred;
45 static int _randr_major, _randr_minor, _randr_version;
47 XRRScreenResources *(*_ecore_x_randr_screen_resources_get)(Display *disp, Window win);
53 _ecore_x_randr_init(void)
60 /* try to query the randr extenstion version */
61 if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
63 _randr_version = (_randr_major << 16) | _randr_minor;
65 if (_randr_version >= RANDR_VERSION_1_3)
66 _ecore_x_randr_screen_resources_get = XRRGetScreenResourcesCurrent;
67 else if (_randr_version == RANDR_VERSION_1_2)
68 _ecore_x_randr_screen_resources_get = XRRGetScreenResources;
70 _randr_avail = EINA_TRUE;
72 connector_type = ecore_x_atom_get(RR_PROPERTY_CONNECTOR_TYPE);
73 connector_number = ecore_x_atom_get(RR_PROPERTY_CONNECTOR_NUMBER);
78 /* public functions */
80 ecore_x_randr_version_get(void)
83 if (_randr_avail) return _randr_version;
89 ecore_x_randr_query(void)
95 * @brief This function returns the current config timestamp from
96 * XRRScreenConfiguration.
98 * @param root root window to query screen configuration from
100 * @returns The screen configuration timestamp
105 ecore_x_randr_config_timestamp_get(Ecore_X_Window root)
107 Ecore_X_Time timestamp = 0;
110 XRRScreenConfiguration *cfg;
112 /* try to get the screen configuration from Xrandr */
113 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
117 XRRConfigTimes(cfg, &tm);
119 timestamp = (Ecore_X_Time)tm;
121 /* free any returned screen config */
122 if (cfg) XRRFreeScreenConfigInfo(cfg);
129 /***************************************
130 * API Functions for RandR version 1.1 *
131 ***************************************/
134 * @param root window which's primary output will be queried
136 EAPI Ecore_X_Randr_Orientation
137 ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root)
140 Rotation ret = 0, crot = 0;
142 /* get the rotations available from XRandr */
143 ret = XRRRotations(_ecore_x_disp,
144 XRRRootToScreen(_ecore_x_disp, root), &crot);
153 * @param root window which's primary output will be queried
154 * @return the current orientation of the root window's screen primary output
156 EAPI Ecore_X_Randr_Orientation
157 ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root)
162 /* get the current rotation available from XRandr */
163 XRRRotations(_ecore_x_disp,
164 XRRRootToScreen(_ecore_x_disp, root), &ret);
173 * @brief Sets a given screen's primary output's orientation.
175 * @param root Window which's screen's primary output will be queried.
176 * @param orientation orientation which should be set for the root window's
177 * screen primary output.
178 * @return @c EINA_TRUE if the primary output's orientation could be
179 * successfully altered.
182 ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orient)
185 Eina_Bool ret = EINA_FALSE;
187 XRRScreenConfiguration *cfg = NULL;
190 /* try to get the screen config from XRandr */
191 if (!(cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
194 /* get the screen's current size id */
195 id = XRRConfigCurrentConfiguration(cfg, &crot);
197 /* attempt to set the new orientation */
198 if (!XRRSetScreenConfig(_ecore_x_disp, cfg, root, id, orient, CurrentTime))
201 /* free any returned screen config */
202 if (cfg) XRRFreeScreenConfigInfo(cfg);
211 * @brief gets a screen's primary output's possible sizes
212 * @param root window which's primary output will be queried
213 * @param num number of sizes reported as supported by the screen's primary output
214 * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL
216 EAPI Ecore_X_Randr_Screen_Size_MM *
217 ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num)
221 Ecore_X_Randr_Screen_Size_MM *ret = NULL;
222 XRRScreenSize *sizes;
225 /* retrieve the number of sizes from X, and the sizes themselves.
227 * NB: don't have to free the returned sizes */
228 sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
229 if (!sizes) return NULL;
230 if (n <= 0) return NULL;
232 /* try to allocate our structure for these sizes */
233 if (!(ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM))))
238 /* fill in our allocated structure with the screen sizes */
239 for (i = 0; i < n; i++)
241 ret[i].width = sizes[i].width;
242 ret[i].height = sizes[i].height;
243 ret[i].width_mm = sizes[i].mwidth;
244 ret[i].height_mm = sizes[i].mheight;
254 ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm, int *size_index)
257 XRRScreenConfiguration *cfg = NULL;
259 /* try to get the screen config from XRandr */
260 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
262 XRRScreenSize *sizes;
266 /* retrieve the number of sizes from X, and the sizes themselves.
268 * NB: don't have to free the returned sizes */
270 XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
271 if ((sizes) && (n > 0))
275 /* get the index of the current configuration */
276 idx = XRRConfigCurrentConfiguration(cfg, &crot);
278 /* if the index is valid, then fill in the return variables with
279 * the size information for this index */
280 if ((idx < n) && (idx >= 0))
282 if (w) *w = sizes[idx].width;
283 if (h) *h = sizes[idx].height;
284 if (w_mm) *w_mm = sizes[idx].mwidth;
285 if (h_mm) *h_mm = sizes[idx].mheight;
286 if (size_index) *size_index = idx;
290 /* free the returned screen config */
291 XRRFreeScreenConfigInfo(cfg);
297 * @brief Sets a given screen's primary output size, but disables all other
298 * outputs at the same time.
300 * @param root Window which's primary output will be queried.
301 * @param size_index Within the list of sizes reported as supported by the root
302 * window's screen primary output.
303 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g.
307 ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index)
310 Eina_Bool ret = EINA_FALSE;
313 /* check for valid size index first */
314 if (size_index < 0) return EINA_FALSE;
316 /* get the number of sizes from XRandr */
317 XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
319 /* make sure the requested index is below the number returned from randr */
322 XRRScreenConfiguration *cfg = NULL;
324 /* try to get the screen config from XRandr */
325 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
327 /* try to set the new screen config
329 * NB: Returns Success (0) if it works */
330 if (!XRRSetScreenConfig(_ecore_x_disp, cfg, root, size_index,
331 ECORE_X_RANDR_ORIENTATION_ROT_0,
337 /* free the returned screen config */
338 XRRFreeScreenConfigInfo(cfg);
349 * @param root window which's primary output will be queried
350 * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0
352 EAPI Ecore_X_Randr_Refresh_Rate
353 ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root)
356 XRRScreenConfiguration *cfg = NULL;
358 /* try to get the screen config from XRandr */
359 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
361 Ecore_X_Randr_Refresh_Rate ret = 0.0;
363 /* try to get the current refresh rate */
364 ret = XRRConfigCurrentRate(cfg);
366 /* free the returned screen config */
367 XRRFreeScreenConfigInfo(cfg);
376 * @param root window which's primary output will be queried
377 * @param size_index referencing the size to query valid refresh rates for
378 * @return currently used refresh rate or - if request failed or RandRR is not available - NULL
380 EAPI Ecore_X_Randr_Refresh_Rate *
381 ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num)
384 Ecore_X_Randr_Refresh_Rate *rates = NULL;
387 /* try to get the refresh rates for this screen */
388 if ((rates = XRRRates(_ecore_x_disp,
389 XRRRootToScreen(_ecore_x_disp, root), size_index, &n)))
391 Ecore_X_Randr_Refresh_Rate *ret = NULL;
393 if (n == 0) return NULL;
395 /* try to allocate space for the return */
396 if ((ret = malloc(n * sizeof(Ecore_X_Randr_Refresh_Rate))))
400 /* fill in our return values */
401 for (i = 0; i < n; i++)
414 * @brief Sets the current primary output's refresh rate.
416 * @param root Window which's primary output will be queried.
417 * @param size_index Referencing the size to be set.
418 * @param rate The refresh rate to be set.
419 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
422 ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, int size_index, Ecore_X_Randr_Refresh_Rate rate)
425 if (_randr_version >= RANDR_VERSION_1_1)
427 XRRScreenConfiguration *cfg = NULL;
429 /* try to get the screen config from XRandr */
430 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
432 Eina_Bool ret = EINA_FALSE;
435 /* get the current rotation */
436 XRRConfigRotations(cfg, &rot);
438 /* try to set the new screen config
440 * NB: Returns Success (0) if it works */
441 if (!XRRSetScreenConfigAndRate(_ecore_x_disp, cfg, root,
442 size_index, rot, rate, CurrentTime))
447 /* free the returned screen config */
448 XRRFreeScreenConfigInfo(cfg);
457 /***************************************
458 * API Functions for RandR version 1.2 *
459 ***************************************/
462 * @brief Enable event selection. This enables basic interaction with
463 * output/crtc events and requires RandR >= 1.2.
465 * @param win Select this window's properties for RandR events.
466 * @param on Enable/disable selecting.
469 ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on)
476 mask = RRScreenChangeNotifyMask;
477 if (_randr_version >= RANDR_VERSION_1_2)
478 mask |= (RRCrtcChangeNotifyMask | RROutputChangeNotifyMask |
479 RROutputPropertyNotifyMask);
482 /* tell randr what events we want to listen to for this window */
483 XRRSelectInput(_ecore_x_disp, win, mask);
488 * @param w width of screen in px
489 * @param h height of screen in px
492 ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm)
495 if (_randr_version >= RANDR_VERSION_1_2)
499 /* get the screen number */
500 scr = XRRRootToScreen(_ecore_x_disp, root);
502 if (w) *w = DisplayWidth(_ecore_x_disp, scr);
503 if (h) *h = DisplayHeight(_ecore_x_disp, scr);
504 if (w_mm) *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
505 if (h_mm) *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
511 * @param root window which's screen will be queried
512 * @param wmin minimum width the screen can be set to
513 * @param hmin minimum height the screen can be set to
514 * @param wmax maximum width the screen can be set to
515 * @param hmax maximum height the screen can be set to
518 ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax)
521 if (_randr_version >= RANDR_VERSION_1_2)
523 int swmin = 0, shmin = 0, swmax = 0, shmax = 0;
525 /* try to get the screen size range from XRandr
527 * NB: returns 1 on success */
528 if ((XRRGetScreenSizeRange(_ecore_x_disp, root, &swmin, &shmin,
531 /* fill in the return variables */
532 if (wmin) *wmin = swmin;
533 if (hmin) *hmin = shmin;
534 if (wmax) *wmax = swmax;
535 if (hmax) *hmax = shmax;
542 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
543 * and all other CRTCs dx,dy respectively.
544 * @param root the window's screen which will be reset.
547 ecore_x_randr_screen_reset(Ecore_X_Window root)
550 XRRScreenResources *res = NULL;
552 if (_randr_version < RANDR_VERSION_1_2) return;
554 /* try to get the screen resources from Xrandr */
555 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
559 Ecore_X_Randr_Crtc crtcs[res->ncrtc];
560 int i = 0, nenabled = 0;
562 int dx = 100000, dy = 100000;
564 for (i = 0; i < res->ncrtc; i++)
566 XRRCrtcInfo *info = NULL;
568 /* try to get the crtc info from Xrandr */
569 if (!(info = XRRGetCrtcInfo(_ecore_x_disp, res, res->crtcs[i])))
573 if ((info->mode <= 0) || (info->noutput == 0))
575 /* free the crtc info */
576 XRRFreeCrtcInfo(info);
581 crtcs[nenabled++] = res->crtcs[i];
583 if ((int)(info->x + info->width) > nw)
584 nw = (info->x + info->width);
586 if ((int)(info->y + info->height) > nh)
587 nh = (info->y + info->height);
589 if (info->x < dx) dx = info->x;
590 if (info->y < dy) dy = info->y;
592 /* free the crtc info */
593 XRRFreeCrtcInfo(info);
596 /* free the resources */
597 XRRFreeScreenResources(res);
599 if ((dx > 0) || (dy > 0))
601 if (ecore_x_randr_move_crtcs(root, crtcs, nenabled, -dx, -dy))
608 ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1);
615 * @param root Window which's screen's size should be set. If invalid (e.g.
616 * @c NULL) no action is taken.
617 * @param w Width in px the screen should be set to. If out of valid
618 * boundaries, current value is assumed.
619 * @param h Height in px the screen should be set to. If out of valid
620 * boundaries, current value is assumed.
621 * @param w_mm Width in mm the screen should be set to. If @c 0, current
623 * @param h_mm Height in mm the screen should be set to. If @c 0, current
625 * @return @c EINA_TRUE if request was successfully sent or screen is already
626 * in requested size, @c EINA_FALSE if parameters are invalid.
629 ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm)
632 if (_randr_version >= RANDR_VERSION_1_2)
634 int cw = 0, ch = 0, cwmm = 0, chmm = 0;
635 int wmin = 0, hmin = 0, wmax = 0, hmax = 0;
637 /* get the current screen size */
638 ecore_x_randr_screen_current_size_get(root, &cw, &ch, &cwmm, &chmm);
640 /* compare to the values passed in. if there are no changes, get out */
641 if ((w == cw) && (h == ch) &&
642 ((w_mm == -1) || (w_mm == cwmm)) &&
643 ((h_mm == -1) || (h_mm == chmm)))
646 /* get the current size range */
647 ecore_x_randr_screen_size_range_get(root, &wmin, &hmin, &wmax, &hmax);
649 /* compare to the values passed in. make sure they are within range */
650 if ((w != 0) && ((w < wmin) || (w > wmax))) return EINA_FALSE;
651 if ((h != 0) && ((h < hmin) || (h > hmax))) return EINA_FALSE;
653 /* safety check some values */
659 w_mm = (int)(((double)(cwmm / (double)cw)) * (double)w);
661 w_mm = (int)(((double)(cwmm)) * (double)w);
666 h_mm = (int)(((double)(chmm / (double)ch)) * (double)h);
668 h_mm = (int)(((double)(chmm)) * (double)h);
671 /* tell XRandr to set screen size */
672 XRRSetScreenSize(_ecore_x_disp, root, w, h, w_mm, h_mm);
681 * @brief get detailed information for all modes related to a root window's screen
682 * @param root window which's screen's resources are queried
683 * @param num number of modes returned
684 * @return modes' information
686 EAPI Ecore_X_Randr_Mode_Info **
687 ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num)
691 XRRScreenResources *res = NULL;
693 if (_randr_version < RANDR_VERSION_1_2) return NULL;
695 /* try to get the screen resources from Xrandr */
696 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
698 Ecore_X_Randr_Mode_Info **ret = NULL;
700 /* set the returned number of modes */
701 if (num) *num = res->nmode;
703 /* if we did not get any modes from X, then cleanup and return */
706 /* free the resources */
707 XRRFreeScreenResources(res);
712 /* try to allocate space for our return variable */
713 if ((ret = (Ecore_X_Randr_Mode_Info **)
714 malloc(res->nmode * sizeof(Ecore_X_Randr_Mode_Info *))))
718 /* loop through all the modes and assign to our return var */
719 for (i = 0; i < res->nmode; i++)
721 if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
723 ret[i]->xid = res->modes[i].id;
724 ret[i]->width = res->modes[i].width;
725 ret[i]->height = res->modes[i].height;
726 ret[i]->dotClock = res->modes[i].dotClock;
727 ret[i]->hSyncStart = res->modes[i].hSyncStart;
728 ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
729 ret[i]->hTotal = res->modes[i].hTotal;
730 ret[i]->hSkew = res->modes[i].hSkew;
731 ret[i]->vSyncStart = res->modes[i].vSyncStart;
732 ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
733 ret[i]->vTotal = res->modes[i].vTotal;
734 if (res->modes[i].nameLength > 0)
737 (malloc(res->modes[i].nameLength + 1))))
738 strncpy(ret[i]->name, res->modes[i].name,
739 (res->modes[i].nameLength + 1));
746 ret[i]->nameLength = res->modes[i].nameLength;
747 ret[i]->modeFlags = res->modes[i].modeFlags;
760 /* free the resources */
761 XRRFreeScreenResources(res);
770 * @brief Add a mode to a display.
772 * @param root Window to which's screen's ressources are added.
774 * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
778 EAPI Ecore_X_Randr_Mode
779 ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info)
782 if (_randr_version >= RANDR_VERSION_1_2)
784 Ecore_X_Randr_Mode mode = 0;
786 /* if we have valid mode_info from the user, then ask XRandr to
787 * create the new mode using that as base */
789 mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo *)mode_info);
798 * @brief Delete a mode from the display.
804 ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode)
807 if (_randr_version >= RANDR_VERSION_1_2)
808 XRRDestroyMode(_ecore_x_disp, mode);
813 * @brief get detailed information for a given mode id
814 * @param root window which's screen's ressources are queried
815 * @param mode the XID which identifies the mode of interest
816 * @return mode's detailed information
818 EAPI Ecore_X_Randr_Mode_Info *
819 ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode)
822 XRRScreenResources *res = NULL;
824 if (_randr_version < RANDR_VERSION_1_2) return NULL;
826 /* try to get the screen resources from Xrandr */
827 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
829 Ecore_X_Randr_Mode_Info *ret = NULL;
834 /* free the resources */
835 XRRFreeScreenResources(res);
840 /* loop the mode informations and find the one we want */
841 for (i = 0; i < res->nmode; i++)
843 /* compare mode ids */
844 if (res->modes[i].id != mode) continue;
846 /* try to allocate our return mode information structure */
847 if (!(ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
850 /* copy the mode information into our return structure */
851 ret->xid = res->modes[i].id;
852 ret->width = res->modes[i].width;
853 ret->height = res->modes[i].height;
854 ret->dotClock = res->modes[i].dotClock;
855 ret->hSyncStart = res->modes[i].hSyncStart;
856 ret->hSyncEnd = res->modes[i].hSyncEnd;
857 ret->hTotal = res->modes[i].hTotal;
858 ret->hSkew = res->modes[i].hSkew;
859 ret->vSyncStart = res->modes[i].vSyncStart;
860 ret->vSyncEnd = res->modes[i].vSyncEnd;
861 ret->vTotal = res->modes[i].vTotal;
862 ret->modeFlags = res->modes[i].modeFlags;
865 if (res->modes[i].nameLength > 0)
867 ret->nameLength = res->modes[i].nameLength;
868 if ((ret->name = malloc(res->modes[i].nameLength + 1)))
869 strncpy(ret->name, res->modes[i].name,
870 (res->modes[i].nameLength + 1));
875 /* free the resources */
876 XRRFreeScreenResources(res);
885 * @brief Free detailed mode information. The pointer handed in will be set to
886 * @c NULL after freeing the memory.
888 * @param mode_info The mode information that should be freed.
891 ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
894 if (_randr_version >= RANDR_VERSION_1_2)
898 if (mode_info->name) free(mode_info->name);
906 * @brief Get all known CRTCs related to a root window's screen.
908 * @param root Window which's screen's ressources are queried.
909 * @param num Number of CRTCs returned.
912 EAPI Ecore_X_Randr_Crtc *
913 ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num)
917 XRRScreenResources *res = NULL;
919 if (_randr_version < RANDR_VERSION_1_2) return NULL;
921 /* try to get the screen resources from Xrandr */
922 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
924 Ecore_X_Randr_Crtc *ret = NULL;
928 /* free the resources */
929 XRRFreeScreenResources(res);
934 /* try to allocate space for our return variable */
935 if ((ret = malloc(res->ncrtc * sizeof(Ecore_X_Randr_Crtc))))
939 if (num) *num = res->ncrtc;
941 /* copy the crtc information into our return variable */
942 for (i = 0; i < res->ncrtc; i++)
943 ret[i] = res->crtcs[i];
946 /* free the resources */
947 XRRFreeScreenResources(res);
955 EAPI Ecore_X_Randr_Output *
956 ecore_x_randr_outputs_get(Ecore_X_Window root, int *num)
960 XRRScreenResources *res = NULL;
962 if (_randr_version < RANDR_VERSION_1_2) return NULL;
964 /* try to get the screen resources from Xrandr */
965 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
967 Ecore_X_Randr_Output *ret = NULL;
969 if (res->noutput == 0)
971 /* free the resources */
972 XRRFreeScreenResources(res);
977 /* try to allocate space for our return variable */
978 if ((ret = malloc(res->noutput * sizeof(Ecore_X_Randr_Output))))
982 if (num) *num = res->noutput;
984 /* copy the output information into our return variable */
985 for (i = 0; i < res->noutput; i++)
986 ret[i] = res->outputs[i];
989 /* free the resources */
990 XRRFreeScreenResources(res);
999 * @brief Get the outputs, which display a certain window.
1001 * @param window Window the displaying outputs shall be found for
1002 * @param num The number of outputs displaying the window
1003 * @return Array of outputs that display a certain window. @c NULL if no
1004 * outputs was found that displays the specified window.
1006 EAPI Ecore_X_Randr_Output *
1007 ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num)
1011 Ecore_X_Window root;
1012 Ecore_X_Randr_Crtc *crtcs = NULL;
1015 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1017 /* grab this windows root window */
1018 root = ecore_x_window_root_get(window);
1020 /* get the crtcs from xrandr */
1021 if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
1023 XRRScreenResources *res = NULL;
1024 Ecore_X_Randr_Output *ret = NULL;
1026 /* try to get the screen resources from Xrandr
1028 * NB: We do this ONCE here as we reuse it for every crtc.
1029 * NB: The old code used to loop and fetch the screen resources on
1031 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1033 Ecore_X_Randr_Output *tret = NULL;
1034 int i = 0, nret = 0;
1036 /* for each crtc, get it's outputs */
1037 for (i = 0, nret = 0; i < ncrtcs; i++)
1039 XRRCrtcInfo *crtc = NULL;
1041 /* try to get the crtc info for this crtc */
1042 if (!(crtc = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
1045 if (crtc->noutput > 0)
1047 /* try to reallocate our return variable */
1048 if ((tret = realloc(ret, ((nret + crtc->noutput) *
1049 sizeof(Ecore_X_Randr_Output)))))
1052 memcpy(&ret[nret], crtc->outputs,
1053 (crtc->noutput * sizeof(Ecore_X_Randr_Output)));
1054 nret += crtc->noutput;
1057 /* free the crtc info */
1058 XRRFreeCrtcInfo(crtc);
1061 if (num) *num = nret;
1063 /* free the resources */
1064 XRRFreeScreenResources(res);
1067 /* free any allocated crtcs from the get function */
1077 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
1078 * @brief Get the outputs, which display a certain window.
1080 * @param window Window the displaying outputs shall be found for.
1081 * @param num The number of outputs displaying the window.
1082 * @return Array of outputs that display a certain window. @c NULL if no
1083 * outputs was found that displays the specified window.
1085 EAPI Ecore_X_Randr_Output *
1086 ecore_x_randr_current_output_get(Ecore_X_Window window, int *num)
1088 return ecore_x_randr_window_outputs_get(window, num);
1092 * @brief get the CRTCs, which display a certain window
1093 * @param window window the displaying crtcs shall be found for
1094 * @param num the number of crtcs displaying the window
1095 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
1096 * was found that displays the specified window.
1099 EAPI Ecore_X_Randr_Crtc *
1100 ecore_x_randr_window_crtcs_get(Ecore_X_Window window, int *num)
1104 Ecore_X_Window root;
1105 Ecore_X_Randr_Crtc *crtcs = NULL;
1108 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1110 /* grab this windows root window */
1111 root = ecore_x_window_root_get(window);
1113 /* get the crtcs from xrandr */
1114 if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
1116 XRRScreenResources *res = NULL;
1117 Ecore_X_Randr_Crtc *ret = NULL;
1125 /* make sure we can allocate our return variable */
1126 if (!(ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc))))
1132 /* try to get the screen resources from Xrandr
1134 * NB: We do this ONCE here as we reuse it for every crtc.
1135 * NB: The old code used to loop and fetch the screen resources on
1137 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1140 Eina_Rectangle wrect, crect;
1141 int i = 0, nret = 0;
1143 /* get the geometry of this window */
1144 ecore_x_window_geometry_get(window, &wrect.x, &wrect.y,
1145 &wrect.w, &wrect.h);
1147 /* translate coordinates relative to root window */
1148 XTranslateCoordinates(_ecore_x_disp, window, root,
1149 0, 0, &wrect.x, &wrect.y, &tw);
1151 for (i = 0; i < ncrtcs; i++)
1153 XRRCrtcInfo *info = NULL;
1155 /* try to get crtc info */
1156 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
1158 /* check if crtc is enabled */
1159 if (info->mode != 0)
1161 /* enabled. get geometry */
1164 crect.w = info->width;
1165 crect.h = info->height;
1167 /* check intersection with window */
1168 if (eina_rectangles_intersect(&wrect, &crect))
1170 /* add if intersect */
1171 ret[nret] = crtcs[i];
1176 /* free the crtc info */
1177 XRRFreeCrtcInfo(info);
1181 /* free the resources */
1182 XRRFreeScreenResources(res);
1184 if (num) *num = nret;
1196 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
1197 * @brief get the CRTCs, which display a certain window
1198 * @param window window the displaying crtcs shall be found for
1199 * @param num the number of crtcs displaying the window
1200 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
1201 * was found that displays the specified window.
1203 EAPI Ecore_X_Randr_Crtc *
1204 ecore_x_randr_current_crtc_get(Ecore_X_Window window, int *num)
1206 return ecore_x_randr_window_crtcs_get(window, num);
1210 * @brief get a CRTC's outputs.
1211 * @param root the root window which's screen will be queried
1212 * @param num number of outputs referenced by given CRTC
1214 EAPI Ecore_X_Randr_Output *
1215 ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num)
1219 XRRScreenResources *res = NULL;
1221 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1223 /* try to get the screen resources from Xrandr */
1224 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1226 XRRCrtcInfo *info = NULL;
1227 Ecore_X_Randr_Output *ret = NULL;
1229 /* try to get crtc info */
1230 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1232 /* if we have no outputs, return NULL */
1233 if (info->noutput == 0)
1235 /* free the crtc info */
1236 XRRFreeCrtcInfo(info);
1238 /* free the resources */
1239 XRRFreeScreenResources(res);
1244 /* try to allocate our return struct */
1245 if ((ret = malloc(info->noutput * sizeof(Ecore_X_Randr_Output))))
1249 /* loop the outputs on this crtc */
1250 for (i = 0; i < info->noutput; i++)
1251 ret[i] = info->outputs[i];
1253 if (num) *num = info->noutput;
1256 /* free the crtc info */
1257 XRRFreeCrtcInfo(info);
1260 /* free the resources */
1261 XRRFreeScreenResources(res);
1270 * @brief get a CRTC's possible outputs.
1271 * @param root the root window which's screen will be queried
1272 * @param num number of possible outputs referenced by given CRTC
1274 EAPI Ecore_X_Randr_Output *
1275 ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num)
1279 XRRScreenResources *res = NULL;
1281 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1283 /* try to get the screen resources from Xrandr */
1284 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1286 XRRCrtcInfo *info = NULL;
1287 Ecore_X_Randr_Output *ret = NULL;
1289 /* try to get crtc info */
1290 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1292 if (info->npossible == 0)
1294 /* free the crtc info */
1295 XRRFreeCrtcInfo(info);
1297 /* free the resources */
1298 XRRFreeScreenResources(res);
1303 /* try to allocate our return struct */
1304 if ((ret = malloc(info->npossible * sizeof(Ecore_X_Randr_Output))))
1308 /* loop the outputs on this crtc */
1309 for (i = 0; i < info->npossible; i++)
1310 ret[i] = info->possible[i];
1312 if (num) *num = info->npossible;
1315 /* free the crtc info */
1316 XRRFreeCrtcInfo(info);
1319 /* free the resources */
1320 XRRFreeScreenResources(res);
1329 ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
1332 XRRScreenResources *res = NULL;
1334 if (_randr_version < RANDR_VERSION_1_2) return;
1336 /* try to get the screen resources from Xrandr */
1337 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1339 XRRCrtcInfo *info = NULL;
1341 /* try to get crtc info */
1342 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1344 if (x) *x = info->x;
1345 if (y) *y = info->y;
1346 if (w) *w = info->width;
1347 if (h) *h = info->height;
1349 /* free the crtc info */
1350 XRRFreeCrtcInfo(info);
1353 /* free the resources */
1354 XRRFreeScreenResources(res);
1360 ecore_x_randr_crtc_pos_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y)
1363 if (_randr_version < RANDR_VERSION_1_2) return;
1365 ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
1370 * @brief Sets the position of given CRTC within root window's screen.
1372 * @param root The window's screen to be queried.
1373 * @param crtc The CRTC which's position within the mentioned screen is to be
1375 * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
1376 * value will be kept.
1377 * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
1378 * value will be kept.
1379 * @return @c EINA_TRUE if position could successfully be altered.
1382 ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y)
1385 int cx = 0, cy = 0, cw = 0, ch = 0;
1386 int sw = 0, sh = 0, nw = 0, nh = 0;
1388 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1390 /* grab the current crtc geometry */
1391 ecore_x_randr_crtc_geometry_get(root, crtc, &cx, &cy, &cw, &ch);
1393 /* grab the current screen geometry */
1394 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
1396 /* safety check some values */
1399 if ((x + cw) > sw) nw = (x + cw);
1400 if ((y + ch) > sh) nh = (y + ch);
1402 if ((nw > 0) && (nh > 0))
1404 /* try to update the current screen geometry */
1405 if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0))
1409 /* try to set the new crtc position */
1410 return ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1);
1416 * @brief Get the current set mode of a given CRTC
1417 * @param root the window's screen to be queried
1418 * @param crtc the CRTC which's should be queried
1419 * @return currently set mode or - in case parameters are invalid -
1420 * Ecore_X_Randr_Unset
1422 EAPI Ecore_X_Randr_Mode
1423 ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1426 XRRScreenResources *res = NULL;
1428 if (_randr_version < RANDR_VERSION_1_2) return -1;
1430 /* try to get the screen resources from Xrandr */
1431 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1433 XRRCrtcInfo *info = NULL;
1434 Ecore_X_Randr_Mode ret = -1;
1436 /* try to get crtc info */
1437 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1442 /* free the crtc info */
1443 XRRFreeCrtcInfo(info);
1446 /* free the resources */
1447 XRRFreeScreenResources(res);
1456 * @brief Sets a mode for a CRTC and the outputs attached to it.
1458 * @param root The window's screen to be queried.
1459 * @param crtc The CRTC which shall be set.
1460 * @param outputs Array of outputs which have to be compatible with the mode.
1461 * If @c NULL, CRTC will be disabled.
1462 * @param noutputs Number of outputs in array to be used. Use
1463 * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
1464 * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
1465 * disabled. If set to @c -1 the call will fail.
1466 * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
1470 ecore_x_randr_crtc_mode_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, Ecore_X_Randr_Mode mode)
1473 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1475 return ecore_x_randr_crtc_settings_set(root, crtc, outputs, noutputs,
1482 ecore_x_randr_crtc_size_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *w, int *h)
1485 if (_randr_version < RANDR_VERSION_1_2) return;
1486 ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
1490 EAPI Ecore_X_Randr_Refresh_Rate
1491 ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc EINA_UNUSED, Ecore_X_Randr_Mode mode)
1494 XRRScreenResources *res = NULL;
1496 if (_randr_version < RANDR_VERSION_1_2) return 0.0;
1498 /* try to get the screen resources from Xrandr */
1499 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1504 for (i = 0; i < res->nmode; i++)
1506 if (res->modes[i].id == mode)
1508 if ((res->modes[i].hTotal) && (res->modes[i].vTotal))
1510 ret = ((double)res->modes[i].dotClock /
1511 ((double)res->modes[i].hTotal *
1512 (double)res->modes[i].vTotal));
1518 /* free the resources */
1519 XRRFreeScreenResources(res);
1527 EAPI Ecore_X_Randr_Orientation
1528 ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1531 XRRScreenResources *res = NULL;
1533 if (_randr_version < RANDR_VERSION_1_2) return 0;
1535 /* try to get the screen resources from Xrandr */
1536 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1538 XRRCrtcInfo *info = NULL;
1539 Ecore_X_Randr_Orientation ret = 0;
1541 /* try to get crtc info */
1542 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1545 ret = info->rotations;
1547 /* free the crtc info */
1548 XRRFreeCrtcInfo(info);
1551 /* free the resources */
1552 XRRFreeScreenResources(res);
1560 EAPI Ecore_X_Randr_Orientation
1561 ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1564 XRRScreenResources *res = NULL;
1566 if (_randr_version < RANDR_VERSION_1_2) return 0;
1568 /* try to get the screen resources from Xrandr */
1569 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1571 XRRCrtcInfo *info = NULL;
1572 Ecore_X_Randr_Orientation ret = 0;
1574 /* try to get crtc info */
1575 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1578 ret = info->rotation;
1580 /* free the crtc info */
1581 XRRFreeCrtcInfo(info);
1584 /* free the resources */
1585 XRRFreeScreenResources(res);
1594 ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Orientation orientation)
1597 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1599 if (orientation != 0)
1600 return ecore_x_randr_crtc_settings_set(root, crtc, NULL,
1601 -1, -1, -1, -1, orientation);
1607 ecore_x_randr_crtc_clone_set(Ecore_X_Window root, Ecore_X_Randr_Crtc original, Ecore_X_Randr_Crtc cln)
1610 Eina_Bool ret = EINA_FALSE;
1611 XRRScreenResources *res = NULL;
1613 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1615 /* try to get the screen resources from Xrandr */
1616 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1618 XRRCrtcInfo *info = NULL;
1619 Ecore_X_Randr_Orientation orig_orient = 0;
1620 Ecore_X_Randr_Mode orig_mode = -1;
1623 /* try to get crtc info for original crtc */
1624 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, original)))
1628 orig_orient = info->rotation;
1629 orig_mode = info->mode;
1631 /* free the crtc info */
1632 XRRFreeCrtcInfo(info);
1635 ret = ecore_x_randr_crtc_settings_set(root, cln, NULL, -1, ox, oy,
1636 orig_mode, orig_orient);
1638 /* free the resources */
1639 XRRFreeScreenResources(res);
1648 * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
1649 * auto enabled in it's preferred mode, when it was disabled before.
1651 * @param root The root window which's default display will be queried.
1652 * @param crtc The CRTC which's configuration should be altered.
1653 * @param outputs An array of outputs, that should display this CRTC's content.
1654 * @param noutputs Number of outputs in the array of outputs. If set to
1655 * Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
1656 * If set to Ecore_X_Randr_None, CRTC will be disabled.
1657 * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
1658 * corrdinate will be assumed.
1659 * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
1660 * corrdinate will be assumed.
1661 * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
1662 * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
1664 * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
1665 * used, the current mode is assumed.
1666 * @return @c EINA_TRUE if the configuration alteration was successful,
1667 * @c EINA_FALSE otherwise.
1670 ecore_x_randr_crtc_settings_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, int x, int y, Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orientation)
1673 Eina_Bool ret = EINA_FALSE;
1674 XRRScreenResources *res = NULL;
1676 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1678 /* try to get the screen resources from Xrandr */
1679 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1682 RROutput *routputs = NULL;
1683 XRRCrtcInfo *info = NULL;
1684 Eina_Bool need_free = EINA_FALSE;
1687 rcrtc = (RRCrtc)crtc;
1689 /* try to get crtc info for original crtc */
1690 if (!(info = XRRGetCrtcInfo(_ecore_x_disp, res, rcrtc)))
1692 /* free the resources */
1693 XRRFreeScreenResources(res);
1697 if ((int)mode == -1) mode = info->mode;
1698 if ((int)orientation == -1) orientation = info->rotation;
1699 if (x < 0) x = info->x;
1700 if (y < 0) y = info->y;
1704 noutputs = info->noutput;
1707 routputs = malloc(noutputs * sizeof(RROutput));
1708 for (i = 0; i < noutputs; i++)
1709 routputs[i] = info->outputs[i];
1710 need_free = EINA_TRUE;
1713 else if (noutputs > 0)
1715 routputs = malloc(noutputs * sizeof(RROutput));
1716 for (i = 0; i < noutputs; i++)
1717 routputs[i] = (RROutput)outputs[i];
1718 need_free = EINA_TRUE;
1721 /* try to set the crtc config */
1722 if (!XRRSetCrtcConfig(_ecore_x_disp, res, rcrtc, CurrentTime,
1723 x, y, mode, orientation,
1724 routputs, noutputs))
1727 if (need_free) free(routputs);
1729 /* free the crtc info */
1730 XRRFreeCrtcInfo(info);
1732 /* free the resources */
1733 XRRFreeScreenResources(res);
1742 * @brief Sets a CRTC relative to another one.
1744 * @param root The root window which's default display will be set.
1745 * @param crtc_r1 The CRTC to be positioned.
1746 * @param crtc_r2 The CRTC the position should be relative to.
1747 * @param policy The relation between the crtcs.
1748 * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
1750 * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
1751 * if repositioning failed or if position of new crtc would be out of given
1752 * screen's min/max bounds.
1755 ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc_r1, Ecore_X_Randr_Crtc crtc_r2, Ecore_X_Randr_Output_Policy policy, Ecore_X_Randr_Relative_Alignment alignment)
1758 Eina_Rectangle r1, r2;
1759 int mw = 0, mh = 0, sw = 0, sh = 0;
1762 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1764 /* check each crtc has a valid mode */
1765 if (ecore_x_randr_crtc_mode_get(root, crtc_r1) == 0) return EINA_FALSE;
1766 if (ecore_x_randr_crtc_mode_get(root, crtc_r2) == 0) return EINA_FALSE;
1768 /* get the geometry of each crtc */
1769 ecore_x_randr_crtc_geometry_get(root, crtc_r1, &r1.x, &r1.y, &r1.w, &r1.h);
1770 ecore_x_randr_crtc_geometry_get(root, crtc_r2, &r2.x, &r2.y, &r2.w, &r2.h);
1772 /* get the geometry of the screen */
1773 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh);
1774 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
1778 case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
1783 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1786 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1787 ny = ((int)(((double)r2.h / 2.0) + r2.y - ((double)r1.h / 2.0)));
1789 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1790 ny = ((int)((double)sh / 2.0) - ((double)r1.h / 2.0));
1795 case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
1800 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1803 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1804 ny = ((int)(((double)r2.h / 2.0) + r2.y - ((double)r1.h / 2.0)));
1806 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1807 ny = ((int)((double)sh / 2.0) - ((double)r1.h / 2.0));
1812 case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
1817 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1820 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1821 nx = ((int)((((double)r2.x + (double)r2.w) / 2.0) -
1822 ((double)r1.w / 2.0)));
1824 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1825 nx = ((int)((double)sw / 2.0));
1830 case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
1835 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1838 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1839 nx = ((int)((((double)r2.x + (double)r2.w) / 2.0) -
1840 ((double)r1.w / 2.0)));
1842 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1843 nx = ((int)((double)sw / 2.0));
1848 case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
1849 return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2.x, r2.y);
1851 case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
1857 if ((nx == r1.x) && (ny == r1.y)) return EINA_TRUE;
1858 if (((ny + r1.h) > mh) || ((nx + r1.w) > mw)) return EINA_FALSE;
1860 return ecore_x_randr_crtc_pos_set(root, crtc_r1, nx, ny);
1869 EAPI Ecore_X_Randr_Crtc_Info *
1870 ecore_x_randr_crtc_info_get(Ecore_X_Window root, const Ecore_X_Randr_Crtc crtc)
1873 XRRScreenResources *res = NULL;
1875 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1877 /* try to get the screen resources from Xrandr */
1878 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1880 XRRCrtcInfo *info = NULL;
1881 Ecore_X_Randr_Crtc_Info *ret = NULL;
1883 /* try to get crtc info */
1884 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1886 if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc_Info))))
1888 /* copy the mode information into our return structure */
1889 ret->timestamp = info->timestamp;
1892 ret->width = info->width;
1893 ret->height = info->height;
1894 ret->mode = info->mode;
1895 ret->rotation = info->rotation;
1896 ret->rotations = info->rotations;
1897 ret->noutput = info->noutput;
1898 ret->npossible = info->npossible;
1900 ret->outputs = NULL;
1901 ret->possible = NULL;
1903 if (info->noutput > 0)
1906 malloc(info->noutput * sizeof(Ecore_X_Randr_Output))))
1910 /* loop the outputs on this crtc */
1911 for (i = 0; i < info->noutput; i++)
1912 ret->outputs[i] = info->outputs[i];
1916 if (info->npossible > 0)
1918 if ((ret->possible =
1919 malloc(info->npossible * sizeof(Ecore_X_Randr_Output))))
1923 /* loop the outputs on this crtc */
1924 for (i = 0; i < info->npossible; i++)
1925 ret->possible[i] = info->possible[i];
1930 /* free the crtc info */
1931 XRRFreeCrtcInfo(info);
1934 /* free the resources */
1935 XRRFreeScreenResources(res);
1947 ecore_x_randr_crtc_info_free(Ecore_X_Randr_Crtc_Info *info)
1950 if (_randr_version >= RANDR_VERSION_1_2)
1954 if (info->outputs) free(info->outputs);
1955 if (info->possible) free(info->possible);
1963 * @brief Add given mode to given output.
1965 * @param output The output the mode is added to.
1966 * @param mode The mode added to the output.
1967 * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
1969 * Additionally, if xcb backend is used, the success of the addition is
1970 * reported back directly.
1974 ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
1977 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1979 if ((output) && (mode))
1981 /* add this mode to output
1983 * NB: This XRR function returns void so we have to assume it worked */
1984 XRRAddOutputMode(_ecore_x_disp, output, mode);
1993 * @brief delete given mode from given output
1994 * @param output the output the mode is removed from
1995 * @param mode the mode removed from the output
1999 ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
2002 if (_randr_version < RANDR_VERSION_1_2) return;
2004 if ((!output) || (!mode)) return;
2006 XRRDeleteOutputMode(_ecore_x_disp, output, mode);
2010 EAPI Ecore_X_Randr_Mode *
2011 ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred)
2014 XRRScreenResources *res = NULL;
2016 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2018 /* try to get the screen resources from Xrandr */
2019 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2021 XRROutputInfo *info = NULL;
2022 Ecore_X_Randr_Mode *modes = NULL;
2024 /* try to get output info */
2025 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2027 if (num) *num = info->nmode;
2028 if (npreferred) *npreferred = info->npreferred;
2030 if (info->nmode > 0)
2032 if ((modes = malloc(info->nmode * sizeof(Ecore_X_Randr_Mode))))
2036 for (i = 0; i < info->nmode; i++)
2037 modes[i] = info->modes[i];
2041 /* free the output info */
2042 XRRFreeOutputInfo(info);
2045 /* free the resources */
2046 XRRFreeScreenResources(res);
2055 * @brief gets the the outputs which might be used simultenously on the same
2057 * @param root window that this information should be queried for.
2058 * @param output the output which's clones we concern
2059 * @param num number of possible clones
2061 EAPI Ecore_X_Randr_Output *
2062 ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
2065 XRRScreenResources *res = NULL;
2067 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2069 /* try to get the screen resources from Xrandr */
2070 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2072 XRROutputInfo *info = NULL;
2073 Ecore_X_Randr_Output *outputs = NULL;
2075 /* try to get output info */
2076 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2078 if (num) *num = info->nclone;
2080 if (info->nclone > 0)
2082 /* try to allocate space for output return */
2083 if ((outputs = malloc(info->nclone * sizeof(Ecore_X_Randr_Output))))
2087 for (i = 0; i < info->nclone; i++)
2088 outputs[i] = info->clones[i];
2092 /* free the output info */
2093 XRRFreeOutputInfo(info);
2096 /* free the resources */
2097 XRRFreeScreenResources(res);
2105 EAPI Ecore_X_Randr_Crtc *
2106 ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
2109 XRRScreenResources *res = NULL;
2111 if (_randr_version < RANDR_VERSION_1_2) return 0;
2113 /* try to get the screen resources from Xrandr */
2114 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2116 XRROutputInfo *info = NULL;
2117 Ecore_X_Randr_Crtc *crtcs = NULL;
2119 /* try to get output info */
2120 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2122 if (num) *num = info->ncrtc;
2124 if (info->ncrtc > 0)
2126 /* try to allocate space for the return crtcs */
2127 if ((crtcs = malloc(info->ncrtc * sizeof(Ecore_X_Randr_Crtc))))
2131 for (i = 0; i < info->ncrtc; i++)
2132 crtcs[i] = info->crtcs[i];
2136 /* free the output info */
2137 XRRFreeOutputInfo(info);
2140 /* free the resources */
2141 XRRFreeScreenResources(res);
2149 EAPI Ecore_X_Randr_Crtc
2150 ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2153 XRRScreenResources *res = NULL;
2155 if (_randr_version < RANDR_VERSION_1_2) return 0;
2157 /* try to get the screen resources from Xrandr */
2158 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2160 XRROutputInfo *info = NULL;
2161 Ecore_X_Randr_Crtc ret = 0;
2163 /* try to get output info */
2164 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2168 /* free the output info */
2169 XRRFreeOutputInfo(info);
2172 /* free the resources */
2173 XRRFreeScreenResources(res);
2182 * @brief gets the given output's name as reported by X
2183 * @param root the window which's screen will be queried
2184 * @param output The output for which the name will be reported.
2185 * @param len length of returned c-string.
2186 * @return name of the output as reported by X
2189 ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len)
2192 XRRScreenResources *res = NULL;
2194 if (_randr_version < RANDR_VERSION_1_2) return 0;
2196 /* try to get the screen resources from Xrandr */
2197 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2199 XRROutputInfo *info = NULL;
2202 /* try to get output info */
2203 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2211 /* pre 1.4.0 does not fill in info->nameLen */
2212 s = strlen(info->name);
2214 ret = malloc(s + 1);
2215 memcpy(ret, info->name, s);
2220 /* free the output info */
2221 XRRFreeOutputInfo(info);
2224 /* free the resources */
2225 XRRFreeScreenResources(res);
2234 * @deprecated use ecore_x_randr_crtc_gamma_size_get()
2236 EINA_DEPRECATED EAPI int
2237 ecore_x_randr_crtc_gamma_ramp_size_get(Ecore_X_Randr_Crtc crtc EINA_UNUSED)
2243 * @deprecated use ecore_x_randr_crtc_gamma_get()
2245 EINA_DEPRECATED EAPI Ecore_X_Randr_Crtc_Gamma **
2246 ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc EINA_UNUSED)
2252 * @deprecated use ecore_x_randr_crtc_gamma_set()
2254 EINA_DEPRECATED EAPI Eina_Bool
2255 ecore_x_randr_crtc_gamma_ramps_set(Ecore_X_Randr_Crtc crtc EINA_UNUSED, const Ecore_X_Randr_Crtc_Gamma *red EINA_UNUSED, const Ecore_X_Randr_Crtc_Gamma *green EINA_UNUSED, const Ecore_X_Randr_Crtc_Gamma *blue EINA_UNUSED)
2264 ecore_x_randr_crtc_gamma_size_get(Ecore_X_Randr_Crtc crtc)
2267 if (_randr_version < RANDR_VERSION_1_2) return 0;
2268 return XRRGetCrtcGammaSize(_ecore_x_disp, crtc);
2278 EAPI Ecore_X_Randr_Crtc_Gamma_Info *
2279 ecore_x_randr_crtc_gamma_get(Ecore_X_Randr_Crtc crtc)
2282 Ecore_X_Randr_Crtc_Gamma_Info *info = NULL;
2283 XRRCrtcGamma *xgamma = NULL;
2285 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2287 /* try to get the gamma for this crtc from Xrandr */
2288 if (!(xgamma = XRRGetCrtcGamma(_ecore_x_disp, crtc)))
2291 /* try to allocate space for the return struct and copy the results in */
2292 if ((info = malloc(sizeof(Ecore_X_Randr_Crtc_Gamma_Info))))
2293 memcpy(info, xgamma, sizeof(Ecore_X_Randr_Crtc_Gamma_Info));
2295 /* free the returned gamma resource */
2296 XRRFreeGamma(xgamma);
2309 ecore_x_randr_crtc_gamma_set(Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Crtc_Gamma_Info *gamma)
2312 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2314 /* try to set the gamma
2316 * NB: XRRSetCrtcGamma returns void
2318 XRRSetCrtcGamma(_ecore_x_disp, crtc, (XRRCrtcGamma *)gamma);
2328 ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, const Ecore_X_Randr_Crtc *not_moved, int nnot_moved, int dx, int dy)
2331 XRRScreenResources *res = NULL;
2332 Eina_Bool ret = EINA_FALSE;
2334 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2336 if ((nnot_moved <= 0) || (!not_moved)) return EINA_FALSE;
2338 /* try to get the screen resources from Xrandr */
2339 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2341 Ecore_X_Randr_Crtc *crtcs = NULL;
2344 n = (res->ncrtc - nnot_moved);
2347 /* try to allocate space for a list of crtcs */
2348 if ((crtcs = malloc(n * sizeof(Ecore_X_Randr_Crtc))))
2350 int i = 0, j = 0, k = 0;
2352 for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
2354 for (j = 0; j < nnot_moved; j++)
2356 if (res->crtcs[i] == not_moved[j])
2360 if (j == nnot_moved) crtcs[k++] = res->crtcs[i];
2365 /* free the resources */
2366 XRRFreeScreenResources(res);
2368 /* actually move the crtcs */
2371 ret = ecore_x_randr_move_crtcs(root, crtcs, n, dx, dy);
2382 * @brief Move given CRTCs belonging to the given root window's screen dx/dy
2383 * pixels relative to their current position. The screen size will be
2384 * automatically adjusted if necessary and possible.
2386 * @param root Window which's screen's resources are used.
2387 * @param crtcs List of CRTCs to be moved.
2388 * @param ncrtc Number of CRTCs in array.
2389 * @param dx Amount of pixels the CRTCs should be moved in x direction.
2390 * @param dy Amount of pixels the CRTCs should be moved in y direction.
2391 * @return @c EINA_TRUE if all crtcs could be moved successfully.
2394 ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int ncrtc, int dx, int dy)
2397 XRRScreenResources *res = NULL;
2398 XRRCrtcInfo **info = NULL;
2401 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2403 if (ncrtc < 1) return EINA_FALSE;
2405 /* try to get the screen resources from Xrandr */
2406 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2408 Eina_Bool ret = EINA_TRUE;
2409 int mw = 0, mh = 0, sw = 0, sh = 0;
2412 info = alloca(ncrtc * sizeof(XRRCrtcInfo *));
2413 memset(info, 0, ncrtc * sizeof(XRRCrtcInfo *));
2415 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh);
2416 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
2420 for (i = 0; i < ncrtc; i++)
2422 /* try to get crtc info for original crtc */
2423 if ((info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
2425 if (((info[i]->x + dx) < 0) || ((info[i]->y + dy < 0)) ||
2426 ((int)(info[i]->x + info[i]->width) > mw) ||
2427 ((int)(info[i]->y + info[i]->height) > mh))
2432 nw = MAX(((int)(info[i]->x + info[i]->width) + dx), nw);
2433 nh = MAX(((int)(info[i]->y + info[i]->height) + dy), nh);
2437 /* resize the screen if we need to */
2438 if (!(((nw > sw) || (nh > sh)) ||
2439 ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)))
2442 /* actually move the crtcs */
2443 for (i = 0; ((i < ncrtc) && info[i]); i++)
2445 if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
2458 /* something went wrong somewhere. move everything back */
2462 ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
2471 for (i = 0; i < ncrtc; i++)
2472 if (info[i]) XRRFreeCrtcInfo(info[i]);
2474 /* free the resources */
2475 XRRFreeScreenResources(res);
2483 /* free the crtc info */
2484 if (info[i]) XRRFreeCrtcInfo(info[i]);
2487 /* free the resources */
2488 if (res) XRRFreeScreenResources(res);
2494 * @brief gets the width and hight of a given mode
2495 * @param mode the mode whose size is to be looked up
2496 * @param w width of given mode in px
2497 * @param h height of given mode in px
2500 ecore_x_randr_mode_size_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode, int *w, int *h)
2503 if (_randr_version < RANDR_VERSION_1_2) return;
2505 if ((mode != 0) && ((w) || (h)))
2507 XRRScreenResources *res = NULL;
2509 /* try to get the screen resources from Xrandr */
2510 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2514 for (i = 0; i < res->nmode; i++)
2516 if (res->modes[i].id == mode)
2518 if (w) *w = res->modes[i].width;
2519 if (h) *h = res->modes[i].height;
2524 /* free the resources */
2525 XRRFreeScreenResources(res);
2531 EAPI Ecore_X_Randr_Connection_Status
2532 ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2535 XRRScreenResources *res = NULL;
2537 if (_randr_version < RANDR_VERSION_1_2)
2538 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2540 /* try to get the screen resources from Xrandr */
2541 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2543 XRROutputInfo *info = NULL;
2544 Ecore_X_Randr_Connection_Status ret =
2545 ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2547 /* try to get output info */
2548 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2550 ret = info->connection;
2552 /* free the output info */
2553 XRRFreeOutputInfo(info);
2556 /* free the resources */
2557 XRRFreeScreenResources(res);
2562 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2566 ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w, int *h)
2569 XRRScreenResources *res = NULL;
2571 if (_randr_version < RANDR_VERSION_1_2) return;
2573 /* try to get the screen resources from Xrandr */
2574 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2576 XRROutputInfo *info = NULL;
2578 /* try to get output info */
2579 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2581 if (w) *w = info->mm_width;
2582 if (h) *h = info->mm_height;
2584 /* free the output info */
2585 XRRFreeOutputInfo(info);
2588 /* free the resources */
2589 XRRFreeScreenResources(res);
2595 ecore_x_randr_output_crtc_set(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output EINA_UNUSED, const Ecore_X_Randr_Crtc crtc EINA_UNUSED)
2602 ecore_x_randr_output_backlight_available(void)
2605 Atom backlight = None;
2607 /* check for new backlight property */
2608 if ((backlight = XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True)))
2611 /* check for legacy backlight property */
2612 if ((backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True)))
2619 * @brief Set up the backlight level to the given level.
2621 * @param root The window's screen which will be set.
2622 * @param level Of the backlight between @c 0 and @c 1.
2625 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level)
2628 XRRScreenResources *res = NULL;
2631 if (_randr_version < RANDR_VERSION_1_3) return;
2633 /* try to get the screen resources from Xrandr */
2634 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2636 /* set the backlight level on each output */
2637 for (i = 0; i < res->noutput; i++)
2638 ecore_x_randr_output_backlight_level_set(root, res->outputs[i], level);
2640 /* free the resources */
2641 XRRFreeScreenResources(res);
2647 ecore_x_randr_output_backlight_level_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
2650 XRRPropertyInfo *info = NULL;
2651 Atom backlight = None, type = None;
2652 unsigned long bytes = 0;
2653 unsigned long items = 0;
2654 unsigned char *prop = NULL;
2658 /* check if "new" backlight is available */
2659 if (_randr_version >= RANDR_VERSION_1_3)
2662 XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True)))
2664 XRRGetOutputProperty(_ecore_x_disp, output, backlight, 0, 4,
2665 False, False, None, &type, &format,
2666 &items, &bytes, &prop);
2670 if ((!prop) || (items == 0))
2672 /* check legacy backlight property
2674 * FIXME: NB: Not sure what randr version we need for the legacy
2675 * backlight property so skip version check */
2676 if ((backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True)))
2680 XRRGetOutputProperty(_ecore_x_disp, output, backlight, 0, 4,
2681 False, False, None, &type, &format,
2682 &items, &bytes, &prop);
2687 if ((!prop) || (type != XA_INTEGER) || (items != 1) || (format != 32))
2690 WRN("Backlight property is not supported on this server or driver");
2694 val = *((long *)prop);
2697 /* try to get the backlight property value from Xrandr */
2698 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, backlight)))
2702 if ((info->range) && (info->num_values == 2))
2704 /* convert the current value */
2705 ret = ((double)(val - info->values[0])) /
2706 ((double)(info->values[1] - info->values[0]));
2719 ecore_x_randr_output_backlight_level_set(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, double level)
2722 XRRPropertyInfo *info = NULL;
2723 Atom backlight = None;
2725 /* safety check some input values */
2726 if ((level < 0) || (level > 1))
2728 ERR("Backlight level should be between 0 and 1");
2732 /* check if "new" backlight is available */
2733 if (_randr_version >= RANDR_VERSION_1_3)
2734 backlight = XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True);
2737 backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True);
2741 WRN("Backlight property is not supported on this server or driver");
2745 /* try to get the output property from Xrandr */
2746 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, backlight)))
2748 Eina_Bool ret = EINA_FALSE;
2750 if ((info->range) && (info->num_values == 2))
2752 double min = 0.0, max = 0.0;
2755 min = info->values[0];
2756 max = info->values[1];
2757 val = (level * (max - min)) + min;
2758 if (val > max) val = max;
2759 if (val < min) val = min;
2761 /* tell xrandr to change the backlight value */
2762 XRRChangeOutputProperty(_ecore_x_disp, output, backlight,
2763 XA_INTEGER, 32, PropModeReplace,
2764 (unsigned char *)&val, 1);
2766 /* send changes to X */
2782 * @brief gets the EDID information of an attached output if available.
2783 * Note that this information is not to be compared using ordinary string
2784 * comparison functions, since it includes 0-bytes.
2785 * @param root window this information should be queried from
2786 * @param output the XID of the output
2787 * @param length length of the byte-array. If NULL, request will fail.
2789 EAPI unsigned char *
2790 ecore_x_randr_output_edid_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, unsigned long *length)
2793 Atom edid = None, type = None;
2794 unsigned char *prop = NULL;
2796 unsigned long nitems = 0, bytes = 0;
2798 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2800 /* try to get the edid atom */
2801 if (!(edid = XInternAtom(_ecore_x_disp, RR_PROPERTY_RANDR_EDID, False)))
2804 /* get the output property
2806 * NB: Returns 0 on success */
2807 if (!XRRGetOutputProperty(_ecore_x_disp, output, edid, 0, 128, False, False,
2808 AnyPropertyType, &type, &format, &nitems,
2811 if ((type == XA_INTEGER) && (nitems >= 1) && (format == 8))
2813 unsigned char *ret = NULL;
2815 if ((ret = malloc(nitems * sizeof(unsigned char))))
2817 if (length) *length = nitems;
2818 memcpy(ret, prop, (nitems * sizeof(unsigned char)));
2829 EAPI Ecore_X_Render_Subpixel_Order
2830 ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2833 XRRScreenResources *res = NULL;
2835 if (_randr_version < RANDR_VERSION_1_2)
2836 return ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN;
2838 /* try to get the screen resources from Xrandr */
2839 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2841 XRROutputInfo *info = NULL;
2842 Ecore_X_Render_Subpixel_Order ret = 0;
2844 /* try to get output info */
2845 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2847 ret = info->subpixel_order;
2849 /* free the output info */
2850 XRRFreeOutputInfo(info);
2853 /* free the resources */
2854 XRRFreeScreenResources(res);
2859 return ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN;
2862 /***************************************
2863 * API Functions for RandR version 1.3 *
2864 ***************************************/
2866 EAPI Ecore_X_Randr_Output *
2867 ecore_x_randr_output_wired_clones_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2870 Atom clones = None, type = None;
2871 unsigned char *prop = NULL;
2873 unsigned long nitems = 0, bytes = 0;
2877 * I am not sure that this code is correct. This needs checking
2880 if (_randr_version < RANDR_VERSION_1_3) return NULL;
2882 /* try to get the edid atom */
2883 if (!(clones = XInternAtom(_ecore_x_disp, RR_PROPERTY_CLONE_LIST, True)))
2886 /* get the output property
2888 * NB: Returns 0 on success */
2889 if (!XRRGetOutputProperty(_ecore_x_disp, output, clones, 0, 100, False, False,
2890 AnyPropertyType, &type, &format, &nitems,
2893 if ((type == XA_ATOM) && (nitems >= 1) && (format == 32))
2895 Ecore_X_Randr_Output *ret = NULL;
2897 if ((ret = malloc(nitems * sizeof(Ecore_X_Randr_Output))))
2899 if (num) *num = nitems;
2900 memcpy(ret, prop, (nitems * sizeof(Ecore_X_Randr_Output)));
2911 EAPI Ecore_X_Randr_Output **
2912 ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output EINA_UNUSED, int *num EINA_UNUSED)
2914 /* TODO: (1.3) !! */
2915 //RR_PROPERTY_COMPATIBILITY_LIST
2919 EAPI Ecore_X_Randr_Signal_Format *
2920 ecore_x_randr_output_signal_formats_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2923 XRRPropertyInfo *info = NULL;
2925 unsigned long bytes = 0;
2926 unsigned long items = 0;
2927 unsigned char *prop = NULL;
2930 if (_randr_version < RANDR_VERSION_1_3) return NULL;
2932 /* try to get the connector number atom */
2933 if (!(sig = XInternAtom(_ecore_x_disp, RR_PROPERTY_SIGNAL_FORMAT, True)))
2936 /* try to get the output property from Xrandr
2938 * NB: Returns 0 on success */
2939 if (XRRGetOutputProperty(_ecore_x_disp, output, sig, 0, 100,
2940 False, False, AnyPropertyType, &type, &format,
2941 &items, &bytes, &prop))
2944 printf("Signal Format property not supported.\n");
2951 if ((type != XA_ATOM) || (items < 1) || (format != 32))
2954 /* try to get the output property from Xrandr */
2955 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, sig)))
2957 Ecore_X_Randr_Signal_Format *formats = NULL;
2959 if (num) *num = info->num_values;
2961 if (info->num_values > 0)
2964 malloc(info->num_values * sizeof(Ecore_X_Randr_Signal_Format))))
2966 memcpy(formats, info->values,
2967 (info->num_values * sizeof(Ecore_X_Randr_Signal_Format)));
2981 ecore_x_randr_output_signal_format_set(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output EINA_UNUSED, Ecore_X_Randr_Signal_Format *sig EINA_UNUSED)
2983 /* TODO: (1.3) !! */
2984 //RR_PROPERTY_SIGNAL_FORMAT
2988 EAPI Ecore_X_Randr_Signal_Property *
2989 ecore_x_randr_output_signal_properties_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2992 XRRPropertyInfo *info = NULL;
2994 unsigned long bytes = 0;
2995 unsigned long items = 0;
2996 unsigned char *prop = NULL;
2999 if (_randr_version < RANDR_VERSION_1_3) return NULL;
3001 /* try to get the connector number atom */
3002 if (!(sig = XInternAtom(_ecore_x_disp, RR_PROPERTY_SIGNAL_PROPERTIES, True)))
3005 /* try to get the output property from Xrandr
3007 * NB: Returns 0 on success */
3008 if (XRRGetOutputProperty(_ecore_x_disp, output, sig, 0, 100,
3009 False, False, AnyPropertyType, &type, &format,
3010 &items, &bytes, &prop))
3013 printf("Signal Properties property not supported.\n");
3020 if ((type != XA_ATOM) || (items < 1) || (format != 32))
3023 /* try to get the output property from Xrandr */
3024 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, sig)))
3026 Ecore_X_Randr_Signal_Property *props = NULL;
3028 if (num) *num = info->num_values;
3030 if (info->num_values > 0)
3033 malloc(info->num_values * sizeof(Ecore_X_Randr_Signal_Property))))
3035 memcpy(props, info->values,
3036 (info->num_values * sizeof(Ecore_X_Randr_Signal_Property)));
3057 * 3 == (typically) TV Connector but is driver/hardware dependent
3061 ecore_x_randr_output_connector_number_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
3064 XRRPropertyInfo *info = NULL;
3066 unsigned long bytes = 0;
3067 unsigned long items = 0;
3068 unsigned char *prop = NULL;
3069 int val = 0, format = 0;
3071 if (_randr_version < RANDR_VERSION_1_3) return -1;
3073 /* try to get the output property from Xrandr
3075 * NB: Returns 0 on success */
3076 if (XRRGetOutputProperty(_ecore_x_disp, output, connector_number, 0, 100,
3077 False, False, AnyPropertyType, &type, &format,
3078 &items, &bytes, &prop))
3081 printf("ConnectionNumber property not supported.\n");
3086 if ((type != XA_INTEGER) || (items != 1) || (format != 32))
3092 val = *((int *)prop);
3095 /* try to get the output property from Xrandr */
3096 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, connector_number)))
3100 /* convert the current value */
3101 ret = (int)(val - info->values[0]);
3112 EAPI Ecore_X_Randr_Connector_Type
3113 ecore_x_randr_output_connector_type_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
3116 XRRPropertyInfo *info = NULL;
3118 unsigned long bytes = 0;
3119 unsigned long items = 0;
3120 unsigned char *prop = NULL;
3121 int val = 0, format = 0;
3123 if (_randr_version < RANDR_VERSION_1_3) return -1;
3125 /* try to get the connector type atom */
3126 if (XRRGetOutputProperty(_ecore_x_disp, output, connector_type, 0, 100,
3127 False, False, AnyPropertyType, &type, &format,
3128 &items, &bytes, &prop) != Success)
3134 if ((!prop) || (items == 0))
3139 /* NB: some butthead drivers (*cough* nouveau *cough*) do not
3140 * implement randr properly. They are not using the connector type
3141 * property of randr, but rather a "subconnector" property */
3142 if ((conn = XInternAtom(_ecore_x_disp, "subconnector", True)))
3143 XRRGetOutputProperty(_ecore_x_disp, output, conn, 0, 4,
3144 False, False, AnyPropertyType, &type,
3145 &format, &items, &bytes, &prop);
3148 if ((!prop) || (items == 0))
3151 WRN("ConnectorType Property not supported.");
3156 if ((type != XA_ATOM) || (items != 1) || (format != 32))
3159 val = *((int *)prop);
3162 /* try to get the output property from Xrandr */
3163 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, connector_type)))
3167 /* convert the current value */
3168 ret = (int)(val - info->values[0]);
3170 /* printf("\tReturn Value: %d\n", ret); */
3171 /* printf("\t\tActual Name: %s\n", */
3172 /* XGetAtomName(_ecore_x_disp, ((Atom)info->values[ret]))); */
3183 EAPI Ecore_X_Randr_Output
3184 ecore_x_randr_primary_output_get(Ecore_X_Window root)
3187 if (_randr_version < RANDR_VERSION_1_3) return 0;
3188 return XRRGetOutputPrimary(_ecore_x_disp, root);
3195 ecore_x_randr_primary_output_set(Ecore_X_Window root, Ecore_X_Randr_Output output)
3198 if (_randr_version < RANDR_VERSION_1_3) return;
3199 XRRSetOutputPrimary(_ecore_x_disp, root, output);
3203 /***************************************
3204 * API Functions for RandR version 1.4 *
3205 ***************************************/
3208 ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3211 XRRScreenResources *res = NULL;
3213 if (_randr_version < RANDR_VERSION_1_4) return;
3215 /* try to get the screen resources from Xrandr */
3216 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3218 XRRPanning *xpan = NULL;
3220 /* get this crtc's panning */
3221 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3223 if (x) *x = xpan->left;
3224 if (y) *y = xpan->top;
3225 if (w) *w = xpan->width;
3226 if (h) *h = xpan->height;
3228 /* free the panning resource */
3229 XRRFreePanning(xpan);
3231 /* free the resources */
3232 XRRFreeScreenResources(res);
3238 ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const int x, const int y, const int w, const int h)
3241 XRRScreenResources *res = NULL;
3242 Eina_Bool ret = EINA_FALSE;
3244 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3246 /* try to get the screen resources from Xrandr */
3247 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3249 XRRPanning *xpan = NULL;
3251 /* get this crtc's panning */
3252 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3258 xpan->timestamp = CurrentTime;
3260 /* set the panning value */
3261 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3264 /* free the panning resource */
3265 XRRFreePanning(xpan);
3268 /* free the resources */
3269 XRRFreeScreenResources(res);
3279 ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3282 XRRScreenResources *res = NULL;
3284 if (_randr_version < RANDR_VERSION_1_4) return;
3286 /* try to get the screen resources from Xrandr */
3287 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3289 XRRPanning *xpan = NULL;
3291 /* get this crtc's panning */
3292 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3294 if (x) *x = xpan->track_left;
3295 if (y) *y = xpan->track_top;
3296 if (w) *w = xpan->track_width;
3297 if (h) *h = xpan->track_height;
3299 /* free the panning resource */
3300 XRRFreePanning(xpan);
3302 /* free the resources */
3303 XRRFreeScreenResources(res);
3309 ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const int x, const int y, const int w, const int h)
3312 XRRScreenResources *res = NULL;
3313 Eina_Bool ret = EINA_FALSE;
3315 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3317 /* try to get the screen resources from Xrandr */
3318 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3320 XRRPanning *xpan = NULL;
3322 /* get this crtc's panning */
3323 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3325 xpan->track_left = x;
3326 xpan->track_top = y;
3327 xpan->track_width = w;
3328 xpan->track_height = h;
3329 xpan->timestamp = CurrentTime;
3331 /* set the panning value */
3332 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3335 /* free the panning resource */
3336 XRRFreePanning(xpan);
3339 /* free the resources */
3340 XRRFreeScreenResources(res);
3350 ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3353 XRRScreenResources *res = NULL;
3355 if (_randr_version < RANDR_VERSION_1_4) return;
3357 /* try to get the screen resources from Xrandr */
3358 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3360 XRRPanning *xpan = NULL;
3362 /* get this crtc's panning */
3363 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3365 if (x) *x = xpan->border_left;
3366 if (y) *y = xpan->border_top;
3367 if (w) *w = xpan->border_right;
3368 if (h) *h = xpan->border_bottom;
3370 /* free the panning resource */
3371 XRRFreePanning(xpan);
3373 /* free the resources */
3374 XRRFreeScreenResources(res);
3380 ecore_x_randr_crtc_border_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const int left, const int top, const int right, const int bottom)
3383 XRRScreenResources *res = NULL;
3384 Eina_Bool ret = EINA_FALSE;
3386 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3388 /* try to get the screen resources from Xrandr */
3389 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3391 XRRPanning *xpan = NULL;
3393 /* get this crtc's panning */
3394 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3396 xpan->border_left = left;
3397 xpan->border_top = top;
3398 xpan->border_right = right;
3399 xpan->border_bottom = bottom;
3400 xpan->timestamp = CurrentTime;
3402 /* set the panning value */
3403 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3406 /* free the panning resource */
3407 XRRFreePanning(xpan);
3410 /* free the resources */
3411 XRRFreeScreenResources(res);
3420 /***************************************
3421 * API Functions for RandR Edid
3422 ***************************************/
3425 ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length)
3427 const unsigned char header[] =
3428 { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
3430 if (!edid) return EINA_FALSE;
3431 if (edid_length < 8) return EINA_FALSE;
3432 if (!memcmp(edid, header, 8)) return EINA_TRUE;
3437 ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length)
3440 unsigned char *iter = NULL;
3442 int i = 0, version = 0;
3444 if (edid_length < 128) return EINA_FALSE;
3446 version = ecore_x_randr_edid_version_get(edid, edid_length);
3447 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3449 for (i = 0; i < 128; i++)
3452 if (sum) return EINA_FALSE;
3454 /* check extension blocks */
3455 for (iter = edid; iter < (edid + edid_length); iter += 128)
3457 if (iter[0] == 0x02)
3459 for (i = 0, sum = 0; i < 128; i++)
3464 if (sum) return EINA_FALSE;
3472 ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
3475 if ((edid_length > RANDR_EDID_VERSION_MINOR) &&
3476 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3478 return (edid[RANDR_EDID_VERSION_MAJOR] << 8) |
3479 edid[RANDR_EDID_VERSION_MINOR];
3482 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3489 ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length)
3492 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3493 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3498 if (!(name = malloc(sizeof(char) * 4))) return NULL;
3500 x = (edid + RANDR_EDID_MANUFACTURER);
3501 name[0] = ((x[0] & 0x7c) >> 2) + '@';
3502 name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@';
3503 name[2] = (x[1] & 0x1f) + '@';
3513 ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length)
3516 unsigned char *block = NULL;
3519 version = ecore_x_randr_edid_version_get(edid, edid_length);
3520 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3522 for (block = (edid + RANDR_EDID_BLOCK);
3523 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3525 if ((block[0] == 0) && (block[1] == 0))
3527 if (block[3] == 0xfc)
3530 const char *edid_name;
3532 edid_name = (const char *)block + 5;
3533 if (!(name = malloc(14))) return NULL;
3534 strncpy(name, edid_name, 13);
3537 for (p = name; *p; p++)
3538 if ((*p < ' ') || (*p > '~')) *p = 0;
3549 ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length)
3552 unsigned char *block = NULL;
3555 version = ecore_x_randr_edid_version_get(edid, edid_length);
3556 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3558 for (block = (edid + RANDR_EDID_BLOCK);
3559 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3561 if ((block[0] == 0) && (block[1] == 0))
3563 if (block[3] == 0xfe)
3565 char *ascii = NULL, *p = NULL;
3566 const char *edid_ascii;
3568 edid_ascii = (const char *)block + 5;
3570 if (!(ascii = malloc(14))) return NULL;
3571 strncpy(ascii, edid_ascii, 13);
3573 for (p = ascii; *p; p++)
3574 if ((*p < ' ') || (*p > '~')) *p = 0;
3585 ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length)
3588 unsigned char *block = NULL;
3591 version = ecore_x_randr_edid_version_get(edid, edid_length);
3592 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3594 for (block = (edid + RANDR_EDID_BLOCK);
3595 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3597 if ((block[0] == 0) && (block[1] == 0))
3599 if (block[3] == 0xff)
3601 char *serial = NULL, *p = NULL;
3602 const char *edid_serial;
3604 edid_serial = (const char *)block + 5;
3606 if (!(serial = malloc(14))) return NULL;
3607 strncpy(serial, edid_serial, 13);
3609 for (p = serial; *p; p++)
3610 if ((*p < ' ') || (*p > '~')) *p = 0;
3621 ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length)
3623 return ecore_x_randr_edid_manufacturer_model_get(edid, edid_length);
3627 ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length)
3630 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3631 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3632 return (int)(edid[0x0c] + (edid[0x0d] << 8) +
3633 (edid[0x0e] << 16) + (edid[0x0f] << 24));
3635 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3642 ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length)
3645 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3646 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3647 return (int)(edid[0x0a] + (edid[0x0b] << 8));
3649 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3653 ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length)
3658 version = ecore_x_randr_edid_version_get(edid, edid_length);
3659 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3661 return !!(edid[0x18] & 0xE0);
3668 ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length)
3673 version = ecore_x_randr_edid_version_get(edid, edid_length);
3674 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3676 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x80);
3682 ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length)
3687 version = ecore_x_randr_edid_version_get(edid, edid_length);
3688 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3690 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x40);
3696 ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length)
3701 version = ecore_x_randr_edid_version_get(edid, edid_length);
3702 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3704 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x20);
3709 EAPI Ecore_X_Randr_Edid_Aspect_Ratio
3710 ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length)
3713 unsigned char *block = NULL;
3716 version = ecore_x_randr_edid_version_get(edid, edid_length);
3717 if (version < RANDR_EDID_VERSION_1_3)
3718 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3720 for (block = (edid + RANDR_EDID_BLOCK);
3721 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3723 if ((block[0] == 0) && (block[1] == 0))
3725 if ((block[3] == 0xfd) && (block[10] == 0x04))
3727 Ecore_X_Randr_Edid_Aspect_Ratio_Preferred ratio =
3728 (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred)((block[15] & 0xe0) >> 5);
3732 case RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3:
3733 return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
3734 case RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9:
3735 return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
3736 case RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10:
3737 return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
3738 case RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4:
3739 return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
3740 case RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9:
3741 return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
3743 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3749 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3755 EAPI Ecore_X_Randr_Edid_Aspect_Ratio
3756 ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length)
3759 Ecore_X_Randr_Edid_Aspect_Ratio ret;
3760 unsigned char *block = NULL;
3763 ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3765 version = ecore_x_randr_edid_version_get(edid, edid_length);
3766 if (version < RANDR_EDID_VERSION_1_3)
3767 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3769 for (block = (edid + RANDR_EDID_BLOCK);
3770 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3772 if ((block[0] == 0) && (block[1] == 0))
3774 if ((block[3] == 0xfd) && (block[10] == 0x04))
3776 if (block[14] & 0x80)
3777 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
3778 if (block[14] & 0x40)
3779 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
3780 if (block[14] & 0x20)
3781 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
3782 if (block[14] & 0x10)
3783 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
3784 if (block[14] & 0x08)
3785 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
3796 EAPI Ecore_X_Randr_Edid_Display_Colorscheme
3797 ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length)
3800 Ecore_X_Randr_Edid_Display_Colorscheme ret;
3803 ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3805 version = ecore_x_randr_edid_version_get(edid, edid_length);
3806 if (version < RANDR_EDID_VERSION_1_3)
3807 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3809 if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length))
3811 ret = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4;
3812 if (edid[0x18] & 0x10)
3813 ret |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4;
3814 if (edid[0x18] & 0x08)
3815 ret |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2;
3818 ret = (edid[0x18] & 0x18);
3827 ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length)
3832 version = ecore_x_randr_edid_version_get(edid, edid_length);
3833 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3835 return !!(edid[0x14] & 0x80);
3841 EAPI Ecore_X_Randr_Edid_Display_Interface_Type
3842 ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length)
3845 Ecore_X_Randr_Edid_Display_Interface_Type type;
3848 type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3850 version = ecore_x_randr_edid_version_get(edid, edid_length);
3851 if (version < RANDR_EDID_VERSION_1_3)
3852 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3854 type = (edid[0x14] & 0x0f);
3855 if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT)
3856 type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;