From: Leif Middelschulte <leif.middelschulte@gmail.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 14 Aug 2010 10:21:03 +0000 (10:21 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 14 Aug 2010 10:21:03 +0000 (10:21 +0000)
patch for ecore-x xrandr 1.3 support - breaks previous api. final api
change (i know about) before we go alpha. in to svn we go.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@51109 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/xlib/Makefile.am
src/lib/ecore_x/xlib/ecore_x_events.c
src/lib/ecore_x/xlib/ecore_x_inline.x [new file with mode: 0644]
src/lib/ecore_x/xlib/ecore_x_randr.c
src/lib/ecore_x/xlib/ecore_x_randr_11.c [new file with mode: 0644]
src/lib/ecore_x/xlib/ecore_x_randr_12.c [new file with mode: 0644]
src/lib/ecore_x/xlib/ecore_x_randr_13.c [new file with mode: 0644]

index 49c815d..9966b53 100644 (file)
@@ -70,6 +70,7 @@ typedef Ecore_X_ID       Ecore_X_Randr_Output;
 typedef Ecore_X_ID       Ecore_X_Randr_Crtc;
 typedef Ecore_X_ID       Ecore_X_Randr_Mode;
 typedef unsigned short   Ecore_X_Randr_Size_ID;
+typedef int              Ecore_X_Randr_Screen;
 
 typedef Ecore_X_ID       Ecore_X_Device;
 
@@ -167,20 +168,34 @@ typedef enum _Ecore_X_Window_Stack_Mode {
    ECORE_X_WINDOW_STACK_OPPOSITE = 4
 } Ecore_X_Window_Stack_Mode;
 
-typedef enum _Ecore_X_Randr_Rotation {
-   ECORE_X_RANDR_ROT_0 = (1 << 0),
-   ECORE_X_RANDR_ROT_90 = (1 << 1),
-   ECORE_X_RANDR_ROT_180 = (1 << 2),
-   ECORE_X_RANDR_ROT_270 = (1 << 3),
-   ECORE_X_RANDR_FLIP_X = (1 << 4),
-   ECORE_X_RANDR_FLIP_Y = (1 << 5)
-} Ecore_X_Randr_Rotation;
-
-typedef enum _Ecore_X_Randr_Connection {
-   ECORE_X_RANDR_CONNECTED = 0,
-   ECORE_X_RANDR_DISCONNECTED = 1,
-   ECORE_X_RANDR_UNKNOWN_CONNECTION = 2
-} Ecore_X_Randr_Connection;
+typedef enum _Ecore_X_Randr_Orientation {
+   ECORE_X_RANDR_ORIENTATION_ROT_0 = (1 << 0),
+   ECORE_X_RANDR_ORIENTATION_ROT_90 = (1 << 1),
+   ECORE_X_RANDR_ORIENTATION_ROT_180 = (1 << 2),
+   ECORE_X_RANDR_ORIENTATION_ROT_270 = (1 << 3),
+   ECORE_X_RANDR_ORIENTATION_FLIP_X = (1 << 4),
+   ECORE_X_RANDR_ORIENTATION_FLIP_Y = (1 << 5)
+} Ecore_X_Randr_Orientation;
+
+typedef enum _Ecore_X_Randr_Connection_Status {
+   ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED = 0,
+   ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED = 1,
+   ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN = 2
+} Ecore_X_Randr_Connection_Status;
+
+typedef enum _Ecore_X_Randr_Output_Policy {
+   ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1,
+   ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2,
+   ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3,
+   ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4,
+   ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5
+} Ecore_X_Randr_Output_Policy;
+
+typedef enum _Ecore_X_Randr_Relative_Alignment {
+   ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE = 0,
+   ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL = 1,
+   ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR = 2
+} Ecore_X_Randr_Relative_Alignment;
 
 typedef enum _Ecore_X_Render_Subpixel_Order {
    ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN = 0,
@@ -360,6 +375,9 @@ typedef struct _Ecore_X_Event_Startup_Sequence   Ecore_X_Event_Startup_Sequence;
 
 typedef struct _Ecore_X_Event_Generic            Ecore_X_Event_Generic;
 
+typedef struct _Ecore_X_Randr_Screen_Size        Ecore_X_Randr_Screen_Size;
+typedef struct _Ecore_X_Randr_Screen_Size_MM     Ecore_X_Randr_Screen_Size_MM;
+
 struct _Ecore_X_Event_Mouse_In
 {
    int                  modifiers;
@@ -697,42 +715,46 @@ struct _Ecore_X_Event_Sync_Alarm
    Ecore_X_Sync_Alarm alarm;
 };
 
+struct _Ecore_X_Randr_Screen_Size
+{
+   int width, height;
+};
+
+struct _Ecore_X_Randr_Screen_Size_MM
+{
+   int width, height, width_mm, height_mm;
+};
+
 struct _Ecore_X_Event_Screen_Change
 {
    Ecore_X_Window                win;
    Ecore_X_Window                root;
-   int                           width;
-   int                           height;
+   Ecore_X_Randr_Screen_Size_MM  size;  /* in pixel and millimeters */
    Ecore_X_Time                  time;
    Ecore_X_Time                  config_time;
-   int                           mm_width; /* in millimeters */
-   int                           mm_height; /* in millimeters */
-   Ecore_X_Randr_Rotation        rotation;
+   Ecore_X_Randr_Orientation     orientation;
    Ecore_X_Render_Subpixel_Order subpixel_order;
    Ecore_X_Randr_Size_ID         size_id;
 };
 
 struct _Ecore_X_Event_Randr_Crtc_Change
 {
-   Ecore_X_Window         win;
-   Ecore_X_Randr_Crtc     crtc;
-   Ecore_X_Randr_Mode     mode;
-   Ecore_X_Randr_Rotation rotation;
-   int                    x;
-   int                    y;
-   int                    width;
-   int                    height;
+   Ecore_X_Window            win;
+   Ecore_X_Randr_Crtc        crtc;
+   Ecore_X_Randr_Mode        mode;
+   Ecore_X_Randr_Orientation orientation;
+   Eina_Rectangle            geo;
 };
 
 struct _Ecore_X_Event_Randr_Output_Change
 {
-   Ecore_X_Window                win;
-   Ecore_X_Randr_Output          output;
-   Ecore_X_Randr_Crtc            crtc;
-   Ecore_X_Randr_Mode            mode;
-   Ecore_X_Randr_Rotation        rotation;
-   Ecore_X_Randr_Connection      connection;
-   Ecore_X_Render_Subpixel_Order subpixel_order;
+   Ecore_X_Window                  win;
+   Ecore_X_Randr_Output            output;
+   Ecore_X_Randr_Crtc              crtc;
+   Ecore_X_Randr_Mode              mode;
+   Ecore_X_Randr_Orientation       orientation;
+   Ecore_X_Randr_Connection_Status connection;
+   Ecore_X_Render_Subpixel_Order   subpixel_order;
 };
 
 struct _Ecore_X_Event_Randr_Output_Property_Notify
@@ -2451,52 +2473,339 @@ EAPI int                  ecore_x_xregion_rect_contain(Ecore_X_XRegion   *region
                                                        Ecore_X_Rectangle *rect);
 
 /* ecore_x_randr.c */
-typedef struct _Ecore_X_Screen_Size           Ecore_X_Screen_Size;
-struct _Ecore_X_Screen_Size
-{
-   int width, height;
-};
 
-typedef struct _Ecore_X_Screen_Refresh_Rate   Ecore_X_Screen_Refresh_Rate;
-struct _Ecore_X_Screen_Refresh_Rate
-{
-   int rate;
-};
+/* The usage of 'Ecore_X_Randr_None' or 'Ecore_X_Randr_Unset'
+ * depends on the context. In most cases 'Ecore_X_Randr_Unset'
+ * can be used, but in some cases -1 is a special value to
+ * functions, thus 'Ecore_X_Randr_None' (=0) musst be used.
+ */
 
-EAPI int                              ecore_x_randr_query(void);
-EAPI int                              ecore_x_randr_events_select(
-   Ecore_X_Window win,
-   int            on);
-EAPI void                             ecore_x_randr_get_screen_info_prefetch(
-   Ecore_X_Window window);
-EAPI void                             ecore_x_randr_get_screen_info_fetch(void);
-EAPI Ecore_X_Randr_Rotation           ecore_x_randr_screen_rotations_get(
+typedef short Ecore_X_Randr_Refresh_Rate;
+typedef int   Ecore_X_Randr_Crtc_Gamma;
+typedef int   Ecore_X_Randr_Signal_Format;
+typedef int   Ecore_X_Randr_Signal_Property;
+typedef int   Ecore_X_Randr_Connector_Type;
+
+typedef struct _Ecore_X_Randr_Mode_Info
+{
+   Ecore_X_ID xid;
+   unsigned int width;
+   unsigned int height;
+   unsigned long dotClock;
+   unsigned int hSyncStart;
+   unsigned int hSyncEnd;
+   unsigned int hTotal;
+   unsigned int hSkew;
+   unsigned int vSyncStart;
+   unsigned int vSyncEnd;
+   unsigned int vTotal;
+   char *name;
+   unsigned int nameLength;
+   unsigned long modeFlags;
+} Ecore_X_Randr_Mode_Info;
+
+EAPI int             ecore_x_randr_version_get(
+   void);
+EAPI const Eina_Bool ecore_x_randr_query(void);
+
+/* ecore_x_randr_11.c */
+EAPI Ecore_X_Randr_Orientation
+                     ecore_x_randr_screen_primary_output_orientations_get(
    Ecore_X_Window root);
-EAPI Ecore_X_Randr_Rotation           ecore_x_randr_screen_rotation_get(
+EAPI Ecore_X_Randr_Orientation
+                     ecore_x_randr_screen_primary_output_orientation_get(
    Ecore_X_Window root);
-EAPI void                             ecore_x_randr_screen_rotation_set(
-   Ecore_X_Window         root,
-   Ecore_X_Randr_Rotation rot);
-EAPI Ecore_X_Screen_Size *            ecore_x_randr_screen_sizes_get(
+EAPI Eina_Bool
+                     ecore_x_randr_screen_primary_output_orientation_set(
    Ecore_X_Window root,
-   int           *num);
-EAPI Ecore_X_Screen_Size              ecore_x_randr_current_screen_size_get(
-   Ecore_X_Window root);
-EAPI int                              ecore_x_randr_screen_size_set(
-   Ecore_X_Window      root,
-   Ecore_X_Screen_Size size);
-
-EAPI Ecore_X_Screen_Refresh_Rate *    ecore_x_randr_screen_refresh_rates_get(
+   Ecore_X_Randr_Orientation
+   orientation);
+EAPI Ecore_X_Randr_Screen_Size_MM *
+                     ecore_x_randr_screen_primary_output_sizes_get(
    Ecore_X_Window root,
-   int            size_id,
-   int           *num);
-EAPI Ecore_X_Screen_Refresh_Rate      ecore_x_randr_current_screen_refresh_rate_get(
+   int *num);
+EAPI void
+                     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);
+EAPI Eina_Bool
+ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root,
+                                             int size_index);
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_screen_primary_output_current_refresh_rate_get(
    Ecore_X_Window root);
+EAPI Ecore_X_Randr_Refresh_Rate *
+ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root,
+                                                      int size_index,
+                                                      int *num);
+EAPI Eina_Bool
+ecore_x_randr_screen_primary_output_refresh_rate_set(
+   Ecore_X_Window root,
+   int size_index,
+   Ecore_X_Randr_Refresh_Rate
+   rate);
+
+/* ecore_x_randr_12.c */
+EAPI void
+ecore_x_randr_events_select(Ecore_X_Window win,
+                            Eina_Bool on);
 
-EAPI int                              ecore_x_randr_screen_refresh_rate_set(
-   Ecore_X_Window              root,
-   Ecore_X_Screen_Size         size,
-   Ecore_X_Screen_Refresh_Rate rate);
+EAPI void
+ecore_x_randr_screen_current_size_get(Ecore_X_Window root,
+                                      int *w,
+                                      int *h,
+                                      int *w_mm,
+                                      int *h_mm);
+EAPI void
+          ecore_x_randr_screen_size_range_get(Ecore_X_Window root,
+                                    int *wmin,
+                                    int *hmin,
+                                    int *wmax,
+                                    int *hmax);
+EAPI void ecore_x_randr_screen_reset(
+   Ecore_X_Window root);
+EAPI Eina_Bool
+          ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
+                                      int w,
+                                      int h,
+                                      int w_mm,
+                                      int h_mm);
+EAPI Ecore_X_Randr_Mode_Info **
+                           ecore_x_randr_modes_info_get(Ecore_X_Window root,
+                             int *num);
+EAPI Ecore_X_Randr_Mode_Info *
+                           ecore_x_randr_mode_info_get(Ecore_X_Window root,
+                            Ecore_X_Randr_Mode mode);
+EAPI void
+                           ecore_x_randr_mode_info_free(
+   Ecore_X_Randr_Mode_Info *mode_info);
+EAPI Ecore_X_Randr_Crtc *  ecore_x_randr_crtcs_get(
+   Ecore_X_Window root,
+   int *num);
+EAPI Ecore_X_Randr_Output *ecore_x_randr_outputs_get(
+   Ecore_X_Window root,
+   int *num);
+EAPI Ecore_X_Randr_Output *
+                           ecore_x_randr_current_output_get(
+   Ecore_X_Window window,
+   int *num);
+EAPI Ecore_X_Randr_Crtc *
+                           ecore_x_randr_current_crtc_get(Ecore_X_Window window,
+                               int *num);
+EAPI Ecore_X_Randr_Output *
+                           ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
+                               Ecore_X_Randr_Crtc crtc,
+                               int *num);
+EAPI Ecore_X_Randr_Output *
+                           ecore_x_randr_crtc_possible_outputs_get(
+   Ecore_X_Window root,
+   Ecore_X_Randr_Crtc crtc,
+   int *num);
+EAPI void
+                           ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
+                                Ecore_X_Randr_Crtc crtc,
+                                int *x,
+                                int *y,
+                                int *w,
+                                int *h);
+EAPI void
+ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
+                           Ecore_X_Randr_Crtc crtc,
+                           int *x,
+                           int *y);
+EAPI Eina_Bool
+ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
+                           Ecore_X_Randr_Crtc crtc,
+                           int x,
+                           int y);
+EAPI Ecore_X_Randr_Mode
+ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool
+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);
+EAPI void
+ecore_x_randr_crtc_size_get(Ecore_X_Window root,
+                            Ecore_X_Randr_Crtc crtc,
+                            int *w,
+                            int *h);
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc,
+                                    Ecore_X_Randr_Mode mode);
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc);
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool
+ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
+                                   Ecore_X_Randr_Crtc crtc,
+                                   const Ecore_X_Randr_Orientation orientation);
+EAPI Eina_Bool
+ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
+                             Ecore_X_Randr_Crtc original,
+                             Ecore_X_Randr_Crtc clone);
+EAPI Eina_Bool
+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);
+EAPI Eina_Bool
+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);
+EAPI Ecore_X_Randr_Mode *
+                     ecore_x_randr_output_modes_get(Ecore_X_Window root,
+                               Ecore_X_Randr_Output output,
+                               int *num,
+                               int *npreferred);
+EAPI Ecore_X_Randr_Output * ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Crtc * ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num);
+EAPI Ecore_X_Randr_Crtc
+                     ecore_x_randr_output_crtc_get(Ecore_X_Window root,
+                              Ecore_X_Randr_Output output);
+EAPI char *
+                     ecore_x_randr_output_name_get(Ecore_X_Window root,
+                              Ecore_X_Randr_Output output,
+                              int *len);
+EAPI int
+                     ecore_x_randr_crtc_gamma_ramp_size_get(
+   Ecore_X_Randr_Crtc crtc);
+EAPI Ecore_X_Randr_Crtc_Gamma **
+                     ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool
+                     ecore_x_randr_crtc_gamma_ramps_set(Ecore_X_Randr_Crtc crtc,
+                                   const Ecore_X_Randr_Crtc_Gamma *red,
+                                   const Ecore_X_Randr_Crtc_Gamma *green,
+                                   const Ecore_X_Randr_Crtc_Gamma *blue);
+EAPI Eina_Bool
+                     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);
+EAPI Eina_Bool ecore_x_randr_move_crtcs(
+   Ecore_X_Window root,
+   const Ecore_X_Randr_Crtc *crtcs,
+   int ncrtc,
+   int dx,
+   int dy);
+EAPI void
+ecore_x_randr_mode_size_get(Ecore_X_Window root,
+                            Ecore_X_Randr_Mode mode,
+                            int *w,
+                            int *h);
+EAPI Ecore_X_Randr_Connection_Status
+ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
+                                           Ecore_X_Randr_Output output);
+EAPI void
+ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
+                                 Ecore_X_Randr_Output output,
+                                 int *w,
+                                 int *h);
+EAPI Eina_Bool
+ecore_x_randr_output_crtc_set(Ecore_X_Window root,
+                              Ecore_X_Randr_Output output,
+                              const Ecore_X_Randr_Crtc crtc);
+
+/* ecore_x_randr_13.c */
+EAPI void
+ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level);
+EAPI double
+ecore_x_randr_output_backlight_level_get(Ecore_X_Window root,
+                                         Ecore_X_Randr_Output output);
+EAPI Eina_Bool
+ecore_x_randr_output_backlight_level_set(Ecore_X_Window root,
+                                         Ecore_X_Randr_Output output,
+                                         double level);
+EAPI Ecore_X_Randr_Output
+ecore_x_randr_primary_output_get(Ecore_X_Window root);
+EAPI void
+ecore_x_randr_primary_output_set(Ecore_X_Window root,
+                                 Ecore_X_Randr_Output output);
+EAPI Ecore_X_Render_Subpixel_Order
+ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root,
+                                        Ecore_X_Randr_Output output);
+EAPI unsigned char *
+ecore_x_randr_output_edid_get(Ecore_X_Window root,
+                              Ecore_X_Randr_Output output,
+                              unsigned long *length);
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_output_wired_clones_get(Ecore_X_Window root,
+                                      Ecore_X_Randr_Output output,
+                                      int *num);
+EAPI Ecore_X_Randr_Output **
+ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root,
+                                            Ecore_X_Randr_Output output,
+                                            int *num);
+EAPI Ecore_X_Randr_Signal_Format *
+ecore_x_randr_output_signal_formats_get(Ecore_X_Window root,
+                                        Ecore_X_Randr_Output output,
+                                        int *num);
+EAPI Eina_Bool
+ecore_x_randr_output_signal_format_set(Ecore_X_Window root,
+                                       Ecore_X_Randr_Output output,
+                                       Ecore_X_Randr_Signal_Format *signal);
+EAPI Ecore_X_Randr_Signal_Property *
+ecore_x_randr_output_signal_properties_get(Ecore_X_Window root,
+                                           Ecore_X_Randr_Output output,
+                                           int *num);
+EAPI int
+ecore_x_randr_output_connector_number_get(Ecore_X_Window root,
+                                          Ecore_X_Randr_Output output);
+EAPI Ecore_X_Randr_Connector_Type
+ecore_x_randr_output_connector_type_get(Ecore_X_Window root,
+                                        Ecore_X_Randr_Output output);
+EAPI Eina_Rectangle *
+ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc,
+                                    int *x,
+                                    int *y,
+                                    int *w,
+                                    int *h);
+EAPI Eina_Bool
+ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc,
+                                    int x,
+                                    const int y,
+                                    const int w,
+                                    const int h);
+EAPI Eina_Rectangle *
+ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root,
+                                     Ecore_X_Randr_Crtc crtc,
+                                     int *x,
+                                     int *y,
+                                     int *w,
+                                     int *h);
+EAPI Eina_Bool
+ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root,
+                                     Ecore_X_Randr_Crtc crtc,
+                                     int x,
+                                     const int y,
+                                     const int w,
+                                     const int h);
+EAPI Eina_Rectangle *
+ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc);
+EAPI Eina_Bool
+ecore_x_randr_crtc_border_area_set(Ecore_X_Window root,
+                                   Ecore_X_Randr_Crtc crtc,
+                                   int left,
+                                   const int top,
+                                   const int right,
+                                   const int bottom);
 
 /* XRender Support (horrendously incomplete) */
 typedef Ecore_X_ID   Ecore_X_Picture;
