Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Gnome/gdk/   (Gnome Linux Desktop Version 4.23.2©)  Datei vom 30.5.2026 mit Größe 11 kB image not shown  

Quelle  gdkseat.c

  Sprache: C
 

/* GDK - The GIMP Drawing Kit
 * Copyright (C) 2015 Red Hat
 *
 * 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/>.
 *
 * Author: Carlos Garnacho <carlosg@gnome.org>
 */


#include "config.h"

#include <glib-object.h>
#include "gdkdisplay.h"
#include "gdkdevice.h"
#include "gdkdevicetoolprivate.h"
#include "gdkeventsprivate.h"
#include "gdkseatprivate.h"
#include "gdksurfaceprivate.h"
#include "gdkdeviceprivate.h"
#include <glib/gi18n-lib.h>

/**
 * GdkSeat:
 *
 * Represents a collection of input devices that belong to a user.
 */


typedef struct _GdkSeatPrivate GdkSeatPrivate;

struct _GdkSeatPrivate
{
  GdkDisplay *display;
  GList *grabs;
};

enum {
  DEVICE_ADDED,
  DEVICE_REMOVED,
  TOOL_ADDED,
  TOOL_REMOVED,
  N_SIGNALS
};

enum {
  PROP_0,
  PROP_DISPLAY,
  N_PROPS
};

static guint signals[N_SIGNALS] = { 0 };
static GParamSpec *props[N_PROPS] = { NULL };

G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkSeat, gdk_seat, G_TYPE_OBJECT)

static void
gdk_seat_set_property (GObject      *object,
                       guint         prop_id,
                       const GValue *value,
                       GParamSpec   *pspec)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (GDK_SEAT (object));

  switch (prop_id)
    {
    case PROP_DISPLAY:
      priv->display = g_value_get_object (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
gdk_seat_get_property (GObject    *object,
                       guint       prop_id,
                       GValue     *value,
                       GParamSpec *pspec)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (GDK_SEAT (object));

  switch (prop_id)
    {
    case PROP_DISPLAY:
      g_value_set_object (value, priv->display);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
gdk_seat_class_init (GdkSeatClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->set_property = gdk_seat_set_property;
  object_class->get_property = gdk_seat_get_property;

  /**
   * GdkSeat::device-added:
   * @seat: the object on which the signal is emitted
   * @device: the newly added `GdkDevice`.
   *
   * Emitted when a new input device is related to this seat.
   */

  signals [DEVICE_ADDED] =
    g_signal_new (g_intern_static_string ("device-added"),
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GdkSeatClass, device_added),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 1,
                  GDK_TYPE_DEVICE);

  /**
   * GdkSeat::device-removed:
   * @seat: the object on which the signal is emitted
   * @device: the just removed `GdkDevice`.
   *
   * Emitted when an input device is removed (e.g. unplugged).
   */

  signals [DEVICE_REMOVED] =
    g_signal_new (g_intern_static_string ("device-removed"),
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GdkSeatClass, device_removed),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 1,
                  GDK_TYPE_DEVICE);

  /**
   * GdkSeat::tool-added:
   * @seat: the object on which the signal is emitted
   * @tool: the new `GdkDeviceTool` known to the seat
   *
   * Emitted whenever a new tool is made known to the seat.
   *
   * The tool may later be assigned to a device (i.e. on
   * proximity with a tablet). The device will emit the
   * [signal@Gdk.Device::tool-changed] signal accordingly.
   *
   * A same tool may be used by several devices.
   */

  signals [TOOL_ADDED] =
    g_signal_new (g_intern_static_string ("tool-added"),
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  0, NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 1,
                  GDK_TYPE_DEVICE_TOOL);

  /**
   * GdkSeat::tool-removed:
   * @seat: the object on which the signal is emitted
   * @tool: the just removed `GdkDeviceTool`
   *
   * Emitted whenever a tool is no longer known to this @seat.
   */

  signals [TOOL_REMOVED] =
    g_signal_new (g_intern_static_string ("tool-removed"),
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  0, NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 1,
                  GDK_TYPE_DEVICE_TOOL);

  /**
   * GdkSeat:display:
   *
   * `GdkDisplay` of this seat.
   */

  props[PROP_DISPLAY] =
    g_param_spec_object ("display", NULL, NULL,
                         GDK_TYPE_DISPLAY,
                         G_PARAM_READWRITE |
                         G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_STATIC_NAME);

  g_object_class_install_properties (object_class, N_PROPS, props);
}

static void
gdk_seat_init (GdkSeat *seat)
{
}

/**
 * gdk_seat_get_capabilities:
 * @seat: a `GdkSeat`
 *
 * Returns the capabilities this `GdkSeat` currently has.
 *
 * Returns: the seat capabilities
 */

GdkSeatCapabilities
gdk_seat_get_capabilities (GdkSeat *seat)
{
  GdkSeatClass *seat_class;

  g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_SEAT_CAPABILITY_NONE);

  seat_class = GDK_SEAT_GET_CLASS (seat);
  return seat_class->get_capabilities (seat);
}

