<commit_before>/* GDK - The GIMP Drawing Kit
 * Copyright (C) 2009 <NAME> <<EMAIL>>
 *
 * 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/>.
 */

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include "config.h"

#include <string.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdktypes.h>
#include "gdkprivate-wayland.h"
#include "gdkwayland.h"
#include "gdkkeysyms.h"
#include "gdkdeviceprivate.h"
#include "gdkdevicemanagerprivate.h"
#include "gdkprivate-wayland.h"

#include <xkbcommon/xkbcommon.h>
#include <X11/keysym.h>

#include <sys/time.h>
#include <sys/mman.h>

typedef struct _GdkWaylandDeviceData GdkWaylandDeviceData;

typedef struct _DataOffer DataOffer;

typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;

struct _GdkWaylandDeviceData
{
  struct wl_seat *wl_seat;
  struct wl_pointer *wl_pointer;
  struct wl_keyboard *wl_keyboard;

  GdkDisplay *display;
  GdkDeviceManager *device_manager;

  GdkDevice *pointer;
  GdkDevice *keyboard;

  GdkKeymap *keymap;

  GdkModifierType modifiers;
  GdkWindow *pointer_focus;
  GdkWindow *keyboard_focus;
  struct wl_data_device *data_device;
  double surface_x, surface_y;
  uint32_t time;
  GdkWindow *pointer_grab_window;
  uint32_t pointer_grab_time;
  guint32 repeat_timer;
  guint32 repeat_key;
  guint32 repeat_count;

  DataOffer *drag_offer;
  DataOffer *selection_offer;

  GdkWaylandSelectionOffer *selection_offer_out;

  struct wl_surface *pointer_surface;
};

struct _GdkWaylandDevice
{
  GdkDevice parent_instance;
  GdkWaylandDeviceData *device;
};

struct _GdkWaylandDeviceClass
{
  GdkDeviceClass parent_class;
};

G_DEFINE_TYPE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE)

#define GDK_TYPE_WAYLAND_DEVICE_MANAGER        (gdk_wayland_device_manager_get_type ())
#define GDK_WAYLAND_DEVICE_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManager))
#define GDK_WAYLAND_DEVICE_MANAGER_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))
#define GDK_IS_WAYLAND_DEVICE_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
#define GDK_IS_WAYLAND_DEVICE_MANAGER_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
#define GDK_WAYLAND_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))

typedef struct _GdkWaylandDeviceManager GdkWaylandDeviceManager;
typedef struct _GdkWaylandDeviceManagerClass GdkWaylandDeviceManagerClass;

struct _GdkWaylandDeviceManager
{
  GdkDeviceManager parent_object;
  GdkDevice *core_pointer;
  GdkDevice *core_keyboard;
  GList *devices;
};

struct _GdkWaylandDeviceManagerClass
{
  GdkDeviceManagerClass parent_class;
};

G_DEFINE_TYPE (GdkWaylandDeviceManager,
	       gdk_wayland_device_manager, GDK_TYPE_DEVICE_MANAGER)

static gboolean
gdk_wayland_device_get_history (GdkDevice      *device,
                                GdkWindow      *window,
                                guint32         start,
                                guint32         stop,
                                GdkTimeCoord ***events,
                                gint           *n_events)
{
  return FALSE;
}

static void
gdk_wayland_device_get_state (GdkDevice       *device,
                              GdkWindow       *window,
                              gdouble         *axes,
                              GdkModifierType *mask)
{
  gint x_int, y_int;

  gdk_window_get_device_position (window, device, &x_int, &y_int, mask);

  if (axes)
    {
      axes[0] = x_int;
      axes[1] = y_int;
    }
}