index d4b068f..65303a4 100644 (file)
@@ -34,6 +34,9 @@ ecore_x.c \
 ecore_x_dnd.c \
 ecore_x_sync.c \
 ecore_x_randr.c \
+ecore_x_randr_11.c \
+ecore_x_randr_12.c \
+ecore_x_randr_13.c \
 ecore_x_fixes.c \
 ecore_x_damage.c \
 ecore_x_composite.c \
index 6486671..c33a5ef 100644 (file)
@@ -2246,13 +2246,13 @@ _ecore_x_event_handle_randr_change(XEvent *xevent)
 
    e->win = randr_event->window;
    e->root = randr_event->root;
-   e->width = randr_event->width;
-   e->height = randr_event->height;
+   e->size.width = randr_event->width;
+   e->size.height = randr_event->height;
    e->time = randr_event->timestamp;
    e->config_time = randr_event->config_timestamp;
-   e->mm_width = randr_event->mwidth;
-   e->mm_height = randr_event->mheight;
-   e->rotation = randr_event->rotation;
+   e->size.width_mm = randr_event->mwidth;
+   e->size.height_mm = randr_event->mheight;
+   e->orientation = randr_event->rotation;
    e->subpixel_order = randr_event->subpixel_order;
    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
 } /* _ecore_x_event_handle_randr_change */
@@ -2272,11 +2272,11 @@ _ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent)
    e->win = randr_event->window;
    e->crtc = randr_event->crtc;
    e->mode = randr_event->mode;
-   e->rotation = randr_event->rotation;
-   e->x = randr_event->x;
-   e->y = randr_event->y;
-   e->width = randr_event->width;
-   e->height = randr_event->height;
+   e->orientation = randr_event->rotation;
+   e->geo.x = randr_event->x;
+   e->geo.y = randr_event->y;
+   e->geo.w = randr_event->width;
+   e->geo.h = randr_event->height;
    ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
 } /* _ecore_x_event_handle_randr_notify_crtc_change */
 
@@ -2296,7 +2296,7 @@ _ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent)
    e->output = randr_event->output;
    e->crtc = randr_event->crtc;
    e->mode = randr_event->mode;
