Compare commits
	
		
			73 Commits
		
	
	
		
			wip/csd-fl
			...
			wip/multit
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | bdfb8609a3 | ||
|   | 141a353a52 | ||
|   | 15186016c2 | ||
|   | bd77a67ea4 | ||
|   | 2a9a499841 | ||
|   | 50aa509ee1 | ||
|   | 0eefb6b306 | ||
|   | d115c90ed1 | ||
|   | 83096642f0 | ||
|   | a65c4e993e | ||
|   | e73a566eeb | ||
|   | 46ef055da5 | ||
|   | 45450c2fa3 | ||
|   | afa4c643a8 | ||
|   | 5d1c302b18 | ||
|   | 53b289ce25 | ||
|   | 776628fde2 | ||
|   | b9f5185c90 | ||
|   | 7555b092eb | ||
|   | f46ef5f6e0 | ||
|   | 0e182c7c3d | ||
|   | 84b9d5c9f9 | ||
|   | 8e3b9be79c | ||
|   | 74520ab20b | ||
|   | 40c2b0c5bb | ||
|   | 40ec37eed0 | ||
|   | 4e6e40de87 | ||
|   | 319208f859 | ||
|   | f670a4f348 | ||
|   | 57dff10ab5 | ||
|   | 53bd0c70c9 | ||
|   | 2507d20bb7 | ||
|   | 7d5e7ec3e6 | ||
|   | 0b8848057b | ||
|   | 0b841f8940 | ||
|   | 61b120d08c | ||
|   | 2aa39eb4fd | ||
|   | dc5b813608 | ||
|   | df044a0035 | ||
|   | 154730a3d9 | ||
|   | 557ed7ac0b | ||
|   | bce2bc0568 | ||
|   | 7c86cb85ba | ||
|   | ab58d87142 | ||
|   | e62076f055 | ||
|   | 1e8f10826a | ||
|   | cca79a77da | ||
|   | 67018d2d04 | ||
|   | 199395a395 | ||
|   | ad911d6cce | ||
|   | daeaf44e02 | ||
|   | ec587190e8 | ||
|   | 22a44bf007 | ||
|   | e1679cb35b | ||
|   | 5da2ff0f4e | ||
|   | a547596be4 | ||
|   | bb7d549136 | ||
|   | e800da2bca | ||
|   | 3def650a93 | ||
|   | 48f59d88fa | ||
|   | 01e77bae9d | ||
|   | 66e9720cb7 | ||
|   | 3a8837f8ab | ||
|   | cc4f66bc8a | ||
|   | 90287cb3f6 | ||
|   | 0c317e8ced | ||
|   | 33c829ee39 | ||
|   | e92757ac8b | ||
|   | 08f06ba012 | ||
|   | e49cbb3614 | ||
|   | 98e95ed5e8 | ||
|   | 5338134b49 | ||
|   | f5aab9398b | 
							
								
								
									
										46
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								configure.in
									
									
									
									
									
								
							| @@ -225,6 +225,50 @@ if test x$have_xcursor = xyes; then | ||||