static void
gdk_wayland_device_set_window_cursor (GdkDevice *device,
                                      GdkWindow *window,
                                      GdkCursor *cursor)
{
  GdkWaylandDeviceData *wd = GDK_WAYLAND_DEVICE(device)->device;
  GdkWaylandDisplay *wayland_display =
    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
  struct wl_buffer *buffer;
  int x, y, w, h;

  if (cursor)
    g_object_ref (cursor);

  /* Setting the cursor to NULL means that we should use the default cursor */
  if (!cursor)
    {
      /* FIXME: Is this the best sensible default ? */
      cursor = _gdk_wayland_display_get_cursor_for_type (device->display,
                                                         GDK_LEFT_PTR);
    }

  buffer = _gdk_wayland_cursor_get_buffer (cursor, &x, &y, &w, &h);
  wl_pointer_set_cursor (wd->wl_pointer,
                         _gdk_wayland_display_get_serial (wayland_display),
                         wd->pointer_surface,
                         x, y);
  wl_surface_attach (wd->pointer_surface, buffer, 0, 0);
  wl_surface_damage (wd->pointer_surface,  0, 0, w, h);
  wl_surface_commit(wd->pointer_surface);

  g_object_unref (cursor);
}

static void
gdk_wayland_device_warp (GdkDevice *device,
                         GdkScreen *screen,
                         gint       x,
                         gint       y)
{
}