-   e->rotation = randr_event->rotation;
+   e->orientation = randr_event->rotation;
    e->connection = randr_event->connection;
    e->subpixel_order = randr_event->subpixel_order;
    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
diff --git a/src/lib/ecore_x/xlib/ecore_x_inline.x b/src/lib/ecore_x/xlib/ecore_x_inline.x
new file mode 100644 (file)
index 0000000..b3d02bc
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ECORE_X_INLINE_X
+#define ECORE_X_INLINE_X
+inline Eina_Bool _ecore_x_randr_root_validate(Ecore_X_Window root);
+inline Eina_Bool _ecore_x_randr_output_validate(Ecore_X_Window root,
+                                                Ecore_X_Randr_Output
+                                                output);
+#endif
index 35526ec..e193c99 100644 (file)
@@ -2,15 +2,27 @@
 # include <config.h>
 #endif /* ifdef HAVE_CONFIG_H */
 
-#include <stdlib.h>
-
 #include "ecore_x_private.h"
+#include "ecore_x_inline.x"
 
-static int _randr_available = 0;
+static Eina_Bool _randr_available = EINA_FALSE;
 #ifdef ECORE_XRANDR
-static int _randr_major, _randr_minor, _randr_version;
+static int _randr_major, _randr_minor;
+int _randr_version;
+#define RANDR_1_1 ((1 << 16) | 1)
 #define RANDR_1_2 ((1 << 16) | 2)
 #define RANDR_1_3 ((1 << 16) | 3)
+
+#define RANDR_VALIDATE_ROOT(screen, \
+                            root) ((screen = \
+                                       XRRRootToScreen(_ecore_x_disp, \
+                                                       root)) != -1)
+
+#define Ecore_X_Randr_Unset -1
+
+XRRScreenResources * (*_ecore_x_randr_get_screen_resources)(Display * dpy,
+                                                            Window window);
+
 #endif /* ifdef ECORE_XRANDR */
 
 void
@@ -21,313 +33,69 @@ _ecore_x_randr_init(void)
    _randr_minor = 3;
    _randr_version = 0;
 
+   _ecore_x_disp = _ecore_x_disp;
+   _ecore_x_randr_get_screen_resources = NULL;
    if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor))
-     {
-        _randr_version = (_randr_major << 16) | _randr_minor;
-        _randr_available = 1;
-     }
+   {
+      _randr_version = (_randr_major << 16) | _randr_minor;
+      if (_randr_version >= RANDR_1_3)
+         _ecore_x_randr_get_screen_resources = XRRGetScreenResourcesCurrent;
+      else if (_randr_version == RANDR_1_2)
+         _ecore_x_randr_get_screen_resources = XRRGetScreenResources;
+
+      _randr_available = EINA_TRUE;
+   }
    else
-      _randr_available = 0;
-
-#else /* ifdef ECORE_XRANDR */
-   _randr_available = 0;
-#endif /* ifdef ECORE_XRANDR */
-} /* _ecore_x_randr_init */
-
-EAPI int
+      _randr_available = EINA_FALSE;
+
+#else
+   _randr_available = EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief query whether randr is available or not
+ * @return EINA_TRUE, if extension is available, else EINA_FALSE
+ */
+EAPI const Eina_Bool
 ecore_x_randr_query(void)
 {
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
    return _randr_available;
-} /* ecore_x_randr_query */
+}
 
+/*
+ * @return version of the RandRR extension supported by the server or,
+ * in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1).
+ * bit version information: 31   MAJOR   16 | 15   MINOR   0
+ */
 EAPI int
-ecore_x_randr_events_select(Ecore_X_Window win, int on)
+ecore_x_randr_version_get(void)
 {
 #ifdef ECORE_XRANDR
-   int mask;
-
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   if (!on)
-      mask = 0;
+   if (_randr_available)
+   {
+      return _randr_version;
+   }
    else
-     {
-        mask = RRScreenChangeNotifyMask;
-        if (_randr_version >= RANDR_1_2)
-           mask |= (RRCrtcChangeNotifyMask |
-                    RROutputChangeNotifyMask |
-                    RROutputPropertyNotifyMask);
-     }
+   {
+      return Ecore_X_Randr_Unset;
+   }
 
-   XRRSelectInput(_ecore_x_disp, win, mask);
+#endif
+}
 
-   return 1;
-#else /* ifdef ECORE_XRANDR */
-   return 0;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_events_select */
-
-EAPI Ecore_X_Randr_Rotation
-ecore_x_randr_screen_rotations_get(Ecore_X_Window root)
+inline Eina_Bool
+_ecore_x_randr_root_validate(Ecore_X_Window root)
 {
 #ifdef ECORE_XRANDR
-   Rotation rot, crot;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   rot = XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
-                                                     root), &crot);
-   return rot;
-#else /* ifdef ECORE_XRANDR */
-   return 0;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_rotations_get */
-
-EAPI Ecore_X_Randr_Rotation
-ecore_x_randr_screen_rotation_get(Ecore_X_Window root)
-{
-#ifdef ECORE_XRANDR
-   Rotation crot = 0;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &crot);
-   return crot;
-#else /* ifdef ECORE_XRANDR */
-   return 0;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_rotation_get */
-
-EAPI void
-ecore_x_randr_screen_rotation_set(Ecore_X_Window         root,
-                                  Ecore_X_Randr_Rotation rot)
-{
-#ifdef ECORE_XRANDR
-   XRRScreenConfiguration *xrrcfg;
-   SizeID sizeid;
-   Rotation crot;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   xrrcfg = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (!xrrcfg)
-      return;
-
-   sizeid = XRRConfigCurrentConfiguration(xrrcfg, &crot);
-   XRRSetScreenConfig(_ecore_x_disp, xrrcfg, root, sizeid, rot, CurrentTime);
-   XRRFreeScreenConfigInfo(xrrcfg);
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_rotation_set */
-
-EAPI Ecore_X_Screen_Size *
-ecore_x_randr_screen_sizes_get(Ecore_X_Window root, int *num)
-{
-#ifdef ECORE_XRANDR
-   Ecore_X_Screen_Size *ret;
-   XRRScreenSize *sizes;
-   int i, n;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   if (num)
-      *num = 0;
-
-   /* we don't have to free sizes, no idea why not */
-   sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
-   ret = calloc(n, sizeof(Ecore_X_Screen_Size));
-   if (!ret)
-      return NULL;
-
-   if (num)
-      *num = n;
-
-   for (i = 0; i < n; i++)
-     {
-        ret[i].width = sizes[i].width;
-        ret[i].height = sizes[i].height;
-     }
-   return ret;
-#else /* ifdef ECORE_XRANDR */
-   if (num)
-      *num = 0;
-
-   return NULL;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_sizes_get */
-
-EAPI Ecore_X_Screen_Size
-ecore_x_randr_current_screen_size_get(Ecore_X_Window root)
-{
-   Ecore_X_Screen_Size ret = { -1, -1 };
-#ifdef ECORE_XRANDR
-   XRRScreenSize *sizes;
-   XRRScreenConfiguration *sc;
-   SizeID size_index;
-   Rotation rotation;
-   int n;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   sc = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (!sc)
-     {
-        ERR("Couldn't get screen information for %d", root);
-        return ret;
-     }
-
-   size_index = XRRConfigCurrentConfiguration(sc, &rotation);
-
-   sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
-   if (size_index < n)
-     {
-        ret.width = sizes[size_index].width;
-        ret.height = sizes[size_index].height;
-     }
-
-   XRRFreeScreenConfigInfo(sc);
-#endif /* ifdef ECORE_XRANDR */
-   return ret;
-} /* ecore_x_randr_current_screen_size_get */
-
-EAPI int
-ecore_x_randr_screen_size_set(Ecore_X_Window root, Ecore_X_Screen_Size size)
-{
-#ifdef ECORE_XRANDR
-   XRRScreenConfiguration *sc;
-   XRRScreenSize *sizes;
-   int i, n, size_index = -1;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
-   for (i = 0; i < n; i++)
-     {
-        if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
-          {
-             size_index = i;
-             break;
-          }
-     }
-   if (size_index == -1)
-      return 0;
-
-   sc = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (XRRSetScreenConfig(_ecore_x_disp, sc,
-                          root, size_index,
-                          RR_Rotate_0, CurrentTime))
-     {
-        ERR("Can't set new screen size!");
-        XRRFreeScreenConfigInfo(sc);
-        return 0;
-     }
-
-   XRRFreeScreenConfigInfo(sc);
-   return 1;
-#else /* ifdef ECORE_XRANDR */
-   return 0;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_size_set */
-
-EAPI Ecore_X_Screen_Refresh_Rate
-ecore_x_randr_current_screen_refresh_rate_get(Ecore_X_Window root)
-{
-   Ecore_X_Screen_Refresh_Rate ret = { -1 };
-#ifdef ECORE_XRANDR
-   XRRScreenConfiguration *sc;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   sc = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (!sc)
-     {
-        ERR("Couldn't get screen information for %d", root);
-        return ret;
-     }
-
-   ret.rate = XRRConfigCurrentRate(sc);
-   XRRFreeScreenConfigInfo(sc);
-#endif /* ifdef ECORE_XRANDR */
-   return ret;
-} /* ecore_x_randr_current_screen_refresh_rate_get */
-
-EAPI Ecore_X_Screen_Refresh_Rate *
-ecore_x_randr_screen_refresh_rates_get(Ecore_X_Window root,
-                                       int            size_id,
-                                       int           *num)
-{
-#ifdef ECORE_XRANDR
-   Ecore_X_Screen_Refresh_Rate *ret = NULL;
-   XRRScreenConfiguration *sc;
-   short *rates;
-   int i, n;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   if (num)
-      *num = 0;
-
-   sc = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (!sc)
-     {
-        ERR("Couldn't get screen information for %d", root);
-        return ret;
-     }
-
-   rates = XRRRates(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
-                                                   root), size_id, &n);
-   ret = calloc(n, sizeof(Ecore_X_Screen_Refresh_Rate));
-   if (!ret)
-     {
-        XRRFreeScreenConfigInfo(sc);
-        return NULL;
-     }
-
-   if (num)
-      *num = n;
-
-   for (i = 0; i < n; i++)
-     {
-        ret[i].rate = rates[i];
-     }
-   XRRFreeScreenConfigInfo(sc);
-   return ret;
-#else /* ifdef ECORE_XRANDR */
-   if (num)
-      *num = 0;
-
-   return NULL;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_refresh_rates_get */
-
-EAPI int
-ecore_x_randr_screen_refresh_rate_set(Ecore_X_Window              root,
-                                      Ecore_X_Screen_Size         size,
-                                      Ecore_X_Screen_Refresh_Rate rate)
-{
-#ifdef ECORE_XRANDR
-   XRRScreenConfiguration *sc;
-   XRRScreenSize *sizes;
-   int i, n, size_index = -1;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   sizes = XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, root), &n);
-   for (i = 0; i < n; i++)
-     {
-        if ((sizes[i].width == size.width) && (sizes[i].height == size.height))
-          {
-             size_index = i;
-             break;
-          }
-     }
-   if (size_index == -1)
-      return 0;
-
-   sc = XRRGetScreenInfo(_ecore_x_disp, root);
-   if (XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
-                                 root, size_index,
-                                 RR_Rotate_0, rate.rate, CurrentTime))
-     {
-        ERR("Can't set new screen size and refresh rate!");
-        XRRFreeScreenConfigInfo(sc);
-        return 0;
-     }
-
-   XRRFreeScreenConfigInfo(sc);
-   return 1;
-#else /* ifdef ECORE_XRANDR */
-   return 1;
-#endif /* ifdef ECORE_XRANDR */
-} /* ecore_x_randr_screen_refresh_rate_set */
+   Ecore_X_Randr_Screen scr = -1;
+   if (root && RANDR_VALIDATE_ROOT(scr, root))
+      return EINA_TRUE;
+   else
+      return EINA_FALSE;
 