|   AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) | ||||
| fi | ||||
|  | ||||
| XINPUT2_VERSION=1.4.0 | ||||
|  | ||||
| AC_ARG_ENABLE(xinput2, | ||||
|   AC_HELP_STRING([--disable-xinput2], | ||||
|                  [disable XInput2 usage]),, | ||||
|   enable_xinput2=yes) | ||||
|  | ||||
| if test x$enable_xinput2 = xyes; then | ||||
|   AC_MSG_CHECKING([XInput2]) | ||||
|   if $PKG_CONFIG --atleast-version $XINPUT2_VERSION xi; then | ||||
|     have_xinput2=yes | ||||
|   else | ||||
|     have_xinput2=no | ||||
|   fi | ||||
|   AC_MSG_RESULT($have_xinput2) | ||||
| else | ||||
|   have_xinput2=no | ||||
| fi | ||||
|  | ||||
| if test x$have_xinput2 = xyes; then | ||||
|   echo "Building with XInput2" | ||||
|   MUTTER_PC_MODULES="$MUTTER_PC_MODULES xi" | ||||
|   AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support]) | ||||
| fi | ||||
|  | ||||
| AM_CONDITIONAL(HAVE_XINPUT2, test "$have_xinput2" = "yes") | ||||
|  | ||||
| if test x$have_xinput2 = xyes; then | ||||
|   mutter_save_libs="$LIBS" | ||||
|   LIBS="-lXi $LIBS" | ||||
|  | ||||
|   AC_CHECK_FUNC(XIAllowTouchEvents, | ||||
|                 have_xtouch=yes, | ||||
|                 have_xtouch=no) | ||||
|  | ||||
|   LIBS="$mutter_save_libs" | ||||
| else | ||||
|   have_xtouch=no | ||||
| fi | ||||
|  | ||||
| if test x$have_xtouch = xyes; then | ||||
|   AC_DEFINE(HAVE_XTOUCH, , [Building with X touch events]) | ||||
| fi | ||||
|  | ||||
| PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES) | ||||
|  | ||||
| AC_PATH_XTRA | ||||
| @@ -544,6 +588,8 @@ mutter-$VERSION | ||||
| 	Shape extension:          ${found_shape} | ||||
| 	Xsync:                    ${found_xsync} | ||||
| 	Xcursor:                  ${have_xcursor} | ||||
| 	XInput2:                  ${have_xinput2} | ||||
| 	Touch events:             ${have_xtouch} | ||||
| " | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -78,6 +78,20 @@ libmutter_la_SOURCES =				\ | ||||
| 	core/constraints.h			\ | ||||
| 	core/core.c				\ | ||||
| 	core/delete.c				\ | ||||
| 	core/device.c				\ | ||||
| 	meta/device.h				\ | ||||
| 	core/device-keyboard.c			\ | ||||
| 	core/device-keyboard.h			\ | ||||
| 	core/device-pointer.c			\ | ||||
| 	core/device-pointer.h			\ | ||||
| 	core/device-private.h			\ | ||||
| 	core/device-map.c			\ | ||||
| 	meta/device-map.h			\ | ||||
| 	core/device-map-private.h		\ | ||||
| 	core/device-map-core.c			\ | ||||
| 	core/device-map-core.h			\ | ||||
| 	core/devices-core.c			\ | ||||
| 	core/devices-core.h			\ | ||||
| 	core/display.c				\ | ||||
| 	core/display-private.h			\ | ||||
| 	meta/display.h				\ | ||||
| @@ -100,6 +114,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	meta/group.h				\ | ||||
| 	core/iconcache.c			\ | ||||
| 	core/iconcache.h			\ | ||||
| 	core/input-events.c			\ | ||||
| 	core/input-events.h			\ | ||||
| 	core/keybindings.c			\ | ||||
| 	core/keybindings-private.h		\ | ||||
| 	core/main.c				\ | ||||
| @@ -157,6 +173,14 @@ libmutter_la_SOURCES =				\ | ||||
| 	ui/preview-widget.c			\ | ||||
| 	$(mutter_built_sources) | ||||
|  | ||||
| if HAVE_XINPUT2 | ||||
| libmutter_la_SOURCES += 			\ | ||||
| 	core/device-map-xi2.c			\ | ||||
| 	core/device-map-xi2.h			\ | ||||
| 	core/devices-xi2.c			\ | ||||
| 	core/devices-xi2.h | ||||
| endif | ||||
|  | ||||
| libmutter_la_LDFLAGS = -no-undefined | ||||
| libmutter_la_LIBADD  = $(MUTTER_LIBS) | ||||
|  | ||||
| @@ -167,6 +191,8 @@ libmutterinclude_base_headers =		\ | ||||
| 	meta/common.h				\ | ||||
| 	meta/compositor-mutter.h		\ | ||||
| 	meta/compositor.h			\ | ||||
| 	meta/device.h				\ | ||||
| 	meta/device-map.h			\ | ||||
| 	meta/display.h				\ | ||||
| 	meta/errors.h				\ | ||||
| 	meta/gradient.h				\ | ||||
|   | ||||
| @@ -18,6 +18,8 @@ | ||||
| #include "meta-background-actor-private.h" | ||||
| #include "window-private.h" /* to check window->hidden */ | ||||
| #include "display-private.h" /* for meta_display_lookup_x_window() */ | ||||
| #include "core.h" /* for meta_core_select_events() */ | ||||
| #include "input-events.h" | ||||
| #include <X11/extensions/shape.h> | ||||
| #include <X11/extensions/Xcomposite.h> | ||||
|  | ||||
| @@ -155,7 +157,6 @@ get_output_window (MetaScreen *screen) | ||||
|   MetaDisplay *display = meta_screen_get_display (screen); | ||||
|   Display     *xdisplay = meta_display_get_xdisplay (display); | ||||
|   Window       output, xroot; | ||||
|   XWindowAttributes attr; | ||||
|   long         event_mask; | ||||
|  | ||||
|   xroot = meta_screen_get_xroot (screen); | ||||
| @@ -169,13 +170,7 @@ get_output_window (MetaScreen *screen) | ||||
|                KeyPressMask | KeyReleaseMask; | ||||
|  | ||||
|   output = XCompositeGetOverlayWindow (xdisplay, xroot); | ||||
|  | ||||
|   if (XGetWindowAttributes (xdisplay, output, &attr)) | ||||
|       { | ||||
|         event_mask |= attr.your_event_mask; | ||||
|       } | ||||
|  | ||||
|   XSelectInput (xdisplay, output, event_mask); | ||||
|   meta_core_select_events (xdisplay, output, event_mask, TRUE); | ||||
|  | ||||
|   return output; | ||||
| } | ||||
| @@ -347,26 +342,34 @@ meta_begin_modal_for_plugin (MetaScreen       *screen, | ||||
|    * merge the two. | ||||
|    */ | ||||
|   MetaDisplay    *display    = meta_screen_get_display (screen); | ||||
|   Display        *xdpy       = meta_display_get_xdisplay (display); | ||||
|   MetaCompositor *compositor = display->compositor; | ||||
|   gboolean pointer_grabbed = FALSE; | ||||
|   gboolean keyboard_grabbed = FALSE; | ||||
|   int result; | ||||
|   gboolean result; | ||||
|   MetaDevice     *device; | ||||
|   MetaGrabInfo   *grab_info; | ||||
|  | ||||
|   if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) | ||||
|   /* FIXME: need a real device here, and probably | ||||
|    * some exclusion mode for other devices */ | ||||
|   device = meta_device_map_lookup (display->device_map, | ||||
|                                    META_CORE_POINTER_ID); | ||||
|  | ||||
|   grab_info = meta_display_get_grab_info (display, device); | ||||
|  | ||||
|   if (compositor->modal_plugin != NULL || grab_info != NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) | ||||
|     { | ||||
|       result = XGrabPointer (xdpy, grab_window, | ||||
|                              False, /* owner_events */ | ||||
|                              (ButtonPressMask | ButtonReleaseMask | | ||||
|                               EnterWindowMask | LeaveWindowMask | PointerMotionMask), | ||||
|                              GrabModeAsync, GrabModeAsync, | ||||
|                              None, /* confine to */ | ||||
|                              cursor, | ||||
|                              timestamp); | ||||
|       if (result != Success) | ||||
|       result = meta_device_grab (device, | ||||
|                                  grab_window, | ||||
|                                  (ButtonPressMask | ButtonReleaseMask | | ||||
|                                   EnterWindowMask | LeaveWindowMask | PointerMotionMask), | ||||
|                                  cursor, | ||||
|                                  FALSE, | ||||
|                                  FALSE, | ||||
|                                  timestamp); | ||||
|       if (!result) | ||||
|         goto fail; | ||||
|  | ||||
|       pointer_grabbed = TRUE; | ||||
| @@ -374,22 +377,25 @@ meta_begin_modal_for_plugin (MetaScreen       *screen, | ||||
|  | ||||
|   if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0) | ||||
|     { | ||||
|       result = XGrabKeyboard (xdpy, grab_window, | ||||
|                               False, /* owner_events */ | ||||
|                               GrabModeAsync, GrabModeAsync, | ||||
|                               timestamp); | ||||
|  | ||||
|       if (result != Success) | ||||
|       result = meta_device_grab (meta_device_get_paired_device (device), | ||||
|                                  grab_window, | ||||
|                                  (KeyPressMask | KeyReleaseMask), | ||||
|                                  META_CURSOR_DEFAULT, | ||||
|                                  FALSE, FALSE, | ||||
|                                  timestamp); | ||||
|       if (!result) | ||||
|         goto fail; | ||||
|  | ||||
|       keyboard_grabbed = TRUE; | ||||
|     } | ||||
|  | ||||
|   display->grab_op = META_GRAB_OP_COMPOSITOR; | ||||
|   display->grab_window = NULL; | ||||
|   display->grab_screen = screen; | ||||
|   display->grab_have_pointer = TRUE; | ||||
|   display->grab_have_keyboard = TRUE; | ||||
|   grab_info = meta_display_create_grab_info (display, device); | ||||
|  | ||||
|   grab_info->grab_op = META_GRAB_OP_COMPOSITOR; | ||||
|   grab_info->grab_window = NULL; | ||||
|   grab_info->grab_screen = screen; | ||||
|   grab_info->grab_have_pointer = TRUE; | ||||
|   grab_info->grab_have_keyboard = TRUE; | ||||
|  | ||||
|   compositor->modal_plugin = plugin; | ||||
|  | ||||
| @@ -397,9 +403,9 @@ meta_begin_modal_for_plugin (MetaScreen       *screen, | ||||
|  | ||||
|  fail: | ||||
|   if (pointer_grabbed) | ||||
|     XUngrabPointer (xdpy, timestamp); | ||||
|     meta_device_ungrab (device, timestamp); | ||||
|   if (keyboard_grabbed) | ||||
|     XUngrabKeyboard (xdpy, timestamp); | ||||
|     meta_device_ungrab (meta_device_get_paired_device (device), timestamp); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
| @@ -410,20 +416,19 @@ meta_end_modal_for_plugin (MetaScreen     *screen, | ||||
|                            guint32         timestamp) | ||||
| { | ||||
|   MetaDisplay    *display    = meta_screen_get_display (screen); | ||||
|   Display        *xdpy = meta_display_get_xdisplay (display); | ||||
|   MetaCompositor *compositor = display->compositor; | ||||
|   MetaDevice     *device; | ||||
|  | ||||
|   g_return_if_fail (compositor->modal_plugin == plugin); | ||||
|  | ||||
|   XUngrabPointer (xdpy, timestamp); | ||||
|   XUngrabKeyboard (xdpy, timestamp); | ||||
|   /* FIXME: need a real device here */ | ||||
|   device = meta_device_map_lookup (display->device_map, | ||||
|                                    META_CORE_POINTER_ID); | ||||
|  | ||||
|   display->grab_op = META_GRAB_OP_NONE; | ||||
|   display->grab_window = NULL; | ||||
|   display->grab_screen = NULL; | ||||
|   display->grab_have_pointer = FALSE; | ||||
|   display->grab_have_keyboard = FALSE; | ||||
|   meta_device_ungrab (device, timestamp); | ||||
|   meta_device_ungrab (meta_device_get_paired_device (device), timestamp); | ||||
|  | ||||
|   meta_display_remove_grab_info (display, device); | ||||
|   compositor->modal_plugin = NULL; | ||||
| } | ||||
|  | ||||
| @@ -456,7 +461,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor, | ||||
|   Window          xroot         = meta_screen_get_xroot (screen); | ||||
|   Window          xwin; | ||||
|   gint            width, height; | ||||
|   XWindowAttributes attr; | ||||
|   long            event_mask; | ||||
|   guint           n_retries; | ||||
|   guint           max_retries; | ||||
| @@ -531,12 +535,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor, | ||||
|                KeyPressMask | KeyReleaseMask | | ||||
|                StructureNotifyMask; | ||||
|  | ||||
|   if (XGetWindowAttributes (xdisplay, xwin, &attr)) | ||||
|       { | ||||
|         event_mask |= attr.your_event_mask; | ||||
|       } | ||||
|  | ||||
|   XSelectInput (xdisplay, xwin, event_mask); | ||||
|   meta_core_select_events (xdisplay, xwin, event_mask, TRUE); | ||||
|  | ||||
|   info->window_group = meta_window_group_new (screen); | ||||
|   info->background_actor = meta_background_actor_new_for_screen (screen); | ||||
| @@ -695,9 +694,15 @@ meta_compositor_set_updates (MetaCompositor *compositor, | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_grabbed_event (XEvent *event) | ||||
| is_grabbed_event (MetaDisplay *display, | ||||
|                   XEvent      *event) | ||||
| { | ||||
|   switch (event->xany.type) | ||||
|   guint evtype; | ||||
|  | ||||
|   if (!meta_input_event_get_type (display, event, &evtype)) | ||||
|     return FALSE; | ||||
|  | ||||
|   switch (evtype) | ||||
|     { | ||||
|     case ButtonPress: | ||||
|     case ButtonRelease: | ||||
| @@ -730,7 +735,8 @@ meta_compositor_process_event (MetaCompositor *compositor, | ||||
|                                XEvent         *event, | ||||
|                                MetaWindow     *window) | ||||
| { | ||||
|   if (compositor->modal_plugin && is_grabbed_event (event)) | ||||
|   if (compositor->modal_plugin && | ||||
|       is_grabbed_event (compositor->display, event)) | ||||
|     { | ||||
|       MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin); | ||||
|  | ||||
|   | ||||
| @@ -230,6 +230,35 @@ bell_flash_window_frame (MetaWindow *window) | ||||
|       bell_unflash_frame, window->frame, NULL); | ||||
| } | ||||
|  | ||||
| static MetaWindow * | ||||
| get_flash_window (MetaDisplay *display, | ||||
|                   XkbAnyEvent *xkb_ev) | ||||
| { | ||||
|   XkbBellNotifyEvent *xkb_bell_event; | ||||
|   MetaWindow *window; | ||||
|  | ||||
|   g_assert (xkb_ev->xkb_type == XkbBellNotify); | ||||
|  | ||||
|   xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev; | ||||
|   window = meta_display_lookup_x_window (display, xkb_bell_event->window); | ||||
|  | ||||
|   if (!window && | ||||
|       g_hash_table_size (display->focus_info) == 1) | ||||
|     { | ||||
|       GHashTableIter iter; | ||||
|       MetaFocusInfo *info; | ||||
|  | ||||
|       /* If there is only one focused window, use it */ | ||||
|       g_hash_table_iter_init (&iter, display->focus_info); | ||||
|  | ||||
|       if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info) && | ||||
|           info->focus_window && info->focus_window->frame) | ||||
|         window = info->focus_window; | ||||
|     } | ||||
|  | ||||
|   return window; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Flashes the frame of the focussed window. If there is no focussed window, | ||||
|  * flashes the screen. | ||||
| @@ -241,15 +270,11 @@ static void | ||||
| bell_flash_frame (MetaDisplay *display,  | ||||
| 		  XkbAnyEvent *xkb_ev) | ||||
| { | ||||
|   XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev; | ||||
|   MetaWindow *window; | ||||
|    | ||||
|   g_assert (xkb_ev->xkb_type == XkbBellNotify); | ||||
|   window = meta_display_lookup_x_window (display, xkb_bell_event->window); | ||||
|   if (!window && (display->focus_window)) | ||||
|     { | ||||
|       window = display->focus_window; | ||||
|     } | ||||
|   window = get_flash_window (display, xkb_ev); | ||||
|  | ||||
|   if (window && window->frame) | ||||
|     { | ||||
|       bell_flash_window_frame (window); | ||||
| @@ -310,9 +335,7 @@ meta_bell_notify (MetaDisplay *display, | ||||
|       ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event")); | ||||
|       ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent"); | ||||
|  | ||||
|       window = meta_display_lookup_x_window (display, xkb_bell_event->window); | ||||
|       if (!window && (display->focus_window) && (display->focus_window->frame)) | ||||
|         window = display->focus_window; | ||||
|       window = get_flash_window (display, xkb_ev); | ||||
|  | ||||
|       if (window) | ||||
|         { | ||||
|   | ||||
| @@ -1363,15 +1363,18 @@ constrain_titlebar_visible (MetaWindow         *window, | ||||
|   int bottom_amount; | ||||
|   int horiz_amount_offscreen, vert_amount_offscreen; | ||||
|   int horiz_amount_onscreen,  vert_amount_onscreen; | ||||
|   MetaGrabInfo *grab_info; | ||||
|  | ||||
|   if (priority > PRIORITY_TITLEBAR_VISIBLE) | ||||
|     return TRUE; | ||||
|  | ||||
|   grab_info = window->cur_grab; | ||||
|  | ||||
|   /* Allow the titlebar beyond the top of the screen only if the user wasn't | ||||
|    * clicking on the frame to start the move. | ||||
|    */ | ||||
|   unconstrained_user_action = | ||||
|     info->is_user_action && !window->display->grab_frame_action; | ||||
|     info->is_user_action && (!grab_info || !grab_info->grab_frame_action); | ||||
|  | ||||
|   /* Exit early if we know the constraint won't apply--note that this constraint | ||||
|    * is only meant for normal windows (e.g. we don't want docks to be shoved  | ||||
|   | ||||
							
								
								
									
										202
									
								
								src/core/core.c
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								src/core/core.c
									
									
									
									
									
								
							| @@ -27,9 +27,15 @@ | ||||
| #include "core.h" | ||||
| #include "frame.h" | ||||
| #include "workspace-private.h" | ||||
| #include "input-events.h" | ||||
| #include <meta/prefs.h> | ||||
| #include <meta/errors.h> | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
| #include <X11/extensions/XInput2.h> | ||||
| #include "devices-xi2.h" | ||||
| #endif | ||||
|  | ||||
| /* Looks up the MetaWindow representing the frame of the given X window. | ||||
|  * Used as a helper function by a bunch of the functions below. | ||||
|  * | ||||
| @@ -245,9 +251,19 @@ lower_window_and_transients (MetaWindow *window, | ||||
| void | ||||
| meta_core_user_lower_and_unfocus (Display *xdisplay, | ||||
|                                   Window   frame_xwindow, | ||||
|                                   int      device_id, | ||||
|                                   guint32  timestamp) | ||||
| { | ||||
|   MetaWindow *window = get_window (xdisplay, frame_xwindow); | ||||
|   MetaDevice *pointer; | ||||
|  | ||||
|   pointer = meta_device_map_lookup (window->display->device_map, device_id); | ||||
|  | ||||
|   if (pointer == NULL) | ||||
|     return; | ||||
|  | ||||
|   if (!META_IS_DEVICE_POINTER (pointer)) | ||||
|     pointer = meta_device_get_paired_device (pointer); | ||||
|  | ||||
|   lower_window_and_transients (window, NULL); | ||||
|  | ||||
| @@ -256,6 +272,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, | ||||
|   * this will be invoked via keyboard action or by a mouse action; | ||||
|   * in either case the window or a modal child will have been focused.) */ | ||||
|   meta_workspace_focus_default_window (window->screen->active_workspace, | ||||
|                                        pointer, | ||||
|                                        NULL, | ||||
|                                        timestamp); | ||||
| } | ||||
| @@ -263,16 +280,21 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, | ||||
| void | ||||
| meta_core_lower_beneath_grab_window (Display *xdisplay, | ||||
|                                      Window   xwindow, | ||||
|                                      int      device_id, | ||||
|                                      guint32  timestamp) | ||||
| { | ||||
|   XWindowChanges changes; | ||||
|   MetaDisplay *display; | ||||
|   MetaScreen *screen; | ||||
|   MetaWindow *grab_window; | ||||
|   MetaDevice *pointer; | ||||
|   MetaGrabInfo *grab_info; | ||||
|  | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   screen = meta_display_screen_for_xwindow (display, xwindow); | ||||
|   grab_window = display->grab_window; | ||||
|   pointer = meta_device_map_lookup (display->device_map, device_id); | ||||
|   grab_info = meta_display_get_grab_info (display, pointer); | ||||
|   grab_window = grab_info->grab_window; | ||||
|  | ||||
|   if (grab_window == NULL) | ||||
|     return; | ||||
| @@ -491,18 +513,27 @@ meta_core_get_active_workspace (Screen *xscreen) | ||||
| void | ||||
| meta_core_show_window_menu (Display *xdisplay, | ||||
|                             Window   frame_xwindow, | ||||
|                             int      device_id, | ||||
|                             int      root_x, | ||||
|                             int      root_y, | ||||
|                             int      button, | ||||
|                             guint32  timestamp) | ||||
| { | ||||
|   MetaWindow *window = get_window (xdisplay, frame_xwindow); | ||||
|    | ||||
|   MetaDevice *device; | ||||
|  | ||||
|   /* There is already a menu popped up, | ||||
|    * most likely from another device | ||||
|    */ | ||||
|   if (window->menu) | ||||
|     return; | ||||
|  | ||||
|   if (meta_prefs_get_raise_on_click ()) | ||||
|     meta_window_raise (window); | ||||
|   meta_window_focus (window, timestamp); | ||||
|  | ||||
|   meta_window_show_menu (window, root_x, root_y, button, timestamp); | ||||
|   device = meta_device_map_lookup (window->display->device_map, device_id); | ||||
|   meta_window_show_menu (window, device, root_x, root_y, button, timestamp); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -638,6 +669,7 @@ meta_core_get_workspace_name_with_index (Display *xdisplay, | ||||
| gboolean | ||||
| meta_core_begin_grab_op (Display    *xdisplay, | ||||
|                          Window      frame_xwindow, | ||||
|                          int         device_id, | ||||
|                          MetaGrabOp  op, | ||||
|                          gboolean    pointer_already_grabbed, | ||||
|                          gboolean    frame_action, | ||||
| @@ -650,13 +682,16 @@ meta_core_begin_grab_op (Display    *xdisplay, | ||||
|   MetaWindow *window = get_window (xdisplay, frame_xwindow); | ||||
|   MetaDisplay *display; | ||||
|   MetaScreen *screen; | ||||
|    | ||||
|   MetaDevice *device; | ||||
|  | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   screen = meta_display_screen_for_xwindow (display, frame_xwindow); | ||||
|  | ||||
|   g_assert (screen != NULL); | ||||
|    | ||||
|   return meta_display_begin_grab_op (display, screen, window, | ||||
|  | ||||
|   device = meta_device_map_lookup (display->device_map, device_id); | ||||
|  | ||||
|   return meta_display_begin_grab_op (display, screen, window, device, | ||||
|                                      op, pointer_already_grabbed, | ||||
|                                      frame_action, | ||||
|                                      button, modmask, | ||||
| @@ -665,57 +700,58 @@ meta_core_begin_grab_op (Display    *xdisplay, | ||||
|  | ||||
| void | ||||
| meta_core_end_grab_op (Display *xdisplay, | ||||
|                        int      device_id, | ||||
|                        guint32  timestamp) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|    | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   MetaDevice *device; | ||||
|  | ||||
|   meta_display_end_grab_op (display, timestamp); | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   device = meta_device_map_lookup (display->device_map, device_id); | ||||
|  | ||||
|   meta_display_end_grab_op (display, device, timestamp); | ||||
| } | ||||
|  | ||||
| MetaGrabOp | ||||
| meta_core_get_grab_op (Display *xdisplay) | ||||
| meta_core_frame_has_grab (Display    *xdisplay, | ||||
|                           Window      frame_xwindow, | ||||
|                           gint       *device_id, | ||||
|                           gint       *button_ret) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|    | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   MetaWindow *window; | ||||
|  | ||||
|   return display->grab_op; | ||||
|   window = get_window (xdisplay, frame_xwindow); | ||||
|  | ||||
|   if (window != NULL && | ||||
|       window->cur_grab != NULL) | ||||
|     { | ||||
|       if (button_ret) | ||||
|         *button_ret = window->cur_grab->grab_button; | ||||
|  | ||||
|       if (device_id) | ||||
|         *device_id = meta_device_get_id (window->cur_grab->grab_pointer); | ||||
|  | ||||
|       return window->cur_grab->grab_op; | ||||
|     } | ||||
|  | ||||
|   return META_GRAB_OP_NONE; | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_core_get_grab_frame (Display *xdisplay) | ||||
| meta_core_get_frame (Display *xdisplay, | ||||
|                      Window   client_xwindow) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|    | ||||
|   MetaWindow *window; | ||||
|  | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   window = meta_display_lookup_x_window (display, client_xwindow); | ||||
|  | ||||
|   g_assert (display != NULL); | ||||
|   g_assert (display->grab_op == META_GRAB_OP_NONE ||  | ||||
|             display->grab_screen != NULL); | ||||
|   g_assert (display->grab_op == META_GRAB_OP_NONE || | ||||
|             display->grab_screen->display->xdisplay == xdisplay); | ||||
|    | ||||
|   if (display->grab_op != META_GRAB_OP_NONE && | ||||
|       display->grab_window && | ||||
|       display->grab_window->frame) | ||||
|     return display->grab_window->frame->xwindow; | ||||
|   else | ||||
|     return None; | ||||
| } | ||||
|   if (window && | ||||
|       window->frame) | ||||
|     return window->frame->xwindow; | ||||
|  | ||||
| int | ||||
| meta_core_get_grab_button (Display  *xdisplay) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|    | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|  | ||||
|   if (display->grab_op == META_GRAB_OP_NONE) | ||||
|     return -1; | ||||
|    | ||||
|   return display->grab_button; | ||||
|   return None; | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -731,13 +767,24 @@ meta_core_grab_buttons  (Display *xdisplay, | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_core_set_screen_cursor (Display *xdisplay, | ||||
|                              Window   frame_on_screen, | ||||
|                              MetaCursor cursor) | ||||
| meta_core_set_screen_cursor (Display    *xdisplay, | ||||
|                              Window      frame_on_screen, | ||||
|                              gint        device_id, | ||||
|                              MetaCursor  cursor) | ||||
| { | ||||
|   MetaWindow *window = get_window (xdisplay, frame_on_screen); | ||||
|   MetaDevice *pointer; | ||||
|  | ||||
|   meta_frame_set_screen_cursor (window->frame, cursor); | ||||
|   pointer = meta_device_map_lookup (window->display->device_map, | ||||
|                                     device_id); | ||||
|  | ||||
|   if (pointer == NULL) | ||||
|     return; | ||||
|  | ||||
|   if (!META_IS_DEVICE_POINTER (pointer)) | ||||
|     pointer = meta_device_get_paired_device (pointer); | ||||
|  | ||||
|   meta_frame_set_screen_cursor (window->frame, pointer, cursor); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -775,3 +822,70 @@ meta_invalidate_default_icons (void) | ||||
|   g_slist_free (windows); | ||||
| } | ||||
|  | ||||
| /* Selects events on an xwindow, using XInput2 if available/in use, | ||||
|  * this function doesn't require the xwindow to have a backing | ||||
|  * MetaWindow. | ||||
|  */ | ||||
| void | ||||
| meta_core_select_events (Display  *xdisplay, | ||||
|                          Window    xwindow, | ||||
|                          gint      evmask, | ||||
|                          gboolean  preserve_old_mask) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (display->have_xinput2) | ||||
|     { | ||||
|       XIEventMask mask; | ||||
|  | ||||
|       mask.deviceid = XIAllMasterDevices; | ||||
|       mask.mask = meta_device_xi2_translate_event_mask (evmask, | ||||
|                                                         &mask.mask_len); | ||||
|  | ||||
|       if (preserve_old_mask) | ||||
|         { | ||||
|           XIEventMask *prev; | ||||
|           gint n_masks, i, j; | ||||
|  | ||||
|           prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks); | ||||
|  | ||||
|           for (i = 0; i < n_masks; i++) | ||||
|             { | ||||
|               if (prev[i].deviceid != XIAllMasterDevices) | ||||
|                 continue; | ||||
|  | ||||
|               for (j = 0; j < MIN (mask.mask_len, prev[i].mask_len); j++) | ||||
|                 mask.mask[j] |= prev[i].mask[j]; | ||||
|             } | ||||
|  | ||||
|           XFree (prev); | ||||
|         } | ||||
|  | ||||
|       XISelectEvents (xdisplay, xwindow, &mask, 1); | ||||
|  | ||||
|       /* Unset any input event so they are only handled via XInput2 */ | ||||
|       evmask &= ~(META_INPUT_TOUCH_EVENTS_MASK | | ||||
|                   KeyPressMask | KeyReleaseMask | | ||||
|                   ButtonPressMask | ButtonReleaseMask | | ||||
|                   EnterWindowMask | LeaveWindowMask | | ||||
|                   PointerMotionMask | PointerMotionHintMask | | ||||
|                   Button1MotionMask | Button2MotionMask | | ||||
|                   Button3MotionMask | Button4MotionMask | | ||||
|                   Button5MotionMask | ButtonMotionMask | | ||||
|                   FocusChangeMask); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   if (preserve_old_mask) | ||||
|     { | ||||
|       XWindowAttributes attr; | ||||
|  | ||||
|       if (XGetWindowAttributes (xdisplay, xwindow, &attr)) | ||||
|         evmask |= attr.your_event_mask; | ||||
|     } | ||||
|  | ||||
|   XSelectInput (xdisplay, xwindow, evmask); | ||||
| } | ||||
|   | ||||
| @@ -110,6 +110,7 @@ void meta_core_user_raise   (Display *xdisplay, | ||||
|                              Window   frame_xwindow); | ||||
| void meta_core_user_lower_and_unfocus (Display *xdisplay, | ||||
|                                        Window   frame_xwindow, | ||||
|                                        int      device_id, | ||||
|                                        guint32  timestamp); | ||||
|  | ||||
| void meta_core_user_focus   (Display *xdisplay, | ||||
| @@ -118,6 +119,7 @@ void meta_core_user_focus   (Display *xdisplay, | ||||
|  | ||||
| void meta_core_lower_beneath_grab_window (Display *xdisplay, | ||||
|                                           Window   xwindow, | ||||
|                                           int      device_id, | ||||
|                                           guint32  timestamp); | ||||
|  | ||||
| void meta_core_minimize         (Display *xdisplay, | ||||
| @@ -163,6 +165,7 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay, | ||||
|  | ||||
| void meta_core_show_window_menu (Display *xdisplay, | ||||
|                                  Window   frame_xwindow, | ||||
|                                  int      device_id, | ||||
|                                  int      root_x, | ||||
|                                  int      root_y, | ||||
|                                  int      button, | ||||
| @@ -175,6 +178,7 @@ void meta_core_get_menu_accelerator (MetaMenuOp           menu_op, | ||||
|  | ||||
| gboolean   meta_core_begin_grab_op (Display    *xdisplay, | ||||
|                                     Window      frame_xwindow, | ||||
|                                     int         device_id, | ||||
|                                     MetaGrabOp  op, | ||||
|                                     gboolean    pointer_already_grabbed, | ||||
|                                     gboolean    frame_action, | ||||
| @@ -184,18 +188,29 @@ gboolean   meta_core_begin_grab_op (Display    *xdisplay, | ||||
|                                     int         root_x, | ||||
|                                     int         root_y); | ||||
| void       meta_core_end_grab_op   (Display    *xdisplay, | ||||
|                                     int         device_id, | ||||
|                                     guint32     timestamp); | ||||
| MetaGrabOp meta_core_get_grab_op     (Display    *xdisplay); | ||||
| Window     meta_core_get_grab_frame  (Display   *xdisplay); | ||||
| int        meta_core_get_grab_button (Display  *xdisplay); | ||||
|  | ||||
| MetaGrabOp meta_core_frame_has_grab  (Display    *xdisplay, | ||||
|                                       Window      frame_xwindow, | ||||
|                                       gint       *device_id, | ||||
|                                       gint       *button_ret); | ||||
| Window     meta_core_get_frame       (Display    *xdisplay, | ||||
|                                       Window      client_xwindow); | ||||
|  | ||||
| void       meta_core_grab_buttons  (Display *xdisplay, | ||||
|                                     Window   frame_xwindow); | ||||
|  | ||||
| void       meta_core_set_screen_cursor (Display *xdisplay, | ||||
|                                         Window   frame_on_screen, | ||||
|                                         MetaCursor cursor); | ||||
| void       meta_core_set_screen_cursor (Display    *xdisplay, | ||||
|                                         Window      frame_on_screen, | ||||
|                                         int         device_id, | ||||
|                                         MetaCursor  cursor); | ||||
|  | ||||
| void       meta_core_select_events     (Display  *xdisplay, | ||||
|                                         Window    xwindow, | ||||
|                                         gint      evmask, | ||||
|                                         gboolean  preserve_old_mask); | ||||
|  | ||||
|  | ||||
| /* Used because we ignore EnterNotify when a window is unmapped that | ||||
|  * really shouldn't cause focus changes, by comparing the event serial | ||||
|   | ||||
							
								
								
									
										69
									
								
								src/core/device-keyboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/core/device-keyboard.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Keyboard device abstraction */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "device-keyboard.h" | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE (MetaDeviceKeyboard, | ||||
|                         meta_device_keyboard, | ||||
|                         META_TYPE_DEVICE) | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_class_init (MetaDeviceKeyboardClass *klass) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_init (MetaDeviceKeyboard *keyboard) | ||||
| { | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard) | ||||
| { | ||||
|   MetaDeviceKeyboardClass *klass; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_KEYBOARD (keyboard), None); | ||||
|  | ||||
|   klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard); | ||||
|  | ||||
|   if (!klass->get_focus_window) | ||||
|     return None; | ||||
|  | ||||
|   return (klass->get_focus_window) (keyboard); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard, | ||||
|                                        Window              xwindow, | ||||
|                                        Time                timestamp) | ||||
| { | ||||
|   MetaDeviceKeyboardClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_KEYBOARD (keyboard)); | ||||
|  | ||||
|   klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard); | ||||
|  | ||||
|   if (klass->set_focus_window) | ||||
|     (klass->set_focus_window) (keyboard, xwindow, timestamp); | ||||
| } | ||||
							
								
								
									
										69
									
								
								src/core/device-keyboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/core/device-keyboard.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device-keyboard.h  Keyboard device abstraction | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the internal abstraction of keyboard devices so | ||||
|  * XInput2/core events can be handled similarly. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_KEYBOARD_H | ||||
| #define META_DEVICE_KEYBOARD_H | ||||
|  | ||||
| #include "display-private.h" | ||||
| #include "device-private.h" | ||||
|  | ||||
| #define META_TYPE_DEVICE_KEYBOARD            (meta_device_keyboard_get_type ()) | ||||
| #define META_DEVICE_KEYBOARD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboard)) | ||||
| #define META_DEVICE_KEYBOARD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass)) | ||||
| #define META_IS_DEVICE_KEYBOARD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD)) | ||||
| #define META_IS_DEVICE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_KEYBOARD)) | ||||
| #define META_DEVICE_KEYBOARD_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass)) | ||||
|  | ||||
| typedef struct _MetaDeviceKeyboard MetaDeviceKeyboard; | ||||
| typedef struct _MetaDeviceKeyboardClass MetaDeviceKeyboardClass; | ||||
|  | ||||
| struct _MetaDeviceKeyboard | ||||
| { | ||||
|   MetaDevice parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceKeyboardClass | ||||
| { | ||||
|   MetaDeviceClass parent_instance; | ||||
|  | ||||
|   Window (* get_focus_window) (MetaDeviceKeyboard *keyboard); | ||||
|   void   (* set_focus_window) (MetaDeviceKeyboard *keyboard, | ||||
|                                Window              xwindow, | ||||
|                                Time                timestamp); | ||||
| }; | ||||
|  | ||||
| GType    meta_device_keyboard_get_type   (void) G_GNUC_CONST; | ||||
|  | ||||
| Window   meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard); | ||||
| void     meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard, | ||||
|                                                 Window              xwindow, | ||||
|                                                 Time                timestamp); | ||||
|  | ||||
|  | ||||
| #endif /* META_DEVICE_KEYBOARD_H */ | ||||
							
								
								
									
										134
									
								
								src/core/device-map-core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/core/device-map-core.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Input device map, core protocol implementation */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "device-map-core.h" | ||||
| #include "devices-core.h" | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDeviceMapCore, meta_device_map_core, META_TYPE_DEVICE_MAP) | ||||
|  | ||||
| static gboolean | ||||
| meta_device_map_core_grab_key (MetaDeviceMap *device_map, | ||||
|                                Window         xwindow, | ||||
|                                guint          keycode, | ||||
|                                guint          modifiers, | ||||
|                                gboolean       sync) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   gint retval; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   retval = XGrabKey (display->xdisplay, keycode, modifiers, | ||||
|                      xwindow, True, | ||||
|                      GrabModeAsync, /* Never care about the other device */ | ||||
|                      (sync) ? GrabModeSync : GrabModeAsync); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_core_ungrab_key (MetaDeviceMap *device_map, | ||||
|                                  Window         xwindow, | ||||
|                                  guint          keycode, | ||||
|                                  guint          modifiers) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   XUngrabKey (display->xdisplay, keycode, modifiers, xwindow); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_device_map_core_grab_button (MetaDeviceMap *device_map, | ||||
|                                   Window         xwindow, | ||||
|                                   guint          n_button, | ||||
|                                   guint          modifiers, | ||||
|                                   guint          evmask, | ||||
|                                   gboolean       sync) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   gint retval; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   retval = XGrabButton (display->xdisplay, n_button, | ||||
|                         modifiers, xwindow, False, | ||||
|                         evmask, | ||||
|                         (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                         GrabModeAsync, /* Never care about the other device */ | ||||
|                         None, None); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_core_ungrab_button (MetaDeviceMap *device_map, | ||||
|                                     Window         xwindow, | ||||
|                                     guint          n_button, | ||||
|                                     guint          modifiers) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   XUngrabButton (display->xdisplay, n_button, modifiers, xwindow); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_core_constructed (GObject *object) | ||||
| { | ||||
|   MetaDeviceMap *device_map = META_DEVICE_MAP (object); | ||||
|   MetaDevice *pointer, *keyboard; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   /* Insert core devices */ | ||||
|   pointer = meta_device_pointer_core_new (display); | ||||
|   meta_device_map_add_device (device_map, pointer); | ||||
|  | ||||
|   keyboard = meta_device_keyboard_core_new (display); | ||||
|   meta_device_map_add_device (device_map, keyboard); | ||||
|  | ||||
|   meta_device_pair_devices (pointer, keyboard); | ||||
|  | ||||
|   g_object_unref (pointer); | ||||
|   g_object_unref (keyboard); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_core_class_init (MetaDeviceMapCoreClass *klass) | ||||
| { | ||||
|   MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass); | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->constructed = meta_device_map_core_constructed; | ||||
|  | ||||
|   device_map_class->grab_key = meta_device_map_core_grab_key; | ||||
|   device_map_class->ungrab_key = meta_device_map_core_ungrab_key; | ||||
|   device_map_class->grab_button = meta_device_map_core_grab_button; | ||||
|   device_map_class->ungrab_button = meta_device_map_core_ungrab_button; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_core_init (MetaDeviceMapCore *device_map) | ||||
| { | ||||
| } | ||||
							
								
								
									
										56
									
								
								src/core/device-map-core.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/core/device-map-core.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device-map-core.h  device map for core devices | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the core protocol implementation of the device map | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_MAP_CORE_H | ||||
| #define META_DEVICE_MAP_CORE_H | ||||
|  | ||||
| typedef struct _MetaDeviceMapCore MetaDeviceMapCore; | ||||
| typedef struct _MetaDeviceMapCoreClass MetaDeviceMapCoreClass; | ||||
|  | ||||
| #include "device-map-private.h" | ||||
|  | ||||
| #define META_TYPE_DEVICE_MAP_CORE            (meta_device_map_core_get_type ()) | ||||
| #define META_DEVICE_MAP_CORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCore)) | ||||
| #define META_DEVICE_MAP_CORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass)) | ||||
| #define META_IS_DEVICE_MAP_CORE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_CORE)) | ||||
| #define META_IS_DEVICE_MAP_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_MAP_CORE)) | ||||
| #define META_DEVICE_MAP_CORE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass)) | ||||
|  | ||||
| struct _MetaDeviceMapCore | ||||
| { | ||||
|   MetaDeviceMap parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceMapCoreClass | ||||
| { | ||||
|   MetaDeviceMapClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType           meta_device_map_core_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| #endif /* META_DEVICE_MAP_CORE_H */ | ||||
							
								
								
									
										120
									
								
								src/core/device-map-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/core/device-map-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device-map.h  object containing input devices | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the device map, used to find out the device behind | ||||
|  * XInput2/core events. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_MAP_PRIVATE_H | ||||
| #define META_DEVICE_MAP_PRIVATE_H | ||||
|  | ||||
| #include <meta/device-map.h> | ||||
| #include <meta/device.h> | ||||
| #include "display-private.h" | ||||
| #include "device-private.h" | ||||
|  | ||||
| /* Device IDs for Virtual Core Pointer/Keyboard, | ||||
|  * use only in case of emergency. | ||||
|  */ | ||||
| #define META_CORE_POINTER_ID  2 | ||||
| #define META_CORE_KEYBOARD_ID 3 | ||||
|  | ||||
| struct _MetaDeviceMap | ||||
| { | ||||
|   GObject parent_instance; | ||||
|   gpointer priv; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceMapClass | ||||
| { | ||||
|   GObjectClass parent_instance; | ||||
|  | ||||
|   void (* device_added)   (MetaDeviceMap *device_map, | ||||
|                            MetaDevice    *device); | ||||
|   void (* device_removed) (MetaDeviceMap *device_map, | ||||
|                            MetaDevice    *device); | ||||
|  | ||||
|   gboolean (* grab_key)       (MetaDeviceMap *device_map, | ||||
|                                Window         xwindow, | ||||
|                                guint          keycode, | ||||
|                                guint          modifiers, | ||||
|                                gboolean       sync); | ||||
|   void     (* ungrab_key)     (MetaDeviceMap *device_map, | ||||
|                                Window         xwindow, | ||||
|                                guint          keycode, | ||||
|                                guint          modifiers); | ||||
|  | ||||
|   gboolean (* grab_button)    (MetaDeviceMap *device_map, | ||||
|                                Window         xwindow, | ||||
|                                guint          n_button, | ||||
|                                guint          modifiers, | ||||
|                                guint          evmask, | ||||
|                                gboolean       sync); | ||||
|   void     (* ungrab_button)  (MetaDeviceMap *pointer, | ||||
|                                Window         xwindow, | ||||
|                                guint          n_button, | ||||
|                                guint          modifiers); | ||||
|   void     (* grab_touch)     (MetaDeviceMap *pointer, | ||||
|                                Window         xwindow); | ||||
|   void     (* ungrab_touch)   (MetaDeviceMap *pointer, | ||||
|                                Window         xwindow); | ||||
| }; | ||||
|  | ||||
| GType           meta_device_map_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDeviceMap * meta_device_map_new    (MetaDisplay   *display, | ||||
|                                         gboolean       force_core); | ||||
|  | ||||
| void            meta_device_map_add_device    (MetaDeviceMap *device_map, | ||||
|                                                MetaDevice    *device); | ||||
| void            meta_device_map_remove_device (MetaDeviceMap *device_map, | ||||
|                                                MetaDevice    *device); | ||||
|  | ||||
| gboolean meta_device_map_grab_key        (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow, | ||||
|                                           guint               keycode, | ||||
|                                           guint               modifiers, | ||||
|                                           gboolean            sync); | ||||
| void     meta_device_map_ungrab_key      (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow, | ||||
|                                           guint               keycode, | ||||
|                                           guint               modifiers); | ||||
| gboolean meta_device_map_grab_button     (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow, | ||||
|                                           guint               n_button, | ||||
|                                           guint               modifiers, | ||||
|                                           guint               evmask, | ||||
|                                           gboolean            sync); | ||||
| void     meta_device_map_ungrab_button   (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow, | ||||
|                                           guint               n_button, | ||||
|                                           guint               modifiers); | ||||
|  | ||||
| void     meta_device_map_grab_touch      (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow); | ||||
| void     meta_device_map_ungrab_touch    (MetaDeviceMap      *device_map, | ||||
|                                           Window              xwindow); | ||||
|  | ||||
| #endif /* META_DEVICE_MAP_PRIVATE_H */ | ||||
							
								
								
									
										323
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,323 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Input device map, XInput2 implementation */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "device-map-xi2.h" | ||||
| #include <X11/extensions/XInput2.h> | ||||
| #include "devices-xi2.h" | ||||
| #include "input-events.h" | ||||
|  | ||||
| #define XINPUT2_VERSION_MAJOR 2 | ||||
| #define XINPUT2_VERSION_MINOR 0 | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDeviceMapXI2, meta_device_map_xi2, META_TYPE_DEVICE_MAP) | ||||
|  | ||||
| static gboolean | ||||
| meta_device_map_xi2_grab_key (MetaDeviceMap *device_map, | ||||
|                               Window         xwindow, | ||||
|                               guint          keycode, | ||||
|                               guint          modifiers, | ||||
|                               gboolean       sync) | ||||
| { | ||||
|   XIGrabModifiers mods = { modifiers, 0 }; | ||||
|   MetaDisplay *display; | ||||
|   XIEventMask mask; | ||||
|   gint retval; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   mask.deviceid = XIAllMasterDevices; | ||||
|   mask.mask = meta_device_xi2_translate_event_mask (KeyPressMask | | ||||
|                                                     KeyReleaseMask, | ||||
|                                                     &mask.mask_len); | ||||
|  | ||||
|   retval = XIGrabKeycode (display->xdisplay, | ||||
|                           XIAllMasterDevices, | ||||
|                           keycode, xwindow, | ||||
|                           (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                           GrabModeAsync, /* Never care about the other device */ | ||||
|                           True, &mask, 1, &mods); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_ungrab_key (MetaDeviceMap *device_map, | ||||
|                                 Window         xwindow, | ||||
|                                 guint          keycode, | ||||
|                                 guint          modifiers) | ||||
| { | ||||
|   XIGrabModifiers mods = { modifiers, 0 }; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   XIUngrabKeycode (display->xdisplay, | ||||
|                    XIAllMasterDevices, | ||||
|                    keycode, xwindow, | ||||
|                    1, &mods); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_device_map_xi2_grab_button (MetaDeviceMap *device_map, | ||||
|                                  Window         xwindow, | ||||
|                                  guint          n_button, | ||||
|                                  guint          modifiers, | ||||
|                                  guint          evmask, | ||||
|                                  gboolean       sync) | ||||
| { | ||||
|   XIGrabModifiers mods = { modifiers, 0 }; | ||||
|   XIEventMask mask; | ||||
|   MetaDisplay *display; | ||||
|   int retval; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   mask.deviceid = XIAllMasterDevices; | ||||
|   mask.mask = meta_device_xi2_translate_event_mask (evmask, &mask.mask_len); | ||||
|  | ||||
|   retval = XIGrabButton (display->xdisplay, | ||||
|                          XIAllMasterDevices, | ||||
|                          n_button, xwindow, None, | ||||
|                          (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                          GrabModeAsync, /* Never care about the other device */ | ||||
|                          False, &mask, 1, &mods); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_ungrab_button (MetaDeviceMap *device_map, | ||||
|                                    Window         xwindow, | ||||
|                                    guint          n_button, | ||||
|                                    guint          modifiers) | ||||
| { | ||||
|   XIGrabModifiers mods = { modifiers, 0 }; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   XIUngrabButton (display->xdisplay, | ||||
|                   XIAllMasterDevices, | ||||
|                   n_button, xwindow, 1, &mods); | ||||
| } | ||||
|  | ||||
| static MetaDevice * | ||||
| create_device_from_info (MetaDeviceMap *device_map, | ||||
|                          gint           use, | ||||
|                          gint           device_id) | ||||
| { | ||||
|   MetaDevice *device = NULL; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   if (use == XIMasterPointer || | ||||
|       use == XISlavePointer) | ||||
|     device = meta_device_pointer_xi2_new (display, device_id); | ||||
|   else if (use == XIMasterKeyboard) | ||||
|     device = meta_device_keyboard_xi2_new (display, device_id); | ||||
|  | ||||
|   return device; | ||||
| } | ||||
|  | ||||
| static void | ||||
| pair_devices (gpointer key, | ||||
|               gpointer value, | ||||
|               gpointer user_data) | ||||
| { | ||||
|   MetaDevice *device1, *device2; | ||||
|   MetaDeviceMap *device_map; | ||||
|  | ||||
|   device_map = user_data; | ||||
|   device1 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (key)); | ||||
|   device2 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (value)); | ||||
|  | ||||
|   meta_device_pair_devices (device1, device2); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_constructed (GObject *object) | ||||
| { | ||||
|   MetaDeviceMap *device_map = META_DEVICE_MAP (object); | ||||
|   MetaDisplay *display; | ||||
|   XIDeviceInfo *info; | ||||
|   GHashTable *pairs; | ||||
|   int n_devices, i; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   /* We're only interested in master devices, | ||||
|    * detached slave devices are left for applications | ||||
|    * to handle. | ||||
|    */ | ||||
|   info = XIQueryDevice (display->xdisplay, XIAllDevices, &n_devices); | ||||
|   pairs = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   for (i = 0; i < n_devices; i++) | ||||
|     { | ||||
|       MetaDevice *device; | ||||
|  | ||||
|       device = create_device_from_info (device_map, info[i].use, | ||||
|                                         info[i].deviceid); | ||||
|       if (device) | ||||
|         { | ||||
|           meta_device_map_add_device (device_map, device); | ||||
|  | ||||
|           if (info[i].use == XIMasterPointer || | ||||
|               info[i].use == XIMasterKeyboard) | ||||
|             g_hash_table_insert (pairs, | ||||
|                                  GINT_TO_POINTER (info[i].deviceid), | ||||
|                                  GINT_TO_POINTER (info[i].attachment)); | ||||
|  | ||||
|           g_object_unref (device); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_hash_table_foreach (pairs, pair_devices, device_map); | ||||
|   g_hash_table_destroy (pairs); | ||||
|  | ||||
|   XIFreeDeviceInfo (info); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_grab_touch (MetaDeviceMap *device_map, | ||||
|                                 Window         xwindow) | ||||
| { | ||||
|   XIGrabModifiers unused = { 0 }; | ||||
|   MetaDisplay *display; | ||||
|   XIEventMask mask; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|  | ||||
|   g_message ("Grabbing passively on touch begin\n"); | ||||
|  | ||||
|   mask.deviceid = XIAllMasterDevices; | ||||
|   mask.mask = meta_device_xi2_translate_event_mask (META_INPUT_TOUCH_EVENTS_MASK | | ||||
|                                                     ButtonPressMask | | ||||
|                                                     ButtonReleaseMask | | ||||
|                                                     PointerMotionMask | | ||||
|                                                     KeyPressMask | | ||||
|                                                     KeyReleaseMask, | ||||
|                                                     &mask.mask_len); | ||||
|   XIGrabTouchBegin (display->xdisplay, | ||||
|                     XIAllMasterDevices, | ||||
|                     xwindow, True, | ||||
|                     &mask, 1, &unused); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_ungrab_touch (MetaDeviceMap *device_map, | ||||
|                                   Window         xwindow) | ||||
| { | ||||
|   XIGrabModifiers unused = { 0 }; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (device_map); | ||||
|   XIUngrabTouchBegin (display->xdisplay, | ||||
|                       XIAllMasterDevices, | ||||
|                       xwindow, 0, &unused); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_class_init (MetaDeviceMapXI2Class *klass) | ||||
| { | ||||
|   MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass); | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->constructed = meta_device_map_xi2_constructed; | ||||
|  | ||||
|   device_map_class->grab_key = meta_device_map_xi2_grab_key; | ||||
|   device_map_class->ungrab_key = meta_device_map_xi2_ungrab_key; | ||||
|   device_map_class->grab_button = meta_device_map_xi2_grab_button; | ||||
|   device_map_class->ungrab_button = meta_device_map_xi2_ungrab_button; | ||||
|   device_map_class->grab_touch = meta_device_map_xi2_grab_touch; | ||||
|   device_map_class->ungrab_touch = meta_device_map_xi2_ungrab_touch; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_xi2_init (MetaDeviceMapXI2 *device_map) | ||||
| { | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map, | ||||
|                                             XEvent           *ev) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_map_get_display (META_DEVICE_MAP (device_map)); | ||||
|  | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIHierarchyEvent *xev; | ||||
|       GHashTable *pairs; | ||||
|       gint i; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIHierarchyEvent *) ev->xcookie.data; | ||||
|  | ||||
|       if (xev->evtype != XI_HierarchyChanged) | ||||
|         return FALSE; | ||||
|  | ||||
|       pairs = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|       for (i = 0; i < xev->num_info; i++) | ||||
|         { | ||||
|           if (xev->info[i].flags & XIMasterAdded || | ||||
|               xev->info[i].flags & XISlaveAdded) | ||||
|             { | ||||
|               MetaDevice *device; | ||||
|  | ||||
|               device = create_device_from_info (META_DEVICE_MAP (device_map), | ||||
|                                                 xev->info[i].use, | ||||
|                                                 xev->info[i].deviceid); | ||||
|  | ||||
|               if (device && | ||||
|                   xev->info[i].flags & XIMasterAdded) | ||||
|                 g_hash_table_insert (pairs, | ||||
|                                      GINT_TO_POINTER (xev->info[i].deviceid), | ||||
|                                      GINT_TO_POINTER (xev->info[i].attachment)); | ||||
|             } | ||||
|           else if (xev->info[i].flags & XIMasterRemoved || | ||||
|                    xev->info[i].flags & XISlaveRemoved) | ||||
|             { | ||||
|               MetaDevice *device; | ||||
|  | ||||
|               device = meta_device_map_lookup (META_DEVICE_MAP (device_map), | ||||
|                                                xev->info[i].deviceid); | ||||
|  | ||||
|               if (device) | ||||
|                 meta_device_map_remove_device (META_DEVICE_MAP (device_map), | ||||
|                                                device); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|       g_hash_table_foreach (pairs, pair_devices, device_map); | ||||
|       g_hash_table_destroy (pairs); | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/core/device-map-xi2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/core/device-map-xi2.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device-map-xi2.h  device map for XInput2 devices | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the XInput2 implementation of the device map | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_MAP_XI2_H | ||||
| #define META_DEVICE_MAP_XI2_H | ||||
|  | ||||
| typedef struct _MetaDeviceMapXI2 MetaDeviceMapXI2; | ||||
| typedef struct _MetaDeviceMapXI2Class MetaDeviceMapXI2Class; | ||||
|  | ||||
| #include "device-map-private.h" | ||||
|  | ||||
| #define META_TYPE_DEVICE_MAP_XI2            (meta_device_map_xi2_get_type ()) | ||||
| #define META_DEVICE_MAP_XI2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2)) | ||||
| #define META_DEVICE_MAP_XI2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class)) | ||||
| #define META_IS_DEVICE_MAP_XI2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_XI2)) | ||||
| #define META_IS_DEVICE_MAP_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_MAP_XI2)) | ||||
| #define META_DEVICE_MAP_XI2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class)) | ||||
|  | ||||
| struct _MetaDeviceMapXI2 | ||||
| { | ||||
|   MetaDeviceMap parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceMapXI2Class | ||||
| { | ||||
|   MetaDeviceMapClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType           meta_device_map_xi2_get_type        (void) G_GNUC_CONST; | ||||
|  | ||||
| gboolean meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map, | ||||
|                                                      XEvent           *ev); | ||||
|  | ||||
| #endif /* META_DEVICE_MAP_XI2_H */ | ||||
							
								
								
									
										429
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,429 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Input device map */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "device-map-private.h" | ||||
| #include "device-map-core.h" | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
| #include <X11/extensions/XInput2.h> | ||||
| #include "device-map-xi2.h" | ||||
|  | ||||
| #define XINPUT2_VERSION_MAJOR 2 | ||||
| #define XINPUT2_VERSION_MINOR 0 | ||||
| #endif | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDeviceMap, meta_device_map, G_TYPE_OBJECT) | ||||
|  | ||||
| typedef struct MetaDeviceMapPrivate MetaDeviceMapPrivate; | ||||
|  | ||||
| struct MetaDeviceMapPrivate | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   GHashTable *devices; | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   PROP_0, | ||||
|   PROP_DISPLAY | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   DEVICE_ADDED, | ||||
|   DEVICE_REMOVED, | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint signals[LAST_SIGNAL] = { 0 }; | ||||
|  | ||||
| static void | ||||
| meta_device_map_get_property (GObject    *object, | ||||
|                               guint       param_id, | ||||
|                               GValue     *value, | ||||
|                               GParamSpec *pspec) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   priv = META_DEVICE_MAP (object)->priv; | ||||
|  | ||||
|   switch (param_id) | ||||
|     { | ||||
|     case PROP_DISPLAY: | ||||
|       g_value_set_object (value, priv->display); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_set_property (GObject      *object, | ||||
|                               guint         param_id, | ||||
|                               const GValue *value, | ||||
|                               GParamSpec   *pspec) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   priv = META_DEVICE_MAP (object)->priv; | ||||
|  | ||||
|   switch (param_id) | ||||
|     { | ||||
|     case PROP_DISPLAY: | ||||
|       priv->display = g_value_get_object (value); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_finalize (GObject *object) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|   GHashTableIter iter; | ||||
|   MetaDevice *device; | ||||
|  | ||||
|   priv = META_DEVICE_MAP (object)->priv; | ||||
|   g_hash_table_iter_init (&iter, priv->devices); | ||||
|  | ||||
|   while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) | ||||
|     { | ||||
|       /* Detach the device */ | ||||
|       g_hash_table_iter_steal (&iter); | ||||
|  | ||||
|       g_signal_emit (object, signals[DEVICE_REMOVED], 0, device); | ||||
|       g_object_unref (device); | ||||
|     } | ||||
|  | ||||
|   g_hash_table_destroy (priv->devices); | ||||
|   G_OBJECT_CLASS (meta_device_map_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_class_init (MetaDeviceMapClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->get_property = meta_device_map_get_property; | ||||
|   object_class->set_property = meta_device_map_set_property; | ||||
|   object_class->finalize = meta_device_map_finalize; | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_DISPLAY, | ||||
|                                    g_param_spec_object ("display", | ||||
|                                                         "Display", | ||||
|                                                         "Display", | ||||
|                                                         META_TYPE_DISPLAY, | ||||
|                                                         G_PARAM_READWRITE | | ||||
|                                                         G_PARAM_CONSTRUCT_ONLY)); | ||||
|   signals[DEVICE_ADDED] = | ||||
|     g_signal_new ("device-added", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, | ||||
|                   g_cclosure_marshal_VOID__OBJECT, | ||||
|                   G_TYPE_NONE, 1, META_TYPE_DEVICE); | ||||
|   signals[DEVICE_REMOVED] = | ||||
|     g_signal_new ("device-removed", | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, | ||||
|                   g_cclosure_marshal_VOID__OBJECT, | ||||
|                   G_TYPE_NONE, 1, META_TYPE_DEVICE); | ||||
|  | ||||
|   g_type_class_add_private (klass, sizeof (MetaDeviceMapPrivate)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_map_init (MetaDeviceMap *device_map) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   priv = device_map->priv = G_TYPE_INSTANCE_GET_PRIVATE (device_map, | ||||
|                                                          META_TYPE_DEVICE_MAP, | ||||
|                                                          MetaDeviceMapPrivate); | ||||
|   priv->devices = g_hash_table_new_full (NULL, NULL, NULL, | ||||
|                                          (GDestroyNotify) g_object_unref); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_add_device (MetaDeviceMap *device_map, | ||||
|                             MetaDevice    *device) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   priv = device_map->priv; | ||||
|   g_hash_table_insert (priv->devices, | ||||
|                        GINT_TO_POINTER (meta_device_get_id (device)), | ||||
|                        g_object_ref (device)); | ||||
|  | ||||
|   g_signal_emit (device_map, signals[DEVICE_ADDED], 0, device); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_remove_device (MetaDeviceMap *device_map, | ||||
|                                MetaDevice    *device) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   priv = device_map->priv; | ||||
|  | ||||
|   if (g_hash_table_steal (priv->devices, | ||||
|                           GINT_TO_POINTER (meta_device_get_id (device)))) | ||||
|     { | ||||
|       g_signal_emit (device_map, signals[DEVICE_REMOVED], 0, device); | ||||
|       g_object_unref (device); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|  | ||||
| static gboolean | ||||
| initialize_xinput (MetaDisplay *display) | ||||
| { | ||||
|   int major, minor, opcode; | ||||
|   int unused; | ||||
|  | ||||
|   if (!XQueryExtension (display->xdisplay, | ||||
|                         "XInputExtension", | ||||
|                         &opcode, &unused, &unused)) | ||||
|     return FALSE; | ||||
|  | ||||
|   major = XI_2_Major; | ||||
| #ifdef HAVE_XTOUCH | ||||
|   minor = XI_2_1_Minor; | ||||
| #else | ||||
|   minor = XI_2_Minor; | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|  | ||||
|   XIQueryVersion (display->xdisplay, &major, &minor); | ||||
|  | ||||
|   if (major == XI_2_Major && | ||||
|       ( | ||||
| #ifdef HAVE_XTOUCH | ||||
|        minor == XI_2_1_Minor || | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|        minor == XI_2_Minor)) | ||||
|     { | ||||
|       display->have_xinput2 = TRUE; | ||||
|       display->have_xtouch = (minor >= XI_2_1_Minor); | ||||
|       display->xinput2_opcode = opcode; | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|  | ||||
| MetaDeviceMap * | ||||
| meta_device_map_new (MetaDisplay *display, | ||||
|                      gboolean     force_core) | ||||
| { | ||||
|   GType type = META_TYPE_DEVICE_MAP_CORE; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (!force_core && | ||||
|       initialize_xinput (display)) | ||||
|     type = META_TYPE_DEVICE_MAP_XI2; | ||||
| #endif | ||||
|  | ||||
|   return g_object_new (type, | ||||
|                        "display", display, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_device_map_lookup: | ||||
|  * @device_map: a #MetaDeviceMap | ||||
|  * @device_id: ID for a device | ||||
|  * | ||||
|  * returns the device corresponding to @device_id | ||||
|  * | ||||
|  * Returns: (transfer none): (allow-none): The matching device, or %NULL. | ||||
|  **/ | ||||
| MetaDevice * | ||||
| meta_device_map_lookup (MetaDeviceMap *device_map, | ||||
|                         gint           device_id) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL); | ||||
|  | ||||
|   priv = device_map->priv; | ||||
|   return g_hash_table_lookup (priv->devices, | ||||
|                               GINT_TO_POINTER (device_id)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_device_map_get_display: | ||||
|  * @device_map: a #MetaDeviceMap | ||||
|  * | ||||
|  * Returns the #MetaDisplay to which @device_map belongs to. | ||||
|  * | ||||
|  * Returns: (transfer none): The #MetaDisplay. | ||||
|  **/ | ||||
| MetaDisplay * | ||||
| meta_device_map_get_display (MetaDeviceMap *device_map) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL); | ||||
|  | ||||
|   priv = device_map->priv; | ||||
|   return priv->display; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_device_map_list_devices: | ||||
|  * @device_map: a #MetaDeviceMap | ||||
|  * | ||||
|  * Returns the list of devices that @device_map holds. | ||||
|  * | ||||
|  * Returns: (element-type Meta.Device) (transfer container): the list | ||||
|  *          of devices, the contained objects are owned by @device_map | ||||
|  *          and should not be unref'ed. The list must be freed with | ||||
|  *          g_list_free(). | ||||
|  **/ | ||||
| GList * | ||||
| meta_device_map_list_devices (MetaDeviceMap *device_map) | ||||
| { | ||||
|   MetaDeviceMapPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL); | ||||
|  | ||||
|   priv = device_map->priv; | ||||
|   return g_hash_table_get_values (priv->devices); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_device_map_grab_key (MetaDeviceMap *device_map, | ||||
|                           Window         xwindow, | ||||
|                           guint          keycode, | ||||
|                           guint          modifiers, | ||||
|                           gboolean       sync) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE); | ||||
|   g_return_val_if_fail (xwindow != None, FALSE); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (!klass->grab_key) | ||||
|     return FALSE; | ||||
|  | ||||
|   return (klass->grab_key) (device_map, xwindow, keycode, modifiers, sync); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_ungrab_key (MetaDeviceMap *device_map, | ||||
|                             Window         xwindow, | ||||
|                             guint          keycode, | ||||
|                             guint          modifiers) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_MAP (device_map)); | ||||
|   g_return_if_fail (xwindow != None); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (klass->ungrab_key) | ||||
|     (klass->ungrab_key) (device_map, xwindow, keycode, modifiers); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_device_map_grab_button (MetaDeviceMap *device_map, | ||||
|                              Window         xwindow, | ||||
|                              guint          n_button, | ||||
|                              guint          modifiers, | ||||
|                              guint          evmask, | ||||
|                              gboolean       sync) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE); | ||||
|   g_return_val_if_fail (xwindow != None, FALSE); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (!klass->grab_button) | ||||
|     return FALSE; | ||||
|  | ||||
|   return (klass->grab_button) (device_map, xwindow, n_button, | ||||
|                                modifiers, evmask, sync); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_ungrab_button (MetaDeviceMap *device_map, | ||||
|                                Window         xwindow, | ||||
|                                guint          n_button, | ||||
|                                guint          modifiers) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_MAP (device_map)); | ||||
|   g_return_if_fail (xwindow != None); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (klass->ungrab_button) | ||||
|     (klass->ungrab_button) (device_map, xwindow, n_button, modifiers); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_grab_touch (MetaDeviceMap *device_map, | ||||
|                             Window         xwindow) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_MAP (device_map)); | ||||
|   g_return_if_fail (xwindow != None); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (klass->grab_touch) | ||||
|     (klass->grab_touch) (device_map, xwindow); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_map_ungrab_touch (MetaDeviceMap *device_map, | ||||
|                               Window         xwindow) | ||||
| { | ||||
|   MetaDeviceMapClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_MAP (device_map)); | ||||
|   g_return_if_fail (xwindow != None); | ||||
|  | ||||
|   klass = META_DEVICE_MAP_GET_CLASS (device_map); | ||||
|  | ||||
|   if (klass->ungrab_touch) | ||||
|     (klass->ungrab_touch) (device_map, xwindow); | ||||
| } | ||||
							
								
								
									
										124
									
								
								src/core/device-pointer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/core/device-pointer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Pointer device abstraction */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "device-pointer.h" | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE (MetaDevicePointer, | ||||
|                         meta_device_pointer, | ||||
|                         META_TYPE_DEVICE) | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_class_init (MetaDevicePointerClass *klass) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_init (MetaDevicePointer *pointer) | ||||
| { | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_pointer_warp (MetaDevicePointer *pointer, | ||||
|                           MetaScreen        *screen, | ||||
|                           gint               x, | ||||
|                           gint               y) | ||||
| { | ||||
|   MetaDevicePointerClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_POINTER (pointer)); | ||||
|   g_return_if_fail (META_IS_SCREEN (screen)); | ||||
|  | ||||
|   klass = META_DEVICE_POINTER_GET_CLASS (pointer); | ||||
|  | ||||
|   if (klass->warp) | ||||
|     (klass->warp) (pointer, screen, x, y); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer, | ||||
|                                        Window             xwindow, | ||||
|                                        MetaCursor         cursor) | ||||
| { | ||||
|   MetaDevicePointerClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE_POINTER (pointer)); | ||||
|   g_return_if_fail (xwindow != None); | ||||
|  | ||||
|   klass = META_DEVICE_POINTER_GET_CLASS (pointer); | ||||
|  | ||||
|   if (klass->set_window_cursor) | ||||
|     (klass->set_window_cursor) (pointer, xwindow, cursor); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_device_pointer_query_position (MetaDevicePointer *pointer, | ||||
|                                     Window             xwindow, | ||||
|                                     Window            *root_ret, | ||||
|                                     Window            *child_ret, | ||||
|                                     gint              *root_x_ret, | ||||
|                                     gint              *root_y_ret, | ||||
|                                     gint              *x_ret, | ||||
|                                     gint              *y_ret, | ||||
|                                     guint             *mask_ret) | ||||
| { | ||||
|   MetaDevicePointerClass *klass; | ||||
|   gint root_x, root_y, x, y; | ||||
|   Window root, child; | ||||
|   gboolean retval; | ||||
|   guint mask; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE_POINTER (pointer), FALSE); | ||||
|   g_return_val_if_fail (xwindow != None, FALSE); | ||||
|  | ||||
|   klass = META_DEVICE_POINTER_GET_CLASS (pointer); | ||||
|  | ||||
|   if (!klass->query_position) | ||||
|     return FALSE; | ||||
|  | ||||
|   retval = (klass->query_position) (pointer, xwindow, &root, &child, | ||||
|                                     &root_x, &root_y, &x, &y, &mask); | ||||
|  | ||||
|   if (root_ret) | ||||
|     *root_ret = root; | ||||
|  | ||||
|   if (child_ret) | ||||
|     *child_ret = child; | ||||
|  | ||||
|   if (root_x_ret) | ||||
|     *root_x_ret = root_x; | ||||
|  | ||||
|   if (root_y_ret) | ||||
|     *root_y_ret = root_y; | ||||
|  | ||||
|   if (x_ret) | ||||
|     *x_ret = x; | ||||
|  | ||||
|   if (y_ret) | ||||
|     *y_ret = y; | ||||
|  | ||||
|   if (mask_ret) | ||||
|     *mask_ret = mask; | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
							
								
								
									
										95
									
								
								src/core/device-pointer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/core/device-pointer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device-pointer.h  Pointer device abstraction | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the internal abstraction of pointer devices so | ||||
|  * XInput2/core events can be handled similarly. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_POINTER_H | ||||
| #define META_DEVICE_POINTER_H | ||||
|  | ||||
| #include "display-private.h" | ||||
| #include <meta/screen.h> | ||||
| #include "device-private.h" | ||||
|  | ||||
| #define META_TYPE_DEVICE_POINTER            (meta_device_pointer_get_type ()) | ||||
| #define META_DEVICE_POINTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER, MetaDevicePointer)) | ||||
| #define META_DEVICE_POINTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_POINTER, MetaDevicePointerClass)) | ||||
| #define META_IS_DEVICE_POINTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER)) | ||||
| #define META_IS_DEVICE_POINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_POINTER)) | ||||
| #define META_DEVICE_POINTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_POINTER, MetaDevicePointerClass)) | ||||
|  | ||||
| typedef struct _MetaDevicePointer MetaDevicePointer; | ||||
| typedef struct _MetaDevicePointerClass MetaDevicePointerClass; | ||||
|  | ||||
| struct _MetaDevicePointer | ||||
| { | ||||
|   MetaDevice parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDevicePointerClass | ||||
| { | ||||
|   MetaDeviceClass parent_instance; | ||||
|  | ||||
|   void     (* warp)           (MetaDevicePointer *pointer, | ||||
|                                MetaScreen        *screen, | ||||
|                                gint               x, | ||||
|                                gint               y); | ||||
|  | ||||
|   void (* set_window_cursor)  (MetaDevicePointer *pointer, | ||||
|                                Window             xwindow, | ||||
|                                MetaCursor         cursor); | ||||
|   gboolean (* query_position) (MetaDevicePointer *pointer, | ||||
|                                Window             xwindow, | ||||
|                                Window            *root, | ||||
|                                Window            *child, | ||||
|                                gint              *root_x, | ||||
|                                gint              *root_y, | ||||
|                                gint              *x, | ||||
|                                gint              *y, | ||||
|                                guint             *mask); | ||||
| }; | ||||
|  | ||||
| GType    meta_device_pointer_get_type      (void) G_GNUC_CONST; | ||||
|  | ||||
| void     meta_device_pointer_warp              (MetaDevicePointer *pointer, | ||||
|                                                 MetaScreen        *screen, | ||||
|                                                 gint               x, | ||||
|                                                 gint               y); | ||||
| void     meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer, | ||||
| 						Window             xwindow, | ||||
| 						MetaCursor         cursor); | ||||
|  | ||||
| gboolean meta_device_pointer_query_position    (MetaDevicePointer *pointer, | ||||
|                                                 Window             xwindow, | ||||
|                                                 Window            *root, | ||||
|                                                 Window            *child, | ||||
|                                                 gint              *root_x, | ||||
|                                                 gint              *root_y, | ||||
|                                                 gint              *x, | ||||
|                                                 gint              *y, | ||||
|                                                 guint             *mask); | ||||
|  | ||||
| #endif /* META_DEVICE_POINTER_H */ | ||||
							
								
								
									
										80
									
								
								src/core/device-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/core/device-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file device.h  Input device abstraction | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the internal abstraction of input devices so | ||||
|  * XInput2/core events can be handled similarly. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_PRIVATE_H | ||||
| #define META_DEVICE_PRIVATE_H | ||||
|  | ||||
| #include <meta/device.h> | ||||
| #include "display-private.h" | ||||
|  | ||||
| struct _MetaDevice | ||||
| { | ||||
|   GObject parent_instance; | ||||
|   gpointer priv; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceClass | ||||
| { | ||||
|   GObjectClass parent_instance; | ||||
|  | ||||
|   void     (* allow_events) (MetaDevice  *device, | ||||
|                              int          mode, | ||||
|                              Time         time); | ||||
|  | ||||
|   gboolean (* grab)         (MetaDevice *device, | ||||
|                              Window      xwindow, | ||||
|                              guint       evmask, | ||||
|                              MetaCursor  cursor, | ||||
|                              gboolean    owner_events, | ||||
|                              gboolean    sync, | ||||
|                              Time        time); | ||||
|   void     (* ungrab)       (MetaDevice *device, | ||||
|                              Time        time); | ||||
| }; | ||||
|  | ||||
| GType        meta_device_get_type     (void) G_GNUC_CONST; | ||||
|  | ||||
| void         meta_device_allow_events (MetaDevice  *device, | ||||
|                                        int          mode, | ||||
|                                        Time         time); | ||||
|  | ||||
| gboolean     meta_device_grab         (MetaDevice *device, | ||||
|                                        Window      xwindow, | ||||
|                                        guint       evmask, | ||||
|                                        MetaCursor  cursor, | ||||
|                                        gboolean    owner_events, | ||||
|                                        gboolean    sync, | ||||
|                                        Time        time); | ||||
| void         meta_device_ungrab       (MetaDevice *device, | ||||
|                                        Time        time); | ||||
|  | ||||
| void         meta_device_pair_devices      (MetaDevice *device, | ||||
|                                             MetaDevice *other_device); | ||||
|  | ||||
| #endif /* META_DEVICE_PRIVATE_H */ | ||||
							
								
								
									
										270
									
								
								src/core/device.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/core/device.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,270 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Input device abstraction */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "device-private.h" | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE (MetaDevice, meta_device, G_TYPE_OBJECT) | ||||
|  | ||||
| enum { | ||||
|   PROP_0, | ||||
|   PROP_DEVICE_ID, | ||||
|   PROP_DISPLAY, | ||||
|   PROP_PAIRED_DEVICE | ||||
| }; | ||||
|  | ||||
| typedef struct MetaDevicePrivate MetaDevicePrivate; | ||||
|  | ||||
| struct MetaDevicePrivate | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   MetaDevice *paired_device; | ||||
|   gint device_id; | ||||
| }; | ||||
|  | ||||
| static void | ||||
| meta_device_get_property (GObject    *object, | ||||
|                           guint       param_id, | ||||
|                           GValue     *value, | ||||
|                           GParamSpec *pspec) | ||||
| { | ||||
|   switch (param_id) | ||||
|     { | ||||
|     case PROP_DEVICE_ID: | ||||
|       g_value_set_int (value, | ||||
|                        meta_device_get_id (META_DEVICE (object))); | ||||
|       break; | ||||
|     case PROP_DISPLAY: | ||||
|       g_value_set_object (value, | ||||
|                           meta_device_get_display (META_DEVICE (object))); | ||||
|       break; | ||||
|     case PROP_PAIRED_DEVICE: | ||||
|       g_value_set_object (value, | ||||
|                           meta_device_get_paired_device (META_DEVICE (object))); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_set_property (GObject      *object, | ||||
|                           guint         param_id, | ||||
|                           const GValue *value, | ||||
|                           GParamSpec   *pspec) | ||||
| { | ||||
|   MetaDevicePrivate *priv = META_DEVICE (object)->priv; | ||||
|  | ||||
|   switch (param_id) | ||||
|     { | ||||
|     case PROP_DEVICE_ID: | ||||
|       priv->device_id = g_value_get_int (value); | ||||
|       break; | ||||
|     case PROP_DISPLAY: | ||||
|       priv->display = g_value_get_object (value); | ||||
|       break; | ||||
|     case PROP_PAIRED_DEVICE: | ||||
|       meta_device_pair_devices (META_DEVICE (object), | ||||
|                                 g_value_get_object (value)); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_class_init (MetaDeviceClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->get_property = meta_device_get_property; | ||||
|   object_class->set_property = meta_device_set_property; | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_DEVICE_ID, | ||||
|                                    g_param_spec_int ("device-id", | ||||
|                                                      "Device ID", | ||||
|                                                      "Device ID", | ||||
|                                                      2, G_MAXINT, 2, | ||||
|                                                      G_PARAM_READWRITE | | ||||
|                                                      G_PARAM_CONSTRUCT_ONLY)); | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_DISPLAY, | ||||
|                                    g_param_spec_object ("display", | ||||
|                                                         "Display", | ||||
|                                                         "Display", | ||||
|                                                         META_TYPE_DISPLAY, | ||||
|                                                         G_PARAM_READWRITE | | ||||
|                                                         G_PARAM_CONSTRUCT_ONLY)); | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_PAIRED_DEVICE, | ||||
|                                    g_param_spec_object ("paired-device", | ||||
|                                                         "Paired device", | ||||
|                                                         "Paired device", | ||||
|                                                         META_TYPE_DEVICE, | ||||
|                                                         G_PARAM_READWRITE)); | ||||
|  | ||||
|   g_type_class_add_private (klass, sizeof (MetaDevicePrivate)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_init (MetaDevice *device) | ||||
| { | ||||
|   device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, | ||||
|                                               META_TYPE_DEVICE, | ||||
|                                               MetaDevicePrivate); | ||||
| } | ||||
|  | ||||
| int | ||||
| meta_device_get_id (MetaDevice *device) | ||||
| { | ||||
|   MetaDevicePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE (device), 0); | ||||
|  | ||||
|   priv = device->priv; | ||||
|   return priv->device_id; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_device_get_display: | ||||
|  * @device: a #MetaDevice | ||||
|  * | ||||
|  * Returns the #MetaDisplay to which the device belongs | ||||
|  * | ||||
|  * Returns: (transfer none): the #MetaDisplay to which the device belongs | ||||
|  **/ | ||||
| MetaDisplay * | ||||
| meta_device_get_display (MetaDevice *device) | ||||
| { | ||||
|   MetaDevicePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE (device), NULL); | ||||
|  | ||||
|   priv = device->priv; | ||||
|   return priv->display; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_allow_events (MetaDevice  *device, | ||||
|                           int          mode, | ||||
|                           Time         time) | ||||
| { | ||||
|   MetaDeviceClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE (device)); | ||||
|  | ||||
|   klass = META_DEVICE_GET_CLASS (device); | ||||
|  | ||||
|   if (klass->allow_events) | ||||
|     (klass->allow_events) (device, mode, time); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_device_grab (MetaDevice *device, | ||||
|                   Window      xwindow, | ||||
|                   guint       evmask, | ||||
|                   MetaCursor  cursor, | ||||
|                   gboolean    owner_events, | ||||
|                   gboolean    sync, | ||||
|                   Time        time) | ||||
| { | ||||
|   MetaDeviceClass *klass; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE (device), FALSE); | ||||
|   g_return_val_if_fail (xwindow != None, FALSE); | ||||
|  | ||||
|   klass = META_DEVICE_GET_CLASS (device); | ||||
|  | ||||
|   if (!klass->grab) | ||||
|     return FALSE; | ||||
|  | ||||
|   return (klass->grab) (device, xwindow, evmask, cursor, | ||||
|                         owner_events, sync, time); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_ungrab (MetaDevice *device, | ||||
|                     Time        time) | ||||
| { | ||||
|   MetaDeviceClass *klass; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE (device)); | ||||
|  | ||||
|   klass = META_DEVICE_GET_CLASS (device); | ||||
|  | ||||
|   if (klass->ungrab) | ||||
|     (klass->ungrab) (device, time); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_device_pair_devices (MetaDevice *device, | ||||
|                           MetaDevice *other_device) | ||||
| { | ||||
|   MetaDevicePrivate *priv1, *priv2; | ||||
|  | ||||
|   g_return_if_fail (META_IS_DEVICE (device)); | ||||
|   g_return_if_fail (META_IS_DEVICE (other_device)); | ||||
|  | ||||
|   priv1 = device->priv; | ||||
|   priv2 = other_device->priv; | ||||
|  | ||||
|   /* Consider safe multiple calls | ||||
|    * on already paired devices | ||||
|    */ | ||||
|   if (priv1->paired_device != NULL && | ||||
|       priv2->paired_device != NULL && | ||||
|       priv1->paired_device == other_device && | ||||
|       priv2->paired_device == device) | ||||
|     return; | ||||
|  | ||||
|   g_return_if_fail (priv1->paired_device == NULL); | ||||
|   g_return_if_fail (priv2->paired_device == NULL); | ||||
|  | ||||
|   priv1->paired_device = g_object_ref (other_device); | ||||
|   priv2->paired_device = g_object_ref (device); | ||||
|  | ||||
|   g_object_notify (G_OBJECT (device), "paired-device"); | ||||
|   g_object_notify (G_OBJECT (other_device), "paired-device"); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_device_get_paired_device: | ||||
|  * @device: a #MetaDevice | ||||
|  * | ||||
|  * Returns the paired device. Devices come in keyboard/pointer pairs. | ||||
|  * | ||||
|  * Returns: (transfer none): The paired device. | ||||
|  **/ | ||||
| MetaDevice * | ||||
| meta_device_get_paired_device (MetaDevice *device) | ||||
| { | ||||
|   MetaDevicePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_DEVICE (device), NULL); | ||||
|  | ||||
|   priv = device->priv; | ||||
|   return priv->paired_device; | ||||
| } | ||||
							
								
								
									
										256
									
								
								src/core/devices-core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								src/core/devices-core.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,256 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* Core input devices implementation */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "screen-private.h" | ||||
| #include "devices-core.h" | ||||
| #include "device-map-private.h" | ||||
|  | ||||
| /* Common functions */ | ||||
| static void | ||||
| meta_device_core_common_allow_events (MetaDevice *device, | ||||
|                                       int         mode, | ||||
|                                       Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   XAllowEvents (display->xdisplay, mode, time); | ||||
| } | ||||
|  | ||||
| /* Core pointer */ | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDevicePointerCore, | ||||
|                meta_device_pointer_core, | ||||
|                META_TYPE_DEVICE_POINTER) | ||||
|  | ||||
| static gboolean | ||||
| meta_device_pointer_core_grab (MetaDevice *device, | ||||
|                                Window      xwindow, | ||||
|                                guint       evmask, | ||||
|                                MetaCursor  cursor, | ||||
|                                gboolean    owner_events, | ||||
|                                gboolean    sync, | ||||
|                                Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Cursor xcursor; | ||||
|   int retval; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   xcursor = meta_display_create_x_cursor (display, cursor); | ||||
|  | ||||
|   retval = XGrabPointer (display->xdisplay, | ||||
|                          xwindow, owner_events, | ||||
|                          evmask, | ||||
|                          (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                          (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                          None, xcursor, time); | ||||
|  | ||||
|   if (xcursor != None) | ||||
|     XFreeCursor (display->xdisplay, xcursor); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_core_ungrab (MetaDevice *device, | ||||
|                                  Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   XUngrabPointer (display->xdisplay, time); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_core_warp (MetaDevicePointer *pointer, | ||||
|                                MetaScreen        *screen, | ||||
|                                gint               x, | ||||
|                                gint               y) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   XWarpPointer (display->xdisplay, | ||||
|                 None, screen->xroot, | ||||
|                 0, 0, 0, 0, x, y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_core_set_window_cursor (MetaDevicePointer *pointer, | ||||
|                                             Window             xwindow, | ||||
|                                             MetaCursor         cursor) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Cursor xcursor; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   xcursor = meta_display_create_x_cursor (display, cursor); | ||||
|  | ||||
|   XDefineCursor (display->xdisplay, xwindow, xcursor); | ||||
|  | ||||
|   if (xcursor != None) | ||||
|     XFreeCursor (display->xdisplay, xcursor); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_device_pointer_core_query_position (MetaDevicePointer *pointer, | ||||
|                                          Window             xwindow, | ||||
|                                          Window            *root, | ||||
|                                          Window            *child, | ||||
|                                          gint              *root_x, | ||||
|                                          gint              *root_y, | ||||
|                                          gint              *x, | ||||
|                                          gint              *y, | ||||
|                                          guint             *mask) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   return XQueryPointer (display->xdisplay, xwindow, | ||||
|                         root, child, root_x, root_y, | ||||
|                         x, y, mask); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_core_class_init (MetaDevicePointerCoreClass *klass) | ||||
| { | ||||
|   MetaDevicePointerClass *pointer_class = META_DEVICE_POINTER_CLASS (klass); | ||||
|   MetaDeviceClass *device_class = META_DEVICE_CLASS (klass); | ||||
|  | ||||
|   device_class->allow_events = meta_device_core_common_allow_events; | ||||
|   device_class->grab = meta_device_pointer_core_grab; | ||||
|   device_class->ungrab = meta_device_pointer_core_ungrab; | ||||
|  | ||||
|   pointer_class->warp = meta_device_pointer_core_warp; | ||||
|   pointer_class->set_window_cursor = meta_device_pointer_core_set_window_cursor; | ||||
|   pointer_class->query_position = meta_device_pointer_core_query_position; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_core_init (MetaDevicePointerCore *pointer) | ||||
| { | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_device_pointer_core_new (MetaDisplay *display) | ||||
| { | ||||
|   return g_object_new (META_TYPE_DEVICE_POINTER_CORE, | ||||
|                        "device-id", META_CORE_POINTER_ID, | ||||
|                        "display", display, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Core Keyboard */ | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDeviceKeyboardCore, | ||||
|                meta_device_keyboard_core, | ||||
|                META_TYPE_DEVICE_KEYBOARD) | ||||
|  | ||||
| static gboolean | ||||
| meta_device_keyboard_core_grab (MetaDevice *device, | ||||
|                                 Window      xwindow, | ||||
|                                 guint       evmask, | ||||
|                                 MetaCursor  cursor, | ||||
|                                 gboolean    owner_events, | ||||
|                                 gboolean    sync, | ||||
|                                 Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   gint retval; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   retval = XGrabKeyboard (display->xdisplay, xwindow, owner_events, | ||||
|                           (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                           (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                           time); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_core_ungrab (MetaDevice *device, | ||||
|                                   Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   XUngrabKeyboard (display->xdisplay, time); | ||||
| } | ||||
|  | ||||
| static Window | ||||
| meta_device_keyboard_core_get_focus_window (MetaDeviceKeyboard *keyboard) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Window xwindow; | ||||
|   int unused; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (keyboard)); | ||||
|   XGetInputFocus (display->xdisplay, &xwindow, &unused); | ||||
|  | ||||
|   return xwindow; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_core_set_focus_window (MetaDeviceKeyboard *keyboard, | ||||
|                                             Window              xwindow, | ||||
|                                             Time                timestamp) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (keyboard)); | ||||
|   XSetInputFocus (display->xdisplay, | ||||
|                   xwindow, | ||||
|                   RevertToPointerRoot, | ||||
|                   timestamp); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_core_class_init (MetaDeviceKeyboardCoreClass *klass) | ||||
| { | ||||
|   MetaDeviceKeyboardClass *keyboard_class = META_DEVICE_KEYBOARD_CLASS (klass); | ||||
|   MetaDeviceClass *device_class = META_DEVICE_CLASS (klass); | ||||
|  | ||||
|   keyboard_class->get_focus_window = meta_device_keyboard_core_get_focus_window; | ||||
|   keyboard_class->set_focus_window = meta_device_keyboard_core_set_focus_window; | ||||
|  | ||||
|   device_class->allow_events = meta_device_core_common_allow_events; | ||||
|   device_class->grab = meta_device_keyboard_core_grab; | ||||
|   device_class->ungrab = meta_device_keyboard_core_ungrab; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_core_init (MetaDeviceKeyboardCore *keyboard) | ||||
| { | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_device_keyboard_core_new (MetaDisplay *display) | ||||
| { | ||||
|   return g_object_new (META_TYPE_DEVICE_KEYBOARD_CORE, | ||||
|                        "device-id", META_CORE_KEYBOARD_ID, | ||||
|                        "display", display, | ||||
|                        NULL); | ||||
| } | ||||
							
								
								
									
										85
									
								
								src/core/devices-core.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/core/devices-core.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file devices-core.h  Core input devices implementation | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the core X protocol implementation of input devices. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICES_CORE_H | ||||
| #define META_DEVICES_CORE_H | ||||
|  | ||||
| #include "device-pointer.h" | ||||
| #include "device-keyboard.h" | ||||
|  | ||||
| /* Pointer */ | ||||
| #define META_TYPE_DEVICE_POINTER_CORE            (meta_device_pointer_core_get_type ()) | ||||
| #define META_DEVICE_POINTER_CORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCore)) | ||||
| #define META_DEVICE_POINTER_CORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCoreClass)) | ||||
| #define META_IS_DEVICE_POINTER_CORE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER_CORE)) | ||||
| #define META_IS_DEVICE_POINTER_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_POINTER_CORE)) | ||||
| #define META_DEVICE_POINTER_CORE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_POINTER_CORE, MetaDevicePointerCoreClass)) | ||||
|  | ||||
| typedef struct _MetaDevicePointerCore MetaDevicePointerCore; | ||||
| typedef struct _MetaDevicePointerCoreClass MetaDevicePointerCoreClass; | ||||
|  | ||||
| struct _MetaDevicePointerCore | ||||
| { | ||||
|   MetaDevicePointer parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDevicePointerCoreClass | ||||
| { | ||||
|   MetaDevicePointerClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType       meta_device_pointer_core_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDevice *meta_device_pointer_core_new      (MetaDisplay *display); | ||||
|  | ||||
| /* Keyboard */ | ||||
| #define META_TYPE_DEVICE_KEYBOARD_CORE            (meta_device_keyboard_core_get_type ()) | ||||
| #define META_DEVICE_KEYBOARD_CORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCore)) | ||||
| #define META_DEVICE_KEYBOARD_CORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCoreClass)) | ||||
| #define META_IS_DEVICE_KEYBOARD_CORE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD_CORE)) | ||||
| #define META_IS_DEVICE_KEYBOARD_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_KEYBOARD_CORE)) | ||||
| #define META_DEVICE_KEYBOARD_CORE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_KEYBOARD_CORE, MetaDeviceKeyboardCoreClass)) | ||||
|  | ||||
| typedef struct _MetaDeviceKeyboardCore MetaDeviceKeyboardCore; | ||||
| typedef struct _MetaDeviceKeyboardCoreClass MetaDeviceKeyboardCoreClass; | ||||
|  | ||||
| struct _MetaDeviceKeyboardCore | ||||
| { | ||||
|   MetaDeviceKeyboard parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceKeyboardCoreClass | ||||
| { | ||||
|   MetaDeviceKeyboardClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType       meta_device_keyboard_core_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDevice *meta_device_keyboard_core_new      (MetaDisplay *display); | ||||
|  | ||||
| #endif /* META_DEVICES_CORE_H */ | ||||
							
								
								
									
										353
									
								
								src/core/devices-xi2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								src/core/devices-xi2.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,353 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* XInput2 devices implementation */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "devices-xi2.h" | ||||
| #include "display-private.h" | ||||
| #include "screen-private.h" | ||||
| #include "input-events.h" | ||||
| #include <X11/extensions/XInput2.h> | ||||
|  | ||||
| /* Common functions */ | ||||
| static void | ||||
| meta_device_xi2_common_allow_events (MetaDevice *device, | ||||
|                                      int         mode, | ||||
|                                      Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   gint device_id; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   device_id = meta_device_get_id (device); | ||||
|  | ||||
|   switch (mode) | ||||
|     { | ||||
|     case AsyncPointer: | ||||
|     case AsyncKeyboard: | ||||
|       mode = XIAsyncDevice; | ||||
|       break; | ||||
|     case SyncPointer: | ||||
|     case SyncKeyboard: | ||||
|       mode = XISyncDevice; | ||||
|       break; | ||||
|     case ReplayPointer: | ||||
|     case ReplayKeyboard: | ||||
|       mode = XIReplayDevice; | ||||
|       break; | ||||
|     case AsyncBoth: | ||||
|       mode = XIAsyncPair; | ||||
|       break; | ||||
|     case SyncBoth: | ||||
|       mode = XISyncPair; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   XIAllowEvents (display->xdisplay, device_id, mode, time); | ||||
| } | ||||
|  | ||||
| guchar * | ||||
| meta_device_xi2_translate_event_mask (guint  evmask, | ||||
|                                       gint  *len) | ||||
| { | ||||
|   guchar *mask; | ||||
|  | ||||
|   *len = XIMaskLen (XI_LASTEVENT); | ||||
|   mask = g_new0 (guchar, *len); | ||||
|  | ||||
|   if (evmask & KeyPressMask) | ||||
|     XISetMask (mask, XI_KeyPress); | ||||
|   if (evmask & KeyReleaseMask) | ||||
|     XISetMask (mask, XI_KeyRelease); | ||||
|   if (evmask & ButtonPressMask) | ||||
|     XISetMask (mask, XI_ButtonPress); | ||||
|   if (evmask & ButtonReleaseMask) | ||||
|     XISetMask (mask, XI_ButtonRelease); | ||||
|   if (evmask & EnterWindowMask) | ||||
|     XISetMask (mask, XI_Enter); | ||||
|   if (evmask & LeaveWindowMask) | ||||
|     XISetMask (mask, XI_Leave); | ||||
|  | ||||
|   /* No motion hints in XI2 at the moment... */ | ||||
|   if (evmask & PointerMotionMask || | ||||
|       evmask & PointerMotionHintMask) | ||||
|     XISetMask (mask, XI_Motion); | ||||
|  | ||||
|   if (evmask & FocusChangeMask) | ||||
|     { | ||||
|       XISetMask (mask, XI_FocusIn); | ||||
|       XISetMask (mask, XI_FocusOut); | ||||
|     } | ||||
|  | ||||
| #ifdef HAVE_XTOUCH | ||||
|   if (evmask & META_INPUT_TOUCH_EVENTS_MASK) | ||||
|     { | ||||
|       XISetMask (mask, XI_TouchBegin); | ||||
|       XISetMask (mask, XI_TouchEnd); | ||||
|       XISetMask (mask, XI_TouchUpdate); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   return mask; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_device_xi2_common_grab (MetaDevice *device, | ||||
|                              Window      xwindow, | ||||
|                              guint       evmask, | ||||
|                              MetaCursor  cursor, | ||||
|                              gboolean    owner_events, | ||||
|                              gboolean    sync, | ||||
|                              Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   XIEventMask mask; | ||||
|   gint device_id, retval; | ||||
|   Cursor xcursor; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   device_id = meta_device_get_id (device); | ||||
|   xcursor = meta_display_create_x_cursor (display, cursor); | ||||
|  | ||||
|   mask.deviceid = device_id; | ||||
|   mask.mask = meta_device_xi2_translate_event_mask (evmask, &mask.mask_len); | ||||
|  | ||||
|   retval = XIGrabDevice (display->xdisplay, | ||||
|                          device_id, xwindow, | ||||
|                          time, xcursor, | ||||
|                          (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                          (sync) ? GrabModeSync : GrabModeAsync, | ||||
|                          owner_events, &mask); | ||||
|  | ||||
|   if (xcursor != None) | ||||
|     XFreeCursor (display->xdisplay, xcursor); | ||||
|  | ||||
|   return (retval == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_xi2_common_ungrab (MetaDevice *device, | ||||
|                                Time        time) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   gint device_id; | ||||
|  | ||||
|   display = meta_device_get_display (device); | ||||
|   device_id = meta_device_get_id (device); | ||||
|  | ||||
|   XIUngrabDevice (display->xdisplay, device_id, time); | ||||
| } | ||||
|  | ||||
| /* Pointer */ | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDevicePointerXI2, | ||||
|                meta_device_pointer_xi2, | ||||
|                META_TYPE_DEVICE_POINTER) | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_xi2_warp (MetaDevicePointer *pointer, | ||||
|                               MetaScreen        *screen, | ||||
|                               gint               x, | ||||
|                               gint               y) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   int device_id; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   device_id = meta_device_get_id (META_DEVICE (pointer)); | ||||
|  | ||||
|   XIWarpPointer (display->xdisplay, | ||||
|                  device_id, | ||||
|                  None, screen->xroot, | ||||
|                  0, 0, 0, 0, x, y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_xi2_set_window_cursor (MetaDevicePointer *pointer, | ||||
|                                            Window             xwindow, | ||||
|                                            MetaCursor         cursor) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Cursor xcursor; | ||||
|   int device_id; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   device_id = meta_device_get_id (META_DEVICE (pointer)); | ||||
|   xcursor = meta_display_create_x_cursor (display, cursor); | ||||
|  | ||||
|   if (xcursor != None) | ||||
|     { | ||||
|       XIDefineCursor (display->xdisplay, device_id, xwindow, xcursor); | ||||
|       XFreeCursor (display->xdisplay, xcursor); | ||||
|     } | ||||
|   else | ||||
|     XIUndefineCursor (display->xdisplay, device_id, xwindow); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_device_pointer_xi2_query_position (MetaDevicePointer *pointer, | ||||
|                                         Window             xwindow, | ||||
|                                         Window            *root_ret, | ||||
|                                         Window            *child_ret, | ||||
|                                         gint              *root_x_ret, | ||||
|                                         gint              *root_y_ret, | ||||
|                                         gint              *x_ret, | ||||
|                                         gint              *y_ret, | ||||
|                                         guint             *mask_ret) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   XIModifierState mods; | ||||
|   XIGroupState group_unused; | ||||
|   XIButtonState buttons; | ||||
|   gdouble root_x, root_y, x, y; | ||||
|   int device_id; | ||||
|   gboolean retval; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (pointer)); | ||||
|   device_id = meta_device_get_id (META_DEVICE (pointer)); | ||||
|  | ||||
|   retval = XIQueryPointer (display->xdisplay, | ||||
|                            device_id, xwindow, | ||||
|                            root_ret, child_ret, | ||||
|                            &root_x, &root_y, &x, &y, | ||||
|                            &buttons, &mods, | ||||
|                            &group_unused); | ||||
|   if (mask_ret) | ||||
|     { | ||||
|       *mask_ret = mods.effective; | ||||
|  | ||||
|       if (XIMaskIsSet (buttons.mask, 1)) | ||||
|         *mask_ret |= Button1Mask; | ||||
|       else if (XIMaskIsSet (buttons.mask, 2)) | ||||
|         *mask_ret |= Button2Mask; | ||||
|       else if (XIMaskIsSet (buttons.mask, 3)) | ||||
|         *mask_ret |= Button3Mask; | ||||
|     } | ||||
|  | ||||
|   if (root_x_ret) | ||||
|     *root_x_ret = (int) root_x; | ||||
|  | ||||
|   if (root_y_ret) | ||||
|     *root_y_ret = (int) root_y; | ||||
|  | ||||
|   if (x_ret) | ||||
|     *x_ret = (int) x; | ||||
|  | ||||
|   if (y_ret) | ||||
|     *y_ret = (int) y; | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_xi2_class_init (MetaDevicePointerXI2Class *klass) | ||||
| { | ||||
|   MetaDevicePointerClass *pointer_class = META_DEVICE_POINTER_CLASS (klass); | ||||
|   MetaDeviceClass *device_class = META_DEVICE_CLASS (klass); | ||||
|  | ||||
|   device_class->allow_events = meta_device_xi2_common_allow_events; | ||||
|   device_class->grab = meta_device_xi2_common_grab; | ||||
|   device_class->ungrab = meta_device_xi2_common_ungrab; | ||||
|  | ||||
|   pointer_class->warp = meta_device_pointer_xi2_warp; | ||||
|   pointer_class->set_window_cursor = meta_device_pointer_xi2_set_window_cursor; | ||||
|   pointer_class->query_position = meta_device_pointer_xi2_query_position; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_pointer_xi2_init (MetaDevicePointerXI2 *pointer) | ||||
| { | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_device_pointer_xi2_new (MetaDisplay *display, | ||||
|                              gint         device_id) | ||||
| { | ||||
|   return g_object_new (META_TYPE_DEVICE_POINTER_XI2, | ||||
|                        "device-id", device_id, | ||||
|                        "display", display, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /* Keyboard */ | ||||
|  | ||||
| G_DEFINE_TYPE (MetaDeviceKeyboardXI2, | ||||
|                meta_device_keyboard_xi2, | ||||
|                META_TYPE_DEVICE_KEYBOARD) | ||||
|  | ||||
| static Window | ||||
| meta_device_keyboard_xi2_get_focus_window (MetaDeviceKeyboard *keyboard) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   Window xwindow; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (keyboard)); | ||||
|   XIGetFocus (display->xdisplay, | ||||
|               meta_device_get_id (META_DEVICE (keyboard)), | ||||
|               &xwindow); | ||||
|  | ||||
|   return xwindow; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_xi2_set_focus_window (MetaDeviceKeyboard *keyboard, | ||||
|                                            Window              xwindow, | ||||
|                                            Time                timestamp) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_device_get_display (META_DEVICE (keyboard)); | ||||
|  | ||||
|   XISetFocus (display->xdisplay, | ||||
|               meta_device_get_id (META_DEVICE (keyboard)), | ||||
|               xwindow, | ||||
|               timestamp); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_xi2_class_init (MetaDeviceKeyboardXI2Class *klass) | ||||
| { | ||||
|   MetaDeviceKeyboardClass *keyboard_class = META_DEVICE_KEYBOARD_CLASS (klass); | ||||
|   MetaDeviceClass *device_class = META_DEVICE_CLASS (klass); | ||||
|  | ||||
|   keyboard_class->get_focus_window = meta_device_keyboard_xi2_get_focus_window; | ||||
|   keyboard_class->set_focus_window = meta_device_keyboard_xi2_set_focus_window; | ||||
|  | ||||
|   device_class->allow_events = meta_device_xi2_common_allow_events; | ||||
|   device_class->grab = meta_device_xi2_common_grab; | ||||
|   device_class->ungrab = meta_device_xi2_common_ungrab; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_device_keyboard_xi2_init (MetaDeviceKeyboardXI2 *keyboard) | ||||
| { | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_device_keyboard_xi2_new (MetaDisplay *display, | ||||
|                               gint         device_id) | ||||
| { | ||||
|   return g_object_new (META_TYPE_DEVICE_KEYBOARD_XI2, | ||||
|                        "device-id", device_id, | ||||
|                        "display", display, | ||||
|                        NULL); | ||||
| } | ||||
							
								
								
									
										92
									
								
								src/core/devices-xi2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/core/devices-xi2.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file devices-xi2.h  XInput2 input devices implementation | ||||
|  * | ||||
|  * Input devices. | ||||
|  * This file contains the XInput2 implementation of input devices. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICES_XI2_H | ||||
| #define META_DEVICES_XI2_H | ||||
|  | ||||
| #include "device-pointer.h" | ||||
| #include "device-keyboard.h" | ||||
|  | ||||
| /* Pointer */ | ||||
| #define META_TYPE_DEVICE_POINTER_XI2            (meta_device_pointer_xi2_get_type ()) | ||||
| #define META_DEVICE_POINTER_XI2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2)) | ||||
| #define META_DEVICE_POINTER_XI2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class)) | ||||
| #define META_IS_DEVICE_POINTER_XI2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER_XI2)) | ||||
| #define META_IS_DEVICE_POINTER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_POINTER_XI2)) | ||||
| #define META_DEVICE_POINTER_XI2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class)) | ||||
|  | ||||
| typedef struct _MetaDevicePointerXI2 MetaDevicePointerXI2; | ||||
| typedef struct _MetaDevicePointerXI2Class MetaDevicePointerXI2Class; | ||||
|  | ||||
| struct _MetaDevicePointerXI2 | ||||
| { | ||||
|   MetaDevicePointer parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDevicePointerXI2Class | ||||
| { | ||||
|   MetaDevicePointerClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType       meta_device_pointer_xi2_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDevice *meta_device_pointer_xi2_new      (MetaDisplay *display, | ||||
|                                               gint         device_id); | ||||
|  | ||||
| /* Keyboard */ | ||||
| #define META_TYPE_DEVICE_KEYBOARD_XI2            (meta_device_keyboard_xi2_get_type ()) | ||||
| #define META_DEVICE_KEYBOARD_XI2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2)) | ||||
| #define META_DEVICE_KEYBOARD_XI2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class)) | ||||
| #define META_IS_DEVICE_KEYBOARD_XI2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD_XI2)) | ||||
| #define META_IS_DEVICE_KEYBOARD_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_KEYBOARD_XI2)) | ||||
| #define META_DEVICE_KEYBOARD_XI2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class)) | ||||
|  | ||||
| typedef struct _MetaDeviceKeyboardXI2 MetaDeviceKeyboardXI2; | ||||
| typedef struct _MetaDeviceKeyboardXI2Class MetaDeviceKeyboardXI2Class; | ||||
|  | ||||
| struct _MetaDeviceKeyboardXI2 | ||||
| { | ||||
|   MetaDeviceKeyboard parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaDeviceKeyboardXI2Class | ||||
| { | ||||
|   MetaDeviceKeyboardClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType       meta_device_keyboard_xi2_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDevice *meta_device_keyboard_xi2_new      (MetaDisplay *display, | ||||
|                                                gint         device_id); | ||||
|  | ||||
| /* Helper function for translating event masks */ | ||||
| guchar * meta_device_xi2_translate_event_mask (guint        evmask, | ||||
|                                                gint        *len); | ||||
|  | ||||
|  | ||||
| #endif /* META_DEVICES_XI2_H */ | ||||
| @@ -38,6 +38,7 @@ | ||||
| #include <meta/boxes.h> | ||||
| #include <meta/display.h> | ||||
| #include "keybindings-private.h" | ||||
| #include "device-map-private.h" | ||||
| #include <meta/prefs.h> | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| @@ -56,6 +57,10 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks; | ||||
|  | ||||
| typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; | ||||
|  | ||||
| typedef struct _MetaGrabInfo MetaGrabInfo; | ||||
| typedef struct _MetaFocusInfo MetaFocusInfo; | ||||
| typedef struct _MetaTouchInfo MetaTouchInfo; | ||||
|  | ||||
| typedef void (* MetaWindowPingFunc) (MetaDisplay *display, | ||||
| 				     Window       xwindow, | ||||
| 				     guint32      timestamp, | ||||
| @@ -86,6 +91,78 @@ typedef enum { | ||||
|   META_TILE_MAXIMIZED | ||||
| } MetaTileMode; | ||||
|  | ||||
| struct _MetaGrabInfo | ||||
| { | ||||
|   MetaDevice *grab_pointer; | ||||
|   MetaDevice *grab_keyboard; | ||||
|  | ||||
|   MetaGrabOp  grab_op; | ||||
|   MetaScreen *grab_screen; | ||||
|   MetaWindow *grab_window; | ||||
|   Window      grab_xwindow; | ||||
|   int         grab_button; | ||||
|   int         grab_anchor_root_x; | ||||
|   int         grab_anchor_root_y; | ||||
|   MetaRectangle grab_anchor_window_pos; | ||||
|   MetaTileMode  grab_tile_mode; | ||||
|   int           grab_tile_monitor_number; | ||||
|   int         grab_latest_motion_x; | ||||
|   int         grab_latest_motion_y; | ||||
|   gulong      grab_mask; | ||||
|   guint       grab_have_pointer : 1; | ||||
|   guint       grab_have_keyboard : 1; | ||||
|   guint       grab_frame_action : 1; | ||||
|   /* During a resize operation, the directions in which we've broken | ||||
|    * out of the initial maximization state */ | ||||
|   guint       grab_resize_unmaximize : 2; /* MetaMaximizeFlags */ | ||||
|   MetaRectangle grab_initial_window_pos; | ||||
|   int         grab_initial_x, grab_initial_y;  /* These are only relevant for */ | ||||
|   gboolean    grab_threshold_movement_reached; /* raise_on_click == FALSE.    */ | ||||
|   MetaResizePopup *grab_resize_popup; | ||||
|   GTimeVal    grab_last_moveresize_time; | ||||
|   guint32     grab_motion_notify_time; | ||||
|   GList*      grab_old_window_stacking; | ||||
|   unsigned int grab_last_user_action_was_snap; | ||||
|  | ||||
| #ifdef HAVE_XSYNC | ||||
|   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ | ||||
|   XSyncAlarm  grab_sync_request_alarm; | ||||
| #endif | ||||
|   int	      grab_resize_timeout_id; | ||||
| }; | ||||
|  | ||||
| struct _MetaFocusInfo | ||||
| { | ||||
|   /* This is the actual window from focus events, | ||||
|    * not the one we last set | ||||
|    */ | ||||
|   MetaWindow *focus_window; | ||||
|  | ||||
|   /* window we are expecting a FocusIn event for or the current focus | ||||
|    * window if we are not expecting any FocusIn/FocusOut events; not | ||||
|    * perfect because applications can call XSetInputFocus directly. | ||||
|    * (It could also be messed up if a timestamp later than current | ||||
|    * time is sent to meta_display_set_input_focus_window, though that | ||||
|    * would be a programming error).  See bug 154598 for more info. | ||||
|    */ | ||||
|   MetaWindow *expected_focus_window; | ||||
|  | ||||
|   /* last timestamp passed to XSetInputFocus */ | ||||
|   guint32 last_focus_time; | ||||
| }; | ||||
|  | ||||
| struct _MetaTouchInfo | ||||
| { | ||||
|   gdouble root_x; | ||||
|   gdouble root_y; | ||||
|  | ||||
|   gdouble initial_root_x; | ||||
|   gdouble initial_root_y; | ||||
|  | ||||
|   guint notified : 1; | ||||
|   guint use_for_hotspot : 1; | ||||
| }; | ||||
|  | ||||
| struct _MetaDisplay | ||||
| { | ||||
|   GObject parent_instance; | ||||
| @@ -104,22 +181,8 @@ struct _MetaDisplay | ||||
| #include <meta/atomnames.h> | ||||
| #undef item | ||||
|  | ||||
|   /* This is the actual window from focus events, | ||||
|    * not the one we last set | ||||
|    */ | ||||
|   MetaWindow *focus_window; | ||||
|  | ||||
|   /* window we are expecting a FocusIn event for or the current focus | ||||
|    * window if we are not expecting any FocusIn/FocusOut events; not | ||||
|    * perfect because applications can call XSetInputFocus directly. | ||||
|    * (It could also be messed up if a timestamp later than current | ||||
|    * time is sent to meta_display_set_input_focus_window, though that | ||||
|    * would be a programming error).  See bug 154598 for more info. | ||||
|    */ | ||||
|   MetaWindow *expected_focus_window; | ||||
|  | ||||
|   /* last timestamp passed to XSetInputFocus */ | ||||
|   guint32 last_focus_time; | ||||
|   /* keyboard -> MetaFocusInfo hashtable */ | ||||
|   GHashTable *focus_info; | ||||
|  | ||||
|   /* last user interaction time in any app */ | ||||
|   guint32 last_user_time; | ||||
| @@ -179,35 +242,11 @@ struct _MetaDisplay | ||||
|   /* Alt+click button grabs */ | ||||
|   unsigned int window_grab_modifiers; | ||||
|    | ||||
|   /* current window operation */ | ||||
|   MetaGrabOp  grab_op; | ||||
|   MetaScreen *grab_screen; | ||||
|   MetaWindow *grab_window; | ||||
|   Window      grab_xwindow; | ||||
|   int         grab_button; | ||||
|   int         grab_anchor_root_x; | ||||
|   int         grab_anchor_root_y; | ||||
|   MetaRectangle grab_anchor_window_pos; | ||||
|   MetaTileMode  grab_tile_mode; | ||||
|   int           grab_tile_monitor_number; | ||||
|   int         grab_latest_motion_x; | ||||
|   int         grab_latest_motion_y; | ||||
|   gulong      grab_mask; | ||||
|   guint       grab_have_pointer : 1; | ||||
|   guint       grab_have_keyboard : 1; | ||||
|   guint       grab_frame_action : 1; | ||||
|   /* During a resize operation, the directions in which we've broken | ||||
|    * out of the initial maximization state */ | ||||
|   guint       grab_resize_unmaximize : 2; /* MetaMaximizeFlags */ | ||||
|   MetaRectangle grab_initial_window_pos; | ||||
|   int         grab_initial_x, grab_initial_y;  /* These are only relevant for */ | ||||
|   gboolean    grab_threshold_movement_reached; /* raise_on_click == FALSE.    */ | ||||
|   MetaResizePopup *grab_resize_popup; | ||||
|   GTimeVal    grab_last_moveresize_time; | ||||
|   guint32     grab_motion_notify_time; | ||||
|   GList*      grab_old_window_stacking; | ||||
|   MetaEdgeResistanceData *grab_edge_resistance_data; | ||||
|   unsigned int grab_last_user_action_was_snap; | ||||
|   /* per-device current window operation */ | ||||
|   GHashTable *current_grabs; | ||||
|  | ||||
|   /* per-screen edge resistance cache */ | ||||
|   GHashTable *edge_resistance_info; | ||||
|  | ||||
|   /* we use property updates as sentinels for certain window focus events | ||||
|    * to avoid some race conditions on EnterNotify events | ||||
| @@ -218,11 +257,6 @@ struct _MetaDisplay | ||||
|   int         xkb_base_event_type; | ||||
|   guint32     last_bell_time; | ||||
| #endif | ||||
| #ifdef HAVE_XSYNC | ||||
|   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ | ||||
|   XSyncAlarm  grab_sync_request_alarm; | ||||
| #endif | ||||
|   int	      grab_resize_timeout_id; | ||||
|  | ||||
|   /* Keybindings stuff */ | ||||
|   MetaKeyBinding *key_bindings; | ||||
| @@ -269,6 +303,9 @@ struct _MetaDisplay | ||||
|   /* Managed by compositor.c */ | ||||
|   MetaCompositor *compositor; | ||||
|  | ||||
|   /* Managed by device-map.c */ | ||||
|   MetaDeviceMap *device_map; | ||||
|  | ||||
|   int render_event_base; | ||||
|   int render_error_base; | ||||
|  | ||||
| @@ -292,6 +329,15 @@ struct _MetaDisplay | ||||
|   int shape_event_base; | ||||
|   int shape_error_base; | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   int xinput2_opcode; | ||||
|   unsigned int have_xinput2 : 1; | ||||
| #ifdef HAVE_XTOUCH | ||||
|   unsigned int have_xtouch : 1; | ||||
| #endif /* HAVE_XTOUCH */ | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_XSYNC | ||||
|   unsigned int have_xsync : 1; | ||||
| #define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync) | ||||
| @@ -377,18 +423,24 @@ Cursor         meta_display_create_x_cursor (MetaDisplay *display, | ||||
|  | ||||
| void     meta_display_set_grab_op_cursor (MetaDisplay *display, | ||||
|                                           MetaScreen  *screen, | ||||
|                                           MetaDevice  *device, | ||||
|                                           MetaGrabOp   op, | ||||
|                                           gboolean     change_pointer, | ||||
|                                           Window       grab_xwindow, | ||||
|                                           guint32      timestamp); | ||||
|  | ||||
| void    meta_display_check_threshold_reached (MetaDisplay *display, | ||||
|                                               MetaDevice  *device, | ||||
|                                               int          x, | ||||
|                                               int          y); | ||||
| void     meta_display_grab_window_buttons    (MetaDisplay *display, | ||||
|                                               Window       xwindow); | ||||
| void     meta_display_ungrab_window_buttons  (MetaDisplay *display, | ||||
|                                               Window       xwindow); | ||||
| void     meta_display_grab_window_touches    (MetaDisplay *display, | ||||
|                                               MetaWindow  *window); | ||||
| void     meta_display_ungrab_window_touches  (MetaDisplay *display, | ||||
|                                               MetaWindow  *window); | ||||
|  | ||||
| void meta_display_grab_focus_window_button   (MetaDisplay *display, | ||||
|                                               MetaWindow  *window); | ||||
| @@ -396,7 +448,8 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display, | ||||
|                                               MetaWindow  *window); | ||||
|  | ||||
| /* Next function is defined in edge-resistance.c */ | ||||
| void meta_display_cleanup_edges              (MetaDisplay *display); | ||||
| void meta_display_cleanup_edges              (MetaDisplay *display, | ||||
|                                               MetaScreen  *screen); | ||||
|  | ||||
| /* make a request to ensure the event serial has changed */ | ||||
| void     meta_display_increment_event_serial (MetaDisplay *display); | ||||
| @@ -444,4 +497,15 @@ void meta_display_overlay_key_activate (MetaDisplay *display); | ||||
| /* In above-tab-keycode.c */ | ||||
| guint meta_display_get_above_tab_keycode (MetaDisplay *display); | ||||
|  | ||||
| MetaGrabInfo * meta_display_create_grab_info         (MetaDisplay  *display, | ||||
|                                                       MetaDevice   *device); | ||||
| void           meta_display_remove_grab_info         (MetaDisplay  *display, | ||||
|                                                       MetaDevice   *device); | ||||
|  | ||||
| MetaGrabInfo * meta_display_get_grab_info            (MetaDisplay  *display, | ||||
|                                                       MetaDevice   *device); | ||||
| MetaFocusInfo * meta_display_get_focus_info          (MetaDisplay  *display, | ||||
|                                                       MetaDevice   *device); | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										2988
									
								
								src/core/display.c
									
									
									
									
									
								
							
							
						
						
									
										2988
									
								
								src/core/display.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -30,12 +30,12 @@ | ||||
| /* A simple macro for whether a given window's edges are potentially | ||||
|  * relevant for resistance/snapping during a move/resize operation | ||||
|  */ | ||||
| #define WINDOW_EDGES_RELEVANT(window, display) \ | ||||
|   meta_window_should_be_showing (window) &&    \ | ||||
|   window->screen == display->grab_screen &&    \ | ||||
|   window         != display->grab_window &&    \ | ||||
|   window->type   != META_WINDOW_DESKTOP &&     \ | ||||
|   window->type   != META_WINDOW_MENU    &&     \ | ||||
| #define WINDOW_EDGES_RELEVANT(window, display, screen) \ | ||||
|   meta_window_should_be_showing (window) &&            \ | ||||
|   window->screen == screen &&                          \ | ||||
|   window->cur_grab == NULL &&                          \ | ||||
|   window->type   != META_WINDOW_DESKTOP &&             \ | ||||
|   window->type   != META_WINDOW_MENU    &&             \ | ||||
|   window->type   != META_WINDOW_SPLASHSCREEN | ||||
|  | ||||
| struct ResistanceDataForAnEdge | ||||
| @@ -44,8 +44,9 @@ struct ResistanceDataForAnEdge | ||||
|   guint        timeout_id; | ||||
|   int          timeout_edge_pos; | ||||
|   gboolean     timeout_over; | ||||
|   GSourceFunc  timeout_func; | ||||
|   MetaEdgeResistanceFunc timeout_func; | ||||
|   MetaWindow  *window; | ||||
|   MetaDevice  *device; | ||||
|   int          keyboard_buildup; | ||||
| }; | ||||
| typedef struct ResistanceDataForAnEdge ResistanceDataForAnEdge; | ||||
| @@ -63,7 +64,9 @@ struct MetaEdgeResistanceData | ||||
|   ResistanceDataForAnEdge bottom_data; | ||||
| }; | ||||
|  | ||||
| static void compute_resistance_and_snapping_edges (MetaDisplay *display); | ||||
| static MetaEdgeResistanceData * | ||||
|         compute_resistance_and_snapping_edges (MetaDisplay *display, | ||||
|                                                MetaScreen  *screen); | ||||
|  | ||||
| /* !WARNING!: this function can return invalid indices (namely, either -1 or | ||||
|  * edges->len); this is by design, but you need to remember this. | ||||
| @@ -318,20 +321,22 @@ edge_resistance_timeout (gpointer data) | ||||
|  | ||||
|   resistance_data->timeout_over = TRUE; | ||||
|   resistance_data->timeout_id = 0; | ||||
|   (*resistance_data->timeout_func)(resistance_data->window); | ||||
|   (*resistance_data->timeout_func) (resistance_data->window, | ||||
|                                     resistance_data->device); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static int | ||||
| apply_edge_resistance (MetaWindow                *window, | ||||
|                        MetaDevice                *device, | ||||
|                        int                        old_pos, | ||||
|                        int                        new_pos, | ||||
|                        const MetaRectangle       *old_rect, | ||||
|                        const MetaRectangle       *new_rect, | ||||
|                        GArray                    *edges, | ||||
|                        ResistanceDataForAnEdge   *resistance_data, | ||||
|                        GSourceFunc                timeout_func, | ||||
|                        MetaEdgeResistanceFunc     timeout_func, | ||||
|                        gboolean                   xdir, | ||||
|                        gboolean                   keyboard_op) | ||||
| { | ||||
| @@ -445,6 +450,7 @@ apply_edge_resistance (MetaWindow                *window, | ||||
|                   resistance_data->timeout_over = FALSE; | ||||
|                   resistance_data->timeout_func = timeout_func; | ||||
|                   resistance_data->window = window; | ||||
|                   resistance_data->device = device; | ||||
|                 } | ||||
|               if (!resistance_data->timeout_over && | ||||
|                   timeout_length_ms != 0) | ||||
| @@ -533,29 +539,28 @@ apply_edge_snapping (int                  old_pos, | ||||
|  * a proposed new position (ignoring edge resistance/snapping), and then | ||||
|  * applies edge resistance to EACH edge (separately) updating new_outer. | ||||
|  * It returns true if new_outer is modified, false otherwise. | ||||
|  * | ||||
|  * display->grab_edge_resistance_data MUST already be setup or calling this | ||||
|  * function will cause a crash. | ||||
|  */ | ||||
| static gboolean  | ||||
| apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|                                     MetaWindow          *window, | ||||
|                                     const MetaRectangle *old_outer, | ||||
|                                     MetaRectangle       *new_outer, | ||||
|                                     GSourceFunc          timeout_func, | ||||
|                                     gboolean             auto_snap, | ||||
|                                     gboolean             keyboard_op, | ||||
|                                     gboolean             is_resize) | ||||
| apply_edge_resistance_to_each_side (MetaDisplay            *display, | ||||
|                                     MetaWindow             *window, | ||||
|                                     MetaDevice             *device, | ||||
|                                     const MetaRectangle    *old_outer, | ||||
|                                     MetaRectangle          *new_outer, | ||||
|                                     MetaEdgeResistanceFunc  timeout_func, | ||||
|                                     gboolean                auto_snap, | ||||
|                                     gboolean                keyboard_op, | ||||
|                                     gboolean                is_resize) | ||||
| { | ||||
|   MetaEdgeResistanceData *edge_data; | ||||
|   MetaRectangle           modified_rect; | ||||
|   gboolean                modified; | ||||
|   int new_left, new_right, new_top, new_bottom; | ||||
|  | ||||
|   if (display->grab_edge_resistance_data == NULL) | ||||
|     compute_resistance_and_snapping_edges (display); | ||||
|   edge_data = g_hash_table_lookup (display->edge_resistance_info, | ||||
|                                    window->screen); | ||||
|  | ||||
|   edge_data = display->grab_edge_resistance_data; | ||||
|   if (!edge_data) | ||||
|     edge_data = compute_resistance_and_snapping_edges (display, window->screen); | ||||
|  | ||||
|   if (auto_snap) | ||||
|     { | ||||
| @@ -601,7 +606,7 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|       if (!is_resize || window->size_hints.width_inc == 1) | ||||
|         { | ||||
|           /* Now, apply the normal horizontal edge resistance */ | ||||
|           new_left   = apply_edge_resistance (window, | ||||
|           new_left   = apply_edge_resistance (window, device, | ||||
|                                               BOX_LEFT (*old_outer), | ||||
|                                               BOX_LEFT (*new_outer), | ||||
|                                               old_outer, | ||||
| @@ -611,7 +616,7 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|                                               timeout_func, | ||||
|                                               TRUE, | ||||
|                                               keyboard_op); | ||||
|           new_right  = apply_edge_resistance (window, | ||||
|           new_right  = apply_edge_resistance (window, device, | ||||
|                                               BOX_RIGHT (*old_outer), | ||||
|                                               BOX_RIGHT (*new_outer), | ||||
|                                               old_outer, | ||||
| @@ -630,7 +635,7 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|       /* Same for vertical resizes... */ | ||||
|       if (!is_resize || window->size_hints.height_inc == 1) | ||||
|         { | ||||
|           new_top    = apply_edge_resistance (window, | ||||
|           new_top    = apply_edge_resistance (window, device, | ||||
|                                               BOX_TOP (*old_outer), | ||||
|                                               BOX_TOP (*new_outer), | ||||
|                                               old_outer, | ||||
| @@ -640,7 +645,7 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|                                               timeout_func, | ||||
|                                               FALSE, | ||||
|                                               keyboard_op); | ||||
|           new_bottom = apply_edge_resistance (window, | ||||
|           new_bottom = apply_edge_resistance (window, device, | ||||
|                                               BOX_BOTTOM (*old_outer), | ||||
|                                               BOX_BOTTOM (*new_outer), | ||||
|                                               old_outer, | ||||
| @@ -669,15 +674,20 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_display_cleanup_edges (MetaDisplay *display) | ||||
| meta_display_cleanup_edges (MetaDisplay *display, | ||||
|                             MetaScreen  *screen) | ||||
| { | ||||
|   guint i,j; | ||||
|   MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data; | ||||
|   MetaEdgeResistanceData *edge_data; | ||||
|   GHashTable *edges_to_be_freed; | ||||
|  | ||||
|   edge_data = g_hash_table_lookup (display->edge_resistance_info, screen); | ||||
|  | ||||
|   if (edge_data == NULL) /* Not currently cached */ | ||||
|     return; | ||||
|  | ||||
|   g_hash_table_steal (display->edge_resistance_info, screen); | ||||
|  | ||||
|   /* We first need to clean out any window edges */ | ||||
|   edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal, | ||||
|                                              g_free, NULL); | ||||
| @@ -750,8 +760,7 @@ meta_display_cleanup_edges (MetaDisplay *display) | ||||
|       edge_data->bottom_data.timeout_id != 0) | ||||
|     g_source_remove (edge_data->bottom_data.timeout_id); | ||||
|  | ||||
|   g_free (display->grab_edge_resistance_data); | ||||
|   display->grab_edge_resistance_data = NULL; | ||||
|   g_free (edge_data); | ||||
| } | ||||
|  | ||||
| static int | ||||
| @@ -763,8 +772,9 @@ stupid_sort_requiring_extra_pointer_dereference (gconstpointer a, | ||||
|   return meta_rectangle_edge_cmp_ignore_type (*a_edge, *b_edge); | ||||
| } | ||||
|  | ||||
| static void | ||||
| static MetaEdgeResistanceData * | ||||
| cache_edges (MetaDisplay *display, | ||||
|              MetaScreen  *screen, | ||||
|              GList *window_edges, | ||||
|              GList *monitor_edges, | ||||
|              GList *screen_edges) | ||||
| @@ -848,9 +858,8 @@ cache_edges (MetaDisplay *display, | ||||
|   /* | ||||
|    * 2nd: Allocate the edges | ||||
|    */ | ||||
|   g_assert (display->grab_edge_resistance_data == NULL); | ||||
|   display->grab_edge_resistance_data = g_new0 (MetaEdgeResistanceData, 1); | ||||
|   edge_data = display->grab_edge_resistance_data; | ||||
|   edge_data = g_new0 (MetaEdgeResistanceData, 1); | ||||
|  | ||||
|   edge_data->left_edges   = g_array_sized_new (FALSE, | ||||
|                                                FALSE, | ||||
|                                                sizeof(MetaEdge*), | ||||
| @@ -917,21 +926,21 @@ cache_edges (MetaDisplay *display, | ||||
|    * avoided this sort by sticking them into the array with some simple | ||||
|    * merging of the lists). | ||||
|    */ | ||||
|   g_array_sort (display->grab_edge_resistance_data->left_edges,  | ||||
|   g_array_sort (edge_data->left_edges, | ||||
|                 stupid_sort_requiring_extra_pointer_dereference); | ||||
|   g_array_sort (display->grab_edge_resistance_data->right_edges,  | ||||
|   g_array_sort (edge_data->right_edges, | ||||
|                 stupid_sort_requiring_extra_pointer_dereference); | ||||
|   g_array_sort (display->grab_edge_resistance_data->top_edges,  | ||||
|   g_array_sort (edge_data->top_edges, | ||||
|                 stupid_sort_requiring_extra_pointer_dereference); | ||||
|   g_array_sort (display->grab_edge_resistance_data->bottom_edges,  | ||||
|   g_array_sort (edge_data->bottom_edges, | ||||
|                 stupid_sort_requiring_extra_pointer_dereference); | ||||
|  | ||||
|   return edge_data; | ||||
| } | ||||
|  | ||||
| static void | ||||
| initialize_grab_edge_resistance_data (MetaDisplay *display) | ||||
| initialize_grab_edge_resistance_data (MetaEdgeResistanceData *edge_data) | ||||
| { | ||||
|   MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data; | ||||
|  | ||||
|   edge_data->left_data.timeout_setup   = FALSE; | ||||
|   edge_data->right_data.timeout_setup  = FALSE; | ||||
|   edge_data->top_data.timeout_setup    = FALSE; | ||||
| @@ -943,8 +952,9 @@ initialize_grab_edge_resistance_data (MetaDisplay *display) | ||||
|   edge_data->bottom_data.keyboard_buildup = 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
| static MetaEdgeResistanceData * | ||||
| compute_resistance_and_snapping_edges (MetaDisplay *display, | ||||
|                                        MetaScreen  *screen) | ||||
| { | ||||
|   GList *stacked_windows; | ||||
|   GList *cur_window_iter; | ||||
| @@ -956,18 +966,17 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|    * in the layer that we are working on | ||||
|    */ | ||||
|   GSList *rem_windows, *rem_win_stacking; | ||||
|   MetaEdgeResistanceData *edge_data; | ||||
|  | ||||
|   g_assert (display->grab_window != NULL); | ||||
|   meta_topic (META_DEBUG_WINDOW_OPS, | ||||
|               "Computing edges to resist-movement or snap-to for %s.\n", | ||||
|               display->grab_window->desc); | ||||
|               "Computing edges to resist-movement or snap-to for screen %s.\n", | ||||
|               screen->screen_name); | ||||
|  | ||||
|   /* | ||||
|    * 1st: Get the list of relevant windows, from bottom to top | ||||
|    */ | ||||
|   stacked_windows =  | ||||
|     meta_stack_list_windows (display->grab_screen->stack, | ||||
|                              display->grab_screen->active_workspace); | ||||
|     meta_stack_list_windows (screen->stack, screen->active_workspace); | ||||
|  | ||||
|   /* | ||||
|    * 2nd: we need to separate that stacked list into a list of windows that | ||||
| @@ -981,7 +990,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|   while (cur_window_iter != NULL) | ||||
|     { | ||||
|       MetaWindow *cur_window = cur_window_iter->data; | ||||
|       if (WINDOW_EDGES_RELEVANT (cur_window, display)) | ||||
|       if (WINDOW_EDGES_RELEVANT (cur_window, display, screen)) | ||||
|         { | ||||
|           MetaRectangle *new_rect; | ||||
|           new_rect = g_new (MetaRectangle, 1); | ||||
| @@ -1016,7 +1025,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|        * resistance (note that dock edges are considered screen edges | ||||
|        * which are handled separately | ||||
|        */ | ||||
|       if (WINDOW_EDGES_RELEVANT (cur_window, display) && | ||||
|       if (WINDOW_EDGES_RELEVANT (cur_window, display, screen) && | ||||
|           cur_window->type != META_WINDOW_DOCK) | ||||
|         { | ||||
|           GList *new_edges; | ||||
| @@ -1028,7 +1037,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|            * by other windows or DOCKS, but that's handled below). | ||||
|            */ | ||||
|           meta_rectangle_intersect (&cur_rect,  | ||||
|                                     &display->grab_screen->rect, | ||||
|                                     &screen->rect, | ||||
|                                     &reduced); | ||||
|  | ||||
|           new_edges = NULL; | ||||
| @@ -1123,32 +1132,36 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) | ||||
|    * monitor edges in an array for quick access.  Free the edges since | ||||
|    * they've been cached elsewhere. | ||||
|    */ | ||||
|   cache_edges (display, | ||||
|                edges, | ||||
|                display->grab_screen->active_workspace->monitor_edges, | ||||
|                display->grab_screen->active_workspace->screen_edges); | ||||
|   edge_data = cache_edges (display, screen, | ||||
|                            edges, | ||||
|                            screen->active_workspace->monitor_edges, | ||||
|                            screen->active_workspace->screen_edges); | ||||
|   g_list_free (edges); | ||||
|  | ||||
|   /* | ||||
|    * 6th: Initialize the resistance timeouts and buildups | ||||
|    */ | ||||
|   initialize_grab_edge_resistance_data (display); | ||||
|   initialize_grab_edge_resistance_data (edge_data); | ||||
|  | ||||
|   return edge_data; | ||||
| } | ||||
|  | ||||
| /* Note that old_[xy] and new_[xy] are with respect to inner positions of | ||||
|  * the window. | ||||
|  */ | ||||
| void | ||||
| meta_window_edge_resistance_for_move (MetaWindow  *window, | ||||
|                                       int          old_x, | ||||
|                                       int          old_y, | ||||
|                                       int         *new_x, | ||||
|                                       int         *new_y, | ||||
|                                       GSourceFunc  timeout_func, | ||||
|                                       gboolean     snap, | ||||
|                                       gboolean     is_keyboard_op) | ||||
| meta_window_edge_resistance_for_move (MetaWindow             *window, | ||||
|                                       MetaDevice             *device, | ||||
|                                       int                     old_x, | ||||
|                                       int                     old_y, | ||||
|                                       int                    *new_x, | ||||
|                                       int                    *new_y, | ||||
|                                       MetaEdgeResistanceFunc  timeout_func, | ||||
|                                       gboolean                snap, | ||||
|                                       gboolean                is_keyboard_op) | ||||
| { | ||||
|   MetaRectangle old_outer, proposed_outer, new_outer; | ||||
|   MetaGrabInfo *grab_info; | ||||
|   gboolean is_resize; | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &old_outer); | ||||
| @@ -1158,10 +1171,14 @@ meta_window_edge_resistance_for_move (MetaWindow  *window, | ||||
|   proposed_outer.y += (*new_y - old_y); | ||||
|   new_outer = proposed_outer; | ||||
|  | ||||
|   window->display->grab_last_user_action_was_snap = snap; | ||||
|   grab_info = meta_display_get_grab_info (window->display, device); | ||||
|   g_assert (grab_info != NULL); | ||||
|  | ||||
|   grab_info->grab_last_user_action_was_snap = snap; | ||||
|   is_resize = FALSE; | ||||
|   if (apply_edge_resistance_to_each_side (window->display, | ||||
|                                           window, | ||||
|                                           device, | ||||
|                                           &old_outer, | ||||
|                                           &new_outer, | ||||
|                                           timeout_func, | ||||
| @@ -1223,18 +1240,20 @@ meta_window_edge_resistance_for_move (MetaWindow  *window, | ||||
|  * sizes of the inner window. | ||||
|  */ | ||||
| void | ||||
| meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|                                         int          old_width, | ||||
|                                         int          old_height, | ||||
|                                         int         *new_width, | ||||
|                                         int         *new_height, | ||||
|                                         int          gravity, | ||||
|                                         GSourceFunc  timeout_func, | ||||
|                                         gboolean     snap, | ||||
|                                         gboolean     is_keyboard_op) | ||||
| meta_window_edge_resistance_for_resize (MetaWindow             *window, | ||||
|                                         MetaDevice             *device, | ||||
|                                         int                     old_width, | ||||
|                                         int                     old_height, | ||||
|                                         int                    *new_width, | ||||
|                                         int                    *new_height, | ||||
|                                         int                     gravity, | ||||
|                                         MetaEdgeResistanceFunc  timeout_func, | ||||
|                                         gboolean                snap, | ||||
|                                         gboolean                is_keyboard_op) | ||||
| { | ||||
|   MetaRectangle old_outer, new_outer; | ||||
|   int proposed_outer_width, proposed_outer_height; | ||||
|   MetaGrabInfo *grab_info; | ||||
|   gboolean is_resize; | ||||
|  | ||||
|   meta_window_get_outer_rect (window, &old_outer); | ||||
| @@ -1246,10 +1265,14 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|                                       proposed_outer_width, | ||||
|                                       proposed_outer_height); | ||||
|  | ||||
|   window->display->grab_last_user_action_was_snap = snap; | ||||
|   grab_info = meta_display_get_grab_info (window->display, device); | ||||
|   g_assert (grab_info != NULL); | ||||
|  | ||||
|   grab_info->grab_last_user_action_was_snap = snap; | ||||
|   is_resize = TRUE; | ||||
|   if (apply_edge_resistance_to_each_side (window->display, | ||||
|                                           window, | ||||
|                                           device, | ||||
|                                           &old_outer, | ||||
|                                           &new_outer, | ||||
|                                           timeout_func, | ||||
|   | ||||
| @@ -26,23 +26,28 @@ | ||||
|  | ||||
| #include "window-private.h" | ||||
|  | ||||
| void        meta_window_edge_resistance_for_move   (MetaWindow  *window, | ||||
|                                                     int          old_x, | ||||
|                                                     int          old_y, | ||||
|                                                     int         *new_x, | ||||
|                                                     int         *new_y, | ||||
|                                                     GSourceFunc  timeout_func, | ||||
|                                                     gboolean     snap, | ||||
|                                                     gboolean     is_keyboard_op); | ||||
| void        meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|                                                     int          old_width, | ||||
|                                                     int          old_height, | ||||
|                                                     int         *new_width, | ||||
|                                                     int         *new_height, | ||||
|                                                     int          gravity, | ||||
|                                                     GSourceFunc  timeout_func, | ||||
|                                                     gboolean     snap, | ||||
|                                                     gboolean     is_keyboard_op); | ||||
| typedef gboolean (* MetaEdgeResistanceFunc) (MetaWindow *window, | ||||
|                                              MetaDevice *device); | ||||
|  | ||||
| void meta_window_edge_resistance_for_move   (MetaWindow             *window, | ||||
|                                              MetaDevice             *device, | ||||
|                                              int                     old_x, | ||||
|                                              int                     old_y, | ||||
|                                              int                    *new_x, | ||||
|                                              int                    *new_y, | ||||
|                                              MetaEdgeResistanceFunc  func, | ||||
|                                              gboolean                snap, | ||||
|                                              gboolean                is_keyboard_op); | ||||
| void meta_window_edge_resistance_for_resize (MetaWindow             *window, | ||||
|                                              MetaDevice             *device, | ||||
|                                              int                     old_width, | ||||
|                                              int                     old_height, | ||||
|                                              int                    *new_width, | ||||
|                                              int                    *new_height, | ||||
|                                              int                     gravity, | ||||
|                                              MetaEdgeResistanceFunc  func, | ||||
|                                              gboolean                snap, | ||||
|                                              gboolean                is_keyboard_op); | ||||
|  | ||||
| #endif /* META_EDGE_RESISTANCE_H */ | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,7 @@ | ||||
| #include "bell.h" | ||||
| #include <meta/errors.h> | ||||
| #include "keybindings-private.h" | ||||
| #include "device-pointer.h" | ||||
|  | ||||
| #include <X11/extensions/Xrender.h> | ||||
|  | ||||
| @@ -64,7 +65,7 @@ meta_window_ensure_frame (MetaWindow *window) | ||||
|   frame->child_y = 0; | ||||
|   frame->bottom_height = 0; | ||||
|   frame->right_width = 0; | ||||
|   frame->current_cursor = 0; | ||||
|   frame->cursors = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   frame->mapped = FALSE; | ||||
|   frame->is_flashing = FALSE; | ||||
| @@ -228,9 +229,10 @@ meta_window_destroy_frame (MetaWindow *window) | ||||
|  | ||||
|   /* Move keybindings to window instead of frame */ | ||||
|   meta_window_grab_keys (window); | ||||
|    | ||||
|  | ||||
|   g_hash_table_destroy (frame->cursors); | ||||
|   g_free (frame); | ||||
|    | ||||
|  | ||||
|   /* Put our state back where it should be */ | ||||
|   meta_window_queue (window, META_QUEUE_CALC_SHOWING); | ||||
|   meta_window_queue (window, META_QUEUE_MOVE_RESIZE); | ||||
| @@ -244,6 +246,12 @@ meta_frame_get_flags (MetaFrame *frame) | ||||
|  | ||||
|   flags = 0; | ||||
|  | ||||
|   /* Disallow frame operations | ||||
|    * while the popup menu is open. | ||||
|    */ | ||||
|   if (frame->window->menu) | ||||
|     return flags; | ||||
|  | ||||
|   if (frame->window->border_only) | ||||
|     { | ||||
|       ; /* FIXME this may disable the _function_ as well as decor | ||||
| @@ -377,8 +385,7 @@ meta_frame_sync_to_window (MetaFrame *frame, | ||||
|       /* If we're interactively resizing the frame, repaint | ||||
|        * it immediately so we don't start to lag. | ||||
|        */ | ||||
|       if (frame->window->display->grab_window == | ||||
|           frame->window) | ||||
|       if (frame->window->cur_grab != NULL) | ||||
|         meta_ui_repaint_frame (frame->window->screen->ui, | ||||
|                                frame->xwindow); | ||||
|     } | ||||
| @@ -403,22 +410,22 @@ meta_frame_queue_draw (MetaFrame *frame) | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_frame_set_screen_cursor (MetaFrame	*frame, | ||||
| 			      MetaCursor cursor) | ||||
| meta_frame_set_screen_cursor (MetaFrame	 *frame, | ||||
|                               MetaDevice *pointer, | ||||
| 			      MetaCursor  cursor) | ||||
| { | ||||
|   Cursor xcursor; | ||||
|   if (cursor == frame->current_cursor) | ||||
|   MetaCursor old_cursor; | ||||
|  | ||||
|   old_cursor = GPOINTER_TO_UINT (g_hash_table_lookup (frame->cursors, pointer)); | ||||
|  | ||||
|   if (cursor == old_cursor) | ||||
|     return; | ||||
|   frame->current_cursor = cursor; | ||||
|   if (cursor == META_CURSOR_DEFAULT) | ||||
|     XUndefineCursor (frame->window->display->xdisplay, frame->xwindow); | ||||
|   else | ||||
|     {  | ||||
|       xcursor = meta_display_create_x_cursor (frame->window->display, cursor); | ||||
|       XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor); | ||||
|       XFlush (frame->window->display->xdisplay); | ||||
|       XFreeCursor (frame->window->display->xdisplay, xcursor); | ||||
|     } | ||||
|  | ||||
|   g_hash_table_insert (frame->cursors, pointer, | ||||
|                        GUINT_TO_POINTER (cursor)); | ||||
|   meta_device_pointer_set_window_cursor (META_DEVICE_POINTER (pointer), | ||||
|                                          frame->xwindow, cursor); | ||||
|   XFlush (frame->window->display->xdisplay); | ||||
| } | ||||
|  | ||||
| Window | ||||
|   | ||||
| @@ -34,7 +34,7 @@ struct _MetaFrame | ||||
|   /* reparent window */ | ||||
|   Window xwindow; | ||||
|  | ||||
|   MetaCursor current_cursor; | ||||
|   GHashTable *cursors; | ||||
|  | ||||
|   /* This rect is trusted info from where we put the | ||||
|    * frame, not the result of ConfigureNotify | ||||
| @@ -76,7 +76,8 @@ gboolean meta_frame_sync_to_window (MetaFrame         *frame, | ||||
|  | ||||
| cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); | ||||
|  | ||||
| void meta_frame_set_screen_cursor (MetaFrame	*frame, | ||||
| void meta_frame_set_screen_cursor (MetaFrame   *frame, | ||||
|                                    MetaDevice  *pointer, | ||||
| 				   MetaCursor	cursor); | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										803
									
								
								src/core/input-events.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										803
									
								
								src/core/input-events.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,803 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* XEvent utility methods */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include "input-events.h" | ||||
| #include "devices-core.h" | ||||
| #include "device-map-private.h" | ||||
| #include <X11/Xlib.h> | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
| #include <X11/extensions/XInput2.h> | ||||
| #endif | ||||
|  | ||||
| /* Quite a hack: normalizes XI2 events to their | ||||
|  * core event equivalent, so most code is shared | ||||
|  * for both implementations, code handling input | ||||
|  * events should use the helper functions so | ||||
|  * the actual event is treated correctly. | ||||
|  */ | ||||
| gboolean | ||||
| meta_input_event_get_type (MetaDisplay *display, | ||||
|                            XEvent      *ev, | ||||
|                            guint       *ev_type) | ||||
| { | ||||
|   guint type = 0; /* Silence gcc */ | ||||
|   gboolean retval = TRUE; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (display->have_xinput2 && | ||||
|       ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       /* NB: GDK event filters already have generic events | ||||
|        * allocated, so no need to do XGetEventData() on our own | ||||
|        */ | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|           type = MotionNotify; | ||||
|           break; | ||||
|         case XI_ButtonPress: | ||||
|           type = ButtonPress; | ||||
|           break; | ||||
|         case XI_ButtonRelease: | ||||
|           type = ButtonRelease; | ||||
|           break; | ||||
|         case XI_KeyPress: | ||||
|           type = KeyPress; | ||||
|           break; | ||||
|         case XI_KeyRelease: | ||||
|           type = KeyRelease; | ||||
|           break; | ||||
|         case XI_FocusIn: | ||||
|           type = FocusIn; | ||||
|           break; | ||||
|         case XI_FocusOut: | ||||
|           type = FocusOut; | ||||
|           break; | ||||
|         case XI_Enter: | ||||
|           type = EnterNotify; | ||||
|           break; | ||||
|         case XI_Leave: | ||||
|           type = LeaveNotify; | ||||
|           break; | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|           type = ButtonPress; | ||||
|           break; | ||||
|         case XI_TouchEnd: | ||||
|           type = ButtonRelease; | ||||
|           break; | ||||
|         case XI_TouchUpdate: | ||||
|           if (((XIDeviceEvent *) xev)->flags & XITouchPendingEnd) | ||||
|             { | ||||
|               /* Consider these events like TouchEnd, as we | ||||
|                * could still need to call XIAllowTouchEvents() | ||||
|                * for this touch sequence so we get the real | ||||
|                * TouchEnd event, handling this event type the | ||||
|                * second time it arrives should be a NO-OP. | ||||
|                */ | ||||
|               type = ButtonRelease; | ||||
|             } | ||||
|           else | ||||
|             type = MotionNotify; | ||||
|           break; | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case MotionNotify: | ||||
|         case ButtonPress: | ||||
|         case ButtonRelease: | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|         case FocusIn: | ||||
|         case FocusOut: | ||||
|         case EnterNotify: | ||||
|         case LeaveNotify: | ||||
|           type = ev->type; | ||||
|           break; | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (retval) | ||||
|     { | ||||
|       if (ev_type) | ||||
|         *ev_type = type; | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_is_type (MetaDisplay *display, | ||||
|                           XEvent      *ev, | ||||
|                           guint        ev_type) | ||||
| { | ||||
|   guint type; | ||||
|  | ||||
|   if (!meta_input_event_get_type (display, ev, &type)) | ||||
|     return FALSE; | ||||
|  | ||||
|   return (type == ev_type); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_get_touch_id (MetaDisplay *display, | ||||
|                                XEvent      *ev, | ||||
|                                guint       *touch_id) | ||||
| { | ||||
| #if defined(HAVE_XINPUT2) && defined(HAVE_XTOUCH) | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
|           if (touch_id) | ||||
|             *touch_id = ((XIDeviceEvent *) xev)->detail; | ||||
|           return TRUE; | ||||
|         default: | ||||
|           return FALSE; | ||||
|         } | ||||
|     } | ||||
| #endif /* HAVE_XINPUT2 && HAVE_XTOUCH */ | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_input_event_get_window (MetaDisplay *display, | ||||
|                              XEvent      *ev) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       /* GDK event filters already have generic events allocated */ | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           return ((XIDeviceEvent *) xev)->event; | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           return ((XIEnterEvent *) xev)->event; | ||||
|         default: | ||||
|           return None; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     return ev->xany.window; | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_input_event_get_root_window (MetaDisplay *display, | ||||
|                                   XEvent      *ev) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           return ((XIDeviceEvent *) xev)->root; | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           return ((XIEnterEvent *) xev)->root; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|           return ev->xkey.root; | ||||
|         case ButtonPress: | ||||
|         case ButtonRelease: | ||||
|           return ev->xbutton.root; | ||||
|         case EnterNotify: | ||||
|         case LeaveNotify: | ||||
|           return ev->xcrossing.root; | ||||
|         case MotionNotify: | ||||
|           return ev->xbutton.root; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return None; | ||||
| } | ||||
|  | ||||
| Time | ||||
| meta_input_event_get_time (MetaDisplay *display, | ||||
|                            XEvent      *ev) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           return ((XIDeviceEvent *) xev)->time; | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           return ((XIEnterEvent *) xev)->time; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|           return ev->xkey.time; | ||||
|         case ButtonPress: | ||||
|         case ButtonRelease: | ||||
|           return ev->xbutton.time; | ||||
|         case EnterNotify: | ||||
|         case LeaveNotify: | ||||
|           return ev->xcrossing.time; | ||||
|         case MotionNotify: | ||||
|           return ev->xmotion.time; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return CurrentTime; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_get_coordinates (MetaDisplay *display, | ||||
|                                   XEvent      *ev, | ||||
|                                   gdouble     *x_ret, | ||||
|                                   gdouble     *y_ret, | ||||
|                                   gdouble     *x_root_ret, | ||||
|                                   gdouble     *y_root_ret) | ||||
| { | ||||
|   gdouble x, y, x_root, y_root; | ||||
|   gboolean retval = TRUE; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           { | ||||
|             XIDeviceEvent *event = (XIDeviceEvent *) xev; | ||||
|  | ||||
|             x = event->event_x; | ||||
|             y = event->event_y; | ||||
|             x_root = event->root_x; | ||||
|             y_root = event->root_y; | ||||
|           } | ||||
|  | ||||
|           break; | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           { | ||||
|             XIEnterEvent *event = (XIEnterEvent *) xev; | ||||
|  | ||||
|             x = event->event_x; | ||||
|             y = event->event_y; | ||||
|             x_root = event->root_x; | ||||
|             y_root = event->root_y; | ||||
|           } | ||||
|  | ||||
|           break; | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|           x = ev->xkey.x; | ||||
|           y = ev->xkey.y; | ||||
|           x_root = ev->xkey.x_root; | ||||
|           y_root = ev->xkey.y_root; | ||||
|           break; | ||||
|         case ButtonPress: | ||||
|         case ButtonRelease: | ||||
|           x = ev->xbutton.x; | ||||
|           y = ev->xbutton.y; | ||||
|           x_root = ev->xbutton.x_root; | ||||
|           y_root = ev->xbutton.y_root; | ||||
|           break; | ||||
|         case EnterNotify: | ||||
|         case LeaveNotify: | ||||
|           x = ev->xcrossing.x; | ||||
|           y = ev->xcrossing.y; | ||||
|           x_root = ev->xcrossing.x_root; | ||||
|           y_root = ev->xcrossing.y_root; | ||||
|           break; | ||||
|         case MotionNotify: | ||||
|           x = ev->xmotion.x; | ||||
|           y = ev->xmotion.y; | ||||
|           x_root = ev->xmotion.x_root; | ||||
|           y_root = ev->xmotion.y_root; | ||||
|           break; | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (retval) | ||||
|     { | ||||
|       if (x_ret) | ||||
|         *x_ret = x; | ||||
|  | ||||
|       if (y_ret) | ||||
|         *y_ret = y; | ||||
|  | ||||
|       if (x_root_ret) | ||||
|         *x_root_ret = x_root; | ||||
|  | ||||
|       if (y_root_ret) | ||||
|         *y_root_ret = y_root; | ||||
|     } | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_get_state (MetaDisplay *display, | ||||
|                             XEvent      *ev, | ||||
|                             guint       *state) | ||||
| { | ||||
|   gboolean retval = TRUE; | ||||
|   guint s; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           s = ((XIDeviceEvent *) xev)->mods.effective; | ||||
|           break; | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           s = ((XIDeviceEvent *) xev)->mods.effective; | ||||
|           break; | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|           s = ev->xkey.state; | ||||
|           break; | ||||
|         case ButtonPress: | ||||
|         case ButtonRelease: | ||||
|           s = ev->xbutton.state; | ||||
|           break; | ||||
|         case EnterNotify: | ||||
|         case LeaveNotify: | ||||
|           s = ev->xcrossing.state; | ||||
|           break; | ||||
|         case MotionNotify: | ||||
|           s = ev->xmotion.state; | ||||
|           break; | ||||
|         default: | ||||
|           retval = FALSE; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (retval && state) | ||||
|     *state = s; | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_get_keycode (MetaDisplay *display, | ||||
|                               XEvent      *ev, | ||||
|                               guint       *keycode) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       if (xev->evtype == XI_KeyPress || | ||||
|           xev->evtype == XI_KeyRelease) | ||||
|         { | ||||
|           if (keycode) | ||||
|             { | ||||
|               /* The detail field contains keycode for key events */ | ||||
|               *keycode = ((XIDeviceEvent *) xev)->detail; | ||||
|             } | ||||
|  | ||||
|           return TRUE; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       if (ev->type == KeyPress || | ||||
|           ev->type == KeyRelease) | ||||
|         { | ||||
|           if (keycode) | ||||
|             *keycode = ev->xkey.keycode; | ||||
|  | ||||
|           return TRUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_input_event_get_button (MetaDisplay *display, | ||||
|                              XEvent      *ev, | ||||
|                              guint       *button) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       if (xev->evtype == XI_ButtonPress || | ||||
|           xev->evtype == XI_ButtonRelease) | ||||
|         { | ||||
|           if (button) | ||||
|             { | ||||
|               /* The detail field contains | ||||
|                * button number for button events | ||||
|                */ | ||||
|               *button = ((XIDeviceEvent *) xev)->detail; | ||||
|             } | ||||
|  | ||||
|           return TRUE; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       if (ev->type == ButtonPress || | ||||
|           ev->type == ButtonRelease) | ||||
|         { | ||||
|           if (button) | ||||
|             *button = ev->xbutton.button; | ||||
|  | ||||
|           return TRUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /* NB: Also works for focus in/out events */ | ||||
| gboolean | ||||
| meta_input_event_get_crossing_details (MetaDisplay *display, | ||||
|                                        XEvent      *ev, | ||||
|                                        guint       *mode_out, | ||||
|                                        guint       *detail_out) | ||||
| { | ||||
|   gboolean retval = TRUE; | ||||
|   guint mode, detail; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       if (xev->evtype == XI_Enter || | ||||
|           xev->evtype == XI_Leave || | ||||
|           xev->evtype == XI_FocusIn || | ||||
|           xev->evtype == XI_FocusOut) | ||||
|         { | ||||
|           mode = ((XIEnterEvent *) xev)->mode; | ||||
|           detail = ((XIEnterEvent *) xev)->detail; | ||||
|         } | ||||
|       else | ||||
|         retval = FALSE; | ||||
|     } | ||||
|   else | ||||
| #endif /* HAVE_XINPUT2 */ | ||||
|     { | ||||
|       if (ev->type == EnterNotify || | ||||
|           ev->type == LeaveNotify) | ||||
|         { | ||||
|           mode = ev->xcrossing.mode; | ||||
|           detail = ev->xcrossing.detail; | ||||
|         } | ||||
|       else if (ev->type == FocusIn || | ||||
|                ev->type == FocusOut) | ||||
|         { | ||||
|           mode = ev->xfocus.mode; | ||||
|           detail = ev->xfocus.detail; | ||||
|         } | ||||
|       else | ||||
|         retval = FALSE; | ||||
|     } | ||||
|  | ||||
|   if (retval) | ||||
|     { | ||||
|       if (mode_out) | ||||
|         *mode_out = mode; | ||||
|  | ||||
|       if (detail_out) | ||||
|         *detail_out = detail; | ||||
|     } | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_input_event_get_device (MetaDisplay *display, | ||||
|                              XEvent      *ev) | ||||
| { | ||||
|   guint evtype; | ||||
|  | ||||
|   if (!meta_input_event_get_type (display, ev, &evtype)) | ||||
|     return NULL; | ||||
|  | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          ((XIDeviceEvent *) xev)->deviceid); | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          ((XIEnterEvent *) xev)->deviceid); | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   else | ||||
| #endif | ||||
|     { | ||||
|       switch (ev->type) | ||||
|         { | ||||
|         case KeyPress: | ||||
|         case KeyRelease: | ||||
|         case FocusIn: | ||||
|         case FocusOut: | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          META_CORE_KEYBOARD_ID); | ||||
|         default: | ||||
|           /* All other events are pointers' */ | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          META_CORE_POINTER_ID); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| MetaDevice * | ||||
| meta_input_event_get_source_device (MetaDisplay *display, | ||||
|                                     XEvent      *ev) | ||||
| { | ||||
| #ifdef HAVE_XINPUT2 | ||||
|   if (ev->type == GenericEvent && | ||||
|       ev->xcookie.extension == display->xinput2_opcode) | ||||
|     { | ||||
|       XIEvent *xev; | ||||
|  | ||||
|       g_assert (display->have_xinput2 == TRUE); | ||||
|  | ||||
|       xev = (XIEvent *) ev->xcookie.data; | ||||
|  | ||||
|       switch (xev->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
| #ifdef HAVE_XTOUCH | ||||
|         case XI_TouchBegin: | ||||
|         case XI_TouchEnd: | ||||
|         case XI_TouchUpdate: | ||||
| #endif /* HAVE_XTOUCH */ | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          ((XIDeviceEvent *) xev)->sourceid); | ||||
|         case XI_FocusIn: | ||||
|         case XI_FocusOut: | ||||
|         case XI_Enter: | ||||
|         case XI_Leave: | ||||
|           return meta_device_map_lookup (display->device_map, | ||||
|                                          ((XIEnterEvent *) xev)->sourceid); | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
							
								
								
									
										88
									
								
								src/core/input-events.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/core/input-events.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /** | ||||
|  * \file event.h  Utility functions for handling events | ||||
|  * | ||||
|  * Handling events. | ||||
|  * This file contains helper methods to handle events, specially | ||||
|  * input events, which can be either core or XInput2. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_EVENT_H | ||||
| #define META_EVENT_H | ||||
|  | ||||
| #include <config.h> | ||||
| #include <X11/Xlib.h> | ||||
| #include "display-private.h" | ||||
| #include <meta/device-map.h> | ||||
|  | ||||
| /* Add an extra flag for touch events in | ||||
|  * evmasks, an arbitrarily high bit is taken. | ||||
|  */ | ||||
| #define META_INPUT_TOUCH_EVENTS_MASK (1L<<31) | ||||
|  | ||||
| gboolean meta_input_event_get_type          (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              guint       *ev_type); | ||||
| gboolean meta_input_event_is_type           (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              guint        ev_type); | ||||
|  | ||||
| gboolean meta_input_event_get_touch_id      (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              guint       *touch_id); | ||||
|  | ||||
| Window   meta_input_event_get_window        (MetaDisplay *display, | ||||
|                                              XEvent      *ev); | ||||
| Window   meta_input_event_get_root_window   (MetaDisplay *display, | ||||
|                                              XEvent      *ev); | ||||
|  | ||||
| Time     meta_input_event_get_time          (MetaDisplay *display, | ||||
|                                              XEvent      *ev); | ||||
|  | ||||
| gboolean meta_input_event_get_coordinates   (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              gdouble     *x_ret, | ||||
|                                              gdouble     *y_ret, | ||||
|                                              gdouble     *x_root_ret, | ||||
|                                              gdouble     *y_root_ret); | ||||
|  | ||||
| gboolean meta_input_event_get_state         (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              guint       *state); | ||||
| gboolean meta_input_event_get_keycode       (MetaDisplay *display, | ||||
|                                              XEvent      *ev, | ||||
|                                              guint       *keycode); | ||||
| gboolean meta_input_event_get_button        (MetaDisplay *display, | ||||
|                                              XEvent      *event, | ||||
|                                              guint       *button); | ||||
| gboolean meta_input_event_get_crossing_details (MetaDisplay *display, | ||||
|                                                 XEvent      *ev, | ||||
|                                                 guint       *mode_out, | ||||
|                                                 guint       *detail_out); | ||||
|  | ||||
| MetaDevice *meta_input_event_get_device        (MetaDisplay *display, | ||||
|                                                 XEvent      *ev); | ||||
| MetaDevice *meta_input_event_get_source_device (MetaDisplay *display, | ||||
|                                                 XEvent      *ev); | ||||
|  | ||||
| #endif /* META_EVENT_H */ | ||||
| @@ -36,14 +36,18 @@ void     meta_display_shutdown_keys         (MetaDisplay *display); | ||||
| void     meta_screen_grab_keys              (MetaScreen  *screen); | ||||
| void     meta_screen_ungrab_keys            (MetaScreen  *screen); | ||||
| gboolean meta_screen_grab_all_keys          (MetaScreen  *screen, | ||||
|                                              MetaDevice  *device, | ||||
|                                              guint32      timestamp); | ||||
| void     meta_screen_ungrab_all_keys        (MetaScreen  *screen,  | ||||
| void     meta_screen_ungrab_all_keys        (MetaScreen  *screen, | ||||
|                                              MetaDevice  *device, | ||||
|                                              guint32      timestamp); | ||||
| void     meta_window_grab_keys              (MetaWindow  *window); | ||||
| void     meta_window_ungrab_keys            (MetaWindow  *window); | ||||
| gboolean meta_window_grab_all_keys          (MetaWindow  *window, | ||||
|                                              MetaDevice  *device, | ||||
|                                              guint32      timestamp); | ||||
| void     meta_window_ungrab_all_keys        (MetaWindow  *window, | ||||
|                                              MetaDevice  *device, | ||||
|                                              guint32      timestamp); | ||||
| gboolean meta_display_process_key_event     (MetaDisplay *display, | ||||
|                                              MetaWindow  *window, | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -311,9 +311,12 @@ static GSourceFuncs event_funcs = { | ||||
| static void | ||||
| meta_clutter_init (void) | ||||
| { | ||||
|   if (!meta_get_use_core_devices ()) | ||||
|     clutter_x11_enable_xinput (); | ||||
|  | ||||
|   clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); | ||||
|   clutter_x11_disable_event_retrieval (); | ||||
|    | ||||
|  | ||||
|   if (CLUTTER_INIT_SUCCESS == clutter_init (NULL, NULL)) | ||||
|     { | ||||
|       GSource *source = g_source_new (&event_funcs, sizeof (GSource)); | ||||
| @@ -424,6 +427,8 @@ meta_init (void) | ||||
|     meta_set_verbose (TRUE); | ||||
|   if (g_getenv ("MUTTER_DEBUG")) | ||||
|     meta_set_debugging (TRUE); | ||||
|   if (g_getenv ("MUTTER_USE_CORE_DEVICES")) | ||||
|     meta_set_use_core_devices (TRUE); | ||||
|  | ||||
|   if (g_get_home_dir ()) | ||||
|     if (chdir (g_get_home_dir ()) < 0) | ||||
|   | ||||
| @@ -90,6 +90,7 @@ northwestcmp (gconstpointer a, gconstpointer b) | ||||
|  | ||||
| static void | ||||
| find_next_cascade (MetaWindow *window, | ||||
|                    MetaDevice *pointer, | ||||
|                    MetaFrameBorders *borders, | ||||
|                    /* visible windows on relevant workspaces */ | ||||
|                    GList      *windows, | ||||
| @@ -136,7 +137,7 @@ find_next_cascade (MetaWindow *window, | ||||
|    * of NW corner of window frame. | ||||
|    */ | ||||
|  | ||||
|   current = meta_screen_get_current_monitor (window->screen); | ||||
|   current = meta_screen_get_current_monitor (window->screen, pointer); | ||||
|   meta_window_get_work_area_for_monitor (window, current->number, &work_area); | ||||
|  | ||||
|   cascade_x = MAX (0, work_area.x); | ||||
| @@ -354,10 +355,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, | ||||
|    * know about the modal-to-the-main-window part. | ||||
|    */ | ||||
|  | ||||
|   MetaWindow *focus_window; | ||||
|   MetaWindow *focus_window = NULL; | ||||
|   MetaFocusInfo *focus_info; | ||||
|   MetaRectangle overlap; | ||||
|   MetaDevice *pointer, *keyboard; | ||||
|  | ||||
|   focus_window = window->display->focus_window; | ||||
|   pointer = meta_window_guess_grab_pointer (window); | ||||
|   keyboard = meta_device_get_paired_device (pointer); | ||||
|   focus_info = meta_display_get_focus_info (window->display, keyboard); | ||||
|  | ||||
|   if (focus_window) | ||||
|     focus_window = focus_info->focus_window; | ||||
|  | ||||
|   if (window->denied_focus_and_not_transient && | ||||
|       window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ | ||||
| @@ -660,6 +668,7 @@ meta_window_place (MetaWindow        *window, | ||||
| { | ||||
|   GList *windows; | ||||
|   const MetaMonitorInfo *xi; | ||||
|   MetaDevice *pointer, *keyboard; | ||||
|  | ||||
|   /* frame member variables should NEVER be used in here, only | ||||
|    * MetaFrameBorders. But remember borders == NULL | ||||
| @@ -671,7 +680,9 @@ meta_window_place (MetaWindow        *window, | ||||
|   meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); | ||||
|  | ||||
|   windows = NULL; | ||||
|    | ||||
|   pointer = meta_window_guess_grab_pointer (window); | ||||
|   keyboard = meta_device_get_paired_device (pointer); | ||||
|  | ||||
|   switch (window->type) | ||||
|     { | ||||
|       /* Run placement algorithm on these. */ | ||||
| @@ -815,7 +826,7 @@ meta_window_place (MetaWindow        *window, | ||||
|       int w, h; | ||||
|  | ||||
|       /* Warning, this function is a round trip! */ | ||||
|       xi = meta_screen_get_current_monitor (window->screen); | ||||
|       xi = meta_screen_get_current_monitor (window->screen, pointer); | ||||
|  | ||||
|       w = xi->rect.width; | ||||
|       h = xi->rect.height; | ||||
| @@ -860,8 +871,8 @@ meta_window_place (MetaWindow        *window, | ||||
|   } | ||||
|  | ||||
|   /* Warning, this is a round trip! */ | ||||
|   xi = meta_screen_get_current_monitor (window->screen); | ||||
|    | ||||
|   xi = meta_screen_get_current_monitor (window->screen, pointer); | ||||
|  | ||||
|   /* "Origin" placement algorithm */ | ||||
|   x = xi->rect.x; | ||||
|   y = xi->rect.y; | ||||
| @@ -899,8 +910,8 @@ meta_window_place (MetaWindow        *window, | ||||
|   /* If no placement has been done, revert to cascade to avoid  | ||||
|    * fully overlapping window (e.g. starting multiple terminals) | ||||
|    * */ | ||||
|   if (x == xi->rect.x && y == xi->rect.y)   | ||||
|     find_next_cascade (window, borders, windows, x, y, &x, &y); | ||||
|   if (x == xi->rect.x && y == xi->rect.y) | ||||
|     find_next_cascade (window, pointer, borders, windows, x, y, &x, &y); | ||||
|  | ||||
|  done_check_denied_focus: | ||||
|   /* If the window is being denied focus and isn't a transient of the | ||||
| @@ -913,8 +924,12 @@ meta_window_place (MetaWindow        *window, | ||||
|       gboolean       found_fit; | ||||
|       MetaWindow    *focus_window; | ||||
|       MetaRectangle  overlap; | ||||
|       MetaFocusInfo *focus_info; | ||||
|  | ||||
|       focus_window = window->display->focus_window; | ||||
|       focus_info = meta_display_get_focus_info (window->display, keyboard); | ||||
|       g_assert (focus_info != NULL); | ||||
|  | ||||
|       focus_window = focus_info->focus_window; | ||||
|       g_assert (focus_window != NULL); | ||||
|  | ||||
|       /* No need to do anything if the window doesn't overlap at all */ | ||||
|   | ||||
| @@ -92,7 +92,8 @@ struct _MetaScreen | ||||
|   MetaStack *stack; | ||||
|   MetaStackTracker *stack_tracker; | ||||
|  | ||||
|   MetaCursor current_cursor; | ||||
|   /* per-pointer cursors */ | ||||
|   GHashTable *cursors; | ||||
|  | ||||
|   Window flash_window; | ||||
|  | ||||
| @@ -160,8 +161,10 @@ void          meta_screen_queue_frame_redraws (MetaScreen                 *scree | ||||
| void          meta_screen_queue_window_resizes (MetaScreen                 *screen); | ||||
|  | ||||
| void          meta_screen_set_cursor          (MetaScreen                 *screen, | ||||
|                                                MetaDevice                 *pointer, | ||||
|                                                MetaCursor                  cursor); | ||||
| void          meta_screen_update_cursor       (MetaScreen                 *screen); | ||||
| void          meta_screen_update_cursor       (MetaScreen                 *screen, | ||||
|                                                MetaDevice                 *pointer); | ||||
|  | ||||
| void          meta_screen_tab_popup_create       (MetaScreen              *screen, | ||||
|                                                   MetaTabList              list_type, | ||||
| @@ -184,9 +187,11 @@ void          meta_screen_tile_preview_update          (MetaScreen    *screen, | ||||
| void          meta_screen_tile_preview_hide            (MetaScreen    *screen); | ||||
|  | ||||
| MetaWindow*   meta_screen_get_mouse_window     (MetaScreen                 *screen, | ||||
|                                                 MetaDevice                 *pointer, | ||||
|                                                 MetaWindow                 *not_this_one); | ||||
|  | ||||
| const MetaMonitorInfo* meta_screen_get_current_monitor    (MetaScreen    *screen); | ||||
| const MetaMonitorInfo* meta_screen_get_current_monitor    (MetaScreen    *screen, | ||||
|                                                            MetaDevice    *pointer); | ||||
| const MetaMonitorInfo* meta_screen_get_monitor_for_rect   (MetaScreen    *screen, | ||||
|                                                            MetaRectangle *rect); | ||||
| const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen    *screen, | ||||
|   | ||||
| @@ -37,10 +37,12 @@ | ||||
| #include "workspace-private.h" | ||||
| #include "keybindings-private.h" | ||||
| #include "stack.h" | ||||
| #include "core.h" | ||||
| #include "xprops.h" | ||||
| #include <meta/compositor.h> | ||||
| #include "mutter-marshal.h" | ||||
| #include "mutter-enum-types.h" | ||||
| #include "device-pointer.h" | ||||
|  | ||||
| #ifdef HAVE_SOLARIS_XINERAMA | ||||
| #include <X11/extensions/xinerama.h> | ||||
| @@ -710,7 +712,6 @@ meta_screen_new (MetaDisplay *display, | ||||
|   MetaScreen *screen; | ||||
|   Window xroot; | ||||
|   Display *xdisplay; | ||||
|   XWindowAttributes attr; | ||||
|   Window new_wm_sn_owner; | ||||
|   Window current_wm_sn_owner; | ||||
|   gboolean replace_current_wm; | ||||
| @@ -825,15 +826,15 @@ meta_screen_new (MetaDisplay *display, | ||||
|   /* We need to or with the existing event mask since | ||||
|    * gtk+ may be interested in other events. | ||||
|    */ | ||||
|   XGetWindowAttributes (xdisplay, xroot, &attr); | ||||
|   XSelectInput (xdisplay, | ||||
|                 xroot, | ||||
|                 SubstructureRedirectMask | SubstructureNotifyMask | | ||||
|                 ColormapChangeMask | PropertyChangeMask | | ||||
|                 LeaveWindowMask | EnterWindowMask | | ||||
|                 KeyPressMask | KeyReleaseMask | | ||||
|                 FocusChangeMask | StructureNotifyMask | | ||||
|                 ExposureMask | attr.your_event_mask); | ||||
|   meta_core_select_events (xdisplay, xroot, | ||||
|                            (SubstructureRedirectMask | SubstructureNotifyMask | | ||||
|                             ColormapChangeMask | PropertyChangeMask | | ||||
|                             LeaveWindowMask | EnterWindowMask | | ||||
|                             KeyPressMask | KeyReleaseMask | | ||||
|                             FocusChangeMask | StructureNotifyMask | | ||||
|                             ExposureMask), | ||||
|                            TRUE); | ||||
|  | ||||
|   if (meta_error_trap_pop_with_return (display) != Success) | ||||
|     { | ||||
|       meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"), | ||||
| @@ -855,10 +856,10 @@ meta_screen_new (MetaDisplay *display, | ||||
|   screen->rect.x = screen->rect.y = 0; | ||||
|   screen->rect.width = WidthOfScreen (screen->xscreen); | ||||
|   screen->rect.height = HeightOfScreen (screen->xscreen); | ||||
|   screen->current_cursor = -1; /* invalid/unset */ | ||||
|   screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); | ||||
|   screen->default_depth = DefaultDepthOfScreen (screen->xscreen); | ||||
|   screen->flash_window = None; | ||||
|   screen->cursors = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   screen->wm_sn_selection_window = new_wm_sn_owner; | ||||
|   screen->wm_sn_atom = wm_sn_atom; | ||||
| @@ -883,8 +884,6 @@ meta_screen_new (MetaDisplay *display, | ||||
|   screen->last_monitor_index = 0;   | ||||
|    | ||||
|   reload_monitor_infos (screen); | ||||
|    | ||||
|   meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); | ||||
|  | ||||
|   /* Handle creating a no_focus_window for this screen */   | ||||
|   screen->no_focus_window = | ||||
| @@ -1019,7 +1018,10 @@ meta_screen_free (MetaScreen *screen, | ||||
|   meta_stack_tracker_free (screen->stack_tracker); | ||||
|  | ||||
|   meta_error_trap_push_with_return (screen->display); | ||||
|   XSelectInput (screen->display->xdisplay, screen->xroot, 0); | ||||
|   meta_core_select_events (screen->display->xdisplay, | ||||
|                            screen->xroot, NoEventMask, | ||||
|                            FALSE); | ||||
|  | ||||
|   if (meta_error_trap_pop_with_return (screen->display) != Success) | ||||
|     meta_warning (_("Could not release screen %d on display \"%s\"\n"), | ||||
|                   screen->number, screen->display->name); | ||||
| @@ -1043,6 +1045,8 @@ meta_screen_free (MetaScreen *screen, | ||||
|    | ||||
|   g_free (screen->screen_name); | ||||
|  | ||||
|   g_hash_table_destroy (screen->cursors); | ||||
|  | ||||
|   g_object_unref (screen); | ||||
|  | ||||
|   XFlush (display->xdisplay); | ||||
| @@ -1656,31 +1660,33 @@ update_focus_mode (MetaScreen *screen) | ||||
|  | ||||
| void | ||||
| meta_screen_set_cursor (MetaScreen *screen, | ||||
|                         MetaDevice *pointer, | ||||
|                         MetaCursor  cursor) | ||||
| { | ||||
|   Cursor xcursor; | ||||
|   MetaCursor old_cursor; | ||||
|  | ||||
|   if (cursor == screen->current_cursor) | ||||
|   old_cursor = GPOINTER_TO_UINT (g_hash_table_lookup (screen->cursors, pointer)); | ||||
|  | ||||
|   if (cursor == old_cursor) | ||||
|     return; | ||||
|  | ||||
|   screen->current_cursor = cursor; | ||||
|    | ||||
|   xcursor = meta_display_create_x_cursor (screen->display, cursor); | ||||
|   XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); | ||||
|   XFlush (screen->display->xdisplay); | ||||
|   XFreeCursor (screen->display->xdisplay, xcursor); | ||||
|   g_hash_table_insert (screen->cursors, pointer, | ||||
|                        GUINT_TO_POINTER (cursor)); | ||||
|  | ||||
|   meta_screen_update_cursor (screen, pointer); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_screen_update_cursor (MetaScreen *screen) | ||||
| meta_screen_update_cursor (MetaScreen *screen, | ||||
|                            MetaDevice *pointer) | ||||
| { | ||||
|   Cursor xcursor; | ||||
|   MetaCursor cursor; | ||||
|  | ||||
|   xcursor = meta_display_create_x_cursor (screen->display,  | ||||
| 					  screen->current_cursor); | ||||
|   XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); | ||||
|   cursor = GPOINTER_TO_UINT (g_hash_table_lookup (screen->cursors, pointer)); | ||||
|   meta_device_pointer_set_window_cursor (META_DEVICE_POINTER (pointer), | ||||
|                                          screen->xroot, | ||||
|                                          cursor); | ||||
|   XFlush (screen->display->xdisplay); | ||||
|   XFreeCursor (screen->display->xdisplay, xcursor); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1934,9 +1940,21 @@ static gboolean | ||||
| meta_screen_tile_preview_update_timeout (gpointer data) | ||||
| { | ||||
|   MetaScreen *screen = data; | ||||
|   MetaWindow *window = screen->display->grab_window; | ||||
|   MetaWindow *window = NULL; | ||||
|   gboolean composited = screen->display->compositor != NULL; | ||||
|   gboolean needs_preview = FALSE; | ||||
|   MetaGrabInfo *grab_info; | ||||
|   MetaDevice *pointer = NULL; | ||||
|   GHashTableIter iter; | ||||
|  | ||||
|   /* FIXME: we're just handling the first grab we find */ | ||||
|   g_hash_table_iter_init (&iter, screen->display->current_grabs); | ||||
|  | ||||
|   if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info)) | ||||
|     { | ||||
|       window = grab_info->grab_window; | ||||
|       pointer = grab_info->grab_pointer; | ||||
|     } | ||||
|  | ||||
|   screen->tile_preview_timeout_id = 0; | ||||
|  | ||||
| @@ -1980,7 +1998,7 @@ meta_screen_tile_preview_update_timeout (gpointer data) | ||||
|       MetaRectangle tile_rect; | ||||
|  | ||||
|       meta_window_get_current_tile_area (window, &tile_rect); | ||||
|       meta_tile_preview_show (screen->tile_preview, &tile_rect); | ||||
|       meta_tile_preview_show (screen->tile_preview, pointer, &tile_rect); | ||||
|     } | ||||
|   else | ||||
|     meta_tile_preview_hide (screen->tile_preview); | ||||
| @@ -2025,28 +2043,23 @@ meta_screen_tile_preview_hide (MetaScreen *screen) | ||||
|  | ||||
| MetaWindow* | ||||
| meta_screen_get_mouse_window (MetaScreen  *screen, | ||||
|                               MetaDevice  *pointer, | ||||
|                               MetaWindow  *not_this_one) | ||||
| { | ||||
|   MetaWindow *window; | ||||
|   Window root_return, child_return; | ||||
|   int root_x_return, root_y_return; | ||||
|   int win_x_return, win_y_return; | ||||
|   unsigned int mask_return; | ||||
|    | ||||
|  | ||||
|   if (not_this_one) | ||||
|     meta_topic (META_DEBUG_FOCUS, | ||||
|                 "Focusing mouse window excluding %s\n", not_this_one->desc); | ||||
|  | ||||
|   meta_error_trap_push (screen->display); | ||||
|   XQueryPointer (screen->display->xdisplay, | ||||
|                  screen->xroot, | ||||
|                  &root_return, | ||||
|                  &child_return, | ||||
|                  &root_x_return, | ||||
|                  &root_y_return, | ||||
|                  &win_x_return, | ||||
|                  &win_y_return, | ||||
|                  &mask_return); | ||||
|   meta_device_pointer_query_position (META_DEVICE_POINTER (pointer), | ||||
|                                       screen->xroot, | ||||
|                                       NULL, NULL, | ||||
|                                       &root_x_return, | ||||
|                                       &root_y_return, | ||||
|                                       NULL, NULL, NULL); | ||||
|   meta_error_trap_pop (screen->display); | ||||
|  | ||||
|   window = meta_stack_get_default_focus_window_at_point (screen->stack, | ||||
| @@ -2142,6 +2155,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, | ||||
|   const MetaMonitorInfo* current; | ||||
|   const MetaMonitorInfo* tmp; | ||||
|   GQueue* monitor_queue; | ||||
|   MetaDevice *pointer; | ||||
|   int* visited; | ||||
|   int cur = 0; | ||||
|   int i; | ||||
| @@ -2149,6 +2163,9 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, | ||||
|   *n_monitors = screen->n_monitor_infos; | ||||
|   *monitors_list = g_new (int, screen->n_monitor_infos); | ||||
|  | ||||
|   pointer = meta_device_map_lookup (screen->display->device_map, | ||||
|                                     META_CORE_POINTER_ID); | ||||
|  | ||||
|   /* we calculate a natural ordering by which to choose monitors for | ||||
|    * window placement.  We start at the current monitor, and perform | ||||
|    * a breadth-first search of the monitors starting from that | ||||
| @@ -2163,7 +2180,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, | ||||
|       visited[i] = FALSE; | ||||
|     } | ||||
|  | ||||
|   current = meta_screen_get_current_monitor (screen); | ||||
|   current = meta_screen_get_current_monitor (screen, pointer); | ||||
|   monitor_queue = g_queue_new (); | ||||
|   g_queue_push_tail (monitor_queue, (gpointer) current); | ||||
|   visited[current->number] = TRUE; | ||||
| @@ -2230,7 +2247,8 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen, | ||||
| } | ||||
|  | ||||
| const MetaMonitorInfo* | ||||
| meta_screen_get_current_monitor (MetaScreen *screen) | ||||
| meta_screen_get_current_monitor (MetaScreen *screen, | ||||
|                                  MetaDevice *pointer) | ||||
| { | ||||
|   if (screen->n_monitor_infos == 1) | ||||
|     return &screen->monitor_infos[0]; | ||||
| @@ -2240,24 +2258,18 @@ meta_screen_get_current_monitor (MetaScreen *screen) | ||||
|    | ||||
|   if (screen->display->monitor_cache_invalidated) | ||||
|     { | ||||
|       Window root_return, child_return; | ||||
|       int win_x_return, win_y_return; | ||||
|       unsigned int mask_return; | ||||
|       int i; | ||||
|       MetaRectangle pointer_position; | ||||
|        | ||||
|       screen->display->monitor_cache_invalidated = FALSE; | ||||
|        | ||||
|       pointer_position.width = pointer_position.height = 1; | ||||
|       XQueryPointer (screen->display->xdisplay, | ||||
|                      screen->xroot, | ||||
|                      &root_return, | ||||
|                      &child_return, | ||||
|                      &pointer_position.x, | ||||
|                      &pointer_position.y, | ||||
|                      &win_x_return, | ||||
|                      &win_y_return, | ||||
|                      &mask_return); | ||||
|       meta_device_pointer_query_position (META_DEVICE_POINTER (pointer), | ||||
|                                           screen->xroot, | ||||
|                                           NULL, NULL, | ||||
|                                           &pointer_position.x, | ||||
|                                           &pointer_position.y, | ||||
|                                           NULL, NULL, NULL); | ||||
|  | ||||
|       screen->last_monitor_index = 0; | ||||
|       for (i = 0; i < screen->n_monitor_infos; i++) | ||||
| @@ -3114,17 +3126,22 @@ static gboolean startup_sequence_timeout (void *data); | ||||
| static void | ||||
| update_startup_feedback (MetaScreen *screen) | ||||
| { | ||||
|   MetaDevice *pointer; | ||||
|  | ||||
|   pointer = meta_device_map_lookup (screen->display->device_map, | ||||
|                                     META_CORE_POINTER_ID); | ||||
|  | ||||
|   if (screen->startup_sequences != NULL) | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting busy cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_BUSY); | ||||
|       meta_screen_set_cursor (screen, pointer, META_CURSOR_BUSY); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting default cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); | ||||
|       meta_screen_set_cursor (screen, pointer, META_CURSOR_DEFAULT); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -211,13 +211,23 @@ meta_stack_thaw (MetaStack *stack) | ||||
|   stack_sync_to_server (stack); | ||||
| } | ||||
|  | ||||
| typedef struct _FocusedForeachData FocusedForeachData; | ||||
|  | ||||
| struct _FocusedForeachData | ||||
| { | ||||
|   MetaWindow *window; | ||||
|   gboolean focused_transient; | ||||
| }; | ||||
|  | ||||
| static gboolean | ||||
| is_focused_foreach (MetaWindow *window, | ||||
|                     void       *data) | ||||
| { | ||||
|   if (window == window->display->expected_focus_window) | ||||
|   FocusedForeachData *focused_data = data; | ||||
|  | ||||
|   if (window == focused_data->window) | ||||
|     { | ||||
|       *((gboolean*) data) = TRUE; | ||||
|       focused_data->focused_transient = TRUE; | ||||
|       return FALSE; | ||||
|     } | ||||
|   return TRUE; | ||||
| @@ -239,7 +249,9 @@ static MetaStackLayer | ||||
| get_standalone_layer (MetaWindow *window) | ||||
| { | ||||
|   MetaStackLayer layer; | ||||
|   gboolean focused_transient = FALSE; | ||||
|   MetaFocusInfo *focus_info; | ||||
|   MetaDevice *keyboard; | ||||
|   FocusedForeachData focused_data = { NULL, FALSE }; | ||||
|  | ||||
|   switch (window->type) | ||||
|     { | ||||
| @@ -263,20 +275,33 @@ get_standalone_layer (MetaWindow *window) | ||||
|     case META_WINDOW_OVERRIDE_OTHER: | ||||
|       layer = META_LAYER_OVERRIDE_REDIRECT; | ||||
|       break; | ||||
|     default:        | ||||
|       meta_window_foreach_transient (window, | ||||
|                                      is_focused_foreach, | ||||
|                                      &focused_transient); | ||||
|     default: | ||||
|       /* FIXME: How about other keyboards? should | ||||
|        * we allow fullscreen for non-VCP/K anyway? | ||||
|        */ | ||||
|       keyboard = meta_device_map_lookup (window->display->device_map, | ||||
|                                          META_CORE_KEYBOARD_ID); | ||||
|  | ||||
|       focus_info = meta_display_get_focus_info (window->display, keyboard); | ||||
|  | ||||
|       if (focus_info) | ||||
|         { | ||||
|           focused_data.window = focus_info->expected_focus_window; | ||||
|           meta_window_foreach_transient (window, | ||||
|                                          is_focused_foreach, | ||||
|                                          &focused_data); | ||||
|         } | ||||
|  | ||||
|       if (window->wm_state_below) | ||||
|         layer = META_LAYER_BOTTOM; | ||||
|       else if (window->fullscreen && | ||||
|                (focused_transient || | ||||
|                 window == window->display->expected_focus_window || | ||||
|                 window->display->expected_focus_window == NULL || | ||||
|                 (window->display->expected_focus_window != NULL && | ||||
|                (focused_data.focused_transient || | ||||
|                 !focus_info || | ||||
|                 window == focus_info->expected_focus_window || | ||||
|                 focus_info->expected_focus_window == NULL || | ||||
|                 (focus_info->expected_focus_window != NULL && | ||||
|                  windows_on_different_monitor (window, | ||||
|                                                window->display->expected_focus_window)))) | ||||
|                                                focus_info->expected_focus_window)))) | ||||
|         layer = META_LAYER_FULLSCREEN; | ||||
|       else if (window->wm_state_above) | ||||
|         layer = META_LAYER_TOP; | ||||
|   | ||||
| @@ -81,6 +81,7 @@ meta_print_backtrace (void) | ||||
| static gint verbose_topics = 0; | ||||
| static gboolean is_debugging = FALSE; | ||||
| static gboolean replace_current = FALSE; | ||||
| static gboolean use_core_devices = FALSE; | ||||
| static int no_prefix = 0; | ||||
|  | ||||
| #ifdef WITH_VERBOSE_MODE | ||||
| @@ -209,6 +210,18 @@ meta_set_debugging (gboolean setting) | ||||
|   is_debugging = setting; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_get_use_core_devices (void) | ||||
| { | ||||
|   return use_core_devices; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_set_use_core_devices (gboolean setting) | ||||
| { | ||||
|   use_core_devices = setting; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_get_replace_current_wm (void) | ||||
| { | ||||
|   | ||||
| @@ -107,6 +107,10 @@ struct _MetaWindow | ||||
|   Window xgroup_leader; | ||||
|   Window xclient_leader; | ||||
|  | ||||
|   /* window menu if any, and the pointer that popped it up */ | ||||
|   MetaWindowMenu *menu; | ||||
|   MetaDevice *menu_device; | ||||
|  | ||||
|   /* Initial workspace property */ | ||||
|   int initial_workspace;   | ||||
|    | ||||
| @@ -322,6 +326,15 @@ struct _MetaWindow | ||||
|   /* if TRUE, window is attached to its parent */ | ||||
|   guint attached : 1; | ||||
|  | ||||
|   /* if TRUE, window didn't yet get the FocusIn for window->focus_keyboard */ | ||||
|   guint expecting_focus_in : 1; | ||||
|  | ||||
|   /* if TRUE, tiling mode is held regardless of newer touch updates */ | ||||
|   guint touch_hold_tiling_mode : 1; | ||||
|  | ||||
|   /* Keyboard currently owning the window focus, or NULL */ | ||||
|   MetaDevice *focus_keyboard; | ||||
|  | ||||
|   /* if non-NULL, the bounds of the window frame */ | ||||
|   cairo_region_t *frame_bounds; | ||||
|  | ||||
| @@ -399,6 +412,18 @@ struct _MetaWindow | ||||
|  | ||||
|   /* Focused window that is (directly or indirectly) attached to this one */ | ||||
|   MetaWindow *attached_focus_window; | ||||
|  | ||||
|   /* Current grab op for this window, or NULL */ | ||||
|   MetaGrabInfo *cur_grab; | ||||
|  | ||||
|   /* Focus info if the window is focused, or NULL */ | ||||
|   MetaFocusInfo *cur_focus; | ||||
|  | ||||
|   GHashTable *cur_touches; | ||||
|   gdouble initial_touch_area_width; | ||||
|   gdouble initial_touch_area_height; | ||||
|   gdouble cur_touch_area_width; | ||||
|   gdouble cur_touch_area_height; | ||||
| }; | ||||
|  | ||||
| struct _MetaWindowClass | ||||
| @@ -570,6 +595,7 @@ void     meta_window_set_current_workspace_hint (MetaWindow *window); | ||||
| unsigned long meta_window_get_net_wm_desktop (MetaWindow *window); | ||||
|  | ||||
| void meta_window_show_menu (MetaWindow *window, | ||||
|                             MetaDevice *device, | ||||
|                             int         root_x, | ||||
|                             int         root_y, | ||||
|                             int         button, | ||||
| @@ -619,13 +645,16 @@ void meta_window_free_delete_dialog (MetaWindow *window); | ||||
|  | ||||
|  | ||||
| void meta_window_begin_grab_op (MetaWindow *window, | ||||
|                                 MetaDevice *device, | ||||
|                                 MetaGrabOp  op, | ||||
|                                 gboolean    frame_action, | ||||
|                                 guint32     timestamp); | ||||
|  | ||||
| void meta_window_update_keyboard_resize (MetaWindow *window, | ||||
|                                          MetaDevice *device, | ||||
|                                          gboolean    update_cursor); | ||||
| void meta_window_update_keyboard_move   (MetaWindow *window); | ||||
| void meta_window_update_keyboard_move   (MetaWindow *window, | ||||
|                                          MetaDevice *device); | ||||
|  | ||||
| void meta_window_update_layer (MetaWindow *window); | ||||
|  | ||||
| @@ -647,8 +676,20 @@ void meta_window_update_for_monitors_changed (MetaWindow *window); | ||||
| void meta_window_update_on_all_workspaces (MetaWindow *window); | ||||
|  | ||||
| void meta_window_propagate_focus_appearance (MetaWindow *window, | ||||
|                                              MetaDevice *keyboard, | ||||
|                                              gboolean    focused); | ||||
|  | ||||
| gboolean meta_window_should_attach_to_parent (MetaWindow *window); | ||||
|  | ||||
| void         meta_window_set_client_pointer (MetaWindow *window, | ||||
|                                              MetaDevice *pointer); | ||||
| MetaDevice * meta_window_get_client_pointer (MetaWindow *window); | ||||
|  | ||||
| MetaDevice * meta_window_guess_grab_pointer (MetaWindow *window); | ||||
|  | ||||
| gboolean     meta_window_update_touch (MetaWindow *window, | ||||
|                                        XEvent     *event); | ||||
| void         meta_window_end_touch    (MetaWindow *window, | ||||
|                                        XEvent     *event); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1507,7 +1507,9 @@ reload_transient_for (MetaWindow    *window, | ||||
|     return; | ||||
|  | ||||
|   if (meta_window_appears_focused (window) && window->xtransient_for != None) | ||||
|     meta_window_propagate_focus_appearance (window, FALSE); | ||||
|     meta_window_propagate_focus_appearance (window, | ||||
|                                             window->focus_keyboard, | ||||
|                                             FALSE); | ||||
|  | ||||
|   old_transient_for = window->xtransient_for; | ||||
|   window->xtransient_for = transient_for; | ||||
| @@ -1560,7 +1562,9 @@ reload_transient_for (MetaWindow    *window, | ||||
|     meta_window_queue (window, META_QUEUE_MOVE_RESIZE); | ||||
|  | ||||
|   if (meta_window_appears_focused (window) && window->xtransient_for != None) | ||||
|     meta_window_propagate_focus_appearance (window, TRUE); | ||||
|     meta_window_propagate_focus_appearance (window, | ||||
|                                             window->focus_keyboard, | ||||
|                                             TRUE); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
							
								
								
									
										1252
									
								
								src/core/window.c
									
									
									
									
									
								
							
							
						
						
									
										1252
									
								
								src/core/window.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -85,6 +85,7 @@ GList* meta_workspace_get_onmonitor_region      (MetaWorkspace *workspace, | ||||
|                                                  int            which_monitor); | ||||
|  | ||||
| void meta_workspace_focus_default_window (MetaWorkspace *workspace, | ||||
|                                           MetaDevice    *pointer, | ||||
|                                           MetaWindow    *not_this_one, | ||||
|                                           guint32        timestamp); | ||||
|  | ||||
|   | ||||
| @@ -538,7 +538,9 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, | ||||
|   MetaWorkspaceLayout layout1, layout2; | ||||
|   gint num_workspaces, current_space, new_space; | ||||
|   MetaMotionDirection direction; | ||||
|    | ||||
|   MetaGrabInfo *grab_info; | ||||
|   GHashTableIter iter; | ||||
|  | ||||
|   meta_verbose ("Activating workspace %d\n", | ||||
|                 meta_workspace_index (workspace)); | ||||
|    | ||||
| @@ -547,7 +549,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, | ||||
|  | ||||
|   /* Free any cached pointers to the workspaces's edges from | ||||
|    * a current resize or move operation */ | ||||
|   meta_display_cleanup_edges (workspace->screen->display); | ||||
|   meta_display_cleanup_edges (workspace->screen->display, workspace->screen); | ||||
|  | ||||
|   if (workspace->screen->active_workspace) | ||||
|     workspace_switch_sound (workspace->screen->active_workspace, workspace); | ||||
| @@ -570,10 +572,22 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, | ||||
|     return; | ||||
|  | ||||
|   move_window = NULL; | ||||
|   if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING || | ||||
|       workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING) | ||||
|     move_window = workspace->screen->display->grab_window; | ||||
|        | ||||
|  | ||||
|   /* FIXME: not quite multidevice friendly, but the whole | ||||
|    * "move window to another workspace" isn't. | ||||
|    */ | ||||
|   g_hash_table_iter_init (&iter, workspace->screen->display->current_grabs); | ||||
|  | ||||
|   while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &grab_info)) | ||||
|     { | ||||
|       if (grab_info->grab_op == META_GRAB_OP_MOVING || | ||||
|           grab_info->grab_op == META_GRAB_OP_KEYBOARD_MOVING) | ||||
|         { | ||||
|           move_window = grab_info->grab_window; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (move_window != NULL) | ||||
|     { | ||||
|       if (move_window->on_all_workspaces) | ||||
| @@ -673,8 +687,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       MetaDevice *pointer; | ||||
|  | ||||
|       pointer = meta_device_map_lookup (screen->display->device_map, | ||||
|                                         META_CORE_POINTER_ID); | ||||
|       meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n"); | ||||
|       meta_workspace_focus_default_window (workspace, NULL, timestamp); | ||||
|       meta_workspace_focus_default_window (workspace, pointer, | ||||
|                                            NULL, timestamp); | ||||
|     } | ||||
|  | ||||
|    /* Emit switched signal from screen.c */ | ||||
| @@ -774,7 +793,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace) | ||||
|   /* If we are in the middle of a resize or move operation, we | ||||
|    * might have cached pointers to the workspace's edges */ | ||||
|   if (workspace == workspace->screen->active_workspace) | ||||
|     meta_display_cleanup_edges (workspace->screen->display); | ||||
|     meta_display_cleanup_edges (workspace->screen->display, workspace->screen); | ||||
|  | ||||
|   g_free (workspace->work_area_monitor); | ||||
|   workspace->work_area_monitor = NULL; | ||||
| @@ -1191,6 +1210,7 @@ meta_workspace_get_name (MetaWorkspace *workspace) | ||||
|  | ||||
| void | ||||
| meta_workspace_focus_default_window (MetaWorkspace *workspace, | ||||
|                                      MetaDevice    *pointer, | ||||
|                                      MetaWindow    *not_this_one, | ||||
|                                      guint32        timestamp) | ||||
| { | ||||
| @@ -1207,7 +1227,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, | ||||
|   else | ||||
|     { | ||||
|       MetaWindow * window; | ||||
|       window = meta_screen_get_mouse_window (workspace->screen, not_this_one); | ||||
|       window = meta_screen_get_mouse_window (workspace->screen, | ||||
|                                              pointer, not_this_one); | ||||
|       if (window && | ||||
|           window->type != META_WINDOW_DOCK && | ||||
|           window->type != META_WINDOW_DESKTOP) | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/meta/device-map.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/meta/device-map.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_MAP_H | ||||
| #define META_DEVICE_MAP_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <meta/types.h> | ||||
| #include <meta/device.h> | ||||
|  | ||||
| #define META_TYPE_DEVICE_MAP            (meta_device_map_get_type ()) | ||||
| #define META_DEVICE_MAP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP, MetaDeviceMap)) | ||||
| #define META_DEVICE_MAP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_MAP, MetaDeviceMapClass)) | ||||
| #define META_IS_DEVICE_MAP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP)) | ||||
| #define META_IS_DEVICE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_MAP)) | ||||
| #define META_DEVICE_MAP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_MAP, MetaDeviceMapClass)) | ||||
|  | ||||
| typedef struct _MetaDeviceMapClass   MetaDeviceMapClass; | ||||
|  | ||||
| GType           meta_device_map_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaDevice *    meta_device_map_lookup      (MetaDeviceMap *device_map, | ||||
| 					     gint           device_id); | ||||
|  | ||||
| MetaDisplay *   meta_device_map_get_display (MetaDeviceMap *device_map); | ||||
| GList *         meta_device_map_list_devices (MetaDeviceMap *device_map); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								src/meta/device.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/meta/device.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2011 Carlos Garnacho | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_DEVICE_H | ||||
| #define META_DEVICE_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <meta/types.h> | ||||
|  | ||||
| #define META_TYPE_DEVICE            (meta_device_get_type ()) | ||||
| #define META_DEVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE, MetaDevice)) | ||||
| #define META_DEVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE, MetaDeviceClass)) | ||||
| #define META_IS_DEVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE)) | ||||
| #define META_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE)) | ||||
| #define META_DEVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE, MetaDeviceClass)) | ||||
|  | ||||
| typedef struct _MetaDeviceClass   MetaDeviceClass; | ||||
|  | ||||
| GType        meta_device_get_type     (void) G_GNUC_CONST; | ||||
|  | ||||
| int          meta_device_get_id       (MetaDevice  *device); | ||||
| MetaDisplay *meta_device_get_display  (MetaDevice *device); | ||||
|  | ||||
| MetaDevice * meta_device_get_paired_device (MetaDevice *device); | ||||
|  | ||||
| #endif | ||||
| @@ -28,6 +28,7 @@ | ||||
| #include <meta/types.h> | ||||
| #include <meta/prefs.h> | ||||
| #include <meta/common.h> | ||||
| #include <meta/device-map.h> | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
| @@ -74,6 +75,9 @@ gboolean meta_display_has_shape (MetaDisplay *display); | ||||
|  | ||||
| MetaScreen *meta_display_screen_for_root (MetaDisplay *display, | ||||
|                                           Window       xroot); | ||||
|  | ||||
| MetaWindow *meta_display_get_keyboard_focus_window (MetaDisplay *display, | ||||
|                                                     MetaDevice  *keyboard); | ||||
| MetaWindow *meta_display_get_focus_window (MetaDisplay *display); | ||||
|  | ||||
| gboolean  meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, | ||||
| @@ -108,9 +112,30 @@ MetaWindow* meta_display_get_tab_current (MetaDisplay   *display, | ||||
|                                           MetaScreen    *screen, | ||||
|                                           MetaWorkspace *workspace); | ||||
|  | ||||
| GList* meta_display_get_device_tab_list (MetaDisplay   *display, | ||||
|                                          MetaTabList    type, | ||||
|                                          MetaScreen    *screen, | ||||
|                                          MetaWorkspace *workspace, | ||||
|                                          MetaDevice    *device); | ||||
|  | ||||
| MetaWindow* meta_display_get_device_tab_next (MetaDisplay   *display, | ||||
|                                               MetaTabList    type, | ||||
|                                               MetaScreen    *screen, | ||||
|                                               MetaWorkspace *workspace, | ||||
|                                               MetaWindow    *window, | ||||
|                                               MetaDevice    *device, | ||||
|                                               gboolean       backward); | ||||
|  | ||||
| MetaWindow* meta_display_get_device_tab_current (MetaDisplay   *display, | ||||
|                                                  MetaTabList    type, | ||||
|                                                  MetaScreen    *screen, | ||||
|                                                  MetaWorkspace *workspace, | ||||
|                                                  MetaDevice    *device); | ||||
|  | ||||
| gboolean meta_display_begin_grab_op (MetaDisplay *display, | ||||
|                                      MetaScreen  *screen, | ||||
|                                      MetaWindow  *window, | ||||
|                                      MetaDevice  *device, | ||||
|                                      MetaGrabOp   op, | ||||
|                                      gboolean     pointer_already_grabbed, | ||||
|                                      gboolean     frame_action, | ||||
| @@ -120,14 +145,28 @@ gboolean meta_display_begin_grab_op (MetaDisplay *display, | ||||
|                                      int          root_x, | ||||
|                                      int          root_y); | ||||
| void     meta_display_end_grab_op   (MetaDisplay *display, | ||||
|                                      MetaDevice  *device, | ||||
|                                      guint32      timestamp); | ||||
|  | ||||
| MetaGrabOp meta_display_get_grab_op (MetaDisplay *display); | ||||
|  | ||||
| MetaGrabOp meta_display_get_device_grab_op (MetaDisplay *display, | ||||
|                                             MetaDevice  *device); | ||||
|  | ||||
| MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay  *display, | ||||
|                                                          unsigned int  keycode, | ||||
|                                                          unsigned long mask); | ||||
|  | ||||
| void meta_display_set_keyboard_focus   (MetaDisplay        *display, | ||||
|                                         MetaWindow         *window, | ||||
|                                         MetaDevice         *keyboard, | ||||
|                                         gboolean            focus_frame, | ||||
|                                         guint32             timestamp); | ||||
| void meta_display_unset_keyboard_focus (MetaDisplay        *display, | ||||
|                                         MetaScreen         *screen, | ||||
|                                         MetaDevice         *keyboard, | ||||
|                                         guint32             timestamp); | ||||
|  | ||||
| /* meta_display_set_input_focus_window is like XSetInputFocus, except | ||||
|  * that (a) it can't detect timestamps later than the current time, | ||||
|  * since Mutter isn't part of the XServer, and thus gives erroneous | ||||
| @@ -162,4 +201,6 @@ void meta_display_unmanage_screen (MetaDisplay *display, | ||||
|                                    MetaScreen  *screen, | ||||
|                                    guint32      timestamp); | ||||
|  | ||||
| MetaDeviceMap * meta_display_get_device_map (MetaDisplay *display); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -67,6 +67,10 @@ void meta_keybindings_switch_window (MetaDisplay    *display, | ||||
| 				     MetaKeyBinding *binding); | ||||
|  | ||||
|  | ||||
| void     meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp); | ||||
| gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp); | ||||
| void     meta_screen_ungrab_all_keys (MetaScreen *screen, | ||||
|                                       MetaDevice *device, | ||||
|                                       guint32     timestamp); | ||||
| gboolean meta_screen_grab_all_keys   (MetaScreen *screen, | ||||
|                                       MetaDevice *device, | ||||
|                                       guint32     timestamp); | ||||
| #endif | ||||
|   | ||||
| @@ -32,6 +32,8 @@ typedef struct _MetaFrame       MetaFrame; | ||||
| typedef struct _MetaScreen      MetaScreen; | ||||
| typedef struct _MetaWindow      MetaWindow; | ||||
| typedef struct _MetaWorkspace   MetaWorkspace; | ||||
| typedef struct _MetaDevice      MetaDevice; | ||||
| typedef struct _MetaDeviceMap   MetaDeviceMap; | ||||
| /** | ||||
|  * MetaGroup: (skip) | ||||
|  * | ||||
|   | ||||
| @@ -38,6 +38,9 @@ gboolean meta_is_syncing (void); | ||||
| void     meta_set_syncing (gboolean setting); | ||||
| void     meta_set_replace_current_wm (gboolean setting); | ||||
|  | ||||
| gboolean meta_get_use_core_devices (void); | ||||
| void     meta_set_use_core_devices (gboolean setting); | ||||
|  | ||||
| void meta_debug_spew_real (const char *format, | ||||
|                            ...) G_GNUC_PRINTF (1, 2); | ||||
| void meta_verbose_real    (const char *format, | ||||
|   | ||||
							
								
								
									
										161
									
								
								src/ui/frames.c
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								src/ui/frames.c
									
									
									
									
									
								
							| @@ -52,6 +52,7 @@ static void meta_frames_unmap         (GtkWidget       *widget); | ||||
|  | ||||
| static void meta_frames_update_prelit_control (MetaFrames      *frames, | ||||
|                                                MetaUIFrame     *frame, | ||||
|                                                GdkDevice       *device, | ||||
|                                                MetaFrameControl control); | ||||
| static gboolean meta_frames_button_press_event    (GtkWidget           *widget, | ||||
|                                                    GdkEventButton      *event); | ||||
| @@ -734,10 +735,18 @@ meta_frames_unmanage_window (MetaFrames *frames, | ||||
|        */ | ||||
|       invalidate_all_caches (frames); | ||||
|        | ||||
| #if 0 | ||||
|       /* This function is only called when destroying the frame | ||||
|        * in core/frame.c, ideally this should be done for every | ||||
|        * device with a cursor on the frame, but in practical | ||||
|        * effects it doesn't matter. | ||||
|        */ | ||||
|  | ||||
|       /* restore the cursor */ | ||||
|       meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), | ||||
|                                    frame->xwindow, | ||||
|                                    META_CURSOR_DEFAULT); | ||||
| #endif | ||||
|  | ||||
|       gdk_window_set_user_data (frame->window, NULL); | ||||
|  | ||||
| @@ -1293,10 +1302,12 @@ meta_frame_titlebar_event (MetaUIFrame    *frame, | ||||
|                            int            action) | ||||
| { | ||||
|   MetaFrameFlags flags; | ||||
|   GdkDevice *pointer; | ||||
|   Display *display; | ||||
|  | ||||
|   display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); | ||||
|    | ||||
|   pointer = gdk_event_get_device ((GdkEvent *) event); | ||||
|  | ||||
|   switch (action) | ||||
|     { | ||||
|     case META_ACTION_TITLEBAR_TOGGLE_SHADE: | ||||
| @@ -1378,12 +1389,14 @@ meta_frame_titlebar_event (MetaUIFrame    *frame, | ||||
|     case META_ACTION_TITLEBAR_LOWER: | ||||
|       meta_core_user_lower_and_unfocus (display, | ||||
|                                         frame->xwindow, | ||||
|                                         gdk_x11_device_get_id (pointer), | ||||
|                                         event->time); | ||||
|       break; | ||||
|  | ||||
|     case META_ACTION_TITLEBAR_MENU: | ||||
|       meta_core_show_window_menu (display, | ||||
|                                   frame->xwindow, | ||||
|                                   gdk_x11_device_get_id (pointer), | ||||
|                                   event->x_root, | ||||
|                                   event->y_root, | ||||
|                                   event->button, | ||||
| @@ -1432,7 +1445,9 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|   MetaFrames *frames; | ||||
|   MetaFrameControl control; | ||||
|   Display *display; | ||||
|    | ||||
|   GdkDevice *device; | ||||
|   int device_id; | ||||
|  | ||||
|   frames = META_FRAMES (widget); | ||||
|   display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); | ||||
|  | ||||
| @@ -1465,7 +1480,10 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|   /* don't do the rest of this if on client area */ | ||||
|   if (control == META_FRAME_CONTROL_CLIENT_AREA) | ||||
|     return FALSE; /* not on the frame, just passed through from client */ | ||||
|    | ||||
|  | ||||
|   device = gdk_event_get_device ((GdkEvent *) event); | ||||
|   device_id = gdk_x11_device_get_id (device); | ||||
|  | ||||
|   /* We want to shade even if we have a GrabOp, since we'll have a move grab | ||||
|    * if we double click the titlebar. | ||||
|    */ | ||||
| @@ -1473,13 +1491,13 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|       event->button == 1 && | ||||
|       event->type == GDK_2BUTTON_PRESS) | ||||
|     { | ||||
|       meta_core_end_grab_op (display, event->time); | ||||
|       meta_core_end_grab_op (display, device_id, event->time); | ||||
|       return meta_frame_double_click_event (frame, event); | ||||
|     } | ||||
|  | ||||
|   if (meta_core_get_grab_op (display) != | ||||
|   if (meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL) != | ||||
|       META_GRAB_OP_NONE) | ||||
|     return FALSE; /* already up to something */   | ||||
|     return FALSE; /* already up to something */ | ||||
|  | ||||
|   if (event->button == 1 && | ||||
|       (control == META_FRAME_CONTROL_MAXIMIZE || | ||||
| @@ -1538,6 +1556,7 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|  | ||||
|       meta_core_begin_grab_op (display, | ||||
|                                frame->xwindow, | ||||
|                                device_id, | ||||
|                                op, | ||||
|                                TRUE, | ||||
|                                TRUE, | ||||
| @@ -1570,6 +1589,7 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|  | ||||
|           meta_core_show_window_menu (display, | ||||
|                                       frame->xwindow, | ||||
|                                       device_id, | ||||
|                                       rect->x + dx, | ||||
|                                       rect->y + rect->height + dy, | ||||
|                                       event->button, | ||||
| @@ -1623,6 +1643,7 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|  | ||||
|       meta_core_begin_grab_op (display, | ||||
|                                frame->xwindow, | ||||
|                                device_id, | ||||
|                                op, | ||||
|                                TRUE, | ||||
|                                TRUE, | ||||
| @@ -1645,6 +1666,7 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
|         {           | ||||
|           meta_core_begin_grab_op (display, | ||||
|                                    frame->xwindow, | ||||
|                                    device_id, | ||||
|                                    META_GRAB_OP_MOVING, | ||||
|                                    TRUE, | ||||
|                                    TRUE, | ||||
| @@ -1668,28 +1690,28 @@ meta_frames_button_press_event (GtkWidget      *widget, | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_frames_notify_menu_hide (MetaFrames *frames) | ||||
| meta_frames_notify_menu_hide (MetaFrames *frames, | ||||
|                               Window      client_xwindow) | ||||
| { | ||||
|   Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); | ||||
|   if (meta_core_get_grab_op (display) == | ||||
|   Window frame_xwindow; | ||||
|   int device_id; | ||||
|  | ||||
|   frame_xwindow = meta_core_get_frame (display, client_xwindow); | ||||
|  | ||||
|   if (frame_xwindow != None && | ||||
|       meta_core_frame_has_grab (display, frame_xwindow, &device_id, NULL) == | ||||
|       META_GRAB_OP_CLICKING_MENU) | ||||
|     { | ||||
|       Window grab_frame; | ||||
|       MetaUIFrame *frame; | ||||
|  | ||||
|       grab_frame = meta_core_get_grab_frame (display); | ||||
|       frame = meta_frames_lookup_window (frames, frame_xwindow); | ||||
|  | ||||
|       if (grab_frame != None) | ||||
|       if (frame) | ||||
|         { | ||||
|           MetaUIFrame *frame; | ||||
|  | ||||
|           frame = meta_frames_lookup_window (frames, grab_frame); | ||||
|  | ||||
|           if (frame) | ||||
|             { | ||||
|               redraw_control (frames, frame, | ||||
|                               META_FRAME_CONTROL_MENU); | ||||
|               meta_core_end_grab_op (display, CurrentTime); | ||||
|             } | ||||
|           redraw_control (frames, frame, | ||||
|                           META_FRAME_CONTROL_MENU); | ||||
|           meta_core_end_grab_op (display, device_id, CurrentTime); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1702,7 +1724,10 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
|   MetaFrames *frames; | ||||
|   MetaGrabOp op; | ||||
|   Display *display; | ||||
|    | ||||
|   int grab_button; | ||||
|   GdkDevice *device; | ||||
|   int device_id, grab_device_id; | ||||
|  | ||||
|   frames = META_FRAMES (widget); | ||||
|   display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); | ||||
|    | ||||
| @@ -1712,17 +1737,21 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
|  | ||||
|   clear_tip (frames); | ||||
|  | ||||
|   op = meta_core_get_grab_op (display); | ||||
|   op = meta_core_frame_has_grab (display, frame->xwindow, | ||||
|                                  &grab_device_id, &grab_button); | ||||
|  | ||||
|   if (op == META_GRAB_OP_NONE) | ||||
|   device = gdk_event_get_device ((GdkEvent *) event); | ||||
|   device_id = gdk_x11_device_get_id (device); | ||||
|  | ||||
|   if (op == META_GRAB_OP_NONE || | ||||
|       grab_device_id != device_id) | ||||
|     return FALSE; | ||||
|  | ||||
|   /* We only handle the releases we handled the presses for (things | ||||
|    * involving frame controls). Window ops that don't require a | ||||
|    * frame are handled in the Xlib part of the code, display.c/window.c | ||||
|    */ | ||||
|   if (frame->xwindow == meta_core_get_grab_frame (display) && | ||||
|       ((int) event->button) == meta_core_get_grab_button (display)) | ||||
|   if (((int) event->button) == grab_button) | ||||
|     { | ||||
|       MetaFrameControl control; | ||||
|  | ||||
| @@ -1733,8 +1762,8 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
|         case META_GRAB_OP_CLICKING_MINIMIZE: | ||||
|           if (control == META_FRAME_CONTROL_MINIMIZE) | ||||
|             meta_core_minimize (display, frame->xwindow); | ||||
|            | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|  | ||||
|         case META_GRAB_OP_CLICKING_MAXIMIZE: | ||||
| @@ -1746,67 +1775,67 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
|                             event->time);       | ||||
|             meta_core_maximize (display, frame->xwindow); | ||||
|           } | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|  | ||||
|         case META_GRAB_OP_CLICKING_UNMAXIMIZE: | ||||
|           if (control == META_FRAME_CONTROL_UNMAXIMIZE) | ||||
|             meta_core_unmaximize (display, frame->xwindow); | ||||
|            | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|            | ||||
|         case META_GRAB_OP_CLICKING_DELETE: | ||||
|           if (control == META_FRAME_CONTROL_DELETE) | ||||
|             meta_core_delete (display, frame->xwindow, event->time); | ||||
|            | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|            | ||||
|         case META_GRAB_OP_CLICKING_MENU: | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|  | ||||
|         case META_GRAB_OP_CLICKING_SHADE: | ||||
|           if (control == META_FRAME_CONTROL_SHADE) | ||||
|             meta_core_shade (display, frame->xwindow, event->time); | ||||
|            | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|   | ||||
|         case META_GRAB_OP_CLICKING_UNSHADE: | ||||
|           if (control == META_FRAME_CONTROL_UNSHADE) | ||||
|             meta_core_unshade (display, frame->xwindow, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|  | ||||
|         case META_GRAB_OP_CLICKING_ABOVE: | ||||
|           if (control == META_FRAME_CONTROL_ABOVE) | ||||
|             meta_core_make_above (display, frame->xwindow); | ||||
|            | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|  | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|   | ||||
|         case META_GRAB_OP_CLICKING_UNABOVE: | ||||
|           if (control == META_FRAME_CONTROL_UNABOVE) | ||||
|             meta_core_unmake_above (display, frame->xwindow); | ||||
|  | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|  | ||||
|         case META_GRAB_OP_CLICKING_STICK: | ||||
|           if (control == META_FRAME_CONTROL_STICK) | ||||
|             meta_core_stick (display, frame->xwindow); | ||||
|  | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|   | ||||
|         case META_GRAB_OP_CLICKING_UNSTICK: | ||||
|           if (control == META_FRAME_CONTROL_UNSTICK) | ||||
|             meta_core_unstick (display, frame->xwindow); | ||||
|  | ||||
|           meta_core_end_grab_op (display, event->time); | ||||
|           meta_core_end_grab_op (display, device_id, event->time); | ||||
|           break; | ||||
|            | ||||
|         default: | ||||
| @@ -1818,7 +1847,9 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
|        * prelit so to let the user know that it can now be pressed. | ||||
|        * :) | ||||
|        */ | ||||
|       meta_frames_update_prelit_control (frames, frame, control); | ||||
|       meta_frames_update_prelit_control (frames, frame,  | ||||
|                                          gdk_event_get_device ((GdkEvent *) event), | ||||
|                                          control); | ||||
|     } | ||||
|    | ||||
|   return TRUE; | ||||
| @@ -1827,12 +1858,12 @@ meta_frames_button_release_event    (GtkWidget           *widget, | ||||
| static void | ||||
| meta_frames_update_prelit_control (MetaFrames      *frames, | ||||
|                                    MetaUIFrame     *frame, | ||||
|                                    GdkDevice       *device, | ||||
|                                    MetaFrameControl control) | ||||
| { | ||||
|   MetaFrameControl old_control; | ||||
|   MetaCursor cursor; | ||||
|  | ||||
|  | ||||
|   meta_verbose ("Updating prelit control from %u to %u\n", | ||||
|                 frame->prelit_control, control); | ||||
|    | ||||
| @@ -1897,6 +1928,7 @@ meta_frames_update_prelit_control (MetaFrames      *frames, | ||||
|   /* set/unset the prelight cursor */ | ||||
|   meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), | ||||
|                                frame->xwindow, | ||||
|                                gdk_x11_device_get_id (device), | ||||
|                                cursor);   | ||||
|  | ||||
|   switch (control) | ||||
| @@ -1952,8 +1984,8 @@ meta_frames_motion_notify_event     (GtkWidget           *widget, | ||||
|  | ||||
|   frames->last_motion_frame = frame; | ||||
|  | ||||
|   grab_op = meta_core_get_grab_op (display); | ||||
|    | ||||
|   grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL); | ||||
|  | ||||
|   switch (grab_op) | ||||
|     { | ||||
|     case META_GRAB_OP_CLICKING_MENU: | ||||
| @@ -1969,10 +2001,9 @@ meta_frames_motion_notify_event     (GtkWidget           *widget, | ||||
|     case META_GRAB_OP_CLICKING_UNSTICK: | ||||
|       { | ||||
|         MetaFrameControl control; | ||||
|         int x, y; | ||||
|          | ||||
|         gdk_window_get_device_position (frame->window, event->device, | ||||
|                                         &x, &y, NULL); | ||||
|         gdouble x, y; | ||||
|  | ||||
|         gdk_event_get_coords ((GdkEvent *) event, &x, &y); | ||||
|  | ||||
|         /* Control is set to none unless it matches | ||||
|          * the current grab | ||||
| @@ -2003,7 +2034,9 @@ meta_frames_motion_notify_event     (GtkWidget           *widget, | ||||
|            control = META_FRAME_CONTROL_NONE; | ||||
|          | ||||
|         /* Update prelit control and cursor */ | ||||
|         meta_frames_update_prelit_control (frames, frame, control); | ||||
|         meta_frames_update_prelit_control (frames, frame,  | ||||
|                                            gdk_event_get_device ((GdkEvent *) event), | ||||
|                                            control); | ||||
|  | ||||
|         /* No tooltip while in the process of clicking */ | ||||
|       } | ||||
| @@ -2011,15 +2044,15 @@ meta_frames_motion_notify_event     (GtkWidget           *widget, | ||||
|     case META_GRAB_OP_NONE: | ||||
|       { | ||||
|         MetaFrameControl control; | ||||
|         int x, y; | ||||
|          | ||||
|         gdk_window_get_device_position (frame->window, event->device, | ||||
|                                         &x, &y, NULL); | ||||
|         gdouble x, y; | ||||
|  | ||||
|         gdk_event_get_coords ((GdkEvent *) event, &x, &y); | ||||
|         control = get_control (frames, frame, x, y); | ||||
|  | ||||
|         /* Update prelit control and cursor */ | ||||
|         meta_frames_update_prelit_control (frames, frame, control); | ||||
|         meta_frames_update_prelit_control (frames, frame,  | ||||
|                                            gdk_event_get_device ((GdkEvent *) event), | ||||
|                                            control); | ||||
|          | ||||
|         queue_tip (frames); | ||||
|       } | ||||
| @@ -2368,7 +2401,6 @@ meta_frames_paint (MetaFrames   *frames, | ||||
|   GdkPixbuf *icon; | ||||
|   int w, h; | ||||
|   MetaButtonState button_states[META_BUTTON_TYPE_LAST]; | ||||
|   Window grab_frame; | ||||
|   int i; | ||||
|   MetaButtonLayout button_layout; | ||||
|   MetaGrabOp grab_op; | ||||
| @@ -2380,11 +2412,8 @@ meta_frames_paint (MetaFrames   *frames, | ||||
|   for (i = 0; i < META_BUTTON_TYPE_LAST; i++) | ||||
|     button_states[i] = META_BUTTON_STATE_NORMAL; | ||||
|  | ||||
|   grab_frame = meta_core_get_grab_frame (display); | ||||
|   grab_op = meta_core_get_grab_op (display); | ||||
|   if (grab_frame != frame->xwindow) | ||||
|     grab_op = META_GRAB_OP_NONE; | ||||
|    | ||||
|   grab_op = meta_core_frame_has_grab (display, frame->xwindow, NULL, NULL); | ||||
|  | ||||
|   /* Set prelight state */ | ||||
|   switch (frame->prelit_control) | ||||
|     { | ||||
| @@ -2546,7 +2575,9 @@ meta_frames_enter_notify_event      (GtkWidget           *widget, | ||||
|     return FALSE; | ||||
|  | ||||
|   control = get_control (frames, frame, event->x, event->y); | ||||
|   meta_frames_update_prelit_control (frames, frame, control); | ||||
|   meta_frames_update_prelit_control (frames, frame,  | ||||
|                                      gdk_event_get_device ((GdkEvent *) event), | ||||
|                                      control); | ||||
|    | ||||
|   return TRUE; | ||||
| } | ||||
| @@ -2564,7 +2595,9 @@ meta_frames_leave_notify_event      (GtkWidget           *widget, | ||||
|   if (frame == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE); | ||||
|   meta_frames_update_prelit_control (frames, frame,  | ||||
|                                      gdk_event_get_device ((GdkEvent *) event), | ||||
|                                      META_FRAME_CONTROL_NONE); | ||||
|    | ||||
|   clear_tip (frames); | ||||
|  | ||||
|   | ||||
| @@ -165,7 +165,8 @@ void meta_frames_move_resize_frame (MetaFrames *frames, | ||||
| void meta_frames_queue_draw (MetaFrames *frames, | ||||
|                              Window      xwindow); | ||||
|  | ||||
| void meta_frames_notify_menu_hide (MetaFrames *frames); | ||||
| void meta_frames_notify_menu_hide (MetaFrames *frames, | ||||
|                                    Window      client_xwindow); | ||||
|  | ||||
| Window meta_frames_get_moving_frame (MetaFrames *frames); | ||||
|  | ||||
|   | ||||
| @@ -137,7 +137,7 @@ menu_closed (GtkMenu *widget, | ||||
|    | ||||
|   menu = data; | ||||
|  | ||||
|   meta_frames_notify_menu_hide (menu->frames); | ||||
|   meta_frames_notify_menu_hide (menu->frames, menu->client_xwindow); | ||||
|   (* menu->func) (menu, | ||||
|                   GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), | ||||
|                   menu->client_xwindow, | ||||
| @@ -157,7 +157,7 @@ activate_cb (GtkWidget *menuitem, gpointer data) | ||||
|    | ||||
|   md = data; | ||||
|  | ||||
|   meta_frames_notify_menu_hide (md->menu->frames); | ||||
|   meta_frames_notify_menu_hide (md->menu->frames, md->menu->client_xwindow); | ||||
|   (* md->menu->func) (md->menu, | ||||
|                       GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), | ||||
|                       md->menu->client_xwindow, | ||||
| @@ -498,13 +498,17 @@ meta_window_menu_new   (MetaFrames         *frames, | ||||
|  | ||||
| void | ||||
| meta_window_menu_popup (MetaWindowMenu     *menu, | ||||
|                         MetaDevice         *device, | ||||
|                         int                 root_x, | ||||
|                         int                 root_y, | ||||
|                         int                 button, | ||||
|                         guint32             timestamp) | ||||
| { | ||||
|   GdkDeviceManager *device_manager; | ||||
|   GdkDevice *gdkdevice; | ||||
|   GdkDisplay *display; | ||||
|   GdkPoint *pt; | ||||
|    | ||||
|  | ||||
|   pt = g_new (GdkPoint, 1); | ||||
|  | ||||
|   g_object_set_data_full (G_OBJECT (menu->menu), | ||||
| @@ -514,12 +518,18 @@ meta_window_menu_popup (MetaWindowMenu     *menu, | ||||
|  | ||||
|   pt->x = root_x; | ||||
|   pt->y = root_y; | ||||
|    | ||||
|   gtk_menu_popup (GTK_MENU (menu->menu), | ||||
|                   NULL, NULL, | ||||
|                   popup_position_func, pt, | ||||
|                   button, | ||||
|                   timestamp); | ||||
|  | ||||
|   display = gtk_widget_get_display (menu->menu); | ||||
|   device_manager = gdk_display_get_device_manager (display); | ||||
|   gdkdevice = gdk_x11_device_manager_lookup (device_manager, | ||||
|                                              meta_device_get_id (device)); | ||||
|  | ||||
|   gtk_menu_popup_for_device (GTK_MENU (menu->menu), | ||||
|                              gdkdevice, | ||||
|                              NULL, NULL, | ||||
|                              popup_position_func, pt, NULL, | ||||
|                              button, | ||||
|                              timestamp); | ||||
|  | ||||
|   if (!gtk_widget_get_visible (menu->menu)) | ||||
|     meta_warning ("GtkMenu failed to grab the pointer\n"); | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #define META_MENU_H | ||||
|  | ||||
| #include <gtk/gtk.h> | ||||
| #include <meta/device.h> | ||||
| #include "frames.h" | ||||
|  | ||||
| /* Stock icons */ | ||||
| @@ -52,6 +53,7 @@ MetaWindowMenu* meta_window_menu_new      (MetaFrames         *frames, | ||||
|                                            MetaWindowMenuFunc  func, | ||||
|                                            gpointer            data); | ||||
| void            meta_window_menu_popup    (MetaWindowMenu     *menu, | ||||
|                                            MetaDevice         *device, | ||||
|                                            int                 root_x, | ||||
|                                            int                 root_y, | ||||
|                                            int                 button, | ||||
|   | ||||
| @@ -852,12 +852,21 @@ static WnckWindowDisplayInfo | ||||
| meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen) | ||||
| { | ||||
|   WnckWindowDisplayInfo wnck_window; | ||||
|   MetaFocusInfo *focus_info; | ||||
|   GHashTableIter iter; | ||||
|  | ||||
|   wnck_window.icon = window->icon; | ||||
|   wnck_window.mini_icon = window->mini_icon; | ||||
|    | ||||
|   wnck_window.is_active = FALSE; | ||||
|   if (window == window->display->expected_focus_window) | ||||
|     wnck_window.is_active = TRUE; | ||||
|  | ||||
|   g_hash_table_iter_init (&iter, window->display->focus_info); | ||||
|  | ||||
|   while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &focus_info)) | ||||
|     { | ||||
|       if (window == focus_info->expected_focus_window) | ||||
|         wnck_window.is_active = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (window->frame) | ||||
|     { | ||||
|   | ||||
| @@ -171,6 +171,7 @@ meta_tile_preview_free (MetaTilePreview *preview) | ||||
|  | ||||
| void | ||||
| meta_tile_preview_show (MetaTilePreview *preview, | ||||
|                         MetaDevice      *pointer, | ||||
|                         MetaRectangle   *tile_rect) | ||||
| { | ||||
|   GdkWindow *window; | ||||
| @@ -187,6 +188,7 @@ meta_tile_preview_show (MetaTilePreview *preview, | ||||
|   window = gtk_widget_get_window (preview->preview_window); | ||||
|   meta_core_lower_beneath_grab_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), | ||||
|                                        GDK_WINDOW_XID (window), | ||||
|                                        meta_device_get_id (pointer), | ||||
|                                        gtk_get_current_event_time ()); | ||||
|  | ||||
|   old_rect.x = old_rect.y = 0; | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #define META_TILE_PREVIEW_H | ||||
|  | ||||
| #include <meta/boxes.h> | ||||
| #include <meta/device.h> | ||||
|  | ||||
| typedef struct _MetaTilePreview MetaTilePreview; | ||||
|  | ||||
| @@ -31,6 +32,7 @@ MetaTilePreview   *meta_tile_preview_new    (int                screen_number, | ||||
|                                              gboolean           composited); | ||||
| void               meta_tile_preview_free   (MetaTilePreview   *preview); | ||||
| void               meta_tile_preview_show   (MetaTilePreview   *preview, | ||||
|                                              MetaDevice        *pointer, | ||||
|                                              MetaRectangle     *rect); | ||||
| void               meta_tile_preview_hide   (MetaTilePreview   *preview); | ||||
| Window             meta_tile_preview_get_xwindow (MetaTilePreview   *preview, | ||||
|   | ||||
							
								
								
									
										111
									
								
								src/ui/ui.c
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								src/ui/ui.c
									
									
									
									
									
								
							| @@ -30,6 +30,7 @@ | ||||
| #include "menu.h" | ||||
| #include "core.h" | ||||
| #include "theme-private.h" | ||||
| #include "input-events.h" | ||||
|  | ||||
| #include "inlinepixbufs.h" | ||||
|  | ||||
| @@ -60,15 +61,8 @@ struct _MetaUI | ||||
| void | ||||
| meta_ui_init (void) | ||||
| { | ||||
|   /* As of 2.91.7, Gdk uses XI2 by default, which conflicts with the | ||||
|    * direct X calls we use - in particular, events caused by calls to | ||||
|    * XGrabPointer/XGrabKeyboard are no longer understood by GDK, while | ||||
|    * GDK will no longer generate the core XEvents we process. | ||||
|    * So at least for now, enforce the previous behavior. | ||||
|    */ | ||||
| #if GTK_CHECK_VERSION(2, 91, 7) | ||||
|   gdk_disable_multidevice (); | ||||
| #endif | ||||
|   if (meta_get_use_core_devices ()) | ||||
|     gdk_disable_multidevice (); | ||||
|  | ||||
|   if (!gtk_init_check (NULL, NULL)) | ||||
|     meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL)); | ||||
| @@ -107,23 +101,25 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|   GdkEvent *gevent; | ||||
|   GdkWindow *gdk_window; | ||||
|   Window window; | ||||
|   MetaDisplay *display; | ||||
|   MetaDevice *device; | ||||
|   gdouble x, y, x_root, y_root; | ||||
|   guint evtype, n_button; | ||||
|   Time evtime; | ||||
|  | ||||
|   switch (xevent->type) | ||||
|     { | ||||
|     case ButtonPress: | ||||
|     case ButtonRelease: | ||||
|       window = xevent->xbutton.window; | ||||
|       break; | ||||
|     case MotionNotify: | ||||
|       window = xevent->xmotion.window; | ||||
|       break; | ||||
|     case EnterNotify: | ||||
|     case LeaveNotify: | ||||
|       window = xevent->xcrossing.window; | ||||
|       break; | ||||
|     default: | ||||
|       return FALSE; | ||||
|     } | ||||
|   display = meta_display_for_x_display (xevent->xany.display); | ||||
|  | ||||
|   if (!meta_input_event_get_type (display, xevent, &evtype)) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (evtype != ButtonPress && | ||||
|       evtype != ButtonRelease && | ||||
|       evtype != EnterNotify && | ||||
|       evtype != LeaveNotify && | ||||
|       evtype != MotionNotify) | ||||
|     return FALSE; | ||||
|  | ||||
|   window = meta_input_event_get_window (display, xevent); | ||||
|  | ||||
|   gdisplay = gdk_x11_lookup_xdisplay (xevent->xany.display); | ||||
|   ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui"); | ||||
| @@ -134,8 +130,14 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|   if (gdk_window == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   device = meta_input_event_get_device (display, xevent); | ||||
|  | ||||
|   if (!device) | ||||
|     return FALSE; | ||||
|  | ||||
|   gmanager = gdk_display_get_device_manager (gdisplay); | ||||
|   gdevice = gdk_device_manager_get_client_pointer (gmanager); | ||||
|   gdevice = gdk_x11_device_manager_lookup (gmanager, | ||||
|                                            meta_device_get_id (device)); | ||||
|  | ||||
|   /* If GDK already thinks it has a grab, we better let it see events; this | ||||
|    * is the menu-navigation case and events need to get sent to the appropriate | ||||
| @@ -144,11 +146,16 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|   if (gdk_display_device_is_grabbed (gdisplay, gdevice)) | ||||
|     return FALSE; | ||||
|  | ||||
|   switch (xevent->type) | ||||
|   evtime = meta_input_event_get_time (display, xevent); | ||||
|   meta_input_event_get_coordinates (display, xevent, | ||||
|                                     &x, &y, &x_root, &y_root); | ||||
|   switch (evtype) | ||||
|     { | ||||
|     case ButtonPress: | ||||
|     case ButtonRelease: | ||||
|       if (xevent->type == ButtonPress) | ||||
|       meta_input_event_get_button (display, xevent, &n_button); | ||||
|  | ||||
|       if (evtype == ButtonPress) | ||||
|         { | ||||
|           GtkSettings *settings = gtk_settings_get_default (); | ||||
|           int double_click_time; | ||||
| @@ -159,11 +166,11 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|                         "gtk-double-click-distance", &double_click_distance, | ||||
|                         NULL); | ||||
|  | ||||
|           if (xevent->xbutton.button == ui->button_click_number && | ||||
|               xevent->xbutton.window == ui->button_click_window && | ||||
|               xevent->xbutton.time < ui->button_click_time + double_click_time && | ||||
|               ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance && | ||||
|               ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance) | ||||
|           if (n_button == ui->button_click_number && | ||||
|               window == ui->button_click_window && | ||||
|               evtime < ui->button_click_time + double_click_time && | ||||
|               ABS ((int) x - ui->button_click_x) <= double_click_distance && | ||||
|               ABS ((int) y - ui->button_click_y) <= double_click_distance) | ||||
|             { | ||||
|               gevent = gdk_event_new (GDK_2BUTTON_PRESS); | ||||
|  | ||||
| @@ -172,11 +179,11 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|           else | ||||
|             { | ||||
|               gevent = gdk_event_new (GDK_BUTTON_PRESS); | ||||
|               ui->button_click_number = xevent->xbutton.button; | ||||
|               ui->button_click_window = xevent->xbutton.window; | ||||
|               ui->button_click_time = xevent->xbutton.time; | ||||
|               ui->button_click_x = xevent->xbutton.x; | ||||
|               ui->button_click_y = xevent->xbutton.y; | ||||
|               ui->button_click_number = n_button; | ||||
|               ui->button_click_window = window; | ||||
|               ui->button_click_time = evtime; | ||||
|               ui->button_click_x = (int) x; | ||||
|               ui->button_click_y = (int) y; | ||||
|             } | ||||
|         } | ||||
|       else | ||||
| @@ -185,25 +192,29 @@ maybe_redirect_mouse_event (XEvent *xevent) | ||||
|         } | ||||
|  | ||||
|       gevent->button.window = g_object_ref (gdk_window); | ||||
|       gevent->button.button = xevent->xbutton.button; | ||||
|       gevent->button.time = xevent->xbutton.time; | ||||
|       gevent->button.x = xevent->xbutton.x; | ||||
|       gevent->button.y = xevent->xbutton.y; | ||||
|       gevent->button.x_root = xevent->xbutton.x_root; | ||||
|       gevent->button.y_root = xevent->xbutton.y_root; | ||||
|       gevent->button.button = n_button; | ||||
|       gevent->button.time = evtime; | ||||
|       gevent->button.x = x; | ||||
|       gevent->button.y = y; | ||||
|       gevent->button.x_root = x_root; | ||||
|       gevent->button.y_root = y_root; | ||||
|  | ||||
|       break; | ||||
|     case MotionNotify: | ||||
|       gevent = gdk_event_new (GDK_MOTION_NOTIFY); | ||||
|       gevent->motion.type = GDK_MOTION_NOTIFY; | ||||
|       gevent->motion.window = g_object_ref (gdk_window); | ||||
|       gevent->motion.x = x; | ||||
|       gevent->motion.y = y; | ||||
|       gevent->motion.x_root = x_root; | ||||
|       gevent->motion.y_root = y_root; | ||||
|       break; | ||||
|     case EnterNotify: | ||||
|     case LeaveNotify: | ||||
|       gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); | ||||
|       gevent = gdk_event_new (evtype == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); | ||||
|       gevent->crossing.window = g_object_ref (gdk_window); | ||||
|       gevent->crossing.x = xevent->xcrossing.x; | ||||
|       gevent->crossing.y = xevent->xcrossing.y; | ||||
|       gevent->crossing.x = x; | ||||
|       gevent->crossing.y = y; | ||||
|       break; | ||||
|     default: | ||||
|       g_assert_not_reached (); | ||||
| @@ -396,7 +407,8 @@ meta_ui_create_frame_window (MetaUI *ui, | ||||
| 		    &attrs, attributes_mask); | ||||
|  | ||||
|   gdk_window_resize (window, width, height); | ||||
|    | ||||
|   gdk_window_set_support_multidevice (window, TRUE); | ||||
|  | ||||
|   meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window); | ||||
|  | ||||
|   return GDK_WINDOW_XID (window); | ||||
| @@ -524,12 +536,13 @@ meta_ui_window_menu_new  (MetaUI             *ui, | ||||
|  | ||||
| void | ||||
| meta_ui_window_menu_popup (MetaWindowMenu     *menu, | ||||
|                            MetaDevice         *device, | ||||
|                            int                 root_x, | ||||
|                            int                 root_y, | ||||
|                            int                 button, | ||||
|                            guint32             timestamp) | ||||
| { | ||||
|   meta_window_menu_popup (menu, root_x, root_y, button, timestamp); | ||||
|   meta_window_menu_popup (menu, device, root_x, root_y, button, timestamp); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
|  | ||||
| /* Don't include gtk.h or gdk.h here */ | ||||
| #include <meta/common.h> | ||||
| #include <meta/device.h> | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/Xutil.h> | ||||
| #include <cairo.h> | ||||
| @@ -129,6 +130,7 @@ MetaWindowMenu* meta_ui_window_menu_new   (MetaUI             *ui, | ||||
|                                            MetaWindowMenuFunc  func, | ||||
|                                            gpointer            data); | ||||
| void            meta_ui_window_menu_popup (MetaWindowMenu     *menu, | ||||
|                                            MetaDevice         *device, | ||||
|                                            int                 root_x, | ||||
|                                            int                 root_y, | ||||
|                                            int                 button, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user