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;
21 # define RANDR_VERSION_1_1 ((1 << 16) | 1)
22 # define RANDR_VERSION_1_2 ((1 << 16) | 2)
23 # define RANDR_VERSION_1_3 ((1 << 16) | 3)
24 # define RANDR_VERSION_1_4 ((1 << 16) | 4)
26 # define RANDR_EDID_VERSION_1_3 ((1 << 8) | 3)
27 # define RANDR_EDID_VERSION_MAJOR 0x12
28 # define RANDR_EDID_VERSION_MINOR 0x13
30 # define RANDR_EDID_MANUFACTURER 0x08
31 # define RANDR_EDID_BLOCK 0x36
33 typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred
35 RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00,
36 RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01,
37 RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02,
38 RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03,
39 RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04
40 } Ecore_X_Randr_Edid_Aspect_Ratio_Preferred;
42 static int _randr_major, _randr_minor, _randr_version;
44 XRRScreenResources *(*_ecore_x_randr_screen_resources_get)(Display *disp, Window win);
50 _ecore_x_randr_init(void)
57 /* try to query the randr extenstion version */
58 if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
60 _randr_version = (_randr_major << 16) | _randr_minor;
62 if (_randr_version >= RANDR_VERSION_1_3)
63 _ecore_x_randr_screen_resources_get = XRRGetScreenResourcesCurrent;
64 else if (_randr_version == RANDR_VERSION_1_2)
65 _ecore_x_randr_screen_resources_get = XRRGetScreenResources;
67 _randr_avail = EINA_TRUE;
72 /* public functions */
74 ecore_x_randr_version_get(void)
77 if (_randr_avail) return _randr_version;
83 ecore_x_randr_query(void)
89 * @brief This function returns the current config timestamp from
90 * XRRScreenConfiguration.
92 * @params root root window to query screen configuration from
94 * @returns The screen configuration timestamp
99 ecore_x_randr_config_timestamp_get(Ecore_X_Window root)
101 Ecore_X_Time timestamp = 0;
104 XRRScreenConfiguration *cfg;
106 /* try to get the screen configuration from Xrandr */
107 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
111 XRRConfigTimes(cfg, &tm);
113 timestamp = (Ecore_X_Time)tm;
115 /* free any returned screen config */
116 if (cfg) XRRFreeScreenConfigInfo(cfg);
123 /***************************************
124 * API Functions for RandR version 1.1 *
125 ***************************************/
128 * @param root window which's primary output will be queried
130 EAPI Ecore_X_Randr_Orientation
131 ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root)
134 Rotation ret = 0, crot = 0;
136 /* get the rotations available from XRandr */
137 ret = XRRRotations(_ecore_x_disp,
138 XRRRootToScreen(_ecore_x_disp, root), &crot);
147 * @param root window which's primary output will be queried
148 * @return the current orientation of the root window's screen primary output
150 EAPI Ecore_X_Randr_Orientation
151 ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root)
156 /* get the current rotation available from XRandr */
157 XRRRotations(_ecore_x_disp,
158 XRRRootToScreen(_ecore_x_disp, root), &ret);
167 * @brief Sets a given screen's primary output's orientation.
169 * @param root Window which's screen's primary output will be queried.
170 * @param orientation orientation which should be set for the root window's
171 * screen primary output.
172 * @return @c EINA_TRUE if the primary output's orientation could be
173 * successfully altered.
176 ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orient)
179 Eina_Bool ret = EINA_FALSE;
181 XRRScreenConfiguration *cfg = NULL;
184 /* try to get the screen config from XRandr */
185 if (!(cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
188 /* get the screen's current size id */
189 id = XRRConfigCurrentConfiguration(cfg, &crot);
191 /* attempt to set the new orientation */
192 if (!XRRSetScreenConfig(_ecore_x_disp, cfg, root, id, orient, CurrentTime))
195 /* free any returned screen config */
196 if (cfg) XRRFreeScreenConfigInfo(cfg);
205 * @brief gets a screen's primary output's possible sizes
206 * @param root window which's primary output will be queried
207 * @param num number of sizes reported as supported by the screen's primary output
208 * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL
210 EAPI Ecore_X_Randr_Screen_Size_MM *
211 ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num)
215 Ecore_X_Randr_Screen_Size_MM *ret = NULL;
216 XRRScreenSize *sizes;
219 /* retrieve the number of sizes from X, and the sizes themselves.
221 * NB: don't have to free the returned sizes */
222 sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
223 if (!sizes) return NULL;
224 if (n <= 0) return NULL;
226 /* try to allocate our structure for these sizes */
227 if (!(ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM))))
232 /* fill in our allocated structure with the screen sizes */
233 for (i = 0; i < n; i++)
235 ret[i].width = sizes[i].width;
236 ret[i].height = sizes[i].height;
237 ret[i].width_mm = sizes[i].mwidth;
238 ret[i].height_mm = sizes[i].mheight;
248 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)
251 XRRScreenConfiguration *cfg = NULL;
253 /* try to get the screen config from XRandr */
254 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
256 XRRScreenSize *sizes;
260 /* retrieve the number of sizes from X, and the sizes themselves.
262 * NB: don't have to free the returned sizes */
264 XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
265 if ((sizes) && (n > 0))
269 /* get the index of the current configuration */
270 idx = XRRConfigCurrentConfiguration(cfg, &crot);
272 /* if the index is valid, then fill in the return variables with
273 * the size information for this index */
274 if ((idx < n) && (idx >= 0))
276 if (w) *w = sizes[idx].width;
277 if (h) *h = sizes[idx].height;
278 if (w_mm) *w_mm = sizes[idx].mwidth;
279 if (h_mm) *h_mm = sizes[idx].mheight;
280 if (size_index) *size_index = idx;
284 /* free the returned screen config */
285 XRRFreeScreenConfigInfo(cfg);
291 * @brief Sets a given screen's primary output size, but disables all other
292 * outputs at the same time.
294 * @param root Window which's primary output will be queried.
295 * @param size_index Within the list of sizes reported as supported by the root
296 * window's screen primary output.
297 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g.
301 ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index)
304 Eina_Bool ret = EINA_FALSE;
307 /* check for valid size index first */
308 if (size_index < 0) return EINA_FALSE;
310 /* get the number of sizes from XRandr */
311 XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
313 /* make sure the requested index is below the number returned from randr */
316 XRRScreenConfiguration *cfg = NULL;
318 /* try to get the screen config from XRandr */
319 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
321 /* try to set the new screen config
323 * NB: Returns Success (0) if it works */
324 if (!XRRSetScreenConfig(_ecore_x_disp, cfg, root, size_index,
325 ECORE_X_RANDR_ORIENTATION_ROT_0,
331 /* free the returned screen config */
332 XRRFreeScreenConfigInfo(cfg);
343 * @param root window which's primary output will be queried
344 * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0
346 EAPI Ecore_X_Randr_Refresh_Rate
347 ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root)
350 XRRScreenConfiguration *cfg = NULL;
352 /* try to get the screen config from XRandr */
353 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
355 Ecore_X_Randr_Refresh_Rate ret = 0.0;
357 /* try to get the current refresh rate */
358 ret = XRRConfigCurrentRate(cfg);
360 /* free the returned screen config */
361 XRRFreeScreenConfigInfo(cfg);
370 * @param root window which's primary output will be queried
371 * @param size_index referencing the size to query valid refresh rates for
372 * @return currently used refresh rate or - if request failed or RandRR is not available - NULL
374 EAPI Ecore_X_Randr_Refresh_Rate *
375 ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num)
378 Ecore_X_Randr_Refresh_Rate *rates = NULL;
381 /* try to get the refresh rates for this screen */
382 if ((rates = XRRRates(_ecore_x_disp,
383 XRRRootToScreen(_ecore_x_disp, root), size_index, &n)))
385 Ecore_X_Randr_Refresh_Rate *ret = NULL;
387 if (n == 0) return NULL;
389 /* try to allocate space for the return */
390 if ((ret = malloc(n * sizeof(Ecore_X_Randr_Refresh_Rate))))
394 /* fill in our return values */
395 for (i = 0; i < n; i++)
408 * @brief Sets the current primary output's refresh rate.
410 * @param root Window which's primary output will be queried.
411 * @param size_index Referencing the size to be set.
412 * @param rate The refresh rate to be set.
413 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
416 ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, int size_index, Ecore_X_Randr_Refresh_Rate rate)
419 if (_randr_version >= RANDR_VERSION_1_1)
421 XRRScreenConfiguration *cfg = NULL;
423 /* try to get the screen config from XRandr */
424 if ((cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
426 Eina_Bool ret = EINA_FALSE;
429 /* get the current rotation */
430 XRRConfigRotations(cfg, &rot);
432 /* try to set the new screen config
434 * NB: Returns Success (0) if it works */
435 if (!XRRSetScreenConfigAndRate(_ecore_x_disp, cfg, root,
436 size_index, rot, rate, CurrentTime))
441 /* free the returned screen config */
442 XRRFreeScreenConfigInfo(cfg);
451 /***************************************
452 * API Functions for RandR version 1.2 *
453 ***************************************/
456 * @brief Enable event selection. This enables basic interaction with
457 * output/crtc events and requires RandR >= 1.2.
459 * @param win Select this window's properties for RandR events.
460 * @param on Enable/disable selecting.
463 ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on)
470 mask = RRScreenChangeNotifyMask;
471 if (_randr_version >= RANDR_VERSION_1_2)
472 mask |= (RRCrtcChangeNotifyMask | RROutputChangeNotifyMask |
473 RROutputPropertyNotifyMask);
476 /* tell randr what events we want to listen to for this window */
477 XRRSelectInput(_ecore_x_disp, win, mask);
482 * @param w width of screen in px
483 * @param h height of screen in px
486 ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm)
489 if (_randr_version >= RANDR_VERSION_1_2)
493 /* get the screen number */
494 scr = XRRRootToScreen(_ecore_x_disp, root);
496 if (w) *w = DisplayWidth(_ecore_x_disp, scr);
497 if (h) *h = DisplayHeight(_ecore_x_disp, scr);
498 if (w_mm) *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
499 if (h_mm) *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
505 * @param root window which's screen will be queried
506 * @param wmin minimum width the screen can be set to
507 * @param hmin minimum height the screen can be set to
508 * @param wmax maximum width the screen can be set to
509 * @param hmax maximum height the screen can be set to
512 ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax)
515 if (_randr_version >= RANDR_VERSION_1_2)
517 int swmin = 0, shmin = 0, swmax = 0, shmax = 0;
519 /* try to get the screen size range from XRandr
521 * NB: returns 1 on success */
522 if ((XRRGetScreenSizeRange(_ecore_x_disp, root, &swmin, &shmin,
525 /* fill in the return variables */
526 if (wmin) *wmin = swmin;
527 if (hmin) *hmin = shmin;
528 if (wmax) *wmax = swmax;
529 if (hmax) *hmax = shmax;
536 * @brief removes unused screen space. The most upper left CRTC is set to 0x0
537 * and all other CRTCs dx,dy respectively.
538 * @param root the window's screen which will be reset.
541 ecore_x_randr_screen_reset(Ecore_X_Window root)
544 XRRScreenResources *res = NULL;
546 if (_randr_version < RANDR_VERSION_1_2) return;
548 /* try to get the screen resources from Xrandr */
549 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
553 Ecore_X_Randr_Crtc crtcs[res->ncrtc];
554 int i = 0, nenabled = 0;
556 int dx = 100000, dy = 100000;
558 for (i = 0; i < res->ncrtc; i++)
560 XRRCrtcInfo *info = NULL;
562 /* try to get the crtc info from Xrandr */
563 if (!(info = XRRGetCrtcInfo(_ecore_x_disp, res, res->crtcs[i])))
567 if ((info->mode <= 0) || (info->noutput == 0))
569 /* free the crtc info */
570 XRRFreeCrtcInfo(info);
575 crtcs[nenabled++] = res->crtcs[i];
577 if ((int)(info->x + info->width) > nw)
578 nw = (info->x + info->width);
580 if ((int)(info->y + info->height) > nh)
581 nh = (info->y + info->height);
583 if (info->x < dx) dx = info->x;
584 if (info->y < dy) dy = info->y;
586 /* free the crtc info */
587 XRRFreeCrtcInfo(info);
590 /* free the resources */
591 XRRFreeScreenResources(res);
593 if ((dx > 0) || (dy > 0))
595 if (ecore_x_randr_move_crtcs(root, crtcs, nenabled, -dx, -dy))
602 ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1);
609 * @param root Window which's screen's size should be set. If invalid (e.g.
610 * @c NULL) no action is taken.
611 * @param w Width in px the screen should be set to. If out of valid
612 * boundaries, current value is assumed.
613 * @param h Height in px the screen should be set to. If out of valid
614 * boundaries, current value is assumed.
615 * @param w_mm Width in mm the screen should be set to. If @c 0, current
617 * @param h_mm Height in mm the screen should be set to. If @c 0, current
619 * @return @c EINA_TRUE if request was successfully sent or screen is already
620 * in requested size, @c EINA_FALSE if parameters are invalid.
623 ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm)
626 if (_randr_version >= RANDR_VERSION_1_2)
628 int cw = 0, ch = 0, cwmm = 0, chmm = 0;
629 int wmin = 0, hmin = 0, wmax = 0, hmax = 0;
631 /* get the current screen size */
632 ecore_x_randr_screen_current_size_get(root, &cw, &ch, &cwmm, &chmm);
634 /* compare to the values passed in. if there are no changes, get out */
635 if ((w == cw) && (h == ch) && (w_mm == cwmm) && (h_mm == chmm))
638 /* get the current size range */
639 ecore_x_randr_screen_size_range_get(root, &wmin, &hmin, &wmax, &hmax);
641 /* compare to the values passed in. make sure they are within range */
642 if ((w != 0) && ((w < wmin) || (w > wmax))) return EINA_FALSE;
643 if ((h != 0) && ((h < hmin) || (h > hmax))) return EINA_FALSE;
645 /* safety check some values */
649 w_mm = (int)(((double)(cwmm / (double)cw)) * (double)w);
651 h_mm = (int)(((double)(chmm / (double)ch)) * (double)h);
653 /* tell XRandr to set screen size */
654 XRRSetScreenSize(_ecore_x_disp, root, w, h, w_mm, h_mm);
663 * @brief get detailed information for all modes related to a root window's screen
664 * @param root window which's screen's ressources are queried
665 * @param num number of modes returned
666 * @return modes' information
668 EAPI Ecore_X_Randr_Mode_Info **
669 ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num)
673 XRRScreenResources *res = NULL;
675 if (_randr_version < RANDR_VERSION_1_2) return NULL;
677 /* try to get the screen resources from Xrandr */
678 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
680 Ecore_X_Randr_Mode_Info **ret = NULL;
682 /* set the returned number of modes */
683 if (num) *num = res->nmode;
685 /* if we did not get any modes from X, then cleanup and return */
688 /* free the resources */
689 XRRFreeScreenResources(res);
694 /* try to allocate space for our return variable */
695 if ((ret = (Ecore_X_Randr_Mode_Info **)
696 malloc(res->nmode * sizeof(Ecore_X_Randr_Mode_Info *))))
700 /* loop through all the modes and assign to our return var */
701 for (i = 0; i < res->nmode; i++)
703 if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
705 ret[i]->xid = res->modes[i].id;
706 ret[i]->width = res->modes[i].width;
707 ret[i]->height = res->modes[i].height;
708 ret[i]->dotClock = res->modes[i].dotClock;
709 ret[i]->hSyncStart = res->modes[i].hSyncStart;
710 ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
711 ret[i]->hTotal = res->modes[i].hTotal;
712 ret[i]->hSkew = res->modes[i].hSkew;
713 ret[i]->vSyncStart = res->modes[i].vSyncStart;
714 ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
715 ret[i]->vTotal = res->modes[i].vTotal;
716 if (res->modes[i].nameLength > 0)
719 (malloc(res->modes[i].nameLength + 1))))
720 strncpy(ret[i]->name, res->modes[i].name,
721 (res->modes[i].nameLength + 1));
728 ret[i]->nameLength = res->modes[i].nameLength;
729 ret[i]->modeFlags = res->modes[i].modeFlags;
742 /* free the resources */
743 XRRFreeScreenResources(res);
752 * @brief Add a mode to a display.
754 * @param root Window to which's screen's ressources are added.
756 * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
760 EAPI Ecore_X_Randr_Mode
761 ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info)
764 if (_randr_version >= RANDR_VERSION_1_2)
766 Ecore_X_Randr_Mode mode = 0;
768 /* if we have valid mode_info from the user, then ask XRandr to
769 * create the new mode using that as base */
771 mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo *)mode_info);
780 * @brief Delete a mode from the display.
786 ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode)
789 if (_randr_version >= RANDR_VERSION_1_2)
790 XRRDestroyMode(_ecore_x_disp, mode);
795 * @brief get detailed information for a given mode id
796 * @param root window which's screen's ressources are queried
797 * @param mode the XID which identifies the mode of interest
798 * @return mode's detailed information
800 EAPI Ecore_X_Randr_Mode_Info *
801 ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode)
804 XRRScreenResources *res = NULL;
806 if (_randr_version < RANDR_VERSION_1_2) return NULL;
808 /* try to get the screen resources from Xrandr */
809 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
811 Ecore_X_Randr_Mode_Info *ret = NULL;
816 /* free the resources */
817 XRRFreeScreenResources(res);
822 /* loop the mode informations and find the one we want */
823 for (i = 0; i < res->nmode; i++)
825 /* compare mode ids */
826 if (res->modes[i].id != mode) continue;
828 /* try to allocate our return mode information structure */
829 if (!(ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
832 /* copy the mode information into our return structure */
833 ret->xid = res->modes[i].id;
834 ret->width = res->modes[i].width;
835 ret->height = res->modes[i].height;
836 ret->dotClock = res->modes[i].dotClock;
837 ret->hSyncStart = res->modes[i].hSyncStart;
838 ret->hSyncEnd = res->modes[i].hSyncEnd;
839 ret->hTotal = res->modes[i].hTotal;
840 ret->hSkew = res->modes[i].hSkew;
841 ret->vSyncStart = res->modes[i].vSyncStart;
842 ret->vSyncEnd = res->modes[i].vSyncEnd;
843 ret->vTotal = res->modes[i].vTotal;
844 ret->modeFlags = res->modes[i].modeFlags;
847 if (res->modes[i].nameLength > 0)
849 ret->nameLength = res->modes[i].nameLength;
850 if ((ret->name = malloc(res->modes[i].nameLength + 1)))
851 strncpy(ret->name, res->modes[i].name,
852 (res->modes[i].nameLength + 1));
857 /* free the resources */
858 XRRFreeScreenResources(res);
867 * @brief Free detailed mode information. The pointer handed in will be set to
868 * @c NULL after freeing the memory.
870 * @param mode_info The mode information that should be freed.
873 ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
876 if (_randr_version >= RANDR_VERSION_1_2)
880 if (mode_info->name) free(mode_info->name);
889 * @brief Get all known CRTCs related to a root window's screen.
891 * @param root Window which's screen's ressources are queried.
892 * @param num Number of CRTCs returned.
895 EAPI Ecore_X_Randr_Crtc *
896 ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num)
900 XRRScreenResources *res = NULL;
902 if (_randr_version < RANDR_VERSION_1_2) return NULL;
904 /* try to get the screen resources from Xrandr */
905 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
907 Ecore_X_Randr_Crtc *ret = NULL;
911 /* free the resources */
912 XRRFreeScreenResources(res);
917 /* try to allocate space for our return variable */
918 if ((ret = malloc(res->ncrtc * sizeof(Ecore_X_Randr_Crtc))))
922 if (num) *num = res->ncrtc;
924 /* copy the crtc information into our return variable */
925 for (i = 0; i < res->ncrtc; i++)
926 ret[i] = res->crtcs[i];
929 /* free the resources */
930 XRRFreeScreenResources(res);
938 EAPI Ecore_X_Randr_Output *
939 ecore_x_randr_outputs_get(Ecore_X_Window root, int *num)
943 XRRScreenResources *res = NULL;
945 if (_randr_version < RANDR_VERSION_1_2) return NULL;
947 /* try to get the screen resources from Xrandr */
948 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
950 Ecore_X_Randr_Output *ret = NULL;
952 if (res->noutput == 0)
954 /* free the resources */
955 XRRFreeScreenResources(res);
960 /* try to allocate space for our return variable */
961 if ((ret = malloc(res->noutput * sizeof(Ecore_X_Randr_Output))))
965 if (num) *num = res->noutput;
967 /* copy the output information into our return variable */
968 for (i = 0; i < res->noutput; i++)
969 ret[i] = res->outputs[i];
972 /* free the resources */
973 XRRFreeScreenResources(res);
982 * @brief Get the outputs, which display a certain window.
984 * @param window Window the displaying outputs shall be found for
985 * @param num The number of outputs displaying the window
986 * @return Array of outputs that display a certain window. @c NULL if no
987 * outputs was found that displays the specified window.
989 EAPI Ecore_X_Randr_Output *
990 ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num)
995 Ecore_X_Randr_Crtc *crtcs = NULL;
998 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1000 /* grab this windows root window */
1001 root = ecore_x_window_root_get(window);
1003 /* get the crtcs from xrandr */
1004 if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
1006 XRRScreenResources *res = NULL;
1007 Ecore_X_Randr_Output *ret = NULL;
1009 /* try to get the screen resources from Xrandr
1011 * NB: We do this ONCE here as we reuse it for every crtc.
1012 * NB: The old code used to loop and fetch the screen resources on
1014 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1016 Ecore_X_Randr_Output *tret = NULL;
1017 int i = 0, nret = 0;
1019 /* for each crtc, get it's outputs */
1020 for (i = 0, nret = 0; i < ncrtcs; i++)
1022 XRRCrtcInfo *crtc = NULL;
1024 /* try to get the crtc info for this crtc */
1025 if (!(crtc = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
1028 /* try to reallocate our return variable */
1029 if ((tret = realloc(ret, ((nret + crtc->noutput) *
1030 sizeof(Ecore_X_Randr_Output)))))
1033 memcpy(&ret[nret], crtc->outputs,
1034 (crtc->noutput * sizeof(Ecore_X_Randr_Output)));
1035 nret += crtc->noutput;
1038 /* free the crtc info */
1039 XRRFreeCrtcInfo(crtc);
1042 if (num) *num = nret;
1044 /* free the resources */
1045 XRRFreeScreenResources(res);
1048 /* free any allocated crtcs from the get function */
1058 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
1059 * @brief Get the outputs, which display a certain window.
1061 * @param window Window the displaying outputs shall be found for.
1062 * @param num The number of outputs displaying the window.
1063 * @return Array of outputs that display a certain window. @c NULL if no
1064 * outputs was found that displays the specified window.
1066 EAPI Ecore_X_Randr_Output *
1067 ecore_x_randr_current_output_get(Ecore_X_Window window, int *num)
1069 return ecore_x_randr_window_outputs_get(window, num);
1073 * @brief get the CRTCs, which display a certain window
1074 * @param window window the displaying crtcs shall be found for
1075 * @param num the number of crtcs displaying the window
1076 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
1077 * was found that displays the specified window.
1080 EAPI Ecore_X_Randr_Crtc *
1081 ecore_x_randr_window_crtcs_get(Ecore_X_Window window, int *num)
1085 Ecore_X_Window root;
1086 Ecore_X_Randr_Crtc *crtcs = NULL;
1089 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1091 /* grab this windows root window */
1092 root = ecore_x_window_root_get(window);
1094 /* get the crtcs from xrandr */
1095 if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
1097 XRRScreenResources *res = NULL;
1098 Ecore_X_Randr_Crtc *ret = NULL;
1100 /* make sure we can allocate our return variable */
1101 if (!(ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc))))
1107 /* try to get the screen resources from Xrandr
1109 * NB: We do this ONCE here as we reuse it for every crtc.
1110 * NB: The old code used to loop and fetch the screen resources on
1112 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1115 Eina_Rectangle wrect, crect;
1116 int i = 0, nret = 0;
1118 /* get the geometry of this window */
1119 ecore_x_window_geometry_get(window, &wrect.x, &wrect.y,
1120 &wrect.w, &wrect.h);
1122 /* translate coordinates relative to root window */
1123 XTranslateCoordinates(_ecore_x_disp, window, root,
1124 0, 0, &wrect.x, &wrect.y, &tw);
1126 for (i = 0; i < ncrtcs; i++)
1128 XRRCrtcInfo *info = NULL;
1130 /* try to get crtc info */
1131 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
1133 /* check if crtc is enabled */
1134 if (info->mode != 0)
1136 /* enabled. get geometry */
1139 crect.w = info->width;
1140 crect.h = info->height;
1142 /* check intersection with window */
1143 if (eina_rectangles_intersect(&wrect, &crect))
1145 /* add if intersect */
1146 ret[nret] = crtcs[i];
1151 /* free the crtc info */
1152 XRRFreeCrtcInfo(info);
1156 /* free the resources */
1157 XRRFreeScreenResources(res);
1159 if (num) *num = nret;
1171 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
1172 * @brief get the CRTCs, which display a certain window
1173 * @param window window the displaying crtcs shall be found for
1174 * @param num the number of crtcs displaying the window
1175 * @return Array of crtcs that display a certain window. @c NULL if no crtcs
1176 * was found that displays the specified window.
1178 EAPI Ecore_X_Randr_Crtc *
1179 ecore_x_randr_current_crtc_get(Ecore_X_Window window, int *num)
1181 return ecore_x_randr_window_crtcs_get(window, num);
1185 * @brief get a CRTC's outputs.
1186 * @param root the root window which's screen will be queried
1187 * @param num number of outputs referenced by given CRTC
1189 EAPI Ecore_X_Randr_Output *
1190 ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num)
1194 XRRScreenResources *res = NULL;
1196 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1198 /* try to get the screen resources from Xrandr */
1199 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1201 XRRCrtcInfo *info = NULL;
1202 Ecore_X_Randr_Output *ret = NULL;
1204 /* try to get crtc info */
1205 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1207 /* if we have no outputs, return NULL */
1208 if (info->noutput == 0)
1210 /* free the crtc info */
1211 XRRFreeCrtcInfo(info);
1213 /* free the resources */
1214 XRRFreeScreenResources(res);
1219 /* try to allocate our return struct */
1220 if ((ret = malloc(info->noutput * sizeof(Ecore_X_Randr_Output))))
1224 /* loop the outputs on this crtc */
1225 for (i = 0; i < info->noutput; i++)
1226 ret[i] = info->outputs[i];
1228 if (num) *num = info->noutput;
1231 /* free the crtc info */
1232 XRRFreeCrtcInfo(info);
1235 /* free the resources */
1236 XRRFreeScreenResources(res);
1245 * @brief get a CRTC's possible outputs.
1246 * @param root the root window which's screen will be queried
1247 * @param num number of possible outputs referenced by given CRTC
1249 EAPI Ecore_X_Randr_Output *
1250 ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num)
1254 XRRScreenResources *res = NULL;
1256 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1258 /* try to get the screen resources from Xrandr */
1259 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1261 XRRCrtcInfo *info = NULL;
1262 Ecore_X_Randr_Output *ret = NULL;
1264 /* try to get crtc info */
1265 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1267 if (info->npossible == 0)
1269 /* free the crtc info */
1270 XRRFreeCrtcInfo(info);
1272 /* free the resources */
1273 XRRFreeScreenResources(res);
1278 /* try to allocate our return struct */
1279 if ((ret = malloc(info->npossible * sizeof(Ecore_X_Randr_Output))))
1283 /* loop the outputs on this crtc */
1284 for (i = 0; i < info->npossible; i++)
1285 ret[i] = info->possible[i];
1287 if (num) *num = info->npossible;
1290 /* free the crtc info */
1291 XRRFreeCrtcInfo(info);
1294 /* free the resources */
1295 XRRFreeScreenResources(res);
1304 ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
1307 XRRScreenResources *res = NULL;
1309 if (_randr_version < RANDR_VERSION_1_2) return;
1311 /* try to get the screen resources from Xrandr */
1312 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1314 XRRCrtcInfo *info = NULL;
1316 /* try to get crtc info */
1317 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1319 if (x) *x = info->x;
1320 if (y) *y = info->y;
1321 if (w) *w = info->width;
1322 if (h) *h = info->height;
1324 /* free the crtc info */
1325 XRRFreeCrtcInfo(info);
1328 /* free the resources */
1329 XRRFreeScreenResources(res);
1335 ecore_x_randr_crtc_pos_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y)
1338 if (_randr_version < RANDR_VERSION_1_2) return;
1340 ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
1345 * @brief Sets the position of given CRTC within root window's screen.
1347 * @param root The window's screen to be queried.
1348 * @param crtc The CRTC which's position within the mentioned screen is to be
1350 * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
1351 * value will be kept.
1352 * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
1353 * value will be kept.
1354 * @return @c EINA_TRUE if position could successfully be altered.
1357 ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y)
1360 int cx = 0, cy = 0, cw = 0, ch = 0;
1361 int sw = 0, sh = 0, nw = 0, nh = 0;
1363 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1365 /* grab the current crtc geometry */
1366 ecore_x_randr_crtc_geometry_get(root, crtc, &cx, &cy, &cw, &ch);
1368 /* grab the current screen geometry */
1369 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
1371 /* safety check some values */
1374 if ((x + cw) > sw) nw = (x + cw);
1375 if ((y + ch) > sh) nh = (y + ch);
1377 if ((nw > 0) && (nh > 0))
1379 /* try to update the current screen geometry */
1380 if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0))
1384 /* try to set the new crtc position */
1385 return ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1);
1391 * @brief Get the current set mode of a given CRTC
1392 * @param root the window's screen to be queried
1393 * @param crtc the CRTC which's should be queried
1394 * @return currently set mode or - in case parameters are invalid -
1395 * Ecore_X_Randr_Unset
1397 EAPI Ecore_X_Randr_Mode
1398 ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1401 XRRScreenResources *res = NULL;
1403 if (_randr_version < RANDR_VERSION_1_2) return -1;
1405 /* try to get the screen resources from Xrandr */
1406 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1408 XRRCrtcInfo *info = NULL;
1409 Ecore_X_Randr_Mode ret = -1;
1411 /* try to get crtc info */
1412 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1417 /* free the crtc info */
1418 XRRFreeCrtcInfo(info);
1421 /* free the resources */
1422 XRRFreeScreenResources(res);
1431 * @brief Sets a mode for a CRTC and the outputs attached to it.
1433 * @param root The window's screen to be queried.
1434 * @param crtc The CRTC which shall be set.
1435 * @param outputs Array of outputs which have to be compatible with the mode.
1436 * If @c NULL, CRTC will be disabled.
1437 * @param noutputs Number of outputs in array to be used. Use
1438 * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
1439 * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
1440 * disabled. If set to @c -1 the call will fail.
1441 * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
1445 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)
1448 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1450 return ecore_x_randr_crtc_settings_set(root, crtc, outputs, noutputs,
1457 ecore_x_randr_crtc_size_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *w, int *h)
1460 if (_randr_version < RANDR_VERSION_1_2) return;
1461 ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
1465 EAPI Ecore_X_Randr_Refresh_Rate
1466 ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc EINA_UNUSED, Ecore_X_Randr_Mode mode)
1469 XRRScreenResources *res = NULL;
1471 if (_randr_version < RANDR_VERSION_1_2) return 0.0;
1473 /* try to get the screen resources from Xrandr */
1474 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1479 for (i = 0; i < res->nmode; i++)
1481 if (res->modes[i].id == mode)
1483 if ((res->modes[i].hTotal) && (res->modes[i].vTotal))
1485 ret = ((double)res->modes[i].dotClock /
1486 ((double)res->modes[i].hTotal *
1487 (double)res->modes[i].vTotal));
1493 /* free the resources */
1494 XRRFreeScreenResources(res);
1502 EAPI Ecore_X_Randr_Orientation
1503 ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1506 XRRScreenResources *res = NULL;
1508 if (_randr_version < RANDR_VERSION_1_2) return 0;
1510 /* try to get the screen resources from Xrandr */
1511 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1513 XRRCrtcInfo *info = NULL;
1514 Ecore_X_Randr_Orientation ret = 0;
1516 /* try to get crtc info */
1517 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1520 ret = info->rotations;
1522 /* free the crtc info */
1523 XRRFreeCrtcInfo(info);
1526 /* free the resources */
1527 XRRFreeScreenResources(res);
1535 EAPI Ecore_X_Randr_Orientation
1536 ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
1539 XRRScreenResources *res = NULL;
1541 if (_randr_version < RANDR_VERSION_1_2) return 0;
1543 /* try to get the screen resources from Xrandr */
1544 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1546 XRRCrtcInfo *info = NULL;
1547 Ecore_X_Randr_Orientation ret = 0;
1549 /* try to get crtc info */
1550 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1553 ret = info->rotation;
1555 /* free the crtc info */
1556 XRRFreeCrtcInfo(info);
1559 /* free the resources */
1560 XRRFreeScreenResources(res);
1569 ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Orientation orientation)
1572 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1574 if (orientation != 0)
1575 return ecore_x_randr_crtc_settings_set(root, crtc, NULL,
1576 -1, -1, -1, -1, orientation);
1582 ecore_x_randr_crtc_clone_set(Ecore_X_Window root, Ecore_X_Randr_Crtc original, Ecore_X_Randr_Crtc cln)
1585 Eina_Bool ret = EINA_FALSE;
1586 XRRScreenResources *res = NULL;
1588 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1590 /* try to get the screen resources from Xrandr */
1591 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1593 XRRCrtcInfo *info = NULL;
1594 Ecore_X_Randr_Orientation orig_orient = 0;
1595 Ecore_X_Randr_Mode orig_mode = -1;
1598 /* try to get crtc info for original crtc */
1599 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, original)))
1603 orig_orient = info->rotation;
1604 orig_mode = info->mode;
1606 /* free the crtc info */
1607 XRRFreeCrtcInfo(info);
1610 ret = ecore_x_randr_crtc_settings_set(root, cln, NULL, -1, ox, oy,
1611 orig_mode, orig_orient);
1613 /* free the resources */
1614 XRRFreeScreenResources(res);
1623 * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
1624 * auto enabled in it's preferred mode, when it was disabled before.
1626 * @param root The root window which's default display will be queried.
1627 * @param crtc The CRTC which's configuration should be altered.
1628 * @param outputs An array of outputs, that should display this CRTC's content.
1629 * @param noutputs Number of outputs in the array of outputs. If set to
1630 * Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
1631 * If set to Ecore_X_Randr_None, CRTC will be disabled.
1632 * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
1633 * corrdinate will be assumed.
1634 * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
1635 * corrdinate will be assumed.
1636 * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
1637 * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
1639 * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
1640 * used, the current mode is assumed.
1641 * @return @c EINA_TRUE if the configuration alteration was successful,
1642 * @c EINA_FALSE otherwise.
1645 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)
1648 Eina_Bool ret = EINA_FALSE;
1649 XRRScreenResources *res = NULL;
1651 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1653 /* try to get the screen resources from Xrandr */
1654 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1657 RROutput *routputs = NULL;
1658 XRRCrtcInfo *info = NULL;
1659 Eina_Bool need_free = EINA_FALSE;
1662 rcrtc = (RRCrtc)crtc;
1664 /* try to get crtc info for original crtc */
1665 if (!(info = XRRGetCrtcInfo(_ecore_x_disp, res, rcrtc)))
1667 /* free the resources */
1668 XRRFreeScreenResources(res);
1672 if ((int)mode == -1) mode = info->mode;
1673 if ((int)orientation == -1) orientation = info->rotation;
1674 if (x < 0) x = info->x;
1675 if (y < 0) y = info->y;
1679 noutputs = info->noutput;
1680 routputs = malloc(noutputs * sizeof(RROutput));
1681 for (i = 0; i < noutputs; i++)
1682 routputs[i] = info->outputs[i];
1683 need_free = EINA_TRUE;
1685 else if (noutputs > 0)
1687 routputs = malloc(noutputs * sizeof(RROutput));
1688 for (i = 0; i < noutputs; i++)
1689 routputs[i] = (RROutput)outputs[i];
1690 need_free = EINA_TRUE;
1693 /* try to set the crtc config */
1694 if (!XRRSetCrtcConfig(_ecore_x_disp, res, rcrtc, CurrentTime,
1695 x, y, mode, orientation,
1696 routputs, noutputs))
1699 if (need_free) free(routputs);
1701 /* free the crtc info */
1702 XRRFreeCrtcInfo(info);
1704 /* free the resources */
1705 XRRFreeScreenResources(res);
1714 * @brief Sets a CRTC relative to another one.
1716 * @param root The root window which's default display will be set.
1717 * @param crtc_r1 The CRTC to be positioned.
1718 * @param crtc_r2 The CRTC the position should be relative to.
1719 * @param policy The relation between the crtcs.
1720 * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
1722 * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
1723 * if repositioning failed or if position of new crtc would be out of given
1724 * screen's min/max bounds.
1727 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)
1730 Eina_Rectangle r1, r2;
1731 int mw = 0, mh = 0, sw = 0, sh = 0;
1734 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1736 /* check each crtc has a valid mode */
1737 if (ecore_x_randr_crtc_mode_get(root, crtc_r1) == 0) return EINA_FALSE;
1738 if (ecore_x_randr_crtc_mode_get(root, crtc_r2) == 0) return EINA_FALSE;
1740 /* get the geometry of each crtc */
1741 ecore_x_randr_crtc_geometry_get(root, crtc_r1, &r1.x, &r1.y, &r1.w, &r1.h);
1742 ecore_x_randr_crtc_geometry_get(root, crtc_r2, &r2.x, &r2.y, &r2.w, &r2.h);
1744 /* get the geometry of the screen */
1745 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh);
1746 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
1750 case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
1755 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1758 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1759 ny = ((int)(((double)r2.h / 2.0) + r2.y - ((double)r1.h / 2.0)));
1761 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1762 ny = ((int)((double)sh / 2.0) - ((double)r1.h / 2.0));
1767 case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
1772 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1775 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1776 ny = ((int)(((double)r2.h / 2.0) + r2.y - ((double)r1.h / 2.0)));
1778 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1779 ny = ((int)((double)sh / 2.0) - ((double)r1.h / 2.0));
1784 case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
1789 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1792 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1793 nx = ((int)((((double)r2.x + (double)r2.w) / 2.0) -
1794 ((double)r1.w / 2.0)));
1796 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1797 nx = ((int)((double)sw / 2.0));
1802 case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
1807 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
1810 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
1811 nx = ((int)((((double)r2.x + (double)r2.w) / 2.0) -
1812 ((double)r1.w / 2.0)));
1814 case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
1815 nx = ((int)((double)sw / 2.0));
1820 case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
1821 return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2.x, r2.y);
1823 case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
1829 if ((nx == r1.x) && (ny == r1.y)) return EINA_TRUE;
1830 if (((ny + r1.h) > mh) || ((nx + r1.w) > mw)) return EINA_FALSE;
1832 return ecore_x_randr_crtc_pos_set(root, crtc_r1, nx, ny);
1841 EAPI Ecore_X_Randr_Crtc_Info *
1842 ecore_x_randr_crtc_info_get(Ecore_X_Window root, const Ecore_X_Randr_Crtc crtc)
1845 XRRScreenResources *res = NULL;
1847 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1849 /* try to get the screen resources from Xrandr */
1850 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1852 XRRCrtcInfo *info = NULL;
1853 Ecore_X_Randr_Crtc_Info *ret = NULL;
1855 /* try to get crtc info */
1856 if ((info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
1858 if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc_Info))))
1860 /* copy the mode information into our return structure */
1861 ret->timestamp = info->timestamp;
1864 ret->width = info->width;
1865 ret->height = info->height;
1866 ret->mode = info->mode;
1867 ret->rotation = info->rotation;
1868 ret->rotations = info->rotations;
1869 ret->noutput = info->noutput;
1870 ret->npossible = info->npossible;
1873 malloc(info->noutput * sizeof(Ecore_X_Randr_Output))))
1877 /* loop the outputs on this crtc */
1878 for (i = 0; i < info->noutput; i++)
1879 ret->outputs[i] = info->outputs[i];
1882 if ((ret->possible =
1883 malloc(info->npossible * sizeof(Ecore_X_Randr_Output))))
1887 /* loop the outputs on this crtc */
1888 for (i = 0; i < info->npossible; i++)
1889 ret->possible[i] = info->possible[i];
1893 /* free the crtc info */
1894 XRRFreeCrtcInfo(info);
1897 /* free the resources */
1898 XRRFreeScreenResources(res);
1910 ecore_x_randr_crtc_info_free(Ecore_X_Randr_Crtc_Info *info)
1913 if (_randr_version >= RANDR_VERSION_1_2)
1917 if (info->outputs) free(info->outputs);
1918 if (info->possible) free(info->possible);
1927 * @brief Add given mode to given output.
1929 * @param output The output the mode is added to.
1930 * @param mode The mode added to the output.
1931 * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else
1933 * Additionally, if xcb backend is used, the success of the addition is
1934 * reported back directly.
1938 ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
1941 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
1943 if ((output) && (mode))
1945 /* add this mode to output
1947 * NB: This XRR function returns void so we have to assume it worked */
1948 XRRAddOutputMode(_ecore_x_disp, output, mode);
1957 * @brief delete given mode from given output
1958 * @param output the output the mode is removed from
1959 * @param mode the mode removed from the output
1963 ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
1966 if (_randr_version < RANDR_VERSION_1_2) return;
1968 if ((!output) || (!mode)) return;
1970 XRRDeleteOutputMode(_ecore_x_disp, output, mode);
1974 EAPI Ecore_X_Randr_Mode *
1975 ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred)
1978 XRRScreenResources *res = NULL;
1980 if (_randr_version < RANDR_VERSION_1_2) return NULL;
1982 /* try to get the screen resources from Xrandr */
1983 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
1985 XRROutputInfo *info = NULL;
1986 Ecore_X_Randr_Mode *modes = NULL;
1988 /* try to get output info */
1989 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
1991 if (num) *num = info->nmode;
1992 if (npreferred) *npreferred = info->npreferred;
1994 if (info->nmode > 0)
1996 if ((modes = malloc(info->nmode * sizeof(Ecore_X_Randr_Mode))))
2000 for (i = 0; i < info->nmode; i++)
2001 modes[i] = info->modes[i];
2005 /* free the output info */
2006 XRRFreeOutputInfo(info);
2009 /* free the resources */
2010 XRRFreeScreenResources(res);
2019 * @brief gets the the outputs which might be used simultenously on the same
2021 * @param root window that this information should be queried for.
2022 * @param output the output which's clones we concern
2023 * @param num number of possible clones
2025 EAPI Ecore_X_Randr_Output *
2026 ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
2029 XRRScreenResources *res = NULL;
2031 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2033 /* try to get the screen resources from Xrandr */
2034 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2036 XRROutputInfo *info = NULL;
2037 Ecore_X_Randr_Output *outputs = NULL;
2039 /* try to get output info */
2040 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2042 if (num) *num = info->nclone;
2044 if (info->nclone > 0)
2046 /* try to allocate space for output return */
2047 if ((outputs = malloc(info->nclone * sizeof(Ecore_X_Randr_Output))))
2051 for (i = 0; i < info->nclone; i++)
2052 outputs[i] = info->clones[i];
2056 /* free the output info */
2057 XRRFreeOutputInfo(info);
2060 /* free the resources */
2061 XRRFreeScreenResources(res);
2069 EAPI Ecore_X_Randr_Crtc *
2070 ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
2073 XRRScreenResources *res = NULL;
2075 if (_randr_version < RANDR_VERSION_1_2) return 0;
2077 /* try to get the screen resources from Xrandr */
2078 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2080 XRROutputInfo *info = NULL;
2081 Ecore_X_Randr_Crtc *crtcs = NULL;
2083 /* try to get output info */
2084 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2086 if (num) *num = info->ncrtc;
2088 if (info->ncrtc > 0)
2090 /* try to allocate space for the return crtcs */
2091 if ((crtcs = malloc(info->ncrtc * sizeof(Ecore_X_Randr_Crtc))))
2095 for (i = 0; i < info->ncrtc; i++)
2096 crtcs[i] = info->crtcs[i];
2100 /* free the output info */
2101 XRRFreeOutputInfo(info);
2104 /* free the resources */
2105 XRRFreeScreenResources(res);
2113 EAPI Ecore_X_Randr_Crtc
2114 ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2117 XRRScreenResources *res = NULL;
2119 if (_randr_version < RANDR_VERSION_1_2) return 0;
2121 /* try to get the screen resources from Xrandr */
2122 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2124 XRROutputInfo *info = NULL;
2125 Ecore_X_Randr_Crtc ret = 0;
2127 /* try to get output info */
2128 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2132 /* free the output info */
2133 XRRFreeOutputInfo(info);
2136 /* free the resources */
2137 XRRFreeScreenResources(res);
2146 * @brief gets the given output's name as reported by X
2147 * @param root the window which's screen will be queried
2148 * @param output The output for which the name will be reported.
2149 * @param len length of returned c-string.
2150 * @return name of the output as reported by X
2153 ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len)
2156 XRRScreenResources *res = NULL;
2158 if (_randr_version < RANDR_VERSION_1_2) return 0;
2160 /* try to get the screen resources from Xrandr */
2161 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2163 XRROutputInfo *info = NULL;
2166 /* try to get output info */
2167 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2173 * Old randr code says there is an xrandr bug here with
2174 * nameLen. Test This !!!
2177 ret = strdup(info->name);
2178 if (len) *len = info->nameLen;
2181 /* free the output info */
2182 XRRFreeOutputInfo(info);
2185 /* free the resources */
2186 XRRFreeScreenResources(res);
2195 * @deprecated use ecore_x_randr_crtc_gamma_size_get()
2197 EINA_DEPRECATED EAPI int
2198 ecore_x_randr_crtc_gamma_ramp_size_get(Ecore_X_Randr_Crtc crtc EINA_UNUSED)
2204 * @deprecated use ecore_x_randr_crtc_gamma_get()
2206 EINA_DEPRECATED EAPI Ecore_X_Randr_Crtc_Gamma **
2207 ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc EINA_UNUSED)
2213 * @deprecated use ecore_x_randr_crtc_gamma_set()
2215 EINA_DEPRECATED EAPI Eina_Bool
2216 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)
2225 ecore_x_randr_crtc_gamma_size_get(Ecore_X_Randr_Crtc crtc)
2228 if (_randr_version < RANDR_VERSION_1_2) return 0;
2229 return XRRGetCrtcGammaSize(_ecore_x_disp, crtc);
2237 EAPI Ecore_X_Randr_Crtc_Gamma_Info *
2238 ecore_x_randr_crtc_gamma_get(Ecore_X_Randr_Crtc crtc)
2241 Ecore_X_Randr_Crtc_Gamma_Info *info = NULL;
2242 XRRCrtcGamma *xgamma = NULL;
2244 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2246 /* try to get the gamma for this crtc from Xrandr */
2247 if (!(xgamma = XRRGetCrtcGamma(_ecore_x_disp, crtc)))
2250 /* try to allocate space for the return struct and copy the results in */
2251 if ((info = malloc(sizeof(Ecore_X_Randr_Crtc_Gamma_Info))))
2252 memcpy(info, xgamma, sizeof(Ecore_X_Randr_Crtc_Gamma_Info));
2254 /* free the returned gamma resource */
2255 XRRFreeGamma(xgamma);
2266 ecore_x_randr_crtc_gamma_set(Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Crtc_Gamma_Info *gamma)
2269 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2271 /* try to set the gamma
2273 * NB: XRRSetCrtcGamma returns void
2275 XRRSetCrtcGamma(_ecore_x_disp, crtc, (XRRCrtcGamma *)gamma);
2282 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)
2285 XRRScreenResources *res = NULL;
2286 Eina_Bool ret = EINA_FALSE;
2288 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2290 if ((nnot_moved <= 0) || (!not_moved)) return EINA_FALSE;
2292 /* try to get the screen resources from Xrandr */
2293 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2295 Ecore_X_Randr_Crtc *crtcs = NULL;
2298 n = (res->ncrtc - nnot_moved);
2301 /* try to allocate space for a list of crtcs */
2302 if ((crtcs = malloc(n * sizeof(Ecore_X_Randr_Crtc))))
2304 int i = 0, j = 0, k = 0;
2306 for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
2308 for (j = 0; j < nnot_moved; j++)
2310 if (res->crtcs[i] == not_moved[j])
2314 if (j == nnot_moved) crtcs[k++] = res->crtcs[i];
2319 /* free the resources */
2320 XRRFreeScreenResources(res);
2322 /* actually move the crtcs */
2325 ret = ecore_x_randr_move_crtcs(root, crtcs, n, dx, dy);
2336 * @brief Move given CRTCs belonging to the given root window's screen dx/dy
2337 * pixels relative to their current position. The screen size will be
2338 * automatically adjusted if necessary and possible.
2340 * @param root Window which's screen's resources are used.
2341 * @param crtcs List of CRTCs to be moved.
2342 * @param ncrtc Number of CRTCs in array.
2343 * @param dx Amount of pixels the CRTCs should be moved in x direction.
2344 * @param dy Amount of pixels the CRTCs should be moved in y direction.
2345 * @return @c EINA_TRUE if all crtcs could be moved successfully.
2348 ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int ncrtc, int dx, int dy)
2351 XRRScreenResources *res = NULL;
2352 XRRCrtcInfo **info = NULL;
2355 if (_randr_version < RANDR_VERSION_1_2) return EINA_FALSE;
2357 if (ncrtc < 1) return EINA_FALSE;
2359 /* try to get the screen resources from Xrandr */
2360 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2362 Eina_Bool ret = EINA_TRUE;
2363 int mw = 0, mh = 0, sw = 0, sh = 0;
2366 info = alloca(ncrtc * sizeof(XRRCrtcInfo *));
2367 memset(info, 0, ncrtc * sizeof(XRRCrtcInfo *));
2369 ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh);
2370 ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
2374 for (i = 0; i < ncrtc; i++)
2376 /* try to get crtc info for original crtc */
2377 if ((info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])))
2379 if (((info[i]->x + dx) < 0) || ((info[i]->y + dy < 0)) ||
2380 ((int)(info[i]->x + info[i]->width) > mw) ||
2381 ((int)(info[i]->y + info[i]->height) > mh))
2386 nw = MAX(((int)(info[i]->x + info[i]->width) + dx), nw);
2387 nh = MAX(((int)(info[i]->y + info[i]->height) + dy), nh);
2391 /* resize the screen if we need to */
2392 if (!(((nw > sw) || (nh > sh)) ||
2393 ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)))
2396 /* actually move the crtcs */
2397 for (i = 0; ((i < ncrtc) && info[i]); i++)
2399 if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
2412 /* something went wrong somewhere. move everything back */
2416 ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
2425 for (i = 0; i < ncrtc; i++)
2426 if (info[i]) XRRFreeCrtcInfo(info[i]);
2428 /* free the resources */
2429 XRRFreeScreenResources(res);
2437 /* free the crtc info */
2438 if (info[i]) XRRFreeCrtcInfo(info[i]);
2441 /* free the resources */
2442 if (res) XRRFreeScreenResources(res);
2448 * @brief gets the width and hight of a given mode
2449 * @param mode the mode which's size is to be looked up
2450 * @param w width of given mode in px
2451 * @param h height of given mode in px
2454 ecore_x_randr_mode_size_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode, int *w, int *h)
2457 if (_randr_version < RANDR_VERSION_1_2) return;
2459 if ((mode != 0) && ((w) || (h)))
2461 XRRScreenResources *res = NULL;
2463 /* try to get the screen resources from Xrandr */
2464 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2468 for (i = 0; i < res->nmode; i++)
2470 if (res->modes[i].id == mode)
2472 if (w) *w = res->modes[i].width;
2473 if (h) *h = res->modes[i].height;
2478 /* free the resources */
2479 XRRFreeScreenResources(res);
2485 EAPI Ecore_X_Randr_Connection_Status
2486 ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2489 XRRScreenResources *res = NULL;
2491 if (_randr_version < RANDR_VERSION_1_2)
2492 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2494 /* try to get the screen resources from Xrandr */
2495 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2497 XRROutputInfo *info = NULL;
2498 Ecore_X_Randr_Connection_Status ret =
2499 ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2501 /* try to get output info */
2502 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2504 ret = info->connection;
2506 /* free the output info */
2507 XRRFreeOutputInfo(info);
2510 /* free the resources */
2511 XRRFreeScreenResources(res);
2516 return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
2520 ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w, int *h)
2523 XRRScreenResources *res = NULL;
2525 if (_randr_version < RANDR_VERSION_1_2) return;
2527 /* try to get the screen resources from Xrandr */
2528 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2530 XRROutputInfo *info = NULL;
2532 /* try to get output info */
2533 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2535 if (w) *w = info->mm_width;
2536 if (h) *h = info->mm_height;
2538 /* free the output info */
2539 XRRFreeOutputInfo(info);
2542 /* free the resources */
2543 XRRFreeScreenResources(res);
2549 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)
2556 ecore_x_randr_output_backlight_available(void)
2559 Atom backlight = None;
2561 /* check for new backlight property */
2562 if ((backlight = XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True)))
2565 /* check for legacy backlight property */
2566 if ((backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True)))
2573 * @brief Set up the backlight level to the given level.
2575 * @param root The window's screen which will be set.
2576 * @param level Of the backlight between @c 0 and @c 1.
2579 ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level)
2582 XRRScreenResources *res = NULL;
2585 if (_randr_version < RANDR_VERSION_1_3) return;
2587 /* try to get the screen resources from Xrandr */
2588 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2590 /* set the backlight level on each output */
2591 for (i = 0; i < res->noutput; i++)
2592 ecore_x_randr_output_backlight_level_set(root, res->outputs[i], level);
2594 /* free the resources */
2595 XRRFreeScreenResources(res);
2601 ecore_x_randr_output_backlight_level_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
2604 XRRPropertyInfo *info = NULL;
2605 Atom backlight = None, type = None;
2606 unsigned long bytes = 0;
2607 unsigned long items = 0;
2608 unsigned char *prop = NULL;
2612 /* check if "new" backlight is available */
2613 if (_randr_version >= RANDR_VERSION_1_3)
2616 XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True)))
2618 XRRGetOutputProperty(_ecore_x_disp, output, backlight, 0, 4,
2619 False, False, None, &type, &format,
2620 &items, &bytes, &prop);
2624 if ((!prop) || (items == 0))
2626 /* check legacy backlight property
2628 * FIXME: NB: Not sure what randr version we need for the legacy
2629 * backlight property so skip version check */
2630 if ((backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True)))
2632 XRRGetOutputProperty(_ecore_x_disp, output, backlight, 0, 4,
2633 False, False, None, &type, &format,
2634 &items, &bytes, &prop);
2639 if ((type != XA_INTEGER) || (items != 1) || (format != 32))
2641 WRN("Backlight property is not supported on this server or driver");
2645 val = *((long *)prop);
2648 /* try to get the backlight property value from Xrandr */
2649 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, backlight)))
2653 if ((info->range) && (info->num_values == 2))
2655 /* convert the current value */
2656 ret = ((double)(val - info->values[0])) /
2657 ((double)(info->values[1] - info->values[0]));
2670 ecore_x_randr_output_backlight_level_set(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, double level)
2673 XRRPropertyInfo *info = NULL;
2674 Atom backlight = None;
2676 /* safety check some input values */
2677 if ((level < 0) || (level > 1))
2679 ERR("Backlight level should be between 0 and 1");
2683 /* check if "new" backlight is available */
2684 if (_randr_version >= RANDR_VERSION_1_3)
2685 backlight = XInternAtom(_ecore_x_disp, RR_PROPERTY_BACKLIGHT, True);
2688 backlight = XInternAtom(_ecore_x_disp, "BACKLIGHT", True);
2692 WRN("Backlight property is not supported on this server or driver");
2696 /* try to get the output property from Xrandr */
2697 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, backlight)))
2699 Eina_Bool ret = EINA_FALSE;
2701 if ((info->range) && (info->num_values == 2))
2703 double min = 0.0, max = 0.0;
2706 min = info->values[0];
2707 max = info->values[1];
2708 val = (level * (max - min)) + min;
2709 if (val > max) val = max;
2710 if (val < min) val = min;
2712 /* tell xrandr to change the backlight value */
2713 XRRChangeOutputProperty(_ecore_x_disp, output, backlight,
2714 XA_INTEGER, 32, PropModeReplace,
2715 (unsigned char *)&val, 1);
2717 /* send changes to X */
2733 * @brief gets the EDID information of an attached output if available.
2734 * Note that this information is not to be compared using ordinary string
2735 * comparison functions, since it includes 0-bytes.
2736 * @param root window this information should be queried from
2737 * @param output the XID of the output
2738 * @param length length of the byte-array. If NULL, request will fail.
2740 EAPI unsigned char *
2741 ecore_x_randr_output_edid_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, unsigned long *length)
2744 Atom edid = None, type = None;
2745 unsigned char *prop;
2747 unsigned long nitems = 0, bytes = 0;
2749 if (_randr_version < RANDR_VERSION_1_2) return NULL;
2751 /* try to get the edid atom */
2752 if (!(edid = XInternAtom(_ecore_x_disp, RR_PROPERTY_RANDR_EDID, False)))
2755 /* get the output property
2757 * NB: Returns 0 on success */
2758 if (!XRRGetOutputProperty(_ecore_x_disp, output, edid, 0, 128, False, False,
2759 AnyPropertyType, &type, &format, &nitems,
2762 if ((type == XA_INTEGER) && (nitems >= 1) && (format == 8))
2764 unsigned char *ret = NULL;
2766 if ((ret = malloc(nitems * sizeof(unsigned char))))
2768 if (length) *length = nitems;
2769 memcpy(ret, prop, (nitems * sizeof(unsigned char)));
2778 EAPI Ecore_X_Render_Subpixel_Order
2779 ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
2782 XRRScreenResources *res = NULL;
2784 if (_randr_version < RANDR_VERSION_1_2)
2785 return ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN;
2787 /* try to get the screen resources from Xrandr */
2788 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
2790 XRROutputInfo *info = NULL;
2791 Ecore_X_Render_Subpixel_Order ret = 0;
2793 /* try to get output info */
2794 if ((info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
2796 ret = info->subpixel_order;
2798 /* free the output info */
2799 XRRFreeOutputInfo(info);
2802 /* free the resources */
2803 XRRFreeScreenResources(res);
2808 return ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN;
2811 /***************************************
2812 * API Functions for RandR version 1.3 *
2813 ***************************************/
2815 EAPI Ecore_X_Randr_Output *
2816 ecore_x_randr_output_wired_clones_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2819 Atom clones = None, type = None;
2820 unsigned char *prop;
2822 unsigned long nitems = 0, bytes = 0;
2826 * I am not sure that this code is correct. This needs checking
2829 if (_randr_version < RANDR_VERSION_1_3) return NULL;
2831 /* try to get the edid atom */
2832 if (!(clones = XInternAtom(_ecore_x_disp, RR_PROPERTY_CLONE_LIST, True)))
2835 /* get the output property
2837 * NB: Returns 0 on success */
2838 if (!XRRGetOutputProperty(_ecore_x_disp, output, clones, 0, 100, False, False,
2839 AnyPropertyType, &type, &format, &nitems,
2842 if ((type == XA_ATOM) && (nitems >= 1) && (format == 32))
2844 Ecore_X_Randr_Output *ret = NULL;
2846 if ((ret = malloc(nitems * sizeof(Ecore_X_Randr_Output))))
2848 if (num) *num = nitems;
2849 memcpy(ret, prop, (nitems * sizeof(Ecore_X_Randr_Output)));
2858 EAPI Ecore_X_Randr_Output **
2859 ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output EINA_UNUSED, int *num EINA_UNUSED)
2861 /* TODO: (1.3) !! */
2862 //RR_PROPERTY_COMPATIBILITY_LIST
2866 EAPI Ecore_X_Randr_Signal_Format *
2867 ecore_x_randr_output_signal_formats_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2870 XRRPropertyInfo *info = NULL;
2872 unsigned long bytes = 0;
2873 unsigned long items = 0;
2874 unsigned char *prop = NULL;
2877 if (_randr_version < RANDR_VERSION_1_3) return NULL;
2879 /* try to get the connector number atom */
2880 if (!(sig = XInternAtom(_ecore_x_disp, RR_PROPERTY_SIGNAL_FORMAT, True)))
2883 /* try to get the output property from Xrandr
2885 * NB: Returns 0 on success */
2886 if (XRRGetOutputProperty(_ecore_x_disp, output, sig, 0, 100,
2887 False, False, AnyPropertyType, &type, &format,
2888 &items, &bytes, &prop))
2890 printf("Signal Format property not supported.\n");
2897 if ((type != XA_ATOM) || (items < 1) || (format != 32))
2900 /* try to get the output property from Xrandr */
2901 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, sig)))
2903 Ecore_X_Randr_Signal_Format *formats = NULL;
2905 if (num) *num = info->num_values;
2907 if (info->num_values > 0)
2910 malloc(info->num_values * sizeof(Ecore_X_Randr_Signal_Format))))
2912 memcpy(formats, info->values,
2913 (info->num_values * sizeof(Ecore_X_Randr_Signal_Format)));
2927 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)
2929 /* TODO: (1.3) !! */
2930 //RR_PROPERTY_SIGNAL_FORMAT
2934 EAPI Ecore_X_Randr_Signal_Property *
2935 ecore_x_randr_output_signal_properties_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output, int *num)
2938 XRRPropertyInfo *info = NULL;
2940 unsigned long bytes = 0;
2941 unsigned long items = 0;
2942 unsigned char *prop = NULL;
2945 if (_randr_version < RANDR_VERSION_1_3) return NULL;
2947 /* try to get the connector number atom */
2948 if (!(sig = XInternAtom(_ecore_x_disp, RR_PROPERTY_SIGNAL_PROPERTIES, True)))
2951 /* try to get the output property from Xrandr
2953 * NB: Returns 0 on success */
2954 if (XRRGetOutputProperty(_ecore_x_disp, output, sig, 0, 100,
2955 False, False, AnyPropertyType, &type, &format,
2956 &items, &bytes, &prop))
2958 printf("Signal Properties property not supported.\n");
2965 if ((type != XA_ATOM) || (items < 1) || (format != 32))
2968 /* try to get the output property from Xrandr */
2969 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, sig)))
2971 Ecore_X_Randr_Signal_Property *props = NULL;
2973 if (num) *num = info->num_values;
2975 if (info->num_values > 0)
2978 malloc(info->num_values * sizeof(Ecore_X_Randr_Signal_Property))))
2980 memcpy(props, info->values,
2981 (info->num_values * sizeof(Ecore_X_Randr_Signal_Property)));
3002 * 3 == (typically) TV Connector but is driver/hardware dependent
3006 ecore_x_randr_output_connector_number_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
3009 XRRPropertyInfo *info = NULL;
3011 unsigned long bytes = 0;
3012 unsigned long items = 0;
3013 unsigned char *prop = NULL;
3014 int val = 0, format = 0;
3016 if (_randr_version < RANDR_VERSION_1_3) return -1;
3018 /* try to get the connector number atom */
3019 if (!(conn = XInternAtom(_ecore_x_disp, RR_PROPERTY_CONNECTOR_NUMBER, True)))
3022 /* try to get the output property from Xrandr
3024 * NB: Returns 0 on success */
3025 if (XRRGetOutputProperty(_ecore_x_disp, output, conn, 0, 100,
3026 False, False, AnyPropertyType, &type, &format,
3027 &items, &bytes, &prop))
3029 printf("ConnectionNumber property not supported.\n");
3034 if ((type != XA_INTEGER) || (items != 1) || (format != 32))
3037 val = *((int *)prop);
3040 /* try to get the output property from Xrandr */
3041 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, conn)))
3045 /* convert the current value */
3046 ret = (int)(val - info->values[0]);
3057 EAPI Ecore_X_Randr_Connector_Type
3058 ecore_x_randr_output_connector_type_get(Ecore_X_Window root EINA_UNUSED, Ecore_X_Randr_Output output)
3061 XRRPropertyInfo *info = NULL;
3063 unsigned long bytes = 0;
3064 unsigned long items = 0;
3065 unsigned char *prop = NULL;
3066 int val = 0, format = 0;
3068 if (_randr_version < RANDR_VERSION_1_3) return -1;
3070 /* try to get the connector type atom */
3071 if ((conn = XInternAtom(_ecore_x_disp, RR_PROPERTY_CONNECTOR_NUMBER, True)))
3072 XRRGetOutputProperty(_ecore_x_disp, output, conn, 0, 4,
3073 False, False, AnyPropertyType, &type, &format,
3074 &items, &bytes, &prop);
3076 if ((!prop) || (items == 0))
3078 /* NB: some butthead drivers (*cough* nouveau *cough*) do not
3079 * implement randr properly. They are not using the connector type
3080 * property of randr, but rather a "subconnector" property */
3081 if ((conn = XInternAtom(_ecore_x_disp, "subconnector", True)))
3082 XRRGetOutputProperty(_ecore_x_disp, output, conn, 0, 4,
3083 False, False, AnyPropertyType, &type,
3084 &format, &items, &bytes, &prop);
3087 if ((!prop) || (items == 0))
3089 WRN("ConnectorType Property not supported.");
3094 if ((type != XA_ATOM) || (items != 1) || (format != 32))
3097 val = *((int *)prop);
3100 /* try to get the output property from Xrandr */
3101 if ((info = XRRQueryOutputProperty(_ecore_x_disp, output, conn)))
3105 /* convert the current value */
3106 ret = (int)(val - info->values[0]);
3108 /* printf("\tReturn Value: %d\n", ret); */
3109 /* printf("\t\tActual Name: %s\n", */
3110 /* XGetAtomName(_ecore_x_disp, ((Atom)info->values[ret]))); */
3121 EAPI Ecore_X_Randr_Output
3122 ecore_x_randr_primary_output_get(Ecore_X_Window root)
3125 if (_randr_version < RANDR_VERSION_1_3) return 0;
3126 return XRRGetOutputPrimary(_ecore_x_disp, root);
3133 ecore_x_randr_primary_output_set(Ecore_X_Window root, Ecore_X_Randr_Output output)
3136 if (_randr_version < RANDR_VERSION_1_3) return;
3137 XRRSetOutputPrimary(_ecore_x_disp, root, output);
3141 /***************************************
3142 * API Functions for RandR version 1.4 *
3143 ***************************************/
3146 ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3149 XRRScreenResources *res = NULL;
3151 if (_randr_version < RANDR_VERSION_1_4) return;
3153 /* try to get the screen resources from Xrandr */
3154 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3156 XRRPanning *xpan = NULL;
3158 /* get this crtc's panning */
3159 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3161 if (x) *x = xpan->left;
3162 if (y) *y = xpan->top;
3163 if (w) *w = xpan->width;
3164 if (h) *h = xpan->height;
3166 /* free the panning resource */
3167 XRRFreePanning(xpan);
3169 /* free the resources */
3170 XRRFreeScreenResources(res);
3176 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)
3179 XRRScreenResources *res = NULL;
3180 Eina_Bool ret = EINA_FALSE;
3182 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3184 /* try to get the screen resources from Xrandr */
3185 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3187 XRRPanning *xpan = NULL;
3189 /* get this crtc's panning */
3190 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3196 xpan->timestamp = CurrentTime;
3198 /* set the panning value */
3199 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3202 /* free the panning resource */
3203 XRRFreePanning(xpan);
3206 /* free the resources */
3207 XRRFreeScreenResources(res);
3217 ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3220 XRRScreenResources *res = NULL;
3222 if (_randr_version < RANDR_VERSION_1_4) return;
3224 /* try to get the screen resources from Xrandr */
3225 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3227 XRRPanning *xpan = NULL;
3229 /* get this crtc's panning */
3230 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3232 if (x) *x = xpan->track_left;
3233 if (y) *y = xpan->track_top;
3234 if (w) *w = xpan->track_width;
3235 if (h) *h = xpan->track_height;
3237 /* free the panning resource */
3238 XRRFreePanning(xpan);
3240 /* free the resources */
3241 XRRFreeScreenResources(res);
3247 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)
3250 XRRScreenResources *res = NULL;
3251 Eina_Bool ret = EINA_FALSE;
3253 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3255 /* try to get the screen resources from Xrandr */
3256 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3258 XRRPanning *xpan = NULL;
3260 /* get this crtc's panning */
3261 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3263 xpan->track_left = x;
3264 xpan->track_top = y;
3265 xpan->track_width = w;
3266 xpan->track_height = h;
3267 xpan->timestamp = CurrentTime;
3269 /* set the panning value */
3270 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3273 /* free the panning resource */
3274 XRRFreePanning(xpan);
3277 /* free the resources */
3278 XRRFreeScreenResources(res);
3288 ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h)
3291 XRRScreenResources *res = NULL;
3293 if (_randr_version < RANDR_VERSION_1_4) return;
3295 /* try to get the screen resources from Xrandr */
3296 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3298 XRRPanning *xpan = NULL;
3300 /* get this crtc's panning */
3301 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3303 if (x) *x = xpan->border_left;
3304 if (y) *y = xpan->border_top;
3305 if (w) *w = xpan->border_right;
3306 if (h) *h = xpan->border_bottom;
3308 /* free the panning resource */
3309 XRRFreePanning(xpan);
3311 /* free the resources */
3312 XRRFreeScreenResources(res);
3318 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)
3321 XRRScreenResources *res = NULL;
3322 Eina_Bool ret = EINA_FALSE;
3324 if (_randr_version < RANDR_VERSION_1_4) return EINA_FALSE;
3326 /* try to get the screen resources from Xrandr */
3327 if ((res = _ecore_x_randr_screen_resources_get(_ecore_x_disp, root)))
3329 XRRPanning *xpan = NULL;
3331 /* get this crtc's panning */
3332 if ((xpan = XRRGetPanning(_ecore_x_disp, res, crtc)))
3334 xpan->border_left = left;
3335 xpan->border_top = top;
3336 xpan->border_right = right;
3337 xpan->border_bottom = bottom;
3338 xpan->timestamp = CurrentTime;
3340 /* set the panning value */
3341 if (!XRRSetPanning(_ecore_x_disp, res, crtc, xpan))
3344 /* free the panning resource */
3345 XRRFreePanning(xpan);
3348 /* free the resources */
3349 XRRFreeScreenResources(res);
3358 /***************************************
3359 * API Functions for RandR Edid
3360 ***************************************/
3363 ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length)
3365 const unsigned char header[] =
3366 { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
3368 if (!edid) return EINA_FALSE;
3369 if (edid_length < 8) return EINA_FALSE;
3370 if (!memcmp(edid, header, 8)) return EINA_TRUE;
3375 ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length)
3378 unsigned char *iter = NULL;
3380 int i = 0, version = 0;
3382 if (edid_length < 128) return EINA_FALSE;
3384 version = ecore_x_randr_edid_version_get(edid, edid_length);
3385 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3387 for (i = 0; i < 128; i++)
3390 if (sum) return EINA_FALSE;
3392 /* check extension blocks */
3393 for (iter = edid; iter < (edid + edid_length); iter += 128)
3395 if (iter[0] == 0x02)
3397 for (i = 0, sum = 0; i < 128; i++)
3402 if (sum) return EINA_FALSE;
3410 ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
3413 if ((edid_length > RANDR_EDID_VERSION_MINOR) &&
3414 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3416 return (edid[RANDR_EDID_VERSION_MAJOR] << 8) |
3417 edid[RANDR_EDID_VERSION_MINOR];
3420 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3427 ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length)
3430 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3431 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3436 if (!(name = malloc(sizeof(char) * 4))) return NULL;
3438 x = (edid + RANDR_EDID_MANUFACTURER);
3439 name[0] = ((x[0] & 0x7c) >> 2) + '@';
3440 name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@';
3441 name[2] = (x[1] & 0x1f) + '@';
3451 ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length)
3454 unsigned char *block = NULL;
3457 version = ecore_x_randr_edid_version_get(edid, edid_length);
3458 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3460 for (block = (edid + RANDR_EDID_BLOCK);
3461 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3463 if ((block[0] == 0) && (block[1] == 0))
3465 if (block[3] == 0xfc)
3468 const char *edid_name;
3470 edid_name = (const char *)block + 5;
3471 if (!(name = malloc(14))) return NULL;
3472 strncpy(name, edid_name, 13);
3475 for (p = name; *p; p++)
3476 if ((*p < ' ') || (*p > '~')) *p = 0;
3487 ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length)
3490 unsigned char *block = NULL;
3493 version = ecore_x_randr_edid_version_get(edid, edid_length);
3494 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3496 for (block = (edid + RANDR_EDID_BLOCK);
3497 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3499 if ((block[0] == 0) && (block[1] == 0))
3501 if (block[3] == 0xfe)
3503 char *ascii = NULL, *p = NULL;
3504 const char *edid_ascii;
3506 edid_ascii = (const char *)block + 5;
3508 if (!(ascii = malloc(14))) return NULL;
3509 strncpy(ascii, edid_ascii, 13);
3511 for (p = ascii; *p; p++)
3512 if ((*p < ' ') || (*p > '~')) *p = 0;
3523 ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length)
3526 unsigned char *block = NULL;
3529 version = ecore_x_randr_edid_version_get(edid, edid_length);
3530 if (version < RANDR_EDID_VERSION_1_3) return NULL;
3532 for (block = (edid + RANDR_EDID_BLOCK);
3533 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3535 if ((block[0] == 0) && (block[1] == 0))
3537 if (block[3] == 0xff)
3539 char *serial = NULL, *p = NULL;
3540 const char *edid_serial;
3542 edid_serial = (const char *)block + 5;
3544 if (!(serial = malloc(14))) return NULL;
3545 strncpy(serial, edid_serial, 13);
3547 for (p = serial; *p; p++)
3548 if ((*p < ' ') || (*p > '~')) *p = 0;
3559 ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length)
3561 return ecore_x_randr_edid_manufacturer_model_get(edid, edid_length);
3565 ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length)
3568 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3569 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3570 return (int)(edid[0x0c] + (edid[0x0d] << 8) +
3571 (edid[0x0e] << 16) + (edid[0x0f] << 24));
3573 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3580 ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length)
3583 if ((edid_length > RANDR_EDID_MANUFACTURER + 1) &&
3584 (ecore_x_randr_edid_has_valid_header(edid, edid_length)))
3585 return (int)(edid[0x0a] + (edid[0x0b] << 8));
3587 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3591 ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length)
3596 version = ecore_x_randr_edid_version_get(edid, edid_length);
3597 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3599 return !!(edid[0x18] & 0xE0);
3606 ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length)
3611 version = ecore_x_randr_edid_version_get(edid, edid_length);
3612 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3614 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x80);
3620 ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length)
3625 version = ecore_x_randr_edid_version_get(edid, edid_length);
3626 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3628 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x40);
3634 ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length)
3639 version = ecore_x_randr_edid_version_get(edid, edid_length);
3640 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3642 if (edid[0x18] & 0xE0) return !!(edid[0x18] & 0x20);
3647 EAPI Ecore_X_Randr_Edid_Aspect_Ratio
3648 ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length)
3651 unsigned char *block = NULL;
3654 version = ecore_x_randr_edid_version_get(edid, edid_length);
3655 if (version < RANDR_EDID_VERSION_1_3)
3656 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3658 for (block = (edid + RANDR_EDID_BLOCK);
3659 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3661 if ((block[0] == 0) && (block[1] == 0))
3663 if ((block[3] == 0xfd) && (block[10] == 0x04))
3665 Ecore_X_Randr_Edid_Aspect_Ratio_Preferred ratio =
3666 (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred)((block[15] & 0xe0) >> 5);
3670 case RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3:
3671 return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
3672 case RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9:
3673 return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
3674 case RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10:
3675 return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
3676 case RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4:
3677 return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
3678 case RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9:
3679 return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
3681 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3687 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3693 EAPI Ecore_X_Randr_Edid_Aspect_Ratio
3694 ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length)
3697 Ecore_X_Randr_Edid_Aspect_Ratio ret;
3698 unsigned char *block = NULL;
3701 ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3703 version = ecore_x_randr_edid_version_get(edid, edid_length);
3704 if (version < RANDR_EDID_VERSION_1_3)
3705 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3707 for (block = (edid + RANDR_EDID_BLOCK);
3708 block <= (edid + RANDR_EDID_BLOCK + (3 * 18)); block += 18)
3710 if ((block[0] == 0) && (block[1] == 0))
3712 if ((block[3] == 0xfd) && (block[10] == 0x04))
3714 if (block[14] & 0x80)
3715 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3;
3716 if (block[14] & 0x40)
3717 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9;
3718 if (block[14] & 0x20)
3719 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10;
3720 if (block[14] & 0x10)
3721 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4;
3722 if (block[14] & 0x08)
3723 ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9;
3734 EAPI Ecore_X_Randr_Edid_Display_Colorscheme
3735 ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length)
3738 Ecore_X_Randr_Edid_Display_Colorscheme ret;
3741 ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3743 version = ecore_x_randr_edid_version_get(edid, edid_length);
3744 if (version < RANDR_EDID_VERSION_1_3)
3745 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3747 if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length))
3749 ret = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4;
3750 if (edid[0x18] & 0x10)
3751 ret |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4;
3752 if (edid[0x18] & 0x08)
3753 ret |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2;
3756 ret = (edid[0x18] & 0x18);
3765 ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length)
3770 version = ecore_x_randr_edid_version_get(edid, edid_length);
3771 if (version < RANDR_EDID_VERSION_1_3) return EINA_FALSE;
3773 return !!(edid[0x14] & 0x80);
3779 EAPI Ecore_X_Randr_Edid_Display_Interface_Type
3780 ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length)
3783 Ecore_X_Randr_Edid_Display_Interface_Type type;
3786 type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3788 version = ecore_x_randr_edid_version_get(edid, edid_length);
3789 if (version < RANDR_EDID_VERSION_1_3)
3790 return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
3792 type = (edid[0x14] & 0x0f);
3793 if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT)
3794 type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE;