diff --git a/legacy/ecore/configure.in b/legacy/ecore/configure.in index 07d8b70785..c824a518c7 100644 --- a/legacy/ecore/configure.in +++ b/legacy/ecore/configure.in @@ -365,6 +365,38 @@ CFLAGS=$PCFLAGS AC_SUBST(Xinerama_cflags) AC_SUBST(Xinerama_libs) +Xrandr_libs="" +Xrandr_cflags="" +use_Xrandr="no" +PCFLAGS=$CFLAGS +CFLAGS=$x_cflags" "$x_includes +AC_CHECK_HEADER(X11/extensions/Xrandr.h, [ + AC_CHECK_LIB(Xrandr, XRRSizes, [ + AC_DEFINE(ECORE_XRANDR, 1, [Build support for Xrandr]) + Xrandr_cflags="" + Xrandr_libs="-lXrandr" + use_Xrandr="yes" + ], [ + Xrandr_cflags="" + Xrandr_libs="" + use_Xrandr="no" + ], [ + $x_libs $x_ldflags + ] + ) + ], [ + Xrandr_cflags="" + Xrandr_libs="" + use_Xrandr="no" + ], [ + #include + ] +) +CFLAGS=$PCFLAGS + +AC_SUBST(Xrandr_cflags) +AC_SUBST(Xrandr_libs) + AC_SUBST(ecore_x_cflags) AC_SUBST(ecore_x_libs) @@ -1024,7 +1056,7 @@ echo echo " Ecore_Job...............: $have_ecore_job" echo " Ecore_Con...............: $have_ecore_con (OpenSSL: $use_openssl)" echo " Ecore_Txt...............: $have_ecore_txt" -echo " Ecore_X.................: $have_ecore_x (Xcursor: $use_Xcursor) (Xprint: $use_Xprint) (Xinerama: $use_Xinerama)" +echo " Ecore_X.................: $have_ecore_x (Xcursor: $use_Xcursor) (Xprint: $use_Xprint) (Xinerama: $use_Xinerama) (Xrandr: $use_Xrandr)" echo " Ecore_FB................: $have_ecore_fb" echo " Ecore_Evas..............: $have_ecore_evas" echo " Ecore_Evas GL Support...: $have_ecore_evas_gl" diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h index 68ff1dd609..14a0a2937a 100644 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ b/legacy/ecore/src/lib/ecore_x/Ecore_X.h @@ -245,6 +245,7 @@ typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Mess typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape; 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_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; @@ -637,6 +638,12 @@ struct _Ecore_X_Event_Sync_Alarm Ecore_X_Sync_Alarm alarm; }; +struct _Ecore_X_Event_Screen_Change +{ + Ecore_X_Window win, root; + int width, height; +}; + struct _Ecore_X_Event_Window_Delete_Request { Ecore_X_Window win; @@ -771,6 +778,7 @@ extern EAPI int ECORE_X_EVENT_CLIENT_MESSAGE; extern EAPI int ECORE_X_EVENT_WINDOW_SHAPE; extern EAPI int ECORE_X_EVENT_SYNC_COUNTER; extern EAPI int ECORE_X_EVENT_SYNC_ALARM; +extern EAPI int ECORE_X_EVENT_SCREEN_CHANGE; extern EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST; /* @@ -1313,6 +1321,19 @@ EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y); EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); +/* ecore_x_randr.c */ +typedef struct _Ecore_X_Screen_Size Ecore_X_Screen_Size; +struct _Ecore_X_Screen_Size +{ + int width, height; +}; + +EAPI int ecore_x_randr_events_select(Ecore_X_Window win, int on); +EAPI Ecore_X_Screen_Size *ecore_x_randr_screen_sizes_get(Ecore_X_Window root, int *num); +EAPI int ecore_x_randr_screen_size_set(Ecore_X_Window root, + Ecore_X_Screen_Size *size); + + #ifdef __cplusplus } #endif diff --git a/legacy/ecore/src/lib/ecore_x/Makefile.am b/legacy/ecore/src/lib/ecore_x/Makefile.am index 6b3bac9c23..8d60e9d144 100644 --- a/legacy/ecore/src/lib/ecore_x/Makefile.am +++ b/legacy/ecore/src/lib/ecore_x/Makefile.am @@ -4,6 +4,7 @@ INCLUDES = \ @Xcursor_cflags@ \ @Xprint_cflags@ \ @Xinerama_cflags@ \ +@Xrandr_cflags@ \ @x_cflags@ \ -I$(top_srcdir)/src/lib/ecore \ -I$(top_srcdir)/src/lib/ecore_txt \ @@ -29,6 +30,7 @@ libecore_x_la_SOURCES = \ ecore_x.c \ ecore_x_dnd.c \ ecore_x_sync.c \ +ecore_x_randr.c \ ecore_x_error.c \ ecore_x_events.c \ ecore_x_icccm.c \ @@ -48,6 +50,7 @@ libecore_x_la_LIBADD = \ @Xcursor_libs@ \ @Xprint_libs@ \ @Xinerama_libs@ \ +@Xrandr_libs@ \ @x_ldflags@ \ @x_libs@ \ $(top_builddir)/src/lib/ecore/libecore.la \ @@ -68,6 +71,7 @@ Ecore_X_Cursor.h \ ecore_x.c \ ecore_x_dnd.c \ ecore_x_sync.c \ +ecore_x_randr.c \ ecore_x_error.c \ ecore_x_events.c \ ecore_x_icccm.c \ diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x.c b/legacy/ecore/src/lib/ecore_x/ecore_x.c index 2d52bc3fad..6eb6cd6cb6 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x.c @@ -18,6 +18,9 @@ static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL; static Ecore_Event_Filter *_ecore_x_filter_handler = NULL; static int _ecore_x_event_shape_id = 0; static int _ecore_x_event_sync_id = 0; +#ifdef ECORE_XRANDR +static int _ecore_x_event_randr_id = 0; +#endif static int _ecore_x_event_handlers_num = 0; static void (**_ecore_x_event_handlers) (XEvent * event) = NULL; @@ -120,6 +123,7 @@ int ECORE_X_EVENT_CLIENT_MESSAGE = 0; int ECORE_X_EVENT_WINDOW_SHAPE = 0; int ECORE_X_EVENT_SYNC_COUNTER = 0; int ECORE_X_EVENT_SYNC_ALARM = 0; +int ECORE_X_EVENT_SCREEN_CHANGE = 0; int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0; /* @@ -177,6 +181,10 @@ ecore_x_init(const char *name) int shape_err_base = 0; int sync_base = 0; int sync_err_base = 0; +#ifdef ECORE_XRANDR + int randr_base = 0; + int randr_err_base = 0; +#endif if (_ecore_x_init_count > 0) { @@ -204,6 +212,13 @@ ecore_x_init(const char *name) if (_ecore_x_event_sync_id + XSyncAlarmNotify >= LASTEvent) _ecore_x_event_handlers_num = _ecore_x_event_sync_id + XSyncAlarmNotify + 1; +#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 >= LASTEvent) + _ecore_x_event_handlers_num = _ecore_x_event_randr_id + 1; +#endif + _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *)); if (!_ecore_x_event_handlers) { @@ -256,6 +271,10 @@ ecore_x_init(const char *name) _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] = _ecore_x_event_handle_sync_alarm; } +#ifdef ECORE_XRANDR + if (_ecore_x_event_randr_id) + _ecore_x_event_handlers[_ecore_x_event_randr_id] = _ecore_x_event_handle_randr_change; +#endif if (!ECORE_X_EVENT_KEY_DOWN) { ECORE_X_EVENT_KEY_DOWN = ecore_event_type_new(); @@ -293,6 +312,7 @@ ecore_x_init(const char *name) ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new(); 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_WINDOW_DELETE_REQUEST = ecore_event_type_new(); /* @@ -303,7 +323,7 @@ ecore_x_init(const char *name) ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new(); - ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new(); */ ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new(); @@ -853,15 +873,20 @@ ecore_x_window_root_list(int *num_ret) { int num, i; Ecore_X_Window *roots; +#ifdef ECORE_XPRINT + int xp_base, xp_err_base; +#endif if (!num_ret) return NULL; *num_ret = 0; + #ifdef ECORE_XPRINT + num = ScreenCount(_ecore_x_disp); + if (XpQueryExtension(_ecore_x_disp, &xp_base, &xp_err_base)) { Screen **ps = NULL; int psnum = 0; - num = ScreenCount(_ecore_x_disp); ps = XpQueryScreens(_ecore_x_disp, &psnum); if (ps) { @@ -914,6 +939,14 @@ ecore_x_window_root_list(int *num_ret) roots[i] = RootWindow(_ecore_x_disp, i); } } + else + { + roots = malloc(num * sizeof(Window)); + if (!roots) return NULL; + *num_ret = num; + for (i = 0; i < num; i++) + roots[i] = RootWindow(_ecore_x_disp, i); + } #else num = ScreenCount(_ecore_x_disp); roots = malloc(num * sizeof(Window)); diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c index ca1504b8b1..d3874e1f1b 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c @@ -1581,3 +1581,25 @@ _ecore_x_event_handle_sync_alarm(XEvent *xevent) e->alarm = sync_alarm_event->alarm; ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL); } + +#ifdef ECORE_XRANDR +void +_ecore_x_event_handle_randr_change(XEvent *xevent) +{ + XRRScreenChangeNotifyEvent *randr_event; + Ecore_X_Event_Screen_Change *e; + + randr_event = (XRRScreenChangeNotifyEvent *)xevent; + if (!XRRUpdateConfiguration(xevent)) + printf("ERROR: Can't update RR config!\n"); + + e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)); + if (!e) return; + e->win = randr_event->window; + e->root = randr_event->root; + e->width = randr_event->width; + e->height = randr_event->height; + ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); +} +#endif + diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_private.h b/legacy/ecore/src/lib/ecore_x/ecore_x_private.h index bc9d87b615..89e398e112 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_private.h +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_private.h @@ -27,6 +27,9 @@ #ifdef ECORE_XINERAMA #include #endif +#ifdef ECORE_XRANDR +#include +#endif #include "Ecore_X.h" @@ -179,6 +182,9 @@ void _ecore_x_event_handle_mapping_notify(XEvent *xevent); void _ecore_x_event_handle_shape_change(XEvent *xevent); 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); +#endif void _ecore_x_selection_data_init(void); void _ecore_x_selection_shutdown(void); diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_randr.c b/legacy/ecore/src/lib/ecore_x/ecore_x_randr.c new file mode 100644 index 0000000000..a201f7f6d4 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_randr.c @@ -0,0 +1,84 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include +#include "ecore_x_private.h" + +int +ecore_x_randr_events_select(Ecore_X_Window win, int on) +{ +#ifdef ECORE_XRANDR + if (on) + XRRSelectInput(_ecore_x_disp, win, RRScreenChangeNotifyMask); + else + XRRSelectInput(_ecore_x_disp, win, 0); + + return 1; +#else + return 0; +#endif +} + +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; + + 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 + if (num) *num = 0; + return NULL; +#endif +} + +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; + + 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; + + printf("Size: %d\n", size_index); + sc = XRRGetScreenInfo(_ecore_x_disp, root); + if (XRRSetScreenConfig(_ecore_x_disp, sc, + root, size_index, + RR_Rotate_0, CurrentTime)) + { + printf("ERROR: Can't set new screen size!\n"); + XRRFreeScreenConfigInfo(sc); + return 0; + } + XRRFreeScreenConfigInfo(sc); + return 1; +#else + return 0; +#endif +}