+#else
+   return EINA_FALSE;
+#endif
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_11.c b/src/lib/ecore_x/xlib/ecore_x_randr_11.c
new file mode 100644 (file)
index 0000000..341146f
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* ifdef HAVE_CONFIG_H */
+
+#include "ecore_x_private.h"
+#include "ecore_x_inline.x"
+
+#define Ecore_X_Randr_None 0
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_1          ((1 << 16) | 1)
+
+#define RANDR_VALIDATE_ROOT(screen,\
+                            root) ((screen =\
+                                       XRRRootToScreen(_ecore_x_disp,\
+                                                       root)) != -1)
+#define RANDR_CHECK_1_1_RET(ret)  if(_randr_version < RANDR_1_1) return ret
+
+extern XRRScreenResources * (*_ecore_x_randr_get_screen_resources)(Display *
+                                                                   dpy,
+                                                                   Window
+                                                                   window);
+extern int _randr_version;
+#endif /* ifdef ECORE_XRANDR */
+
+/*
+ * @param root window which's primary output will be queried
+ */
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+   Rotation rot = Ecore_X_Randr_None, crot;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   rot =
+      XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+                                                        root), &crot);
+   return rot;
+#else /* ifdef ECORE_XRANDR */
+   return Ecore_X_Randr_None;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_orientations_get */
+
+/*
+ * @param root window which's primary output will be queried
+ * @return the current orientation of the root window's screen primary output
+ */
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+   Rotation crot = Ecore_X_Randr_None;
+   XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+                                                     root), &crot);
+   return crot;
+#else /* ifdef ECORE_XRANDR */
+   return Ecore_X_Randr_None;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_orientation_get */
+
+/*
+ * @brief sets a given screen's primary output's orientation
+ * @param root window which's screen's primary output will be queried
+ * @param orientation orientation which should be set for the root window's screen primary output
+ * @return EINA_TRUE if the primary output's orientation could be successfully altered
+ */
+EAPI Eina_Bool
+ecore_x_randr_screen_primary_output_orientation_set(
+   Ecore_X_Window root,
+   Ecore_X_Randr_Orientation
+   orientation)
+{
+#ifdef ECORE_XRANDR
+   XRRScreenConfiguration *xrr_screen_cfg = NULL;
+   int sizeid;
+   Rotation crot;
+   Eina_Bool ret = EINA_FALSE;
+   if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
+      return EINA_FALSE;
+
+   sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot);
+   if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid,
+                           orientation, CurrentTime))
+      ret = EINA_TRUE;
+
+   if (xrr_screen_cfg)
+      XRRFreeScreenConfigInfo(xrr_screen_cfg);
+
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_orientation_set */
+
+/*
+ * @brief gets a screen's primary output's possible sizes
+ * @param root window which's primary output will be queried
+ * @param num number of sizes reported as supported by the screen's primary output
+ * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL
+ */
+EAPI Ecore_X_Randr_Screen_Size_MM *
+ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num)
+{
+#ifdef ECORE_XRANDR
+   Ecore_X_Randr_Screen_Size_MM *ret = NULL;
+   XRRScreenSize *sizes;
+   int i, n;
+
+   /* we don't have to free sizes, because they're hold in a cache inside X*/
+   sizes =
+      XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+                                                    root), &n);
+   ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM));
+   if (!ret)
+      return NULL;
+
+   if (num)
+      *num = n;
+
+   for (i = 0; i < n; i++)
+     {
+        ret[i].width = sizes[i].width;
+        ret[i].height = sizes[i].height;
+        ret[i].width_mm = sizes[i].mwidth;
+        ret[i].height_mm = sizes[i].mheight;
+     }
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return NULL;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_sizes_get */
+
+/*
+ * @brief get the current set size of a given screen's primary output
+ * @param root window which's primary output will be queried
+ * @param w the current size's width
+ * @param h the current size's height
+ * @param w_mm the current size's width in mm
+ * @param h_mm the current size's height in mm
+ * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set()
+ */
+EAPI void
+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)
+{
+#ifdef ECORE_XRANDR
+   XRRScreenSize *sizes;
+   XRRScreenConfiguration *sc = NULL;
+   int index;
+   Rotation orientation;
+   int n;
+
+   if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+     {
+        ERR("Couldn't get screen information for %d", root);
+        return;
+     }
+
+   index = XRRConfigCurrentConfiguration(sc, &orientation);
+
+   sizes =
+      XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+                                                    root), &n);
+   if ((index < n) && (index >= 0))
+     {
+        if (w)
+           *w = sizes[index].width;
+
+        if (h)
+           *h = sizes[index].height;
+
+        if (w_mm)
+           *w_mm = sizes[index].mwidth;
+
+        if (h_mm)
+           *h_mm = sizes[index].mheight;
+
+        if (size_index)
+           *size_index = index;
+     }
+
+   XRRFreeScreenConfigInfo(sc);
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_current_size_get */
+
+/*
+ * @brief sets a given screen's primary output size, but disables all other outputs at the same time
+ * @param root window which's primary output will be queried
+ * @param size_index within the list of sizes reported as supported by the root window's screen primary output
+ * @return EINA_TRUE on success, EINA_FALSE on failure due to e.g. invalid times
+ */
+EAPI Eina_Bool
+ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root,
+                                             int            size_index)
+{
+#ifdef ECORE_XRANDR
+   XRRScreenConfiguration *sc = NULL;
+   XRRScreenSize *sizes;
+   Eina_Bool ret = EINA_FALSE;
+   int nsizes = 0;
+
+   if (size_index >= 0 && _ecore_x_randr_root_validate(root))
+     {
+        sizes =
+           XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
+                                                         root), &nsizes);
+
+        if (size_index < nsizes)
+          {
+             sc = XRRGetScreenInfo(_ecore_x_disp, root);
+             if (!XRRSetScreenConfig(_ecore_x_disp, sc,
+                                     root, size_index,
+                                     ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime))
+               {
+                  ret = EINA_TRUE;
+               }
+
+             if (sc)
+                XRRFreeScreenConfigInfo(sc);
+          }
+     }
+
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_size_set */
+
+/*
+ * @param root window which's primary output will be queried
+ * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0
+ */
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_screen_primary_output_current_refresh_rate_get(
+   Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+   Ecore_X_Randr_Refresh_Rate ret = 0.0;
+   XRRScreenConfiguration *sc = NULL;
+
+   if (!_ecore_x_randr_root_validate(root) ||
+       !(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+      return ret;
+
+   ret = XRRConfigCurrentRate(sc);
+   if (sc)
+      XRRFreeScreenConfigInfo(sc);
+
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return 0.0;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_current_refresh_rate_get */
+
+/*
+ * @param root window which's primary output will be queried
+ * @param size_index referencing the size to query valid refresh rates for
+ * @return currently used refresh rate or - if request failed or RandRR is not available - NULL
+ */
+EAPI Ecore_X_Randr_Refresh_Rate *
+ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root,
+                                                      int            size_index,
+                                                      int           *num)
+{
+#ifdef ECORE_XRANDR
+   Ecore_X_Randr_Refresh_Rate *ret = NULL, *rates = NULL;
+   Ecore_X_Randr_Screen scr;
+   int n;
+
+   if (num
+       && RANDR_VALIDATE_ROOT(scr, root)
+       && (rates = XRRRates(_ecore_x_disp, scr, size_index, &n)))
+     {
+        if (rates && (ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * n)))
+          {
+             memcpy(ret, rates, (sizeof(Ecore_X_Randr_Refresh_Rate) * n));
+             *num = n;
+          }
+     }
+
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return NULL;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_refresh_rates_get */
+
+//>= 1.1
+/*
+ * @brief sets the current primary output's refresh rate
+ * @param root window which's primary output will be queried
+ * @param size_index referencing the size to be set
+ * @param rate the refresh rate to be set
+ * @return EINA_TRUE on success else EINA_FALSE
+ */
+EAPI Eina_Bool
+ecore_x_randr_screen_primary_output_refresh_rate_set(
+   Ecore_X_Window root,
+   int            size_index,
+   Ecore_X_Randr_Refresh_Rate
+   rate)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_1_RET(EINA_FALSE);
+   Eina_Bool ret = EINA_FALSE;
+   XRRScreenConfiguration *sc = NULL;
+
+   if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
+      return ret;
+
+   if (!XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
+                                  root, size_index,
+                                  RR_Rotate_0, rate, CurrentTime))
+      ret = EINA_TRUE;
+
+   XRRFreeScreenConfigInfo(sc);
+   return ret;
+#else /* ifdef ECORE_XRANDR */
+   return EINA_FALSE;
+#endif /* ifdef ECORE_XRANDR */
+} /* ecore_x_randr_screen_primary_output_refresh_rate_set */
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/src/lib/ecore_x/xlib/ecore_x_randr_12.c
new file mode 100644 (file)
index 0000000..ea6e7b3
--- /dev/null
@@ -0,0 +1,1898 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+#include "ecore_x_inline.x"
+
+#define Ecore_X_Randr_None   0
+#define Ecore_X_Randr_Unset -1
+
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_2 ((1 << 16) | 2)
+
+#define RANDR_VALIDATE_ROOT(screen, \
+                            root) ((screen = \
+                                       XRRRootToScreen(_ecore_x_disp, \
+                                                       root)) != -1)
+#define RANDR_CHECK_1_2_RET(ret) if(_randr_version < RANDR_1_2) return ret
+
+#define RANDR_PROPERTY_EDID                     "EDID"
+#define RANDR_PROPERTY_BACKLIGHT                "Backlight"
+#define RANDR_PROPERTY_SIGNAL_FORMAT            "SignalFormat"
+#define RANDR_PROPERTY_SIGNAL_PROPERTIES        "SignalProperties"
+#define RANDR_PROPERTY_CONNECTOR_TYPE           "ConnectorType"
+#define RANDR_PROPERTY_CONNECTOR_NUMBER         "ConnectorNumber"
+#define RANDR_PROPERTY_COMPATIBILITY_LIST       "CompatibilityList"
+#define RANDR_PROPERTY_CLONE_LIST               "CloneList"
+
+extern XRRScreenResources * (*_ecore_x_randr_get_screen_resources)(Display *
+                                                                   dpy,
+                                                                   Window
+                                                                   window);
+extern int _randr_version;
+#endif
+
+/**
+ * @Brief enable event selection. This enables basic interaction with
+ * output/crtc events and requires RRandR >= 1.2.
+ * @param win select this window's properties for RandRR events
+ * @param on enable/disable selecting
+ */
+EAPI void
+ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on)
+{
+#ifdef ECORE_XRANDR
+   int mask;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   if (!on)
+      mask = 0;
+   else
+     {
+        mask = RRScreenChangeNotifyMask;
+        if (_randr_version >= RANDR_1_2)
+           mask |= (RRCrtcChangeNotifyMask |
+                    RROutputChangeNotifyMask |
+                    RROutputPropertyNotifyMask);
+     }
+
+   XRRSelectInput(_ecore_x_disp, win, mask);
+#endif
+}
+
+/**
+ * @brief validates a CRTC for a given root window's screen.
+ * @param root the window which's default display will be queried
+ * @param crtc the CRTC to be validated.
+ * @return in case it is found EINA_TRUE will be returned. Else EINA_FALSE is returned.
+ */
+static inline Eina_Bool
+_ecore_x_randr_crtc_validate(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   XRRScreenResources *res = NULL;
+   int i;
+   Eina_Bool ret = EINA_FALSE;
+
+   if ((crtc == Ecore_X_Randr_None) || (crtc == Ecore_X_Randr_Unset))
+      return ret;
+
+   if (_ecore_x_randr_root_validate(root) && crtc &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        for (i = 0; i < res->ncrtc; i++)
+          {
+             if (res->crtcs[i] == crtc)
+               {
+                  ret = EINA_TRUE;
+                  break;
+               }
+          }
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+inline Eina_Bool
+_ecore_x_randr_output_validate(Ecore_X_Window root, Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   Eina_Bool ret = EINA_FALSE;
+   XRRScreenResources *res = NULL;
+   int i;
+
+   if (_ecore_x_randr_root_validate(root) && output &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        for (i = 0; i < res->noutput; i++)
+          {
+             if (res->outputs[i] == output)
+               {
+                  ret = EINA_TRUE;
+                  break;
+               }
+          }
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+static inline Eina_Bool
+_ecore_x_randr_mode_validate(Ecore_X_Window root, Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   Eina_Bool ret = EINA_FALSE;
+   XRRScreenResources *res = NULL;
+   int i;
+
+   if (_ecore_x_randr_root_validate(root) && mode &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        for (i = 0; i < res->nmode; i++)
+          {
+             if (res->modes[i].id == mode)
+               {
+                  ret = EINA_TRUE;
+                  break;
+               }
+          }
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/*
+ * @param w width of screen in px
+ * @param h height of screen in px
+ */
+EAPI void
+ecore_x_randr_screen_current_size_get(Ecore_X_Window root,
+                                      int *w,
+                                      int *h,
+                                      int *w_mm,
+                                      int *h_mm)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   Ecore_X_Randr_Screen scr;
+
+   if (!RANDR_VALIDATE_ROOT(scr, root))
+      return;
+
+   if (w)
+      *w = DisplayWidth(_ecore_x_disp, scr);
+
+   if (h)
+      *h = DisplayHeight(_ecore_x_disp, scr);
+
+   if (w_mm)
+      *w_mm = DisplayWidthMM(_ecore_x_disp, scr);
+
+   if (h_mm)
+      *h_mm = DisplayHeightMM(_ecore_x_disp, scr);
+
+#endif
+}
+
+/*
+ * @param root window which's screen will be queried
+ * @param wmin minimum width the screen can be set to
+ * @param hmin minimum height the screen can be set to
+ * @param wmax maximum width the screen can be set to
+ * @param hmax maximum height the screen can be set to
+ */
+EAPI void
+ecore_x_randr_screen_size_range_get(Ecore_X_Window root,
+                                    int *wmin,
+                                    int *hmin,
+                                    int *wmax,
+                                    int *hmax)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   int twmin, thmin, twmax, thmax;
+   if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax,
+                              &thmax))
+     {
+        if (wmin)
+           *wmin = twmin;
+
+        if (hmin)
+           *hmin = thmin;
+
+        if (wmax)
+           *wmax = twmax;
+
+        if (hmax)
+           *hmax = thmax;
+     }
+
+#endif
+}
+
+/*
+ * @param root window which's screen's size should be set. If invalid (e.g. NULL) no action is taken.
+ * @param w width in px the screen should be set to. If out of valid boundaries, current value is assumed.
+ * @param h height in px the screen should be set to. If out of valid boundaries, current value is assumed.
+ * @param w_mm width in mm the screen should be set to. If 0, current aspect is assumed.
+ * @param h_mm height in mm the screen should be set to. If 0, current aspect is assumed.
+ * @return EINA_TRUE if request was successfully sent or screen is already in
+ * requested size, EINA_FALSE if parameters are invalid
+ */
+EAPI Eina_Bool
+ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
+                                      int w,
+                                      int h,
+                                      int w_mm,
+                                      int h_mm)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   Ecore_X_Randr_Screen scr;
+   int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax;
+
+   if (!RANDR_VALIDATE_ROOT(scr, root))
+      return EINA_FALSE;
+
+   ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c);
+   if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm))
+      return EINA_TRUE;
+
+   ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax);
+
+   if (((w != Ecore_X_Randr_None) &&
+        ((w < twmin) ||
+         (w > twmax))) ||
+       ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax))))
+      return EINA_FALSE;
+
+   if (w <= 0)
+      w = DisplayWidth(_ecore_x_disp, scr);
+
+   if (h <= 0)
+      h = DisplayHeight(_ecore_x_disp, scr);
+
+   if(w_mm <= 0)
+      w_mm =
+         (int)(((double)(DisplayWidthMM(_ecore_x_disp,
+                                        scr) /
+                         (double)DisplayWidth(_ecore_x_disp,
+                                              scr))) * (double)w);
+
+   if(h_mm <= 0)
+      h_mm =
+         (int)(((double)(DisplayHeightMM(_ecore_x_disp,
+                                         scr) /
+                         (double)DisplayHeight(_ecore_x_disp,
+                                               scr))) * (double)h);
+
+   XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm);
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/*
+ * @brief get detailed information for all modes related to a root window's screen
+ * @param root window which's screen's ressources are queried
+ * @param num number of modes returned
+ * @return modes' information
+ */
+EAPI Ecore_X_Randr_Mode_Info **
+ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Mode_Info **ret = NULL;
+   int i;
+
+   if (_ecore_x_randr_root_validate(root) &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        if ((ret =
+                (Ecore_X_Randr_Mode_Info **)malloc(sizeof(
+                                                      Ecore_X_Randr_Mode_Info *)
+                                                   *
+                                                   res->nmode)))
+          {
+             for (i = 0; i < res->nmode; i++)
+               {
+                  if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+                    {
+                       ret[i]->xid = res->modes[i].id;
+                       ret[i]->width = res->modes[i].width;
+                       ret[i]->height = res->modes[i].height;
+                       ret[i]->dotClock = res->modes[i].dotClock;
+                       ret[i]->hSyncStart = res->modes[i].hSyncStart;
+                       ret[i]->hSyncEnd = res->modes[i].hSyncEnd;
+                       ret[i]->hTotal = res->modes[i].hTotal;
+                       ret[i]->hSkew = res->modes[i].hSkew;
+                       ret[i]->vSyncStart = res->modes[i].vSyncStart;
+                       ret[i]->vSyncEnd = res->modes[i].vSyncEnd;
+                       ret[i]->vTotal = res->modes[i].vTotal;
+                       if ((ret[i]->name = (malloc(res->modes[i].nameLength))))
+                          strncpy(ret[i]->name, res->modes[i].name,
+                                  res->modes[i].nameLength);
+                       else
+                          ret[i]->name = NULL;
+
+                       ret[i]->nameLength = res->modes[i].nameLength;
+                       ret[i]->modeFlags = res->modes[i].modeFlags;
+                    }
+                  else
+                    {
+                       while(i > 0)
+                          free(ret[--i]);
+                          free(ret);
+                       ret = NULL;
+                       break;
+                    }
+               }
+          }
+
+        if (ret && num)
+           *num = res->nmode;
+
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+/*
+ * @brief get detailed information for a given mode id
+ * @param root window which's screen's ressources are queried
+ * @param mode the XID which identifies the mode of interest
+ * @return mode's detailed information
+ */
+EAPI Ecore_X_Randr_Mode_Info *
+ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Mode_Info *ret = NULL;
+   int i;
+
+   if (_ecore_x_randr_root_validate(root) &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        for (i = 0; i < res->nmode; i++)
+          {
+             if ((res->modes[i].id == mode) &&
+                 (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
+               {
+                  ret->xid = res->modes[i].id;
+                  ret->width = res->modes[i].width;
+                  ret->height = res->modes[i].height;
+                  ret->dotClock = res->modes[i].dotClock;
+                  ret->hSyncStart = res->modes[i].hSyncStart;
+                  ret->hSyncEnd = res->modes[i].hSyncEnd;
+                  ret->hTotal = res->modes[i].hTotal;
+                  ret->hSkew = res->modes[i].hSkew;
+                  ret->vSyncStart = res->modes[i].vSyncStart;
+                  ret->vSyncEnd = res->modes[i].vSyncEnd;
+                  ret->vTotal = res->modes[i].vTotal;
+                  if (!(ret->name =
+                           strndup(res->modes[i].name, res->modes[i].nameLength)))
+                    {
+                       ret->name = NULL;
+                       ret->nameLength = 0;
+                    }
+                  else
+                     ret->nameLength = res->modes[i].nameLength;
+
+                  ret->modeFlags = res->modes[i].modeFlags;
+                  break;
+               }
+          }
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+/*
+ * @brief free detailed mode information. The pointer handed in will be set to
+ * NULL after freeing the memory.
+ * @param mode_info the mode information that should be freed
+ */
+EAPI void
+ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   if (!mode_info)
+      return;
+
+   if (mode_info->name)
+      free(mode_info->name);
+
+      free(mode_info);
+   mode_info = NULL;
+#endif
+}
+
+/*
+ * @brief get all known CRTCs related to a root window's screen
+ * @param root window which's screen's ressources are queried
+ * @param num number of CRTCs returned
+ * @return CRTC IDs
+ */
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Crtc *ret = NULL;
+
+   if (num && root &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc)))
+          {
+             memcpy(ret, res->crtcs, (sizeof(Ecore_X_Randr_Crtc) * res->ncrtc));
+             *num = res->ncrtc;
+          }
+
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_outputs_get(Ecore_X_Window root, int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Output *ret = NULL;
+
+   if (num && root &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput)))
+          {
+             memcpy(ret, res->outputs,
+                    (sizeof(Ecore_X_Randr_Output) * res->noutput));
+             if (num)
+                *num = res->noutput;
+          }
+
+        if (res)
+           XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+//Per Crtc
+/*
+ * @brief get a CRTC's outputs.
+ * @param root the root window which's screen will be queried
+ * @param num number of outputs referenced by given CRTC
+ */
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
+                               Ecore_X_Randr_Crtc crtc,
+                               int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Output *ret = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res =
+           _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+                                                root)) &&
+       (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+     {
+        if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput)))
+          {
+             memcpy(ret, crtc_info->outputs,
+                    (sizeof(Ecore_X_Randr_Output) * crtc_info->noutput));
+             if (num)
+                *num = res->ncrtc;
+          }
+
+        if (crtc_info)
+           XRRFreeCrtcInfo(crtc_info);
+
+        if (res)
+           XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+/*
+ * @brief get a CRTC's possible outputs.
+ * @param root the root window which's screen will be queried
+ * @param num number of possible outputs referenced by given CRTC
+ */
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root,
+                                        Ecore_X_Randr_Crtc crtc,
+                                        int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Output *ret = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        if((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+          {
+             if ((ret =
+                     malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible)))
+               {
+                  memcpy(ret, crtc_info->possible,
+                         (sizeof(Ecore_X_Randr_Output) * crtc_info->npossible));
+                  if (num)
+                     *num = res->ncrtc;
+               }
+
+             XRRFreeCrtcInfo(crtc_info);
+          }
+
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+EAPI void
+ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
+                                Ecore_X_Randr_Crtc crtc,
+                                int *x,
+                                int *y,
+                                int *w,
+                                int *h)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res =
+           _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+                                                root)) &&
+       (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+     {
+        if (x)
+           *x = crtc_info->x;
+
+        if (y)
+           *y = crtc_info->y;
+
+        if (w)
+           *w = crtc_info->width;
+
+        if (h)
+           *h = crtc_info->height;
+
+        XRRFreeCrtcInfo(crtc_info);
+        XRRFreeScreenResources(res);
+     }
+
+#endif
+}
+
+/*
+ * @Brief sets the position of given CRTC within root window's screen
+ * @param root the window's screen to be queried
+ * @param crtc the CRTC which's position within the mentioned screen is to be altered
+ * @param x position on the x-axis (0 == left) of the screen. if x < 0 current value will be kept.
+ * @param y position on the y-ayis (0 == top) of the screen. if y < 0, current value will be kept.
+ * @return EINA_TRUE if position could be successfully be altered.
+ */
+EAPI Eina_Bool
+ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
+                           Ecore_X_Randr_Crtc crtc,
+                           int x,
+                           int y)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+   int w_c, h_c, w_new = 0, h_new = 0;
+   Eina_Rectangle crtc_geo;
+
+   ecore_x_randr_crtc_geometry_get(root,
+                                   crtc,
+                                   &crtc_geo.x,
+                                   &crtc_geo.y,
+                                   &crtc_geo.w,
+                                   &crtc_geo.h);
+   ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL);
+   if (x < 0)
+      x = crtc_geo.x;
+
+   if (y < 0)
+      y = crtc_geo.y;
+
+   if ((x + crtc_geo.w) > w_c)
+      w_new = x + crtc_geo.w;
+
+   if ((y + crtc_geo.h) > h_c)
+      h_new = y + crtc_geo.h;
+
+   if ((w_new != 0) || (h_new != 0))
+      if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0))
+         return EINA_FALSE;
+
+   return ecore_x_randr_crtc_settings_set(root,
+                                          crtc,
+                                          NULL,
+                                          Ecore_X_Randr_Unset,
+                                          x,
+                                          y,
+                                          Ecore_X_Randr_Unset,
+                                          Ecore_X_Randr_Unset);
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/**
+ * @Brief Get the current set mode of a given CRTC
+ * @param root the window's screen to be queried
+ * @param crtc the CRTC which's should be queried
+ * @return currently set mode or - in case parameters are invalid -
+ * Ecore_X_Randr_Unset
+ */
+EAPI Ecore_X_Randr_Mode
+ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+   Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
+   if (_ecore_x_randr_root_validate(root) &&
+       _ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res =
+           _ecore_x_randr_get_screen_resources(_ecore_x_disp,
+                                               root)) &&
+       (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+     {
+        ret = crtc_info->mode;
+        XRRFreeCrtcInfo(crtc_info);
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return Ecore_X_Randr_Unset;
+#endif
+}
+
+/**
+ * @Brief sets a mode for a CRTC and the outputs attached to it
+ * @param root the window's screen to be queried
+ * @param crtc the CRTC which shall be set
+ * @param outputs array of outputs which have to be compatible with the mode. If
+ * NULL CRTC will be disabled.
+ * @param noutputs number of outputs in array to be used. Use
+ * Ecore_X_Randr_Unset (or -1) to use currently used outputs.
+ * @para mode XID of the mode to be set. If set to 0 the CRTC will be disabled.
+ * If set to -1 the call will fail.
+ * @return EINA_TRUE if mode setting was successfull. Else EINA_FALSE
+ */
+EAPI Eina_Bool
+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)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   if (mode == Ecore_X_Randr_Unset)
+      return EINA_FALSE;
+
+   return ecore_x_randr_crtc_settings_set(root,
+                                          crtc,
+                                          outputs,
+                                          noutputs,
+                                          Ecore_X_Randr_Unset,
+                                          Ecore_X_Randr_Unset,
+                                          mode,
+                                          Ecore_X_Randr_Unset);
+#else
+   return EINA_FALSE;
+#endif
+}
+
+EAPI void
+ecore_x_randr_crtc_size_get(Ecore_X_Window root,
+                            Ecore_X_Randr_Crtc crtc,
+                            int *w,
+                            int *h)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
+#endif
+}
+
+EAPI Ecore_X_Randr_Refresh_Rate
+ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc,
+                                    Ecore_X_Randr_Mode mode)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(0.0);
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+   Ecore_X_Randr_Refresh_Rate ret = 0.0;
+   int i;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        for (i = 0; i < res->nmode; i++)
+           if (res->modes[i].id == mode)
+             {
+                if (res->modes[i].hTotal && res->modes[i].vTotal)
+                   ret = ((double)res->modes[i].dotClock /
+                          ((double)res->modes[i].hTotal *
+                           (double)res->modes[i].vTotal));
+
+                break;
+             }
+
+     }
+
+   if (crtc_info)
+      XRRFreeCrtcInfo(crtc_info);
+
+   if (res)
+      XRRFreeScreenResources(res);
+
+   return ret;
+#else
+   return 0.0;
+#endif
+}
+
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
+                                    Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+   XRRCrtcInfo *crtc_info = NULL;
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res =
+           _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+                                                root)) &&
+       (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+     {
+        ret = crtc_info->rotations;
+        if (crtc_info)
+           XRRFreeCrtcInfo(crtc_info);
+
+        if (res)
+           XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Ecore_X_Randr_Orientation
+ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+   XRRCrtcInfo *crtc_info = NULL;
+   XRRScreenResources *res = NULL;
+   Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res =
+           _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+                                                root)) &&
+       (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+     {
+        ret = crtc_info->rotation;
+        if (crtc_info)
+           XRRFreeCrtcInfo(crtc_info);
+
+        if (res)
+           XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
+                                   Ecore_X_Randr_Crtc crtc,
+                                   Ecore_X_Randr_Orientation orientation)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+   Eina_Bool ret = EINA_FALSE;
+
+   if (orientation != Ecore_X_Randr_None)
+     {
+        ret = ecore_x_randr_crtc_settings_set(root,
+                                              crtc,
+                                              NULL,
+                                              Ecore_X_Randr_Unset,
+                                              Ecore_X_Randr_Unset,
+                                              Ecore_X_Randr_Unset,
+                                              Ecore_X_Randr_Unset,
+                                              orientation);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+EAPI void
+ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
+                           Ecore_X_Randr_Crtc crtc,
+                           int *x,
+                           int *y)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+
+   ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
+#endif
+}
+
+EAPI Eina_Bool
+ecore_x_randr_crtc_clone_set(Ecore_X_Window root,
+                             Ecore_X_Randr_Crtc original,
+                             Ecore_X_Randr_Crtc clone)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *clone_crtc_info = NULL;
+   Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None;
+   Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None;
+   Eina_Bool ret = EINA_FALSE;
+   int x, y;
+
+   if (_ecore_x_randr_root_validate(root) &&
+           _ecore_x_randr_crtc_validate(root,
+                                    original) &&
+           _ecore_x_randr_crtc_validate(root,
+                                    clone) &&
+       (res =
+           _ecore_x_randr_get_screen_resources (_ecore_x_disp,
+                                                root)) &&
+       (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clone)))
+     {
+        ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL);
+        original_mode = ecore_x_randr_crtc_mode_get(root, original);
+        original_orientation = ecore_x_randr_crtc_orientation_get(root,
+                                                                  original);
+        ret = ecore_x_randr_crtc_settings_set(root,
+                                              clone,
+                                              NULL,
+                                              Ecore_X_Randr_Unset,
+                                              x,
+                                              y,
+                                              original_mode,
+                                              original_orientation);
+        XRRFreeCrtcInfo(clone_crtc_info);
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/**
+ * @brief sets the demanded parameters for a given CRTC. Note that the CRTC is
+ * auto enabled in it's preferred mode, when it was disabled before.
+ * @param root the root window which's default display will be queried
+ * @param crtc the CRTC which's configuration should be altered
+ * @param outputs an array of outputs, that should display this CRTC's content.
+ * @param noutputs number of outputs in the array of outputs.
+ * If set to Ecore_X_Randr_Unset, current outputs and number of outputs will be used.
+ * If set to Ecore_X_Randr_None, CRTC will be disabled
+ * @param x new x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
+ * corrdinate will be assumed.
+ * @param y new y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
+ * corrdinate will be assumed.
+ * @param mode the new mode to be set. If Ecore_X_Randr_None is passed, the
+ * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is assumed.
+ * @param orientation the new orientation to be set. If Ecore_X_Randr_Unset is used,
+ * the current mode is assumed.
+ * @return EINA_TRUE if the configuration alteration was successful, else
+ * EINA_FALSE
+ */
+EAPI Eina_Bool
+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)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *crtc_info = NULL;
+   Eina_Bool ret = EINA_FALSE;
+
+   if (_ecore_x_randr_crtc_validate(root,
+                                    crtc) &&
+       (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+     {
+        if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc)))
+          {
+             if ((mode == Ecore_X_Randr_None) ||
+                 (noutputs == Ecore_X_Randr_None))
+               {
+                  outputs = NULL;
+                  noutputs = 0;
+               }
+             else if (noutputs == Ecore_X_Randr_Unset)
+               {
+                  outputs = (Ecore_X_Randr_Output *)crtc_info->outputs;
+                  noutputs = crtc_info->noutput;
+               }
+
+             if (mode == Ecore_X_Randr_Unset)
+                mode = crtc_info->mode;
+
+             if (x < 0)
+                x = crtc_info->x;
+
+             if (y < 0)
+                y = crtc_info->y;
+
+             if (orientation == Ecore_X_Randr_Unset)
+                orientation = crtc_info->rotation;
+
+             if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime,
+                                   x, y, mode, orientation, (RROutput *)outputs,
+                                   noutputs))
+                ret = EINA_TRUE;
+
+             XRRFreeCrtcInfo(crtc_info);
+          }
+
+        XRRFreeScreenResources(res);
+     }
+
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/**
+ * @brief sets a CRTC relative to another one.
+ * @crtc_r1 the CRTC to be positioned.
+ * @crtc_r2 the CRTC the position should be relative to
+ * @position the relation between the crtcs
+ * @aligment in case CRTCs size differ, aligns CRTC1 accordingly at CRTC2's
+ * borders
+ * @return EINA_TRUE if crtc could be successfully positioned. EINA_FALSE if
+ * repositioning failed or if position of new crtc would be out of given screen's min/max bounds.
+ */
+EAPI Eina_Bool
+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)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+
+   Eina_Rectangle r1_geo, r2_geo;
+   int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n =
+      Ecore_X_Randr_Unset;
+   /*
+   int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h;
+   Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs;
+   Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode;
+   Eina_Bool ret;
+   */
+
+   if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None)
+       || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None))
+      return EINA_FALSE;
+
+   if (!_ecore_x_randr_crtc_validate(root,
+                                     crtc_r1) ||
+        (!(crtc_r1 != crtc_r2) &&
+       !_ecore_x_randr_crtc_validate(root, crtc_r2)))
+      return EINA_FALSE;
+
+   ecore_x_randr_crtc_geometry_get(root,
+                                   crtc_r1,
+                                   &r1_geo.x,
+                                   &r1_geo.y,
+                                   &r1_geo.w,
+                                   &r1_geo.h);
+   ecore_x_randr_crtc_geometry_get(root,
+                                   crtc_r2,
+                                   &r2_geo.x,
+                                   &r2_geo.y,
+                                   &r2_geo.w,
+                                   &r2_geo.h);
+   ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
+   ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
+
+   switch (policy)
+     {
+      case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
+         //set r1 right of r2
+         x_n = r2_geo.x + r2_geo.w;
+
+         switch (alignment)
+           {
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+               y_n = Ecore_X_Randr_Unset;
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+               y_n =
+                  ((int)(((double)r2_geo.h /
+                          2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0)));
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+               y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0));
+               break;
+           }
+         break;
+
+      case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
+         //set r1 left of r2
+         x_n = r2_geo.x - r1_geo.w;
+
+         switch (alignment)
+           {
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+               y_n = Ecore_X_Randr_Unset;
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+               y_n =
+                  ((int)(((double)r2_geo.h /
+                          2.0) + r2_geo.y - ((double)r1_geo.h / 2.0)));
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+               y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0)));
+               break;
+           }
+         break;
+
+      case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
+         //set r1 below r2
+         y_n = r2_geo.y + r2_geo.h;
+
+         switch (alignment)
+           {
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+               x_n = Ecore_X_Randr_Unset;
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+               x_n =
+                  ((int)((((double)r2_geo.x +
+                           (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+               x_n = ((int)((double)cw / 2.0));
+               break;
+           }
+         break;
+
+      case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
+         y_n = r2_geo.y - r1_geo.h;
+
+         //set r1 above r2
+         switch (alignment)
+           {
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE:
+               x_n = Ecore_X_Randr_Unset;
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL:
+               x_n =
+                  ((int)((((double)r2_geo.x +
+                           (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0)));
+               break;
+
+            case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR:
+               x_n = ((int)((double)cw / 2.0));
+               break;
+           }
+        break;
+
+      case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
+        return  ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y);
+
+        /* entire cloning (including modesetting)
+         //all outputs of crtc1 capable of crtc2's current mode?
+         r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
+         if (!(r1_outputs =
+                  ecore_x_randr_crtc_outputs_get(root, crtc_r1,
+                                                 &r1_noutputs)) ||
+             (r1_noutputs == 0))
+            return EINA_FALSE;
+
+         for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
+           {
+              if (!(r1_modes =
+                       ecore_x_randr_output_modes_get(root, r1_outputs[i],
+                                                      &r1_nmodes, NULL)))
+                {
+                   free(r1_outputs);
+                   return EINA_FALSE;
+                }
+
+              for (j = 0; j < r1_nmodes; j++)
+                {
+                   ecore_x_randr_mode_size_get(root,
+                                               r1_modes[j],
+                                               &mode_w,
+                                               &mode_h);
+                   if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h))
+                     {
+                        r1_mode = r1_modes[j];
+                        ++outputs_mode_found;
+                        free(r1_modes);
+                        r1_modes = NULL;
+                        break;
+                     }
+                }
+              if (r1_modes)
+                        free(r1_modes);
+
+              if (outputs_mode_found <= i)
+                {
+                   //an output doesn't support the set mode, cancel!
+                        free(r1_outputs);
+                   return EINA_FALSE;
+                }
+           }
+                        free (r1_outputs);
+         //CRTC 1's outputs support a mode of same geometry as CRTC 2.
+         ret =
+            (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None,
+                                         Ecore_X_Randr_None,
+                                         r1_mode) &&
+             ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y));
+         return ret;
+        */
+
+        /* entire cloning on same CRTC
+         //all outputs of crtc1 capable of crtc2's current mode?
+         r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2);
+         if (!(r1_outputs =
+                  ecore_x_randr_crtc_outputs_get(root, crtc_r1,
+                                                 &r1_noutputs)) ||
+             (r1_noutputs == 0))
+            return EINA_FALSE;
+
+         for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++)
+           {
+              if (!(r1_modes =
+                       ecore_x_randr_output_modes_get(root, r1_outputs[i],
+                                                      &r1_nmodes, NULL)))
+                {
+                        free(r1_outputs);
+                   return EINA_FALSE;
+                }
+
+              for (j = 0; j < r1_nmodes; j++)
+                {
+                   if (r1_modes[j] == r2_mode)
+                     {
+                        ++outputs_mode_found;
+                        free(r1_modes);
+                        r1_modes = NULL;
+                        break;
+                     }
+                }
+              if (r1_modes)
+                        free(r1_modes);
+
+              if (outputs_mode_found <= i)
+                {
+                   //an output doesn't support the set mode, cancel!
+                        free(r1_outputs);
+                   return EINA_FALSE;
+                }
+           }
+         //check whether crtc r2 can use all outputs of r1.
+         if (!(r2_outputs =
+                  ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2,
+                                                          &r2_noutputs)) ||
+             (r2_noutputs == 0))
+           {
+                   free(r1_outputs);
+              return EINA_FALSE;
+           }
+
+         for (i = 0; i < r1_noutputs; i++)
+           {
+              for (j = 0; j < r2_noutputs; )
+                {
+                   if (r1_outputs[i] == r2_outputs[j])
+                      break;
+
+                   j++;
+                }
+              if (j == r2_noutputs)
+                {
+                   //didn't find the output!
+                   free (r1_outputs);
+                   free (r2_outputs);
+                   return EINA_FALSE;
+                }
+           }
+
+         //apparently crtc2 supports all outputs of r1
+         //TODO: check with the compatible list of outputs (property in RR1.3)
+         r2_r1_outputs =
+            malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs));
+         for (i = 0; i < r1_noutputs; i++)
+           {
+              r2_r1_outputs[i] = r1_outputs[i];
+           }
+            free(r1_outputs);
+         for (; i < r2_noutputs; i++)
+           {
+              r2_r1_outputs[i] = r2_outputs[i];
+           }
+            free(r2_outputs);
+         ret =
+            ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs,
+                                        (r1_noutputs + r1_noutputs), r2_mode);
+         free (r2_r1_outputs);
+         return ret;
+        */
+     }
+   if ((x_n == r1_geo.x) && (y_n == r1_geo.x))
+      return EINA_TRUE;
+
+   //out of possible bounds?
+   if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max))
+      return EINA_FALSE;
+
+   return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n);
+#else
+   return EINA_FALSE;
+#endif
+}
+
+
+EAPI Ecore_X_Randr_Mode *
+ecore_x_randr_output_modes_get(Ecore_X_Window root,
+                               Ecore_X_Randr_Output output,
+                               int *num,
+                               int *npreferred)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   Ecore_X_Randr_Mode *modes = NULL;
+
+   if ((output != Ecore_X_Randr_None)
+       && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+       && (output_info =
+              XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
+     {
+        if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode)))
+          {
+             memcpy(modes, output_info->modes,
+                    (sizeof(Ecore_X_Randr_Mode) * output_info->nmode));
+             if (num)
+                *num = output_info->nmode;
+
+             if (npreferred)
+                *npreferred = output_info->npreferred;
+          }
+     }
+
+   if (output_info)
+      XRRFreeOutputInfo(output_info);
+
+   if (res)
+      XRRFreeScreenResources(res);
+
+   return modes;
+#else
+   return NULL;
+#endif
+}
+
+EAPI Ecore_X_Randr_Crtc *
+ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   Ecore_X_Randr_Crtc *crtcs = NULL;
+
+   if ((output != Ecore_X_Randr_None))
+     {
+       if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+         {
+            if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+              {
+                 if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)))
+                   {
+                      memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc));
+                      if (num) *num = output_info->ncrtc;
+                   }
+                 XRRFreeOutputInfo(output_info);
+              }
+            XRRFreeScreenResources(res);
+         }
+     }
+     return crtcs;
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+/**
+ * @brief gets the the outputs which might be used simultenously on the same
+ * CRTC.
+ * @root window that this information should be queried for.
+ * @output the output which's clones we concern
+ * @num number of possible clones
+ */
+EAPI Ecore_X_Randr_Output *
+ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   Ecore_X_Randr_Output *outputs = NULL;
+
+   if ((output != Ecore_X_Randr_None))
+     {
+       if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+         {
+            if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+              {
+                 if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone)))
+                   {
+                      memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone));
+                      if (num) *num = output_info->nclone;
+                   }
+                 XRRFreeOutputInfo(output_info);
+              }
+            XRRFreeScreenResources(res);
+         }
+     }
+     return outputs;
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+EAPI Ecore_X_Randr_Crtc
+ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
+
+   if ((output != Ecore_X_Randr_None))
+     {
+       if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+         {
+            if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+              {
+                 ret = output_info->crtc;
+                 XRRFreeOutputInfo(output_info);
+              }
+            XRRFreeScreenResources(res);
+         }
+     }
+
+   return ret;
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+/**
+ * @brief gets the given output's name as reported by X
+ * @param root the window which's screen will be queried
+ * @len length of returned c-string.
+ * @return name of the output as reported by X
+ */
+   EAPI char *
+ecore_x_randr_output_name_get(Ecore_X_Window root,
+      Ecore_X_Randr_Output output,
+      int *len)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   char *ret = NULL;
+
+   if ((output != Ecore_X_Randr_None)
+        && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+        && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+     {
+       /*
+        * Actually the bewow command is correct, but due to a bug in libXrandr
+        * it doesn't work. Therefor we stick with strlen().
+        * Replace the line below with the following once
+        * libXrandr >= git revision '25d793ab4ec111658e541c94eba4893a81d6a3b7'.
+        * is shipped and standard.
+        *
+        *    *len = output_info->nameLen;
+        *
+        */
+       if ((ret = strdup(output_info->name)) && len)
+         *len = strlen(ret);
+
+       XRRFreeOutputInfo(output_info);
+     }
+
+   if (res)
+     XRRFreeScreenResources(res);
+
+   return ret;
+#else
+   return NULL;
+#endif
+}
+
+/**
+ * @brief gets the width and hight of a given mode
+ * @param mode the mode which's size is to be looked up
+ * @w width of given mode in px
+ * @h height of given mode in px
+ */
+   EAPI void
+ecore_x_randr_mode_size_get(Ecore_X_Window root,
+      Ecore_X_Randr_Mode mode,
+      int *w,
+      int *h)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   XRRScreenResources *res = NULL;
+   int i;
+
+   if ((mode != Ecore_X_Randr_None)
+        && (w || h)
+        && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+     {
+       for (i = 0; i < res->nmode; i++)
+         {
+            if (res->modes[i].id == mode)
+              {
+                 if (w)
+                   *w = res->modes[i].width;
+
+                 if (h)
+                   *h = res->modes[i].height;
+
+                 break;
+              }
+         }
+     }
+
+   if (res)
+     XRRFreeScreenResources(res);
+
+#endif
+}
+
+/**
+ * @Brief gets the EDID information of an attached output if available.
+ * Note that this information is not to be compared using ordinary string
+ * comparison functions, since it includes 0-bytes.
+ * @param root window this information should be queried from
+ * @output the XID of the output
+ * @length length of the byte-array. If NULL, request will fail.
+ */
+EAPI unsigned char *
+ecore_x_randr_output_edid_get(Ecore_X_Window root,
+                              Ecore_X_Randr_Output output,
+                              unsigned long *length)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(NULL);
+   Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False);
+   unsigned char *prop_data, *ret = NULL;
+   int actual_format;
+   unsigned long nitems, bytes_after;
+   Atom actual_type;
+
+   if (!length || !_ecore_x_randr_output_validate(root, output))
+      return NULL;
+
+   if(XRRGetOutputProperty (_ecore_x_disp, output, name,
+                            0, 100, False, False,
+                            AnyPropertyType,
+                            &actual_type, &actual_format,
+                            &nitems, &bytes_after, &prop_data) == Success)
+     {
+        if (actual_type == XA_INTEGER && actual_format == 8)
+          {
+             if ((ret = malloc(nitems * sizeof(unsigned char))))
+               {
+                  if(length &&
+                     (memcpy(ret, prop_data, (nitems * sizeof(unsigned char)))))
+                     *length = nitems;
+
+                  return ret;
+               }
+          }
+     }
+
+   return NULL;
+#else
+   return NULL;
+#endif
+}
+
+EAPI Ecore_X_Randr_Connection_Status
+ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
+                                           Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+   Ecore_X_Randr_Connection_Status ret =
+      ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+
+   if ((output != Ecore_X_Randr_None)
+       && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))
+       && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output)))
+     {
+        ret = output_info->connection;
+     }
+
+   if (output_info)
+      XRRFreeOutputInfo(output_info);
+
+   if (res)
+      XRRFreeScreenResources(res);
+
+   return ret;
+#else
+   return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+#endif
+}
+
+EAPI void
+ecore_x_randr_output_size_mm_get(Ecore_X_Window root,
+                                 Ecore_X_Randr_Output output,
+                                 int *w_mm,
+                                 int *h_mm)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET();
+   XRRScreenResources *res = NULL;
+   XRROutputInfo *output_info = NULL;
+
+   if ((output != Ecore_X_Randr_None)
+       && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+     {
+        if ((output_info =
+                XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output)))
+          {
+             if (w_mm)
+                *w_mm = output_info->mm_width;
+
+             if (h_mm)
+                *h_mm = output_info->mm_height;
+
+             XRRFreeOutputInfo(output_info);
+          }
+
+        XRRFreeScreenResources(res);
+     }
+
+#endif
+}
+
+EAPI Eina_Bool
+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)
+{
+#ifdef ECORE_XRANDR
+   Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL;
+   XRRScreenResources *res = NULL;
+   int i, j, k, n;
+   Eina_Bool ret;
+
+
+   if ((nnot_moved <= 0) || (not_moved == NULL)
+       || !_ecore_x_randr_root_validate(root)
+       || !(res =
+               _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+      return EINA_FALSE;
+
+   n = (res->ncrtc - nnot_moved);
+   if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n)))
+     {
+        for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++)
+          {
+             for (j = 0; j < nnot_moved; j++)
+               {
+                  if (res->crtcs[i] == not_moved[j])
+                     break;
+               }
+             if (j == nnot_moved)
+                //crtcs[i] is not in the 'not to move'-list
+                crtcs_to_be_moved[k++] = res->crtcs[i];
+          }
+     }
+
+   XRRFreeScreenResources(res);
+   ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy);
+   free(crtcs_to_be_moved);
+   return ret;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/*
+ * @Brief move given CRTCs belonging to the given root window's screen dx/dy pixels relative to their current position. The screen size will be automatically adjusted if neccessary and possible.
+ * @param root window which's screen's resources are used
+ * @param crtcs list of CRTCs to be moved
+ * @param ncrtc number of CRTCs in array
+ * @param dx amount of pixels the CRTCs should be moved in x direction
+ * @param dy amount of pixels the CRTCs should be moved in y direction
+ * @return EINA_TRUE if all crtcs could be moved successfully.
+ */
+EAPI Eina_Bool
+ecore_x_randr_move_crtcs(Ecore_X_Window root,
+                         const Ecore_X_Randr_Crtc *crtcs,
+                         int ncrtc,
+                         int dx,
+                         int dy)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_2_RET(EINA_FALSE);
+   XRRScreenResources *res = NULL;
+   XRRCrtcInfo *crtc_info[ncrtc];
+   Eina_Bool ret = EINA_TRUE;
+   int i, cw, ch, w_max, h_max, nw, nh;
+
+   if (_ecore_x_randr_root_validate(root)
+       && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)))
+     {
+        ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
+        ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
+        nw = cw;
+        nh = ch;
+
+        for (i = 0;
+             (i < ncrtc) &&
+             (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i]));
+             i++)
+          {
+             if (((crtc_info[i]->x + dx) < 0) ||
+                 ((crtc_info[i]->x + crtc_info[i]->width + dx) > w_max)
+                 || ((crtc_info[i]->y + dy) < 0) ||
+                 ((crtc_info[i]->y + crtc_info[i]->height + dy) > h_max)
+                 )
+                goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
+
+             nw = MAX((crtc_info[i]->x + crtc_info[i]->width + dx), nw);
+             nh = MAX((crtc_info[i]->y + crtc_info[i]->height + dy), nh);
+          }
+        //not out of bounds
+
+        //resize if necessary
+        if (!(((nw > cw) ||
+               (nh > ch)) ||
+              ecore_x_randr_screen_current_size_set(root, nw, nh,
+                                                    Ecore_X_Randr_Unset,
+                                                    Ecore_X_Randr_Unset)))
+           goto _ecore_x_randr_move_crtcs_fail_free_crtc_info;
+
+        //actually move all the crtcs, keep their rotation and mode.
+        for (i = 0; i < ncrtc; i++)
+          {
+             if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL,
+                                                  Ecore_X_Randr_Unset,
+                                                  (crtc_info[i]->x + dx),
+                                                  (crtc_info[i]->y + dy),
+                                                  crtc_info[i]->mode,
+                                                  crtc_info[i]->rotation))
+               {
+                  ret = EINA_FALSE;
+                  break;
+               }
+          }
+        if (i < ncrtc)
+          {
+             //something went wrong, let's try to move the already moved crtcs
+             //back.
+             while (i-- >= 0)
+                ecore_x_randr_crtc_settings_set(root,
+                                                crtcs[i],
+                                                NULL,
+                                                Ecore_X_Randr_Unset,
+                                                (crtc_info[i]->x - dx),
+                                                (crtc_info[i]->y - dy),
+                                                crtc_info[i]->mode,
+                                                crtc_info[i]->rotation);
+          }
+
+        for (i = 0; i < ncrtc; i++)
+          {
+             XRRFreeCrtcInfo(crtc_info[i]);
+          }
+     }
+
+   XRRFreeScreenResources(res);
+
+   return ret;
+_ecore_x_randr_move_crtcs_fail_free_crtc_info:
+   while (i-- > 0)
+      XRRFreeCrtcInfo(crtc_info[i]);
+   XRRFreeScreenResources(res);
+   return EINA_FALSE;
+#else
+   return EINA_FALSE;
+#endif
+}
+
+/**
+ * @brief removes unused screen space. The most upper left CRTC is set to 0x0
+ * and all other CRTCs dx,dy respectively.
+ * @param root the window's screen which will be reset.
+ */
+EAPI void
+ecore_x_randr_screen_reset(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+   XRRCrtcInfo *crtc_info = NULL;
+   XRRScreenResources *res = NULL;
+   //the 100000 are just a random huge number.
+   int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0;
+
+   if (!_ecore_x_randr_root_validate(root) ||
+       !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)))
+      return;
+
+   Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc];
+
+   for (i = 0; i < res->ncrtc; i++)
+     {
+        if (!(crtc_info =
+                 XRRGetCrtcInfo(_ecore_x_disp, res,
+                                res->crtcs[i])) ||
+            (crtc_info->mode == Ecore_X_Randr_None) ||
+            (crtc_info->mode == Ecore_X_Randr_Unset)
+            || ((crtc_info->noutput == 0)))
+           continue;
+
+       enabled_crtcs[nenabled_crtcs++] = res->crtcs[i];
+
+        if ((crtc_info->x + crtc_info->width) > w_n)
+           w_n = (crtc_info->x + crtc_info->width);
+
+        if ((crtc_info->y + crtc_info->height) > h_n)
+           h_n = (crtc_info->y + crtc_info->height);
+
+       if (crtc_info->x < dx_min)
+         dx_min = crtc_info->x;
+       if (crtc_info->y < dy_min)
+         dy_min = crtc_info->y;
+
+        XRRFreeCrtcInfo(crtc_info);
+     }
+   fprintf(stderr, "E_RANDR: babam, resize! Trying to move all CRTCs with dx %d and dy %d", dx_min, dy_min);
+   if ((dx_min > 0) || (dy_min > 0))
+     {
+       if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min))
+         {
+            w_n -= dx_min;
+            h_n -= dy_min;
+         }
+     }
+   ecore_x_randr_screen_current_size_set(root,
+                                         w_n,
+                                         h_n,
+                                         Ecore_X_Randr_Unset,
+                                         Ecore_X_Randr_Unset);
+#endif
+}
diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_13.c b/src/lib/ecore_x/xlib/ecore_x_randr_13.c
new file mode 100644 (file)
index 0000000..6e23730
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ecore_x_private.h"
+#include "ecore_x_inline.x"
+
+#define Ecore_X_Randr_None   0
+#define Ecore_X_Randr_Unset -1
+
+#ifdef ECORE_XRANDR
+
+#define RANDR_1_3 ((1 << 16) | 3)
+#define RANDR_CHECK_1_3_RET(ret) if(_randr_version < RANDR_1_3) return ret
+
+extern XRRScreenResources * (*_ecore_x_randr_get_screen_resources)(Display *
+                                                                   dpy,
+                                                                   Window
+                                                                   window);
+extern int _randr_version;
+#endif
+
+/*
+ * @param root window which's screen should be queried
+ * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None
+ */
+EAPI Ecore_X_Randr_Output
+ecore_x_randr_primary_output_get(Ecore_X_Window root)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_3_RET(Ecore_X_Randr_None);
+   if (!_ecore_x_randr_root_validate(root))
+      return Ecore_X_Randr_None;
+
+   return XRRGetOutputPrimary(_ecore_x_disp, root);
+#else
+   return Ecore_X_Randr_None;
+#endif
+}
+
+/*
+ * @param root window which's screen should be queried
+ * @param output that should be set as given root window's screen primary output
+ */
+EAPI void
+ecore_x_randr_primary_output_set(Ecore_X_Window root,
+                                 Ecore_X_Randr_Output output)
+{
+#ifdef ECORE_XRANDR
+   RANDR_CHECK_1_3_RET();
+
+   if (_ecore_x_randr_output_validate(root, output))
+     {
+        XRRSetOutputPrimary(_ecore_x_disp, root, output);
+     }
+
+#endif
+}