aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c294
1 files changed, 240 insertions, 54 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c
index 62f7618..81a7c3f 100644
--- a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c
+++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c
@@ -1,7 +1,6 @@
1/* TODO: List of missing functions 1/* TODO: List of missing functions
2 * 2 *
3 * ecore_x_randr_crtc_clone_set 3 * ecore_x_randr_crtc_clone_set
4 * ecore_x_randr_output_size_mm_get
5 * ecore_x_randr_output_crtc_set 4 * ecore_x_randr_output_crtc_set
6 * ecore_x_randr_edid_version_get 5 * ecore_x_randr_edid_version_get
7 * ecore_x_randr_edid_info_has_valid_checksum 6 * ecore_x_randr_edid_info_has_valid_checksum
@@ -776,6 +775,24 @@ ecore_x_randr_output_modes_get(Ecore_X_Window root,
776 return modes; 775 return modes;
777} 776}
778 777
778EAPI Eina_Bool
779ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
780{
781 LOGFN(__FILE__, __LINE__, __FUNCTION__);
782 CHECK_XCB_CONN;
783
784#ifdef ECORE_XCB_RANDR
785 RANDR_CHECK_1_2_RET(EINA_FALSE);
786
787 if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
788 return EINA_FALSE;
789
790 xcb_randr_add_output_mode(_ecore_xcb_conn, output, mode);
791 return EINA_TRUE;
792#endif
793 return EINA_FALSE;
794}
795
779/* 796/*
780 * @brief get detailed information for a given mode id 797 * @brief get detailed information for a given mode id
781 * @param root window which's screen's ressources are queried 798 * @param root window which's screen's ressources are queried
@@ -805,6 +822,63 @@ ecore_x_randr_mode_info_get(Ecore_X_Window root,
805} 822}
806 823
807/* 824/*
825 * @brief add a mode to a display
826 * @param root window to which's screen's ressources are added
827 * @param mode_info
828 * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
829 * adding failed.
830 * @since 1.2.0
831 */
832EAPI Ecore_X_Randr_Mode
833ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info)
834{
835#ifdef ECORE_XCB_RANDR
836 Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
837 xcb_randr_create_mode_cookie_t cookie;
838 xcb_randr_create_mode_reply_t *reply;
839 xcb_randr_mode_info_t info;
840 int namelen = 0;
841#endif
842
843 LOGFN(__FILE__, __LINE__, __FUNCTION__);
844 CHECK_XCB_CONN;
845
846#ifdef ECORE_XCB_RANDR
847 RANDR_CHECK_1_2_RET(EINA_FALSE);
848
849 if (!mode_info) return Ecore_X_Randr_None;
850 if (!_ecore_xcb_randr_root_validate(root)) return Ecore_X_Randr_None;
851
852 namelen = strlen(mode_info->name);
853
854 memset(&info, 0, sizeof(info));
855 info.width = mode_info->width;
856 info.height = mode_info->height;
857 info.dot_clock = mode_info->dotClock;
858 info.hsync_start = mode_info->hSyncStart;
859 info.hsync_end = mode_info->hSyncEnd;
860 info.htotal = mode_info->hTotal;
861 info.hskew = mode_info->hSkew;
862 info.vsync_start = mode_info->vSyncStart;
863 info.vsync_end = mode_info->vSyncEnd;
864 info.vtotal = mode_info->vTotal;
865 info.mode_flags = mode_info->modeFlags;
866 info.name_len = namelen;
867
868 cookie =
869 xcb_randr_create_mode_unchecked(_ecore_xcb_conn, root, info,
870 namelen, mode_info->name);
871 reply = xcb_randr_create_mode_reply(_ecore_xcb_conn, cookie, NULL);
872 if (reply)
873 {
874 mode = mode_info->xid;
875 free(reply);
876 }
877#endif
878 return mode;
879}
880
881/*
808 * @brief get detailed information for all modes related to a root window's screen 882 * @brief get detailed information for all modes related to a root window's screen
809 * @param root window which's screen's ressources are queried 883 * @param root window which's screen's ressources are queried
810 * @param num number of modes returned 884 * @param num number of modes returned
@@ -1057,6 +1131,53 @@ ecore_x_randr_output_crtc_get(Ecore_X_Window root,
1057 return Ecore_X_Randr_None; 1131 return Ecore_X_Randr_None;
1058} 1132}
1059 1133
1134EAPI void
1135ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w_mm, int *h_mm)
1136{
1137#ifdef ECORE_XCB_RANDR
1138 xcb_randr_get_output_info_cookie_t ocookie;
1139 xcb_randr_get_output_info_reply_t *oreply;
1140 xcb_timestamp_t timestamp = 0;
1141#endif
1142
1143 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1144 CHECK_XCB_CONN;
1145
1146 if (w_mm) *w_mm = 0;
1147 if (h_mm) *h_mm = 0;
1148
1149#ifdef ECORE_XCB_RANDR
1150 RANDR_CHECK_1_2_RET();
1151
1152 if ((output != Ecore_X_Randr_None) && (_randr_version >= RANDR_1_3))
1153 {
1154 xcb_randr_get_screen_resources_current_reply_t *reply;
1155
1156 reply = _ecore_xcb_randr_13_get_resources(root);
1157 timestamp = reply->config_timestamp;
1158 free(reply);
1159 }
1160 else if ((output != Ecore_X_Randr_None) && (_randr_version == RANDR_1_2))
1161 {
1162 xcb_randr_get_screen_resources_reply_t *reply;
1163
1164 reply = _ecore_xcb_randr_12_get_resources(root);
1165 timestamp = reply->config_timestamp;
1166 free(reply);
1167 }
1168
1169 ocookie =
1170 xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, timestamp);
1171 oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL);
1172 if (oreply)
1173 {
1174 if (w_mm) *w_mm = oreply->mm_width;
1175 if (h_mm) *h_mm = oreply->mm_height;
1176 free(oreply);
1177 }
1178#endif
1179}
1180
1060/** 1181/**
1061 * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is 1182 * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is
1062 * auto enabled in it's preferred mode, when it was disabled before. 1183 * auto enabled in it's preferred mode, when it was disabled before.
@@ -1439,6 +1560,87 @@ ecore_x_randr_crtcs_get(Ecore_X_Window root,
1439} 1560}
1440 1561
1441/* 1562/*
1563 * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
1564 * @brief get the CRTCs, which display a certain window
1565 * @param window window the displaying CRTCs shall be found for
1566 * @param num the number of CRTCs displaying the window
1567 * @return array of CRTCs that display a certain window. NULL if no CRTCs
1568 * was found that displays the specified window.
1569 */
1570EAPI Ecore_X_Randr_Crtc *
1571ecore_x_randr_current_crtc_get(Ecore_X_Window window,
1572 int *num)
1573{
1574 return ecore_x_randr_window_crtcs_get(window, num);
1575}
1576
1577/*
1578 * @brief get the CRTCs, which display a certain window
1579 * @param window window the displaying crtcs shall be found for
1580 * @param num the number of crtcs displaying the window
1581 * @return array of crtcs that display a certain window. NULL if no crtcs
1582 * was found that displays the specified window.
1583 * @since 1.2.0
1584 */
1585EAPI Ecore_X_Randr_Crtc *
1586ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
1587 int *num)
1588{
1589#ifdef ECORE_XCB_RANDR
1590 Ecore_X_Window root;
1591 Eina_Rectangle w_geo, c_geo;
1592 Ecore_X_Randr_Crtc *crtcs, *ret = NULL;
1593 Ecore_X_Randr_Mode mode;
1594 int ncrtcs, i, nret = 0;
1595 xcb_translate_coordinates_cookie_t cookie;
1596 xcb_translate_coordinates_reply_t *trans;
1597#endif
1598
1599 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1600 CHECK_XCB_CONN;
1601
1602#ifdef ECORE_XCB_RANDR
1603 RANDR_CHECK_1_2_RET(NULL);
1604
1605 ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h);
1606
1607 root = ecore_x_window_root_get(window);
1608 crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs);
1609 if (!crtcs) return NULL;
1610
1611 /* now get window RELATIVE to root window - thats what matters. */
1612 cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0);
1613 trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL);
1614 w_geo.x = trans->dst_x;
1615 w_geo.y = trans->dst_y;
1616 free(trans);
1617
1618 for (i = 0, nret = 0; i < ncrtcs; i++)
1619 {
1620 /* if crtc is not enabled, don't bother about it any further */
1621 mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
1622 if (mode == Ecore_X_Randr_None) continue;
1623
1624 ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y,
1625 &c_geo.w, &c_geo.h);
1626 if (eina_rectangles_intersect(&w_geo, &c_geo))
1627 {
1628 ret = realloc(ret, (++nret *
1629 sizeof(Ecore_X_Randr_Output)));
1630 ret[nret] = crtcs[i];
1631 }
1632 }
1633 free(crtcs);
1634
1635 if (num) *num = nret;
1636 return ret;
1637
1638#endif
1639 if (num) *num = 0;
1640 return NULL;
1641}
1642
1643/*
1442 * @brief get a CRTC's outputs. 1644 * @brief get a CRTC's outputs.
1443 * @param root the root window which's screen will be queried 1645 * @param root the root window which's screen will be queried
1444 * @param num number of outputs referenced by given CRTC 1646 * @param num number of outputs referenced by given CRTC
@@ -2172,6 +2374,22 @@ ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
2172} 2374}
2173 2375
2174/* 2376/*
2377 * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
2378 * @brief get the outputs, which display a certain window
2379 * @param window window the displaying outputs shall be found for
2380 * @param num the number of outputs displaying the window
2381 * @return array of outputs that display a certain window. NULL if no outputs
2382 * was found that displays the specified window.
2383 */
2384
2385Ecore_X_Randr_Output *
2386ecore_x_randr_current_output_get(Ecore_X_Window window,
2387 int *num)
2388{
2389 return ecore_x_randr_window_outputs_get(window, num);
2390}
2391
2392/*
2175 * @brief get the outputs, which display a certain window 2393 * @brief get the outputs, which display a certain window
2176 * @param window window the displaying outputs shall be found for 2394 * @param window window the displaying outputs shall be found for
2177 * @param num the number of outputs displaying the window 2395 * @param num the number of outputs displaying the window
@@ -2184,13 +2402,9 @@ ecore_x_randr_window_outputs_get(Ecore_X_Window window,
2184{ 2402{
2185#ifdef ECORE_XCB_RANDR 2403#ifdef ECORE_XCB_RANDR
2186 Ecore_X_Window root; 2404 Ecore_X_Window root;
2187 Eina_Rectangle w_geo, c_geo;
2188 Ecore_X_Randr_Crtc *crtcs; 2405 Ecore_X_Randr_Crtc *crtcs;
2189 Ecore_X_Randr_Mode mode; 2406 Ecore_X_Randr_Output *outputs, *ret = NULL;
2190 Ecore_X_Randr_Output *outputs, *ret = NULL, *tret;
2191 int ncrtcs, noutputs, i, nret = 0; 2407 int ncrtcs, noutputs, i, nret = 0;
2192 xcb_translate_coordinates_cookie_t cookie;
2193 xcb_translate_coordinates_reply_t *trans;
2194#endif 2408#endif
2195 2409
2196 LOGFN(__FILE__, __LINE__, __FUNCTION__); 2410 LOGFN(__FILE__, __LINE__, __FUNCTION__);
@@ -2199,64 +2413,36 @@ ecore_x_randr_window_outputs_get(Ecore_X_Window window,
2199 if (num) *num = 0; 2413 if (num) *num = 0;
2200 2414
2201#ifdef ECORE_XCB_RANDR 2415#ifdef ECORE_XCB_RANDR
2202 RANDR_CHECK_1_2_RET(NULL); 2416 if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
2203
2204 ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h);
2205 2417
2206 root = ecore_x_window_root_get(window); 2418 root = ecore_x_window_root_get(window);
2207 crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); 2419 if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
2208 if (!crtcs) return NULL; 2420 goto _ecore_x_randr_current_output_get_fail;
2209 2421
2210 /* now get window RELATIVE to root window - thats what matters. */ 2422 for (i = 0, nret = 0; i < ncrtcs; i++)
2211 cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0);
2212 trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL);
2213 w_geo.x = trans->dst_x;
2214 w_geo.y = trans->dst_y;
2215 free(trans);
2216
2217 for (i = 0; i < ncrtcs; i++)
2218 { 2423 {
2219 /* if crtc is not enabled, don't bother about it any further */
2220 mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
2221 if (mode == Ecore_X_Randr_None) continue;
2222 2424
2223 ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y, 2425 outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
2224 &c_geo.w, &c_geo.h); 2426 &noutputs);
2225 if (eina_rectangles_intersect(&w_geo, &c_geo)) 2427 if (!outputs)
2226 { 2428 goto _ecore_x_randr_current_output_get_fail_free;
2227 outputs = 2429 nret += noutputs;
2228 ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs); 2430 ret = realloc(ret, (nret * sizeof(Ecore_X_Randr_Output)));
2229 /* The case below should be impossible, but for safety reasons 2431 memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
2230 * remains */ 2432 free(outputs);
2231 if (!outputs)
2232 {
2233 if (num) *num = 0;
2234 free(ret);
2235 free(crtcs);
2236 return NULL;
2237 }
2238 tret = realloc(ret, ((nret + noutputs) *
2239 sizeof(Ecore_X_Randr_Output)));
2240 if (!tret)
2241 {
2242 if (num) *num = 0;
2243 free(outputs);
2244 free(ret);
2245 free(crtcs);
2246 return NULL;
2247 }
2248 ret = tret;
2249 memcpy(&ret[nret], outputs,
2250 (noutputs * sizeof(Ecore_X_Randr_Output)));
2251 nret += noutputs;
2252 free(outputs);
2253 }
2254 } 2433 }
2255 free(crtcs); 2434 free(crtcs);
2256 2435
2257 if (num) *num = nret; 2436 if (num)
2437 *num = nret;
2438
2258 return ret; 2439 return ret;
2259 2440
2441_ecore_x_randr_current_output_get_fail_free:
2442 free(outputs);
2443 free(crtcs);
2444 free(ret);
2445_ecore_x_randr_current_output_get_fail:
2260#endif 2446#endif
2261 if (num) *num = 0; 2447 if (num) *num = 0;
2262 return NULL; 2448 return NULL;