From e3c2dad2b5774fa324dfbb9c37281a9be64bbcf8 Mon Sep 17 00:00:00 2001 From: barbieri Date: Sat, 2 May 2009 23:34:29 +0000 Subject: [PATCH] xrandr1.3 support: first steps (events). starting to implement xrandr 1.3 support, now we support all events and their fields. This commit also fix way that extensions register their ids and base. The way it was, ids was being added to the last event id, that was wrong! Fortunately, those that were wrong had just one event and always added "0", making no harm. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@40492 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore_x/Ecore_X.h | 73 ++++++++++++++++++++++++++-- src/lib/ecore_x/xlib/ecore_x.c | 59 +++++++++++++---------- src/lib/ecore_x/xlib/ecore_x_events.c | 87 ++++++++++++++++++++++++++++++++++ src/lib/ecore_x/xlib/ecore_x_private.h | 2 + src/lib/ecore_x/xlib/ecore_x_randr.c | 49 ++++++++++++++----- 5 files changed, 231 insertions(+), 39 deletions(-) diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 04cc139..8b2e857 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -67,6 +67,11 @@ typedef void Ecore_X_Screen; typedef Ecore_X_ID Ecore_X_Sync_Counter; typedef Ecore_X_ID Ecore_X_Sync_Alarm; +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; + #ifdef __cplusplus extern "C" { #endif @@ -168,6 +173,21 @@ typedef enum _Ecore_X_Randr_Rotation { 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_Render_Subpixel_Order { + ECORE_X_RENDER_SUBPIXEL_ORDER_UNKNOWN = 0, + ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_RGB = 1, + ECORE_X_RENDER_SUBPIXEL_ORDER_HORIZONTAL_BGR = 2, + ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_RGB = 3, + ECORE_X_RENDER_SUBPIXEL_ORDER_VERTICAL_BGR = 4, + ECORE_X_RENDER_SUBPIXEL_ORDER_NONE = 5 +} Ecore_X_Render_Subpixel_Order; + #define ECORE_X_SELECTION_TARGET_TARGETS "TARGETS" #define ECORE_X_SELECTION_TARGET_TEXT "TEXT" #define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT" @@ -299,6 +319,9 @@ typedef struct _Ecore_X_Event_Screensaver_Notify Ecore_X_Event_Screensaver typedef struct _Ecore_X_Event_Sync_Counter Ecore_X_Event_Sync_Counter; typedef struct _Ecore_X_Event_Sync_Alarm Ecore_X_Event_Sync_Alarm; typedef struct _Ecore_X_Event_Screen_Change Ecore_X_Event_Screen_Change; +typedef struct _Ecore_X_Event_Randr_Crtc_Change Ecore_X_Event_Randr_Crtc_Change; +typedef struct _Ecore_X_Event_Randr_Output_Change Ecore_X_Event_Randr_Output_Change; +typedef struct _Ecore_X_Event_Randr_Output_Property_Notify Ecore_X_Event_Randr_Output_Property_Notify; typedef struct _Ecore_X_Event_Window_Delete_Request Ecore_X_Event_Window_Delete_Request; typedef struct _Ecore_X_Event_Window_Prop_Title_Change Ecore_X_Event_Window_Prop_Title_Change; @@ -647,8 +670,49 @@ struct _Ecore_X_Event_Sync_Alarm struct _Ecore_X_Event_Screen_Change { - Ecore_X_Window win, root; - int width, height; + Ecore_X_Window win; + Ecore_X_Window root; + int width; + int height; + 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_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; +}; + +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; +}; + +struct _Ecore_X_Event_Randr_Output_Property_Notify +{ + Ecore_X_Window win; + Ecore_X_Randr_Output output; + Ecore_X_Atom property; + Ecore_X_Time time; + int state; /* NewValue, Deleted */ }; struct _Ecore_X_Event_Window_Delete_Request @@ -792,6 +856,9 @@ EAPI extern int ECORE_X_EVENT_SCREENSAVER_NOTIFY; EAPI extern int ECORE_X_EVENT_SYNC_COUNTER; EAPI extern int ECORE_X_EVENT_SYNC_ALARM; EAPI extern int ECORE_X_EVENT_SCREEN_CHANGE; +EAPI extern int ECORE_X_EVENT_RANDR_CRTC_CHANGE; +EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE; +EAPI extern int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY; EAPI extern int ECORE_X_EVENT_DAMAGE_NOTIFY; EAPI extern int ECORE_X_EVENT_WINDOW_DELETE_REQUEST; @@ -1566,7 +1633,7 @@ struct _Ecore_X_Screen_Refresh_Rate int rate; }; -EAPI int ecore_x_randr_query(); +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); diff --git a/src/lib/ecore_x/xlib/ecore_x.c b/src/lib/ecore_x/xlib/ecore_x.c index 5dd7938..8536c9a 100644 --- a/src/lib/ecore_x/xlib/ecore_x.c +++ b/src/lib/ecore_x/xlib/ecore_x.c @@ -93,7 +93,9 @@ EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0; EAPI int ECORE_X_EVENT_SYNC_ALARM = 0; EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0; EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0; - +EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0; +EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0; +EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0; EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0; /* EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0; @@ -175,19 +177,23 @@ ecore_x_init(const char *name) if (!_ecore_x_disp) return 0; _ecore_x_error_handler_init(); _ecore_x_event_handlers_num = LASTEvent; - + +#define ECORE_X_EVENT_HANDLERS_GROW(ext_base, ext_num_events) \ + do { \ + if (_ecore_x_event_handlers_num < (ext_base + ext_num_events)) \ + _ecore_x_event_handlers_num = (ext_base + ext_num_events); \ + } while (0) + if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base)) - _ecore_x_event_shape_id = shape_base + ShapeNotify; - if (_ecore_x_event_shape_id >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_shape_id + 1; - + _ecore_x_event_shape_id = shape_base; + ECORE_X_EVENT_HANDLERS_GROW(shape_base, ShapeNumberEvents); + #ifdef ECORE_XSS if (XScreenSaverQueryExtension(_ecore_x_disp, &screensaver_base, &screensaver_err_base)) - _ecore_x_event_screensaver_id = screensaver_base + ScreenSaverNotify; -#endif - if (_ecore_x_event_screensaver_id >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_screensaver_id + 1; - + _ecore_x_event_screensaver_id = screensaver_base; +#endif + ECORE_X_EVENT_HANDLERS_GROW(screensaver_base, ScreenSaverNumberEvents); + if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base)) { int major, minor; @@ -196,28 +202,24 @@ ecore_x_init(const char *name) if (!XSyncInitialize(_ecore_x_disp, &major, &minor)) _ecore_x_event_sync_id = 0; } - if (_ecore_x_event_sync_id + XSyncAlarmNotify >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_sync_id + XSyncAlarmNotify + 1; - + ECORE_X_EVENT_HANDLERS_GROW(sync_base, XSyncNumberEvents); + #ifdef ECORE_XRANDR if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base)) - _ecore_x_event_randr_id = randr_base + RRScreenChangeNotify; - if (_ecore_x_event_randr_id >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_randr_id + 1; + _ecore_x_event_randr_id = randr_base; + ECORE_X_EVENT_HANDLERS_GROW(randr_base, RRNumberEvents); #endif #ifdef ECORE_XFIXES if (XFixesQueryExtension(_ecore_x_disp, &fixes_base, &fixes_err_base)) - _ecore_x_event_fixes_selection_id = fixes_base + XFixesSelectionNotify; - if (_ecore_x_event_fixes_selection_id >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_fixes_selection_id + 1; + _ecore_x_event_fixes_selection_id = fixes_base; + ECORE_X_EVENT_HANDLERS_GROW(fixes_base, XFixesNumberEvents); #endif #ifdef ECORE_XDAMAGE if (XDamageQueryExtension(_ecore_x_disp, &damage_base, &damage_err_base)) - _ecore_x_event_damage_id = damage_base + XDamageNotify; - if (_ecore_x_event_damage_id >= _ecore_x_event_handlers_num) - _ecore_x_event_handlers_num = _ecore_x_event_damage_id + 1; + _ecore_x_event_damage_id = damage_base; + ECORE_X_EVENT_HANDLERS_GROW(damage_base, XDamageNumberEvents); #endif _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *)); @@ -277,7 +279,10 @@ ecore_x_init(const char *name) } #ifdef ECORE_XRANDR if (_ecore_x_event_randr_id) - _ecore_x_event_handlers[_ecore_x_event_randr_id] = _ecore_x_event_handle_randr_change; + { + _ecore_x_event_handlers[_ecore_x_event_randr_id + RRScreenChangeNotify] = _ecore_x_event_handle_randr_change; + _ecore_x_event_handlers[_ecore_x_event_randr_id + RRNotify] = _ecore_x_event_handle_randr_notify; + } #endif #ifdef ECORE_XFIXES if (_ecore_x_event_fixes_selection_id) @@ -334,6 +339,9 @@ ecore_x_init(const char *name) ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new(); ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new(); ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new(); ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new(); ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new(); @@ -426,7 +434,8 @@ ecore_x_init(const char *name) _ecore_x_damage_init(); _ecore_x_composite_init(); _ecore_x_dpms_init(); - + _ecore_x_randr_init(); + _ecore_x_init_count++; _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456); diff --git a/src/lib/ecore_x/xlib/ecore_x_events.c b/src/lib/ecore_x/xlib/ecore_x_events.c index 8838778..81d24c8 100644 --- a/src/lib/ecore_x/xlib/ecore_x_events.c +++ b/src/lib/ecore_x/xlib/ecore_x_events.c @@ -1852,8 +1852,95 @@ _ecore_x_event_handle_randr_change(XEvent *xevent) e->root = randr_event->root; e->width = randr_event->width; e->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->subpixel_order = randr_event->subpixel_order; ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); } + +static void +_ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent) +{ + const XRRCrtcChangeNotifyEvent *randr_event; + Ecore_X_Event_Randr_Crtc_Change *e; + + randr_event = (const XRRCrtcChangeNotifyEvent *)xevent; + + e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)); + if (!e) return; + 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; + ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL); +} + +static void +_ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent) +{ + const XRROutputChangeNotifyEvent *randr_event; + Ecore_X_Event_Randr_Output_Change *e; + + randr_event = (const XRROutputChangeNotifyEvent *)xevent; + + e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change)); + if (!e) return; + e->win = randr_event->window; + e->output = randr_event->output; + e->crtc = randr_event->crtc; + e->mode = randr_event->mode; + e->rotation = randr_event->rotation; + e->connection = randr_event->connection; + e->subpixel_order = randr_event->subpixel_order; +} + +static void +_ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent *xevent) +{ + const XRROutputPropertyNotifyEvent *randr_event; + Ecore_X_Event_Randr_Output_Property_Notify *e; + + randr_event = (const XRROutputPropertyNotifyEvent *)xevent; + + e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify)); + if (!e) return; + e->win = randr_event->window; + e->output = randr_event->output; + e->property = randr_event->property; + e->time = randr_event->timestamp; + e->state = randr_event->state; +} + +void +_ecore_x_event_handle_randr_notify(XEvent *xevent) +{ + const XRRNotifyEvent *randr_event; + + randr_event = (const XRRNotifyEvent *)xevent; + switch (randr_event->subtype) + { + case RRNotify_CrtcChange: + _ecore_x_event_handle_randr_notify_crtc_change(randr_event); + break; + case RRNotify_OutputChange: + _ecore_x_event_handle_randr_notify_output_change(randr_event); + break; + case RRNotify_OutputProperty: + _ecore_x_event_handle_randr_notify_output_property(randr_event); + break; + default: + fprintf(stderr, "ERROR: unknown XRandR RRNotify subtype: %d.\n", + randr_event->subtype); + break; + } +} #endif #ifdef ECORE_XFIXES diff --git a/src/lib/ecore_x/xlib/ecore_x_private.h b/src/lib/ecore_x/xlib/ecore_x_private.h index 3bd0027..3d74bdd 100644 --- a/src/lib/ecore_x/xlib/ecore_x_private.h +++ b/src/lib/ecore_x/xlib/ecore_x_private.h @@ -208,6 +208,7 @@ void _ecore_x_event_handle_sync_counter(XEvent *xevent); void _ecore_x_event_handle_sync_alarm(XEvent *xevent); #ifdef ECORE_XRANDR void _ecore_x_event_handle_randr_change(XEvent *xevent); +void _ecore_x_event_handle_randr_notify(XEvent *xevent); #endif #ifdef ECORE_XFIXES void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent); @@ -248,6 +249,7 @@ void _ecore_x_fixes_init(void); void _ecore_x_damage_init(void); void _ecore_x_composite_init(void); void _ecore_x_dpms_init(void); +void _ecore_x_randr_init(void); void _ecore_x_atoms_init(void); diff --git a/src/lib/ecore_x/xlib/ecore_x_randr.c b/src/lib/ecore_x/xlib/ecore_x_randr.c index 4fc211e..580b49d 100644 --- a/src/lib/ecore_x/xlib/ecore_x_randr.c +++ b/src/lib/ecore_x/xlib/ecore_x_randr.c @@ -10,30 +10,57 @@ #include "ecore_x_private.h" -EAPI int -ecore_x_randr_query() +static int _randr_available = 0; +#ifdef ECORE_XRANDR +static int _randr_major, _randr_minor, _randr_version; +#define RANDR_1_2 ((1 << 16) | 2) +#define RANDR_1_3 ((1 << 16) | 3) +#endif + +void +_ecore_x_randr_init(void) { #ifdef ECORE_XRANDR - int randr_base = 0; - int randr_err_base = 0; + _randr_major = 1; + _randr_minor = 3; + _randr_version = 0; - if (XRRQueryExtension(_ecore_x_disp, &randr_base, &randr_err_base)) - return 1; + if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor)) + { + _randr_version = (_randr_major << 16) | _randr_minor; + _randr_available = 1; + } else - return 0; + _randr_available = 0; #else - return 0; + _randr_available = 0; #endif } EAPI int +ecore_x_randr_query(void) +{ + return _randr_available; +} + +EAPI int ecore_x_randr_events_select(Ecore_X_Window win, int on) { #ifdef ECORE_XRANDR - if (on) - XRRSelectInput(_ecore_x_disp, win, RRScreenChangeNotifyMask); + int mask; + + if (!on) + mask = 0; else - XRRSelectInput(_ecore_x_disp, win, 0); + { + mask = RRScreenChangeNotifyMask; + if (_randr_version >= RANDR_1_2) + mask |= (RRCrtcChangeNotifyMask | + RROutputChangeNotifyMask | + RROutputPropertyNotifyMask); + } + + XRRSelectInput(_ecore_x_disp, win, mask); return 1; #else -- 2.7.4