Compare commits
	
		
			72 Commits
		
	
	
		
			wip/cally-
			...
			wip/multit
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2e8682d607 | ||
| 
						 | 
					de0d9e4da8 | ||
| 
						 | 
					900b91f385 | ||
| 
						 | 
					7971d5a871 | ||
| 
						 | 
					c8f0a136cc | ||
| 
						 | 
					3b578c2983 | ||
| 
						 | 
					0142e34af8 | ||
| 
						 | 
					6439856800 | ||
| 
						 | 
					704e2320c3 | ||
| 
						 | 
					bbc69c4220 | ||
| 
						 | 
					6a03efe435 | ||
| 
						 | 
					85c1058c94 | ||
| 
						 | 
					91f87e8173 | ||
| 
						 | 
					052e8cc8e2 | ||
| 
						 | 
					827999aa82 | ||
| 
						 | 
					54a58bd9b8 | ||
| 
						 | 
					dc29985b80 | ||
| 
						 | 
					acbd4bf599 | ||
| 
						 | 
					b742d1bc64 | ||
| 
						 | 
					ae1290e3b4 | ||
| 
						 | 
					8037cc5ec4 | ||
| 
						 | 
					275ab901b0 | ||
| 
						 | 
					b3a9d1b39a | ||
| 
						 | 
					ac187476ae | ||
| 
						 | 
					f512da8c47 | ||
| 
						 | 
					2b47bffbee | ||
| 
						 | 
					8da5a01c92 | ||
| 
						 | 
					25dc04440b | ||
| 
						 | 
					7138cc7ea4 | ||
| 
						 | 
					04cbdb4e23 | ||
| 
						 | 
					e138726ded | ||
| 
						 | 
					84dfc98636 | ||
| 
						 | 
					95247457ef | ||
| 
						 | 
					9b1b7b71e2 | ||
| 
						 | 
					4facab385d | ||
| 
						 | 
					cc6dba2113 | ||
| 
						 | 
					5f6f67fb4e | ||
| 
						 | 
					0d97e6adeb | ||
| 
						 | 
					991fdeb9dd | ||
| 
						 | 
					df908e5256 | ||
| 
						 | 
					4b88c1c72a | ||
| 
						 | 
					33d4732bde | ||
| 
						 | 
					2bbd82ba51 | ||
| 
						 | 
					13acafabe2 | ||
| 
						 | 
					20537b9bb0 | ||
| 
						 | 
					373ef2e6f1 | ||
| 
						 | 
					93c7a22161 | ||
| 
						 | 
					9f06372e17 | ||
| 
						 | 
					b3ecd268f6 | ||
| 
						 | 
					c32ee410e9 | ||
| 
						 | 
					3584f38d08 | ||
| 
						 | 
					712d2feb73 | ||
| 
						 | 
					7b21bd8c6f | ||
| 
						 | 
					c7c1053ade | ||
| 
						 | 
					d7bd7c9a40 | ||
| 
						 | 
					96cdedf569 | ||
| 
						 | 
					8865578933 | ||
| 
						 | 
					1a29f2cd0f | ||
| 
						 | 
					324d9fdb14 | ||
| 
						 | 
					190037cd72 | ||
| 
						 | 
					a3ca52bf0f | ||
| 
						 | 
					29b5fd7fd7 | ||
| 
						 | 
					7a3d49b88e | ||
| 
						 | 
					3e3ad71a68 | ||
| 
						 | 
					1c3b695848 | ||
| 
						 | 
					e1379441d4 | ||
| 
						 | 
					d75f43f504 | ||
| 
						 | 
					de6dceb3ac | ||
| 
						 | 
					03ddc0cd94 | ||
| 
						 | 
					f440af2c02 | ||
| 
						 | 
					8b3ef16460 | ||
| 
						 | 
					7d587770f3 | 
							
								
								
									
										28
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								configure.in
									
									
									
									
									
								
							@@ -199,6 +199,33 @@ 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")
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
 | 
			
		||||
 | 
			
		||||
# This is used for plugins
 | 
			
		||||
@@ -468,6 +495,7 @@ mutter-$VERSION
 | 
			
		||||
	Shape extension:          ${found_shape}
 | 
			
		||||
	Xsync:                    ${found_xsync}
 | 
			
		||||
	Xcursor:                  ${have_xcursor}
 | 
			
		||||
	XInput2:                  ${have_xinput2}
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -75,6 +75,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				\
 | 
			
		||||