static void
gdk_wayland_device_query_state (GdkDevice        *device,
                                GdkWindow        *window,
                                GdkWindow       **root_window,
                                GdkWindow       **child_window,
                                gint             *root_x,
                                gint             *root_y,
                                gint             *win_x,
                                gint             *win_y,
                                GdkModifierType  *mask)
{
  GdkWaylandDeviceData *wd;
  GdkScreen *default_screen;

  wd = GDK_WAYLAND_DEVICE(device)->device;<commit_msg>wayland: Keep hotspot when changing cursors<commit_after>/* GDK - The GIMP Drawing Kit
 * Copyright (C) 2009 <NAME> <<EMAIL>>
 *
 * 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/>.
 */

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include "config.h"

#include <string.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdktypes.h>
#include "gdkprivate-wayland.h"
#include "gdkwayland.h"
#include "gdkkeysyms.h"
#include "gdkdeviceprivate.h"
#include "gdkdevicemanagerprivate.h"
#include "gdkprivate-wayland.h"

#include <xkbcommon/xkbcommon.h>
#include <X11/keysym.h>

#include <sys/time.h>
#include <sys/mman.h>

typedef struct _GdkWaylandDeviceData GdkWaylandDeviceData;

typedef struct _DataOffer DataOffer;

typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;

struct _GdkWaylandDeviceData
{
  struct wl_seat *wl_seat;
  struct wl_pointer *wl_pointer;
  struct wl_keyboard *wl_keyboard;

  GdkDisplay *display;
  GdkDeviceManager *device_manager;

  GdkDevice *pointer;
  GdkDevice *keyboard;

  GdkKeymap *keymap;

  GdkModifierType modifiers;
  GdkWindow *pointer_focus;
  GdkWindow *keyboard_focus;
  struct wl_data_device *data_device;
  double surface_x, surface_y;
  uint32_t time;
  GdkWindow *pointer_grab_window;
  uint32_t pointer_grab_time;
  guint32 repeat_timer;
  guint32 repeat_key;
  guint32 repeat_count;

  DataOffer *drag_offer;
  DataOffer *selection_offer;

  GdkWaylandSelectionOffer *selection_offer_out;

  struct wl_surface *pointer_surface;
  int hotspot_x, hotspot_y;
};

struct _GdkWaylandDevice
{
  GdkDevice parent_instance;
  GdkWaylandDeviceData *device;
};

struct _GdkWaylandDeviceClass
{
  GdkDeviceClass parent_class;
};

G_DEFINE_TYPE (GdkWaylandDevice, gdk_wayland_device, GDK_TYPE_DEVICE)

#define GDK_TYPE_WAYLAND_DEVICE_MANAGER        (gdk_wayland_device_manager_get_type ())
#define GDK_WAYLAND_DEVICE_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManager))
#define GDK_WAYLAND_DEVICE_MANAGER_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))
#define GDK_IS_WAYLAND_DEVICE_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
#define GDK_IS_WAYLAND_DEVICE_MANAGER_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_WAYLAND_DEVICE_MANAGER))
#define GDK_WAYLAND_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_WAYLAND_DEVICE_MANAGER, GdkWaylandDeviceManagerClass))

typedef struct _GdkWaylandDeviceManager GdkWaylandDeviceManager;
typedef struct _GdkWaylandDeviceManagerClass GdkWaylandDeviceManagerClass;

struct _GdkWaylandDeviceManager
{
  GdkDeviceManager parent_object;
  GdkDevice *core_pointer;
  GdkDevice *core_keyboard;
  GList *devices;
};

struct _GdkWaylandDeviceManagerClass
{
  GdkDeviceManagerClass parent_class;
};

G_DEFINE_TYPE (GdkWaylandDeviceManager,
	       gdk_wayland_device_manager, GDK_TYPE_DEVICE_MANAGER)

static gboolean
gdk_wayland_device_get_history (GdkDevice      *device,
                                GdkWindow      *window,
                                guint32         start,
                                guint32         stop,
                                GdkTimeCoord ***events,
                                gint           *n_events)
{
  return FALSE;
}

static void
gdk_wayland_device_get_state (GdkDevice       *device,
                              GdkWindow       *window,
                              gdouble         *axes,
                              GdkModifierType *mask)
{
  gint x_int, y_int;

  gdk_window_get_device_position (window, device, &x_int, &y_int, mask);

  if (axes)
    {
      axes[0] = x_int;
      axes[1] = y_int;
    }
}

static void
gdk_wayland_device_set_window_cursor (GdkDevice *device,
                                      GdkWindow *window,
                                      GdkCursor *cursor)
{
  GdkWaylandDeviceData *wd = GDK_WAYLAND_DEVICE(device)->device;
  GdkWaylandDisplay *wayland_display =
    GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
  struct wl_buffer *buffer;
  int x, y, w, h;

  if (cursor)
    g_object_ref (cursor);

  /* Setting the cursor to NULL means that we should use the default cursor */
  if (!cursor)
    {
      /* FIXME: Is this the best sensible default ? */
      cursor = _gdk_wayland_display_get_cursor_for_type (device->display,
                                                         GDK_LEFT_PTR);
    }

  buffer = _gdk_wayland_cursor_get_buffer (cursor, &x, &y, &w, &h);
  wl_pointer_set_cursor (wd->wl_pointer,
                         _gdk_wayland_display_get_serial (wayland_display),
                         wd->pointer_surface,
                         x, y);
  wl_surface_attach (wd->pointer_surface, buffer, wd->hotspot_x - x, wd->hotspot_y - y);
  wl_surface_damage (wd->pointer_surface,  0, 0, w, h);
  wl_surface_commit(wd->pointer_surface);

  wd->hotspot_x = x;
  wd->hotspot_y = y;

  g_object_unref (cursor);
}

static void
gdk_wayland_device_warp (GdkDevice *device,
                         GdkScreen *screen,
                         gint       x,
                         gint       y)
{
}

static void
gdk_wayland_device_query_state (GdkDevice        *device,
                                GdkWindow        *window,
                                GdkWindow       **root_window,
                                GdkWindow       **child_window,
                                gint             *root_x,
                                gint             *root_y,
                                gint             *win_x,
                                gint             *win_y,
                                GdkModifierType  *mask)
{
  GdkWaylandDeviceData *wd;
  GdkScreen *default_screen;

  wd = GDK_WAYLAND_DEVICE(device)->device;
{'fraction_non_alphanumeric': 0.07392084927015846, 'fraction_numerical': 0.004059011786745765, 'mean_word_length': 2.6794945433658817, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6321205', 'n_tokens_mistral': 4335, 'n_tokens_neox': 4139, 'n_words': 913}