Blame gdk/gdkevents.c

Packit 98cdb6
/* GDK - The GIMP Drawing Kit
Packit 98cdb6
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit 98cdb6
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit 98cdb6
 * files for a list of changes.  These files are distributed with
Packit 98cdb6
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <string.h>		/* For memset() */
Packit 98cdb6
Packit 98cdb6
#include "gdk.h"
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
typedef struct _GdkIOClosure GdkIOClosure;
Packit 98cdb6
Packit 98cdb6
struct _GdkIOClosure
Packit 98cdb6
{
Packit 98cdb6
  GdkInputFunction function;
Packit 98cdb6
  GdkInputCondition condition;
Packit 98cdb6
  GDestroyNotify notify;
Packit 98cdb6
  gpointer data;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
/* Private variable declarations
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
GdkEventFunc   _gdk_event_func = NULL;    /* Callback for events */
Packit 98cdb6
gpointer       _gdk_event_data = NULL;
Packit 98cdb6
GDestroyNotify _gdk_event_notify = NULL;
Packit 98cdb6
Packit 98cdb6
/*********************************************
Packit 98cdb6
 * Functions for maintaining the event queue *
Packit 98cdb6
 *********************************************/
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_find_first:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * 
Packit 98cdb6
 * Find the first event on the queue that is not still
Packit 98cdb6
 * being filled in.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: Pointer to the list node for that event, or NULL.
Packit 98cdb6
 **/
Packit 98cdb6
GList*
Packit 98cdb6
_gdk_event_queue_find_first (GdkDisplay *display)
Packit 98cdb6
{
Packit 98cdb6
  GList *tmp_list = display->queued_events;
Packit 98cdb6
Packit 98cdb6
  while (tmp_list)
Packit 98cdb6
    {
Packit 98cdb6
      GdkEventPrivate *event = tmp_list->data;
Packit 98cdb6
      if (!(event->flags & GDK_EVENT_PENDING))
Packit 98cdb6
	return tmp_list;
Packit 98cdb6
Packit 98cdb6
      tmp_list = g_list_next (tmp_list);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_prepend:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @event: Event to prepend.
Packit 98cdb6
 *
Packit 98cdb6
 * Prepends an event before the head of the event queue.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: the newly prepended list node.
Packit 98cdb6
 **/
Packit 98cdb6
GList*
Packit 98cdb6
_gdk_event_queue_prepend (GdkDisplay *display,
Packit 98cdb6
			  GdkEvent   *event)
Packit 98cdb6
{
Packit 98cdb6
  display->queued_events = g_list_prepend (display->queued_events, event);
Packit 98cdb6
  if (!display->queued_tail)
Packit 98cdb6
    display->queued_tail = display->queued_events;
Packit 98cdb6
  return display->queued_events;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_append:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @event: Event to append.
Packit 98cdb6
 * 
Packit 98cdb6
 * Appends an event onto the tail of the event queue.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: the newly appended list node.
Packit 98cdb6
 **/
Packit 98cdb6
GList *
Packit 98cdb6
_gdk_event_queue_append (GdkDisplay *display,
Packit 98cdb6
			 GdkEvent   *event)
Packit 98cdb6
{
Packit 98cdb6
  display->queued_tail = g_list_append (display->queued_tail, event);
Packit 98cdb6
  
Packit 98cdb6
  if (!display->queued_events)
Packit 98cdb6
    display->queued_events = display->queued_tail;
Packit 98cdb6
  else
Packit 98cdb6
    display->queued_tail = display->queued_tail->next;
Packit 98cdb6
Packit 98cdb6
  return display->queued_tail;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_insert_after:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @sibling: Append after this event.
Packit 98cdb6
 * @event: Event to append.
Packit 98cdb6
 *
Packit 98cdb6
 * Appends an event after the specified event, or if it isn't in
Packit 98cdb6
 * the queue, onto the tail of the event queue.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: the newly appended list node.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.16
Packit 98cdb6
 */
Packit 98cdb6
GList*
Packit 98cdb6
_gdk_event_queue_insert_after (GdkDisplay *display,
Packit 98cdb6
                               GdkEvent   *sibling,
Packit 98cdb6
                               GdkEvent   *event)
Packit 98cdb6
{
Packit 98cdb6
  GList *prev = g_list_find (display->queued_events, sibling);
Packit 98cdb6
  if (prev && prev->next)
Packit 98cdb6
    {
Packit 98cdb6
      display->queued_events = g_list_insert_before (display->queued_events, prev->next, event);
Packit 98cdb6
      return prev->next;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return _gdk_event_queue_append (display, event);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_insert_after:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @sibling: Append after this event.
Packit 98cdb6
 * @event: Event to append.
Packit 98cdb6
 *
Packit 98cdb6
 * Appends an event before the specified event, or if it isn't in
Packit 98cdb6
 * the queue, onto the tail of the event queue.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: the newly appended list node.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.16
Packit 98cdb6
 */
Packit 98cdb6
GList*
Packit 98cdb6
_gdk_event_queue_insert_before (GdkDisplay *display,
Packit 98cdb6
				GdkEvent   *sibling,
Packit 98cdb6
				GdkEvent   *event)
Packit 98cdb6
{
Packit 98cdb6
  GList *next = g_list_find (display->queued_events, sibling);
Packit 98cdb6
  if (next)
Packit 98cdb6
    {
Packit 98cdb6
      display->queued_events = g_list_insert_before (display->queued_events, next, event);
Packit 98cdb6
      return next->prev;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return _gdk_event_queue_append (display, event);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_queue_remove_link:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @node: node to remove
Packit 98cdb6
 * 
Packit 98cdb6
 * Removes a specified list node from the event queue.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
_gdk_event_queue_remove_link (GdkDisplay *display,
Packit 98cdb6
			      GList      *node)
Packit 98cdb6
{
Packit 98cdb6
  if (node->prev)
Packit 98cdb6
    node->prev->next = node->next;
Packit 98cdb6
  else
Packit 98cdb6
    display->queued_events = node->next;
Packit 98cdb6
  
Packit 98cdb6
  if (node->next)
Packit 98cdb6
    node->next->prev = node->prev;
Packit 98cdb6
  else
Packit 98cdb6
    display->queued_tail = node->prev;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_event_unqueue:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * 
Packit 98cdb6
 * Removes and returns the first event from the event
Packit 98cdb6
 * queue that is not still being filled in.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the event, or %NULL. Ownership is transferred
Packit 98cdb6
 * to the caller.
Packit 98cdb6
 **/
Packit 98cdb6
GdkEvent*
Packit 98cdb6
_gdk_event_unqueue (GdkDisplay *display)
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent *event = NULL;
Packit 98cdb6
  GList *tmp_list;
Packit 98cdb6
Packit 98cdb6
  tmp_list = _gdk_event_queue_find_first (display);
Packit 98cdb6
Packit 98cdb6
  if (tmp_list)
Packit 98cdb6
    {
Packit 98cdb6
      event = tmp_list->data;
Packit 98cdb6
      _gdk_event_queue_remove_link (display, tmp_list);
Packit 98cdb6
      g_list_free_1 (tmp_list);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return event;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_handler_set:
Packit 98cdb6
 * @func: the function to call to handle events from GDK.
Packit 98cdb6
 * @data: user data to pass to the function. 
Packit 98cdb6
 * @notify: the function to call when the handler function is removed, i.e. when
Packit 98cdb6
 *          gdk_event_handler_set() is called with another event handler.
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the function to call to handle all events from GDK.
Packit 98cdb6
 *
Packit 98cdb6
 * Note that GTK+ uses this to install its own event handler, so it is
Packit 98cdb6
 * usually not useful for GTK+ applications. (Although an application
Packit 98cdb6
 * can call this function then call gtk_main_do_event() to pass
Packit 98cdb6
 * events to GTK+.)
Packit 98cdb6
 **/
Packit 98cdb6
void 
Packit 98cdb6
gdk_event_handler_set (GdkEventFunc   func,
Packit 98cdb6
		       gpointer       data,
Packit 98cdb6
		       GDestroyNotify notify)
Packit 98cdb6
{
Packit 98cdb6
  if (_gdk_event_notify)
Packit 98cdb6
    (*_gdk_event_notify) (_gdk_event_data);
Packit 98cdb6
Packit 98cdb6
  _gdk_event_func = func;
Packit 98cdb6
  _gdk_event_data = data;
Packit 98cdb6
  _gdk_event_notify = notify;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get:
Packit 98cdb6
 * 
Packit 98cdb6
 * Checks all open displays for a #GdkEvent to process,to be processed
Packit 98cdb6
 * on, fetching events from the windowing system if necessary.
Packit 98cdb6
 * See gdk_display_get_event().
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the next #GdkEvent to be processed, or %NULL if no events
Packit 98cdb6
 * are pending. The returned #GdkEvent should be freed with gdk_event_free().
Packit 98cdb6
 **/
Packit 98cdb6
GdkEvent*
Packit 98cdb6
gdk_event_get (void)
Packit 98cdb6
{
Packit 98cdb6
  GSList *tmp_list;
Packit 98cdb6
Packit 98cdb6
  for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
Packit 98cdb6
    {
Packit 98cdb6
      GdkEvent *event = gdk_display_get_event (tmp_list->data);
Packit 98cdb6
      if (event)
Packit 98cdb6
	return event;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_peek:
Packit 98cdb6
 *
Packit 98cdb6
 * If there is an event waiting in the event queue of some open
Packit 98cdb6
 * display, returns a copy of it. See gdk_display_peek_event().
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a copy of the first #GdkEvent on some event queue, or %NULL if no
Packit 98cdb6
 * events are in any queues. The returned #GdkEvent should be freed with
Packit 98cdb6
 * gdk_event_free().
Packit 98cdb6
 **/
Packit 98cdb6
GdkEvent*
Packit 98cdb6
gdk_event_peek (void)
Packit 98cdb6
{
Packit 98cdb6
  GSList *tmp_list;
Packit 98cdb6
Packit 98cdb6
  for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
Packit 98cdb6
    {
Packit 98cdb6
      GdkEvent *event = gdk_display_peek_event (tmp_list->data);
Packit 98cdb6
      if (event)
Packit 98cdb6
	return event;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_put:
Packit 98cdb6
 * @event: a #GdkEvent.
Packit 98cdb6
 *
Packit 98cdb6
 * Appends a copy of the given event onto the front of the event
Packit 98cdb6
 * queue for event->any.window's display, or the default event
Packit 98cdb6
 * queue if event->any.window is %NULL. See gdk_display_put_event().
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_event_put (const GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (event != NULL);
Packit 98cdb6
Packit 98cdb6
  if (event->any.window)
Packit 98cdb6
    display = gdk_drawable_get_display (event->any.window);
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      GDK_NOTE (MULTIHEAD,
Packit 98cdb6
		g_message ("Falling back to default display for gdk_event_put()"));
Packit 98cdb6
      display = gdk_display_get_default ();
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  gdk_display_put_event (display, event);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GHashTable *event_hash = NULL;
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_new:
Packit 98cdb6
 * @type: a #GdkEventType 
Packit 98cdb6
 * 
Packit 98cdb6
 * Creates a new event of the given type. All fields are set to 0.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a newly-allocated #GdkEvent. The returned #GdkEvent 
Packit 98cdb6
 * should be freed with gdk_event_free().
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
GdkEvent*
Packit 98cdb6
gdk_event_new (GdkEventType type)
Packit 98cdb6
{
Packit 98cdb6
  GdkEventPrivate *new_private;
Packit 98cdb6
  GdkEvent *new_event;
Packit 98cdb6
  
Packit 98cdb6
  if (!event_hash)
Packit 98cdb6
    event_hash = g_hash_table_new (g_direct_hash, NULL);
Packit 98cdb6
Packit 98cdb6
  new_private = g_slice_new0 (GdkEventPrivate);
Packit 98cdb6
  
Packit 98cdb6
  new_private->flags = 0;
Packit 98cdb6
  new_private->screen = NULL;
Packit 98cdb6
Packit 98cdb6
  g_hash_table_insert (event_hash, new_private, GUINT_TO_POINTER (1));
Packit 98cdb6
Packit 98cdb6
  new_event = (GdkEvent *) new_private;
Packit 98cdb6
Packit 98cdb6
  new_event->any.type = type;
Packit 98cdb6
Packit 98cdb6
  /*
Packit 98cdb6
   * Bytewise 0 initialization is reasonable for most of the 
Packit 98cdb6
   * current event types. Explicitely initialize double fields
Packit 98cdb6
   * since I trust bytewise 0 == 0. less than for integers
Packit 98cdb6
   * or pointers.
Packit 98cdb6
   */
Packit 98cdb6
  switch (type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_MOTION_NOTIFY:
Packit 98cdb6
      new_event->motion.x = 0.;
Packit 98cdb6
      new_event->motion.y = 0.;
Packit 98cdb6
      new_event->motion.x_root = 0.;
Packit 98cdb6
      new_event->motion.y_root = 0.;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_BUTTON_PRESS:
Packit 98cdb6
    case GDK_2BUTTON_PRESS:
Packit 98cdb6
    case GDK_3BUTTON_PRESS:
Packit 98cdb6
    case GDK_BUTTON_RELEASE:
Packit 98cdb6
      new_event->button.x = 0.;
Packit 98cdb6
      new_event->button.y = 0.;
Packit 98cdb6
      new_event->button.x_root = 0.;
Packit 98cdb6
      new_event->button.y_root = 0.;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_SCROLL:
Packit 98cdb6
      new_event->scroll.x = 0.;
Packit 98cdb6
      new_event->scroll.y = 0.;
Packit 98cdb6
      new_event->scroll.x_root = 0.;
Packit 98cdb6
      new_event->scroll.y_root = 0.;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_ENTER_NOTIFY:
Packit 98cdb6
    case GDK_LEAVE_NOTIFY:
Packit 98cdb6
      new_event->crossing.x = 0.;
Packit 98cdb6
      new_event->crossing.y = 0.;
Packit 98cdb6
      new_event->crossing.x_root = 0.;
Packit 98cdb6
      new_event->crossing.y_root = 0.;
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return new_event;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gdk_event_is_allocated (const GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  if (event_hash)
Packit 98cdb6
    return g_hash_table_lookup (event_hash, event) != NULL;
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
 
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_copy:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * 
Packit 98cdb6
 * Copies a #GdkEvent, copying or incrementing the reference count of the
Packit 98cdb6
 * resources associated with it (e.g. #GdkWindow's and strings).
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a copy of @event. The returned #GdkEvent should be freed with
Packit 98cdb6
 * gdk_event_free().
Packit 98cdb6
 **/
Packit 98cdb6
GdkEvent*
Packit 98cdb6
gdk_event_copy (const GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  GdkEventPrivate *new_private;
Packit 98cdb6
  GdkEvent *new_event;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (event != NULL, NULL);
Packit 98cdb6
  
Packit 98cdb6
  new_event = gdk_event_new (GDK_NOTHING);
Packit 98cdb6
  new_private = (GdkEventPrivate *)new_event;
Packit 98cdb6
Packit 98cdb6
  *new_event = *event;
Packit 98cdb6
  if (new_event->any.window)
Packit 98cdb6
    g_object_ref (new_event->any.window);
Packit 98cdb6
Packit 98cdb6
  if (gdk_event_is_allocated (event))
Packit 98cdb6
    {
Packit 98cdb6
      GdkEventPrivate *private = (GdkEventPrivate *)event;
Packit 98cdb6
Packit 98cdb6
      new_private->screen = private->screen;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  switch (event->any.type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_KEY_PRESS:
Packit 98cdb6
    case GDK_KEY_RELEASE:
Packit 98cdb6
      new_event->key.string = g_strdup (event->key.string);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_ENTER_NOTIFY:
Packit 98cdb6
    case GDK_LEAVE_NOTIFY:
Packit 98cdb6
      if (event->crossing.subwindow != NULL)
Packit 98cdb6
	g_object_ref (event->crossing.subwindow);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_DRAG_ENTER:
Packit 98cdb6
    case GDK_DRAG_LEAVE:
Packit 98cdb6
    case GDK_DRAG_MOTION:
Packit 98cdb6
    case GDK_DRAG_STATUS:
Packit 98cdb6
    case GDK_DROP_START:
Packit 98cdb6
    case GDK_DROP_FINISHED:
Packit 98cdb6
      g_object_ref (event->dnd.context);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_EXPOSE:
Packit 98cdb6
    case GDK_DAMAGE:
Packit 98cdb6
      if (event->expose.region)
Packit 98cdb6
	new_event->expose.region = gdk_region_copy (event->expose.region);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_SETTING:
Packit 98cdb6
      new_event->setting.name = g_strdup (new_event->setting.name);
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    case GDK_BUTTON_PRESS:
Packit 98cdb6
    case GDK_BUTTON_RELEASE:
Packit 98cdb6
      if (event->button.axes) 
Packit 98cdb6
	new_event->button.axes = g_memdup (event->button.axes, 
Packit 98cdb6
					     sizeof (gdouble) * event->button.device->num_axes);
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    case GDK_MOTION_NOTIFY:
Packit 98cdb6
      if (event->motion.axes) 
Packit 98cdb6
	new_event->motion.axes = g_memdup (event->motion.axes, 
Packit 98cdb6
					   sizeof (gdouble) * event->motion.device->num_axes);
Packit 98cdb6
      
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    default:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (gdk_event_is_allocated (event))
Packit 98cdb6
    _gdk_windowing_event_data_copy (event, new_event);
Packit 98cdb6
  
Packit 98cdb6
  return new_event;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_free:
Packit 98cdb6
 * @event:  a #GdkEvent.
Packit 98cdb6
 * 
Packit 98cdb6
 * Frees a #GdkEvent, freeing or decrementing any resources associated with it.
Packit 98cdb6
 * Note that this function should only be called with events returned from
Packit 98cdb6
 * functions such as gdk_event_peek(), gdk_event_get(),
Packit 98cdb6
 * gdk_event_get_graphics_expose() and gdk_event_copy() and gdk_event_new().
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_event_free (GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (event != NULL);
Packit 98cdb6
Packit 98cdb6
  if (event->any.window)
Packit 98cdb6
    g_object_unref (event->any.window);
Packit 98cdb6
  
Packit 98cdb6
  switch (event->any.type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_KEY_PRESS:
Packit 98cdb6
    case GDK_KEY_RELEASE:
Packit 98cdb6
      g_free (event->key.string);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_ENTER_NOTIFY:
Packit 98cdb6
    case GDK_LEAVE_NOTIFY:
Packit 98cdb6
      if (event->crossing.subwindow != NULL)
Packit 98cdb6
	g_object_unref (event->crossing.subwindow);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_DRAG_ENTER:
Packit 98cdb6
    case GDK_DRAG_LEAVE:
Packit 98cdb6
    case GDK_DRAG_MOTION:
Packit 98cdb6
    case GDK_DRAG_STATUS:
Packit 98cdb6
    case GDK_DROP_START:
Packit 98cdb6
    case GDK_DROP_FINISHED:
Packit 98cdb6
      g_object_unref (event->dnd.context);
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    case GDK_BUTTON_PRESS:
Packit 98cdb6
    case GDK_BUTTON_RELEASE:
Packit 98cdb6
      g_free (event->button.axes);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_EXPOSE:
Packit 98cdb6
    case GDK_DAMAGE:
Packit 98cdb6
      if (event->expose.region)
Packit 98cdb6
	gdk_region_destroy (event->expose.region);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_MOTION_NOTIFY:
Packit 98cdb6
      g_free (event->motion.axes);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_SETTING:
Packit 98cdb6
      g_free (event->setting.name);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    default:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  _gdk_windowing_event_data_free (event);
Packit 98cdb6
Packit 98cdb6
  g_hash_table_remove (event_hash, event);
Packit 98cdb6
  g_slice_free (GdkEventPrivate, (GdkEventPrivate*) event);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_time:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the time stamp from @event, if there is one; otherwise
Packit 98cdb6
 * returns #GDK_CURRENT_TIME. If @event is %NULL, returns #GDK_CURRENT_TIME.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: time stamp field from @event
Packit 98cdb6
 **/
Packit 98cdb6
guint32
Packit 98cdb6
gdk_event_get_time (const GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  if (event)
Packit 98cdb6
    switch (event->type)
Packit 98cdb6
      {
Packit 98cdb6
      case GDK_MOTION_NOTIFY:
Packit 98cdb6
	return event->motion.time;
Packit 98cdb6
      case GDK_BUTTON_PRESS:
Packit 98cdb6
      case GDK_2BUTTON_PRESS:
Packit 98cdb6
      case GDK_3BUTTON_PRESS:
Packit 98cdb6
      case GDK_BUTTON_RELEASE:
Packit 98cdb6
	return event->button.time;
Packit 98cdb6
      case GDK_SCROLL:
Packit 98cdb6
        return event->scroll.time;
Packit 98cdb6
      case GDK_KEY_PRESS:
Packit 98cdb6
      case GDK_KEY_RELEASE:
Packit 98cdb6
	return event->key.time;
Packit 98cdb6
      case GDK_ENTER_NOTIFY:
Packit 98cdb6
      case GDK_LEAVE_NOTIFY:
Packit 98cdb6
	return event->crossing.time;
Packit 98cdb6
      case GDK_PROPERTY_NOTIFY:
Packit 98cdb6
	return event->property.time;
Packit 98cdb6
      case GDK_SELECTION_CLEAR:
Packit 98cdb6
      case GDK_SELECTION_REQUEST:
Packit 98cdb6
      case GDK_SELECTION_NOTIFY:
Packit 98cdb6
	return event->selection.time;
Packit 98cdb6
      case GDK_PROXIMITY_IN:
Packit 98cdb6
      case GDK_PROXIMITY_OUT:
Packit 98cdb6
	return event->proximity.time;
Packit 98cdb6
      case GDK_DRAG_ENTER:
Packit 98cdb6
      case GDK_DRAG_LEAVE:
Packit 98cdb6
      case GDK_DRAG_MOTION:
Packit 98cdb6
      case GDK_DRAG_STATUS:
Packit 98cdb6
      case GDK_DROP_START:
Packit 98cdb6
      case GDK_DROP_FINISHED:
Packit 98cdb6
	return event->dnd.time;
Packit 98cdb6
      case GDK_CLIENT_EVENT:
Packit 98cdb6
      case GDK_VISIBILITY_NOTIFY:
Packit 98cdb6
      case GDK_NO_EXPOSE:
Packit 98cdb6
      case GDK_CONFIGURE:
Packit 98cdb6
      case GDK_FOCUS_CHANGE:
Packit 98cdb6
      case GDK_NOTHING:
Packit 98cdb6
      case GDK_DAMAGE:
Packit 98cdb6
      case GDK_DELETE:
Packit 98cdb6
      case GDK_DESTROY:
Packit 98cdb6
      case GDK_EXPOSE:
Packit 98cdb6
      case GDK_MAP:
Packit 98cdb6
      case GDK_UNMAP:
Packit 98cdb6
      case GDK_WINDOW_STATE:
Packit 98cdb6
      case GDK_SETTING:
Packit 98cdb6
      case GDK_OWNER_CHANGE:
Packit 98cdb6
      case GDK_GRAB_BROKEN:
Packit 98cdb6
      case GDK_EVENT_LAST:
Packit 98cdb6
        /* return current time */
Packit 98cdb6
        break;
Packit 98cdb6
      }
Packit 98cdb6
  
Packit 98cdb6
  return GDK_CURRENT_TIME;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_state:
Packit 98cdb6
 * @event: a #GdkEvent or NULL
Packit 98cdb6
 * @state: (out): return location for state
Packit 98cdb6
 * 
Packit 98cdb6
 * If the event contains a "state" field, puts that field in @state. Otherwise
Packit 98cdb6
 * stores an empty state (0). Returns %TRUE if there was a state field
Packit 98cdb6
 * in the event. @event may be %NULL, in which case it's treated
Packit 98cdb6
 * as if the event had no state field.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if there was a state field in the event 
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_event_get_state (const GdkEvent        *event,
Packit 98cdb6
                     GdkModifierType       *state)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (state != NULL, FALSE);
Packit 98cdb6
  
Packit 98cdb6
  if (event)
Packit 98cdb6
    switch (event->type)
Packit 98cdb6
      {
Packit 98cdb6
      case GDK_MOTION_NOTIFY:
Packit 98cdb6
	*state = event->motion.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_BUTTON_PRESS:
Packit 98cdb6
      case GDK_2BUTTON_PRESS:
Packit 98cdb6
      case GDK_3BUTTON_PRESS:
Packit 98cdb6
      case GDK_BUTTON_RELEASE:
Packit 98cdb6
        *state =  event->button.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_SCROLL:
Packit 98cdb6
	*state =  event->scroll.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_KEY_PRESS:
Packit 98cdb6
      case GDK_KEY_RELEASE:
Packit 98cdb6
	*state =  event->key.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_ENTER_NOTIFY:
Packit 98cdb6
      case GDK_LEAVE_NOTIFY:
Packit 98cdb6
	*state =  event->crossing.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_PROPERTY_NOTIFY:
Packit 98cdb6
	*state =  event->property.state;
Packit 98cdb6
        return TRUE;
Packit 98cdb6
      case GDK_VISIBILITY_NOTIFY:
Packit 98cdb6
      case GDK_CLIENT_EVENT:
Packit 98cdb6
      case GDK_NO_EXPOSE:
Packit 98cdb6
      case GDK_CONFIGURE:
Packit 98cdb6
      case GDK_FOCUS_CHANGE:
Packit 98cdb6
      case GDK_SELECTION_CLEAR:
Packit 98cdb6
      case GDK_SELECTION_REQUEST:
Packit 98cdb6
      case GDK_SELECTION_NOTIFY:
Packit 98cdb6
      case GDK_PROXIMITY_IN:
Packit 98cdb6
      case GDK_PROXIMITY_OUT:
Packit 98cdb6
      case GDK_DAMAGE:
Packit 98cdb6
      case GDK_DRAG_ENTER:
Packit 98cdb6
      case GDK_DRAG_LEAVE:
Packit 98cdb6
      case GDK_DRAG_MOTION:
Packit 98cdb6
      case GDK_DRAG_STATUS:
Packit 98cdb6
      case GDK_DROP_START:
Packit 98cdb6
      case GDK_DROP_FINISHED:
Packit 98cdb6
      case GDK_NOTHING:
Packit 98cdb6
      case GDK_DELETE:
Packit 98cdb6
      case GDK_DESTROY:
Packit 98cdb6
      case GDK_EXPOSE:
Packit 98cdb6
      case GDK_MAP:
Packit 98cdb6
      case GDK_UNMAP:
Packit 98cdb6
      case GDK_WINDOW_STATE:
Packit 98cdb6
      case GDK_SETTING:
Packit 98cdb6
      case GDK_OWNER_CHANGE:
Packit 98cdb6
      case GDK_GRAB_BROKEN:
Packit 98cdb6
      case GDK_EVENT_LAST:
Packit 98cdb6
        /* no state field */
Packit 98cdb6
        break;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
  *state = 0;
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_coords:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * @x_win: (out): location to put event window x coordinate
Packit 98cdb6
 * @y_win: (out): location to put event window y coordinate
Packit 98cdb6
 * 
Packit 98cdb6
 * Extract the event window relative x/y coordinates from an event.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if the event delivered event window coordinates
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_event_get_coords (const GdkEvent *event,
Packit 98cdb6
		      gdouble        *x_win,
Packit 98cdb6
		      gdouble        *y_win)
Packit 98cdb6
{
Packit 98cdb6
  gdouble x = 0, y = 0;
Packit 98cdb6
  gboolean fetched = TRUE;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (event != NULL, FALSE);
Packit 98cdb6
Packit 98cdb6
  switch (event->type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_CONFIGURE:
Packit 98cdb6
      x = event->configure.x;
Packit 98cdb6
      y = event->configure.y;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_ENTER_NOTIFY:
Packit 98cdb6
    case GDK_LEAVE_NOTIFY:
Packit 98cdb6
      x = event->crossing.x;
Packit 98cdb6
      y = event->crossing.y;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_SCROLL:
Packit 98cdb6
      x = event->scroll.x;
Packit 98cdb6
      y = event->scroll.y;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_BUTTON_PRESS:
Packit 98cdb6
    case GDK_2BUTTON_PRESS:
Packit 98cdb6
    case GDK_3BUTTON_PRESS:
Packit 98cdb6
    case GDK_BUTTON_RELEASE:
Packit 98cdb6
      x = event->button.x;
Packit 98cdb6
      y = event->button.y;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_MOTION_NOTIFY:
Packit 98cdb6
      x = event->motion.x;
Packit 98cdb6
      y = event->motion.y;
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      fetched = FALSE;
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (x_win)
Packit 98cdb6
    *x_win = x;
Packit 98cdb6
  if (y_win)
Packit 98cdb6
    *y_win = y;
Packit 98cdb6
Packit 98cdb6
  return fetched;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_root_coords:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * @x_root: (out): location to put root window x coordinate
Packit 98cdb6
 * @y_root: (out): location to put root window y coordinate
Packit 98cdb6
 * 
Packit 98cdb6
 * Extract the root window relative x/y coordinates from an event.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if the event delivered root window coordinates
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_event_get_root_coords (const GdkEvent *event,
Packit 98cdb6
			   gdouble        *x_root,
Packit 98cdb6
			   gdouble        *y_root)
Packit 98cdb6
{
Packit 98cdb6
  gdouble x = 0, y = 0;
Packit 98cdb6
  gboolean fetched = TRUE;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (event != NULL, FALSE);
Packit 98cdb6
Packit 98cdb6
  switch (event->type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_MOTION_NOTIFY:
Packit 98cdb6
      x = event->motion.x_root;
Packit 98cdb6
      y = event->motion.y_root;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_SCROLL:
Packit 98cdb6
      x = event->scroll.x_root;
Packit 98cdb6
      y = event->scroll.y_root;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_BUTTON_PRESS:
Packit 98cdb6
    case GDK_2BUTTON_PRESS:
Packit 98cdb6
    case GDK_3BUTTON_PRESS:
Packit 98cdb6
    case GDK_BUTTON_RELEASE:
Packit 98cdb6
      x = event->button.x_root;
Packit 98cdb6
      y = event->button.y_root;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_ENTER_NOTIFY:
Packit 98cdb6
    case GDK_LEAVE_NOTIFY:
Packit 98cdb6
      x = event->crossing.x_root;
Packit 98cdb6
      y = event->crossing.y_root;
Packit 98cdb6
      break;
Packit 98cdb6
    case GDK_DRAG_ENTER:
Packit 98cdb6
    case GDK_DRAG_LEAVE:
Packit 98cdb6
    case GDK_DRAG_MOTION:
Packit 98cdb6
    case GDK_DRAG_STATUS:
Packit 98cdb6
    case GDK_DROP_START:
Packit 98cdb6
    case GDK_DROP_FINISHED:
Packit 98cdb6
      x = event->dnd.x_root;
Packit 98cdb6
      y = event->dnd.y_root;
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      fetched = FALSE;
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (x_root)
Packit 98cdb6
    *x_root = x;
Packit 98cdb6
  if (y_root)
Packit 98cdb6
    *y_root = y;
Packit 98cdb6
Packit 98cdb6
  return fetched;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_axis:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * @axis_use: the axis use to look for
Packit 98cdb6
 * @value: (out): location to store the value found
Packit 98cdb6
 * 
Packit 98cdb6
 * Extract the axis value for a particular axis use from
Packit 98cdb6
 * an event structure.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if the specified axis was found, otherwise %FALSE
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_event_get_axis (const GdkEvent *event,
Packit 98cdb6
		    GdkAxisUse      axis_use,
Packit 98cdb6
		    gdouble        *value)
Packit 98cdb6
{
Packit 98cdb6
  gdouble *axes;
Packit 98cdb6
  GdkDevice *device;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (event != NULL, FALSE);
Packit 98cdb6
  
Packit 98cdb6
  if (axis_use == GDK_AXIS_X || axis_use == GDK_AXIS_Y)
Packit 98cdb6
    {
Packit 98cdb6
      gdouble x, y;
Packit 98cdb6
      
Packit 98cdb6
      switch (event->type)
Packit 98cdb6
	{
Packit 98cdb6
	case GDK_MOTION_NOTIFY:
Packit 98cdb6
	  x = event->motion.x;
Packit 98cdb6
	  y = event->motion.y;
Packit 98cdb6
	  break;
Packit 98cdb6
	case GDK_SCROLL:
Packit 98cdb6
	  x = event->scroll.x;
Packit 98cdb6
	  y = event->scroll.y;
Packit 98cdb6
	  break;
Packit 98cdb6
	case GDK_BUTTON_PRESS:
Packit 98cdb6
	case GDK_BUTTON_RELEASE:
Packit 98cdb6
	  x = event->button.x;
Packit 98cdb6
	  y = event->button.y;
Packit 98cdb6
	  break;
Packit 98cdb6
	case GDK_ENTER_NOTIFY:
Packit 98cdb6
	case GDK_LEAVE_NOTIFY:
Packit 98cdb6
	  x = event->crossing.x;
Packit 98cdb6
	  y = event->crossing.y;
Packit 98cdb6
	  break;
Packit 98cdb6
	  
Packit 98cdb6
	default:
Packit 98cdb6
	  return FALSE;
Packit 98cdb6
	}
Packit 98cdb6
Packit 98cdb6
      if (axis_use == GDK_AXIS_X && value)
Packit 98cdb6
	*value = x;
Packit 98cdb6
      if (axis_use == GDK_AXIS_Y && value)
Packit 98cdb6
	*value = y;
Packit 98cdb6
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  else if (event->type == GDK_BUTTON_PRESS ||
Packit 98cdb6
	   event->type == GDK_BUTTON_RELEASE)
Packit 98cdb6
    {
Packit 98cdb6
      device = event->button.device;
Packit 98cdb6
      axes = event->button.axes;
Packit 98cdb6
    }
Packit 98cdb6
  else if (event->type == GDK_MOTION_NOTIFY)
Packit 98cdb6
    {
Packit 98cdb6
      device = event->motion.device;
Packit 98cdb6
      axes = event->motion.axes;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  return gdk_device_get_axis (device, axes, axis_use, value);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_request_motions:
Packit 98cdb6
 * @event: a valid #GdkEvent
Packit 98cdb6
 *
Packit 98cdb6
 * Request more motion notifies if @event is a motion notify hint event.
Packit 98cdb6
 * This function should be used instead of gdk_window_get_pointer() to
Packit 98cdb6
 * request further motion notifies, because it also works for extension
Packit 98cdb6
 * events where motion notifies are provided for devices other than the
Packit 98cdb6
 * core pointer. Coordinate extraction, processing and requesting more
Packit 98cdb6
 * motion events from a %GDK_MOTION_NOTIFY event usually works like this:
Packit 98cdb6
 *
Packit 98cdb6
 * |[
Packit 98cdb6
 * { 
Packit 98cdb6
 *   /* motion_event handler */
Packit 98cdb6
 *   x = motion_event->x;
Packit 98cdb6
 *   y = motion_event->y;
Packit 98cdb6
 *   /* handle (x,y) motion */
Packit 98cdb6
 *   gdk_event_request_motions (motion_event); /* handles is_hint events */
Packit 98cdb6
 * }
Packit 98cdb6
 * ]|
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.12
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_event_request_motions (const GdkEventMotion *event)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (event != NULL);
Packit 98cdb6
  
Packit 98cdb6
  if (event->type == GDK_MOTION_NOTIFY && event->is_hint)
Packit 98cdb6
    {
Packit 98cdb6
      gdk_device_get_state (event->device, event->window, NULL, NULL);
Packit 98cdb6
      
Packit 98cdb6
      display = gdk_drawable_get_display (event->window);
Packit 98cdb6
      _gdk_display_enable_motion_hints (display);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_set_screen:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * @screen: a #GdkScreen
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the screen for @event to @screen. The event must
Packit 98cdb6
 * have been allocated by GTK+, for instance, by
Packit 98cdb6
 * gdk_event_copy().
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_event_set_screen (GdkEvent  *event,
Packit 98cdb6
		      GdkScreen *screen)
Packit 98cdb6
{
Packit 98cdb6
  GdkEventPrivate *private;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (gdk_event_is_allocated (event));
Packit 98cdb6
Packit 98cdb6
  private = (GdkEventPrivate *)event;
Packit 98cdb6
  
Packit 98cdb6
  private->screen = screen;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_event_get_screen:
Packit 98cdb6
 * @event: a #GdkEvent
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the screen for the event. The screen is
Packit 98cdb6
 * typically the screen for <literal>event->any.window</literal>, but
Packit 98cdb6
 * for events such as mouse events, it is the screen
Packit 98cdb6
 * where the pointer was when the event occurs -
Packit 98cdb6
 * that is, the screen which has the root window 
Packit 98cdb6
 * to which <literal>event->motion.x_root</literal> and
Packit 98cdb6
 * <literal>event->motion.y_root</literal> are relative.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the screen for the event
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
GdkScreen *
Packit 98cdb6
gdk_event_get_screen (const GdkEvent *event)
Packit 98cdb6
{
Packit 98cdb6
  if (gdk_event_is_allocated (event))
Packit 98cdb6
    {
Packit 98cdb6
      GdkEventPrivate *private = (GdkEventPrivate *)event;
Packit 98cdb6
Packit 98cdb6
      if (private->screen)
Packit 98cdb6
	return private->screen;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (event->any.window)
Packit 98cdb6
    return gdk_drawable_get_screen (event->any.window);
Packit 98cdb6
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_set_show_events:
Packit 98cdb6
 * @show_events:  %TRUE to output event debugging information.
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets whether a trace of received events is output.
Packit 98cdb6
 * Note that GTK+ must be compiled with debugging (that is,
Packit 98cdb6
 * configured using the <option>--enable-debug</option> option)
Packit 98cdb6
 * to use this option.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_set_show_events (gboolean show_events)
Packit 98cdb6
{
Packit 98cdb6
  if (show_events)
Packit 98cdb6
    _gdk_debug_flags |= GDK_DEBUG_EVENTS;
Packit 98cdb6
  else
Packit 98cdb6
    _gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_get_show_events:
Packit 98cdb6
 * 
Packit 98cdb6
 * Gets whether event debugging output is enabled.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if event debugging output is enabled.
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_get_show_events (void)
Packit 98cdb6
{
Packit 98cdb6
  return (_gdk_debug_flags & GDK_DEBUG_EVENTS) != 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_io_destroy (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GdkIOClosure *closure = data;
Packit 98cdb6
Packit 98cdb6
  if (closure->notify)
Packit 98cdb6
    closure->notify (closure->data);
Packit 98cdb6
Packit 98cdb6
  g_free (closure);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* What do we do with G_IO_NVAL?
Packit 98cdb6
 */
Packit 98cdb6
#define READ_CONDITION (G_IO_IN | G_IO_HUP | G_IO_ERR)
Packit 98cdb6
#define WRITE_CONDITION (G_IO_OUT | G_IO_ERR)
Packit 98cdb6
#define EXCEPTION_CONDITION (G_IO_PRI)
Packit 98cdb6
Packit 98cdb6
static gboolean  
Packit 98cdb6
gdk_io_invoke (GIOChannel   *source,
Packit 98cdb6
	       GIOCondition  condition,
Packit 98cdb6
	       gpointer      data)
Packit 98cdb6
{
Packit 98cdb6
  GdkIOClosure *closure = data;
Packit 98cdb6
  GdkInputCondition gdk_cond = 0;
Packit 98cdb6
Packit 98cdb6
  if (condition & READ_CONDITION)
Packit 98cdb6
    gdk_cond |= GDK_INPUT_READ;
Packit 98cdb6
  if (condition & WRITE_CONDITION)
Packit 98cdb6
    gdk_cond |= GDK_INPUT_WRITE;
Packit 98cdb6
  if (condition & EXCEPTION_CONDITION)
Packit 98cdb6
    gdk_cond |= GDK_INPUT_EXCEPTION;
Packit 98cdb6
Packit 98cdb6
  if (closure->condition & gdk_cond)
Packit 98cdb6
    closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_input_add_full:
Packit 98cdb6
 * @source: a file descriptor.
Packit 98cdb6
 * @condition: the condition.
Packit 98cdb6
 * @function: the callback function.
Packit 98cdb6
 * @data: callback data passed to @function.
Packit 98cdb6
 * @destroy: callback function to call with @data when the input
Packit 98cdb6
 * handler is removed.
Packit 98cdb6
 *
Packit 98cdb6
 * Establish a callback when a condition becomes true on
Packit 98cdb6
 * a file descriptor.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: a tag that can later be used as an argument to
Packit 98cdb6
 * gdk_input_remove().
Packit 98cdb6
 *
Packit 98cdb6
 * Deprecated: 2.14: Use g_io_add_watch_full() on a #GIOChannel
Packit 98cdb6
 */
Packit 98cdb6
gint
Packit 98cdb6
gdk_input_add_full (gint	      source,
Packit 98cdb6
		    GdkInputCondition condition,
Packit 98cdb6
		    GdkInputFunction  function,
Packit 98cdb6
		    gpointer	      data,
Packit 98cdb6
		    GDestroyNotify    destroy)
Packit 98cdb6
{
Packit 98cdb6
  guint result;
Packit 98cdb6
  GdkIOClosure *closure = g_new (GdkIOClosure, 1);
Packit 98cdb6
  GIOChannel *channel;
Packit 98cdb6
  GIOCondition cond = 0;
Packit 98cdb6
Packit 98cdb6
  closure->function = function;
Packit 98cdb6
  closure->condition = condition;
Packit 98cdb6
  closure->notify = destroy;
Packit 98cdb6
  closure->data = data;
Packit 98cdb6
Packit 98cdb6
  if (condition & GDK_INPUT_READ)
Packit 98cdb6
    cond |= READ_CONDITION;
Packit 98cdb6
  if (condition & GDK_INPUT_WRITE)
Packit 98cdb6
    cond |= WRITE_CONDITION;
Packit 98cdb6
  if (condition & GDK_INPUT_EXCEPTION)
Packit 98cdb6
    cond |= EXCEPTION_CONDITION;
Packit 98cdb6
Packit 98cdb6
  channel = g_io_channel_unix_new (source);
Packit 98cdb6
  result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond, 
Packit 98cdb6
				gdk_io_invoke,
Packit 98cdb6
				closure, gdk_io_destroy);
Packit 98cdb6
  g_io_channel_unref (channel);
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_input_add:
Packit 98cdb6
 * @source: a file descriptor.
Packit 98cdb6
 * @condition: the condition.
Packit 98cdb6
 * @function: the callback function.
Packit 98cdb6
 * @data: callback data passed to @function.
Packit 98cdb6
 *
Packit 98cdb6
 * Establish a callback when a condition becomes true on
Packit 98cdb6
 * a file descriptor.
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: a tag that can later be used as an argument to
Packit 98cdb6
 * gdk_input_remove().
Packit 98cdb6
 *
Packit 98cdb6
 * Deprecated: 2.14: Use g_io_add_watch() on a #GIOChannel
Packit 98cdb6
 */
Packit 98cdb6
gint
Packit 98cdb6
gdk_input_add (gint		 source,
Packit 98cdb6
	       GdkInputCondition condition,
Packit 98cdb6
	       GdkInputFunction	 function,
Packit 98cdb6
	       gpointer		 data)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_input_add_full (source, condition, function, data, NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_input_remove (gint tag)
Packit 98cdb6
{
Packit 98cdb6
  g_source_remove (tag);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_synthesize_click (GdkDisplay *display,
Packit 98cdb6
		      GdkEvent   *event,
Packit 98cdb6
		      gint	  nclicks)
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent temp_event;
Packit 98cdb6
  GdkEvent *event_copy;
Packit 98cdb6
  GList *link;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (event != NULL);
Packit 98cdb6
  
Packit 98cdb6
  temp_event = *event;
Packit 98cdb6
  temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
Packit 98cdb6
Packit 98cdb6
  event_copy = gdk_event_copy (&temp_event);
Packit 98cdb6
  link = _gdk_event_queue_append (display, event_copy);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_event_button_generate (GdkDisplay *display,
Packit 98cdb6
			    GdkEvent   *event)
Packit 98cdb6
{
Packit 98cdb6
  if ((event->button.time < (display->button_click_time[1] + 2*display->double_click_time)) &&
Packit 98cdb6
      (event->button.window == display->button_window[1]) &&
Packit 98cdb6
      (event->button.button == display->button_number[1]) &&
Packit 98cdb6
      (ABS (event->button.x - display->button_x[1]) <= display->double_click_distance) &&
Packit 98cdb6
      (ABS (event->button.y - display->button_y[1]) <= display->double_click_distance))
Packit 98cdb6
{
Packit 98cdb6
      gdk_synthesize_click (display, event, 3);
Packit 98cdb6
            
Packit 98cdb6
      display->button_click_time[1] = 0;
Packit 98cdb6
      display->button_click_time[0] = 0;
Packit 98cdb6
      display->button_window[1] = NULL;
Packit 98cdb6
      display->button_window[0] = NULL;
Packit 98cdb6
      display->button_number[1] = -1;
Packit 98cdb6
      display->button_number[0] = -1;
Packit 98cdb6
      display->button_x[0] = display->button_x[1] = 0;
Packit 98cdb6
      display->button_y[0] = display->button_y[1] = 0;
Packit 98cdb6
    }
Packit 98cdb6
  else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) &&
Packit 98cdb6
	   (event->button.window == display->button_window[0]) &&
Packit 98cdb6
	   (event->button.button == display->button_number[0]) &&
Packit 98cdb6
	   (ABS (event->button.x - display->button_x[0]) <= display->double_click_distance) &&
Packit 98cdb6
	   (ABS (event->button.y - display->button_y[0]) <= display->double_click_distance))
Packit 98cdb6
    {
Packit 98cdb6
      gdk_synthesize_click (display, event, 2);
Packit 98cdb6
      
Packit 98cdb6
      display->button_click_time[1] = display->button_click_time[0];
Packit 98cdb6
      display->button_click_time[0] = event->button.time;
Packit 98cdb6
      display->button_window[1] = display->button_window[0];
Packit 98cdb6
      display->button_window[0] = event->button.window;
Packit 98cdb6
      display->button_number[1] = display->button_number[0];
Packit 98cdb6
      display->button_number[0] = event->button.button;
Packit 98cdb6
      display->button_x[1] = display->button_x[0];
Packit 98cdb6
      display->button_x[0] = event->button.x;
Packit 98cdb6
      display->button_y[1] = display->button_y[0];
Packit 98cdb6
      display->button_y[0] = event->button.y;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      display->button_click_time[1] = 0;
Packit 98cdb6
      display->button_click_time[0] = event->button.time;
Packit 98cdb6
      display->button_window[1] = NULL;
Packit 98cdb6
      display->button_window[0] = event->button.window;
Packit 98cdb6
      display->button_number[1] = -1;
Packit 98cdb6
      display->button_number[0] = event->button.button;
Packit 98cdb6
      display->button_x[1] = 0;
Packit 98cdb6
      display->button_x[0] = event->button.x;
Packit 98cdb6
      display->button_y[1] = 0;
Packit 98cdb6
      display->button_y[0] = event->button.y;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_synthesize_window_state (GdkWindow     *window,
Packit 98cdb6
                             GdkWindowState unset_flags,
Packit 98cdb6
                             GdkWindowState set_flags)
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent temp_event;
Packit 98cdb6
  GdkWindowState old;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (window != NULL);
Packit 98cdb6
  
Packit 98cdb6
  temp_event.window_state.window = window;
Packit 98cdb6
  temp_event.window_state.type = GDK_WINDOW_STATE;
Packit 98cdb6
  temp_event.window_state.send_event = FALSE;
Packit 98cdb6
  
Packit 98cdb6
  old = ((GdkWindowObject*) temp_event.window_state.window)->state;
Packit 98cdb6
  
Packit 98cdb6
  temp_event.window_state.new_window_state = old;
Packit 98cdb6
  temp_event.window_state.new_window_state |= set_flags;
Packit 98cdb6
  temp_event.window_state.new_window_state &= ~unset_flags;
Packit 98cdb6
  temp_event.window_state.changed_mask = temp_event.window_state.new_window_state ^ old;
Packit 98cdb6
Packit 98cdb6
  if (temp_event.window_state.new_window_state == old)
Packit 98cdb6
    return; /* No actual work to do, nothing changed. */
Packit 98cdb6
Packit 98cdb6
  /* Actually update the field in GdkWindow, this is sort of an odd
Packit 98cdb6
   * place to do it, but seems like the safest since it ensures we expose no
Packit 98cdb6
   * inconsistent state to the user.
Packit 98cdb6
   */
Packit 98cdb6
  
Packit 98cdb6
  ((GdkWindowObject*) window)->state = temp_event.window_state.new_window_state;
Packit 98cdb6
Packit 98cdb6
  if (temp_event.window_state.changed_mask & GDK_WINDOW_STATE_WITHDRAWN)
Packit 98cdb6
    _gdk_window_update_viewable (window);
Packit 98cdb6
Packit 98cdb6
  /* We only really send the event to toplevels, since
Packit 98cdb6
   * all the window states don't apply to non-toplevels.
Packit 98cdb6
   * Non-toplevels do use the GDK_WINDOW_STATE_WITHDRAWN flag
Packit 98cdb6
   * internally so we needed to update window->state.
Packit 98cdb6
   */
Packit 98cdb6
  switch (((GdkWindowObject*) window)->window_type)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_WINDOW_TOPLEVEL:
Packit 98cdb6
    case GDK_WINDOW_DIALOG:
Packit 98cdb6
    case GDK_WINDOW_TEMP: /* ? */
Packit 98cdb6
      gdk_display_put_event (gdk_drawable_get_display (window), &temp_event);
Packit 98cdb6
      break;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_WINDOW_FOREIGN:
Packit 98cdb6
    case GDK_WINDOW_ROOT:
Packit 98cdb6
    case GDK_WINDOW_CHILD:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_display_set_double_click_time:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @msec: double click time in milliseconds (thousandths of a second) 
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the double click time (two clicks within this time interval
Packit 98cdb6
 * count as a double click and result in a #GDK_2BUTTON_PRESS event).
Packit 98cdb6
 * Applications should <emphasis>not</emphasis> set this, it is a global 
Packit 98cdb6
 * user-configured setting.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_display_set_double_click_time (GdkDisplay *display,
Packit 98cdb6
				   guint       msec)
Packit 98cdb6
{
Packit 98cdb6
  display->double_click_time = msec;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_set_double_click_time:
Packit 98cdb6
 * @msec: double click time in milliseconds (thousandths of a second)
Packit 98cdb6
 *
Packit 98cdb6
 * Set the double click time for the default display. See
Packit 98cdb6
 * gdk_display_set_double_click_time(). 
Packit 98cdb6
 * See also gdk_display_set_double_click_distance().
Packit 98cdb6
 * Applications should <emphasis>not</emphasis> set this, it is a 
Packit 98cdb6
 * global user-configured setting.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_set_double_click_time (guint msec)
Packit 98cdb6
{
Packit 98cdb6
  gdk_display_set_double_click_time (gdk_display_get_default (), msec);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_display_set_double_click_distance:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @distance: distance in pixels
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the double click distance (two clicks within this distance
Packit 98cdb6
 * count as a double click and result in a #GDK_2BUTTON_PRESS event).
Packit 98cdb6
 * See also gdk_display_set_double_click_time().
Packit 98cdb6
 * Applications should <emphasis>not</emphasis> set this, it is a global 
Packit 98cdb6
 * user-configured setting.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.4
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_display_set_double_click_distance (GdkDisplay *display,
Packit 98cdb6
				       guint       distance)
Packit 98cdb6
{
Packit 98cdb6
  display->double_click_distance = distance;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GType
Packit 98cdb6
gdk_event_get_type (void)
Packit 98cdb6
{
Packit 98cdb6
  static GType our_type = 0;
Packit 98cdb6
  
Packit 98cdb6
  if (our_type == 0)
Packit 98cdb6
    our_type = g_boxed_type_register_static (g_intern_static_string ("GdkEvent"),
Packit 98cdb6
					     (GBoxedCopyFunc)gdk_event_copy,
Packit 98cdb6
					     (GBoxedFreeFunc)gdk_event_free);
Packit 98cdb6
  return our_type;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_setting_get:
Packit 98cdb6
 * @name: the name of the setting.
Packit 98cdb6
 * @value: location to store the value of the setting.
Packit 98cdb6
 *
Packit 98cdb6
 * Obtains a desktop-wide setting, such as the double-click time,
Packit 98cdb6
 * for the default screen. See gdk_screen_get_setting().
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: %TRUE if the setting existed and a value was stored
Packit 98cdb6
 *   in @value, %FALSE otherwise.
Packit 98cdb6
 **/
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_setting_get (const gchar *name,
Packit 98cdb6
		 GValue      *value)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_screen_get_setting (gdk_screen_get_default (), name, value);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_EVENTS_C__
Packit 98cdb6
#include "gdkaliasdef.c"