@@ -97,6 +111,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				\
 | 
			
		||||
@@ -151,6 +167,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)
 | 
			
		||||
 | 
			
		||||
@@ -161,6 +185,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;
 | 
			
		||||
@@ -533,12 +537,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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -239,6 +239,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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_flash_frame:
 | 
			
		||||
 * @display:  The display the bell event came in on
 | 
			
		||||
@@ -251,15 +280,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);
 | 
			
		||||
@@ -320,9 +345,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)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -1365,15 +1365,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 */
 | 
			
		||||
							
								
								
									
										327
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
			
		||||
/* -*- 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 2
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
  /* FIXME: Doesn't seem to work with
 | 
			
		||||
   * XIAllMasterDevices, use the VCK
 | 
			
		||||
   * at the moment
 | 
			
		||||
   */
 | 
			
		||||
  retval = XIGrabKeycode (display->xdisplay,
 | 
			
		||||
                          META_CORE_KEYBOARD_ID,
 | 
			
		||||
                          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,
 | 
			
		||||
                   META_CORE_KEYBOARD_ID,
 | 
			
		||||
                   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,
 | 
			
		||||
                  META_CORE_POINTER_ID,
 | 
			
		||||
                  //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 */
 | 
			
		||||
							
								
								
									
										420
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										420
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,420 @@
 | 
			
		||||
/* -*- 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 2
 | 
			
		||||
#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 = XINPUT2_VERSION_MAJOR;
 | 
			
		||||
  minor = XINPUT2_VERSION_MINOR;
 | 
			
		||||
 | 
			
		||||
  XIQueryVersion (display->xdisplay, &major, &minor);
 | 
			
		||||
 | 
			
		||||
  if (major == XINPUT2_VERSION_MAJOR &&
 | 
			
		||||
      minor == XINPUT2_VERSION_MINOR)
 | 
			
		||||
    {
 | 
			
		||||
      display->have_xinput2 = TRUE;
 | 
			
		||||
      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 */
 | 
			
		||||
							
								
								
									
										351
									
								
								src/core/devices-xi2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								src/core/devices-xi2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,351 @@
 | 
			
		||||
/* -*- 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (evmask & META_INPUT_TOUCH_EVENTS_MASK)
 | 
			
		||||
    {
 | 
			
		||||
      XISetMask (mask, XI_TouchBegin);
 | 
			
		||||
      XISetMask (mask, XI_TouchEnd);
 | 
			
		||||
      XISetMask (mask, XI_TouchUpdate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  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,79 @@ 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;
 | 
			
		||||
  MetaEdgeResistanceData *grab_edge_resistance_data;
 | 
			
		||||
 | 
			
		||||
#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 +182,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;
 | 
			
		||||
@@ -182,35 +246,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
 | 
			
		||||
@@ -221,11 +261,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;
 | 
			
		||||
@@ -272,6 +307,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;
 | 
			
		||||
 | 
			
		||||
@@ -295,6 +333,12 @@ struct _MetaDisplay
 | 
			
		||||
  int shape_event_base;
 | 
			
		||||
  int shape_error_base;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
  int xinput2_opcode;
 | 
			
		||||
  unsigned int have_xinput2 : 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XSYNC
 | 
			
		||||
  unsigned int have_xsync : 1;
 | 
			
		||||
#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
 | 
			
		||||
@@ -380,18 +424,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);
 | 
			
		||||
@@ -399,7 +449,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);
 | 
			
		||||
@@ -447,4 +498,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3002
									
								
								src/core/display.c
									
									
									
									
									
								
							
							
						
						
									
										3002
									
								
								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
 | 
			
		||||
@@ -382,8 +390,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);
 | 
			
		||||
    }
 | 
			
		||||
@@ -408,22 +415,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										813
									
								
								src/core/input-events.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										813
									
								
								src/core/input-events.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,813 @@
 | 
			
		||||
/* -*- 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;
 | 
			
		||||
        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;
 | 
			
		||||
        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_ignore (MetaDisplay *display,
 | 
			
		||||
                         XEvent      *ev)
 | 
			
		||||
{
 | 
			
		||||
  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:
 | 
			
		||||
          if (((XIDeviceEvent *) xev)->flags & XIPointerEmulated)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_input_event_get_touch_id (MetaDisplay *display,
 | 
			
		||||
                               XEvent      *ev,
 | 
			
		||||
                               guint       *touch_id)
 | 
			
		||||
{
 | 
			
		||||
  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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          {
 | 
			
		||||
            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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
          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 */
 | 
			
		||||
@@ -57,14 +57,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
											
										
									
								
							@@ -301,9 +301,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));
 | 
			
		||||
