242 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GDK - The GIMP Drawing Kit
 | |
|  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library 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
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include "config.h"
 | |
| 
 | |
| #include <gdk/gdkwindow.h>
 | |
| 
 | |
| #include <windowsx.h>
 | |
| #include <objbase.h>
 | |
| 
 | |
| #include "gdkdisplayprivate.h"
 | |
| #include "gdkdevice-virtual.h"
 | |
| #include "gdkdevice-win32.h"
 | |
| #include "gdkwin32.h"
 | |
| 
 | |
| G_DEFINE_TYPE (GdkDeviceVirtual, gdk_device_virtual, GDK_TYPE_DEVICE)
 | |
| 
 | |
| void
 | |
| _gdk_device_virtual_set_active (GdkDevice *device,
 | |
| 				GdkDevice *new_active)
 | |
| {
 | |
|   GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
 | |
|   int n_axes, i;
 | |
|   GdkAtom label_atom;
 | |
|   GdkAxisUse use;
 | |
|   gdouble min_value, max_value, resolution;
 | |
| 
 | |
|   if (virtual->active_device == new_active)
 | |
|     return;
 | |
| 
 | |
|   virtual->active_device = new_active;
 | |
| 
 | |
|   if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
 | |
|     {
 | |
|       _gdk_device_reset_axes (device);
 | |
|       n_axes = gdk_device_get_n_axes (new_active);
 | |
|       for (i = 0; i < n_axes; i++)
 | |
| 	{
 | |
| 	  _gdk_device_get_axis_info (new_active, i,
 | |
| 				     &label_atom, &use,
 | |
| 				     &min_value, &max_value, &resolution);
 | |
| 	  _gdk_device_add_axis (device,
 | |
| 				label_atom, use,
 | |
| 				min_value, max_value, resolution);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   g_signal_emit_by_name (G_OBJECT (device), "changed");
 | |
| }
 | |
| 
 | |
| static gboolean
 | |
| gdk_device_virtual_get_history (GdkDevice      *device,
 | |
| 				GdkWindow      *window,
 | |
| 				guint32         start,
 | |
| 				guint32         stop,
 | |
| 				GdkTimeCoord ***events,
 | |
| 				gint           *n_events)
 | |
| {
 | |
|   /* History is only per slave device */
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_get_state (GdkDevice       *device,
 | |
| 			      GdkWindow       *window,
 | |
| 			      gdouble         *axes,
 | |
| 			      GdkModifierType *mask)
 | |
| {
 | |
|   GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
 | |
|   GdkDevice *active = virtual->active_device;
 | |
| 
 | |
|   GDK_DEVICE_GET_CLASS (active)->get_state (active,
 | |
| 					    window, axes, mask);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_set_window_cursor (GdkDevice *device,
 | |
| 				      GdkWindow *window,
 | |
| 				      GdkCursor *cursor)
 | |
| {
 | |
|   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 | |
|   GdkCursor *previous_cursor = impl->cursor;
 | |
| 
 | |
|   if (cursor != NULL && GDK_WIN32_CURSOR (cursor)->hcursor != NULL)
 | |
|     {
 | |
|       SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
 | |
|     }
 | |
|   else if (previous_cursor != NULL &&
 | |
|            GetCursor () == GDK_WIN32_CURSOR (previous_cursor)->hcursor)
 | |
|     {
 | |
|       /* The caller will unref previous_cursor shortly,
 | |
|        * but it holds the handle to currently-used cursor,
 | |
|        * and we can't call SetCursor(NULL).
 | |
|        */
 | |
|       g_warning (G_STRLOC ": Refusing to replace cursor %p (handle %p) with NULL. "
 | |
|                  "Expect ugly results.",
 | |
|                  previous_cursor, GDK_WIN32_CURSOR (previous_cursor)->hcursor);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       /* Up the stack all effors were made already to ensure that
 | |
|        * the "cursor" argument is non-NULL.
 | |
|        * If it is, calling SetCursor(NULL) is absolutely not
 | |
|        * the right decision, so we just warn and bail out.
 | |
|        */
 | |
|       g_warning (G_STRLOC ": Refusing to set NULL cursor");
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_warp (GdkDevice *device,
 | |
| 			 GdkScreen *screen,
 | |
| 			 gdouble   x,
 | |
| 			 gdouble   y)
 | |
| {
 | |
|   SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_query_state (GdkDevice        *device,
 | |
| 				GdkWindow        *window,
 | |
| 				GdkWindow       **root_window,
 | |
| 				GdkWindow       **child_window,
 | |
| 				gdouble          *root_x,
 | |
| 				gdouble          *root_y,
 | |
| 				gdouble          *win_x,
 | |
| 				gdouble          *win_y,
 | |
| 				GdkModifierType  *mask)
 | |
| {
 | |
|   GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
 | |
| 
 | |
|   _gdk_device_query_state (virtual->active_device,
 | |
| 			   window, root_window, child_window,
 | |
| 			   root_x, root_y,
 | |
| 			   win_x, win_y,
 | |
| 			   mask);
 | |
| }
 | |
| 
 | |
| static GdkGrabStatus
 | |
| gdk_device_virtual_grab (GdkDevice    *device,
 | |
| 			 GdkWindow    *window,
 | |
| 			 gboolean      owner_events,
 | |
| 			 GdkEventMask  event_mask,
 | |
| 			 GdkWindow    *confine_to,
 | |
| 			 GdkCursor    *cursor,
 | |
| 			 guint32       time_)
 | |
| {
 | |
|   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 | |
| 
 | |
|   if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
 | |
|     {
 | |
|       if (_gdk_win32_grab_cursor != NULL)
 | |
| 	{
 | |
| 	  if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
 | |
| 	    SetCursor (NULL);
 | |
| 	}
 | |
| 
 | |
|       g_set_object (&_gdk_win32_grab_cursor, cursor);
 | |
| 
 | |
|       if (_gdk_win32_grab_cursor != NULL)
 | |
| 	SetCursor (GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor);
 | |
|       else if (impl->cursor != NULL)
 | |
| 	SetCursor (GDK_WIN32_CURSOR (impl->cursor)->hcursor);
 | |
|       else
 | |
| 	SetCursor (LoadCursor (NULL, IDC_ARROW));
 | |
| 
 | |
|       SetCapture (GDK_WINDOW_HWND (window));
 | |
|     }
 | |
| 
 | |
|   return GDK_GRAB_SUCCESS;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_ungrab (GdkDevice *device,
 | |
|                          guint32    time_)
 | |
| {
 | |
|   GdkDeviceGrabInfo *info;
 | |
|   GdkDisplay *display;
 | |
| 
 | |
|   display = gdk_device_get_display (device);
 | |
|   info = _gdk_display_get_last_device_grab (display, device);
 | |
| 
 | |
|   if (info)
 | |
|     info->serial_end = 0;
 | |
| 
 | |
|   if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
 | |
|     {
 | |
|       if (_gdk_win32_grab_cursor != NULL)
 | |
| 	{
 | |
| 	  if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
 | |
| 	    SetCursor (NULL);
 | |
| 	}
 | |
|       g_clear_object (&_gdk_win32_grab_cursor);
 | |
| 
 | |
|       ReleaseCapture ();
 | |
|     }
 | |
| 
 | |
|   _gdk_display_device_grab_update (display, device, device, 0);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_select_window_events (GdkDevice    *device,
 | |
| 					 GdkWindow    *window,
 | |
| 					 GdkEventMask  event_mask)
 | |
| {
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_class_init (GdkDeviceVirtualClass *klass)
 | |
| {
 | |
|   GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
 | |
| 
 | |
|   device_class->get_history = gdk_device_virtual_get_history;
 | |
|   device_class->get_state = gdk_device_virtual_get_state;
 | |
|   device_class->set_window_cursor = gdk_device_virtual_set_window_cursor;
 | |
|   device_class->warp = gdk_device_virtual_warp;
 | |
|   device_class->query_state = gdk_device_virtual_query_state;
 | |
|   device_class->grab = gdk_device_virtual_grab;
 | |
|   device_class->ungrab = gdk_device_virtual_ungrab;
 | |
|   device_class->window_at_position = _gdk_device_win32_window_at_position;
 | |
|   device_class->select_window_events = gdk_device_virtual_select_window_events;
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_device_virtual_init (GdkDeviceVirtual *device_virtual)
 | |
| {
 | |
| }
 | 