GdkGrabStatus
gdk_seat_grab (GdkSeat    *seat,
               GdkSurface *surface)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat);
  GdkSeatClass *seat_class;
  GdkGrabStatus status;

  g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_GRAB_FAILED);
  g_return_val_if_fail (GDK_IS_SURFACE (surface), GDK_GRAB_FAILED);
  g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_seat_get_display (seat), GDK_GRAB_FAILED);

  seat_class = GDK_SEAT_GET_CLASS (seat);

  status = seat_class->grab (seat, surface);

  if (status == GDK_GRAB_SUCCESS)
    priv->grabs = g_list_prepend (priv->grabs, g_object_ref (surface));

  return status;
}

/*
 * gdk_seat_ungrab:
 * @seat: a `GdkSeat`
 *
 * Releases a grab.
 *
 * See [method@Gdk.Seat.grab] for more information.
 */

void
gdk_seat_ungrab (GdkSeat    *seat,
                 GdkSurface *surface)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat);
  GdkSeatClass *seat_class;
  GdkSurface *grab_surface;

  g_return_if_fail (GDK_IS_SEAT (seat));

  seat_class = GDK_SEAT_GET_CLASS (seat);
  seat_class->ungrab (seat, surface);

  if (!priv->grabs)
    {
      g_warning ("Unpaired ungrab call");
      return;
    }

  grab_surface = priv->grabs->data;
  priv->grabs = g_list_remove (priv->grabs, grab_surface);
  g_clear_object (&grab_surface);
}

/**
 * gdk_seat_get_devices:
 * @seat: a `GdkSeat`
 * @capabilities: capabilities to get devices for
 *
 * Returns the devices that match the given capabilities.
 *
 * Returns: (transfer container) (element-type GdkDevice): A list
 *   of `GdkDevices`. The list must be freed with g_list_free(),
 *   the elements are owned by GTK and must not be freed.
 */

GList *
gdk_seat_get_devices (GdkSeat             *seat,
                      GdkSeatCapabilities  capabilities)
{
  GdkSeatClass *seat_class;

  g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);

  seat_class = GDK_SEAT_GET_CLASS (seat);
  return seat_class->get_devices (seat, capabilities);
}

/**
 * gdk_seat_get_pointer:
 * @seat: a `GdkSeat`
 *
 * Returns the device that routes pointer events.
 *
 * Returns: (transfer none) (nullable): a `GdkDevice` with pointer
 *   capabilities. This object is owned by GTK and must not be freed.
 */

GdkDevice *
gdk_seat_get_pointer (GdkSeat *seat)
{
  GdkSeatClass *seat_class;

  g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);

  seat_class = GDK_SEAT_GET_CLASS (seat);
  return seat_class->get_logical_device (seat, GDK_SEAT_CAPABILITY_POINTER);
}

/**
 * gdk_seat_get_keyboard:
 * @seat: a `GdkSeat`
 *
 * Returns the device that routes keyboard events.
 *
 * Returns: (transfer none) (nullable): a `GdkDevice` with keyboard
 *   capabilities. This object is owned by GTK and must not be freed.
 */

