Blame gdk/x11/gdkmain-x11.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
Packit 98cdb6
#include <glib/gprintf.h>
Packit 98cdb6
#include <stdlib.h>
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include <unistd.h>
Packit 98cdb6
#include <limits.h>
Packit 98cdb6
#include <errno.h>
Packit 98cdb6
Packit 98cdb6
#include <X11/Xatom.h>
Packit 98cdb6
#include <X11/Xlib.h>
Packit 98cdb6
#include <X11/Xutil.h>
Packit 98cdb6
Packit 98cdb6
#ifdef HAVE_XKB
Packit 98cdb6
#include <X11/XKBlib.h>
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
#include "gdk.h"
Packit 98cdb6
Packit 98cdb6
#include "gdkx.h"
Packit 98cdb6
#include "gdkasync.h"
Packit 98cdb6
#include "gdkdisplay-x11.h"
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
#include "gdkintl.h"
Packit 98cdb6
#include "gdkregion-generic.h"
Packit 98cdb6
#include "gdkinputprivate.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
typedef struct _GdkPredicate  GdkPredicate;
Packit 98cdb6
typedef struct _GdkErrorTrap  GdkErrorTrap;
Packit 98cdb6
Packit 98cdb6
struct _GdkPredicate
Packit 98cdb6
{
Packit 98cdb6
  GdkEventFunc func;
Packit 98cdb6
  gpointer data;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
struct _GdkErrorTrap
Packit 98cdb6
{
Packit 98cdb6
  int (*old_handler) (Display *, XErrorEvent *);
Packit 98cdb6
  gint error_warnings;
Packit 98cdb6
  gint error_code;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
/* 
Packit 98cdb6
 * Private function declarations
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#ifndef HAVE_XCONVERTCASE
Packit 98cdb6
static void	 gdkx_XConvertCase	(KeySym	       symbol,
Packit 98cdb6
					 KeySym	      *lower,
Packit 98cdb6
					 KeySym	      *upper);
Packit 98cdb6
#define XConvertCase gdkx_XConvertCase
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
static int	    gdk_x_error			 (Display     *display, 
Packit 98cdb6
						  XErrorEvent *error);
Packit 98cdb6
static int	    gdk_x_io_error		 (Display     *display);
Packit 98cdb6
Packit 98cdb6
/* Private variable declarations
Packit 98cdb6
 */
Packit 98cdb6
static GSList *gdk_error_traps = NULL;               /* List of error traps */
Packit 98cdb6
static GSList *gdk_error_trap_free_list = NULL;      /* Free list */
Packit 98cdb6
Packit 98cdb6
const GOptionEntry _gdk_windowing_args[] = {
Packit 98cdb6
  { "sync", 0, 0, G_OPTION_ARG_NONE, &_gdk_synchronize, 
Packit 98cdb6
    /* Description of --sync in --help output */ N_("Make X calls synchronous"), NULL },
Packit 98cdb6
  { NULL }
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_windowing_init (void)
Packit 98cdb6
{
Packit 98cdb6
  _gdk_x11_initialize_locale ();
Packit 98cdb6
  
Packit 98cdb6
  XSetErrorHandler (gdk_x_error);
Packit 98cdb6
  XSetIOErrorHandler (gdk_x_io_error);
Packit 98cdb6
Packit 98cdb6
  _gdk_selection_property = gdk_atom_intern_static_string ("GDK_SELECTION");
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_set_use_xshm (gboolean use_xshm)
Packit 98cdb6
{
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_get_use_xshm (void)
Packit 98cdb6
{
Packit 98cdb6
  return GDK_DISPLAY_X11 (gdk_display_get_default ())->use_xshm;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkGrabStatus
Packit 98cdb6
gdk_x11_convert_grab_status (gint status)
Packit 98cdb6
{
Packit 98cdb6
  switch (status)
Packit 98cdb6
    {
Packit 98cdb6
    case GrabSuccess:
Packit 98cdb6
      return GDK_GRAB_SUCCESS;
Packit 98cdb6
    case AlreadyGrabbed:
Packit 98cdb6
      return GDK_GRAB_ALREADY_GRABBED;
Packit 98cdb6
    case GrabInvalidTime:
Packit 98cdb6
      return GDK_GRAB_INVALID_TIME;
Packit 98cdb6
    case GrabNotViewable:
Packit 98cdb6
      return GDK_GRAB_NOT_VIEWABLE;
Packit 98cdb6
    case GrabFrozen:
Packit 98cdb6
      return GDK_GRAB_FROZEN;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  g_assert_not_reached();
Packit 98cdb6
Packit 98cdb6
  return 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
has_pointer_grab_callback (GdkDisplay *display,
Packit 98cdb6
			   gpointer data,
Packit 98cdb6
			   gulong serial)
Packit 98cdb6
{
Packit 98cdb6
  _gdk_display_pointer_grab_update (display, serial);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkGrabStatus
Packit 98cdb6
_gdk_windowing_pointer_grab (GdkWindow *window,
Packit 98cdb6
			     GdkWindow *native,
Packit 98cdb6
			     gboolean owner_events,
Packit 98cdb6
			     GdkEventMask event_mask,
Packit 98cdb6
			     GdkWindow *confine_to,
Packit 98cdb6
			     GdkCursor *cursor,
Packit 98cdb6
			     guint32 time)
Packit 98cdb6
{
Packit 98cdb6
  gint return_val;
Packit 98cdb6
  GdkCursorPrivate *cursor_private;
Packit 98cdb6
  GdkDisplayX11 *display_x11;
Packit 98cdb6
  guint xevent_mask;
Packit 98cdb6
  Window xwindow;
Packit 98cdb6
  Window xconfine_to;
Packit 98cdb6
  Cursor xcursor;
Packit 98cdb6
  int i;
Packit 98cdb6
Packit 98cdb6
  if (confine_to)
Packit 98cdb6
    confine_to = _gdk_window_get_impl_window (confine_to);
Packit 98cdb6
Packit 98cdb6
  display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native));
Packit 98cdb6
Packit 98cdb6
  cursor_private = (GdkCursorPrivate*) cursor;
Packit 98cdb6
Packit 98cdb6
  xwindow = GDK_WINDOW_XID (native);
Packit 98cdb6
Packit 98cdb6
  if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
Packit 98cdb6
    xconfine_to = None;
Packit 98cdb6
  else
Packit 98cdb6
    xconfine_to = GDK_WINDOW_XID (confine_to);
Packit 98cdb6
Packit 98cdb6
  if (!cursor)
Packit 98cdb6
    xcursor = None;
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      _gdk_x11_cursor_update_theme (cursor);
Packit 98cdb6
      xcursor = cursor_private->xcursor;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  xevent_mask = 0;
Packit 98cdb6
  for (i = 0; i < _gdk_nenvent_masks; i++)
Packit 98cdb6
    {
Packit 98cdb6
      if (event_mask & (1 << (i + 1)))
Packit 98cdb6
	xevent_mask |= _gdk_event_mask_table[i];
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* We don't want to set a native motion hint mask, as we're emulating motion
Packit 98cdb6
   * hints. If we set a native one we just wouldn't get any events.
Packit 98cdb6
   */
Packit 98cdb6
  xevent_mask &= ~PointerMotionHintMask;
Packit 98cdb6
Packit 98cdb6
  return_val = _gdk_input_grab_pointer (window,
Packit 98cdb6
					native,
Packit 98cdb6
					owner_events,
Packit 98cdb6
					event_mask,
Packit 98cdb6
					confine_to,
Packit 98cdb6
					time);
Packit 98cdb6
Packit 98cdb6
  if (return_val == GrabSuccess ||
Packit 98cdb6
      G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed))
Packit 98cdb6
    {
Packit 98cdb6
      if (!GDK_WINDOW_DESTROYED (native))
Packit 98cdb6
	{
Packit 98cdb6
#ifdef G_ENABLE_DEBUG
Packit 98cdb6
	  if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
Packit 98cdb6
	    return_val = GrabSuccess;
Packit 98cdb6
	  else
Packit 98cdb6
#endif
Packit 98cdb6
	    return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (native),
Packit 98cdb6
				       xwindow,
Packit 98cdb6
				       owner_events,
Packit 98cdb6
				       xevent_mask,
Packit 98cdb6
				       GrabModeAsync, GrabModeAsync,
Packit 98cdb6
				       xconfine_to,
Packit 98cdb6
				       xcursor,
Packit 98cdb6
				       time);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	return_val = AlreadyGrabbed;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (return_val == GrabSuccess)
Packit 98cdb6
    _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11),
Packit 98cdb6
			      has_pointer_grab_callback,
Packit 98cdb6
			      NULL);
Packit 98cdb6
Packit 98cdb6
  return gdk_x11_convert_grab_status (return_val);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 * gdk_keyboard_grab
Packit 98cdb6
 *
Packit 98cdb6
 *   Grabs the keyboard to a specific window
Packit 98cdb6
 *
Packit 98cdb6
 * Arguments:
Packit 98cdb6
 *   "window" is the window which will receive the grab
Packit 98cdb6
 *   "owner_events" specifies whether events will be reported as is,
Packit 98cdb6
 *     or relative to "window"
Packit 98cdb6
 *   "time" specifies the time
Packit 98cdb6
 *
Packit 98cdb6
 * Results:
Packit 98cdb6
 *
Packit 98cdb6
 * Side effects:
Packit 98cdb6
 *   requires a corresponding call to gdk_keyboard_ungrab
Packit 98cdb6
 *
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
GdkGrabStatus
Packit 98cdb6
gdk_keyboard_grab (GdkWindow *	   window,
Packit 98cdb6
		   gboolean	   owner_events,
Packit 98cdb6
		   guint32	   time)
Packit 98cdb6
{
Packit 98cdb6
  gint return_val;
Packit 98cdb6
  unsigned long serial;
Packit 98cdb6
  GdkDisplay *display;
Packit 98cdb6
  GdkDisplayX11 *display_x11;
Packit 98cdb6
  GdkWindow *native;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (window != NULL, 0);
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
Packit 98cdb6
Packit 98cdb6
  native = gdk_window_get_toplevel (window);
Packit 98cdb6
Packit 98cdb6
  /* TODO: What do we do for offscreens and  children? We need to proxy the grab somehow */
Packit 98cdb6
  if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl))
Packit 98cdb6
    return GDK_GRAB_SUCCESS;
Packit 98cdb6
Packit 98cdb6
  display = GDK_WINDOW_DISPLAY (native);
Packit 98cdb6
  display_x11 = GDK_DISPLAY_X11 (display);
Packit 98cdb6
Packit 98cdb6
  serial = NextRequest (GDK_WINDOW_XDISPLAY (native));
Packit 98cdb6
Packit 98cdb6
  if (!GDK_WINDOW_DESTROYED (native))
Packit 98cdb6
    {
Packit 98cdb6
#ifdef G_ENABLE_DEBUG
Packit 98cdb6
      if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
Packit 98cdb6
	return_val = GrabSuccess;
Packit 98cdb6
      else
Packit 98cdb6
#endif
Packit 98cdb6
	return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native),
Packit 98cdb6
				    GDK_WINDOW_XID (native),
Packit 98cdb6
				    owner_events,
Packit 98cdb6
				    GrabModeAsync, GrabModeAsync,
Packit 98cdb6
				    time);
Packit 98cdb6
	if (G_UNLIKELY (!display_x11->trusted_client && 
Packit 98cdb6
			return_val == AlreadyGrabbed))
Packit 98cdb6
	  /* we can't grab the keyboard, but we can do a GTK-local grab */
Packit 98cdb6
	  return_val = GrabSuccess;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    return_val = AlreadyGrabbed;
Packit 98cdb6
Packit 98cdb6
  if (return_val == GrabSuccess)
Packit 98cdb6
    _gdk_display_set_has_keyboard_grab (display,
Packit 98cdb6
					window,	native,
Packit 98cdb6
					owner_events,
Packit 98cdb6
					serial, time);
Packit 98cdb6
Packit 98cdb6
  return gdk_x11_convert_grab_status (return_val);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_xgrab_check_unmap:
Packit 98cdb6
 * @window: a #GdkWindow
Packit 98cdb6
 * @serial: serial from Unmap event (or from NextRequest(display)
Packit 98cdb6
 *   if the unmap is being done by this client.)
Packit 98cdb6
 * 
Packit 98cdb6
 * Checks to see if an unmap request or event causes the current
Packit 98cdb6
 * grab window to become not viewable, and if so, clear the
Packit 98cdb6
 * the pointer we keep to it.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
_gdk_xgrab_check_unmap (GdkWindow *window,
Packit 98cdb6
			gulong     serial)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display = gdk_drawable_get_display (window);
Packit 98cdb6
Packit 98cdb6
  _gdk_display_end_pointer_grab (display, serial, window, TRUE);
Packit 98cdb6
Packit 98cdb6
  if (display->keyboard_grab.window &&
Packit 98cdb6
      serial >= display->keyboard_grab.serial)
Packit 98cdb6
    {
Packit 98cdb6
      GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
Packit 98cdb6
      GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
Packit 98cdb6
Packit 98cdb6
      while (tmp && tmp != private)
Packit 98cdb6
	tmp = tmp->parent;
Packit 98cdb6
Packit 98cdb6
      if (tmp)
Packit 98cdb6
	_gdk_display_unset_has_keyboard_grab (display, TRUE);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_xgrab_check_destroy:
Packit 98cdb6
 * @window: a #GdkWindow
Packit 98cdb6
 * 
Packit 98cdb6
 * Checks to see if window is the current grab window, and if
Packit 98cdb6
 * so, clear the current grab window.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
_gdk_xgrab_check_destroy (GdkWindow *window)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display = gdk_drawable_get_display (window);
Packit 98cdb6
  GdkPointerGrabInfo *grab;
Packit 98cdb6
Packit 98cdb6
  /* Make sure there is no lasting grab in this native
Packit 98cdb6
     window */
Packit 98cdb6
  grab = _gdk_display_get_last_pointer_grab (display);
Packit 98cdb6
  if (grab && grab->native_window == window)
Packit 98cdb6
    {
Packit 98cdb6
      /* We don't know the actual serial to end, but it
Packit 98cdb6
	 doesn't really matter as this only happens
Packit 98cdb6
	 after we get told of the destroy from the
Packit 98cdb6
	 server so we know its ended in the server,
Packit 98cdb6
	 just make sure its ended. */
Packit 98cdb6
      grab->serial_end = grab->serial_start;
Packit 98cdb6
      grab->implicit_ungrab = TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  if (window == display->keyboard_grab.native_window &&
Packit 98cdb6
      display->keyboard_grab.window != NULL)
Packit 98cdb6
    _gdk_display_unset_has_keyboard_grab (display, TRUE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_windowing_display_set_sm_client_id (GdkDisplay  *display,
Packit 98cdb6
					 const gchar *sm_client_id)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
Packit 98cdb6
Packit 98cdb6
  if (display->closed)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (sm_client_id && strcmp (sm_client_id, ""))
Packit 98cdb6
    {
Packit 98cdb6
      XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
Packit 98cdb6
		       gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
Packit 98cdb6
		       XA_STRING, 8, PropModeReplace, (guchar *)sm_client_id,
Packit 98cdb6
		       strlen (sm_client_id));
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
Packit 98cdb6
		     gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_set_sm_client_id:
Packit 98cdb6
 * @sm_client_id: the client id assigned by the session manager when the
Packit 98cdb6
 *    connection was opened, or %NULL to remove the property.
Packit 98cdb6
 *
Packit 98cdb6
 * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that
Packit 98cdb6
 * the window manager can save the application's state using the X11R6 ICCCM
Packit 98cdb6
 * session management protocol.
Packit 98cdb6
 *
Packit 98cdb6
 * See the X Session Management Library documentation for more information on
Packit 98cdb6
 * session management and the Inter-Client Communication Conventions Manual
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.24
Packit 98cdb6
 */
Packit 98cdb6
void
Packit 98cdb6
gdk_x11_set_sm_client_id (const gchar *sm_client_id)
Packit 98cdb6
{
Packit 98cdb6
  gdk_set_sm_client_id (sm_client_id);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Close all open displays
Packit 98cdb6
 */
Packit 98cdb6
void
Packit 98cdb6
_gdk_windowing_exit (void)
Packit 98cdb6
{
Packit 98cdb6
  GSList *tmp_list = _gdk_displays;
Packit 98cdb6
    
Packit 98cdb6
  while (tmp_list)
Packit 98cdb6
    {
Packit 98cdb6
      XCloseDisplay (GDK_DISPLAY_XDISPLAY (tmp_list->data));
Packit 98cdb6
      
Packit 98cdb6
      tmp_list = tmp_list->next;
Packit 98cdb6
  }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 * gdk_x_error
Packit 98cdb6
 *
Packit 98cdb6
 *   The X error handling routine.
Packit 98cdb6
 *
Packit 98cdb6
 * Arguments:
Packit 98cdb6
 *   "display" is the X display the error orignated from.
Packit 98cdb6
 *   "error" is the XErrorEvent that we are handling.
Packit 98cdb6
 *
Packit 98cdb6
 * Results:
Packit 98cdb6
 *   Either we were expecting some sort of error to occur,
Packit 98cdb6
 *   in which case we set the "_gdk_error_code" flag, or this
Packit 98cdb6
 *   error was unexpected, in which case we will print an
Packit 98cdb6
 *   error message and exit. (Since trying to continue will
Packit 98cdb6
 *   most likely simply lead to more errors).
Packit 98cdb6
 *
Packit 98cdb6
 * Side effects:
Packit 98cdb6
 *
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
static int
Packit 98cdb6
gdk_x_error (Display	 *display,
Packit 98cdb6
	     XErrorEvent *error)
Packit 98cdb6
{
Packit 98cdb6
  if (error->error_code)
Packit 98cdb6
    {
Packit 98cdb6
      if (_gdk_error_warnings)
Packit 98cdb6
	{
Packit 98cdb6
	  gchar buf[64];
Packit 98cdb6
          gchar *msg;
Packit 98cdb6
          
Packit 98cdb6
	  XGetErrorText (display, error->error_code, buf, 63);
Packit 98cdb6
Packit 98cdb6
          msg =
Packit 98cdb6
            g_strdup_printf ("The program '%s' received an X Window System error.\n"
Packit 98cdb6
                             "This probably reflects a bug in the program.\n"
Packit 98cdb6
                             "The error was '%s'.\n"
Packit 98cdb6
                             "  (Details: serial %ld error_code %d request_code %d minor_code %d)\n"
Packit 98cdb6
                             "  (Note to programmers: normally, X errors are reported asynchronously;\n"
Packit 98cdb6
                             "   that is, you will receive the error a while after causing it.\n"
Packit 98cdb6
                             "   To debug your program, run it with the --sync command line\n"
Packit 98cdb6
                             "   option to change this behavior. You can then get a meaningful\n"
Packit 98cdb6
                             "   backtrace from your debugger if you break on the gdk_x_error() function.)",
Packit 98cdb6
                             g_get_prgname (),
Packit 98cdb6
                             buf,
Packit 98cdb6
                             error->serial, 
Packit 98cdb6
                             error->error_code, 
Packit 98cdb6
                             error->request_code,
Packit 98cdb6
                             error->minor_code);
Packit 98cdb6
          
Packit 98cdb6
#ifdef G_ENABLE_DEBUG	  
Packit 98cdb6
	  g_error ("%s", msg);
Packit 98cdb6
#else /* !G_ENABLE_DEBUG */
Packit 98cdb6
	  g_fprintf (stderr, "%s\n", msg);
Packit 98cdb6
Packit 98cdb6
	  exit (1);
Packit 98cdb6
#endif /* G_ENABLE_DEBUG */
Packit 98cdb6
	}
Packit 98cdb6
      _gdk_error_code = error->error_code;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 * gdk_x_io_error
Packit 98cdb6
 *
Packit 98cdb6
 *   The X I/O error handling routine.
Packit 98cdb6
 *
Packit 98cdb6
 * Arguments:
Packit 98cdb6
 *   "display" is the X display the error orignated from.
Packit 98cdb6
 *
Packit 98cdb6
 * Results:
Packit 98cdb6
 *   An X I/O error basically means we lost our connection
Packit 98cdb6
 *   to the X server. There is not much we can do to
Packit 98cdb6
 *   continue, so simply print an error message and exit.
Packit 98cdb6
 *
Packit 98cdb6
 * Side effects:
Packit 98cdb6
 *
Packit 98cdb6
 *--------------------------------------------------------------
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
static int
Packit 98cdb6
gdk_x_io_error (Display *display)
Packit 98cdb6
{
Packit 98cdb6
  /* This is basically modelled after the code in XLib. We need
Packit 98cdb6
   * an explicit error handler here, so we can disable our atexit()
Packit 98cdb6
   * which would otherwise cause a nice segfault.
Packit 98cdb6
   * We fprintf(stderr, instead of g_warning() because g_warning()
Packit 98cdb6
   * could possibly be redirected to a dialog
Packit 98cdb6
   */
Packit 98cdb6
  if (errno == EPIPE)
Packit 98cdb6
    {
Packit 98cdb6
      g_fprintf (stderr,
Packit 98cdb6
               "The application '%s' lost its connection to the display %s;\n"
Packit 98cdb6
               "most likely the X server was shut down or you killed/destroyed\n"
Packit 98cdb6
               "the application.\n",
Packit 98cdb6
               g_get_prgname (),
Packit 98cdb6
               display ? DisplayString (display) : gdk_get_display_arg_name ());
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      g_fprintf (stderr, "%s: Fatal IO error %d (%s) on X server %s.\n",
Packit 98cdb6
               g_get_prgname (),
Packit 98cdb6
	       errno, g_strerror (errno),
Packit 98cdb6
	       display ? DisplayString (display) : gdk_get_display_arg_name ());
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  exit(1);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*************************************************************
Packit 98cdb6
 * gdk_error_trap_push:
Packit 98cdb6
 *     Push an error trap. X errors will be trapped until
Packit 98cdb6
 *     the corresponding gdk_error_pop(), which will return
Packit 98cdb6
 *     the error code, if any.
Packit 98cdb6
 *   arguments:
Packit 98cdb6
 *     
Packit 98cdb6
 *   results:
Packit 98cdb6
 *************************************************************/
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_error_trap_push (void)
Packit 98cdb6
{
Packit 98cdb6
  GSList *node;
Packit 98cdb6
  GdkErrorTrap *trap;
Packit 98cdb6
Packit 98cdb6
  if (gdk_error_trap_free_list)
Packit 98cdb6
    {
Packit 98cdb6
      node = gdk_error_trap_free_list;
Packit 98cdb6
      gdk_error_trap_free_list = gdk_error_trap_free_list->next;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      node = g_slist_alloc ();
Packit 98cdb6
      node->data = g_new (GdkErrorTrap, 1);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  node->next = gdk_error_traps;
Packit 98cdb6
  gdk_error_traps = node;
Packit 98cdb6
  
Packit 98cdb6
  trap = node->data;
Packit 98cdb6
  trap->old_handler = XSetErrorHandler (gdk_x_error);
Packit 98cdb6
  trap->error_code = _gdk_error_code;
Packit 98cdb6
  trap->error_warnings = _gdk_error_warnings;
Packit 98cdb6
Packit 98cdb6
  _gdk_error_code = 0;
Packit 98cdb6
  _gdk_error_warnings = 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*************************************************************
Packit 98cdb6
 * gdk_error_trap_pop:
Packit 98cdb6
 *     Pop an error trap added with gdk_error_push()
Packit 98cdb6
 *   arguments:
Packit 98cdb6
 *     
Packit 98cdb6
 *   results:
Packit 98cdb6
 *     0, if no error occured, otherwise the error code.
Packit 98cdb6
 *************************************************************/
Packit 98cdb6
Packit 98cdb6
gint
Packit 98cdb6
gdk_error_trap_pop (void)
Packit 98cdb6
{
Packit 98cdb6
  GSList *node;
Packit 98cdb6
  GdkErrorTrap *trap;
Packit 98cdb6
  gint result;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (gdk_error_traps != NULL, 0);
Packit 98cdb6
Packit 98cdb6
  node = gdk_error_traps;
Packit 98cdb6
  gdk_error_traps = gdk_error_traps->next;
Packit 98cdb6
Packit 98cdb6
  node->next = gdk_error_trap_free_list;
Packit 98cdb6
  gdk_error_trap_free_list = node;
Packit 98cdb6
  
Packit 98cdb6
  result = _gdk_error_code;
Packit 98cdb6
  
Packit 98cdb6
  trap = node->data;
Packit 98cdb6
  _gdk_error_code = trap->error_code;
Packit 98cdb6
  _gdk_error_warnings = trap->error_warnings;
Packit 98cdb6
  XSetErrorHandler (trap->old_handler);
Packit 98cdb6
  
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gchar *
Packit 98cdb6
gdk_get_display (void)
Packit 98cdb6
{
Packit 98cdb6
  return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gdk_send_xevent:
Packit 98cdb6
 * @display: #GdkDisplay which @window is on
Packit 98cdb6
 * @window: window ID to which to send the event
Packit 98cdb6
 * @propagate: %TRUE if the event should be propagated if the target window
Packit 98cdb6
 *             doesn't handle it.
Packit 98cdb6
 * @event_mask: event mask to match against, or 0 to send it to @window
Packit 98cdb6
 *              without regard to event masks.
Packit 98cdb6
 * @event_send: #XEvent to send
Packit 98cdb6
 * 
Packit 98cdb6
 * Send an event, like XSendEvent(), but trap errors and check
Packit 98cdb6
 * the result.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: %TRUE if sending the event succeeded.
Packit 98cdb6
 **/
Packit 98cdb6
gint 
Packit 98cdb6
_gdk_send_xevent (GdkDisplay *display,
Packit 98cdb6
		  Window      window, 
Packit 98cdb6
		  gboolean    propagate, 
Packit 98cdb6
		  glong       event_mask,
Packit 98cdb6
		  XEvent     *event_send)
Packit 98cdb6
{
Packit 98cdb6
  gboolean result;
Packit 98cdb6
Packit 98cdb6
  if (display->closed)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  gdk_error_trap_push ();
Packit 98cdb6
  result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window, 
Packit 98cdb6
		       propagate, event_mask, event_send);
Packit 98cdb6
  XSync (GDK_DISPLAY_XDISPLAY (display), False);
Packit 98cdb6
  
Packit 98cdb6
  if (gdk_error_trap_pop ())
Packit 98cdb6
    return FALSE;
Packit 98cdb6
 
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_region_get_xrectangles (const GdkRegion *region,
Packit 98cdb6
                             gint             x_offset,
Packit 98cdb6
                             gint             y_offset,
Packit 98cdb6
                             XRectangle     **rects,
Packit 98cdb6
                             gint            *n_rects)
Packit 98cdb6
{
Packit 98cdb6
  XRectangle *rectangles = g_new (XRectangle, region->numRects);
Packit 98cdb6
  GdkRegionBox *boxes = region->rects;
Packit 98cdb6
  gint i;
Packit 98cdb6
  
Packit 98cdb6
  for (i = 0; i < region->numRects; i++)
Packit 98cdb6
    {
Packit 98cdb6
      rectangles[i].x = CLAMP (boxes[i].x1 + x_offset, G_MINSHORT, G_MAXSHORT);
Packit 98cdb6
      rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT);
Packit 98cdb6
      rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
Packit 98cdb6
      rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  *rects = rectangles;
Packit 98cdb6
  *n_rects = region->numRects;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_grab_server:
Packit 98cdb6
 * 
Packit 98cdb6
 * Call gdk_x11_display_grab() on the default display. 
Packit 98cdb6
 * To ungrab the server again, use gdk_x11_ungrab_server(). 
Packit 98cdb6
 *
Packit 98cdb6
 * gdk_x11_grab_server()/gdk_x11_ungrab_server() calls can be nested.
Packit 98cdb6
 **/ 
Packit 98cdb6
void
Packit 98cdb6
gdk_x11_grab_server (void)
Packit 98cdb6
{
Packit 98cdb6
  gdk_x11_display_grab (gdk_display_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_ungrab_server:
Packit 98cdb6
 *
Packit 98cdb6
 * Ungrab the default display after it has been grabbed with 
Packit 98cdb6
 * gdk_x11_grab_server(). 
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_x11_ungrab_server (void)
Packit 98cdb6
{
Packit 98cdb6
  gdk_x11_display_ungrab (gdk_display_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_default_screen:
Packit 98cdb6
 * 
Packit 98cdb6
 * Gets the default GTK+ screen number.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: returns the screen number specified by
Packit 98cdb6
 *   the --display command line option or the DISPLAY environment
Packit 98cdb6
 *   variable when gdk_init() calls XOpenDisplay().
Packit 98cdb6
 **/
Packit 98cdb6
gint
Packit 98cdb6
gdk_x11_get_default_screen (void)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_screen_get_number (gdk_screen_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_default_root_xwindow:
Packit 98cdb6
 * 
Packit 98cdb6
 * Gets the root window of the default screen 
Packit 98cdb6
 * (see gdk_x11_get_default_screen()).  
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: an Xlib <type>Window</type>.
Packit 98cdb6
 **/
Packit 98cdb6
Window
Packit 98cdb6
gdk_x11_get_default_root_xwindow (void)
Packit 98cdb6
{
Packit 98cdb6
  return GDK_SCREEN_XROOTWIN (gdk_screen_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_default_xdisplay:
Packit 98cdb6
 * 
Packit 98cdb6
 * Gets the default GTK+ display.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the Xlib <type>Display*</type> for the display
Packit 98cdb6
 * specified in the <option>--display</option> command line option 
Packit 98cdb6
 * or the <envar>DISPLAY</envar> environment variable.
Packit 98cdb6
 **/
Packit 98cdb6
Display *
Packit 98cdb6
gdk_x11_get_default_xdisplay (void)
Packit 98cdb6
{
Packit 98cdb6
  return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_MAIN_X11_C__
Packit 98cdb6
#include "gdkaliasdef.c"