@@ -414,6 +417,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, &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_info (window->screen);
 | 
			
		||||
      xi = meta_screen_get_current_monitor_info (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_info (window->screen);
 | 
			
		||||
  
 | 
			
		||||
  xi = meta_screen_get_current_monitor_info (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;
 | 
			
		||||
 | 
			
		||||
@@ -158,8 +159,10 @@ void          meta_screen_foreach_window      (MetaScreen                 *scree
 | 
			
		||||
                                               gpointer                    data);
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
@@ -182,9 +185,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_info   (MetaScreen    *screen);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_current_monitor_info   (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,9 +37,11 @@
 | 
			
		||||
#include "workspace-private.h"
 | 
			
		||||
#include "keybindings-private.h"
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "xprops.h"
 | 
			
		||||
#include <meta/compositor.h>
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include "device-pointer.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/extensions/Xinerama.h>
 | 
			
		||||
 | 
			
		||||
@@ -621,7 +623,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;
 | 
			
		||||
@@ -736,15 +737,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"),
 | 
			
		||||
@@ -766,10 +767,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;
 | 
			
		||||
@@ -794,8 +795,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 =
 | 
			
		||||
@@ -930,7 +929,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);
 | 
			
		||||
@@ -954,6 +956,8 @@ meta_screen_free (MetaScreen *screen,
 | 
			
		||||
  
 | 
			
		||||
  g_free (screen->screen_name);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (screen->cursors);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (screen);
 | 
			
		||||
 | 
			
		||||
  XFlush (display->xdisplay);
 | 
			
		||||
@@ -1572,31 +1576,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
 | 
			
		||||
@@ -1850,8 +1856,20 @@ static gboolean
 | 
			
		||||
meta_screen_tile_preview_update_timeout (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen = data;
 | 
			
		||||
  MetaWindow *window = screen->display->grab_window;
 | 
			
		||||
  MetaWindow *window = 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;
 | 
			
		||||
 | 
			
		||||
@@ -1894,7 +1912,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);
 | 
			
		||||
@@ -1939,28 +1957,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,
 | 
			
		||||
@@ -2056,6 +2069,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;
 | 
			
		||||
@@ -2063,6 +2077,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
 | 
			
		||||
@@ -2077,7 +2094,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
 | 
			
		||||
      visited[i] = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  current = meta_screen_get_current_monitor_info (screen);
 | 
			
		||||
  current = meta_screen_get_current_monitor_info (screen, pointer);
 | 
			
		||||
  monitor_queue = g_queue_new ();
 | 
			
		||||
  g_queue_push_tail (monitor_queue, (gpointer) current);
 | 
			
		||||
  visited[current->number] = TRUE;
 | 
			
		||||
@@ -2144,11 +2161,12 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MetaMonitorInfo*
 | 
			
		||||
meta_screen_get_current_monitor_info (MetaScreen *screen)
 | 
			
		||||
meta_screen_get_current_monitor_info (MetaScreen *screen,
 | 
			
		||||
                                      MetaDevice *pointer)
 | 
			
		||||
{
 | 
			
		||||
    int monitor_index;
 | 
			
		||||
    monitor_index = meta_screen_get_current_monitor (screen);
 | 
			
		||||
    return &screen->monitor_infos[monitor_index];
 | 
			
		||||
  int monitor_index;
 | 
			
		||||
  monitor_index = meta_screen_get_current_monitor (screen, pointer);
 | 
			
		||||
  return &screen->monitor_infos[monitor_index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -2160,7 +2178,8 @@ meta_screen_get_current_monitor_info (MetaScreen *screen)
 | 
			
		||||
 * Return value: a monitor index
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
meta_screen_get_current_monitor (MetaScreen *screen)
 | 
			
		||||
meta_screen_get_current_monitor (MetaScreen *screen,
 | 
			
		||||
                                 MetaDevice *pointer)
 | 
			
		||||
{
 | 
			
		||||
  if (screen->n_monitor_infos == 1)
 | 
			
		||||
    return 0;
 | 
			
		||||
@@ -2170,24 +2189,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++)
 | 
			
		||||
@@ -3060,17 +3073,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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -274,13 +274,23 @@ meta_stack_update_window_tile_matches (MetaStack     *stack,
 | 
			
		||||
  g_list_free (windows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
@@ -303,6 +313,9 @@ get_standalone_layer (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaStackLayer layer;
 | 
			
		||||
  gboolean focused_transient = FALSE;
 | 
			
		||||
  MetaFocusInfo *focus_info;
 | 
			
		||||
  MetaDevice *keyboard;
 | 
			
		||||
  FocusedForeachData focused_data = { 0 };
 | 
			
		||||
 | 
			
		||||
  switch (window->type)
 | 
			
		||||
    {
 | 
			
		||||
@@ -326,20 +339,30 @@ get_standalone_layer (MetaWindow *window)
 | 
			
		||||
    case META_WINDOW_OVERRIDE_OTHER:
 | 
			
		||||
      layer = META_LAYER_OVERRIDE_REDIRECT;
 | 
			
		||||
      break;
 | 
			
		||||
    default:       
 | 
			
		||||
    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);
 | 
			
		||||
      focused_data.window = focus_info->expected_focus_window;
 | 
			
		||||
 | 
			
		||||
      meta_window_foreach_transient (window,
 | 
			
		||||
                                     is_focused_foreach,
 | 
			
		||||
                                     &focused_transient);
 | 
			
		||||
                                     &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 &&
 | 
			
		||||
                !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 && !META_WINDOW_MAXIMIZED (window))
 | 
			
		||||
        layer = META_LAYER_TOP;
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,7 @@ meta_topic_real_valist (MetaDebugTopic topic,
 | 
			
		||||
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
 | 
			
		||||
@@ -178,6 +179,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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,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;  
 | 
			
		||||
  
 | 
			
		||||
@@ -333,6 +337,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;
 | 
			
		||||
 | 
			
		||||
@@ -413,6 +426,18 @@ struct _MetaWindow
 | 
			
		||||
 | 
			
		||||
  /* The currently complementary tiled window, if any */
 | 
			
		||||
  MetaWindow *tile_match;
 | 
			
		||||
 | 
			
		||||
  /* 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
 | 
			
		||||
@@ -569,6 +594,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,
 | 
			
		||||
@@ -618,8 +644,10 @@ void meta_window_free_delete_dialog (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
@@ -641,11 +669,24 @@ 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);
 | 
			
		||||
gboolean meta_window_can_tile_side_by_side   (MetaWindow *window);
 | 
			
		||||
gboolean meta_window_can_tile_side_by_side   (MetaWindow *window,
 | 
			
		||||
                                              MetaDevice *pointer);
 | 
			
		||||
 | 
			
		||||
void meta_window_compute_tile_match (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
 | 
			
		||||
 
 | 
			
		||||
@@ -1438,6 +1438,13 @@ reload_transient_for (MetaWindow    *window,
 | 
			
		||||
  MetaWindow *parent = NULL;
 | 
			
		||||
  Window transient_for, old_transient_for;
 | 
			
		||||
 | 
			
		||||
  if (meta_window_appears_focused (window) && window->xtransient_for != None)
 | 
			
		||||
    meta_window_propagate_focus_appearance (window,
 | 
			
		||||
                                            window->focus_keyboard,
 | 
			
		||||
                                            FALSE);
 | 
			
		||||
 | 
			
		||||
  window->xtransient_for = None;
 | 
			
		||||
  
 | 
			
		||||
  if (value->type != META_PROP_VALUE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
      transient_for = value->v.xwindow;
 | 
			
		||||
@@ -1474,7 +1481,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;
 | 
			
		||||
@@ -1527,7 +1536,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1254
									
								
								src/core/window.c
									
									
									
									
									
								
							
							
						
						
									
										1254
									
								
								src/core/window.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -95,6 +95,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;
 | 
			
		||||
@@ -1198,6 +1217,7 @@ meta_workspace_get_name (MetaWorkspace *workspace)
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_workspace_focus_default_window (MetaWorkspace *workspace,
 | 
			
		||||
                                     MetaDevice    *pointer,
 | 
			
		||||
                                     MetaWindow    *not_this_one,
 | 
			
		||||
                                     guint32        timestamp)
 | 
			
		||||
{
 | 
			
		||||
@@ -1214,7 +1234,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
 | 
			
		||||
{
 | 
			
		||||
@@ -75,6 +76,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,
 | 
			
		||||
@@ -111,9 +115,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,
 | 
			
		||||
@@ -123,6 +148,7 @@ 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);
 | 
			
		||||
@@ -137,10 +163,23 @@ gboolean meta_display_add_keybinding    (MetaDisplay         *display,
 | 
			
		||||
gboolean meta_display_remove_keybinding (MetaDisplay         *display,
 | 
			
		||||
                                         const char          *name);
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -176,5 +215,6 @@ void meta_display_unmanage_screen (MetaDisplay *display,
 | 
			
		||||
                                   guint32      timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_display_clear_mouse_mode (MetaDisplay *display);
 | 
			
		||||
MetaDeviceMap * meta_display_get_device_map (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,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
 | 
			
		||||
 
 | 
			
		||||
@@ -254,6 +254,7 @@ typedef void (* MetaKeyHandlerFunc) (MetaDisplay    *display,
 | 
			
		||||
                                     MetaWindow     *window,
 | 
			
		||||
                                     XEvent         *event,
 | 
			
		||||
                                     MetaKeyBinding *binding,
 | 
			
		||||
                                     MetaDevice     *device,
 | 
			
		||||
                                     gpointer        user_data);
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaKeyHandler MetaKeyHandler;
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,8 @@ MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
 | 
			
		||||
 | 
			
		||||
int  meta_screen_get_n_monitors       (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_primary_monitor  (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_current_monitor  (MetaScreen    *screen);
 | 
			
		||||
int  meta_screen_get_current_monitor  (MetaScreen    *screen,
 | 
			
		||||
                                       MetaDevice    *pointer);
 | 
			
		||||
void meta_screen_get_monitor_geometry (MetaScreen    *screen,
 | 
			
		||||
                                       int            monitor,
 | 
			
		||||
                                       MetaRectangle *geometry);
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -189,6 +189,7 @@ void        meta_window_focus              (MetaWindow  *window,
 | 
			
		||||
                                            guint32      timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_window_begin_grab_op (MetaWindow *window,
 | 
			
		||||
                                MetaDevice *device,
 | 
			
		||||
                                MetaGrabOp  op,
 | 
			
		||||
                                gboolean    frame_action,
 | 
			
		||||
                                guint32     timestamp);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										155
									
								
								src/ui/frames.c
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/ui/frames.c
									
									
									
									
									
								
							@@ -51,6 +51,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);
 | 
			
		||||
@@ -637,10 +638,12 @@ meta_frames_unmanage_window (MetaFrames *frames,
 | 
			
		||||
 | 
			
		||||
  if (frame)
 | 
			
		||||
    {
 | 
			
		||||
#if 0
 | 
			
		||||
      /* 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);
 | 
			
		||||
 | 
			
		||||
@@ -1046,10 +1049,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 G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
 | 
			
		||||
@@ -1131,12 +1136,14 @@ meta_frame_titlebar_event (MetaUIFrame    *frame,
 | 
			
		||||
    case G_DESKTOP_TITLEBAR_ACTION_LOWER:
 | 
			
		||||
      meta_core_user_lower_and_unfocus (display,
 | 
			
		||||
                                        frame->xwindow,
 | 
			
		||||
                                        gdk_x11_device_get_id (pointer),
 | 
			
		||||
                                        event->time);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case G_DESKTOP_TITLEBAR_ACTION_MENU:
 | 
			
		||||
      meta_core_show_window_menu (display,
 | 
			
		||||
                                  frame->xwindow,
 | 
			
		||||
                                  gdk_x11_device_get_id (pointer),
 | 
			
		||||
                                  event->x_root,
 | 
			
		||||
                                  event->y_root,
 | 
			
		||||
                                  event->button,
 | 
			
		||||
@@ -1182,7 +1189,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 ());
 | 
			
		||||
 | 
			
		||||
@@ -1213,7 +1222,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.
 | 
			
		||||
   */
 | 
			
		||||
@@ -1221,13 +1233,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 ||
 | 
			
		||||
@@ -1286,6 +1298,7 @@ meta_frames_button_press_event (GtkWidget      *widget,
 | 
			
		||||
 | 
			
		||||
      meta_core_begin_grab_op (display,
 | 
			
		||||
                               frame->xwindow,
 | 
			
		||||
                               device_id,
 | 
			
		||||
                               op,
 | 
			
		||||
                               TRUE,
 | 
			
		||||
                               TRUE,
 | 
			
		||||
@@ -1318,6 +1331,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,
 | 
			
		||||
@@ -1371,6 +1385,7 @@ meta_frames_button_press_event (GtkWidget      *widget,
 | 
			
		||||
 | 
			
		||||
      meta_core_begin_grab_op (display,
 | 
			
		||||
                               frame->xwindow,
 | 
			
		||||
                               device_id,
 | 
			
		||||
                               op,
 | 
			
		||||
                               TRUE,
 | 
			
		||||
                               TRUE,
 | 
			
		||||
@@ -1393,6 +1408,7 @@ meta_frames_button_press_event (GtkWidget      *widget,
 | 
			
		||||
        {          
 | 
			
		||||
          meta_core_begin_grab_op (display,
 | 
			
		||||
                                   frame->xwindow,
 | 
			
		||||
                                   device_id,
 | 
			
		||||
                                   META_GRAB_OP_MOVING,
 | 
			
		||||
                                   TRUE,
 | 
			
		||||
                                   TRUE,
 | 
			
		||||
@@ -1416,28 +1432,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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1450,7 +1466,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 ());
 | 
			
		||||
  
 | 
			
		||||
@@ -1458,17 +1477,21 @@ meta_frames_button_release_event    (GtkWidget           *widget,
 | 
			
		||||
  if (frame == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
@@ -1479,8 +1502,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:
 | 
			
		||||
@@ -1492,67 +1515,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:
 | 
			
		||||
@@ -1564,7 +1587,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;
 | 
			
		||||
@@ -1573,12 +1598,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);
 | 
			
		||||
  
 | 
			
		||||
@@ -1643,6 +1668,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)
 | 
			
		||||
@@ -1696,8 +1722,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:
 | 
			
		||||
@@ -1713,10 +1739,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
 | 
			
		||||
@@ -1747,21 +1772,23 @@ 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);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    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);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
@@ -1909,7 +1936,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;
 | 
			
		||||
@@ -1920,11 +1946,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)
 | 
			
		||||
    {
 | 
			
		||||
@@ -2085,7 +2108,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;
 | 
			
		||||
}
 | 
			
		||||
@@ -2103,7 +2128,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);
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +156,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,
 | 
			
		||||
 
 | 
			
		||||
@@ -855,12 +855,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)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -148,6 +148,7 @@ meta_tile_preview_free (MetaTilePreview *preview)
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_tile_preview_show (MetaTilePreview *preview,
 | 
			
		||||
                        MetaDevice      *pointer,
 | 
			
		||||
                        MetaRectangle   *tile_rect)
 | 
			
		||||
{
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
@@ -164,6 +165,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,12 +24,14 @@
 | 
			
		||||
#define META_TILE_PREVIEW_H
 | 
			
		||||
 | 
			
		||||
#include <meta/boxes.h>
 | 
			
		||||
#include <meta/device.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaTilePreview MetaTilePreview;
 | 
			
		||||
 | 
			
		||||
MetaTilePreview   *meta_tile_preview_new    (int                screen_number);
 | 
			
		||||
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));
 | 
			
		||||
@@ -113,23 +107,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");
 | 
			
		||||
@@ -140,8 +136,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
 | 
			
		||||
@@ -150,11 +152,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;
 | 
			
		||||
@@ -165,11 +172,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);
 | 
			
		||||
 | 
			
		||||
@@ -178,11 +185,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
 | 
			
		||||
@@ -191,25 +198,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 ();
 | 
			
		||||
@@ -402,7 +413,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);
 | 
			
		||||
@@ -530,12 +542,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>
 | 
			
		||||
@@ -131,6 +132,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