GdkDevice *
gdk_seat_get_keyboard (GdkSeat *seat)
{
  GdkSeatClass *seat_class;

  g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);

  seat_class = GDK_SEAT_GET_CLASS (seat);
  return seat_class->get_logical_device (seat, GDK_SEAT_CAPABILITY_KEYBOARD);
}

void
gdk_seat_device_added (GdkSeat   *seat,
                       GdkDevice *device)
{
  gdk_device_set_seat (device, seat);
  g_signal_emit (seat, signals[DEVICE_ADDED], 0, device);
}

void
gdk_seat_device_removed (GdkSeat   *seat,
                         GdkDevice *device)
{
  gdk_device_set_seat (device, NULL);
  g_signal_emit (seat, signals[DEVICE_REMOVED], 0, device);
}

/**
 * gdk_seat_get_display:
 * @seat: a `GdkSeat`
 *
 * Returns the `GdkDisplay` this seat belongs to.
 *
 * Returns: (transfer none): a `GdkDisplay`. This object
 *   is owned by GTK and must not be freed.
 */

GdkDisplay *
gdk_seat_get_display (GdkSeat *seat)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat);

  g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);

  return priv->display;
}

void
gdk_seat_tool_added (GdkSeat       *seat,
                     GdkDeviceTool *tool)
{
  g_signal_emit (seat, signals[TOOL_ADDED], 0, tool);
}

void
gdk_seat_tool_removed (GdkSeat       *seat,
                       GdkDeviceTool *tool)
{
  g_signal_emit (seat, signals[TOOL_REMOVED], 0, tool);
}

GdkDeviceTool *
gdk_seat_get_tool (GdkSeat          *seat,
                   guint64           serial,
                   guint64           hw_id,
                   GdkDeviceToolType type)
{
  GdkDeviceTool *match = NULL;
  GList *tools, *l;

  tools = gdk_seat_get_tools (seat);

  for (l = tools; l; l = l->next)
    {
      GdkDeviceTool *tool = l->data;

      if (tool->serial == serial && tool->hw_id == hw_id && tool->type == type)
        {
          match = tool;
          break;
        }
    }

  g_list_free (tools);

  return match;
}

/**
 * gdk_seat_get_tools:
 * @seat: a `GdkSeat`
 *
 * Returns all `GdkDeviceTools` that are known to the application.
 *
 * Returns: (transfer container) (element-type Gdk.DeviceTool):
 *   A list of tools. Free with g_list_free().
 */

GList *
gdk_seat_get_tools (GdkSeat *seat)
{
  GdkSeatClass *seat_class;

  g_return_val_if_fail (GDK_IS_SEAT (seat), NULL);

  seat_class = GDK_SEAT_GET_CLASS (seat);
  return seat_class->get_tools (seat);
}

GdkSurface *
gdk_seat_get_topmost_grab_surface (GdkSeat *seat)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat);

  if (!priv->grabs)
    return NULL;

  return priv->grabs->data;
}

static gboolean
surface_has_ancestor (GdkSurface *surface,
                      GdkSurface *ancestor)
{
  while (surface->parent)
    {
      surface = surface->parent;
      if (surface == ancestor)
        return TRUE;
    }

  return FALSE;
}

void
gdk_seat_break_grab (GdkSeat    *seat,
                     GdkSurface *if_child)
{
  GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat);
  GList *l;

  for (l = priv->grabs; l; l = l->next)
    {
      GdkSurface *grab_surface;
      GdkEvent *event;

      grab_surface = l->data;

      if (grab_surface != if_child &&
          surface_has_ancestor (grab_surface, if_child))
        break;

      event = gdk_grab_broken_event_new (grab_surface,
                                         gdk_seat_get_pointer (seat),
                                         NULL,
                                         FALSE);

      _gdk_event_queue_append (priv->display, event);
    }
}

Messung V0.5 in Prozent
C=99 H=88 G=93

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-07-03) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.