Start of integration of Erwann Chenede's multihead work from the

Thu Apr 25 16:51:40 2002  Owen Taylor  <otaylor@redhat.com>

        Start of integration of Erwann Chenede's multihead work
        from the gtk-multihead branch.

        * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
        gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
        New classes representing a set of screens with attached
        input devices and a single contiguous area, respectively.

        * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
        gdk/x11/gdkprivate-x11.h: Make the initialization interface
        simple _gdk_windowing_init() and do the rest in
        gdk_open_display() calls.

        * gdk/gdk.[ch]: Add gdk_parse_args() which can be used
        to do the display-independent part of initialization
        instead of gdk_init_[check].

        * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
        gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
        Add multihead variants (_for_display(), for_screen()) of functions
        getting information specific to a particular screen screen or
        display.

        * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
        like gdk_rgb_get_colormap() that used to get/list global
        objects.

        * gdk/x11/gdkx.h: Add functions for converting GdkScreen
        and GdkDisplay into the X equivalents.

        * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
        not in the headers and unused.

        * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
        Remove gxid support ... has not been tested for a long time...
        "xfree" support is more portable to non XFree86.

        * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
        used to turn off functions that are inherently non-multihead
        safe.

        * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
        are used in non-multihead-safe ways.

        * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
        multihead safe.
This commit is contained in:
Owen Taylor 2002-04-25 22:29:14 +00:00 committed by Owen Taylor
parent e39e92123b
commit 425b9886c9
91 changed files with 6794 additions and 4396 deletions

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -1,3 +1,52 @@
Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com>
Start of integration of Erwann Chenede's multihead work
from the gtk-multihead branch.
* gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]
gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch]
New classes representing a set of screens with attached
input devices and a single contiguous area, respectively.
* gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c:
gdk/x11/gdkprivate-x11.h: Make the initialization interface
simple _gdk_windowing_init() and do the rest in
gdk_open_display() calls.
* gdk/gdk.[ch]: Add gdk_parse_args() which can be used
to do the display-independent part of initialization
instead of gdk_init_[check].
* gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h
gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h:
Add multihead variants (_for_display(), for_screen()) of functions
getting information specific to a particular screen screen or
display.
* gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions
like gdk_rgb_get_colormap() that used to get/list global
objects.
* gdk/x11/gdkx.h: Add functions for converting GdkScreen
and GdkDisplay into the X equivalents.
* gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords()
not in the headers and unused.
* configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}:
Remove gxid support ... has not been tested for a long time...
"xfree" support is more portable to non XFree86.
* gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be
used to turn off functions that are inherently non-multihead
safe.
* gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions
are used in non-multihead-safe ways.
* gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK
multihead safe.
Thu Apr 25 23:49:01 2002 Kristian Rietveld <kris@gtk.org>
Fixes #74206.

View File

@ -175,7 +175,7 @@ AC_ARG_ENABLE(xkb, [ --enable-xkb support XKB [default=maybe]],
, enable_xkb="maybe")
AC_ARG_ENABLE(rebuilds, [ --disable-rebuilds disable all source autogeneration rules],,enable_rebuilds=yes)
AC_ARG_WITH(xinput, [ --with-xinput=[no/gxi/xfree] support XInput ])
AC_ARG_WITH(xinput, [ --with-xinput=[no/yes] support XInput ])
AC_ARG_WITH(wintab, [ --with-wintab=DIRECTORY use Wintab API with win32 backend])
AC_ARG_WITH(ie55, [ --with-ie55=DIRECTORY IE5.5 libs and headers (for Active IMM)])
@ -1084,18 +1084,13 @@ if test "x$gdktarget" = "xx11"; then
# set up things for XInput
if test "x$with_xinput" = "xgxi" || test "x$with_xinput" = "xyes"; then
AC_DEFINE(XINPUT_GXI)
xinput_progs=gxid
x_extra_libs="-lXi $x_extra_libs"
elif test "x$with_xinput" = "xxfree"; then
if test "x$with_xinput" = "xxfree" || test "x$with_xinput" = "xyes"; then
AC_DEFINE(XINPUT_XFREE)
x_extra_libs="-lXi $x_extra_libs"
else
AC_DEFINE(XINPUT_NONE)
fi
AM_CONDITIONAL(XINPUT_GXI, test x$with_xinput = xgxi)
AM_CONDITIONAL(XINPUT_XFREE, test x$with_xinput = xxfree)
if test "x$enable_shm" = "xyes"; then

View File

@ -101,10 +101,9 @@ Creates a new colormap for the given visual.
<!-- ##### FUNCTION gdk_colormap_get_system ##### -->
<para>
Returns the system's default colormap.
</para>
@Returns: the default colormap.
@Returns:
<!-- ##### FUNCTION gdk_colormap_get_system_size ##### -->

View File

@ -79,24 +79,9 @@ locale.
<!-- ##### FUNCTION gdk_set_sm_client_id ##### -->
<para>
Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that
the window manager can save the application's state using the X11R6 ICCCM
session management protocol.
</para>
<para>
The leader window is automatically created by GDK and never shown. It's only
use is for session management. The <literal>WM_CLIENT_LEADER</literal> property is automatically
set on all X windows created by the application to point to the leader window.
</para>
<para>
See the X Session Management Library documentation for more information on
session management and the Inter-Client Communication Conventions Manual
(ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property.
(Both documents are part of the X Window System distribution.)
</para>
@sm_client_id: the client id assigned by the session manager when the
connection was opened, or %NULL to remove the property.
@sm_client_id:
<!-- ##### FUNCTION gdk_exit ##### -->

View File

@ -120,18 +120,14 @@ image is freed.</para></warning>
<!-- ##### FUNCTION gdk_image_get ##### -->
<para>
Gets part of a #GdkWindow and stores it in a new #GdkImage.
</para>
@drawable:
@x: the left edge of the rectangle to copy from @window.
@y: the top edge of the rectangle to copy from @window.
@width: the width of the area to copy, in pixels.
@height: the height of the area to copy, in pixels.
@Returns: a new #GdkImage with a copy of the given area of @window.
<!-- # Unused Parameters # -->
@window: the #GdkWindow to copy from.
@x:
@y:
@width:
@height:
@Returns:
<!-- ##### FUNCTION gdk_image_ref ##### -->
<para>

View File

@ -90,6 +90,7 @@ in the keymap and see what keyval it corresponds to.
</para>
@parent_instance:
@display:
<!-- ##### STRUCT GdkKeymapKey ##### -->
<para>

View File

@ -245,9 +245,6 @@ either @region or @rect.
<!-- ##### FUNCTION gdk_region_intersect ##### -->
<para>
Sets the area of @source1 to the intersection of the areas of @source1
and @source2. The resulting area is the set of pixels contained in
both @source1 and @source2.
</para>
@source1: a #GdkRegion
@ -278,13 +275,10 @@ area is the set of pixels contained in @source1 but not in @source2.
<!-- ##### FUNCTION gdk_region_xor ##### -->
<para>
Sets the area of @source1 to the exclusive-OR of the areas of @source1
and @source2. The resulting area is the set of pixels contained in one
or the other of the two sources but not in both.
</para>
@source1: a #GdkRegion
@source2: a #GdkRegion
@source1:
@source2:
<!-- ##### STRUCT GdkSpan ##### -->

View File

@ -407,14 +407,9 @@ private colormap.
<!-- ##### FUNCTION gdk_rgb_get_visual ##### -->
<para>
Gets a "preferred visual" chosen by GdkRGB. In previous versions of
GDK, this was the only visual GdkRGB could use for rendering. In
current versions, it's simply the visual GdkRGB would have chosen as
the optimal one in those previous versions. GdkRGB can now render to
drawables with any visual.
</para>
@Returns: The #GdkVisual chosen by GdkRGB.
@Returns:
<!-- ##### FUNCTION gdk_rgb_get_colormap ##### -->

View File

@ -108,6 +108,7 @@ pixel_from_rgb (GdkVisual *visual,
<structfield>blue_prec</structfield> give an alternate presentation
of the information in <structfield>blue_mask</structfield>.
@blue_prec: See above.
@screen:
<!-- ##### ENUM GdkVisualType ##### -->
<para>

View File

@ -245,6 +245,7 @@ the @window_at_pointer function in #GdkPointerHooks. It will be used
when GDK gets multihead support.
</para>
@parent_instance:
<!-- ##### FUNCTION gdk_window_new ##### -->
<para>

View File

@ -59,8 +59,10 @@ Returns the X window belonging to a #GdkWindow.
Returns the display of a #GdkPixmap.
</para>
@win: a #GdkPixmap.
@pix:
@Returns: an Xlib <type>Display*</type>.
<!-- # Unused Parameters # -->
@win: a #GdkPixmap.
<!-- ##### MACRO GDK_PIXMAP_XID ##### -->
@ -68,8 +70,10 @@ Returns the display of a #GdkPixmap.
Returns the X pixmap belonging to a #GdkPixmap.
</para>
@win: a #GdkPixmap.
@pix:
@Returns: the Xlib <type>XPixmap</type> of @win.
<!-- # Unused Parameters # -->
@win: a #GdkPixmap.
<!-- ##### MACRO GDK_DRAWABLE_XDISPLAY ##### -->

View File

@ -110,6 +110,8 @@ gdk_public_h_sources = @STRIP_BEGIN@ \
gdktypes.h \
gdkvisual.h \
gdkwindow.h \
gdkdisplay.h \
gdkscreen.h \
@STRIP_END@
gdk_headers = @STRIP_BEGIN@ \
@ -142,6 +144,8 @@ gdk_c_sources = @STRIP_BEGIN@ \
gdkregion-generic.c \
gdkregion-generic.h \
gdkwindow.c \
gdkdisplay.c \
gdkscreen.c \
@STRIP_END@
#

205
gdk/gdk.c
View File

@ -51,6 +51,8 @@ static int gdk_initialized = 0; /* 1 if the library is initialized,
*/
static gchar *gdk_progclass = NULL;
static gint gdk_argc = 0;
static gchar **gdk_argv = NULL;
#ifdef G_ENABLE_DEBUG
static const GDebugKey gdk_debug_keys[] = {
@ -66,6 +68,7 @@ static const GDebugKey gdk_debug_keys[] = {
{"image", GDK_DEBUG_IMAGE},
{"input", GDK_DEBUG_INPUT},
{"cursor", GDK_DEBUG_CURSOR},
{"multihead", GDK_DEBUG_MULTIHEAD},
};
static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys);
@ -233,8 +236,10 @@ gdk_arg_name_cb (const char *key, const char *value, gpointer user_data)
}
static GdkArgDesc gdk_args[] = {
{ "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb },
{ "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb },
{ "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb },
{ "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb },
{ "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL },
#ifdef G_ENABLE_DEBUG
{ "gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb },
{ "gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb },
@ -242,6 +247,116 @@ static GdkArgDesc gdk_args[] = {
{ NULL }
};
/**
* _gdk_get_command_line_args:
* @argv: location to store argv pointer
* @argc: location
*
* Retrieve the command line arguments passed to gdk_init().
* The returned argv pointer points to static storage ; no
* copy is made.
**/
void
_gdk_get_command_line_args (int *argc,
char ***argv)
{
*argc = gdk_argc;
*argv = gdk_argv;
}
/**
* gdk_parse_args:
* @argc: the number of command line arguments.
* @argv: the array of command line arguments.
*
* Parse command line arguments, and store for future
* use by calls to gdk_open_display().
*
* Any arguments used by GDK are removed from the array and @argc and @argv are
* updated accordingly.
*
* You shouldn't call this function explicitely if you are using
* gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check().
**/
void
gdk_parse_args (int *argc,
char ***argv)
{
GdkArgContext *arg_context;
gint i;
if (argc && argv)
{
gdk_argc = *argc;
gdk_argv = g_malloc ((gdk_argc + 1) * sizeof (char*));
for (i = 0; i < gdk_argc; i++)
gdk_argv[i] = g_strdup ((*argv)[i]);
gdk_argv[gdk_argc] = NULL;
if (*argc > 0)
{
gchar *d;
d = strrchr((*argv)[0], G_DIR_SEPARATOR);
if (d != NULL)
g_set_prgname (d + 1);
else
g_set_prgname ((*argv)[0]);
}
}
else
{
g_set_prgname ("<unknown>");
}
/* We set the fallback program class here, rather than lazily in
* gdk_get_program_class, since we don't want -name to override it.
*/
gdk_progclass = g_strdup (g_get_prgname ());
if (gdk_progclass[0])
gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
#ifdef G_ENABLE_DEBUG
{
gchar *debug_string = getenv("GDK_DEBUG");
if (debug_string != NULL)
_gdk_debug_flags = g_parse_debug_string (debug_string,
(GDebugKey *) gdk_debug_keys,
gdk_ndebug_keys);
}
#endif /* G_ENABLE_DEBUG */
arg_context = gdk_arg_context_new (NULL);
gdk_arg_context_add_table (arg_context, gdk_args);
gdk_arg_context_add_table (arg_context, _gdk_windowing_args);
gdk_arg_context_parse (arg_context, argc, argv);
gdk_arg_context_destroy (arg_context);
GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
g_type_init ();
/* Do any setup particular to the windowing system
*/
_gdk_windowing_init ();
}
/**
* gdk_get_display_arg_name:
*
* Gets the display name specified in the command line arguments passed
* to gdk_init() or gdk_parse_args(), if any.
*
* Returns: the display name, if specified explicitely, otherwise %NULL
*/
gchar *
gdk_get_display_arg_name (void)
{
return _gdk_display_name;
}
/*
*--------------------------------------------------------------
* gdk_init_check
@ -268,86 +383,24 @@ gboolean
gdk_init_check (int *argc,
char ***argv)
{
gchar **argv_orig = NULL;
gint argc_orig = 0;
GdkArgContext *arg_context;
gboolean result;
int i;
GdkDisplay *display;
if (gdk_initialized)
return TRUE;
if (argc && argv)
{
argc_orig = *argc;
argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*));
for (i = 0; i < argc_orig; i++)
argv_orig[i] = g_strdup ((*argv)[i]);
argv_orig[argc_orig] = NULL;
if (*argc > 0)
{
gchar *d;
d = strrchr((*argv)[0], G_DIR_SEPARATOR);
if (d != NULL)
g_set_prgname (d + 1);
else
g_set_prgname ((*argv)[0]);
}
}
else
{
g_set_prgname ("<unknown>");
}
/* We set the fallback program class here, rather than lazily in
* gdk_get_program_class, since we don't want -name to override it.
*/
gdk_progclass = g_strdup (g_get_prgname ());
if (gdk_progclass[0])
gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
#ifdef G_ENABLE_DEBUG
{
gchar *debug_string = getenv("GDK_DEBUG");
if (debug_string != NULL)
_gdk_debug_flags = g_parse_debug_string (debug_string,
(GDebugKey *) gdk_debug_keys,
gdk_ndebug_keys);
}
#endif /* G_ENABLE_DEBUG */
arg_context = gdk_arg_context_new (NULL);
gdk_arg_context_add_table (arg_context, gdk_args);
gdk_arg_context_add_table (arg_context, _gdk_windowing_args);
gdk_arg_context_parse (arg_context, argc, argv);
gdk_arg_context_destroy (arg_context);
GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
g_type_init ();
result = _gdk_windowing_init_check (argc_orig, argv_orig);
for (i = 0; i < argc_orig; i++)
g_free(argv_orig[i]);
g_free(argv_orig);
if (!result)
return FALSE;
_gdk_visual_init ();
_gdk_windowing_window_init ();
_gdk_windowing_image_init ();
_gdk_events_init ();
_gdk_input_init ();
_gdk_dnd_init ();
gdk_parse_args (argc, argv);
gdk_initialized = 1;
return TRUE;
display = gdk_open_display (_gdk_display_name);
if (display)
{
gdk_set_default_display (display);
return TRUE;
}
else
return FALSE;
}
void
@ -355,7 +408,7 @@ gdk_init (int *argc, char ***argv)
{
if (!gdk_init_check (argc, argv))
{
g_warning ("cannot open display: %s", gdk_get_display ());
g_warning ("cannot open display: %s", gdk_get_display_arg_name ());
exit(1);
}
}

View File

@ -29,6 +29,7 @@
#include <gdk/gdkcolor.h>
#include <gdk/gdkcursor.h>
#include <gdk/gdkdisplay.h>
#include <gdk/gdkdnd.h>
#include <gdk/gdkdrawable.h>
#include <gdk/gdkenumtypes.h>
@ -44,6 +45,7 @@
#include <gdk/gdkproperty.h>
#include <gdk/gdkregion.h>
#include <gdk/gdkrgb.h>
#include <gdk/gdkscreen.h>
#include <gdk/gdkselection.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkvisual.h>
@ -57,6 +59,8 @@ extern "C" {
/* Initialization, exit and events
*/
#define GDK_PRIORITY_EVENTS (G_PRIORITY_DEFAULT)
void gdk_parse_args (gint *argc,
gchar ***argv);
void gdk_init (gint *argc,
gchar ***argv);
gboolean gdk_init_check (gint *argc,
@ -81,6 +85,7 @@ gboolean gdk_get_use_xshm (void);
#endif /* GDK_DISABLE_DEPRECATED */
gchar* gdk_get_display (void);
gchar* gdk_get_display_arg_name (void);
#ifndef GDK_DISABLE_DEPRECATED
gint gdk_input_add_full (gint source,
@ -101,10 +106,12 @@ GdkGrabStatus gdk_pointer_grab (GdkWindow *window,
GdkWindow *confine_to,
GdkCursor *cursor,
guint32 time);
void gdk_pointer_ungrab (guint32 time);
GdkGrabStatus gdk_keyboard_grab (GdkWindow *window,
gboolean owner_events,
guint32 time);
#ifndef GDK_MULTIHEAD_SAFE
void gdk_pointer_ungrab (guint32 time);
void gdk_keyboard_ungrab (guint32 time);
gboolean gdk_pointer_is_grabbed (void);
@ -114,10 +121,14 @@ gint gdk_screen_height (void) G_GNUC_CONST;
gint gdk_screen_width_mm (void) G_GNUC_CONST;
gint gdk_screen_height_mm (void) G_GNUC_CONST;
void gdk_flush (void);
void gdk_beep (void);
#endif /* GDK_MULTIHEAD_SAFE */
void gdk_set_double_click_time (guint msec);
void gdk_flush (void);
#ifndef GDK_MULTIHEAD_SAFE
void gdk_set_double_click_time (guint msec);
#endif
/* Rectangle utilities
*/
@ -140,10 +151,14 @@ gint gdk_mbstowcs (GdkWChar *dest,
gint dest_max);
/* Miscellaneous */
void gdk_event_send_clientmessage_toall (GdkEvent *event);
gboolean gdk_event_send_client_message (GdkEvent *event,
guint32 xid);
#ifndef GDK_MULTIHEAD_SAFE
gboolean gdk_event_send_client_message (GdkEvent *event,
guint32 xid);
void gdk_event_send_clientmessage_toall (GdkEvent *event);
#endif
gboolean gdk_event_send_client_message_for_display (GdkDisplay *display,
GdkEvent *event,
guint32 xid);
/* Threading
*/

View File

@ -48,6 +48,7 @@ struct _GdkColormap
GdkVisual *visual;
gpointer windowing_data;
GdkScreen *screen;
};
struct _GdkColormapClass
@ -66,9 +67,13 @@ GdkColormap* gdk_colormap_ref (GdkColormap *cmap);
void gdk_colormap_unref (GdkColormap *cmap);
#endif
GdkColormap* gdk_colormap_get_system (void);
#ifndef GDK_MULTIHEAD_SAFE
GdkColormap* gdk_colormap_get_system (void);
#endif
#ifndef GDK_DISABLE_DEPRECATED
gint gdk_colormap_get_system_size (void);
gint gdk_colormap_get_system_size (void);
void gdk_colormap_change (GdkColormap *colormap,
gint ncolors);
#endif

View File

@ -105,13 +105,18 @@ struct _GdkCursor
GType gdk_cursor_get_type (void);
GdkCursor* gdk_cursor_new_for_screen (GdkScreen *screen,
GdkCursorType cursor_type);
#ifndef GDK_MULTIHEAD_SAFE
GdkCursor* gdk_cursor_new (GdkCursorType cursor_type);
#endif
GdkCursor* gdk_cursor_new_from_pixmap (GdkPixmap *source,
GdkPixmap *mask,
GdkColor *fg,
GdkColor *bg,
gint x,
gint y);
GdkScreen* gdk_cursor_get_screen (GdkCursor *cursor);
GdkCursor* gdk_cursor_ref (GdkCursor *cursor);
void gdk_cursor_unref (GdkCursor *cursor);

292
gdk/gdkdisplay.c Normal file
View File

@ -0,0 +1,292 @@
/* GDK - The GIMP Drawing Kit
* gdkdisplay.c
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include "gdkdisplay.h"
#include "gdkinternals.h"
static void gdk_display_class_init (GdkDisplayClass *class);
static void gdk_display_init (GdkDisplay *display);
static void gdk_display_finalize (GObject *object);
static GdkDisplay *default_display = NULL;
static GObjectClass *parent_class;
GType
gdk_display_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info = {
sizeof (GdkDisplayClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gdk_display_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkDisplay),
0, /* n_preallocs */
(GInstanceInitFunc) gdk_display_init
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"GdkDisplay", &object_info, 0);
}
return object_type;
}
static void
gdk_display_class_init (GdkDisplayClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
parent_class = g_type_class_peek_parent (class);
object_class->finalize = gdk_display_finalize;
}
static void
gdk_display_init (GdkDisplay *display)
{
_gdk_displays = g_slist_prepend (_gdk_displays, display);
display->button_click_time[0] = display->button_click_time[1] = 0;
display->button_window[0] = display->button_window[1] = NULL;
display->button_number[0] = display->button_number[1] = -1;
display->double_click_time = 250;
}
static void
gdk_display_finalize (GObject *object)
{
GdkDisplay *display = GDK_DISPLAY_OBJECT (object);
_gdk_displays = g_slist_remove (_gdk_displays, display);
if (default_display == display)
default_display = NULL;
parent_class->finalize (object);
}
/**
* gdk_display_get_name:
* @display: a #GdkDisplay
*
* Gets the name of the display.
*
* Returns: a string representing the display name.
*/
G_CONST_RETURN gchar *
gdk_display_get_name (GdkDisplay * display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return GDK_DISPLAY_GET_CLASS (display)->get_display_name (display);
}
/**
* gdk_display_get_n_screens:
* @display: a #GdkDisplay
*
* Gets the number of screen managed by the @display.
*
* Returns: number of screens.
*/
gint
gdk_display_get_n_screens (GdkDisplay * display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
return GDK_DISPLAY_GET_CLASS (display)->get_n_screens (display);
}
/**
* gdk_display_get_screen:
* @display: a #GdkDisplay
* @screen_num: the screen number
*
* Returns a screen object for one of the screens of the display.
*
* Returns: the #GdkScreen object
*/
GdkScreen *
gdk_display_get_screen (GdkDisplay * display, gint screen_num)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return GDK_DISPLAY_GET_CLASS (display)->get_screen (display, screen_num);
}
/**
* gdk_display_get_default_screen:
* @display: a #GdkDisplay
*
* Get the default #GdkScreen for @display.
*
* Returns: the default #GdkScreen object for @display
*/
GdkScreen *
gdk_display_get_default_screen (GdkDisplay * display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return GDK_DISPLAY_GET_CLASS (display)->get_default_screen (display);
}
/**
* gdk_display_close:
* @display: a #GdkDisplay
*
* Closes and cleanup the resources used by the @display
*/
void
gdk_display_close (GdkDisplay *display)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
g_object_unref (G_OBJECT (display));
}
/**
* gdk_set_default_display:
* @display: a #GdkDisplay
*
* Sets @display as the default display.
**/
void
gdk_set_default_display (GdkDisplay *display)
{
default_display = display;
}
/**
* gdk_get_default_display:
*
* Gets the default #GdkDisplay.
*
* Returns: a #GdkDisplay, or %NULL if there is no default
* display.
*/
GdkDisplay *
gdk_get_default_display (void)
{
return default_display;
}
/**
* gdk_get_default_screen:
*
* Gets the default screen for the default display. (See
* gdk_get_default_display ()).
*
* Returns: a #GdkScreen.
*/
GdkScreen *
gdk_get_default_screen (void)
{
return gdk_display_get_default_screen (gdk_get_default_display ());
}
/**
* gdk_list_displays:
*
* List all currently open displays.
*
* Return value: a newly allocated #GSList of #GdkDisplay objects.
* Free this list with g_slist_free() when you are done with it.
**/
GSList *
gdk_list_displays (void)
{
return g_slist_copy (_gdk_displays);
}
/**
* gdk_display_get_event:
* @display: a #GdkDisplay
* @event: a #GdkEvent
*
* Gets the next #GdkEvent to be processed for @display, fetching events from the
* windowing system if necessary.
*
* Return value: the next #GdkEvent to be processed, or %NULL if no events
* are pending. The returned #GdkEvent should be freed with gdk_event_free().
**/
GdkEvent*
gdk_display_get_event (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
_gdk_events_queue (display);
return _gdk_event_unqueue (display);
}
/**
* gdk_display_peek_event:
* @void:
*
* Gets a copy of the first #GdkEvent in the @display's event queue, without
* removing the event from the queue. (Note that this function will
* not get more events from the windowing system. It only checks the events
* that have already been moved to the GDK event queue.)
*
* Return value: a copy of the first #GdkEvent on the event queue, or %NULL if no
* events are in the queue. The returned #GdkEvent should be freed with
* gdk_event_free().
**/
GdkEvent*
gdk_display_peek_event (GdkDisplay *display)
{
GList *tmp_list;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
tmp_list = _gdk_event_queue_find_first (display);
if (tmp_list)
return gdk_event_copy (tmp_list->data);
else
return NULL;
}
/**
* gdk_display_put_event:
* @display: a #GdkDisplay
* @event: a #GdkEvent.
*
* Appends a copy of the given event onto the front of the event
* queue for @display.
**/
void
gdk_display_put_event (GdkDisplay *display,
GdkEvent *event)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
g_return_if_fail (event != NULL);
_gdk_event_queue_append (display, gdk_event_copy (event));
}

112
gdk/gdkdisplay.h Normal file
View File

@ -0,0 +1,112 @@
/*
* gdkdisplay.h
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GDK_DISPLAY_H__
#define __GDK_DISPLAY_H__
#include <gdk/gdktypes.h>
#include <gdk/gdkevents.h>
#include <glib-object.h>
G_BEGIN_DECLS
typedef struct _GdkDisplayClass GdkDisplayClass;
#define GDK_TYPE_DISPLAY (gdk_display_get_type ())
#define GDK_DISPLAY_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY, GdkDisplay))
#define GDK_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY, GdkDisplayClass))
#define GDK_IS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY))
#define GDK_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY))
#define GDK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY, GdkDisplayClass))
struct _GdkDisplay
{
GObject parent_instance;
/*< private >*/
GList *queued_events;
GList *queued_tail;
/* Information for determining if the latest button click
* is part of a double-click or triple-click
*/
guint32 button_click_time[2]; /* The last 2 button click times. */
GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. */
guint button_number[2]; /* The last 2 buttons to be pressed. */
guint double_click_time; /* Maximum time between clicks in msecs */
};
struct _GdkDisplayClass
{
GObjectClass parent_class;
G_CONST_RETURN gchar * (*get_display_name) (GdkDisplay *display);
gint (*get_n_screens) (GdkDisplay *display);
GdkScreen * (*get_screen) (GdkDisplay *display,
gint screen_num);
GdkScreen * (*get_default_screen) (GdkDisplay *display);
};
GType gdk_display_get_type (void);
GdkDisplay *gdk_open_display (const gchar *display_name);
G_CONST_RETURN gchar * gdk_display_get_name (GdkDisplay *display);
gint gdk_display_get_n_screens (GdkDisplay *display);
GdkScreen * gdk_display_get_screen (GdkDisplay *display,
gint screen_num);
GdkScreen * gdk_display_get_default_screen (GdkDisplay *display);
void gdk_display_pointer_ungrab (GdkDisplay *display,
guint32 time);
void gdk_display_keyboard_ungrab (GdkDisplay *display,
guint32 time);
gboolean gdk_display_pointer_is_grabbed (GdkDisplay *display);
void gdk_display_beep (GdkDisplay *display);
void gdk_display_sync (GdkDisplay *display);
void gdk_display_close (GdkDisplay *display);
GList * gdk_display_list_devices (GdkDisplay *display);
GdkEvent* gdk_display_get_event (GdkDisplay *display);
GdkEvent* gdk_display_peek_event (GdkDisplay *display);
void gdk_display_put_event (GdkDisplay *display,
GdkEvent *event);
void gdk_display_add_client_message_filter (GdkDisplay *display,
GdkAtom message_type,
GdkFilterFunc func,
gpointer data);
void gdk_display_set_double_click_time (GdkDisplay *display,
guint msec);
void gdk_display_set_sm_client_id (GdkDisplay *display,
const gchar *sm_client_id);
void gdk_set_default_display (GdkDisplay *display);
GdkDisplay *gdk_get_default_display (void);
G_END_DECLS
#endif /* __GDK_DISPLAY_H__ */

View File

@ -101,8 +101,15 @@ GdkAtom gdk_drag_get_selection (GdkDragContext *context);
GdkDragContext * gdk_drag_begin (GdkWindow *window,
GList *targets);
guint32 gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol);
guint32 gdk_drag_get_protocol_for_display (GdkDisplay *display,
guint32 xid,
GdkDragProtocol *protocol);
#ifndef GDK_MULTIHEAD_SAFE
guint32 gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol);
#endif /* GDK_MULTIHEAD_SAFE */
void gdk_drag_find_window (GdkDragContext *context,
GdkWindow *drag_window,
gint x_root,

View File

@ -27,6 +27,7 @@
#include "gdkdrawable.h"
#include "gdkinternals.h"
#include "gdkwindow.h"
#include "gdkscreen.h"
#include "gdk-pixbuf-private.h"
#include "gdkpixbuf.h"
@ -202,7 +203,38 @@ gdk_drawable_get_depth (GdkDrawable *drawable)
return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
}
/**
* gdk_drawable_get_screen:
* @drawable: a #GdkDrawable
*
* Gets the #GdkScreen associated with a #GdkDrawable.
*
* Return value: the #GdkScreen associated with @drawable
**/
GdkScreen*
gdk_drawable_get_screen(GdkDrawable *drawable)
{
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
return GDK_DRAWABLE_GET_CLASS (drawable)->get_screen (drawable);
}
/**
* gdk_drawable_get_display:
* @drawable: a #GdkDrawable
*
* Gets the #GdkDisplay associated with a #GdkDrawable.
*
* Return value: the #GdkDisplay associated with @drawable
**/
GdkDisplay*
gdk_drawable_get_display (GdkDrawable *drawable)
{
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
return gdk_screen_get_display (gdk_drawable_get_screen (drawable));
}
/**
* gdk_drawable_set_colormap:
* @drawable: a #GdkDrawable
@ -1216,7 +1248,8 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
*/
if (visual)
{
gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (visual->depth);
gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
visual->depth);
if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
visual->depth == 16 &&
@ -1245,7 +1278,9 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
GdkImage *image = _gdk_image_get_scratch (width1, height1, gdk_drawable_get_depth (drawable), &xs0, &ys0);
GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
width1, height1,
gdk_drawable_get_depth (drawable), &xs0, &ys0);
_gdk_drawable_copy_to_image (drawable, image,
dest_x + x0, dest_y + y0,

View File

@ -113,8 +113,9 @@ struct _GdkDrawableClass
void (*set_colormap) (GdkDrawable *drawable,
GdkColormap *cmap);
GdkColormap* (*get_colormap) (GdkDrawable *drawable);
GdkVisual* (*get_visual) (GdkDrawable *drawable);
GdkColormap* (*get_colormap) (GdkDrawable *drawable);
GdkVisual* (*get_visual) (GdkDrawable *drawable);
GdkScreen* (*get_screen) (GdkDrawable *drawable);
GdkImage* (*get_image) (GdkDrawable *drawable,
gint x,
@ -194,6 +195,8 @@ void gdk_drawable_set_colormap (GdkDrawable *drawable,
GdkColormap* gdk_drawable_get_colormap (GdkDrawable *drawable);
GdkVisual* gdk_drawable_get_visual (GdkDrawable *drawable);
gint gdk_drawable_get_depth (GdkDrawable *drawable);
GdkScreen* gdk_drawable_get_screen (GdkDrawable *drawable);
GdkDisplay* gdk_drawable_get_display (GdkDrawable *drawable);
#ifndef GDK_DISABLE_DEPRECATED
GdkDrawable* gdk_drawable_ref (GdkDrawable *drawable);

View File

@ -55,22 +55,11 @@ struct _GdkEventPrivate
/* Private variable declarations
*/
static guint32 button_click_time[2] = { 0, 0}; /* The last 2 button click times. Used
* to determine if the latest button click
* is part of a double or triple click.
*/
static GdkWindow *button_window[2] = { NULL, NULL}; /* The last 2 windows to receive button presses.
* Also used to determine if the latest button
* click is part of a double or triple click.
*/
static guint button_number[2] = { -1, -1 }; /* The last 2 buttons to be pressed.
*/
GdkEventFunc _gdk_event_func = NULL; /* Callback for events */
gpointer _gdk_event_data = NULL;
GDestroyNotify _gdk_event_notify = NULL;
static guint double_click_time = 250;
#define TRIPLE_CLICK_TIME (2*double_click_time)
#define TRIPLE_CLICK_TIME(display) (2*display->double_click_time)
#define DOUBLE_CLICK_DIST 5
#define TRIPLE_CLICK_DIST 5
@ -78,20 +67,19 @@ static guint double_click_time = 250;
* Functions for maintaining the event queue *
*********************************************/
/*************************************************************
/**
* _gdk_event_queue_find_first:
* Find the first event on the queue that is not still
* being filled in.
* arguments:
*
* results:
* Pointer to the list node for that event, or NULL
*************************************************************/
* @display: a #GdkDisplay
*
* Find the first event on the queue that is not still
* being filled in.
*
* Return value: Pointer to the list node for that event, or NULL.
**/
GList*
_gdk_event_queue_find_first (void)
_gdk_event_queue_find_first (GdkDisplay *display)
{
GList *tmp_list = _gdk_queued_events;
GList *tmp_list = display->queued_events;
while (tmp_list)
{
@ -105,58 +93,93 @@ _gdk_event_queue_find_first (void)
return NULL;
}
/*************************************************************
* _gdk_event_queue_remove_link:
* Remove a specified list node from the event queue.
* arguments:
* node: Node to remove.
* results:
*************************************************************/
/**
* _gdk_event_queue_append:
* @display: a #GdkDisplay
* @event: Event to append.
*
* Appends an event onto the tail of the event queue.
*
* Returns: the newly appended list node.
**/
GList *
_gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event)
{
display->queued_tail = g_list_append (display->queued_tail, event);
if (!display->queued_events)
display->queued_events = display->queued_tail;
else
display->queued_tail = display->queued_tail->next;
return display->queued_tail;
}
/**
* _gdk_event_queue_remove_link:
* @display: a #GdkDisplay
* @node: node to remove
*
* Removes a specified list node from the event queue.
**/
void
_gdk_event_queue_remove_link (GList *node)
_gdk_event_queue_remove_link (GdkDisplay *display,
GList *node)
{
if (node->prev)
node->prev->next = node->next;
else
_gdk_queued_events = node->next;
display->queued_events = node->next;
if (node->next)
node->next->prev = node->prev;
else
_gdk_queued_tail = node->prev;
display->queued_tail = node->prev;
}
/*************************************************************
* _gdk_event_queue_append:
* Append an event onto the tail of the event queue.
* arguments:
* event: Event to append.
* results:
*************************************************************/
void
_gdk_event_queue_append (GdkEvent *event)
{
_gdk_queued_tail = g_list_append (_gdk_queued_tail, event);
if (!_gdk_queued_events)
_gdk_queued_events = _gdk_queued_tail;
else
_gdk_queued_tail = _gdk_queued_tail->next;
}
/*************************************************************
* gdk_event_handler_set:
*
* arguments:
* func: Callback function to be called for each event.
* data: Data supplied to the function
* notify: function called when function is no longer needed
/**
* _gdk_event_unqueue:
* @display: a #GdkDisplay
*
* results:
*************************************************************/
* Removes and returns the first event from the event
* queue that is not still being filled in.
*
* Return value: the event, or %NULL. Ownership is transferred
* to the caller.
**/
GdkEvent*
_gdk_event_unqueue (GdkDisplay *display)
{
GdkEvent *event = NULL;
GList *tmp_list;
tmp_list = _gdk_event_queue_find_first (display);
if (tmp_list)
{
event = tmp_list->data;
_gdk_event_queue_remove_link (display, tmp_list);
g_list_free_1 (tmp_list);
}
return event;
}
/**
* gdk_event_handler_set:
* @func: the function to call to handle events from GDK.
* @data: user data to pass to the function.
* @notify: the function to call when the handler function is removed, i.e. when
* gdk_event_handler_set() is called with another event handler.
*
* Sets the function to call to handle all events from GDK.
*
* Note that GTK+ uses this to install its own event handler, so it is
* usually not useful for GTK+ applications. (Although an application
* can call this function then call gtk_main_do_event() to pass
* events to GTK+.)
**/
void
gdk_event_handler_set (GdkEventFunc func,
gpointer data,
@ -170,94 +193,83 @@ gdk_event_handler_set (GdkEventFunc func,
_gdk_event_notify = notify;
}
/*
*--------------------------------------------------------------
* gdk_event_get
*
* Gets the next event.
*
* Arguments:
*
* Results:
* If an event is waiting that we care about, returns
* a pointer to that event, to be freed with gdk_event_free.
* Otherwise, returns NULL.
*
* Side effects:
*
*--------------------------------------------------------------
*/
/**
* gdk_event_get:
*
* Checks all open displays for a #GdkEvent to process,to be processed
* on, fetching events from the windowing system if necessary.
* See gdk_display_get_event().
*
* Return value: the next #GdkEvent to be processed, or %NULL if no events
* are pending. The returned #GdkEvent should be freed with gdk_event_free().
**/
GdkEvent*
gdk_event_get (void)
{
_gdk_events_queue ();
GSList *tmp_list;
return _gdk_event_unqueue ();
for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
{
GdkEvent *event = gdk_display_get_event (tmp_list->data);
if (event)
return event;
}
return NULL;
}
/*
*--------------------------------------------------------------
* gdk_event_peek
/**
* gdk_event_peek:
*
* Gets the next event.
*
* Arguments:
*
* Results:
* If an event is waiting that we care about, returns
* a copy of that event, but does not remove it from
* the queue. The pointer is to be freed with gdk_event_free.
* Otherwise, returns NULL.
*
* Side effects:
*
*--------------------------------------------------------------
*/
* If there is an event waiting in the event queue of some open
* display, returns a copy of it. See gdk_display_peek_event().
*
* Return value: a copy of the first #GdkEvent on some event queue, or %NULL if no
* events are in any queues. The returned #GdkEvent should be freed with
* gdk_event_free().
**/
GdkEvent*
gdk_event_peek (void)
{
GList *tmp_list;
GSList *tmp_list;
tmp_list = _gdk_event_queue_find_first ();
if (tmp_list)
return gdk_event_copy (tmp_list->data);
else
return NULL;
for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
{
GdkEvent *event = gdk_display_peek_event (tmp_list->data);
if (event)
return event;
}
return NULL;
}
/**
* gdk_event_put:
* @event: a #GdkEvent.
*
* Appends a copy of the given event onto the front of the event
* queue for event->any.window's display, or the default event
* queue if event->any.window is %NULL. See gdk_display_put_event().
**/
void
gdk_event_put (GdkEvent *event)
{
GdkEvent *new_event;
GdkDisplay *display;
g_return_if_fail (event != NULL);
new_event = gdk_event_copy (event);
_gdk_event_queue_append (new_event);
if (event->any.window)
display = gdk_drawable_get_display (event->any.window);
else
{
GDK_NOTE (MULTIHEAD,
g_message ("Falling back to default display for gdk_event_put()"));
display = gdk_get_default_display ();
}
gdk_display_put_event (display, event);
}
/*
*--------------------------------------------------------------
* gdk_event_copy
*
* Copy a event structure into new storage.
*
* Arguments:
* "event" is the event struct to copy.
*
* Results:
* A new event structure. Free it with gdk_event_free.
*
* Side effects:
* The reference count of the window in the event is increased.
*
*--------------------------------------------------------------
*/
static GMemChunk *event_chunk = NULL;
GdkEvent*
@ -277,6 +289,16 @@ _gdk_event_new (void)
return (GdkEvent*) new_event;
}
/**
* gdk_event_copy:
* @event: a #GdkEvent
*
* Copies a #GdkEvent, copying or incrementing the reference count of the
* resources associated with it (e.g. #GdkWindow's and strings).
*
* Return value: a copy of @event. The returned #GdkEvent should be freed with
* gdk_event_free().
**/
GdkEvent*
gdk_event_copy (GdkEvent *event)
{
@ -328,24 +350,15 @@ gdk_event_copy (GdkEvent *event)
return new_event;
}
/*
*--------------------------------------------------------------
* gdk_event_free
*
* Free a event structure obtained from gdk_event_copy. Do not use
* with other event structures.
*
* Arguments:
* "event" is the event struct to free.
*
* Results:
*
* Side effects:
* The reference count of the window in the event is decreased and
* might be freed, too.
*
*-------------------------------------------------------------- */
/**
* gdk_event_free:
* @event: a #GdkEvent.
*
* Frees a #GdkEvent, freeing or decrementing any resources associated with it.
* Note that this function should only be called with events returned from
* gdk_event_peek(), gdk_event_get(), gdk_event_get_graphics_expose() and
* gdk_event_copy().
**/
void
gdk_event_free (GdkEvent *event)
{
@ -740,26 +753,15 @@ gdk_event_get_axis (GdkEvent *event,
return gdk_device_get_axis (device, axes, axis_use, value);
}
/*
*--------------------------------------------------------------
* gdk_set_show_events
*
* Turns on/off the showing of events.
*
* Arguments:
* "show_events" is a boolean describing whether or
* not to show the events gdk receives.
*
* Results:
*
* Side effects:
* When "show_events" is TRUE, calls to "gdk_event_get"
* will output debugging informatin regarding the event
* received to stdout.
*
*--------------------------------------------------------------
*/
/**
* gdk_set_show_events:
* @show_events: %TRUE to output event debugging information.
*
* Sets whether a trace of received events is output.
* Note that GTK+ must be compiled with debugging (that is,
* configured using the <option>--enable-debug</option> option)
* to use this option.
**/
void
gdk_set_show_events (gboolean show_events)
{
@ -769,6 +771,13 @@ gdk_set_show_events (gboolean show_events)
_gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
}
/**
* gdk_get_show_events:
*
* Returns non-zero if event debugging output is enabled.
*
* Return value: non-zero if event debugging output is enabled.
**/
gboolean
gdk_get_show_events (void)
{
@ -861,27 +870,10 @@ gdk_input_remove (gint tag)
g_source_remove (tag);
}
GdkEvent*
_gdk_event_unqueue (void)
{
GdkEvent *event = NULL;
GList *tmp_list;
tmp_list = _gdk_event_queue_find_first ();
if (tmp_list)
{
event = tmp_list->data;
_gdk_event_queue_remove_link (tmp_list);
g_list_free_1 (tmp_list);
}
return event;
}
static void
gdk_synthesize_click (GdkEvent *event,
gint nclicks)
gdk_synthesize_click (GdkDisplay *display,
GdkEvent *event,
gint nclicks)
{
GdkEvent temp_event;
@ -890,50 +882,50 @@ gdk_synthesize_click (GdkEvent *event,
temp_event = *event;
temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
gdk_event_put (&temp_event);
gdk_display_put_event (display, &temp_event);
}
void
_gdk_event_button_generate (GdkEvent *event)
_gdk_event_button_generate (GdkDisplay *display,
GdkEvent *event)
{
if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
(event->button.window == button_window[1]) &&
(event->button.button == button_number[1]))
if ((event->button.time < (display->button_click_time[1] + TRIPLE_CLICK_TIME (display))) &&
(event->button.window == display->button_window[1]) &&
(event->button.button == display->button_number[1]))
{
gdk_synthesize_click (event, 3);
gdk_synthesize_click (display, event, 3);
button_click_time[1] = 0;
button_click_time[0] = 0;
button_window[1] = NULL;
button_window[0] = 0;
button_number[1] = -1;
button_number[0] = -1;
display->button_click_time[1] = 0;
display->button_click_time[0] = 0;
display->button_window[1] = NULL;
display->button_window[0] = 0;
display->button_number[1] = -1;
display->button_number[0] = -1;
}
else if ((event->button.time < (button_click_time[0] + double_click_time)) &&
(event->button.window == button_window[0]) &&
(event->button.button == button_number[0]))
else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) &&
(event->button.window == display->button_window[0]) &&
(event->button.button == display->button_number[0]))
{
gdk_synthesize_click (event, 2);
gdk_synthesize_click (display, event, 2);
button_click_time[1] = button_click_time[0];
button_click_time[0] = event->button.time;
button_window[1] = button_window[0];
button_window[0] = event->button.window;
button_number[1] = button_number[0];
button_number[0] = event->button.button;
display->button_click_time[1] = display->button_click_time[0];
display->button_click_time[0] = event->button.time;
display->button_window[1] = display->button_window[0];
display->button_window[0] = event->button.window;
display->button_number[1] = display->button_number[0];
display->button_number[0] = event->button.button;
}
else
{
button_click_time[1] = 0;
button_click_time[0] = event->button.time;
button_window[1] = NULL;
button_window[0] = event->button.window;
button_number[1] = -1;
button_number[0] = event->button.button;
display->button_click_time[1] = 0;
display->button_click_time[0] = event->button.time;
display->button_window[1] = NULL;
display->button_window[0] = event->button.window;
display->button_number[1] = -1;
display->button_number[0] = event->button.button;
}
}
void
gdk_synthesize_window_state (GdkWindow *window,
GdkWindowState unset_flags,
@ -975,7 +967,7 @@ gdk_synthesize_window_state (GdkWindow *window,
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_DIALOG:
case GDK_WINDOW_TEMP: /* ? */
gdk_event_put (&temp_event);
gdk_display_put_event (gdk_drawable_get_display (window), &temp_event);
break;
case GDK_WINDOW_FOREIGN:
@ -986,18 +978,33 @@ gdk_synthesize_window_state (GdkWindow *window,
}
/**
* gdk_set_double_click_time:
* @msec: double click time in milliseconds (thousandths of a second)
*
* gdk_display_set_double_click_time:
* @display: a #GdkDisplay
* @msec: double click time in milliseconds (thousandths of a second)
*
* Sets the double click time (two clicks within this time interval
* count as a double click and result in a #GDK_2BUTTON_PRESS event).
* Applications should NOT set this, it is a global user-configured setting.
**/
void
gdk_set_double_click_time_for_display (GdkDisplay *display,
guint msec)
{
display->double_click_time = msec;
}
/**
* gdk_set_double_click_time:
* @msec: double click time in milliseconds (thousandths of a second)
*
* Set the double click time for the default display. See
* gdk_display_set_double_click_time(). Applications should NOT
* set this, it is a global user-configured setting.
**/
void
gdk_set_double_click_time (guint msec)
{
double_click_time = msec;
gdk_set_double_click_time_for_display (gdk_get_default_display (), msec);
}
GType

View File

@ -472,16 +472,14 @@ void gdk_event_handler_set (GdkEventFunc func,
void gdk_set_show_events (gboolean show_events);
gboolean gdk_get_show_events (void);
/*
* The following function adds a global filter for all client
* messages of type message_type
*/
#ifndef GDK_MULTIHEAD_SAFE
void gdk_add_client_message_filter (GdkAtom message_type,
GdkFilterFunc func,
gpointer data);
gboolean gdk_setting_get (const gchar *name,
GValue *value);
#endif /* GDK_MULTIHEAD_SAFE */
#ifdef __cplusplus
}

View File

@ -31,9 +31,18 @@ struct _GdkFont
GType gdk_font_get_type (void);
#ifndef GDK_MULTIHEAD_SAFE
GdkFont* gdk_font_load (const gchar *font_name);
GdkFont* gdk_fontset_load (const gchar *fontset_name);
GdkFont* gdk_font_from_description (PangoFontDescription *font_desc);
#endif
GdkFont *gdk_font_load_for_display (GdkDisplay *display,
const gchar *font_name);
GdkFont *gdk_fontset_load_for_display (GdkDisplay *display,
const gchar *fontset_name);
GdkFont *gdk_font_from_description_for_display (GdkDisplay *display,
PangoFontDescription *font_desc);
GdkFont* gdk_font_ref (GdkFont *font);
void gdk_font_unref (GdkFont *font);
@ -92,6 +101,8 @@ void gdk_string_extents (GdkFont *font,
gint *ascent,
gint *descent);
GdkDisplay * gdk_font_get_display (GdkFont *font);
#ifdef GDK_WINDOWING_WIN32
/* Ditto temporary */
gchar* gdk_font_full_name_get (GdkFont *font);

View File

@ -263,6 +263,7 @@ void gdk_gc_set_rgb_fg_color (GdkGC *gc,
GdkColor *color);
void gdk_gc_set_rgb_bg_color (GdkGC *gc,
GdkColor *color);
GdkScreen * gdk_gc_get_screen (GdkGC *gc);
#ifndef GDK_DISABLE_DEPRECATED
#define gdk_gc_destroy gdk_gc_unref

View File

@ -30,13 +30,13 @@
#include "gdkprivate.h"
#include "config.h"
guint _gdk_debug_flags = 0;
GdkWindow *_gdk_parent_root = NULL;
gint _gdk_error_code = 0;
gint _gdk_error_warnings = TRUE;
GList *_gdk_default_filters = NULL;
GList *_gdk_queued_events = NULL;
GList *_gdk_queued_tail = NULL;
guint _gdk_debug_flags = 0;
gint _gdk_error_code = 0;
gint _gdk_error_warnings = TRUE;
GList *_gdk_default_filters = NULL;
gchar *_gdk_display_name = NULL;
GSList *_gdk_displays = NULL;
GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */

View File

@ -188,6 +188,8 @@ struct _GdkScratchImageInfo {
gint tile_x;
gint tile_y1;
gint tile_y2;
GdkScreen *screen;
};
static GSList *scratch_image_infos = NULL;
@ -201,9 +203,11 @@ allocate_scratch_images (GdkScratchImageInfo *info,
for (i = 0; i < n_images; i++)
{
info->static_image[i] = _gdk_image_new_for_depth (shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
info->static_image[i] = _gdk_image_new_for_depth (info->screen,
shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
NULL,
GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), GDK_SCRATCH_IMAGE_HEIGHT,
GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images),
GDK_SCRATCH_IMAGE_HEIGHT,
info->depth);
if (!info->static_image[i])
@ -221,7 +225,8 @@ allocate_scratch_images (GdkScratchImageInfo *info,
}
static GdkScratchImageInfo *
scratch_image_info_for_depth (gint depth)
scratch_image_info_for_depth (GdkScreen *screen,
gint depth)
{
GSList *tmp_list;
GdkScratchImageInfo *image_info;
@ -231,7 +236,7 @@ scratch_image_info_for_depth (gint depth)
while (tmp_list)
{
image_info = tmp_list->data;
if (image_info->depth == depth)
if (image_info->depth == depth && image_info->screen == screen)
return image_info;
tmp_list = tmp_list->next;
@ -240,6 +245,7 @@ scratch_image_info_for_depth (gint depth)
image_info = g_new (GdkScratchImageInfo, 1);
image_info->depth = depth;
image_info->screen = screen;
/* Try to allocate as few possible shared images */
for (i=0; i < G_N_ELEMENTS (possible_n_images); i++)
@ -307,6 +313,7 @@ alloc_scratch_image (GdkScratchImageInfo *image_info)
/**
* _gdk_image_get_scratch:
* @screen: a #GdkScreen
* @width: desired width
* @height: desired height
* @depth: depth of image
@ -314,24 +321,28 @@ alloc_scratch_image (GdkScratchImageInfo *image_info)
* @y: Y location within returned image of scratch image
*
* Allocates an image of size width/height, up to a maximum
* of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT
* of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT that is
* suitable to use on @screen.
*
* Return value: a scratch image. This must be used by a
* call to gdk_image_put() before any other calls to
* _gdk_image_get_scratch()
**/
GdkImage *
_gdk_image_get_scratch (gint width,
gint height,
gint depth,
gint *x,
gint *y)
_gdk_image_get_scratch (GdkScreen *screen,
gint width,
gint height,
gint depth,
gint *x,
gint *y)
{
GdkScratchImageInfo *image_info;
GdkImage *image;
gint idx;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
image_info = scratch_image_info_for_depth (depth);
image_info = scratch_image_info_for_depth (screen, depth);
if (width >= (GDK_SCRATCH_IMAGE_WIDTH >> 1))
{

View File

@ -97,8 +97,10 @@ struct _GdkTimeCoord
GType gdk_device_get_type (void);
#ifndef GDK_MULTIHEAD_SAFE
/* Returns a list of GdkDevice * */
GList * gdk_devices_list (void);
GList * gdk_devices_list (void);
#endif /* GDK_MULTIHEAD_SAFE */
/* Functions to configure a device */
void gdk_device_set_source (GdkDevice *device,

View File

@ -75,7 +75,8 @@ typedef enum {
GDK_DEBUG_PIXMAP = 1 << 8,
GDK_DEBUG_IMAGE = 1 << 9,
GDK_DEBUG_INPUT = 1 <<10,
GDK_DEBUG_CURSOR = 1 <<11
GDK_DEBUG_CURSOR = 1 <<11,
GDK_DEBUG_MULTIHEAD = 1 <<12
} GdkDebugFlag;
#ifndef GDK_DISABLE_DEPRECATED
@ -145,39 +146,44 @@ extern GdkEventFunc _gdk_event_func; /* Callback for events */
extern gpointer _gdk_event_data;
extern GDestroyNotify _gdk_event_notify;
/* FIFO's for event queue, and for events put back using
* gdk_event_put().
*/
extern GList *_gdk_queued_events;
extern GList *_gdk_queued_tail;
extern GdkDevice *_gdk_core_pointer;
extern GSList *_gdk_displays;
extern gchar *_gdk_display_name;
GdkEvent* _gdk_event_new (void);
void _gdk_events_init (void);
void _gdk_events_queue (void);
GdkEvent* _gdk_event_unqueue (void);
GList* _gdk_event_queue_find_first (void);
void _gdk_event_queue_remove_link (GList *node);
void _gdk_event_queue_append (GdkEvent *event);
void _gdk_events_queue (GdkDisplay *display);
GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
void _gdk_event_button_generate (GdkEvent *event);
GList* _gdk_event_queue_find_first (GdkDisplay *display);
void _gdk_event_queue_remove_link (GdkDisplay *display,
GList *node);
GList* _gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event);
void _gdk_event_button_generate (GdkDisplay *display,
GdkEvent *event);
void gdk_synthesize_window_state (GdkWindow *window,
GdkWindowState unset_flags,
GdkWindowState set_flags);
#define GDK_SCRATCH_IMAGE_WIDTH 256
#define GDK_SCRATCH_IMAGE_HEIGHT 64
GdkImage* _gdk_image_new_for_depth (GdkImageType type,
GdkImage* _gdk_image_new_for_depth (GdkScreen *screen,
GdkImageType type,
GdkVisual *visual,
gint width,
gint height,
gint depth);
GdkImage *_gdk_image_get_scratch (gint width,
gint height,
gint depth,
gint *x,
gint *y);
GdkImage *_gdk_image_get_scratch (GdkScreen *screen,
gint width,
gint height,
gint depth,
gint *x,
gint *y);
/* Will most likely be exported in the future
*/
@ -224,8 +230,8 @@ void _gdk_colormap_real_destroy (GdkColormap *colormap);
void _gdk_cursor_destroy (GdkCursor *cursor);
extern GdkArgDesc _gdk_windowing_args[];
gboolean _gdk_windowing_init_check (int argc,
char **argv);
void _gdk_windowing_init (void);
void _gdk_windowing_window_get_offsets (GdkWindow *window,
gint *x_offset,
gint *y_offset);
@ -248,10 +254,9 @@ GdkWindow* _gdk_windowing_window_get_pointer (GdkWindow *window,
gint *y,
GdkModifierType *mask);
/* Return the number of bits-per-pixel for images of the specified depth.
* (Future: needs to be GdkDiplay specific.)
*/
gint _gdk_windowing_get_bits_for_depth (gint depth);
/* Return the number of bits-per-pixel for images of the specified depth. */
gint _gdk_windowing_get_bits_for_depth (GdkDisplay *display,
gint depth);
#define GDK_WINDOW_IS_MAPPED(window) ((((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
@ -289,18 +294,12 @@ GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST;
* Initialization and exit routines *
************************************/
void _gdk_windowing_window_init (void);
void _gdk_visual_init (void);
void _gdk_dnd_init (void);
void _gdk_windowing_image_init (void);
void _gdk_image_exit (void);
void _gdk_input_init (void);
void _gdk_input_exit (void);
void _gdk_windowing_exit (void);
void _gdk_get_command_line_args (int *argc,
char ***argv);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -24,19 +24,17 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gdkkeys.h"
#include <config.h>
#include "gdkkeys.h"
enum {
DIRECTION_CHANGED,
LAST_SIGNAL
};
static void gdk_keymap_init (GdkKeymap *keymap);
static void gdk_keymap_class_init (GdkKeymapClass *klass);
static gpointer parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
GType
@ -56,7 +54,7 @@ gdk_keymap_get_type (void)
NULL, /* class_data */
sizeof (GdkKeymap),
0, /* n_preallocs */
(GInstanceInitFunc) gdk_keymap_init,
(GInstanceInitFunc) NULL,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
@ -67,19 +65,11 @@ gdk_keymap_get_type (void)
return object_type;
}
static void
gdk_keymap_init (GdkKeymap *keymap)
{
}
static void
gdk_keymap_class_init (GdkKeymapClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
signals[DIRECTION_CHANGED] =
g_signal_new ("direction_changed",
G_OBJECT_CLASS_TYPE (object_class),

View File

@ -61,10 +61,10 @@ typedef struct _GdkKeymapClass GdkKeymapClass;
#define GDK_IS_KEYMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_KEYMAP))
#define GDK_KEYMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_KEYMAP, GdkKeymapClass))
struct _GdkKeymap
{
GObject parent_instance;
GObject parent_instance;
GdkDisplay *display;
};
struct _GdkKeymapClass
@ -76,7 +76,10 @@ struct _GdkKeymapClass
GType gdk_keymap_get_type (void) G_GNUC_CONST;
GdkKeymap* gdk_keymap_get_default (void);
#ifndef GDK_MULTIHEAD_SAFE
GdkKeymap* gdk_keymap_get_default (void);
#endif
GdkKeymap* gdk_keymap_get_for_display (GdkDisplay *display);
guint gdk_keymap_lookup_key (GdkKeymap *keymap,

View File

@ -28,13 +28,10 @@ extern "C" {
/* Pango interaction */
/* FIXME: The following function needs more parameters so that we can
* properly deal with different visuals, the potential for multiple
* screens in the future, etc. The PangoContext needs enough information
* in it to create new GC's and to set the colors on those GC's.
* A colormap is not sufficient.
*/
PangoContext *gdk_pango_context_get_for_screen (GdkScreen *screen);
#ifndef GDK_MULTIHEAD_SAFE
PangoContext *gdk_pango_context_get (void);
#endif
void gdk_pango_context_set_colormap (PangoContext *context,
GdkColormap *colormap);

View File

@ -25,12 +25,12 @@
#include <config.h>
#include <stdio.h>
#include <string.h>
#include "gdk.h" /* For gdk_screen_width/gdk_screen_height */
#include "gdkcolor.h"
#include "gdkimage.h"
#include "gdkvisual.h"
#include "gdkwindow.h"
#include "gdkpixbuf.h"
#include "gdkpixmap.h"
#include "gdk-pixbuf-private.h"
#include "gdkinternals.h"
@ -1552,7 +1552,8 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
image = _gdk_image_get_scratch (width1, height1, depth, &xs0, &ys0);
image = _gdk_image_get_scratch (gdk_drawable_get_screen (src),
width1, height1, depth, &xs0, &ys0);
_gdk_drawable_copy_to_image (src, image,
src_x + x0, src_y + y0,

View File

@ -25,6 +25,7 @@
#include "gdkinternals.h" /* _gdk_draw_pixbuf() */
#include "gdk-pixbuf-private.h"
#include "gdkpixbuf.h"
#include "gdkscreen.h"
@ -309,10 +310,11 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
{
GdkGC *gc;
*pixmap_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
gdk_colormap_get_visual (colormap)->depth);
gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return),
colormap);
*pixmap_return = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen),
gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
gdk_screen_get_rgb_visual (colormap->screen)->depth);
gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), colormap);
gc = gdk_gc_new (*pixmap_return);
gdk_pixbuf_render_to_drawable (pixbuf, *pixmap_return, gc,
0, 0, 0, 0,
@ -326,8 +328,9 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
{
if (gdk_pixbuf_get_has_alpha (pixbuf))
{
*mask_return = gdk_pixmap_new (NULL, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1);
*mask_return = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen),
gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1);
gdk_pixbuf_render_threshold_alpha (pixbuf, *mask_return,
0, 0, 0, 0,
gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),

View File

@ -51,10 +51,12 @@ void gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
GdkPixmap **pixmap_return,
GdkBitmap **mask_return,
int alpha_threshold);
#ifndef GDK_MULTIHEAD_SAFE
void gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf *pixbuf,
GdkPixmap **pixmap_return,
GdkBitmap **mask_return,
int alpha_threshold);
#endif
/* Fetching a region from a drawable */

View File

@ -27,6 +27,7 @@
#include "gdkpixmap.h"
#include "gdkinternals.h"
#include "gdkpixbuf.h"
#include "gdkscreen.h"
static GdkGC *gdk_pixmap_create_gc (GdkDrawable *drawable,
GdkGCValues *values,
@ -200,6 +201,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
drawable_class->draw_image = gdk_pixmap_draw_image;
drawable_class->_draw_pixbuf = gdk_pixmap_draw_pixbuf;
drawable_class->get_depth = gdk_pixmap_real_get_depth;
drawable_class->get_screen = gdk_pixmap_get_screen;
drawable_class->get_size = gdk_pixmap_real_get_size;
drawable_class->set_colormap = gdk_pixmap_real_set_colormap;
drawable_class->get_colormap = gdk_pixmap_real_get_colormap;
@ -474,13 +476,14 @@ gdk_pixmap_copy_to_image (GdkDrawable *drawable,
}
static GdkBitmap *
make_solid_mask (gint width, gint height)
make_solid_mask (GdkScreen *screen, gint width, gint height)
{
GdkBitmap *bitmap;
GdkGC *gc;
GdkGCValues gc_values;
bitmap = gdk_pixmap_new (NULL, width, height, 1);
bitmap = gdk_pixmap_new (gdk_screen_get_root_window (screen),
width, height, 1);
gc_values.foreground.pixel = 1;
gc = gdk_gc_new_with_values (bitmap, &gc_values, GDK_GC_FOREGROUND);
@ -504,7 +507,7 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap,
GdkPixbuf *render_pixbuf;
GdkGC *tmp_gc;
pixmap = gdk_pixmap_new (NULL,
pixmap = gdk_pixmap_new (gdk_screen_get_root_window (colormap->screen),
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
gdk_colormap_get_visual (colormap)->depth);
@ -533,10 +536,11 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap,
gdk_pixbuf_unref (render_pixbuf);
if (mask)
gdk_pixbuf_render_pixmap_and_mask (pixbuf, NULL, mask, 128);
gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, NULL, mask, 128);
if (mask && !*mask)
*mask = make_solid_mask (gdk_pixbuf_get_width (pixbuf),
*mask = make_solid_mask (colormap->screen,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf));
return pixmap;

View File

@ -73,9 +73,19 @@ GdkPixmap* gdk_pixmap_colormap_create_from_xpm_d (GdkWindow *window,
GdkColor *transparent_color,
gchar **data);
/* Functions to create/lookup pixmaps from their native equivalents */
GdkScreen *gdk_pixmap_get_screen (GdkDrawable *drawable);
/* Functions to create/lookup pixmaps from their native equivalents
*/
#ifndef GDK_MULTIHEAD_SAFE
GdkPixmap* gdk_pixmap_foreign_new (GdkNativeWindow anid);
GdkPixmap* gdk_pixmap_lookup (GdkNativeWindow anid);
#endif /* GDK_MULTIHEAD_SAFE */
GdkPixmap* gdk_pixmap_foreign_new_for_screen (GdkScreen *screen,
GdkNativeWindow anid);
GdkPixmap* gdk_pixmap_lookup_for_display (GdkDisplay *display,
GdkNativeWindow anid);
#ifndef GDK_DISABLE_DEPRECATED
#define gdk_bitmap_ref gdk_drawable_ref

View File

@ -37,7 +37,7 @@ void gdk_property_change (GdkWindow *window,
gint nelements);
void gdk_property_delete (GdkWindow *window,
GdkAtom property);
#ifndef GDK_MULTIHEAD_SAFE
gint gdk_text_property_to_text_list (GdkAtom encoding,
gint format,
const guchar *text,
@ -48,20 +48,46 @@ gint gdk_text_property_to_utf8_list (GdkAtom encoding,
const guchar *text,
gint length,
gchar ***list);
gchar *gdk_utf8_to_string_target (const gchar *str);
gboolean gdk_utf8_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length);
void gdk_free_text_list (gchar **list);
gint gdk_string_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length);
#endif
gint gdk_text_property_to_text_list_for_display (GdkDisplay *display,
GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list);
gint gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list);
gchar *gdk_utf8_to_string_target (const gchar *str);
gint gdk_string_to_compound_text_for_display (GdkDisplay *display,
const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length);
gboolean gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length);
void gdk_free_text_list (gchar **list);
void gdk_free_compound_text (guchar *ctext);
#ifdef __cplusplus

View File

@ -516,7 +516,6 @@ miIntersectO (GdkRegion *pReg,
* Converts @source1 into the intersection between @source1 and @source2.
* That is, after calling this function @source2 will be unchanged and
* @source1 will be the areas the two regions have in common.
*
**/
void
gdk_region_intersect (GdkRegion *region,
@ -1409,8 +1408,8 @@ gdk_region_subtract (GdkRegion *region,
* @source2: another #GdkRegion
*
* XORs the two regions, placing the result in @source1. The XOR of two
* regions contains all areas which were not overlapping. That is,
* it's the union of the regions minus the intersection of the
* regions contains all areas in one or the other ofthe regions, but not both.
* That is, it's the union of the regions minus the intersection of the
* regions.
*
**/

View File

@ -51,6 +51,7 @@
#include "gdkinternals.h" /* _gdk_windowing_get_bits_for_depth() */
#include "gdkrgb.h"
#include "gdkscreen.h"
typedef struct _GdkRgbInfo GdkRgbInfo;
typedef struct _GdkRgbCmapInfo GdkRgbCmapInfo;
@ -228,7 +229,7 @@ gdk_rgb_try_colormap (GdkRgbInfo *image_info, gboolean force,
if (image_info->cmap)
cmap = image_info->cmap;
else
cmap = gdk_colormap_get_system ();
cmap = gdk_screen_get_system_colormap (image_info->visual->screen);
colors_needed = nr * ng * nb;
for (i = 0; i < 256; i++)
@ -238,7 +239,7 @@ gdk_rgb_try_colormap (GdkRgbInfo *image_info, gboolean force,
}
#ifndef GAMMA
if (cmap == gdk_colormap_get_system())
if (cmap == gdk_screen_get_system_colormap (image_info->visual->screen))
/* find color cube colors that are already present */
for (i = 0; i < MIN (256, cmap->size); i++)
{
@ -457,7 +458,7 @@ gdk_rgb_score_visual (GdkVisual *visual)
if (quality == 0)
return 0;
sys = (visual == gdk_visual_get_system ());
sys = (visual == gdk_screen_get_system_visual (visual->screen));
pseudo = (visual->type == GDK_VISUAL_PSEUDO_COLOR || visual->type == GDK_VISUAL_TRUE_COLOR);
@ -475,13 +476,13 @@ gdk_rgb_score_visual (GdkVisual *visual)
}
static GdkVisual *
gdk_rgb_choose_visual (void)
gdk_rgb_choose_visual (GdkScreen *screen)
{
GList *visuals, *tmp_list;
guint32 score, best_score;
GdkVisual *visual, *best_visual;
visuals = gdk_list_visuals ();
visuals = gdk_screen_list_visuals (screen);
tmp_list = visuals;
best_visual = tmp_list->data;
@ -633,14 +634,14 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
image_info->visual->depth >= 3))
{
if (!image_info->cmap)
image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ());
image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen));
gdk_rgb_colorcube_222 (image_info);
}
else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR)
{
if (!image_info->cmap &&
(gdk_rgb_install_cmap || image_info->visual != gdk_visual_get_system ()))
(gdk_rgb_install_cmap || image_info->visual != gdk_screen_get_system_visual (visual->screen)))
{
image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
image_info->cmap_alloced = TRUE;
@ -658,7 +659,7 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
image_info->nblue_shades);
if (!image_info->cmap)
image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ());
image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen));
}
#ifdef ENABLE_GRAYSCALE
else if (image_info->visual->type == GDK_VISUAL_GRAYSCALE)
@ -678,8 +679,8 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
{
/* Always install colormap in direct color. */
if (image_info->visual->type != GDK_VISUAL_DIRECT_COLOR &&
image_info->visual == gdk_visual_get_system ())
image_info->cmap = gdk_colormap_ref (gdk_colormap_get_system ());
image_info->visual == gdk_screen_get_system_visual (visual->screen))
image_info->cmap = gdk_colormap_ref (gdk_screen_get_system_colormap (visual->screen));
else
{
image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
@ -690,8 +691,7 @@ gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap)
image_info->bitmap = (image_info->visual->depth == 1);
image_info->bpp = (_gdk_windowing_get_bits_for_depth (image_info->visual->depth) + 7) / 8;
image_info->bpp = (_gdk_windowing_get_bits_for_depth (gdk_screen_get_display (visual->screen), image_info->visual->depth) + 7) / 8;
gdk_rgb_select_conv (image_info);
if (!gdk_rgb_quark)
@ -793,7 +793,7 @@ gdk_rgb_xpixel_from_rgb (guint32 rgb)
guint32 g = rgb & 0xff00;
guint32 b = rgb & 0xff;
return gdk_rgb_xpixel_from_rgb_internal (gdk_rgb_get_colormap(),
return gdk_rgb_xpixel_from_rgb_internal (gdk_screen_get_rgb_colormap (gdk_get_default_screen ()),
(r >> 8) + (r >> 16), g + (g >> 8), b + (b << 8));
}
@ -2884,7 +2884,8 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
depth = image_info->visual->depth;
bpp = _gdk_windowing_get_bits_for_depth (image_info->visual->depth);
bpp = _gdk_windowing_get_bits_for_depth (gdk_screen_get_display (image_info->visual->screen),
image_info->visual->depth);
byte_order = image_info->visual->byte_order;
if (gdk_rgb_verbose)
@ -3117,7 +3118,9 @@ gdk_draw_rgb_image_core (GdkRgbInfo *image_info,
width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
buf_ptr = buf + y0 * rowstride + x0 * pixstride;
image = _gdk_image_get_scratch (width1, height1, image_info->visual->depth, &xs0, &ys0);
image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
width1, height1,
image_info->visual->depth, &xs0, &ys0);
conv (image_info, image, xs0, ys0, width1, height1, buf_ptr, rowstride,
x + x0 + xdith, y + y0 + ydith, cmap);
@ -3134,6 +3137,7 @@ static GdkRgbInfo *
gdk_rgb_get_info_from_drawable (GdkDrawable *drawable)
{
GdkColormap *cmap = gdk_drawable_get_colormap (drawable);
GdkScreen *screen = gdk_drawable_get_screen (drawable);
if (!cmap)
{
@ -3142,7 +3146,7 @@ gdk_rgb_get_info_from_drawable (GdkDrawable *drawable)
*/
gint depth = gdk_drawable_get_depth (drawable);
GdkColormap *rgb_cmap = gdk_rgb_get_colormap();
GdkColormap *rgb_cmap = gdk_screen_get_rgb_colormap (screen);
if (depth == gdk_colormap_get_visual (rgb_cmap)->depth)
cmap = rgb_cmap;
else
@ -3453,7 +3457,7 @@ gdk_rgb_ditherable (void)
/**
* gdk_rgb_get_colormap:
*
* Returns the preferred colormap for rendering image data. Not a
* Get the preferred colormap for rendering image data. Not a
* very useful function; historically, GDK could only render RGB image
* data to one colormap and visual, but in the current version it can
* render to any colormap and visual. So there's no need to call this
@ -3465,18 +3469,77 @@ GdkColormap *
gdk_rgb_get_colormap (void)
{
static GdkColormap *cmap = NULL;
if (!cmap)
{
GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (), NULL);
GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (gdk_get_default_screen ()), NULL);
cmap = image_info->cmap;
}
return cmap;
}
/**
* gdk_screen_get_rgb_colormap:
* @screen : a #GdkScreen.
*
* Gets the preferred colormap for rendering image data on @screen.
* Not a very useful function; historically, GDK could only render RGB
* image data to one colormap and visual, but in the current version
* it can render to any colormap and visual. So there's no need to
* call this function.
*
* Return value: the preferred colormap
**/
GdkColormap *
gdk_screen_get_rgb_colormap (GdkScreen *screen)
{
GdkColormap *cmap;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
cmap = g_object_get_data (G_OBJECT (screen), "rgb-colormap");
if (!cmap)
{
GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (screen), NULL);
cmap = image_info->cmap;
g_object_set_data (G_OBJECT (screen), "rgb-colormap", cmap);
}
return cmap;
}
/**
* gdk_screen_get_rgb_visual:
* @screen : a #GdkScreen
*
* Gets a "preferred visual" chosen by GdkRGB for rendering image data
* on @screen. In previous versions of
* GDK, this was the only visual GdkRGB could use for rendering. In
* current versions, it's simply the visual GdkRGB would have chosen as
* the optimal one in those previous versions. GdkRGB can now render to
* drawables with any visual.
*
* Return value: The #GdkVisual chosen by GdkRGB.
**/
GdkVisual *
gdk_screen_get_rgb_visual (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return gdk_colormap_get_visual (gdk_screen_get_rgb_colormap (screen));
}
/**
* gdk_rgb_get_visual:
*
* Gets a "preferred visual" chosen by GdkRGB for rendering image data
* on the default screen. In previous versions of GDK, this was the
* only visual GdkRGB could use for rendering. In current versions,
* it's simply the visual GdkRGB would have chosen as the optimal one
* in those previous versions. GdkRGB can now render to drawables with
* any visual.
*
* Return value: The #GdkVisual chosen by GdkRGB.
**/
GdkVisual *
gdk_rgb_get_visual (void)
{
return gdk_colormap_get_visual (gdk_rgb_get_colormap ());
return gdk_screen_get_rgb_visual (gdk_get_default_screen ());
}

View File

@ -127,17 +127,17 @@ GdkRgbCmap *gdk_rgb_cmap_new (guint32 *colors,
gint n_colors);
void gdk_rgb_cmap_free (GdkRgbCmap *cmap);
/* Below are some functions which are primarily useful for debugging
and experimentation. */
gboolean gdk_rgb_ditherable (void);
void gdk_rgb_set_verbose (gboolean verbose);
/* experimental colormap stuff */
void gdk_rgb_set_install (gboolean install);
void gdk_rgb_set_min_colors (gint min_colors);
#ifndef GDK_MULTIHEAD_SAFE
GdkColormap *gdk_rgb_get_colormap (void);
GdkVisual * gdk_rgb_get_visual (void);
gboolean gdk_rgb_ditherable (void);
#endif
#ifdef __cplusplus
}

336
gdk/gdkscreen.c Normal file
View File

@ -0,0 +1,336 @@
/*
* gdkscreen.c
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gdkscreen.h"
#include "gdkcolor.h"
GType
gdk_screen_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GdkScreenClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
NULL, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkScreen),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"GdkScreen", &object_info, 0);
}
return object_type;
}
/**
* gdk_screen_get_default_colormap:
* @screen: a #GdkScreen
*
* Gets the default colormap for @screen.
*
* Returns: the default #GdkColormap.
**/
GdkColormap *
gdk_screen_get_default_colormap (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return GDK_SCREEN_GET_CLASS (screen)->get_default_colormap (screen);
}
/**
* gdk_screen_set_default_colormap:
* @screen: a #GdkScreen
* @colormap: a #GdkColormap
*
* Sets the default @colormap for @screen.
**/
void
gdk_screen_set_default_colormap (GdkScreen *screen,
GdkColormap *colormap)
{
g_return_if_fail (GDK_IS_SCREEN (screen));
g_return_if_fail (GDK_IS_COLORMAP (colormap));
GDK_SCREEN_GET_CLASS (screen)->set_default_colormap (screen, colormap);
}
/**
* gdk_screen_get_root_window:
* @screen: a #GdkScreen
*
* Gets the root window of @screen.
*
* Returns: the root window
**/
GdkWindow *
gdk_screen_get_root_window (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return GDK_SCREEN_GET_CLASS (screen)->get_root_window (screen);
}
/**
* gdk_screen_get_display:
* @screen: a #GdkScreen
*
* Gets the display to which the @screen belongs.
*
* Returns: the display to which @screen belongs
**/
GdkDisplay *
gdk_screen_get_display (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return GDK_SCREEN_GET_CLASS (screen)->get_display (screen);
}
/**
* gdk_screen_get_number:
* @screen: a #GdkScreen
*
* Gets the index of @screen among the screens in the display
* to which it belongs. (See gdk_screen_get_display())
*
* Returns: the index
**/
gint
gdk_screen_get_number (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_screen_num (screen);
}
/**
* gdk_screen_get_window_at_pointer:
* @screen: a #GdkScreen
* @win_x: return location for origin of the window under the pointer
* @win_y: return location for origin of the window under the pointer
*
* Obtains the window underneath the mouse pointer, returning the location
* of that window in @win_x, @win_y for @screen. Returns %NULL if the window
* under the mouse pointer is not known to GDK (for example, belongs to
* another application).
*
* Returns: the window under the mouse pointer, or %NULL
**/
GdkWindow *
gdk_screen_get_window_at_pointer (GdkScreen *screen,
gint *win_x,
gint *win_y)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return GDK_SCREEN_GET_CLASS (screen)->get_window_at_pointer (screen, win_x, win_y);
}
/**
* gdk_screen_get_width:
* @screen: a #GdkScreen
*
* Gets the width of @screen in pixels
*
* Returns: the width of @screen in pixels.
**/
gint
gdk_screen_get_width (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_width (screen);
}
/**
* gdk_screen_get_height:
* @screen: a #GdkScreen
*
* Gets the height of @screen in pixels
*
* Returns: the height of @screen in pixels.
**/
gint
gdk_screen_get_height (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_height (screen);
}
/**
* gdk_screen_get_width_mm:
* @screen: a #GdkScreen
*
* Gets the width of @screen in millimeters.
* Note that on some X servers this value will not be correct.
*
* Returns: the width of @screen in pixels.
**/
gint
gdk_screen_get_width_mm (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_width_mm (screen);
}
/**
* gdk_screen_get_height_mm:
* @screen: a #GdkScreen
*
* Returns the height of @screen in millimeters.
* Note that on some X servers this value will not be correct.
*
* Returns: the heigth of @screen in pixels.
**/
gint
gdk_screen_get_height_mm (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_height_mm (screen);
}
/**
* gdk_screen_close:
* @screen: a #GdkScreen
*
* Closes the @screen connection and cleanup its resources.
* Note that this function is called automatically by gdk_display_close().
**/
void
gdk_screen_close (GdkScreen *screen)
{
g_return_if_fail (GDK_IS_SCREEN (screen));
g_object_run_dispose (G_OBJECT (screen));
}
/**
* gdk_screen_use_virtual_screen:
* @screen : a #GdkScreen.
*
* Determines whether @screen is uses multiple monitors as
* a single virtual screen (e.g. Xinerama mode under X).
*
* Returns: %TRUE if multiple monitors are used as a single screen
***/
gboolean
gdk_screen_use_virtual_screen (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
return GDK_SCREEN_GET_CLASS (screen)->use_virtual_screen (screen);
}
/**
* gdk_screen_get_n_monitors:
* @screen : a #GdkScreen.
*
* Returns the number of monitors being part of the virtual screen
*
* Returns: number of monitors part of the virtual screen or
* 0 if @screen is not in virtual screen mode.
**/
gint
gdk_screen_get_n_monitors (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
return GDK_SCREEN_GET_CLASS (screen)->get_n_monitors (screen);
}
/**
* gdk_screen_get_monitor_geometry:
* @screen : a #GdkScreen.
* @monitor_num: the monitor number.
*
* Returns a #GdkRectangle representing the size and start
* coordinates of the individual monitor within the the entire virtual
* screen.
*
* Note that the virtual screen coordinates can be retrieved via
* gdk_screen_get_width() and gdk_screen_get_height().
*
* Returns: the size and start position of the monitor wrt to
* the virtual screen.
**/
GdkRectangle *
gdk_screen_get_monitor_geometry (GdkScreen *screen,
gint monitor_num)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_geometry (screen, monitor_num);
}
/**
* gdk_screen_get_monitor_at_point:
* @screen : a #GdkScreen.
* @x : the x coordinate in the virtual screen.
* @y : the y coordinate in the virtual screen.
*
* Returns the monitor number in which the point (@x,@y) is located.
*
* Returns: the monitor number in which the point (@x,@y) belong, or
* -1 if the point is not in any monitor.
**/
gint
gdk_screen_get_monitor_at_point (GdkScreen *screen,
gint x,
gint y)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_at_point (screen, x,y);
}
/**
* gdk_screen_get_monitor_num_at_window:
* @screen : a #GdkScreen.
* @anid : a #GdkDrawable ID.
*
* Returns the monitor number in which the largest area of the bounding rectangle
* of @anid resides.
*
* Returns: the monitor number in which most of @anid is located.
**/
gint
gdk_screen_get_monitor_at_window (GdkScreen *screen,
GdkNativeWindow anid)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);
return GDK_SCREEN_GET_CLASS (screen)->get_monitor_at_window (screen, anid);
}

122
gdk/gdkscreen.h Normal file
View File

@ -0,0 +1,122 @@
/*
* gdkscreen.h
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GDK_SCREEN_H__
#define __GDK_SCREEN_H__
#include "gdk/gdktypes.h"
#include "gdk/gdkdisplay.h"
G_BEGIN_DECLS
typedef struct _GdkScreenClass GdkScreenClass;
#define GDK_TYPE_SCREEN (gdk_screen_get_type ())
#define GDK_SCREEN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN, GdkScreen))
#define GDK_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN, GdkScreenClass))
#define GDK_IS_SCREEN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN))
#define GDK_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN))
#define GDK_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN, GdkScreenClass))
struct _GdkScreen
{
GObject parent_instance;
};
struct _GdkScreenClass
{
GObjectClass parent_class;
GdkDisplay * (*get_display) (GdkScreen *screen);
gint (*get_width) (GdkScreen *screen);
gint (*get_height) (GdkScreen *screen);
gint (*get_width_mm) (GdkScreen *screen);
gint (*get_height_mm) (GdkScreen *screen);
gint (*get_root_depth) (GdkScreen *screen);
gint (*get_screen_num) (GdkScreen *screen);
GdkWindow * (*get_root_window) (GdkScreen *screen);
GdkColormap * (*get_default_colormap) (GdkScreen *screen);
void (*set_default_colormap) (GdkScreen *screen,
GdkColormap *colormap);
GdkWindow * (*get_window_at_pointer) (GdkScreen *screen,
gint *win_x,
gint *win_y);
gboolean (*use_virtual_screen) (GdkScreen *screen);
gint (*get_n_monitors) (GdkScreen *screen);
GdkRectangle *(*get_monitor_geometry) (GdkScreen *screen,
gint monitor_num);
gint (*get_monitor_at_point) (GdkScreen *screen,
gint x,
gint y);
gint (*get_monitor_at_window) (GdkScreen *screen,
GdkNativeWindow anid);
};
GType gdk_screen_get_type (void);
GdkColormap *gdk_screen_get_default_colormap (GdkScreen *screen);
void gdk_screen_set_default_colormap (GdkScreen *screen,
GdkColormap *colormap);
GdkColormap* gdk_screen_get_system_colormap (GdkScreen *screen);
GdkVisual* gdk_screen_get_system_visual (GdkScreen *screen);
GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen);
GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);
GdkDisplay * gdk_screen_get_display (GdkScreen *screen);
gint gdk_screen_get_number (GdkScreen *screen);
GdkWindow * gdk_screen_get_window_at_pointer (GdkScreen *screen,
gint *win_x,
gint *win_y);
gint gdk_screen_get_width (GdkScreen *screen);
gint gdk_screen_get_height (GdkScreen *screen);
gint gdk_screen_get_width_mm (GdkScreen *screen);
gint gdk_screen_get_height_mm (GdkScreen *screen);
void gdk_screen_close (GdkScreen *screen);
GList * gdk_screen_list_visuals (GdkScreen *screen);
GList * gdk_screen_get_toplevel_windows (GdkScreen *screen);
gboolean gdk_screen_use_virtual_screen (GdkScreen *screen);
gint gdk_screen_get_n_monitors (GdkScreen *screen);
GdkRectangle *gdk_screen_get_monitor_geometry (GdkScreen *screen,
gint monitor_num);
gint gdk_screen_get_monitor_at_point (GdkScreen *screen,
gint x,
gint y);
gint gdk_screen_get_monitor_at_window (GdkScreen *screen,
GdkNativeWindow anid);
void gdk_screen_broadcast_client_message (GdkScreen *screen,
GdkEvent *event);
GdkScreen *gdk_get_default_screen (void);
gboolean gdk_screen_get_setting (GdkScreen *screen,
const gchar *name,
GValue *value);
G_END_DECLS
#endif /* __GDK_SCREEN_H__ */

View File

@ -37,11 +37,23 @@ typedef GdkAtom GdkSelectionType;
/* Selections
*/
#ifndef GDK_MULTIHEAD_SAFE
gboolean gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
gboolean send_event);
GdkWindow* gdk_selection_owner_get (GdkAtom selection);
#endif/* GDK_MULTIHEAD_SAFE */
gboolean gdk_selection_owner_set_for_display (GdkDisplay *display,
GdkWindow *owner,
GdkAtom selection,
guint32 time,
gboolean send_event);
GdkWindow *gdk_selection_owner_get_for_display (GdkDisplay *display,
GdkAtom selection);
void gdk_selection_convert (GdkWindow *requestor,
GdkAtom selection,
GdkAtom target,
@ -50,11 +62,21 @@ gboolean gdk_selection_property_get (GdkWindow *requestor,
guchar **data,
GdkAtom *prop_type,
gint *prop_format);
#ifndef GDK_MULTIHEAD_SAFE
void gdk_selection_send_notify (guint32 requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time);
#endif /* GDK_MULTIHEAD_SAFE */
void gdk_selection_send_notify_for_display (GdkDisplay *display,
guint32 requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time);
#ifdef __cplusplus
}

View File

@ -104,6 +104,8 @@ typedef struct _GdkDrawable GdkDrawable;
typedef struct _GdkDrawable GdkBitmap;
typedef struct _GdkDrawable GdkPixmap;
typedef struct _GdkDrawable GdkWindow;
typedef struct _GdkDisplay GdkDisplay;
typedef struct _GdkScreen GdkScreen;
typedef enum
{

View File

@ -3,9 +3,7 @@
#include <gdk/gdktypes.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
G_BEGIN_DECLS
#define GDK_TYPE_VISUAL (gdk_visual_get_type ())
#define GDK_VISUAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_VISUAL, GdkVisual))
@ -67,10 +65,13 @@ struct _GdkVisual
guint32 blue_mask;
gint blue_shift;
gint blue_prec;
GdkScreen *screen;
};
GType gdk_visual_get_type (void);
#ifndef GDK_MULTIHEAD_SAFE
gint gdk_visual_get_best_depth (void);
GdkVisualType gdk_visual_get_best_type (void);
GdkVisual* gdk_visual_get_system (void);
@ -80,20 +81,19 @@ GdkVisual* gdk_visual_get_best_with_type (GdkVisualType visual_type);
GdkVisual* gdk_visual_get_best_with_both (gint depth,
GdkVisualType visual_type);
#ifndef GDK_DISABLE_DEPRECATED
#define gdk_visual_ref(v) g_object_ref(v)
#define gdk_visual_unref(v) g_object_unref(v)
#endif
void gdk_query_depths (gint **depths,
gint *count);
void gdk_query_visual_types (GdkVisualType **visual_types,
gint *count);
GList* gdk_list_visuals (void);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#ifndef GDK_DISABLE_DEPRECATED
#define gdk_visual_ref(v) g_object_ref(v)
#define gdk_visual_unref(v) g_object_unref(v)
#endif
G_END_DECLS
#endif /* __GDK_VISUAL_H__ */

View File

@ -30,6 +30,7 @@
#include "gdkpixmap.h"
#include "gdkdrawable.h"
#include "gdkpixmap.h"
#include "gdkscreen.h"
#define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
@ -154,8 +155,9 @@ static void gdk_window_real_get_size (GdkDrawable *drawable,
static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
static gint gdk_window_real_get_depth (GdkDrawable *drawable);
static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable);
static void gdk_window_real_set_colormap (GdkDrawable *drawable,
GdkColormap *cmap);
GdkColormap *cmap);
static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
@ -240,6 +242,7 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
drawable_class->draw_image = gdk_window_draw_image;
drawable_class->_draw_pixbuf = gdk_window_draw_pixbuf;
drawable_class->get_depth = gdk_window_real_get_depth;
drawable_class->get_screen = gdk_window_real_get_screen;
drawable_class->get_size = gdk_window_real_get_size;
drawable_class->set_colormap = gdk_window_real_set_colormap;
drawable_class->get_colormap = gdk_window_real_get_colormap;
@ -697,10 +700,46 @@ gdk_window_remove_filter (GdkWindow *window,
}
}
/**
* gdk_screen_get_toplevel_windows:
* @screen : The #GdkScreen where the toplevels are located.
*
* Obtains a list of all toplevel windows known to GDK on the screen @screen.
* A toplevel window is a child of the root window (see
* gdk_get_default_root_window()).
*
* The returned list should be freed with g_list_free(), but
* its elements need not be freed.
*
* Return value: list of toplevel windows, free with g_list_free()
**/
GList *
gdk_screen_get_toplevel_windows (GdkScreen *screen)
{
GdkWindow * root_window;
GList *new_list = NULL;
GList *tmp_list;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
root_window = gdk_screen_get_root_window (screen);
tmp_list = ((GdkWindowObject *)root_window)->children;
while (tmp_list)
{
if (GDK_WINDOW_TYPE (tmp_list->data) != GDK_WINDOW_FOREIGN)
new_list = g_list_prepend (new_list, tmp_list->data);
tmp_list = tmp_list->next;
}
return new_list;
}
/**
* gdk_window_get_toplevels:
*
* Obtains a list of all toplevel windows known to GDK.
* Obtains a list of all toplevel windows known to GDK on the default
* screen (see gdk_window_get_toplevels_for_screen()).
* A toplevel window is a child of the root window (see
* gdk_get_default_root_window()).
*
@ -712,18 +751,7 @@ gdk_window_remove_filter (GdkWindow *window,
GList *
gdk_window_get_toplevels (void)
{
GList *new_list = NULL;
GList *tmp_list;
tmp_list = ((GdkWindowObject *)_gdk_parent_root)->children;
while (tmp_list)
{
if (GDK_WINDOW_TYPE (tmp_list->data) != GDK_WINDOW_FOREIGN)
new_list = g_list_prepend (new_list, tmp_list->data);
tmp_list = tmp_list->next;
}
return new_list;
return gdk_screen_get_toplevel_windows (gdk_get_default_screen ());
}
/**
@ -758,12 +786,14 @@ gboolean
gdk_window_is_viewable (GdkWindow *window)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkScreen *screen = gdk_drawable_get_screen (window);
GdkWindow *root_window = gdk_screen_get_root_window (screen);
g_return_val_if_fail (window != NULL, FALSE);
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
while (private &&
(private != (GdkWindowObject *)_gdk_parent_root) &&
(private != (GdkWindowObject *)root_window) &&
(GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN))
{
if (!GDK_WINDOW_IS_MAPPED (window))
@ -1974,13 +2004,17 @@ gdk_window_real_get_visual (GdkDrawable *drawable)
static gint
gdk_window_real_get_depth (GdkDrawable *drawable)
{
gint depth;
g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
}
static GdkScreen*
gdk_window_real_get_screen (GdkDrawable *drawable)
{
return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
}
static void
gdk_window_real_set_colormap (GdkDrawable *drawable,
GdkColormap *cmap)
@ -2069,7 +2103,7 @@ gdk_window_process_updates_internal (GdkWindow *window)
if (debug_updates)
{
/* Make sure we see the red invalid area before redrawing. */
gdk_flush ();
gdk_display_sync (gdk_drawable_get_display (window));
g_usleep (70000);
}
@ -2723,6 +2757,9 @@ gdk_window_get_pointer (GdkWindow *window,
* location of that window in @win_x, @win_y. Returns %NULL if the
* window under the mouse pointer is not known to GDK (for example,
* belongs to another application).
*
* NOTE: For multihead-aware widgets or applications use
* gdk_screen_get_window_at_pointer() instead.
*
* Return value: window under the mouse pointer
**/
@ -2730,7 +2767,7 @@ GdkWindow*
gdk_window_at_pointer (gint *win_x,
gint *win_y)
{
return current_pointer_hooks->window_at_pointer (NULL, win_x, win_y);
return current_pointer_hooks->window_at_pointer (gdk_get_default_screen (), win_x, win_y);
}
/**
@ -2744,6 +2781,6 @@ gdk_window_at_pointer (gint *win_x,
GdkWindow *
gdk_get_default_root_window (void)
{
return _gdk_parent_root;
return gdk_screen_get_root_window (gdk_get_default_screen ());
}

View File

@ -197,10 +197,6 @@ struct _GdkGeometry
GdkGravity win_gravity;
};
/* Dummy typedef for placeholder in GdkPointerHooks.window_at_pointer
*/
typedef struct _GdkScreen GdkScreen;
struct _GdkPointerHooks
{
GdkWindow* (*get_pointer) (GdkWindow *window,
@ -378,8 +374,14 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
gboolean use_static);
/* Functions to create/lookup windows from their native equivalents */
#ifndef GDK_MULTIHEAD_SAFE
GdkWindow* gdk_window_foreign_new (GdkNativeWindow anid);
GdkWindow* gdk_window_lookup (GdkNativeWindow anid);
#endif
GdkWindow *gdk_window_foreign_new_for_display (GdkDisplay *display,
GdkNativeWindow anid);
GdkWindow* gdk_window_lookup_for_display (GdkDisplay *display,
GdkNativeWindow anid);
/* GdkWindow */
@ -477,7 +479,10 @@ gboolean gdk_window_get_decorations (GdkWindow *window,
GdkWMDecoration *decorations);
void gdk_window_set_functions (GdkWindow *window,
GdkWMFunction functions);
#ifndef GDK_MULTIHEAD_SAFE
GList * gdk_window_get_toplevels (void);
void gdk_set_sm_client_id (const gchar *sm_client_id);
#endif
void gdk_window_iconify (GdkWindow *window);
void gdk_window_deiconify (GdkWindow *window);

View File

@ -18,15 +18,6 @@ LDADDS = @STRIP_BEGIN@ \
noinst_LTLIBRARIES = libgdk-x11.la
if XINPUT_GXI
xinput_sources = \
gdkinput-x11.c \
gdkinput-gxi.c
gxid_sources = \
gxid_lib.c \
gxid_lib.h \
gxid_proto.h
else
if XINPUT_XFREE
xinput_sources = \
gdkinput-x11.c \
@ -35,12 +26,12 @@ else
xinput_sources = \
gdkinput-none.c
endif
endif
libgdk_x11_la_SOURCES = \
MwmUtil.h \
gdkcolor-x11.c \
gdkcursor-x11.c \
gdkdisplay-x11.c \
gdkdnd-x11.c \
gdkdrawable-x11.c \
gdkdrawable-x11.h \
@ -58,6 +49,7 @@ libgdk_x11_la_SOURCES = \
gdkpixmap-x11.c \
gdkpixmap-x11.h \
gdkproperty-x11.c \
gdkscreen-x11.c \
gdkselection-x11.c \
gdkvisual-x11.c \
gdkwindow-x11.c \
@ -66,7 +58,6 @@ libgdk_x11_la_SOURCES = \
gdkx.h \
gdkprivate-x11.h \
gdkinputprivate.h \
$(gxid_sources) \
xsettings-client.h \
xsettings-client.c \
xsettings-common.h \
@ -76,16 +67,9 @@ libgdk_x11_la_SOURCES = \
libgdkinclude_HEADERS = \
gdkx.h
EXTRA_PROGRAMS = gxid
bin_PROGRAMS = @xinput_progs@
gxid_SOURCES = gxid.c
gxid_LDADD = $(LDADDS)
# We need to include all these C files here since the conditionals
# don't seem to be correctly expanded for the dist files.
EXTRA_DIST = \
gdkinput-x11.c \
gdkinput-xfree.c \
gdkinput-gxi.c \
gdkinput-none.c

View File

@ -28,7 +28,9 @@
#include "gdkcolor.h"
#include "gdkinternals.h"
#include "gdkx.h"
#include "gdkprivate-x11.h"
#include "gdkscreen-x11.h"
typedef struct _GdkColormapPrivateX11 GdkColormapPrivateX11;
@ -99,9 +101,9 @@ gdk_colormap_init (GdkColormap *colormap)
private = g_new (GdkColormapPrivateX11, 1);
colormap->screen = NULL;
colormap->windowing_data = private;
private->xdisplay = gdk_display;
private->hash = NULL;
private->last_sync_time = 0;
private->info = NULL;
@ -128,7 +130,7 @@ gdk_colormap_finalize (GObject *object)
gdk_colormap_remove (colormap);
XFreeColormap (private->xdisplay, private->xcolormap);
XFreeColormap (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap);
if (private->hash)
g_hash_table_destroy (private->hash);
@ -146,6 +148,8 @@ gdk_colormap_new (GdkVisual *visual,
GdkColormap *colormap;
GdkColormapPrivateX11 *private;
Visual *xvisual;
Display *xdisplay;
Window xrootwin;
int size;
int i;
@ -159,8 +163,11 @@ gdk_colormap_new (GdkVisual *visual,
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
colormap->visual = visual;
colormap->screen = visual->screen;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
xdisplay = GDK_SCREEN_XDISPLAY (visual->screen);
xrootwin = GDK_SCREEN_XROOTWIN (visual->screen);
colormap->size = visual->colormap_size;
@ -175,20 +182,20 @@ gdk_colormap_new (GdkVisual *visual,
(GEqualFunc) gdk_color_equal);
private->private_val = private_cmap;
private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
private->xcolormap = XCreateColormap (xdisplay, xrootwin,
xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
if (private_cmap)
{
XColor *default_colors;
default_colors = g_new (XColor, colormap->size);
default_colors = g_new (XColor, colormap->size);
for (i = 0; i < colormap->size; i++)
default_colors[i].pixel = i;
XQueryColors (private->xdisplay,
DefaultColormap (private->xdisplay, _gdk_screen),
XQueryColors (xdisplay,
DefaultColormapOfScreen (GDK_SCREEN_X11 (visual->screen)->xscreen),
default_colors, colormap->size);
for (i = 0; i < colormap->size; i++)
@ -207,7 +214,7 @@ gdk_colormap_new (GdkVisual *visual,
case GDK_VISUAL_DIRECT_COLOR:
private->private_val = TRUE;
private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
private->xcolormap = XCreateColormap (xdisplay, xrootwin,
xvisual, AllocAll);
colormap->colors = g_new (GdkColor, colormap->size);
@ -229,7 +236,7 @@ gdk_colormap_new (GdkVisual *visual,
case GDK_VISUAL_STATIC_GRAY:
case GDK_VISUAL_STATIC_COLOR:
private->private_val = FALSE;
private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
private->xcolormap = XCreateColormap (xdisplay, xrootwin,
xvisual, AllocNone);
colormap->colors = g_new (GdkColor, colormap->size);
@ -238,7 +245,7 @@ gdk_colormap_new (GdkVisual *visual,
case GDK_VISUAL_TRUE_COLOR:
private->private_val = FALSE;
private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
private->xcolormap = XCreateColormap (xdisplay, xrootwin,
xvisual, AllocNone);
break;
}
@ -283,7 +290,8 @@ gdk_colormap_sync (GdkColormap *colormap,
}
}
XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
XQueryColors (GDK_SCREEN_XDISPLAY (colormap->screen),
private->xcolormap, xpalette, nlookup);
for (i = 0; i < nlookup; i++)
{
@ -297,58 +305,86 @@ gdk_colormap_sync (GdkColormap *colormap,
g_free (xpalette);
}
/**
* gdk_screen_get_system_colormap:
* @screen: a #GdkScreen
*
* Gets the system's default colormap for @screen
*
* Returns: the default colormap for @screen.
*/
GdkColormap *
gdk_screen_get_system_colormap (GdkScreen *screen)
{
GdkColormap *colormap = NULL;
GdkColormapPrivateX11 *private;
GdkScreenX11 *screen_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
if (screen_x11->system_colormap)
return screen_x11->system_colormap;
colormap = g_object_new (gdk_colormap_get_type (), NULL);
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
colormap->screen = screen;
colormap->visual = gdk_screen_get_system_visual (screen);
private->xcolormap = DefaultColormapOfScreen (screen_x11->xscreen);
private->private_val = FALSE;
private->hash = NULL;
private->last_sync_time = 0;
private->info = NULL;
colormap->colors = NULL;
colormap->size = colormap->visual->colormap_size;
switch (colormap->visual->type)
{
case GDK_VISUAL_GRAYSCALE:
case GDK_VISUAL_PSEUDO_COLOR:
private->info = g_new0 (GdkColorInfo, colormap->size);
private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
(GEqualFunc) gdk_color_equal);
/* Fall through */
case GDK_VISUAL_STATIC_GRAY:
case GDK_VISUAL_STATIC_COLOR:
colormap->colors = g_new (GdkColor, colormap->size);
gdk_colormap_sync (colormap, TRUE);
case GDK_VISUAL_DIRECT_COLOR:
case GDK_VISUAL_TRUE_COLOR:
break;
}
gdk_colormap_add (colormap);
screen_x11->system_colormap = colormap;
return colormap;
}
/**
* gdk_colormap_get_system:
*
* Gets the system's default colormap for the default screen. (See
* gdk_colormap_get_system_for_screen ())
*
* Return value: the default colormap.
**/
GdkColormap*
gdk_colormap_get_system (void)
{
static GdkColormap *colormap = NULL;
GdkColormapPrivateX11 *private;
if (!colormap)
{
colormap = g_object_new (gdk_colormap_get_type (), NULL);
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
private->xdisplay = gdk_display;
private->xcolormap = DefaultColormap (gdk_display, _gdk_screen);
colormap->visual = gdk_visual_get_system ();
private->private_val = FALSE;
private->hash = NULL;
private->last_sync_time = 0;
private->info = NULL;
colormap->colors = NULL;
colormap->size = colormap->visual->colormap_size;
switch (colormap->visual->type)
{
case GDK_VISUAL_GRAYSCALE:
case GDK_VISUAL_PSEUDO_COLOR:
private->info = g_new0 (GdkColorInfo, colormap->size);
private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
(GEqualFunc) gdk_color_equal);
/* Fall through */
case GDK_VISUAL_STATIC_GRAY:
case GDK_VISUAL_STATIC_COLOR:
colormap->colors = g_new (GdkColor, colormap->size);
gdk_colormap_sync (colormap, TRUE);
case GDK_VISUAL_DIRECT_COLOR:
case GDK_VISUAL_TRUE_COLOR:
break;
}
gdk_colormap_add (colormap);
}
return colormap;
return gdk_screen_get_system_colormap (gdk_get_default_screen ());
}
gint
gdk_colormap_get_system_size (void)
{
return DisplayCells (gdk_display, _gdk_screen);
return DisplayCells (GDK_SCREEN_XDISPLAY (gdk_get_default_screen()),
GDK_SCREEN_X11 (gdk_get_default_screen())->screen_num);
}
void
@ -358,6 +394,7 @@ gdk_colormap_change (GdkColormap *colormap,
GdkColormapPrivateX11 *private;
GdkVisual *visual;
XColor *palette;
Display *xdisplay;
gint shift;
int max_colors;
int size;
@ -365,6 +402,7 @@ gdk_colormap_change (GdkColormap *colormap,
g_return_if_fail (GDK_IS_COLORMAP (colormap));
xdisplay = GDK_SCREEN_XDISPLAY (colormap->screen);
palette = g_new (XColor, ncolors);
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
@ -381,7 +419,7 @@ gdk_colormap_change (GdkColormap *colormap,
palette[i].flags = DoRed | DoGreen | DoBlue;
}
XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
XStoreColors (xdisplay, private->xcolormap, palette, ncolors);
break;
case GDK_VISUAL_DIRECT_COLOR:
@ -398,7 +436,7 @@ gdk_colormap_change (GdkColormap *colormap,
palette[i].flags = DoRed;
}
XStoreColors (private->xdisplay, private->xcolormap, palette, size);
XStoreColors (xdisplay, private->xcolormap, palette, size);
shift = visual->green_shift;
max_colors = 1 << visual->green_prec;
@ -411,7 +449,7 @@ gdk_colormap_change (GdkColormap *colormap,
palette[i].flags = DoGreen;
}
XStoreColors (private->xdisplay, private->xcolormap, palette, size);
XStoreColors (xdisplay, private->xcolormap, palette, size);
shift = visual->blue_shift;
max_colors = 1 << visual->blue_prec;
@ -424,7 +462,7 @@ gdk_colormap_change (GdkColormap *colormap,
palette[i].flags = DoBlue;
}
XStoreColors (private->xdisplay, private->xcolormap, palette, size);
XStoreColors (xdisplay, private->xcolormap, palette, size);
break;
default:
@ -450,9 +488,9 @@ gdk_colors_alloc (GdkColormap *colormap,
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
contiguous, planes, nplanes, pixels, npixels);
return_val = XAllocColorCells (GDK_SCREEN_XDISPLAY (colormap->screen),
private->xcolormap,contiguous, planes,
nplanes, pixels, npixels);
if (return_val)
{
for (i=0; i<npixels; i++)
@ -509,7 +547,7 @@ gdk_colors_free (GdkColormap *colormap,
}
if (npixels)
XFreeColors (private->xdisplay, private->xcolormap,
XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap,
pixels, npixels, planes);
g_free (pixels);
}
@ -557,7 +595,7 @@ gdk_colormap_free_colors (GdkColormap *colormap,
}
if (npixels)
XFreeColors (private->xdisplay, private->xcolormap,
XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap,
pixels, npixels, 0);
g_free (pixels);
@ -586,7 +624,7 @@ gdk_colormap_alloc1 (GdkColormap *colormap,
xcolor.pixel = color->pixel;
xcolor.flags = DoRed | DoGreen | DoBlue;
if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
if (XAllocColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor))
{
ret->pixel = xcolor.pixel;
ret->red = xcolor.red;
@ -597,7 +635,7 @@ gdk_colormap_alloc1 (GdkColormap *colormap,
{
if (private->info[ret->pixel].ref_count) /* got a duplicate */
{
XFreeColors (private->xdisplay, private->xcolormap,
XFreeColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap,
&xcolor.pixel, 1, 0);
}
else
@ -659,7 +697,7 @@ gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
pixels = g_new (gulong, ncolors);
/* Allocation of a writeable color cells */
status = XAllocColorCells (private->xdisplay, private->xcolormap,
status = XAllocColorCells (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap,
FALSE, NULL, 0, pixels, ncolors);
if (status)
{
@ -722,7 +760,8 @@ gdk_colormap_alloc_colors_private (GdkColormap *colormap,
}
}
XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
XStoreColors (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap,
store, nstore);
g_free (store);
if (nremaining > 0 && best_match)
@ -954,7 +993,7 @@ gdk_colormap_alloc_colors (GdkColormap *colormap,
xcolor.pixel = colors[i].pixel;
xcolor.flags = DoRed | DoGreen | DoBlue;
if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
if (XAllocColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor))
{
colors[i].pixel = xcolor.pixel;
success[i] = TRUE;
@ -1013,7 +1052,7 @@ gdk_colormap_query_color (GdkColormap *colormap,
break;
case GDK_VISUAL_STATIC_COLOR:
xcolor.pixel = pixel;
XQueryColor (private->xdisplay, private->xcolormap, &xcolor);
XQueryColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor);
result->red = xcolor.red;
result->green = xcolor.green;
result->blue = xcolor.blue;
@ -1047,7 +1086,7 @@ gdk_color_change (GdkColormap *colormap,
xcolor.flags = DoRed | DoGreen | DoBlue;
private = GDK_COLORMAP_PRIVATE_DATA (colormap);
XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
XStoreColor (GDK_SCREEN_XDISPLAY (colormap->screen), private->xcolormap, &xcolor);
return TRUE;
}
@ -1059,6 +1098,7 @@ GdkColormap*
gdkx_colormap_get (Colormap xcolormap)
{
GdkColormap *colormap;
#if 0
GdkColormapPrivateX11 *private;
colormap = gdk_colormap_lookup (xcolormap);
@ -1075,6 +1115,7 @@ gdkx_colormap_get (Colormap xcolormap)
private->xcolormap = xcolormap;
colormap->visual = NULL;
private->private_val = TRUE;
#endif
/* To do the following safely, we would have to have some way of finding
* out what the size or visual of the given colormap is. It seems

View File

@ -30,10 +30,13 @@
#include "gdkprivate-x11.h"
#include "gdkcursor.h"
#include "gdkpixmap-x11.h"
#include "gdkx.h"
#include <gdk/gdkpixmap.h>
#include "gdkscreen-x11.h"
/**
* gdk_cursor_new:
* gdk_cursor_new_for_screen:
* @screen: the #GdkScreen where the cursor will be defined
* @cursor_type: cursor to create
*
* Creates a new cursor from the set of builtin cursors.
@ -98,23 +101,44 @@
* Return value: a new #GdkCursor
**/
GdkCursor*
gdk_cursor_new (GdkCursorType cursor_type)
gdk_cursor_new_for_screen (GdkScreen *screen,
GdkCursorType cursor_type)
{
GdkCursorPrivate *private;
GdkCursor *cursor;
Cursor xcursor;
xcursor = XCreateFontCursor (gdk_display, cursor_type);
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
xcursor = XCreateFontCursor (GDK_SCREEN_XDISPLAY (screen), cursor_type);
private = g_new (GdkCursorPrivate, 1);
private->xdisplay = gdk_display;
private->screen = screen;
private->xcursor = xcursor;
cursor = (GdkCursor*) private;
cursor = (GdkCursor *) private;
cursor->type = cursor_type;
cursor->ref_count = 1;
return cursor;
}
/**
* gdk_cursor_new:
* @cursor_type: cursor to create
*
* Creates a new cursor from the set of builtin cursors for the default screen.
* See gdk_cursor_new_for_screen().
*
* To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
* a cursor with no pixels in it.
*
* Return value: a new #GdkCursor
**/
GdkCursor*
gdk_cursor_new (GdkCursorType cursor_type)
{
return gdk_cursor_new_for_screen (gdk_get_default_screen(), cursor_type);
}
GdkCursor*
gdk_cursor_new_from_pixmap (GdkPixmap *source,
GdkPixmap *mask,
@ -128,6 +152,7 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
Pixmap source_pixmap, mask_pixmap;
Cursor xcursor;
XColor xfg, xbg;
GdkScreen *screen;
g_return_val_if_fail (GDK_IS_PIXMAP (source), NULL);
g_return_val_if_fail (GDK_IS_PIXMAP (mask), NULL);
@ -136,6 +161,7 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
source_pixmap = GDK_PIXMAP_XID (source);
mask_pixmap = GDK_PIXMAP_XID (mask);
screen = GDK_PIXMAP_SCREEN (source);
xfg.pixel = fg->pixel;
xfg.red = fg->red;
@ -146,9 +172,10 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
xbg.blue = bg->blue;
xbg.green = bg->green;
xcursor = XCreatePixmapCursor (gdk_display, source_pixmap, mask_pixmap, &xfg, &xbg, x, y);
xcursor = XCreatePixmapCursor (GDK_SCREEN_XDISPLAY (screen),
source_pixmap, mask_pixmap, &xfg, &xbg, x, y);
private = g_new (GdkCursorPrivate, 1);
private->xdisplay = gdk_display;
private->screen = screen;
private->xcursor = xcursor;
cursor = (GdkCursor *) private;
cursor->type = GDK_CURSOR_IS_PIXMAP;
@ -166,7 +193,7 @@ _gdk_cursor_destroy (GdkCursor *cursor)
g_return_if_fail (cursor->ref_count == 0);
private = (GdkCursorPrivate *) cursor;
XFreeCursor (private->xdisplay, private->xcursor);
XFreeCursor (GDK_SCREEN_XDISPLAY (private->screen), private->xcursor);
g_free (private);
}
@ -176,7 +203,7 @@ gdk_x11_cursor_get_xdisplay (GdkCursor *cursor)
{
g_return_val_if_fail (cursor != NULL, NULL);
return ((GdkCursorPrivate *)cursor)->xdisplay;
return GDK_SCREEN_XDISPLAY(((GdkCursorPrivate *)cursor)->screen);
}
Cursor
@ -186,3 +213,20 @@ gdk_x11_cursor_get_xcursor (GdkCursor *cursor)
return ((GdkCursorPrivate *)cursor)->xcursor;
}
/**
* gdk_cursor_get_screen:
* @cursor : a #GdkCursor.
*
* Returns the screen on which the GdkCursor is defined
*
* Returns : the #GdkScreen associated to @cursor
*/
GdkScreen *
gdk_cursor_get_screen (GdkCursor *cursor)
{
g_return_val_if_fail (cursor != NULL, NULL);
return ((GdkCursorPrivate *)cursor)->screen;
}

640
gdk/x11/gdkdisplay-x11.c Normal file
View File

@ -0,0 +1,640 @@
/* GDK - The GIMP Drawing Kit
* gdkdisplay-x11.c
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <unistd.h>
#include <glib.h>
#include "gdkx.h"
#include "gdkdisplay.h"
#include "gdkdisplay-x11.h"
#include "gdkscreen.h"
#include "gdkscreen-x11.h"
#include "gdkinternals.h"
#include "gdkinputprivate.h"
#include "xsettings-client.h"
#include <X11/Xatom.h>
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
#ifdef HAS_SOLARIS_XINERAMA
#include <X11/extensions/xinerama.h>
#endif
#ifdef HAS_XFREE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
static void gdk_display_x11_class_init (GdkDisplayX11Class *class);
static gint gdk_display_x11_get_n_screens (GdkDisplay *display);
static GdkScreen * gdk_display_x11_get_screen (GdkDisplay *display,
gint screen_num);
G_CONST_RETURN static char *gdk_display_x11_get_display_name (GdkDisplay *display);
static GdkScreen * gdk_display_x11_get_default_screen (GdkDisplay *display);
static void gdk_display_x11_finalize (GObject *object);
static gpointer parent_class = NULL;
GType
gdk_display_x11_get_type ()
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GdkDisplayX11Class),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) gdk_display_x11_finalize,
(GClassInitFunc) gdk_display_x11_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkDisplayX11),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
object_type = g_type_register_static (GDK_TYPE_DISPLAY,
"GdkDisplayX11",
&object_info, 0);
}
return object_type;
}
static void
gdk_display_x11_class_init (GdkDisplayX11Class * class)
{
GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class);
display_class->get_display_name = gdk_display_x11_get_display_name;
display_class->get_n_screens = gdk_display_x11_get_n_screens;
display_class->get_screen = gdk_display_x11_get_screen;
display_class->get_default_screen = gdk_display_x11_get_default_screen;
G_OBJECT_CLASS (class)->finalize = gdk_display_x11_finalize;
parent_class = g_type_class_peek_parent (class);
}
#ifdef HAS_XINERAMA
static gboolean
check_solaris_xinerama (GdkScreen *screen)
{
#ifdef HAS_SOLARIS_XINERAMA
if (XineramaGetState (GDK_SCREEN_XDISPLAY (screen),
gdk_screen_get_number (screen)))
{
XRectangle monitors[MAXFRAMEBUFFERS];
char hints[16];
result = XineramaGetInfo (GDK_SCREEN_XDISPLAY (screen),
gdk_screen_get_number (screen),
monitors, hints,
&screen_x11->num_monitors);
if (result != Success)
{
/* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
*/
g_error ("error while retrieving Xinerama information");
}
else
{
int i;
screen_x11->use_virtual_screen = TRUE;
screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
for (i = 0; i < screen_x11->num_monitors; i++)
{
screen_x11->monitors[i].x = monitors[i].x;
screen_x11->monitors[i].y = monitors[i].y;
screen_x11->monitors[i].width = monitors[i].width;
screen_x11->monitors[i].height = monitors[i].height;
}
return TRUE;
}
}
#endif /* HAS_SOLARIS_XINERAMA */
return FALSE;
}
static gboolean
check_xfree_xinerama (GdkScreen *screen)
{
#ifdef HAS_XFREE_XINERAMA
if (XineramaIsActive (GDK_SCREEN_XDISPLAY (screen)))
{
XineramaScreenInfo *monitors = XineramaQueryScreens (GDK_SCREEN_XDISPLAY (screen),
&screen_x11->num_monitors);
if (screen_x11->num_monitors <= 0)
{
/* FIXME: We need to trap errors, since XINERAMA isn't always XINERAMA.
* I don't think the num_monitors <= 0 check has any validity.
*/
g_error ("error while retrieving Xinerama information");
}
else
{
int i;
screen_x11->use_virtual_screen = TRUE;
screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
for (i = 0; i < screen_x11->num_monitors; i++)
{
screen_x11->monitors[i].x = monitors[i].x_org;
screen_x11->monitors[i].y = monitors[i].y_org;
screen_x11->monitors[i].width = monitors[i].width;
screen_x11->monitors[i].height = monitors[i].height;
}
XFree (monitors);
return TRUE;
}
}
#endif /* HAS_XFREE_XINERAMA */
return FALSE;
}
#endif /* HAS_XINERAMA */
static void
init_xinerama_support (GdkScreen * screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
#ifdef HAS_XINERAMA
int opcode, firstevent, firsterror;
gint result;
if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA",
&opcode, &firstevent, &firsterror))
{
if (check_solaris_xinerama (screen) ||
check_xfree_xinerama (screen))
return;
}
#endif /* HAS_XINERAMA */
/* No Xinerama
*/
screen_x11->use_virtual_screen = FALSE;
screen_x11->num_monitors = 1;
screen_x11->monitors = g_new0 (GdkRectangle, 1);
screen_x11->monitors[0].x = 0;
screen_x11->monitors[0].y = 0;
screen_x11->monitors[0].width = WidthOfScreen (screen_x11->xscreen);
screen_x11->monitors[0].height = HeightOfScreen (screen_x11->xscreen);
}
GdkDisplay *
gdk_open_display (const gchar *display_name)
{
GdkDisplay *display;
GdkDisplayX11 *display_x11;
gint argc;
gchar **argv;
XClassHint *class_hint;
XKeyboardState keyboard_state;
gulong pid;
gint i;
display = g_object_new (GDK_TYPE_DISPLAY_X11, NULL);
display_x11 = GDK_DISPLAY_X11 (display);
display_x11->use_xft = -1;
display_x11->xdisplay = XOpenDisplay (display_name);
if (!display_x11->xdisplay)
{
g_object_unref (display);
return NULL;
}
/* populate the screen list and set default */
for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
{
GdkScreen *screen;
GdkScreenX11 *screen_x11;
screen = g_object_new (GDK_TYPE_SCREEN_X11, NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
screen_x11->display = display;
screen_x11->xdisplay = display_x11->xdisplay;
screen_x11->xscreen = ScreenOfDisplay (display_x11->xdisplay, i);
screen_x11->screen_num = i;
screen_x11->xroot_window = (Window) RootWindow (display_x11->xdisplay, i);
screen_x11->wmspec_check_window = None;
screen_x11->visual_initialised = FALSE;
screen_x11->colormap_initialised = FALSE;
init_xinerama_support (screen);
if (screen_x11->xscreen == DefaultScreenOfDisplay (display_x11->xdisplay))
{
display_x11->default_screen = screen;
display_x11->leader_window = XCreateSimpleWindow (display_x11->xdisplay,
screen_x11->xroot_window,
10, 10, 10, 10, 0, 0, 0);
}
display_x11->screen_list = g_slist_prepend (display_x11->screen_list, screen);
}
if (_gdk_synchronize)
XSynchronize (display_x11->xdisplay, True);
class_hint = XAllocClassHint();
class_hint->res_name = g_get_prgname ();
class_hint->res_class = (char *)gdk_get_program_class ();
_gdk_get_command_line_args (&argc, &argv);
XmbSetWMProperties (display_x11->xdisplay,
display_x11->leader_window,
NULL, NULL, argv, argc, NULL, NULL,
class_hint);
XFree (class_hint);
pid = getpid ();
XChangeProperty (display_x11->xdisplay,
display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
XGetKeyboardControl (display_x11->xdisplay, &keyboard_state);
#ifdef HAVE_XKB
{
gint xkb_major = XkbMajorVersion;
gint xkb_minor = XkbMinorVersion;
if (XkbLibraryVersion (&xkb_major, &xkb_minor))
{
xkb_major = XkbMajorVersion;
xkb_minor = XkbMinorVersion;
if (XkbQueryExtension (display_x11->xdisplay,
NULL, &display_x11->xkb_event_type, NULL,
&xkb_major, &xkb_minor))
{
Bool detectable_autorepeat_supported;
display_x11->use_xkb = TRUE;
XkbSelectEvents (display_x11->xdisplay,
XkbUseCoreKbd,
XkbMapNotifyMask | XkbStateNotifyMask,
XkbMapNotifyMask | XkbStateNotifyMask);
XkbSetDetectableAutoRepeat (display_x11->xdisplay,
True,
&detectable_autorepeat_supported);
GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
detectable_autorepeat_supported ?
"supported" : "not supported"));
display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
}
}
}
#endif
_gdk_visual_init (display_x11->default_screen);
_gdk_windowing_window_init (display_x11->default_screen);
_gdk_windowing_image_init (display);
_gdk_events_init (display);
_gdk_input_init (display);
_gdk_dnd_init (display);
return display;
}
static G_CONST_RETURN gchar*
gdk_display_x11_get_display_name (GdkDisplay * display)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
return (gchar *) DisplayString (display_x11->xdisplay);
}
static gint
gdk_display_x11_get_n_screens (GdkDisplay * display)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
return ScreenCount (display_x11->xdisplay);
}
static GdkScreen *
gdk_display_x11_get_screen (GdkDisplay *display,
gint screen_num)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
Screen *desired_screen;
GSList *tmp_list;
g_return_val_if_fail (ScreenCount (display_x11->xdisplay) > screen_num, NULL);
desired_screen = ScreenOfDisplay (display_x11->xdisplay, screen_num);
tmp_list = display_x11->screen_list;
while (tmp_list)
{
GdkScreenX11 *screen_x11 = tmp_list->data;
GdkScreen *screen = tmp_list->data;
if (screen_x11->xscreen == desired_screen)
{
if (!screen_x11->visual_initialised)
_gdk_visual_init (screen);
if (!screen_x11->colormap_initialised)
_gdk_windowing_window_init (screen);
if (!screen_x11->xsettings_client)
_gdk_x11_events_init_screen (screen);
return screen;
}
tmp_list = tmp_list->next;
}
g_assert_not_reached ();
return NULL;
}
static GdkScreen *
gdk_display_x11_get_default_screen (GdkDisplay * display)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
return display_x11->default_screen;
}
gboolean
_gdk_x11_display_is_root_window (GdkDisplay *display,
Window xroot_window)
{
GdkDisplayX11 *display_x11;
GSList *tmp_list;
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
display_x11 = GDK_DISPLAY_X11 (display);
tmp_list = display_x11->screen_list;
while (tmp_list)
{
GdkScreenX11 *screen_x11 = tmp_list->data;
if (screen_x11->xroot_window == xroot_window)
return TRUE;
tmp_list = tmp_list->next;
}
return FALSE;
}
/**
* gdk_display_pointer_ungrab:
* @display : a #GdkDisplay.
* @time: a timestap (e.g. GDK_CURRENT_TIME).
*
* Release any pointer grab.
*/
void
gdk_display_pointer_ungrab (GdkDisplay *display,
guint32 time)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
_gdk_input_ungrab_pointer (display, time);
XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time);
GDK_DISPLAY_X11 (display)->pointer_xgrab_window = NULL;
}
/**
* gdk_display_pointer_is_grabbed :
* @display : a #GdkDisplay
*
* Test if the pointer is grabbed.
*
* Returns : TRUE if an active X pointer grab is in effect
*/
gboolean
gdk_display_pointer_is_grabbed (GdkDisplay * display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
return (GDK_DISPLAY_X11 (display)->pointer_xgrab_window != NULL);
}
/**
* gdk_display_keyboard_ungrab:
* @display : a #GdkDisplay.
* @time : a timestap (e.g #GDK_CURRENT_TIME).
*
* Release any keyboard grab
*/
void
gdk_display_keyboard_ungrab (GdkDisplay *display,
guint32 time)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time);
GDK_DISPLAY_X11 (display)->keyboard_xgrab_window = NULL;
}
/**
* gdk_display_beep:
* @display: a #GdkDisplay
*
* Emits a short beep on @display
*
*/
void
gdk_display_beep (GdkDisplay * display)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
XBell (GDK_DISPLAY_XDISPLAY (display), 0);
}
/**
* gdk_display_sync :
* @display : a #GdkDisplay
*
* Flushes any requests queued for the windowing system and waits until all
* requests have been handled. This is often used for making sure that the
* display is synchronized with the current state of the program. Calling
* gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
* generated from earlier requests are handled before the error trap is removed.
*
* This is most useful for X11. On windowing systems where requests handled
* synchronously, this function will do nothing.
*/
void
gdk_display_sync (GdkDisplay * display)
{
g_return_if_fail (GDK_IS_DISPLAY (display));
XSync (GDK_DISPLAY_XDISPLAY (display), False);
}
void
gdk_x11_display_grab (GdkDisplay * display)
{
GdkDisplayX11 *display_x11;
g_return_if_fail (GDK_IS_DISPLAY (display));
display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->grab_count == 0)
XGrabServer (display_x11->xdisplay);
display_x11->grab_count++;
}
void
gdk_x11_display_ungrab (GdkDisplay * display)
{
GdkDisplayX11 *display_x11;
g_return_if_fail (GDK_IS_DISPLAY (display));
display_x11 = GDK_DISPLAY_X11 (display);;
g_return_if_fail (display_x11->grab_count > 0);
display_x11->grab_count--;
if (display_x11->grab_count == 0)
XUngrabServer (display_x11->xdisplay);
}
static void
gdk_display_x11_finalize (GObject *object)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
int i;
GList *tmp;
GSList *stmp;
/* FIXME need to write GdkKeymap finalize fct
g_object_unref (display_x11->keymap);
*/
/* Free motif Dnd */
if (display_x11->motif_target_lists)
{
for (i = 0; i < display_x11->motif_n_target_lists; i++)
g_list_free (display_x11->motif_target_lists[i]);
g_free (display_x11->motif_target_lists);
}
/* Atom Hashtable */
g_hash_table_destroy (display_x11->atom_from_virtual);
g_hash_table_destroy (display_x11->atom_to_virtual);
/* Leader Window */
XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
/* list of filters for client messages */
g_list_free (display_x11->client_filters);
/* X ID hashtable */
g_hash_table_destroy (display_x11->xid_ht);
/* input GdkDevice list */
/* FIXME need to write finalize fct */
for (tmp = display_x11->input_devices; tmp; tmp = tmp->next)
g_object_unref (G_OBJECT (tmp->data));
g_list_free (display_x11->input_devices);
/* input GdkWindow list */
for (tmp = display_x11->input_windows; tmp; tmp = tmp->next)
g_object_unref (G_OBJECT (tmp->data));
g_list_free (display_x11->input_windows);
/* Free all GdkScreens */
for (stmp = display_x11->screen_list; stmp; stmp = stmp->next)
g_object_unref (G_OBJECT (stmp->data));
g_slist_free (display_x11->screen_list);
XCloseDisplay (display_x11->xdisplay);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* gdk_x11_lookup_xdisplay:
* @xdisplay: a pointer to an X Display
*
* Find the #GdkDisplay corresponding to @display, if any exists.
*
* Return value: the #GdkDisplay, if found, otherwise %NULL.
**/
GdkDisplay *
gdk_x11_lookup_xdisplay (Display *xdisplay)
{
GSList *tmp_list;
for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
{
if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay)
return tmp_list->data;
}
return NULL;
}
/**
* _gdk_x11_display_screen_for_xrootwin:
* @display: a #Display
* @xrootwin: window ID for one of of the screen's of the display.
*
* Given the root window ID of one of the screen's of a #GdkDisplay,
* finds the screen.
*
* Return value: the #GdkScreen corresponding to @xrootwin, or %NULL.
**/
GdkScreen *
_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
Window xrootwin)
{
gint n_screens, i;
n_screens = gdk_display_get_n_screens (display);
for (i = 0; i < n_screens; i++)
{
GdkScreen *screen = gdk_display_get_screen (display, i);
if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
return screen;
}
return NULL;
}
Display *
gdk_x11_display_get_xdisplay (GdkDisplay *display)
{
return GDK_DISPLAY_X11 (display)->xdisplay;
}

142
gdk/x11/gdkdisplay-x11.h Normal file
View File

@ -0,0 +1,142 @@
/*
* gdkdisplay-x11.h
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GDK_DISPLAY_X11__
#define __GDK_DISPLAY_X11__
#include <X11/X.h>
#include <X11/Xlib.h>
#include <glib.h>
#include <gdk/gdkdisplay.h>
#include <gdk/gdkkeys.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdk.h> /* For gdk_get_program_class() */
G_BEGIN_DECLS
typedef struct _GdkDisplayX11 GdkDisplayX11;
typedef struct _GdkDisplayX11Class GdkDisplayX11Class;
#define GDK_TYPE_DISPLAY_X11 (gdk_display_x11_get_type())
#define GDK_DISPLAY_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY_X11, GdkDisplayX11))
#define GDK_DISPLAY_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY_X11, GdkDisplayX11Class))
#define GDK_IS_DISPLAY_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY_X11))
#define GDK_IS_DISPLAY_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY_X11))
#define GDK_DISPLAY_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY_X11, GdkDisplayX11Class))
struct _GdkDisplayX11
{
GdkDisplay parent_instance;
Display *xdisplay;
GdkScreen *default_screen;
GSList *screen_list;
gint grab_count;
/* Keyboard related information */
gint xkb_event_type;
gboolean use_xkb;
/* Whether we were able to turn on detectable-autorepeat using
* XkbSetDetectableAutorepeat. If FALSE, we'll fall back
* to checking the next event with XPending(). */
gboolean have_xkb_autorepeat;
GdkKeymap *keymap;
guint keymap_serial;
gboolean use_xshm;
gboolean have_shm_pixmaps;
gint have_shape;
/* Information about current pointer and keyboard grabs held by this
* client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window
* window is NULL, then the other associated fields are ignored
*/
GdkWindowObject *pointer_xgrab_window;
gulong pointer_xgrab_serial;
gboolean pointer_xgrab_owner_events;
GdkWindowObject *keyboard_xgrab_window;
gulong keyboard_xgrab_serial;
gboolean keyboard_xgrab_owner_events;
/* drag and drop information */
GdkDragContext *current_dest_drag;
/* data needed for MOTIF DnD */
Window motif_drag_window;
GdkWindow *motif_drag_gdk_window;
GList **motif_target_lists;
gint motif_n_target_lists;
/* Mapping to/from virtual atoms */
GHashTable *atom_from_virtual;
GHashTable *atom_to_virtual;
/* Session Management leader window see ICCCM */
Window leader_window;
/* list of filters for client messages */
GList *client_filters;
/* X ID hashtable */
GHashTable *xid_ht;
/* translation queue */
GQueue *translate_queue;
/* Input device */
/* input GdkDevice list */
GList *input_devices;
/* input GdkWindow list */
GList *input_windows;
gint input_ignore_core;
/* information about network port and host for gxid daemon */
gchar *input_gxid_host;
gint input_gxid_port;
gint use_xft;
};
struct _GdkDisplayX11Class
{
GdkDisplayClass parent_class;
};
GType gdk_display_x11_get_type (void);
void gdk_x11_display_grab (GdkDisplay *display);
void gdk_x11_display_ungrab (GdkDisplay *display);
GdkScreen *_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
Window xrootwin);
G_END_DECLS
#endif /* __GDK_DISPLAY_X11__ */

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@
#include "gdkprivate-x11.h"
#include "gdkdrawable-x11.h"
#include "gdkpixmap-x11.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h"
static void gdk_x11_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
@ -139,9 +141,8 @@ static void gdk_x11_set_colormap (GdkDrawable *drawable,
GdkColormap *colormap);
static GdkColormap* gdk_x11_get_colormap (GdkDrawable *drawable);
static gint gdk_x11_get_depth (GdkDrawable *drawable);
static GdkScreen * gdk_x11_get_screen (GdkDrawable *drawable);
static GdkVisual* gdk_x11_get_visual (GdkDrawable *drawable);
static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass);
@ -208,6 +209,7 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
drawable_class->get_colormap = gdk_x11_get_colormap;
drawable_class->get_depth = gdk_x11_get_depth;
drawable_class->get_screen = gdk_x11_get_screen;
drawable_class->get_visual = gdk_x11_get_visual;
drawable_class->_copy_to_image = _gdk_x11_copy_to_image;
@ -223,14 +225,15 @@ gdk_drawable_impl_x11_finalize (GObject *object)
#ifdef HAVE_XFT
gboolean
_gdk_x11_have_render (void)
_gdk_x11_have_render (GdkDisplay *display)
{
/* This check is cheap, but if we have to do version checks, we will
* need to cache the result since version checks are round-trip
*/
int event_base, error_base;
return XRenderQueryExtension (gdk_display, &event_base, &error_base);
return XRenderQueryExtension (GDK_DISPLAY_XDISPLAY (display),
&event_base, &error_base);
}
static Picture
@ -238,7 +241,7 @@ gdk_x11_drawable_get_picture (GdkDrawable *drawable)
{
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
if (!_gdk_x11_have_render ())
if (!_gdk_x11_have_render (gdk_drawable_get_display (drawable)))
return None;
if (impl->picture == None)
@ -256,9 +259,11 @@ gdk_x11_drawable_get_picture (GdkDrawable *drawable)
return None;
}
format = XRenderFindVisualFormat (impl->xdisplay, GDK_VISUAL_XVISUAL (visual));
format = XRenderFindVisualFormat (GDK_SCREEN_XDISPLAY (impl->screen),
gdk_x11_visual_get_xvisual(visual));
if (format)
impl->picture = XRenderCreatePicture (impl->xdisplay, impl->xid, format, 0, NULL);
impl->picture = XRenderCreatePicture (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid, format, 0, NULL);
}
return impl->picture;
@ -287,7 +292,8 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
}
XRenderSetPictureClipRectangles (impl->xdisplay, picture, 0, 0, rects, n_boxes);
XRenderSetPictureClipRectangles (GDK_SCREEN_XDISPLAY (impl->screen),
picture, 0, 0, rects, n_boxes);
g_free (rects);
}
@ -295,7 +301,8 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
{
XRenderPictureAttributes pa;
pa.clip_mask = None;
XRenderChangePicture (impl->xdisplay, picture, CPClipMask, &pa);
XRenderChangePicture (GDK_SCREEN_XDISPLAY (impl->screen),
picture, CPClipMask, &pa);
}
}
#endif
@ -349,10 +356,10 @@ gdk_x11_draw_rectangle (GdkDrawable *drawable,
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
if (filled)
XFillRectangle (impl->xdisplay, impl->xid,
XFillRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), x, y, width, height);
else
XDrawRectangle (impl->xdisplay, impl->xid,
XDrawRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), x, y, width, height);
}
@ -373,10 +380,10 @@ gdk_x11_draw_arc (GdkDrawable *drawable,
if (filled)
XFillArc (impl->xdisplay, impl->xid,
XFillArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
else
XDrawArc (impl->xdisplay, impl->xid,
XDrawArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
}
@ -415,10 +422,10 @@ gdk_x11_draw_polygon (GdkDrawable *drawable,
}
if (filled)
XFillPolygon (impl->xdisplay, impl->xid,
XFillPolygon (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin);
else
XDrawLines (impl->xdisplay, impl->xid,
XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin);
g_free (tmp_points);
@ -440,28 +447,30 @@ gdk_x11_draw_text (GdkDrawable *drawable,
gint text_length)
{
GdkDrawableImplX11 *impl;
Display *xdisplay;
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
if (font->type == GDK_FONT_FONT)
{
XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
{
XDrawString (impl->xdisplay, impl->xid,
XDrawString (xdisplay, impl->xid,
GDK_GC_GET_XGC (gc), x, y, text, text_length);
}
else
{
XDrawString16 (impl->xdisplay, impl->xid,
XDrawString16 (xdisplay, impl->xid,
GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
}
}
else if (font->type == GDK_FONT_FONTSET)
{
XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
XmbDrawString (impl->xdisplay, impl->xid,
XmbDrawString (xdisplay, impl->xid,
fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
}
else
@ -478,18 +487,20 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable,
gint text_length)
{
GdkDrawableImplX11 *impl;
Display *xdisplay;
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
if (font->type == GDK_FONT_FONT)
{
XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
gchar *text_8bit;
gint i;
XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
text_8bit = g_new (gchar, text_length);
for (i=0; i<text_length; i++) text_8bit[i] = text[i];
XDrawString (impl->xdisplay, impl->xid,
XDrawString (xdisplay, impl->xid,
GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length);
g_free (text_8bit);
}
@ -497,7 +508,7 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable,
{
if (sizeof(GdkWChar) == sizeof(wchar_t))
{
XwcDrawString (impl->xdisplay, impl->xid,
XwcDrawString (xdisplay, impl->xid,
(XFontSet) GDK_FONT_XFONT (font),
GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length);
}
@ -507,7 +518,7 @@ gdk_x11_draw_text_wc (GdkDrawable *drawable,
gint i;
text_wchar = g_new (wchar_t, text_length);
for (i=0; i<text_length; i++) text_wchar[i] = text[i];
XwcDrawString (impl->xdisplay, impl->xid,
XwcDrawString (xdisplay, impl->xid,
(XFontSet) GDK_FONT_XFONT (font),
GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length);
g_free (text_wchar);
@ -542,7 +553,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable,
if (src_depth == 1)
{
XCopyArea (impl->xdisplay,
XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
impl->xid,
GDK_GC_GET_XGC (gc),
@ -552,7 +563,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable,
}
else if (dest_depth != 0 && src_depth == dest_depth)
{
XCopyArea (impl->xdisplay,
XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
impl->xid,
GDK_GC_GET_XGC (gc),
@ -581,7 +592,7 @@ gdk_x11_draw_points (GdkDrawable *drawable,
*/
if (npoints == 1)
{
XDrawPoint (impl->xdisplay,
XDrawPoint (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
GDK_GC_GET_XGC (gc),
points[0].x, points[0].y);
@ -597,7 +608,7 @@ gdk_x11_draw_points (GdkDrawable *drawable,
tmp_points[i].y = points[i].y;
}
XDrawPoints (impl->xdisplay,
XDrawPoints (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
GDK_GC_GET_XGC (gc),
tmp_points,
@ -624,7 +635,7 @@ gdk_x11_draw_segments (GdkDrawable *drawable,
*/
if (nsegs == 1)
{
XDrawLine (impl->xdisplay, impl->xid,
XDrawLine (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1,
segs[0].x2, segs[0].y2);
}
@ -641,7 +652,7 @@ gdk_x11_draw_segments (GdkDrawable *drawable,
tmp_segs[i].y2 = segs[i].y2;
}
XDrawSegments (impl->xdisplay,
XDrawSegments (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
GDK_GC_GET_XGC (gc),
tmp_segs, nsegs);
@ -669,7 +680,7 @@ gdk_x11_draw_lines (GdkDrawable *drawable,
tmp_points[i].y = points[i].y;
}
XDrawLines (impl->xdisplay,
XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
GDK_GC_GET_XGC (gc),
tmp_points, npoints,
@ -701,11 +712,13 @@ gdk_x11_draw_glyphs (GdkDrawable *drawable,
gdk_x11_drawable_update_picture_clip (drawable, gc);
dest_picture = gdk_x11_drawable_get_picture (drawable);
pango_xft_picture_render (impl->xdisplay, src_picture, dest_picture, font, glyphs, x, y);
pango_xft_picture_render (GDK_SCREEN_XDISPLAY (impl->screen),
src_picture, dest_picture,
font, glyphs, x, y);
}
else
#endif /* !HAVE_XFT */
pango_x_render (impl->xdisplay,
pango_x_render (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
GDK_GC_GET_XGC (gc),
font, glyphs, x, y);
@ -727,11 +740,11 @@ gdk_x11_draw_image (GdkDrawable *drawable,
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
if (image->type == GDK_IMAGE_SHARED)
XShmPutImage (impl->xdisplay, impl->xid,
XShmPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
xsrc, ysrc, xdest, ydest, width, height, False);
else
XPutImage (impl->xdisplay, impl->xid,
XPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
xsrc, ysrc, xdest, ydest, width, height);
}
@ -744,14 +757,8 @@ gdk_x11_get_depth (GdkDrawable *drawable)
return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
}
static GdkVisual*
gdk_x11_get_visual (GdkDrawable *drawable)
{
return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
}
Display *
gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable)
static GdkDrawable * get_impl_drawable (GdkDrawable *drawable)
{
GdkDrawable *impl;
@ -762,10 +769,34 @@ gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable)
else
{
g_warning (G_STRLOC " drawable is not a pixmap or window");
return NULL;
return None;
}
return impl;
}
return ((GdkDrawableImplX11 *)impl)->xdisplay;
static GdkScreen*
gdk_x11_get_screen (GdkDrawable *drawable)
{
if (GDK_IS_DRAWABLE_IMPL_X11 (drawable))
return GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
else
return GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen;
}
static GdkVisual*
gdk_x11_get_visual (GdkDrawable *drawable)
{
return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
}
Display *
gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable)
{
if (GDK_IS_DRAWABLE_IMPL_X11 (drawable))
return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
else
return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen);
}
XID
@ -800,13 +831,14 @@ typedef enum {
} FormatType;
static FormatType
select_format (Display *xdisplay,
select_format (GdkDisplay *display,
XRenderPictFormat **format,
XRenderPictFormat **mask)
{
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
XRenderPictFormat pf;
if (!_gdk_x11_have_render ())
if (!_gdk_x11_have_render (display))
return FORMAT_NONE;
/* Look for a 32-bit xRGB and Axxx formats that exactly match the
@ -1098,7 +1130,8 @@ draw_with_images (GdkDrawable *drawable,
gint width,
gint height)
{
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
GdkImage *image;
GdkPixmap *pix;
GdkGC *pix_gc;
@ -1107,7 +1140,8 @@ draw_with_images (GdkDrawable *drawable,
Picture mask = None;
gint x0, y0;
pix = gdk_pixmap_new (NULL, width, height, 32);
pix = gdk_pixmap_new (gdk_screen_get_root_window (screen), width, height, 32);
pict = XRenderCreatePicture (xdisplay,
GDK_PIXMAP_XID (pix),
format, 0, NULL);
@ -1129,7 +1163,7 @@ draw_with_images (GdkDrawable *drawable,
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0);
image = _gdk_image_get_scratch (screen, width1, height1, 32, &xs0, &ys0);
convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
@ -1221,7 +1255,7 @@ draw_with_pixmaps (GdkDrawable *drawable,
gint width,
gint height)
{
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
Display *xdisplay = GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
GdkImage *image;
Pixmap pix;
Picture pict;
@ -1240,7 +1274,8 @@ draw_with_pixmaps (GdkDrawable *drawable,
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
image = _gdk_image_get_scratch (width1, height1, 32, &xs0, &ys0);
image = _gdk_image_get_scratch (GDK_DRAWABLE_IMPL_X11 (drawable)->screen,
width1, height1, 32, &xs0, &ys0);
if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask))
return FALSE;
@ -1273,7 +1308,6 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
gint x_dither,
gint y_dither)
{
Display *xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
FormatType format_type;
XRenderPictFormat *format, *mask_format;
gint rowstride;
@ -1281,7 +1315,8 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
gboolean use_pixmaps = TRUE;
#endif /* USE_SHM */
format_type = select_format (xdisplay, &format, &mask_format);
format_type = select_format (gdk_drawable_get_display (drawable),
&format, &mask_format);
if (format_type == FORMAT_NONE ||
!gdk_pixbuf_get_has_alpha (pixbuf) ||

View File

@ -30,7 +30,6 @@
#include <config.h>
#include <gdk/gdkdrawable.h>
#include <gdk/x11/gdkx.h>
#ifdef HAVE_XFT
#include <X11/extensions/Xrender.h>
@ -62,7 +61,7 @@ struct _GdkDrawableImplX11
GdkColormap *colormap;
Window xid;
Display *xdisplay;
GdkScreen *screen;
#ifdef HAVE_XFT
Picture picture;

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,12 @@
#include <pango/pangox.h>
#include "gdkx.h"
#include "gdkfont.h"
#include "gdkprivate-x11.h"
#include "gdkinternals.h"
#include "gdkdisplay-x11.h"
#include "gdkscreen-x11.h"
typedef struct _GdkFontPrivateX GdkFontPrivateX;
@ -41,35 +45,86 @@ struct _GdkFontPrivateX
/* XFontStruct *xfont; */
/* generic pointer point to XFontStruct or XFontSet */
gpointer xfont;
Display *xdisplay;
GdkDisplay *display;
GSList *names;
};
static GHashTable *font_name_hash = NULL;
static GHashTable *fontset_name_hash = NULL;
static void
gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name)
static GHashTable *
gdk_font_name_hash_get (GdkDisplay *display)
{
GdkFontPrivateX *private = (GdkFontPrivateX *)font;
GHashTable **hashp = (type == GDK_FONT_FONT) ?
&font_name_hash : &fontset_name_hash;
GHashTable *result;
static GQuark font_name_quark = 0;
if (!*hashp)
*hashp = g_hash_table_new (g_str_hash, g_str_equal);
if (!font_name_quark)
font_name_quark = g_quark_from_static_string ("gdk-font-hash");
private->names = g_slist_prepend (private->names, g_strdup (font_name));
g_hash_table_insert (*hashp, private->names->data, font);
result = g_object_get_qdata (G_OBJECT (display), font_name_quark);
if (!result)
{
result = g_hash_table_new (g_str_hash, g_str_equal);
g_object_set_qdata (G_OBJECT (display), font_name_quark, result);
}
return result;
}
static GHashTable *
gdk_fontset_name_hash_get (GdkDisplay *display)
{
GHashTable *result;
static GQuark fontset_name_quark = 0;
if (!fontset_name_quark)
fontset_name_quark = g_quark_from_static_string ("gdk-fontset-hash");
result = g_object_get_qdata (G_OBJECT (display), fontset_name_quark);
if (!result)
{
result = g_hash_table_new (g_str_hash, g_str_equal);
g_object_set_qdata (G_OBJECT (display), fontset_name_quark, result);
}
return result;
}
/**
* gdk_font_get_display:
* @font: the #GdkFont.
*
* Returns the #GdkDisplay for @font.
*
* Returns : the corresponding #GdkDisplay.
**/
GdkDisplay*
gdk_font_get_display (GdkFont* font)
{
return ((GdkFontPrivateX *)font)->display;
}
static void
gdk_font_hash_remove (GdkFontType type, GdkFont *font)
gdk_font_hash_insert (GdkFontType type,
GdkFont *font,
const gchar *font_name)
{
GdkFontPrivateX *private = (GdkFontPrivateX *)font;
GHashTable *hash = (type == GDK_FONT_FONT) ?
gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display);
private->names = g_slist_prepend (private->names, g_strdup (font_name));
g_hash_table_insert (hash, private->names->data, font);
}
static void
gdk_font_hash_remove (GdkFontType type,
GdkFont *font)
{
GdkFontPrivateX *private = (GdkFontPrivateX *)font;
GSList *tmp_list;
GHashTable *hash = (type == GDK_FONT_FONT) ?
font_name_hash : fontset_name_hash;
gdk_font_name_hash_get (private->display) : gdk_fontset_name_hash_get (private->display);
tmp_list = private->names;
while (tmp_list)
@ -85,12 +140,16 @@ gdk_font_hash_remove (GdkFontType type, GdkFont *font)
}
static GdkFont *
gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
gdk_font_hash_lookup (GdkDisplay *display,
GdkFontType type,
const gchar *font_name)
{
GdkFont *result;
GHashTable *hash = (type == GDK_FONT_FONT) ?
font_name_hash : fontset_name_hash;
GHashTable *hash;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
hash = (type == GDK_FONT_FONT) ? gdk_font_name_hash_get (display) :
gdk_fontset_name_hash_get (display);
if (!hash)
return NULL;
else
@ -103,36 +162,38 @@ gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
}
}
GdkFont*
gdk_font_load (const gchar *font_name)
GdkFont *
gdk_font_load_for_display (GdkDisplay *display,
const gchar *font_name)
{
GdkFont *font;
GdkFontPrivateX *private;
XFontStruct *xfont;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
g_return_val_if_fail (font_name != NULL, NULL);
font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name);
font = gdk_font_hash_lookup (display, GDK_FONT_FONT, font_name);
if (font)
return font;
xfont = XLoadQueryFont (gdk_display, font_name);
xfont = XLoadQueryFont (GDK_DISPLAY_XDISPLAY (display), font_name);
if (xfont == NULL)
return NULL;
font = gdk_font_lookup (xfont->fid);
if (font != NULL)
font = gdk_font_lookup_for_display (display, xfont->fid);
if (font != NULL)
{
private = (GdkFontPrivateX *) font;
if (xfont != private->xfont)
XFreeFont (gdk_display, xfont);
XFreeFont (GDK_DISPLAY_XDISPLAY (display), xfont);
gdk_font_ref (font);
}
else
{
private = g_new (GdkFontPrivateX, 1);
private->xdisplay = gdk_display;
private->display = display;
private->xfont = xfont;
private->base.ref_count = 1;
private->names = NULL;
@ -141,8 +202,8 @@ gdk_font_load (const gchar *font_name)
font->type = GDK_FONT_FONT;
font->ascent = xfont->ascent;
font->descent = xfont->descent;
gdk_xid_table_insert (&xfont->fid, font);
_gdk_xid_table_insert (display, &xfont->fid, font);
}
gdk_font_hash_insert (GDK_FONT_FONT, font, font_name);
@ -150,6 +211,12 @@ gdk_font_load (const gchar *font_name)
return font;
}
GdkFont*
gdk_font_load (const gchar *font_name)
{
return gdk_font_load_for_display (gdk_get_default_display(), font_name);
}
static char *
gdk_font_charset_for_locale (void)
{
@ -187,6 +254,48 @@ gdk_font_charset_for_locale (void)
return g_strdup ("iso8859-1");
};
GdkFont *
gdk_font_from_description_for_display (GdkDisplay *display,
PangoFontDescription *font_desc)
{
PangoFontMap *font_map;
PangoFont *font;
GdkFont *result = NULL;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
g_return_val_if_fail (font_desc != NULL, NULL);
font_map = pango_x_font_map_for_display (GDK_DISPLAY_XDISPLAY (display));
font = pango_font_map_load_font (font_map, NULL, font_desc);
if (font)
{
gchar *charset = gdk_font_charset_for_locale ();
gint n_subfonts;
PangoXSubfont *subfont_ids;
gint *subfont_charsets;
n_subfonts = pango_x_list_subfonts (font, &charset, 1,
&subfont_ids, &subfont_charsets);
if (n_subfonts > 0)
{
gchar *xlfd = pango_x_font_subfont_xlfd (font, subfont_ids[0]);
result = gdk_font_load_for_display (display, xlfd);
g_free (xlfd);
}
g_free (subfont_ids);
g_free (subfont_charsets);
g_free (charset);
g_object_unref (G_OBJECT (font));
}
return result;
}
/**
* gdk_font_from_description:
* @font_desc: a #PangoFontDescription.
@ -203,44 +312,12 @@ gdk_font_charset_for_locale (void)
GdkFont*
gdk_font_from_description (PangoFontDescription *font_desc)
{
PangoFontMap *font_map;
PangoFont *font;
GdkFont *result = NULL;
g_return_val_if_fail (font_desc != NULL, NULL);
font_map = pango_x_font_map_for_display (GDK_DISPLAY ());
font = pango_font_map_load_font (font_map, NULL, font_desc);
if (font)
{
gchar *charset = gdk_font_charset_for_locale ();
gint n_subfonts;
PangoXSubfont *subfont_ids;
gint *subfont_charsets;
n_subfonts = pango_x_list_subfonts (font, &charset, 1,
&subfont_ids, &subfont_charsets);
if (n_subfonts > 0)
{
gchar *xlfd = pango_x_font_subfont_xlfd (font, subfont_ids[0]);
result = gdk_font_load (xlfd);
g_free (xlfd);
}
g_free (subfont_ids);
g_free (subfont_charsets);
g_free (charset);
g_object_unref (G_OBJECT (font));
}
return result;
return gdk_font_from_description_for_display (gdk_get_default_display (),font_desc);
}
GdkFont*
gdk_fontset_load (const gchar *fontset_name)
GdkFont *
gdk_fontset_load_for_display (GdkDisplay *display,
const gchar *fontset_name)
{
GdkFont *font;
GdkFontPrivateX *private;
@ -249,15 +326,17 @@ gdk_fontset_load (const gchar *fontset_name)
gchar **missing_charset_list;
gchar *def_string;
font = gdk_font_hash_lookup (GDK_FONT_FONTSET, fontset_name);
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
font = gdk_font_hash_lookup (display, GDK_FONT_FONTSET, fontset_name);
if (font)
return font;
private = g_new (GdkFontPrivateX, 1);
font = (GdkFont*) private;
private->xdisplay = gdk_display;
fontset = XCreateFontSet (gdk_display, fontset_name,
private->display = display;
fontset = XCreateFontSet (GDK_DISPLAY_XDISPLAY (display), fontset_name,
&missing_charset_list, &missing_charset_count,
&def_string);
@ -297,7 +376,7 @@ gdk_fontset_load (const gchar *fontset_name)
font->ascent = MAX (font->ascent, font_structs[i]->ascent);
font->descent = MAX (font->descent, font_structs[i]->descent);
}
private->names = NULL;
gdk_font_hash_insert (GDK_FONT_FONTSET, font, fontset_name);
@ -305,6 +384,12 @@ gdk_fontset_load (const gchar *fontset_name)
}
}
GdkFont*
gdk_fontset_load (const gchar *fontset_name)
{
return gdk_fontset_load_for_display (gdk_get_default_display (), fontset_name);
}
void
_gdk_font_destroy (GdkFont *font)
{
@ -315,11 +400,13 @@ _gdk_font_destroy (GdkFont *font)
switch (font->type)
{
case GDK_FONT_FONT:
gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
_gdk_xid_table_remove (private->display, ((XFontStruct *) private->xfont)->fid);
XFreeFont (GDK_DISPLAY_XDISPLAY (private->display),
(XFontStruct *) private->xfont);
break;
case GDK_FONT_FONTSET:
XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
XFreeFontSet (GDK_DISPLAY_XDISPLAY (private->display),
(XFontSet) private->xfont);
break;
default:
g_error ("unknown font type.");
@ -670,7 +757,7 @@ gdk_x11_font_get_xdisplay (GdkFont *font)
{
g_return_val_if_fail (font != NULL, NULL);
return ((GdkFontPrivateX *)font)->xdisplay;
return GDK_DISPLAY_XDISPLAY (((GdkFontPrivateX *)font)->display);
}
gpointer

View File

@ -29,6 +29,7 @@
#include "gdkgc.h"
#include "gdkprivate-x11.h"
#include "gdkregion-generic.h"
#include "gdkx.h"
#include <string.h>
@ -110,7 +111,7 @@ gdk_gc_x11_finalize (GObject *object)
#if HAVE_XFT
if (x11_gc->fg_picture != None)
XRenderFreePicture (x11_gc->xdisplay, x11_gc->fg_picture);
XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
#endif
XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
@ -141,7 +142,7 @@ _gdk_x11_gc_new (GdkDrawable *drawable,
private->dirty_mask = 0;
private->clip_region = NULL;
private->xdisplay = GDK_DRAWABLE_IMPL_X11 (drawable)->xdisplay;
private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN))
{
@ -230,7 +231,8 @@ gdk_x11_gc_get_values (GdkGC *gc,
{
values->foreground.pixel = xvalues.foreground;
values->background.pixel = xvalues.background;
values->font = gdk_font_lookup (xvalues.font);
values->font = gdk_font_lookup_for_display (GDK_GC_DISPLAY (gc),
xvalues.font);
switch (xvalues.function)
{
@ -300,8 +302,10 @@ gdk_x11_gc_get_values (GdkGC *gc,
break;
}
values->tile = gdk_pixmap_lookup (xvalues.tile);
values->stipple = gdk_pixmap_lookup (xvalues.stipple);
values->tile = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc),
xvalues.tile);
values->stipple = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc),
xvalues.stipple);
values->clip_mask = NULL;
values->subwindow_mode = xvalues.subwindow_mode;
values->ts_x_origin = xvalues.ts_x_origin;
@ -731,12 +735,28 @@ gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
x11_dst_gc->fg_pixel = x11_src_gc->fg_pixel;
}
/**
* gdk_gc_get_screen:
* @gc: a #GdkGC.
*
* Gets the #GdkScreen for which @gc was created
*
* Returns: the #GdkScreen for @gc.
*/
GdkScreen *
gdk_gc_get_screen (GdkGC *gc)
{
g_return_val_if_fail (GDK_IS_GC_X11 (gc), NULL);
return GDK_GC_X11 (gc)->screen;
}
Display *
gdk_x11_gc_get_xdisplay (GdkGC *gc)
{
g_return_val_if_fail (GDK_IS_GC_X11 (gc), NULL);
return GDK_GC_X11(gc)->xdisplay;
return GDK_SCREEN_XDISPLAY (gdk_gc_get_screen (gc));
}
GC
@ -804,7 +824,7 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc)
g_return_val_if_fail (GDK_IS_GC_X11 (gc), None);
if (!_gdk_x11_have_render ())
if (!_gdk_x11_have_render (GDK_GC_DISPLAY (gc)))
return None;
x11_gc = GDK_GC_X11 (gc);
@ -818,14 +838,15 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc)
if (!pix_format)
return None;
pix = XCreatePixmap (x11_gc->xdisplay, _gdk_root_window,
pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
GDK_SCREEN_XROOTWIN (x11_gc->screen),
1, 1, pix_format->depth);
pa.repeat = True;
x11_gc->fg_picture = XRenderCreatePicture (x11_gc->xdisplay,
x11_gc->fg_picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
pix,
pix_format,
CPRepeat, &pa);
XFreePixmap (x11_gc->xdisplay, pix);
XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
new = TRUE;
}
@ -842,7 +863,7 @@ _gdk_x11_gc_get_fg_picture (GdkGC *gc)
x11_gc->fg_picture_color.blue = color.blue;
x11_gc->fg_picture_color.alpha = 0xffff;
XRenderFillRectangle (x11_gc->xdisplay, PictOpSrc,
XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
x11_gc->fg_picture, &x11_gc->fg_picture_color,
0, 0, 1, 1);
}

View File

@ -134,6 +134,8 @@
#include "gdkx.h"
#include "gdkregion.h"
#include "gdkinternals.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h"
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
typedef struct _GdkWindowParentPos GdkWindowParentPos;
@ -186,8 +188,6 @@ static void gdk_window_clip_changed (GdkWindow *window,
GdkRectangle *old_clip,
GdkRectangle *new_clip);
static GQueue *translate_queue = NULL;
void
_gdk_windowing_window_get_offsets (GdkWindow *window,
gint *x_offset,
@ -915,17 +915,19 @@ static void
gdk_window_queue (GdkWindow *window,
GdkWindowQueueItem *item)
{
if (!translate_queue)
translate_queue = g_queue_new ();
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
if (!display_x11->translate_queue)
display_x11->translate_queue = g_queue_new ();
/* Keep length of queue finite by, if it grows too long,
* figuring out the latest relevant serial and discarding
* irrelevant queue items.
*/
if (translate_queue->length >= 64 )
if (display_x11->translate_queue->length >= 64)
{
gulong serial = find_current_serial (GDK_WINDOW_XDISPLAY (window));
GList *tmp_list = translate_queue->head;
GList *tmp_list = display_x11->translate_queue->head;
while (tmp_list)
{
@ -934,7 +936,7 @@ gdk_window_queue (GdkWindow *window,
if (serial > item->serial)
{
queue_delete_link (translate_queue, tmp_list);
queue_delete_link (display_x11->translate_queue, tmp_list);
queue_item_free (item);
}
@ -948,9 +950,9 @@ gdk_window_queue (GdkWindow *window,
* discard anti-expose items. (We can't discard translate
* items
*/
if (translate_queue->length >= 64 )
if (display_x11->translate_queue->length >= 64)
{
GList *tmp_list = translate_queue->head;
GList *tmp_list = display_x11->translate_queue->head;
while (tmp_list)
{
@ -959,7 +961,7 @@ gdk_window_queue (GdkWindow *window,
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
{
queue_delete_link (translate_queue, tmp_list);
queue_delete_link (display_x11->translate_queue, tmp_list);
queue_item_free (item);
}
@ -972,7 +974,7 @@ gdk_window_queue (GdkWindow *window,
item->window = window;
item->serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
g_queue_push_tail (translate_queue, item);
g_queue_push_tail (display_x11->translate_queue, item);
}
static void
@ -1009,12 +1011,12 @@ _gdk_window_process_expose (GdkWindow *window,
GdkWindowImplX11 *impl;
GdkRegion *invalidate_region = gdk_region_rectangle (area);
GdkRegion *clip_region;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl);
if (translate_queue)
if (display_x11->translate_queue)
{
GList *tmp_list = translate_queue->head;
GList *tmp_list = display_x11->translate_queue->head;
while (tmp_list)
{
@ -1033,7 +1035,8 @@ _gdk_window_process_expose (GdkWindow *window,
}
else
{
queue_delete_link (translate_queue, translate_queue->head);
queue_delete_link (display_x11->translate_queue,
display_x11->translate_queue->head);
queue_item_free (item);
}
}

View File

@ -28,17 +28,8 @@
#include "gdktypes.h"
#include "gdkprivate-x11.h"
#include "config.h"
gboolean _gdk_use_xshm = TRUE;
gchar *_gdk_display_name = NULL;
gboolean _gdk_use_xshm = TRUE; /* used as a cmd line arg */
Display *gdk_display = NULL;
gint _gdk_screen;
Window _gdk_root_window;
Window _gdk_leader_window;
Atom _gdk_wm_window_protocols[3];
GdkAtom _gdk_selection_property;
GdkWindowObject *_gdk_xgrab_window = NULL; /* Window that currently holds the
* x pointer grab
*/
gboolean _gdk_synchronize = FALSE;

View File

@ -27,10 +27,12 @@
#include <locale.h>
#include <stdlib.h>
#include "gdkx.h"
#include "gdk.h" /* For gdk_flush() */
#include "gdkx.h"
#include "gdkpixmap.h"
#include "gdkinternals.h"
#include "gdkprivate-x11.h"
#include "gdkdisplay-x11.h"
#if HAVE_CONFIG_H
# include <config.h>
@ -108,6 +110,17 @@ gdk_set_locale (void)
return setlocale (LC_ALL, NULL);
}
static GdkDisplay *
find_a_display ()
{
GdkDisplay *display = gdk_get_default_display ();
if (!display)
display = _gdk_displays->data;
return display;
}
/*
* gdk_wcstombs
*
@ -123,6 +136,8 @@ gdk_wcstombs (const GdkWChar *src)
if (gdk_use_mb)
{
GdkDisplay *display = find_a_display ();
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
XTextProperty tpr;
if (sizeof(wchar_t) != sizeof(GdkWChar))
@ -133,7 +148,7 @@ gdk_wcstombs (const GdkWChar *src)
src_alt = g_new (wchar_t, i+1);
for (; i>=0; i--)
src_alt[i] = src[i];
if (XwcTextListToTextProperty (gdk_display, &src_alt, 1, XTextStyle, &tpr)
if (XwcTextListToTextProperty (xdisplay, &src_alt, 1, XTextStyle, &tpr)
!= Success)
{
g_free (src_alt);
@ -143,7 +158,7 @@ gdk_wcstombs (const GdkWChar *src)
}
else
{
if (XwcTextListToTextProperty (gdk_display, (wchar_t**)&src, 1,
if (XwcTextListToTextProperty (xdisplay, (wchar_t**)&src, 1,
XTextStyle, &tpr) != Success)
{
return NULL;
@ -185,18 +200,20 @@ gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
{
if (gdk_use_mb)
{
GdkDisplay *display = find_a_display ();
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
XTextProperty tpr;
wchar_t **wstrs, *wstr_src;
gint num_wstrs;
gint len_cpy;
if (XmbTextListToTextProperty (gdk_display, (char **)&src, 1, XTextStyle,
if (XmbTextListToTextProperty (xdisplay, (char **)&src, 1, XTextStyle,
&tpr)
!= Success)
{
/* NoMem or LocaleNotSupp */
return -1;
}
if (XwcTextPropertyToTextList (gdk_display, &tpr, &wstrs, &num_wstrs)
if (XwcTextPropertyToTextList (xdisplay, &tpr, &wstrs, &num_wstrs)
!= Success)
{
/* InvalidChar */

View File

@ -48,23 +48,25 @@
#include <errno.h>
#include "gdk.h" /* For gdk_error_trap_* / gdk_flush_* */
#include "gdkx.h"
#include "gdkimage.h"
#include "gdkprivate.h"
#include "gdkprivate-x11.h"
#include "gdkdisplay-x11.h"
#include "gdkscreen-x11.h"
typedef struct _GdkImagePrivateX11 GdkImagePrivateX11;
struct _GdkImagePrivateX11
{
XImage *ximage;
Display *xdisplay;
GdkScreen *screen;
gpointer x_shm_info;
Pixmap shm_pixmap;
};
static GList *image_list = NULL;
static gpointer parent_class = NULL;
static gboolean have_shm_pixmaps;
static void gdk_x11_image_destroy (GdkImage *image);
static void gdk_image_init (GdkImage *image);
@ -151,7 +153,7 @@ gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h)
GdkImagePrivateX11 *private;
image = g_object_new (gdk_image_get_type (), NULL);
private = PRIVATE_DATA (image);
private->xdisplay = gdk_display;
private->screen = visual->screen;
image->type = GDK_IMAGE_NORMAL;
image->visual = visual;
image->width = w;
@ -159,8 +161,9 @@ gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h)
image->depth = 1;
image->bits_per_pixel = 1;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
private->ximage = XCreateImage(private->xdisplay, xvisual, 1, XYBitmap,
0, 0, w ,h, 8, 0);
private->ximage = XCreateImage (GDK_SCREEN_XDISPLAY (visual->screen),
xvisual, 1, XYBitmap,
0, 0, w ,h, 8, 0);
private->ximage->data = data;
private->ximage->bitmap_bit_order = MSBFirst;
private->ximage->byte_order = MSBFirst;
@ -196,21 +199,24 @@ gdk_image_check_xshm(Display *display)
}
void
_gdk_windowing_image_init (void)
_gdk_windowing_image_init (GdkDisplay *display)
{
if (_gdk_use_xshm)
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->use_xshm)
{
gint res = gdk_image_check_xshm (gdk_display);
gint res = gdk_image_check_xshm (GDK_DISPLAY_XDISPLAY (display));
if (!res)
_gdk_use_xshm = FALSE;
else
have_shm_pixmaps = (res == 2);
display_x11->use_xshm = False;
else
display_x11->have_shm_pixmaps = (res == 2);
}
}
GdkImage*
_gdk_image_new_for_depth (GdkImageType type,
_gdk_image_new_for_depth (GdkScreen *screen,
GdkImageType type,
GdkVisual *visual,
gint width,
gint height,
@ -222,20 +228,27 @@ _gdk_image_new_for_depth (GdkImageType type,
XShmSegmentInfo *x_shm_info;
#endif /* USE_SHM */
Visual *xvisual = NULL;
GdkDisplayX11 *display_x11;
GdkScreenX11 *screen_x11;
g_return_val_if_fail (!visual || GDK_IS_VISUAL (visual), NULL);
g_return_val_if_fail (visual || depth != -1, NULL);
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
display_x11 = GDK_DISPLAY_X11 (screen_x11->display);
if (visual)
depth = visual->depth;
switch (type)
{
case GDK_IMAGE_FASTEST:
image = _gdk_image_new_for_depth (GDK_IMAGE_SHARED, visual, width, height, depth);
image = _gdk_image_new_for_depth (screen, GDK_IMAGE_SHARED,
visual, width, height, depth);
if (!image)
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height, depth);
image = _gdk_image_new_for_depth (screen, GDK_IMAGE_NORMAL,
visual, width, height, depth);
break;
default:
@ -243,7 +256,7 @@ _gdk_image_new_for_depth (GdkImageType type,
private = PRIVATE_DATA (image);
private->xdisplay = gdk_display;
private->screen = screen;
image->type = type;
image->visual = visual;
@ -258,20 +271,20 @@ _gdk_image_new_for_depth (GdkImageType type,
{
case GDK_IMAGE_SHARED:
#ifdef USE_SHM
if (_gdk_use_xshm)
if (display_x11->use_xshm)
{
private->x_shm_info = g_new (XShmSegmentInfo, 1);
x_shm_info = private->x_shm_info;
x_shm_info->shmid = -1;
x_shm_info->shmaddr = (char*) -1;
private->ximage = XShmCreateImage (private->xdisplay, xvisual, depth,
private->ximage = XShmCreateImage (screen_x11->xdisplay, xvisual, depth,
ZPixmap, NULL, x_shm_info, width, height);
if (private->ximage == NULL)
{
g_warning ("XShmCreateImage failed");
_gdk_use_xshm = FALSE;
display_x11->use_xshm = FALSE;
goto error;
}
@ -289,7 +302,7 @@ _gdk_image_new_for_depth (GdkImageType type,
if (errno != EINVAL)
{
g_warning ("shmget failed: error %d (%s)", errno, g_strerror (errno));
_gdk_use_xshm = FALSE;
display_x11->use_xshm = FALSE;
}
goto error;
@ -306,19 +319,19 @@ _gdk_image_new_for_depth (GdkImageType type,
* EMFILE, which would mean that we've exceeded the per-process
* Shm segment limit.
*/
_gdk_use_xshm = FALSE;
display_x11->use_xshm = FALSE;
goto error;
}
gdk_error_trap_push ();
XShmAttach (private->xdisplay, x_shm_info);
XSync (private->xdisplay, False);
XShmAttach (screen_x11->xdisplay, x_shm_info);
XSync (screen_x11->xdisplay, False);
if (gdk_error_trap_pop ())
{
/* this is the common failure case so omit warning */
_gdk_use_xshm = FALSE;
display_x11->use_xshm = FALSE;
goto error;
}
@ -338,7 +351,7 @@ _gdk_image_new_for_depth (GdkImageType type,
goto error;
break;
case GDK_IMAGE_NORMAL:
private->ximage = XCreateImage (private->xdisplay, xvisual, depth,
private->ximage = XCreateImage (screen_x11->xdisplay, xvisual, depth,
ZPixmap, 0, 0, width, height, 32, 0);
/* Use malloc, not g_malloc here, because X will call free()
@ -395,13 +408,17 @@ Pixmap
_gdk_x11_image_get_shm_pixmap (GdkImage *image)
{
GdkImagePrivateX11 *private = PRIVATE_DATA (image);
GdkDisplay *display = GDK_SCREEN_DISPLAY (private->screen);
#ifdef USE_SHM
/* Future: do we need one of these per-screen per-image? ShmPixmaps
* are the same for every screen, but can they be shared?
* are the same for every screen, but can they be shared? Not a concern
* right now since we tie images to a particular screen.
*/
if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED && have_shm_pixmaps)
private->shm_pixmap = XShmCreatePixmap (private->xdisplay, _gdk_root_window,
if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED &&
GDK_DISPLAY_X11 (display)->have_shm_pixmaps)
private->shm_pixmap = XShmCreatePixmap (GDK_SCREEN_XDISPLAY (private->screen),
GDK_SCREEN_XROOTWIN (private->screen),
image->mem, private->x_shm_info,
image->width, image->height, image->depth);
@ -417,7 +434,8 @@ gdk_image_new (GdkImageType type,
gint width,
gint height)
{
return _gdk_image_new_for_depth (type, visual, width, height, -1);
return _gdk_image_new_for_depth (visual->screen, type,
visual, width, height, -1);
}
static GdkImage*
@ -434,7 +452,7 @@ get_full_image (GdkDrawable *drawable,
impl = GDK_DRAWABLE_IMPL_X11 (drawable);
ximage = XGetImage (impl->xdisplay,
ximage = XGetImage (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
src_x, src_y, width, height,
AllPlanes, ZPixmap);
@ -446,7 +464,7 @@ get_full_image (GdkDrawable *drawable,
private = PRIVATE_DATA (image);
private->xdisplay = gdk_display;
private->screen = impl->screen;
private->ximage = ximage;
image->type = GDK_IMAGE_NORMAL;
@ -491,11 +509,11 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
have_grab = FALSE;
#define UNGRAB() G_STMT_START { \
if (have_grab) { \
gdk_x11_ungrab_server (); \
XFlush (impl->xdisplay); \
have_grab = FALSE; } \
#define UNGRAB() G_STMT_START { \
if (have_grab) { \
gdk_x11_display_ungrab (GDK_DRAWABLE_DISPLAY (drawable)); \
XFlush (GDK_DRAWABLE_DISPLAY (drawable)); \
have_grab = FALSE; } \
} G_STMT_END
if (!image && !GDK_IS_WINDOW_IMPL_X11 (drawable))
@ -506,19 +524,20 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
shm_pixmap = _gdk_x11_image_get_shm_pixmap (image);
if (shm_pixmap)
{
Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
GC xgc;
XGCValues values;
/* Again easy, we can just XCopyArea, and don't have to worry about clipping
*/
values.subwindow_mode = IncludeInferiors;
xgc = XCreateGC (impl->xdisplay, impl->xid, GCSubwindowMode, &values);
xgc = XCreateGC (xdisplay, impl->xid, GCSubwindowMode, &values);
XCopyArea (impl->xdisplay, impl->xid, shm_pixmap, xgc,
XCopyArea (xdisplay, impl->xid, shm_pixmap, xgc,
src_x, src_y, width, height, dest_x, dest_y);
XSync (impl->xdisplay, FALSE);
XSync (xdisplay, FALSE);
XFreeGC (impl->xdisplay, xgc);
XFreeGC (xdisplay, xgc);
return image;
}
@ -534,18 +553,18 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
Window child;
have_grab = TRUE;
gdk_x11_grab_server ();
gdk_x11_display_grab (gdk_screen_get_display (impl->screen));
/* Translate screen area into window coordinates */
XTranslateCoordinates (gdk_display,
_gdk_root_window,
impl->xid,
XTranslateCoordinates (GDK_SCREEN_XDISPLAY (impl->screen),
GDK_SCREEN_XROOTWIN (impl->screen),
impl->xid,
0, 0,
&screen_rect.x, &screen_rect.y,
&child);
screen_rect.width = gdk_screen_width ();
screen_rect.height = gdk_screen_height ();
screen_rect.width = gdk_screen_get_width (visual->screen);
screen_rect.height = gdk_screen_get_height (visual->screen);
gdk_error_trap_push ();
@ -603,7 +622,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
if (!image)
{
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height,
image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL,
visual, width, height,
gdk_drawable_get_depth (drawable));
created_image = TRUE;
}
@ -613,7 +633,7 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
/* In the ShmImage but no ShmPixmap case, we could use XShmGetImage when
* we are getting the entire image.
*/
if (XGetSubImage (impl->xdisplay,
if (XGetSubImage (GDK_SCREEN_XDISPLAY (impl->screen),
impl->xid,
req.x, req.y, req.width, req.height,
AllPlanes, ZPixmap,
@ -631,8 +651,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
if (have_grab)
{
gdk_x11_ungrab_server ();
XFlush (impl->xdisplay);
gdk_x11_display_ungrab (gdk_drawable_get_display (drawable));
XFlush (GDK_DRAWABLE_XDISPLAY (drawable));
have_grab = FALSE;
}
@ -641,7 +661,8 @@ _gdk_x11_copy_to_image (GdkDrawable *drawable,
if (success && !image)
{
/* We "succeeded", but could get no content for the image so return junk */
image = _gdk_image_new_for_depth (GDK_IMAGE_NORMAL, visual, width, height,
image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL,
visual, width, height,
gdk_drawable_get_depth (drawable));
}
@ -708,13 +729,13 @@ gdk_x11_image_destroy (GdkImage *image)
case GDK_IMAGE_SHARED:
#ifdef USE_SHM
gdk_flush();
gdk_display_sync (GDK_SCREEN_DISPLAY (private->screen));
if (private->shm_pixmap)
XFreePixmap (private->xdisplay, private->shm_pixmap);
XFreePixmap (GDK_SCREEN_XDISPLAY (private->screen), private->shm_pixmap);
image_list = g_list_remove (image_list, image);
XShmDetach (private->xdisplay, private->x_shm_info);
XShmDetach (GDK_SCREEN_XDISPLAY (private->screen), private->x_shm_info);
XDestroyImage (private->ximage);
x_shm_info = private->x_shm_info;
@ -746,7 +767,7 @@ gdk_x11_image_get_xdisplay (GdkImage *image)
private = PRIVATE_DATA (image);
return private->xdisplay;
return GDK_SCREEN_XDISPLAY (private->screen);
}
XImage *
@ -762,12 +783,13 @@ gdk_x11_image_get_ximage (GdkImage *image)
}
gint
_gdk_windowing_get_bits_for_depth (gint depth)
_gdk_windowing_get_bits_for_depth (GdkDisplay *display,
gint depth)
{
XPixmapFormatValues *formats;
gint count, i;
formats = XListPixmapFormats (gdk_display, &count);
formats = XListPixmapFormats (GDK_DISPLAY_XDISPLAY (display), &count);
for (i = 0; i < count; i++)
if (formats[i].depth == depth)
@ -780,3 +802,4 @@ _gdk_windowing_get_bits_for_depth (gint depth)
g_assert_not_reached ();
return -1;
}

View File

@ -1,574 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include <stdlib.h>
#include "gdkinputprivate.h"
#include "gdkx.h"
/* #define DEBUG_SWITCHING */
#include <gxid_lib.h>
/* Forward declarations */
static void gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev);
static gint gdk_input_is_extension_device (GdkDevicePrivate *device_private);
static void gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev);
static Window gdk_input_find_root_child(Display *dpy, Window w);
static void gdk_input_compute_obscuring(GdkInputWindow *input_window);
static gint gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x,
gdouble y);
/* Local variables */
static GdkDevicePrivate *gdk_input_current_device;
static GdkDevicePrivate *gdk_input_core_pointer;
void
_gdk_input_init(void)
{
GList *tmp_list;
_gdk_init_input_core ();
_gdk_input_ignore_core = FALSE;
gdk_input_core_pointer = NULL;
if (!_gdk_input_gxid_host)
{
_gdk_input_gxid_host = getenv("GXID_HOST");
}
if (!_gdk_input_gxid_port)
{
char *t = getenv("GXID_PORT");
if (t)
_gdk_input_gxid_port = atoi(t);
}
gdk_input_common_init(TRUE);
/* find initial core pointer */
for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
{
GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (gdk_input_is_extension_device (gdkdev))
{
gdk_input_gxi_select_notify (gdkdev);
}
else
{
if (!GDK_IS_CORE (gdkdev))
gdk_input_core_pointer = gdkdev;
}
}
}
static void
gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev)
{
XEventClass class;
ChangeDeviceNotify (gdkdev->xdevice, gdkdev->changenotify_type, class);
XSelectExtensionEvent (gdk_display, _gdk_root_window, &class, 1);
}
/* Set the core pointer. Device should already be enabled. */
static gint
gdk_input_gxi_set_core_pointer(GdkDevicePrivate *gdkdev)
{
gint x_axis = -1;
gint y_axis = -1;
gint i;
g_return_val_if_fail(gdkdev->xdevice,FALSE);
for (i=0; i<gdkdev->info.num_axes; i++)
{
if (gdkdev->info.axes[i].use == GDK_AXIS_X)
x_axis = i;
else if (gdkdev->info.axes[i].use == GDK_AXIS_Y)
y_axis = i;
}
g_return_val_if_fail (x_axis != -1 && y_axis != -1,FALSE);
/* core_pointer might not be up to date so we check with the server
before change the pointer */
if (!gdk_input_is_extension_device (gdkdev))
{
#if 0
if (gdkdev != gdk_input_core_pointer)
g_warning("core pointer inconsistency");
#endif
return TRUE;
}
if ( XChangePointerDevice(gdk_display,gdkdev->xdevice, x_axis, y_axis)
!= Success )
{
return FALSE;
}
else
{
gdk_input_gxi_update_device (gdk_input_core_pointer);
gdk_input_core_pointer = gdkdev;
return TRUE;
}
}
/* FIXME, merge with the XFree implementation */
gboolean
gdk_device_set_mode (GdkDevice *device,
GdkInputMode mode)
{
GList *tmp_list;
GdkDevicePrivate *gdkdev;
GdkInputMode old_mode;
GdkInputWindow *input_window;
if (GDK_IS_CORE (device))
return FALSE;
gdkdev = (GdkDevicePrivate *)device;
if (device->mode == mode)
return TRUE;
old_mode = device->mode;
device->mode = mode;
if (old_mode != GDK_MODE_DISABLED)
{
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
_gdk_input_disable_window (input_window->window, gdkdev);
}
}
if (mode != GDK_MODE_DISABLED)
{
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
if (!_gdk_input_enable_window(input_window->window, gdkdev))
{
gdk_device_set_mode (device, old_mode);
return FALSE;
}
}
}
return TRUE;
}
gint
gdk_input_is_extension_device (GdkDevicePrivate *private)
{
XDeviceInfo *devices;
int num_devices, loop;
if (GDK_IS_CORE (private))
return FALSE;
devices = XListInputDevices(gdk_display, &num_devices);
for(loop=0; loop<num_devices; loop++)
{
if ((devices[loop].id == private->deviceid) &&
(devices[loop].use == IsXExtensionDevice))
{
XFreeDeviceList(devices);
return TRUE;
}
}
XFreeDeviceList(devices);
return FALSE;
}
void
_gdk_input_configure_event (XConfigureEvent *xevent, GdkWindow *window)
{
GdkInputWindow *input_window;
gint root_x, root_y;
input_window = gdk_input_window_find(window);
g_return_if_fail (input_window != NULL);
gdk_input_get_root_relative_geometry(gdk_display,GDK_WINDOW_XWINDOW(window),
&root_x, &root_y, NULL, NULL);
input_window->root_x = root_x;
input_window->root_y = root_y;
gdk_input_compute_obscuring(input_window);
}
void
_gdk_input_enter_event (XCrossingEvent *xevent, GdkWindow *window)
{
GdkInputWindow *input_window;
input_window = gdk_input_window_find(window);
g_return_if_fail (input_window != NULL);
gdk_input_compute_obscuring(input_window);
}
gint
_gdk_input_other_event (GdkEvent *event,
XEvent *xevent,
GdkWindow *window)
{
GdkInputWindow *input_window;
GdkWindowImplX11 *impl;
GdkDevicePrivate *gdkdev;
gint return_val;
input_window = gdk_input_window_find(window);
g_return_val_if_fail (window != NULL, -1);
impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *) input_window->window)->impl);
/* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
but it's potentially faster than scanning through the types of
every device. If we were deceived, then it won't match any of
the types for the device anyways */
gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
if (!gdkdev)
{
return -1; /* we don't handle it - not an XInput event */
}
if (gdkdev->info.mode == GDK_MODE_DISABLED ||
input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
return FALSE;
if (gdkdev != gdk_input_current_device &&
xevent->type != gdkdev->changenotify_type)
{
gdk_input_current_device = gdkdev;
}
return_val = gdk_input_common_other_event (event, xevent,
input_window, gdkdev);
if (return_val > 0 && event->type == GDK_MOTION_NOTIFY &&
(!gdkdev->button_state) && (!input_window->grabbed) &&
((event->motion.x < 0) || (event->motion.y < 0) ||
(event->motion.x > impl->width) ||
(event->motion.y > impl->height) ||
gdk_input_is_obscured(input_window,event->motion.x,event->motion.y)))
{
#ifdef DEBUG_SWITCHING
g_print("gdkinput: Setting core pointer to %d on motion at (%f,%f)\n",
gdkdev->info.deviceid,event->motion.x,event->motion.y);
g_print(" window geometry is: %dx%d\n",
((GdkWindowPrivate *)window)->width,
((GdkWindowPrivate *)window)->height);
#endif
gdk_input_gxi_set_core_pointer(gdkdev);
return FALSE;
}
else
return return_val;
}
static void
gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev)
{
GList *t;
if (gdk_input_is_extension_device (gdkdev))
{
if (!gdkdev->xdevice)
{
gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->deviceid);
gdk_input_gxi_select_notify (gdkdev);
gdkdev->needs_update = 1;
}
if (gdkdev->needs_update && gdkdev->xdevice)
{
for (t = _gdk_input_windows; t; t = t->next)
gdk_input_common_select_events (((GdkInputWindow *)t->data)->window,
gdkdev);
gdkdev->needs_update = 0;
}
}
}
gint
_gdk_input_window_none_event (GdkEvent *event, XEvent *xevent)
{
GdkDevicePrivate *gdkdev =
gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
if (!gdkdev) {
return -1; /* we don't handle it - not an XInput event */
}
if (xevent->type == gdkdev->changenotify_type)
{
if (gdk_input_core_pointer != gdkdev)
{
#ifdef DEBUG_SWITCHING
g_print("ChangeNotify from %d to %d:\n",
gdk_input_core_pointer->info.deviceid,
gdkdev->info.deviceid);
#endif
gdk_input_gxi_update_device (gdk_input_core_pointer);
gdk_input_core_pointer = gdkdev;
}
}
return FALSE;
}
gboolean
_gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
{
GdkInputWindow *input_window;
input_window = gdk_input_window_find (window);
g_return_val_if_fail (input_window != NULL, FALSE);
if (!gdkdev->claimed)
{
if (_gxid_claim_device(_gdk_input_gxid_host, _gdk_input_gxid_port,
gdkdev->deviceid,
GDK_WINDOW_XWINDOW(window), FALSE) !=
GXID_RETURN_OK)
{
g_warning("Could not get device (is gxid running?)\n");
return FALSE;
}
gdkdev->claimed = TRUE;
}
if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
gdk_input_common_select_events(window, gdkdev);
else
gdkdev->needs_update = TRUE;
return TRUE;
}
gboolean
_gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
{
GdkInputWindow *input_window;
input_window = gdk_input_window_find (window);
g_return_val_if_fail (input_window != NULL, FALSE);
if (gdkdev->claimed)
{
_gxid_release_device(_gdk_input_gxid_host, _gdk_input_gxid_port,
gdkdev->deviceid,
GDK_WINDOW_XWINDOW(window));
gdkdev->claimed = FALSE;
}
if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
gdk_input_common_select_events(window, gdkdev);
else
gdkdev->needs_update = TRUE;
return TRUE;
}
static gint
gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, gdouble y)
{
int i;
for (i=0;i<input_window->num_obscuring;i++)
{
GdkRectangle *rect = &input_window->obscuring[i];
if ((x >= rect->x) &&
(y >= rect->y) &&
(x < rect->x + rect->width) &&
(y < rect->y + rect->height))
return TRUE;
}
return FALSE;
}
/* If this routine needs fixing, the corresponding routine
in gxid.c will need it too. */
static Window
gdk_input_find_root_child(Display *dpy, Window w)
{
Window root,parent;
Window *children;
int nchildren;
parent = w;
do
{
w = parent;
XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
if (children) XFree(children);
}
while (parent != root);
return w;
}
static void
gdk_input_compute_obscuring(GdkInputWindow *input_window)
{
int i;
int x,y,width,height;
int xc,yc,widthc,heightc,border_widthc,depthc;
Window root,parent;
Window *children;
int nchildren;
Window w = GDK_WINDOW_XWINDOW(input_window->window);
Window root_child = gdk_input_find_root_child(gdk_display,w);
gdk_input_get_root_relative_geometry(gdk_display,w,&x,&y,&width,&height);
input_window->root_x = x;
input_window->root_y = y;
XQueryTree(gdk_display,GDK_ROOT_WINDOW(),
&root,&parent,&children,&nchildren);
if (input_window->obscuring)
g_free(input_window->obscuring);
input_window->obscuring = 0;
input_window->num_obscuring = 0;
for (i=0;i<nchildren;i++)
if (children[i] == root_child)
break;
if (i>=nchildren-1)
{
if (nchildren)
XFree(children);
return;
}
input_window->obscuring = g_new(GdkRectangle,(nchildren-i-1));
for (i=i+1;i<nchildren;i++)
{
int xmin, xmax, ymin, ymax;
XGetGeometry(gdk_display,children[i],&root,&xc,&yc,&widthc,&heightc,
&border_widthc, &depthc);
xmin = xc>x ? xc : x;
xmax = (xc+widthc)<(x+width) ? xc+widthc : x+width;
ymin = yc>y ? yc : y;
ymax = (yc+heightc)<(y+height) ? yc+heightc : y+height;
if ((xmin < xmax) && (ymin < ymax))
{
XWindowAttributes attributes;
XGetWindowAttributes(gdk_display,children[i],&attributes);
if (attributes.map_state == IsViewable)
{
GdkRectangle *rect = &input_window->obscuring[input_window->num_obscuring];
/* we store the whole window, not just the obscuring part */
rect->x = xc - x;
rect->y = yc - y;
rect->width = widthc;
rect->height = heightc;
input_window->num_obscuring++;
}
}
}
if (nchildren)
XFree(children);
}
gint
_gdk_input_grab_pointer (GdkWindow * window,
gint owner_events,
GdkEventMask event_mask,
GdkWindow * confine_to,
guint32 time)
{
GList *tmp_list;
GdkInputWindow *input_window;
GdkDevicePrivate *gdkdev;
tmp_list = _gdk_input_windows;
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->window == window)
input_window->grabbed = TRUE;
else if (input_window->grabbed)
input_window->grabbed = FALSE;
tmp_list = tmp_list->next;
}
tmp_list = _gdk_input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) &&
gdkdev->xdevice &&
(gdkdev->button_state != 0))
gdkdev->button_state = 0;
tmp_list = tmp_list->next;
}
return Success;
}
void
_gdk_input_ungrab_pointer (guint32 time)
{
GdkInputWindow *input_window;
GList *tmp_list;
tmp_list = _gdk_input_windows;
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->grabbed)
input_window->grabbed = FALSE;
tmp_list = tmp_list->next;
}
}

View File

@ -18,6 +18,7 @@
*/
#include "gdkinputprivate.h"
#include "gdkdisplay-x11.h"
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
@ -27,12 +28,14 @@
*/
void
_gdk_input_init (void)
_gdk_input_init (GdkDisplay *display)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
_gdk_init_input_core ();
_gdk_input_devices = g_list_append (NULL, _gdk_core_pointer);
_gdk_input_ignore_core = FALSE;
display_x11->input_devices = g_list_append (NULL, _gdk_core_pointer);
display_x11->input_ignore_core = FALSE;
}
void
@ -117,7 +120,8 @@ _gdk_input_grab_pointer (GdkWindow * window,
}
void
_gdk_input_ungrab_pointer (guint32 time)
_gdk_input_ungrab_pointer (GdkDisplay *display,
guint32 time)
{
}

View File

@ -28,26 +28,28 @@
#include "gdkinternals.h"
#include "gdkx.h"
#include "gdk.h" /* For gdk_error_trap_push()/pop() */
#include "gdkdisplay-x11.h"
#include <string.h>
/* Forward declarations */
static GdkDevicePrivate *gdk_input_device_new(XDeviceInfo *device,
gint include_core);
static void gdk_input_translate_coordinates(GdkDevicePrivate *gdkdev,
GdkInputWindow *input_window,
gint *axis_data,
gdouble *axis_out,
gdouble *x_out,
gdouble *y_out);
static guint gdk_input_translate_state(guint state, guint device_state);
/* Global variables */
static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *display,
XDeviceInfo *device,
gint include_core);
static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
GdkInputWindow *input_window,
gint *axis_data,
gdouble *axis_out,
gdouble *x_out,
gdouble *y_out);
static guint gdk_input_translate_state (guint state,
guint device_state);
GdkDevicePrivate *
gdk_input_find_device (guint32 id)
gdk_input_find_device (GdkDisplay *display,
guint32 id)
{
GList *tmp_list = _gdk_input_devices;
GList *tmp_list = GDK_DISPLAY_X11 (display)->input_devices;
GdkDevicePrivate *gdkdev;
while (tmp_list)
{
@ -60,7 +62,7 @@ gdk_input_find_device (guint32 id)
}
void
gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ret,
gdk_input_get_root_relative_geometry(Display *display, Window w, int *x_ret, int *y_ret,
int *width_ret, int *height_ret)
{
Window root, parent, child;
@ -70,13 +72,13 @@ gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_
guint width, height;
guint border_widthc, depthc;
XQueryTree (dpy, w, &root, &parent, &children, &nchildren);
XQueryTree (display, w, &root, &parent, &children, &nchildren);
if (children)
XFree(children);
XGetGeometry (dpy, w, &root, &x, &y, &width, &height, &border_widthc, &depthc);
XGetGeometry (display, w, &root, &x, &y, &width, &height, &border_widthc, &depthc);
XTranslateCoordinates (dpy, w, root, 0, 0, &x, &y, &child);
XTranslateCoordinates (display, w, root, 0, 0, &x, &y, &child);
if (x_ret)
*x_ret = x;
@ -89,7 +91,9 @@ gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_
}
static GdkDevicePrivate *
gdk_input_device_new (XDeviceInfo *device, gint include_core)
gdk_input_device_new (GdkDisplay *display,
XDeviceInfo *device,
gint include_core)
{
GdkDevicePrivate *gdkdev;
gchar *tmp_name;
@ -99,6 +103,8 @@ gdk_input_device_new (XDeviceInfo *device, gint include_core)
gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
gdkdev->deviceid = device->id;
gdkdev->display = display;
if (device->name[0])
gdkdev->info.name = g_strdup (device->name);
else
@ -218,7 +224,8 @@ gdk_input_device_new (XDeviceInfo *device, gint include_core)
if (device->use != IsXPointer)
{
gdk_error_trap_push ();
gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->deviceid);
gdkdev->xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (display),
gdkdev->deviceid);
/* return NULL if device is not ready */
if (gdk_error_trap_pop ())
@ -263,7 +270,7 @@ gdk_input_common_find_events(GdkWindow *window,
i = 0;
/* We have to track press and release events in pairs to keep
track of button state correctly and implement grabbing for
the gxi support */
the gxi support. FIXME - is this needed any more since gxi is gone? */
if (mask & GDK_BUTTON_PRESS_MASK || mask & GDK_BUTTON_RELEASE_MASK)
{
DeviceButtonPress (gdkdev->xdevice, gdkdev->buttonpress_type,
@ -366,44 +373,46 @@ gdk_input_common_select_events(GdkWindow *window,
((GdkWindowObject *)window)->extension_events,
classes, &num_classes);
XSelectExtensionEvent (gdk_display,
GDK_WINDOW_XWINDOW(window),
XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW (window),
classes, num_classes);
}
gint
gdk_input_common_init(gint include_core)
gdk_input_common_init (GdkDisplay *display,
gint include_core)
{
char **extensions;
XDeviceInfo *devices;
int num_devices;
int num_extensions, loop;
Display *display = gdk_display;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
/* Init XInput extension */
extensions = XListExtensions(display, &num_extensions);
extensions = XListExtensions(display_x11->xdisplay, &num_extensions);
for (loop = 0; loop < num_extensions &&
(strcmp(extensions[loop], "XInputExtension") != 0); loop++);
XFreeExtensionList(extensions);
_gdk_input_devices = NULL;
display_x11->input_devices = NULL;
if (loop < num_extensions)
{
/* XInput extension found */
devices = XListInputDevices(display, &num_devices);
devices = XListInputDevices(display_x11->xdisplay, &num_devices);
for(loop=0; loop<num_devices; loop++)
{
GdkDevicePrivate *gdkdev = gdk_input_device_new(&devices[loop],
include_core);
GdkDevicePrivate *gdkdev = gdk_input_device_new(display,
&devices[loop],
include_core);
if (gdkdev)
_gdk_input_devices = g_list_append(_gdk_input_devices, gdkdev);
display_x11->input_devices = g_list_append(display_x11->input_devices, gdkdev);
}
XFreeDeviceList(devices);
}
_gdk_input_devices = g_list_append (_gdk_input_devices, _gdk_core_pointer);
display_x11->input_devices = g_list_append (display_x11->input_devices, _gdk_core_pointer);
return TRUE;
}
@ -448,8 +457,8 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
if (gdkdev->info.mode == GDK_MODE_SCREEN)
{
x_scale = gdk_screen_width() / device_width;
y_scale = gdk_screen_height() / device_height;
x_scale = gdk_screen_get_width (gdk_drawable_get_screen (input_window->window)) / device_width;
y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height;
x_offset = - input_window->root_x;
y_offset = - input_window->root_y;
@ -690,7 +699,7 @@ _gdk_device_get_history (GdkDevice *device,
g_return_val_if_fail (input_window != NULL, FALSE);
device_coords = XGetDeviceMotionEvents (gdk_display,
device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (window),
gdkdev->xdevice,
start, stop,
n_events, &mode_return,
@ -756,7 +765,8 @@ gdk_device_get_state (GdkDevice *device,
input_window = gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
state = XQueryDeviceState (gdk_display, gdkdev->xdevice);
state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window),
gdkdev->xdevice);
input_class = state->data;
for (i=0; i<state->num_classes; i++)
{

View File

@ -18,6 +18,7 @@
*/
#include "gdkinputprivate.h"
#include "gdkdisplay-x11.h"
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
@ -28,14 +29,14 @@
/* forward declarations */
static void gdk_input_check_proximity (void);
static void gdk_input_check_proximity (GdkDisplay *display);
void
_gdk_input_init(void)
_gdk_input_init(GdkDisplay *display)
{
_gdk_init_input_core ();
_gdk_input_ignore_core = FALSE;
gdk_input_common_init(FALSE);
GDK_DISPLAY_X11 (display)->input_ignore_core = FALSE;
gdk_input_common_init (display, FALSE);
}
gboolean
@ -46,6 +47,7 @@ gdk_device_set_mode (GdkDevice *device,
GdkDevicePrivate *gdkdev;
GdkInputMode old_mode;
GdkInputWindow *input_window;
GdkDisplayX11 *display_impl;
if (GDK_IS_CORE (device))
return FALSE;
@ -58,10 +60,12 @@ gdk_device_set_mode (GdkDevice *device,
old_mode = device->mode;
device->mode = mode;
display_impl = GDK_DISPLAY_X11 (gdkdev->display);
if (mode == GDK_MODE_WINDOW)
{
device->has_cursor = FALSE;
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
@ -74,13 +78,13 @@ gdk_device_set_mode (GdkDevice *device,
else if (mode == GDK_MODE_SCREEN)
{
device->has_cursor = TRUE;
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
_gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
gdkdev);
}
else /* mode == GDK_MODE_DISABLED */
{
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (old_mode != GDK_MODE_WINDOW ||
@ -94,10 +98,11 @@ gdk_device_set_mode (GdkDevice *device,
}
static void
gdk_input_check_proximity (void)
gdk_input_check_proximity (GdkDisplay *display)
{
gint new_proximity = 0;
GList *tmp_list = _gdk_input_devices;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
GList *tmp_list = display_impl->input_devices;
while (tmp_list && !new_proximity)
{
@ -107,7 +112,7 @@ gdk_input_check_proximity (void)
&& !GDK_IS_CORE (gdkdev)
&& gdkdev->xdevice)
{
XDeviceState *state = XQueryDeviceState(GDK_DISPLAY(),
XDeviceState *state = XQueryDeviceState(display_impl->xdisplay,
gdkdev->xdevice);
XInputClass *xic;
int i;
@ -132,7 +137,7 @@ gdk_input_check_proximity (void)
tmp_list = tmp_list->next;
}
_gdk_input_ignore_core = new_proximity;
display_impl->input_ignore_core = new_proximity;
}
void
@ -145,9 +150,9 @@ _gdk_input_configure_event (XConfigureEvent *xevent,
input_window = gdk_input_window_find(window);
g_return_if_fail (window != NULL);
gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
&root_x,
&root_y, NULL, NULL);
gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW (window),
&root_x, &root_y, NULL, NULL);
input_window->root_x = root_x;
input_window->root_y = root_y;
@ -160,14 +165,14 @@ _gdk_input_enter_event (XCrossingEvent *xevent,
GdkInputWindow *input_window;
gint root_x, root_y;
input_window = gdk_input_window_find(window);
input_window = gdk_input_window_find (window);
g_return_if_fail (window != NULL);
gdk_input_check_proximity();
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
&root_x,
&root_y, NULL, NULL);
gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW(window),
&root_x, &root_y, NULL, NULL);
input_window->root_x = root_x;
input_window->root_y = root_y;
@ -182,6 +187,7 @@ _gdk_input_other_event (GdkEvent *event,
GdkDevicePrivate *gdkdev;
gint return_val;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
input_window = gdk_input_window_find(window);
g_return_val_if_fail (window != NULL, -1);
@ -190,8 +196,8 @@ _gdk_input_other_event (GdkEvent *event,
but it's potentially faster than scanning through the types of
every device. If we were deceived, then it won't match any of
the types for the device anyways */
gdkdev = gdk_input_find_device (((XDeviceButtonEvent *)xevent)->deviceid);
gdkdev = gdk_input_find_device (GDK_WINDOW_DISPLAY (window),
((XDeviceButtonEvent *)xevent)->deviceid);
if (!gdkdev)
return -1; /* we don't handle it - not an XInput event */
@ -202,15 +208,15 @@ _gdk_input_other_event (GdkEvent *event,
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
return FALSE;
if (!_gdk_input_ignore_core)
gdk_input_check_proximity();
if (!display_impl->input_ignore_core)
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
return_val = gdk_input_common_other_event (event, xevent,
input_window, gdkdev);
if (return_val > 0 && event->type == GDK_PROXIMITY_OUT &&
_gdk_input_ignore_core)
gdk_input_check_proximity();
display_impl->input_ignore_core)
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
return return_val;
}
@ -244,8 +250,9 @@ _gdk_input_grab_pointer (GdkWindow * window,
XEventClass event_classes[GDK_MAX_DEVICE_CLASSES];
gint num_classes;
gint result;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
tmp_list = _gdk_input_windows;
tmp_list = display_impl->input_windows;
new_window = NULL;
need_ungrab = FALSE;
@ -268,7 +275,7 @@ _gdk_input_grab_pointer (GdkWindow * window,
{
new_window->grabbed = TRUE;
tmp_list = _gdk_input_devices;
tmp_list = display_impl->input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
@ -282,7 +289,7 @@ _gdk_input_grab_pointer (GdkWindow * window,
result = GrabSuccess;
else
#endif
result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
GDK_WINDOW_XWINDOW (window),
owner_events, num_classes, event_classes,
GrabModeAsync, GrabModeAsync, time);
@ -297,14 +304,14 @@ _gdk_input_grab_pointer (GdkWindow * window,
}
else
{
tmp_list = _gdk_input_devices;
tmp_list = display_impl->input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice &&
((gdkdev->button_state != 0) || need_ungrab))
{
XUngrabDevice( gdk_display, gdkdev->xdevice, time);
XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
gdkdev->button_state = 0;
}
@ -317,13 +324,15 @@ _gdk_input_grab_pointer (GdkWindow * window,
}
void
_gdk_input_ungrab_pointer (guint32 time)
_gdk_input_ungrab_pointer (GdkDisplay *display,
guint32 time)
{
GdkInputWindow *input_window = NULL; /* Quiet GCC */
GdkDevicePrivate *gdkdev;
GList *tmp_list;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
tmp_list = _gdk_input_windows;
tmp_list = display_impl->input_windows;
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
@ -336,12 +345,12 @@ _gdk_input_ungrab_pointer (guint32 time)
{
input_window->grabbed = FALSE;
tmp_list = _gdk_input_devices;
tmp_list = display_impl->input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
XUngrabDevice( gdk_display, gdkdev->xdevice, time);
XUngrabDevice( display_impl->xdisplay, gdkdev->xdevice, time);
tmp_list = tmp_list->next;
}

View File

@ -33,6 +33,8 @@
#include "gdkinput.h"
#include "gdkprivate.h"
#include "gdkinputprivate.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h"
static GdkDeviceAxis gdk_input_core_axes[] = {
{ GDK_AXIS_X, 0, 0 },
@ -41,16 +43,6 @@ static GdkDeviceAxis gdk_input_core_axes[] = {
GdkDevice *_gdk_core_pointer = NULL;
/* Global variables */
/* information about network port and host for gxid daemon */
gchar *_gdk_input_gxid_host;
gint _gdk_input_gxid_port;
gint _gdk_input_ignore_core;
GList *_gdk_input_devices;
GList *_gdk_input_windows;
void
_gdk_init_input_core (void)
{
@ -94,10 +86,35 @@ gdk_device_get_type (void)
return object_type;
}
/**
* gdk_devices_list:
*
* Returns the list of available input devices for the default display.
* The list is statically allocated and should not be freed.
*
* Return value: a list of #GdkDevice
**/
GList *
gdk_devices_list (void)
{
return _gdk_input_devices;
return gdk_display_list_devices (gdk_get_default_display ());
}
/**
* gdk_display_list_devices:
* @display : a #GdkDisplay
*
* Returns the list of available input devices attached to @display.
* The list is statically allocated and should not be freed.
*
* Return value: a list of #GdkDevice
**/
GList *
gdk_display_list_devices (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return GDK_DISPLAY_X11 (display)->input_devices;
}
void
@ -232,8 +249,9 @@ GdkInputWindow *
gdk_input_window_find(GdkWindow *window)
{
GList *tmp_list;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
for (tmp_list=display_x11->input_windows; tmp_list; tmp_list=tmp_list->next)
if (((GdkInputWindow *)(tmp_list->data))->window == window)
return (GdkInputWindow *)(tmp_list->data);
@ -253,11 +271,13 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
GdkWindowObject *window_private;
GList *tmp_list;
GdkInputWindow *iw;
GdkDisplayX11 *display_x11;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
window_private = (GdkWindowObject*) window;
display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
if (GDK_WINDOW_DESTROYED (window))
return;
@ -275,7 +295,7 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
iw->num_obscuring = 0;
iw->grabbed = FALSE;
_gdk_input_windows = g_list_append(_gdk_input_windows,iw);
display_x11->input_windows = g_list_append(display_x11->input_windows,iw);
window_private->extension_events = mask;
/* Add enter window events to the event mask */
@ -289,14 +309,14 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
iw = gdk_input_window_find (window);
if (iw)
{
_gdk_input_windows = g_list_remove(_gdk_input_windows,iw);
display_x11->input_windows = g_list_remove(display_x11->input_windows,iw);
g_free(iw);
}
window_private->extension_events = 0;
}
for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next)
{
GdkDevicePrivate *gdkdev = tmp_list->data;
@ -315,11 +335,12 @@ void
gdk_input_window_destroy (GdkWindow *window)
{
GdkInputWindow *input_window;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
input_window = gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
_gdk_input_windows = g_list_remove (_gdk_input_windows,input_window);
display_x11->input_windows = g_list_remove (display_x11->input_windows, input_window);
g_free(input_window);
}
@ -327,31 +348,37 @@ void
_gdk_input_exit (void)
{
GList *tmp_list;
GSList *display_list;
GdkDevicePrivate *gdkdev;
for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
for (display_list = _gdk_displays ; display_list ; display_list = display_list->next)
{
gdkdev = (GdkDevicePrivate *)(tmp_list->data);
if (!GDK_IS_CORE (gdkdev))
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display_list->data);
for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next)
{
gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED);
g_free(gdkdev->info.name);
gdkdev = (GdkDevicePrivate *)(tmp_list->data);
if (!GDK_IS_CORE (gdkdev))
{
gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED);
g_free(gdkdev->info.name);
#ifndef XINPUT_NONE
g_free(gdkdev->axes);
g_free(gdkdev->axes);
#endif
g_free(gdkdev->info.axes);
g_free(gdkdev->info.keys);
g_free(gdkdev);
g_free(gdkdev->info.axes);
g_free(gdkdev->info.keys);
g_free(gdkdev);
}
}
g_list_free(display_x11->input_devices);
for (tmp_list = display_x11->input_windows; tmp_list; tmp_list = tmp_list->next)
g_free(tmp_list->data);
g_list_free(display_x11->input_windows);
}
g_list_free(_gdk_input_devices);
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
g_free(tmp_list->data);
g_list_free(_gdk_input_windows);
}
/**

View File

@ -67,6 +67,8 @@ struct _GdkDevicePrivate
GdkDevice info;
guint32 deviceid;
GdkDisplay *display;
#ifndef XINPUT_NONE
@ -126,14 +128,6 @@ struct _GdkInputWindow
#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == _gdk_core_pointer)
extern GList *_gdk_input_devices;
extern GList *_gdk_input_windows;
/* information about network port and host for gxid daemon */
extern gchar *_gdk_input_gxid_host;
extern gint _gdk_input_gxid_port;
extern gint _gdk_input_ignore_core;
/* Function declarations */
GdkInputWindow *gdk_input_window_find (GdkWindow *window);
@ -163,7 +157,8 @@ gint _gdk_input_grab_pointer (GdkWindow *window,
GdkEventMask event_mask,
GdkWindow *confine_to,
guint32 time);
void _gdk_input_ungrab_pointer (guint32 time);
void _gdk_input_ungrab_pointer (GdkDisplay *display,
guint32 time);
gboolean _gdk_device_get_history (GdkDevice *device,
GdkWindow *window,
guint32 start,
@ -175,9 +170,11 @@ gboolean _gdk_device_get_history (GdkDevice *device,
#define GDK_MAX_DEVICE_CLASSES 13
gint gdk_input_common_init (gint include_core);
GdkDevicePrivate * gdk_input_find_device (guint32 id);
void gdk_input_get_root_relative_geometry (Display *dpy,
gint gdk_input_common_init (GdkDisplay *display,
gint include_core);
GdkDevicePrivate * gdk_input_find_device (GdkDisplay *display,
guint32 id);
void gdk_input_get_root_relative_geometry (Display *display,
Window w,
int *x_ret,
int *y_ret,

View File

@ -32,56 +32,131 @@
#include <errno.h>
#include "gdk.h"
#include "gdkx.h"
#include "gdkprivate-x11.h"
#include "gdkinternals.h"
#include "gdkdisplay-x11.h"
#include "gdkkeysyms.h"
#include "config.h"
guint _gdk_keymap_serial = 0;
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
static gint min_keycode = 0;
static gint max_keycode = 0;
typedef struct _GdkKeymapX11 GdkKeymapX11;
#define GDK_TYPE_KEYMAP_X11 (gdk_keymap_x11_get_type ())
#define GDK_KEYMAP_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_KEYMAP_X11, GdkKeymapX11))
#define GDK_IS_KEYMAP_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_KEYMAP_X11))
struct _GdkKeymapX11
{
GdkKeymap parent_instance;
gint min_keycode;
gint max_keycode;
KeySym* keymap;
gint keysyms_per_keycode;
XModifierKeymap* mod_keymap;
GdkModifierType group_switch_mask;
PangoDirection current_direction;
gboolean have_direction;
guint current_serial;
#ifdef HAVE_XKB
XkbDescPtr xkb_desc;
#endif
};
#define KEYMAP_USE_XKB(keymap) GDK_DISPLAY_X11 ((keymap)->display)->use_xkb
#define KEYMAP_XDISPLAY(keymap) GDK_DISPLAY_XDISPLAY ((keymap)->display)
static GType gdk_keymap_x11_get_type (void);
static void gdk_keymap_x11_init (GdkKeymapX11 *keymap);
static GType
gdk_keymap_x11_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GdkKeymapClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkKeymapX11),
0, /* n_preallocs */
(GInstanceInitFunc) gdk_keymap_x11_init,
};
object_type = g_type_register_static (GDK_TYPE_KEYMAP,
"GdkKeymapX11",
&object_info, 0);
}
return object_type;
}
static void
gdk_keymap_x11_init (GdkKeymapX11 *keymap)
{
keymap->min_keycode = 0;
keymap->max_keycode = 0;
keymap->keymap = NULL;
keymap->keysyms_per_keycode = 0;
keymap->mod_keymap = NULL;
keymap->group_switch_mask = 0;
keymap->have_direction = FALSE;
keymap->xkb_desc = NULL;
keymap->current_serial = 0;
}
static inline void
update_keyrange (void)
update_keyrange (GdkKeymapX11 *keymap_x11)
{
if (max_keycode == 0)
XDisplayKeycodes (gdk_display, &min_keycode, &max_keycode);
if (keymap_x11->max_keycode == 0)
XDisplayKeycodes (KEYMAP_XDISPLAY (GDK_KEYMAP (keymap_x11)),
&keymap_x11->min_keycode, &keymap_x11->max_keycode);
}
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
gboolean _gdk_use_xkb = FALSE;
gint _gdk_xkb_event_type;
static XkbDescPtr xkb_desc = NULL;
static XkbDescPtr
get_xkb (void)
get_xkb (GdkKeymapX11 *keymap_x11)
{
static guint current_serial = 0;
update_keyrange ();
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display);
Display *xdisplay = display_x11->xdisplay;
if (xkb_desc == NULL)
update_keyrange (keymap_x11);
if (keymap_x11->xkb_desc == NULL)
{
xkb_desc = XkbGetMap (gdk_display, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd);
if (xkb_desc == NULL)
g_error ("Failed to get keymap");
keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd);
if (keymap_x11->xkb_desc == NULL)
g_error ("Failed to get keymap");
XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc);
XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
}
else if (current_serial != _gdk_keymap_serial)
else if (keymap_x11->current_serial != display_x11->keymap_serial)
{
XkbGetUpdatedMap (gdk_display, XkbKeySymsMask | XkbKeyTypesMask, xkb_desc);
XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc);
XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask,
keymap_x11->xkb_desc);
XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
}
current_serial = _gdk_keymap_serial;
keymap_x11->current_serial = display_x11->keymap_serial;
return xkb_desc;
return keymap_x11->xkb_desc;
}
#endif /* HAVE_XKB */
@ -89,66 +164,71 @@ get_xkb (void)
* XkbSetDetectableAutorepeat. If FALSE, we'll fall back
* to checking the next event with XPending().
*/
gboolean _gdk_have_xkb_autorepeat = FALSE;
static KeySym* keymap = NULL;
static gint keysyms_per_keycode = 0;
static XModifierKeymap* mod_keymap = NULL;
static GdkModifierType group_switch_mask = 0;
static PangoDirection current_direction;
static gboolean have_direction = FALSE;
static GdkKeymap *default_keymap = NULL;
/**
* gdk_keymap_get_default:
*
* Gets the #GdkKeymap for the default display.
*
* Return value: the default keymap
/**
* gdk_keymap_get_for_display :
* @display : the #GdkDisplay.
*
* Returns the GdkKeymap attached to @display.
*
* Returns : the GdkKeymap attached to @display.
**/
GdkKeymap*
gdk_keymap_get_for_display (GdkDisplay *display)
{
GdkDisplayX11 *display_x11;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
display_x11 = GDK_DISPLAY_X11 (display);
if (!display_x11->keymap)
display_x11->keymap = g_object_new (gdk_keymap_x11_get_type (), NULL);
display_x11->keymap->display = display;
return display_x11->keymap;
}
GdkKeymap*
gdk_keymap_get_default (void)
{
if (default_keymap == NULL)
default_keymap = g_object_new (gdk_keymap_get_type (), NULL);
return default_keymap;
return gdk_keymap_get_for_display (gdk_get_default_display ());
}
/* Find the index of the group/level pair within the keysyms for a key.
*/
#define KEYSYM_INDEX(group, level) \
(2 * ((group) % (keysyms_per_keycode / 2)) + (level))
#define KEYSYM_INDEX(keymap_impl, group, level) \
(2 * ((group) % (keymap_impl->keysyms_per_keycode / 2)) + (level))
static void
update_keymaps (void)
update_keymaps (GdkKeymapX11 *keymap_x11)
{
static guint current_serial = 0;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_KEYMAP (keymap_x11)->display);
Display *xdisplay = display_x11->xdisplay;
#ifdef HAVE_XKB
g_assert (!_gdk_use_xkb);
g_assert (!KEYMAP_USE_XKB (GDK_KEYMAP (keymap_x11)));
#endif
if (keymap == NULL ||
current_serial != _gdk_keymap_serial)
if (keymap_x11->keymap == NULL ||
keymap_x11->current_serial != display_x11->keymap_serial)
{
gint i;
gint map_size;
gint keycode;
current_serial = _gdk_keymap_serial;
update_keyrange ();
keymap_x11->current_serial = display_x11->keymap_serial;
if (keymap)
XFree (keymap);
update_keyrange (keymap_x11);
if (keymap_x11->keymap)
XFree (keymap_x11->keymap);
if (mod_keymap)
XFreeModifiermap (mod_keymap);
if (keymap_x11->mod_keymap)
XFreeModifiermap (keymap_x11->mod_keymap);
keymap = XGetKeyboardMapping (gdk_display, min_keycode,
max_keycode - min_keycode,
&keysyms_per_keycode);
keymap_x11->keymap = XGetKeyboardMapping (xdisplay, keymap_x11->min_keycode,
keymap_x11->max_keycode - keymap_x11->min_keycode,
&keymap_x11->keysyms_per_keycode);
/* GDK_ISO_Left_Tab, as usually configured through XKB, really messes
@ -156,31 +236,31 @@ update_keymaps (void)
* However, <shift>Tab is not usually GDK_ISO_Left_Tab without XKB,
* we we fudge the map here.
*/
keycode = min_keycode;
while (keycode < max_keycode)
keycode = keymap_x11->min_keycode;
while (keycode < keymap_x11->max_keycode)
{
KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
KeySym *syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
/* Check both groups */
for (i = 0 ; i < 2 ; i++)
{
if (syms[KEYSYM_INDEX (i, 0)] == GDK_Tab)
syms[KEYSYM_INDEX (i, 1)] = GDK_ISO_Left_Tab;
if (syms[KEYSYM_INDEX (keymap_x11, i, 0)] == GDK_Tab)
syms[KEYSYM_INDEX (keymap_x11, i, 1)] = GDK_ISO_Left_Tab;
}
/*
* If there is one keysym and the key symbol has upper and lower
* case variants fudge the keymap
*/
if (syms[KEYSYM_INDEX (0, 1)] == 0)
if (syms[KEYSYM_INDEX (keymap_x11, 0, 1)] == 0)
{
guint lower;
guint upper;
gdk_keyval_convert_case (syms[KEYSYM_INDEX (0, 0)], &lower, &upper);
gdk_keyval_convert_case (syms[KEYSYM_INDEX (keymap_x11, 0, 0)], &lower, &upper);
if (lower != upper)
{
syms[KEYSYM_INDEX (0, 0)] = lower;
syms[KEYSYM_INDEX (0, 1)] = upper;
syms[KEYSYM_INDEX (keymap_x11, 0, 0)] = lower;
syms[KEYSYM_INDEX (keymap_x11, 0, 1)] = upper;
}
}
@ -188,30 +268,31 @@ update_keymaps (void)
++keycode;
}
mod_keymap = XGetModifierMapping (gdk_display);
keymap_x11->mod_keymap = XGetModifierMapping (xdisplay);
group_switch_mask = 0;
keymap_x11->group_switch_mask = 0;
/* there are 8 modifiers, and the first 3 are shift, shift lock,
* and control
*/
map_size = 8 * mod_keymap->max_keypermod;
i = 3 * mod_keymap->max_keypermod;
map_size = 8 * keymap_x11->mod_keymap->max_keypermod;
i = 3 * keymap_x11->mod_keymap->max_keypermod;
while (i < map_size)
{
/* get the key code at this point in the map,
* see if its keysym is GDK_Mode_switch, if so
* we have the mode key
*/
gint keycode = mod_keymap->modifiermap[i];
gint keycode = keymap_x11->mod_keymap->modifiermap[i];
if (keycode >= min_keycode &&
keycode <= max_keycode)
if (keycode >= keymap_x11->min_keycode &&
keycode <= keymap_x11->max_keycode)
{
gint j = 0;
KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
while (j < keysyms_per_keycode)
KeySym *syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
while (j < keymap_x11->keysyms_per_keycode)
{
if (syms[j] == GDK_Mode_switch)
{
@ -222,7 +303,7 @@ update_keymaps (void)
* index
*/
group_switch_mask |= (1 << ( i / mod_keymap->max_keypermod));
keymap_x11->group_switch_mask |= (1 << ( i / keymap_x11->mod_keymap->max_keypermod));
break;
}
@ -236,29 +317,32 @@ update_keymaps (void)
}
static const KeySym*
get_keymap (void)
get_keymap (GdkKeymapX11 *keymap_x11)
{
update_keymaps ();
update_keymaps (keymap_x11);
return keymap;
return keymap_x11->keymap;
}
#if HAVE_XKB
static PangoDirection
get_direction (void)
get_direction (GdkKeymapX11 *keymap_x11)
{
XkbDescRec *xkb = get_xkb ();
XkbDescRec *xkb = get_xkb (keymap_x11);
const char *name;
XkbStateRec state_rec;
PangoDirection result;
XkbGetState (gdk_display, XkbUseCoreKbd, &state_rec);
GdkDisplay *display = GDK_KEYMAP (keymap_x11)->display;
XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd, &state_rec);
if (xkb->names->groups[state_rec.locked_group] == None)
result = PANGO_DIRECTION_LTR;
else
{
name = gdk_x11_get_xatom_name (xkb->names->groups[state_rec.locked_group]);
name = gdk_x11_get_xatom_name_for_display (display, xkb->names->groups[state_rec.locked_group]);
if (g_strcasecmp (name, "arabic") == 0 ||
g_strcasecmp (name, "hebrew") == 0 ||
g_strcasecmp (name, "israelian") == 0)
@ -271,17 +355,21 @@ get_direction (void)
}
void
_gdk_keymap_state_changed (void)
_gdk_keymap_state_changed (GdkDisplay *display)
{
if (default_keymap)
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->keymap)
{
PangoDirection new_direction = get_direction ();
GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (display_x11->keymap);
if (!have_direction || new_direction != current_direction)
PangoDirection new_direction = get_direction (keymap_x11);
if (!keymap_x11->have_direction || new_direction != keymap_x11->current_direction)
{
have_direction = TRUE;
current_direction = new_direction;
g_signal_emit_by_name (G_OBJECT (default_keymap), "direction_changed");
keymap_x11->have_direction = TRUE;
keymap_x11->current_direction = new_direction;
g_signal_emit_by_name (G_OBJECT (keymap_x11), "direction_changed");
}
}
}
@ -290,16 +378,26 @@ _gdk_keymap_state_changed (void)
PangoDirection
gdk_keymap_get_direction (GdkKeymap *keymap)
{
#if HAVE_XKB
if (_gdk_use_xkb)
if (!keymap)
{
if (!have_direction)
keymap = gdk_keymap_get_for_display (gdk_get_default_display ());
GDK_NOTE (MULTIHEAD,
g_message ("_multihead : reverting to default display keymap "
"in gdk_keymap_get_direction"));
}
#if HAVE_XKB
if (KEYMAP_USE_XKB (keymap))
{
GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (keymap);
if (!keymap_x11->have_direction)
{
current_direction = get_direction ();
have_direction = TRUE;
keymap_x11->current_direction = get_direction (keymap_x11);
keymap_x11->have_direction = TRUE;
}
return current_direction;
return keymap_x11->current_direction;
}
else
#endif /* HAVE_XKB */
@ -334,25 +432,36 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap,
gint *n_keys)
{
GArray *retval;
GdkKeymapX11 *keymap_x11;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
g_return_val_if_fail (keys != NULL, FALSE);
g_return_val_if_fail (n_keys != NULL, FALSE);
g_return_val_if_fail (keyval != 0, FALSE);
if (!keymap)
{
keymap = gdk_keymap_get_for_display (gdk_get_default_display ());
GDK_NOTE (MULTIHEAD,
g_message ("_multihead : reverting to default display keymap "
"in gdk_keymap_get_entries_for_keyval\n"));
}
keymap_x11 = GDK_KEYMAP_X11 (keymap);
retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
#ifdef HAVE_XKB
if (_gdk_use_xkb)
if (KEYMAP_USE_XKB (keymap))
{
/* See sec 15.3.4 in XKB docs */
XkbDescRec *xkb = get_xkb ();
XkbDescRec *xkb = get_xkb (keymap_x11);
gint keycode;
keycode = min_keycode;
keycode = keymap_x11->min_keycode;
while (keycode <= max_keycode)
while (keycode <= keymap_x11->max_keycode)
{
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); /* "key width" */
gint group = 0;
@ -383,7 +492,8 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap,
g_array_append_val (retval, key);
g_assert (XkbKeySymEntry (xkb, keycode, level, group) == keyval);
g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
keyval);
}
++level;
@ -403,16 +513,16 @@ gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap,
else
#endif
{
const KeySym *map = get_keymap ();
const KeySym *map = get_keymap (keymap_x11);
gint keycode;
keycode = min_keycode;
while (keycode < max_keycode)
keycode = keymap_x11->min_keycode;
while (keycode < keymap_x11->max_keycode)
{
const KeySym *syms = map + (keycode - min_keycode) * keysyms_per_keycode;
const KeySym *syms = map + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
gint i = 0;
while (i < keysyms_per_keycode)
while (i < keymap_x11->keysyms_per_keycode)
{
if (syms[i] == keyval)
{
@ -475,16 +585,28 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
guint **keyvals,
gint *n_entries)
{
GdkKeymapX11 *keymap_x11;
GArray *key_array;
GArray *keyval_array;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
g_return_val_if_fail (n_entries != NULL, FALSE);
update_keyrange ();
if (!keymap)
{
keymap = gdk_keymap_get_for_display (gdk_get_default_display ());
GDK_NOTE (MULTIHEAD,
g_message ("_multihead : reverting to default display keymap "
"in gdk_keymap_get_entries_for_keycode\n"));
}
if (hardware_keycode < min_keycode ||
hardware_keycode > max_keycode)
keymap_x11 = GDK_KEYMAP_X11 (keymap);
update_keyrange (keymap_x11);
if (hardware_keycode < keymap_x11->min_keycode ||
hardware_keycode > keymap_x11->max_keycode)
{
if (keys)
*keys = NULL;
@ -506,11 +628,11 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
keyval_array = NULL;
#ifdef HAVE_XKB
if (_gdk_use_xkb)
if (KEYMAP_USE_XKB (keymap))
{
/* See sec 15.3.4 in XKB docs */
XkbDescRec *xkb = get_xkb ();
XkbDescRec *xkb = get_xkb (keymap_x11);
gint max_shift_levels;
gint group = 0;
gint level = 0;
@ -560,13 +682,13 @@ gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
else
#endif
{
const KeySym *map = get_keymap ();
const KeySym *map = get_keymap (keymap_x11);
const KeySym *syms;
gint i = 0;
syms = map + (hardware_keycode - min_keycode) * keysyms_per_keycode;
syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
while (i < keysyms_per_keycode)
while (i < keymap_x11->keysyms_per_keycode)
{
if (key_array)
{
@ -639,23 +761,35 @@ guint
gdk_keymap_lookup_key (GdkKeymap *keymap,
const GdkKeymapKey *key)
{
GdkKeymapX11 *keymap_x11;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0);
g_return_val_if_fail (key != NULL, 0);
g_return_val_if_fail (key->group < 4, 0);
#ifdef HAVE_XKB
if (_gdk_use_xkb)
if (!keymap)
{
XkbDescRec *xkb = get_xkb ();
keymap = gdk_keymap_get_for_display (gdk_get_default_display ());
GDK_NOTE (MULTIHEAD,
g_message ("_multihead : reverting to default display keymap "
"in gdk_keymap_lookup_key\n"));
}
keymap_x11 = GDK_KEYMAP_X11 (keymap);
#ifdef HAVE_XKB
if (KEYMAP_USE_XKB (keymap))
{
XkbDescRec *xkb = get_xkb (keymap_x11);
return XkbKeySymEntry (xkb, key->keycode, key->level, key->group);
}
else
#endif
{
const KeySym *map = get_keymap ();
const KeySym *syms = map + (key->keycode - min_keycode) * keysyms_per_keycode;
return syms [KEYSYM_INDEX (key->group, key->level)];
const KeySym *map = get_keymap (keymap_x11);
const KeySym *syms = map + (key->keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
return syms [KEYSYM_INDEX (keymap_x11, key->group, key->level)];
}
}
@ -803,12 +937,15 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
gint *level,
GdkModifierType *consumed_modifiers)
{
GdkKeymapX11 *keymap_x11;
KeySym tmp_keyval = NoSymbol;
guint tmp_modifiers;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
g_return_val_if_fail (group < 4, FALSE);
keymap_x11 = GDK_KEYMAP_X11 (keymap);
if (keyval)
*keyval = NoSymbol;
if (effective_group)
@ -818,16 +955,16 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
if (consumed_modifiers)
*consumed_modifiers = 0;
update_keyrange ();
update_keyrange (keymap_x11);
if (hardware_keycode < min_keycode ||
hardware_keycode > max_keycode)
if (hardware_keycode < keymap_x11->min_keycode ||
hardware_keycode > keymap_x11->max_keycode)
return FALSE;
#ifdef HAVE_XKB
if (_gdk_use_xkb)
if (KEYMAP_USE_XKB (keymap))
{
XkbDescRec *xkb = get_xkb ();
XkbDescRec *xkb = get_xkb (keymap_x11);
/* replace bits 13 and 14 with the provided group */
state &= ~(1 << 13 | 1 << 14);
@ -852,7 +989,7 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
else
#endif
{
const KeySym *map = get_keymap ();
const KeySym *map = get_keymap (keymap_x11);
const KeySym *syms;
gint shift_level;
gboolean ignore_shift = FALSE;
@ -867,24 +1004,24 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
else
shift_level = 0;
syms = map + (hardware_keycode - min_keycode) * keysyms_per_keycode;
syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
#define SYM(g,l) syms[KEYSYM_INDEX (g,l)]
#define SYM(k,g,l) syms[KEYSYM_INDEX (k,g,l)]
/* Drop group and shift if there are no keysymbols on
* the specified key.
*/
if (!SYM (group, shift_level) && SYM (group, 0))
if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, group, 0))
{
shift_level = 0;
ignore_shift = TRUE;
}
if (!SYM (group, shift_level) && SYM (0, shift_level))
if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, 0, shift_level))
{
group = 0;
ignore_group = TRUE;
}
if (!SYM (group, shift_level) && SYM (0, 0))
if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, 0, 0))
{
shift_level = 0;
group = 0;
@ -895,17 +1032,17 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
/* See whether the group and shift level actually mattered
* to know what to put in consumed_modifiers
*/
if (!SYM (group, 1) ||
SYM (group, 0) == SYM (group, 1))
if (!SYM (keymap_x11, group, 1) ||
SYM (keymap_x11, group, 0) == SYM (keymap_x11, group, 1))
ignore_shift = TRUE;
if (!SYM (1, shift_level) ||
SYM (0, shift_level) == SYM (1, shift_level))
if (!SYM (keymap_x11, 1, shift_level) ||
SYM (keymap_x11, 0, shift_level) == SYM (keymap_x11, 1, shift_level))
ignore_group = TRUE;
tmp_keyval = SYM (group, shift_level);
tmp_keyval = SYM (keymap_x11, group, shift_level);
tmp_modifiers = ignore_group ? 0 : group_switch_mask;
tmp_modifiers = ignore_group ? 0 : keymap_x11->group_switch_mask;
tmp_modifiers |= ignore_shift ? 0 : (GDK_SHIFT_MASK | GDK_LOCK_MASK);
if (effective_group)
@ -984,17 +1121,21 @@ gdk_keyval_convert_case (guint symbol,
#endif /* HAVE_XCONVERTCASE */
gint
_gdk_x11_get_group_for_state (GdkModifierType state)
_gdk_x11_get_group_for_state (GdkDisplay *display,
GdkModifierType state)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
#ifdef HAVE_XKB
if (_gdk_use_xkb)
if (display_x11->use_xkb)
{
return XkbGroupForCoreState (state);
}
else
#endif
{
update_keymaps ();
return (state & group_switch_mask) ? 1 : 0;
GdkKeymapX11 *keymap_impl = GDK_KEYMAP_X11 (gdk_keymap_get_for_display (display));
update_keymaps (keymap_impl);
return (state & keymap_impl->group_switch_mask) ? 1 : 0;
}
}

View File

@ -43,7 +43,8 @@
#include "gdk.h"
#include "gdkprivate-x11.h"
#include "gdkx.h"
#include "gdkdisplay-x11.h"
#include "gdkinternals.h"
#include "gdkregion-generic.h"
#include "gdkinputprivate.h"
@ -86,111 +87,23 @@ static int gdk_x_io_error (Display *display);
static int gdk_initialized = 0; /* 1 if the library is initialized,
* 0 otherwise.
*/
static gint autorepeat;
static gboolean gdk_synchronize = FALSE;
static GSList *gdk_error_traps = NULL; /* List of error traps */
static GSList *gdk_error_trap_free_list = NULL; /* Free list */
/* Information about current pointer and keyboard grabs held by this
* client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window
* window is NULL, then the other associated fields are ignored
*/
static GdkWindowObject *gdk_pointer_xgrab_window = NULL;
static gulong gdk_pointer_xgrab_serial;
static gboolean gdk_pointer_xgrab_owner_events;
static GdkWindowObject *gdk_keyboard_xgrab_window = NULL;
static gulong gdk_keyboard_xgrab_serial;
static gboolean gdk_keyboard_xgrab_owner_events;
GdkArgDesc _gdk_windowing_args[] = {
{ "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL },
{ "sync", GDK_ARG_BOOL, &gdk_synchronize, (GdkArgFunc)NULL },
{ "gxid-host", GDK_ARG_STRING, &_gdk_input_gxid_host, (GdkArgFunc)NULL },
{ "gxid-port", GDK_ARG_INT, &_gdk_input_gxid_port, (GdkArgFunc)NULL },
{ "sync", GDK_ARG_BOOL, &_gdk_synchronize, (GdkArgFunc)NULL },
{ NULL }
};
gboolean
_gdk_windowing_init_check (int argc, char **argv)
void
_gdk_windowing_init (void)
{
XKeyboardState keyboard_state;
XClassHint *class_hint;
gulong pid;
_gdk_x11_initialize_locale ();
XSetErrorHandler (gdk_x_error);
XSetIOErrorHandler (gdk_x_io_error);
gdk_display = XOpenDisplay (_gdk_display_name);
if (!gdk_display)
return FALSE;
if (gdk_synchronize)
XSynchronize (gdk_display, True);
_gdk_screen = DefaultScreen (gdk_display);
_gdk_root_window = RootWindow (gdk_display, _gdk_screen);
_gdk_leader_window = XCreateSimpleWindow(gdk_display, _gdk_root_window,
10, 10, 10, 10, 0, 0 , 0);
class_hint = XAllocClassHint();
class_hint->res_name = g_get_prgname ();
class_hint->res_class = (char *)gdk_get_program_class ();
XmbSetWMProperties (gdk_display, _gdk_leader_window,
NULL, NULL, argv, argc,
NULL, NULL, class_hint);
XFree (class_hint);
pid = getpid();
XChangeProperty (gdk_display, _gdk_leader_window,
gdk_x11_get_xatom_by_name ("_NET_WM_PID"),
XA_CARDINAL, 32,
PropModeReplace,
(guchar *)&pid, 1);
_gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
XGetKeyboardControl (gdk_display, &keyboard_state);
autorepeat = keyboard_state.global_auto_repeat;
#ifdef HAVE_XKB
{
gint xkb_major = XkbMajorVersion;
gint xkb_minor = XkbMinorVersion;
if (XkbLibraryVersion (&xkb_major, &xkb_minor))
{
xkb_major = XkbMajorVersion;
xkb_minor = XkbMinorVersion;
if (XkbQueryExtension (gdk_display, NULL, &_gdk_xkb_event_type, NULL,
&xkb_major, &xkb_minor))
{
Bool detectable_autorepeat_supported;
_gdk_use_xkb = TRUE;
XkbSelectEvents (gdk_display,
XkbUseCoreKbd,
XkbMapNotifyMask | XkbStateNotifyMask,
XkbMapNotifyMask | XkbStateNotifyMask);
XkbSetDetectableAutoRepeat (gdk_display,
True,
&detectable_autorepeat_supported);
GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
detectable_autorepeat_supported ? "supported" : "not supported"));
_gdk_have_xkb_autorepeat = detectable_autorepeat_supported;
}
}
}
#endif
return TRUE;
}
void
@ -201,7 +114,7 @@ gdk_set_use_xshm (gboolean use_xshm)
gboolean
gdk_get_use_xshm (void)
{
return _gdk_use_xshm;
return GDK_DISPLAY_X11 (gdk_get_default_display ())->use_xshm;
}
static GdkGrabStatus
@ -323,9 +236,10 @@ gdk_pointer_grab (GdkWindow * window,
if (return_val == GrabSuccess)
{
gdk_pointer_xgrab_window = (GdkWindowObject *)window;
gdk_pointer_xgrab_serial = serial;
gdk_pointer_xgrab_owner_events = owner_events;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
display_x11->pointer_xgrab_window = (GdkWindowObject *)window;
display_x11->pointer_xgrab_serial = serial;
display_x11->pointer_xgrab_owner_events = owner_events;
}
return gdk_x11_convert_grab_status (return_val);
@ -349,10 +263,7 @@ gdk_pointer_grab (GdkWindow * window,
void
gdk_pointer_ungrab (guint32 time)
{
_gdk_input_ungrab_pointer (time);
XUngrabPointer (gdk_display, time);
gdk_pointer_xgrab_window = NULL;
gdk_display_pointer_ungrab (gdk_get_default_display (), time);
}
/*
@ -373,11 +284,12 @@ gdk_pointer_ungrab (guint32 time)
gboolean
gdk_pointer_is_grabbed (void)
{
return gdk_pointer_xgrab_window != NULL;
return gdk_display_pointer_is_grabbed (gdk_get_default_display ());
}
/**
* gdk_pointer_grab_info_libgtk_only:
* @display: the #GdkDisplay for which to get the grab information
* @grab_window: location to store current grab window
* @owner_events: location to store boolean indicating whether
* the @owner_events flag to gdk_pointer_grab() was %TRUE.
@ -389,15 +301,22 @@ gdk_pointer_is_grabbed (void)
* pointer grabbed.
**/
gboolean
gdk_pointer_grab_info_libgtk_only (GdkWindow **grab_window,
gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
GdkWindow **grab_window,
gboolean *owner_events)
{
if (gdk_pointer_xgrab_window)
GdkDisplayX11 *display_x11;
g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->pointer_xgrab_window)
{
if (grab_window)
*grab_window = (GdkWindow *)gdk_pointer_xgrab_window;
*grab_window = (GdkWindow *)display_x11->pointer_xgrab_window;
if (owner_events)
*owner_events = gdk_pointer_xgrab_owner_events;
*owner_events = display_x11->pointer_xgrab_owner_events;
return TRUE;
}
@ -456,9 +375,10 @@ gdk_keyboard_grab (GdkWindow * window,
if (return_val == GrabSuccess)
{
gdk_keyboard_xgrab_window = (GdkWindowObject *)window;
gdk_keyboard_xgrab_serial = serial;
gdk_keyboard_xgrab_owner_events = owner_events;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
display_x11->keyboard_xgrab_window = (GdkWindowObject *)window;
display_x11->keyboard_xgrab_serial = serial;
display_x11->keyboard_xgrab_owner_events = owner_events;
}
return gdk_x11_convert_grab_status (return_val);
@ -482,12 +402,12 @@ gdk_keyboard_grab (GdkWindow * window,
void
gdk_keyboard_ungrab (guint32 time)
{
XUngrabKeyboard (gdk_display, time);
gdk_keyboard_xgrab_window = NULL;
gdk_display_keyboard_ungrab (gdk_get_default_display (), time);
}
/**
* gdk_keyboard_grab_info_libgtk_only:
* @display: the display for which to get the grab information
* @grab_window: location to store current grab window
* @owner_events: location to store boolean indicating whether
* the @owner_events flag to gdk_keyboard_grab() was %TRUE.
@ -499,15 +419,22 @@ gdk_keyboard_ungrab (guint32 time)
* keyboard grabbed.
**/
gboolean
gdk_keyboard_grab_info_libgtk_only (GdkWindow **grab_window,
gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
GdkWindow **grab_window,
gboolean *owner_events)
{
if (gdk_keyboard_xgrab_window)
GdkDisplayX11 *display_x11;
g_return_val_if_fail (GDK_IS_DISPLAY (display), False);
display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->keyboard_xgrab_window)
{
if (grab_window)
*grab_window = (GdkWindow *)gdk_keyboard_xgrab_window;
*grab_window = (GdkWindow *)display_x11->keyboard_xgrab_window;
if (owner_events)
*owner_events = gdk_keyboard_xgrab_owner_events;
*owner_events = display_x11->keyboard_xgrab_owner_events;
return TRUE;
}
@ -529,30 +456,33 @@ void
_gdk_xgrab_check_unmap (GdkWindow *window,
gulong serial)
{
if (gdk_pointer_xgrab_window && serial >= gdk_pointer_xgrab_serial)
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
if (display_x11->pointer_xgrab_window &&
serial >= display_x11->pointer_xgrab_serial)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
GdkWindowObject *tmp = gdk_pointer_xgrab_window;
GdkWindowObject *tmp = display_x11->pointer_xgrab_window;
while (tmp && tmp != private)
tmp = tmp->parent;
if (tmp)
gdk_pointer_xgrab_window = NULL;
display_x11->pointer_xgrab_window = NULL;
}
if (gdk_keyboard_xgrab_window && serial >= gdk_keyboard_xgrab_serial)
if (display_x11->keyboard_xgrab_window &&
serial >= display_x11->keyboard_xgrab_serial)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
GdkWindowObject *tmp = gdk_keyboard_xgrab_window;
GdkWindowObject *tmp = display_x11->keyboard_xgrab_window;
while (tmp && tmp != private)
tmp = tmp->parent;
if (tmp)
gdk_keyboard_xgrab_window = NULL;
display_x11->keyboard_xgrab_window = NULL;
}
}
@ -566,11 +496,13 @@ _gdk_xgrab_check_unmap (GdkWindow *window,
void
_gdk_xgrab_check_destroy (GdkWindow *window)
{
if ((GdkWindowObject *)window == gdk_pointer_xgrab_window)
gdk_pointer_xgrab_window = NULL;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window)
display_x11->pointer_xgrab_window = NULL;
if ((GdkWindowObject *)window == gdk_keyboard_xgrab_window)
gdk_keyboard_xgrab_window = NULL;
if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window)
display_x11->keyboard_xgrab_window = NULL;
}
/*
@ -591,11 +523,7 @@ _gdk_xgrab_check_destroy (GdkWindow *window)
gint
gdk_screen_width (void)
{
gint return_val;
return_val = DisplayWidth (gdk_display, _gdk_screen);
return return_val;
return gdk_screen_get_width (gdk_get_default_screen());
}
/*
@ -616,11 +544,7 @@ gdk_screen_width (void)
gint
gdk_screen_height (void)
{
gint return_val;
return_val = DisplayHeight (gdk_display, _gdk_screen);
return return_val;
return gdk_screen_get_height (gdk_get_default_screen());
}
/*
@ -641,11 +565,7 @@ gdk_screen_height (void)
gint
gdk_screen_width_mm (void)
{
gint return_val;
return_val = DisplayWidthMM (gdk_display, _gdk_screen);
return return_val;
return gdk_screen_get_width_mm (gdk_get_default_screen());
}
/*
@ -666,62 +586,82 @@ gdk_screen_width_mm (void)
gint
gdk_screen_height_mm (void)
{
gint return_val;
return_val = DisplayHeightMM (gdk_display, _gdk_screen);
return return_val;
return gdk_screen_get_height_mm (gdk_get_default_screen ());
}
/*
*--------------------------------------------------------------
* gdk_set_sm_client_id
*
* Set the SM_CLIENT_ID property on the WM_CLIENT_LEADER window
* so that the window manager can save our state using the
* X11R6 ICCCM session management protocol. A NULL value should
* be set following disconnection from the session manager to
* remove the SM_CLIENT_ID property.
*
* Arguments:
/**
* gdk_set_sm_client_id:
* @sm_client_id: the client id assigned by the session manager when the
* connection was opened, or %NULL to remove the property.
*
* "sm_client_id" specifies the client id assigned to us by the
* session manager or NULL to remove the property.
* Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that
* the window manager can save the application's state using the X11R6 ICCCM
* session management protocol.
*
* Results:
*
* Side effects:
*
*--------------------------------------------------------------
*/
* See the X Session Management Library documentation for more information on
* session management and the Inter-Client Communication Conventions Manual
* (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property.
* (Both documents are part of the X Window System distribution.)
**/
void
gdk_set_sm_client_id (const gchar* sm_client_id)
{
gdk_display_set_sm_client_id (gdk_get_default_display (),sm_client_id);
}
/**
* gdk_display_set_sm_client_id:
* @display: a #GdkDisplay
* @sm_client_id: the client id assigned by the session manager when the
* connection was opened, or %NULL to remove the property.
*
* Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window
* so that the window manager can save the application's state using the X11R6 ICCCM
* session management protocol.
*
* See the X Session Management Library documentation for more information on
* session management and the Inter-Client Communication Conventions Manual
* (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property.
* (Both documents are part of the X Window System distribution.)
**/
void
gdk_display_set_sm_client_id (GdkDisplay *display,
const gchar *sm_client_id)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
if (sm_client_id && strcmp (sm_client_id, ""))
{
XChangeProperty (gdk_display, _gdk_leader_window,
gdk_x11_get_xatom_by_name ("SM_CLIENT_ID"),
XA_STRING, 8, PropModeReplace,
sm_client_id, strlen(sm_client_id));
XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
XA_STRING, 8, PropModeReplace, sm_client_id,
strlen (sm_client_id));
}
else
XDeleteProperty (gdk_display, _gdk_leader_window,
gdk_x11_get_xatom_by_name ("SM_CLIENT_ID"));
XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
}
void
gdk_beep (void)
{
XBell(gdk_display, 0);
gdk_display_beep (gdk_get_default_display ());
}
/* Close all open displays
*/
void
_gdk_windowing_exit (void)
{
pango_x_shutdown_display (gdk_display);
XCloseDisplay (gdk_display);
GSList *tmp_list = _gdk_displays;
while (tmp_list)
{
pango_x_shutdown_display (GDK_DISPLAY_XDISPLAY (tmp_list->data));
XCloseDisplay (GDK_DISPLAY_XDISPLAY (tmp_list->data));
tmp_list = tmp_list->next;
}
}
/*
@ -825,14 +765,14 @@ gdk_x_io_error (Display *display)
"most likely the X server was shut down or you killed/destroyed\n"
"the application.\n",
g_get_prgname (),
gdk_display ? DisplayString (gdk_display) : gdk_get_display());
display ? DisplayString (display) : gdk_get_display_arg_name ());
}
else
{
fprintf (stderr, "%s: Fatal IO error %d (%s) on X server %s.\n",
g_get_prgname (),
errno, g_strerror (errno),
gdk_display ? DisplayString (gdk_display) : gdk_get_display());
display ? DisplayString (display) : gdk_get_display_arg_name ());
}
/* Disable the atexit shutdown for GDK */
@ -917,18 +857,37 @@ gdk_error_trap_pop (void)
gchar *
gdk_get_display (void)
{
return (gchar *)XDisplayName (_gdk_display_name);
return g_strdup (gdk_display_get_name (gdk_get_default_display ()));
}
/**
* _gdk_send_xevent:
* @display: #GdkDisplay which @window is on
* @window: window ID to which to send the event
* @propagate: %TRUE if the event should be propagated if the target window
* doesn't handle it.
* @event_mask: event mask to match against, or 0 to send it to @window
* without regard to event masks.
* @event_send: #XEvent to send
*
* Send an event, like XSendEvent(), but trap errors and check
* the result.
*
* Return value: %TRUE if sending the event succeeded.
**/
gint
gdk_send_xevent (Window window, gboolean propagate, glong event_mask,
XEvent *event_send)
_gdk_send_xevent (GdkDisplay *display,
Window window,
gboolean propagate,
glong event_mask,
XEvent *event_send)
{
gboolean result;
gdk_error_trap_push ();
result = XSendEvent (gdk_display, window, propagate, event_mask, event_send);
XSync (gdk_display, False);
result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window,
propagate, event_mask, event_send);
XSync (GDK_DISPLAY_XDISPLAY (display), False);
return result && gdk_error_trap_pop() == Success;
}
@ -956,24 +915,16 @@ _gdk_region_get_xrectangles (GdkRegion *region,
*n_rects = region->numRects;
}
/* FIXME put in GdkDisplay */
static gint grab_count = 0;
void
gdk_x11_grab_server (void)
{
if (grab_count == 0)
XGrabServer (gdk_display);
++grab_count;
gdk_x11_grab_server ()
{
gdk_x11_display_grab (gdk_get_default_display ());
}
void
gdk_x11_ungrab_server (void)
gdk_x11_ungrab_server ()
{
g_return_if_fail (grab_count > 0);
--grab_count;
if (grab_count == 0)
XUngrabServer (gdk_display);
gdk_x11_display_ungrab (gdk_get_default_display ());
}
/**
@ -988,17 +939,17 @@ gdk_x11_ungrab_server (void)
gint
gdk_x11_get_default_screen (void)
{
return _gdk_screen;
return gdk_screen_get_number (gdk_get_default_screen ());
}
Window
gdk_x11_get_default_root_xwindow (void)
{
return _gdk_root_window;
return GDK_SCREEN_XROOTWIN (gdk_get_default_screen ());
}
Display *
gdk_x11_get_default_xdisplay (void)
{
return gdk_display;
return GDK_DISPLAY_XDISPLAY (gdk_get_default_display ());
}

View File

@ -20,17 +20,63 @@
#include <config.h>
#include <stdlib.h>
#include "gdkprivate-x11.h"
#include "gdkx.h"
#include "gdkdisplay-x11.h"
#include "gdkpango.h"
#include <pango/pangox.h>
#ifdef HAVE_XFT
#include <pango/pangoxft.h>
#endif
/**
* gdk_pango_context_get_for_screen:
* @screen: the #GdkScreen for which the context is to be created.
*
* Creates a #PangoContext for @screen.
*
* The context must be freed when you're finished with it.
*
* When using GTK+, normally you should use gtk_widget_get_pango_context()
* instead of this function, to get the appropriate context for
* the widget you intend to render text onto.
*
* Return value: a new #PangoContext for @screen
**/
PangoContext *
gdk_pango_context_get_for_screen (GdkScreen *screen)
{
PangoContext *context;
GdkDisplayX11 *display_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
display_x11 = GDK_DISPLAY_X11 (GDK_SCREEN_DISPLAY (screen));
#ifdef HAVE_XFT
if (display_x11->use_xft == -1)
{
const char *val = g_getenv ("GDK_USE_XFT");
display_x11->use_xft = val && (atoi (val) != 0) &&
_gdk_x11_have_render (GDK_SCREEN_DISPLAY (screen));
}
if (display_x11->use_xft)
context = pango_xft_get_context (GDK_SCREEN_XDISPLAY (screen),
GDK_SCREEN_X11 (screen)->screen_num);
else
#endif /* HAVE_XFT */
context = pango_x_get_context (GDK_SCREEN_XDISPLAY (screen));
g_object_set_data (G_OBJECT (context), "gdk-pango-screen", screen);
return context;
}
/**
* gdk_pango_context_get:
*
* Creates a #PangoContext for the default GDK display.
* Creates a #PangoContext for the default GDK screen.
*
* The context must be freed when you're finished with it.
*
@ -43,18 +89,5 @@
PangoContext *
gdk_pango_context_get (void)
{
#ifdef HAVE_XFT
static gint use_xft = -1;
if (use_xft == -1)
{
const char *val = g_getenv ("GDK_USE_XFT");
use_xft = val && (atoi (val) != 0) && _gdk_x11_have_render ();
}
if (use_xft)
return pango_xft_get_context (GDK_DISPLAY (), DefaultScreen (GDK_DISPLAY ()));
else
#endif /* HAVE_XFT */
return pango_x_get_context (GDK_DISPLAY ());
return gdk_pango_context_get_for_screen (gdk_get_default_screen ());
}

View File

@ -36,6 +36,10 @@
#include "gdkpixmap-x11.h"
#include "gdkprivate-x11.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h"
#include <gdk/gdkinternals.h>
typedef struct
{
@ -127,14 +131,14 @@ gdk_pixmap_impl_x11_finalize (GObject *object)
GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
if (draw_impl->picture)
XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture);
XRenderFreePicture (GDK_PIXMAP_XDISPLAY (wrapper), draw_impl->picture);
}
#endif /* HAVE_XFT */
if (!impl->is_foreign)
XFreePixmap (GDK_PIXMAP_XDISPLAY (wrapper), GDK_PIXMAP_XID (wrapper));
gdk_xid_table_remove (GDK_PIXMAP_XID (wrapper));
_gdk_xid_table_remove (GDK_PIXMAP_DISPLAY (wrapper), GDK_PIXMAP_XID (wrapper));
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -167,7 +171,11 @@ gdk_pixmap_new (GdkWindow *window,
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
if (!window)
window = _gdk_parent_root;
{
GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window "
"for gdk_pixmap_new() to be multihead safe"));
window = gdk_screen_get_root_window (gdk_get_default_screen ());
}
if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window))
return NULL;
@ -181,7 +189,7 @@ gdk_pixmap_new (GdkWindow *window,
pix_impl = GDK_PIXMAP_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl);
draw_impl->wrapper = GDK_DRAWABLE (pixmap);
draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (window);
draw_impl->screen = GDK_WINDOW_SCREEN (window);
draw_impl->xid = XCreatePixmap (GDK_PIXMAP_XDISPLAY (pixmap),
GDK_WINDOW_XID (window),
width, height, depth);
@ -198,8 +206,8 @@ gdk_pixmap_new (GdkWindow *window,
gdk_drawable_set_colormap (pixmap, cmap);
}
gdk_xid_table_insert (&draw_impl->xid, pixmap);
_gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window),
&GDK_PIXMAP_XID (pixmap), pixmap);
return pixmap;
}
@ -217,9 +225,13 @@ gdk_bitmap_create_from_data (GdkWindow *window,
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
g_return_val_if_fail (window == NULL || GDK_IS_DRAWABLE (window), NULL);
if (!window)
window = _gdk_parent_root;
if (!window)
{
GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window "
"for gdk_bitmap_create_from_data() to be multihead safe"));
window = gdk_screen_get_root_window (gdk_get_default_screen ());
}
if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window))
return NULL;
@ -233,13 +245,13 @@ gdk_bitmap_create_from_data (GdkWindow *window,
pix_impl->height = height;
GDK_PIXMAP_OBJECT (pixmap)->depth = 1;
draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (window);
draw_impl->screen = GDK_WINDOW_SCREEN (window);
draw_impl->xid = XCreateBitmapFromData (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
(char *)data, width, height);
gdk_xid_table_insert (&draw_impl->xid, pixmap);
_gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window),
&GDK_PIXMAP_XID (pixmap), pixmap);
return pixmap;
}
@ -264,7 +276,11 @@ gdk_pixmap_create_from_data (GdkWindow *window,
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
if (!window)
window = _gdk_parent_root;
{
GDK_NOTE (MULTIHEAD, g_message ("need to specify the screen parent window"
"for gdk_pixmap_create_from_data() to be multihead safe"));
window = gdk_screen_get_root_window (gdk_get_default_screen ());
}
if (GDK_IS_WINDOW (window) && GDK_WINDOW_DESTROYED (window))
return NULL;
@ -282,19 +298,20 @@ gdk_pixmap_create_from_data (GdkWindow *window,
pix_impl->height = height;
GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
draw_impl->xdisplay = GDK_DRAWABLE_XDISPLAY (window);
draw_impl->screen = GDK_DRAWABLE_SCREEN (window);
draw_impl->xid = XCreatePixmapFromBitmapData (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
(char *)data, width, height,
fg->pixel, bg->pixel, depth);
gdk_xid_table_insert (&draw_impl->xid, pixmap);
_gdk_xid_table_insert (GDK_WINDOW_DISPLAY (window),
&GDK_PIXMAP_XID (pixmap), pixmap);
return pixmap;
}
/**
* gdk_pixmap_foreign_new:
* gdk_pixmap_foreign_new_for_display:
* @screen : The #GdkScreen the @anid is located.
* @anid: a native pixmap handle.
*
* Wraps a native window in a #GdkPixmap.
@ -306,8 +323,9 @@ gdk_pixmap_create_from_data (GdkWindow *window,
* Return value: the newly-created #GdkPixmap wrapper for the
* native pixmap or %NULL if the pixmap has been destroyed.
**/
GdkPixmap*
gdk_pixmap_foreign_new (GdkNativeWindow anid)
GdkPixmap *
gdk_pixmap_foreign_new_for_display (GdkDisplay *display,
GdkNativeWindow anid)
{
GdkPixmap *pixmap;
GdkDrawableImplX11 *draw_impl;
@ -317,27 +335,28 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid)
int x_ret, y_ret;
unsigned int w_ret, h_ret, bw_ret, depth_ret;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
/* check to make sure we were passed something at
least a little sane */
g_return_val_if_fail((anid != 0), NULL);
* least a little sane */
g_return_val_if_fail ((anid != 0), NULL);
/* set the pixmap to the passed in value */
xpixmap = anid;
/* get information about the Pixmap to fill in the structure for
the gdk window */
if (!XGetGeometry(GDK_DISPLAY(),
xpixmap, &root_return,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
return NULL;
if (!XGetGeometry (GDK_SCREEN_XDISPLAY (display),
xpixmap, &root_return,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
return NULL;
pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
draw_impl = GDK_DRAWABLE_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl);
pix_impl = GDK_PIXMAP_IMPL_X11 (GDK_PIXMAP_OBJECT (pixmap)->impl);
draw_impl->wrapper = GDK_DRAWABLE (pixmap);
draw_impl->xdisplay = GDK_DISPLAY ();
draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root_return);
draw_impl->xid = xpixmap;
pix_impl->is_foreign = TRUE;
@ -345,11 +364,44 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid)
pix_impl->height = h_ret;
GDK_PIXMAP_OBJECT (pixmap)->depth = depth_ret;
gdk_xid_table_insert(&draw_impl->xid, pixmap);
_gdk_xid_table_insert (display, &GDK_PIXMAP_XID (pixmap), pixmap);
return pixmap;
}
/**
* gdk_pixmap_foreign_new:
* @anid: a native pixmap handle.
*
* Wraps a native window for the default display in a #GdkPixmap.
* This may fail if the pixmap has been destroyed.
*
* For example in the X backend, a native pixmap handle is an Xlib
* <type>XID</type>.
*
* Return value: the newly-created #GdkPixmap wrapper for the
* native pixmap or %NULL if the pixmap has been destroyed.
**/
GdkPixmap*
gdk_pixmap_foreign_new (GdkNativeWindow anid)
{
return gdk_pixmap_foreign_new_for_display (gdk_get_default_display (), anid);
}
/**
* gdk_pixmap_get_screen :
* @drawable : the #GdkPixmap.
*
* Returns the #GdkScreen for which the pixmap was created.
*
* Returns: the #GdkScreen for which the pixmap was created.
*/
GdkScreen*
gdk_pixmap_get_screen (GdkDrawable *drawable)
{
return GDK_PIXMAP_SCREEN (drawable);
}
/**
* gdk_pixmap_lookup:
* @anid: a native pixmap handle.
@ -365,5 +417,25 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid)
GdkPixmap*
gdk_pixmap_lookup (GdkNativeWindow anid)
{
return (GdkPixmap*) gdk_xid_table_lookup (anid);
return (GdkPixmap*) gdk_xid_table_lookup_for_display (gdk_get_default_display (), anid);
}
/**
* gdk_pixmap_lookup_for_display:
* @display : the #GdkDisplay associated with @anid
* @anid: a native pixmap handle.
*
* Looks up the #GdkPixmap that wraps the given native pixmap handle.
*
* For example in the X backend, a native pixmap handle is an Xlib
* <type>XID</type>.
*
* Return value: the #GdkWindow wrapper for the native window,
* or %NULL if there is none.
**/
GdkPixmap*
gdk_pixmap_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return (GdkPixmap*) gdk_xid_table_lookup_for_display (display, anid);
}

View File

@ -31,6 +31,7 @@
#ifndef __GDK_PRIVATE_X11_H__
#define __GDK_PRIVATE_X11_H__
#include <gdk/gdkcursor.h>
#include <gdk/gdkprivate.h>
#include <gdk/x11/gdkwindow-x11.h>
#include <gdk/x11/gdkpixmap-x11.h>
@ -60,7 +61,7 @@ struct _GdkGCX11
GdkGC parent_instance;
GC xgc;
Display *xdisplay;
GdkScreen *screen;
GdkRegion *clip_region;
guint dirty_mask;
@ -80,7 +81,7 @@ struct _GdkCursorPrivate
{
GdkCursor cursor;
Cursor xcursor;
Display *xdisplay;
GdkScreen *screen;
};
struct _GdkVisualPrivate
@ -89,19 +90,22 @@ struct _GdkVisualPrivate
Visual *xvisual;
};
void gdk_xid_table_insert (XID *xid,
gpointer data);
void gdk_xid_table_remove (XID xid);
gint gdk_send_xevent (Window window,
gboolean propagate,
glong event_mask,
XEvent *event_send);
void _gdk_xid_table_insert (GdkDisplay *display,
XID *xid,
gpointer data);
void _gdk_xid_table_remove (GdkDisplay *display,
XID xid);
gint _gdk_send_xevent (GdkDisplay *display,
Window window,
gboolean propagate,
glong event_mask,
XEvent *event_send);
GType _gdk_gc_x11_get_type (void);
#ifdef HAVE_XFT
gboolean _gdk_x11_have_render (void);
Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
gboolean _gdk_x11_have_render (GdkDisplay *display);
Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
#endif /* HAVE_XFT */
GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable,
@ -123,19 +127,6 @@ GdkImage *_gdk_x11_copy_to_image (GdkDrawable *drawable,
gint height);
Pixmap _gdk_x11_image_get_shm_pixmap (GdkImage *image);
/* Please see gdkwindow.c for comments on how to use */
Window gdk_window_xid_at (Window base,
gint bx,
gint by,
gint x,
gint y,
GList *excludes,
gboolean excl_child);
Window gdk_window_xid_at_coords (gint x,
gint y,
GList *excludes,
gboolean excl_child);
/* Routines from gdkgeometry-x11.c */
void _gdk_window_init_position (GdkWindow *window);
void _gdk_window_move_resize_child (GdkWindow *window,
@ -156,11 +147,13 @@ void _gdk_region_get_xrectangles (GdkRegion *region,
XRectangle **rects,
gint *n_rects);
void _gdk_moveresize_handle_event (XEvent *event);
void _gdk_moveresize_configure_done (void);
gboolean _gdk_moveresize_handle_event (XEvent *event);
gboolean _gdk_moveresize_configure_done (GdkDisplay *display,
GdkWindow *window);
void _gdk_keymap_state_changed (void);
gint _gdk_x11_get_group_for_state (GdkModifierType state);
void _gdk_keymap_state_changed (GdkDisplay *display);
gint _gdk_x11_get_group_for_state (GdkDisplay *display,
GdkModifierType state);
GC _gdk_x11_gc_flush (GdkGC *gc);
@ -170,33 +163,36 @@ void _gdk_xgrab_check_unmap (GdkWindow *window,
gulong serial);
void _gdk_xgrab_check_destroy (GdkWindow *window);
gboolean _gdk_x11_display_is_root_window (GdkDisplay *display,
Window xroot_window);
void _gdk_x11_events_init_screen (GdkScreen *screen);
void _gdk_events_init (GdkDisplay *display);
void _gdk_windowing_window_init (GdkScreen *screen);
void _gdk_visual_init (GdkScreen *screen);
void _gdk_dnd_init (GdkDisplay *display);
void _gdk_windowing_image_init (GdkDisplay *display);
void _gdk_input_init (GdkDisplay *display);
extern GdkDrawableClass _gdk_x11_drawable_class;
extern Window _gdk_root_window;
extern gboolean _gdk_use_xshm;
extern Atom _gdk_wm_window_protocols[];
extern const int _gdk_nenvent_masks;
extern const int _gdk_event_mask_table[];
extern gint _gdk_screen;
extern GdkAtom _gdk_selection_property;
extern gchar *_gdk_display_name;
extern gboolean _gdk_synchronize;
extern Window _gdk_leader_window;
/* Used to detect not-up-to-date keymap */
extern guint _gdk_keymap_serial;
#ifdef HAVE_XKB
extern gboolean _gdk_use_xkb;
extern gboolean _gdk_have_xkb_autorepeat;
extern gint _gdk_xkb_event_type;
#endif
/* Whether we were able to turn on detectable-autorepeat using
* XkbSetDetectableAutorepeat. If FALSE, we'll fall back
* to checking the next event with XPending().
*/
extern gboolean _gdk_have_xkb_autorepeat;
extern GdkWindow *_gdk_moveresize_window;
#define GDK_PIXMAP_SCREEN(pix) (GDK_DRAWABLE_IMPL_X11 (((GdkPixmapObject *)pix)->impl)->screen)
#define GDK_PIXMAP_DISPLAY(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->display)
#define GDK_PIXMAP_XROOTWIN(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->xroot_window)
#define GDK_DRAWABLE_DISPLAY(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_DISPLAY (win) : GDK_PIXMAP_DISPLAY (win))
#define GDK_DRAWABLE_SCREEN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_SCREEN (win) : GDK_PIXMAP_SCREEN (win))
#define GDK_DRAWABLE_XROOTWIN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XROOTWIN (win) : GDK_PIXMAP_XROOTWIN (win))
#define GDK_SCREEN_DISPLAY(screen) (GDK_SCREEN_X11 (screen)->display)
#define GDK_SCREEN_XROOTWIN(screen) (GDK_SCREEN_X11 (screen)->xroot_window)
#define GDK_WINDOW_SCREEN(win) (GDK_DRAWABLE_IMPL_X11 (((GdkWindowObject *)win)->impl)->screen)
#define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->display)
#define GDK_WINDOW_XROOTWIN(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xroot_window)
#define GDK_GC_DISPLAY(gc) (GDK_SCREEN_DISPLAY (GDK_GC_X11(gc)->screen))
#endif /* __GDK_PRIVATE_X11_H__ */

View File

@ -32,11 +32,13 @@
#include "gdkx.h"
#include "gdkproperty.h"
#include "gdkprivate.h"
#include "gdkinternals.h"
#include "gdkdisplay-x11.h"
#include "gdkscreen-x11.h"
#include "gdkselection.h" /* only from predefined atom */
static GPtrArray *virtual_atom_array;
static GHashTable *virtual_atom_hash;
static GHashTable *atom_to_virtual;
static GHashTable *atom_from_virtual;
static gchar *XAtomsStrings[] = {
/* These are all the standard predefined X atoms */
@ -85,7 +87,8 @@ static gchar *XAtomsStrings[] = {
"WM_ZOOM_HINTS",
"MIN_SPACE",
"NORM_SPACE",
"MAX_SPACE", "END_SPACE",
"MAX_SPACE",
"END_SPACE",
"SUPERSCRIPT_X",
"SUPERSCRIPT_Y",
"SUBSCRIPT_X",
@ -120,19 +123,65 @@ static gchar *XAtomsStrings[] = {
#define INDEX_TO_ATOM(atom) ((GdkAtom)GUINT_TO_POINTER(atom))
static void
insert_atom_pair (GdkAtom virtual_atom,
insert_atom_pair (GdkDisplay *display,
GdkAtom virtual_atom,
Atom xatom)
{
if (!atom_from_virtual)
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
if (!display_x11->atom_from_virtual)
{
atom_from_virtual = g_hash_table_new (g_direct_hash, NULL);
atom_to_virtual = g_hash_table_new (g_direct_hash, NULL);
display_x11->atom_from_virtual = g_hash_table_new (g_direct_hash, NULL);
display_x11->atom_to_virtual = g_hash_table_new (g_direct_hash, NULL);
}
g_hash_table_insert (atom_from_virtual,
GDK_ATOM_TO_POINTER (virtual_atom), GUINT_TO_POINTER (xatom));
g_hash_table_insert (atom_to_virtual,
GUINT_TO_POINTER (xatom), GDK_ATOM_TO_POINTER (virtual_atom));
g_hash_table_insert (display_x11->atom_from_virtual,
GDK_ATOM_TO_POINTER (virtual_atom),
GUINT_TO_POINTER (xatom));
g_hash_table_insert (display_x11->atom_to_virtual,
GUINT_TO_POINTER (xatom),
GDK_ATOM_TO_POINTER (virtual_atom));
}
/**
* gdk_x11_atom_to_xatom_for_display:
* @display: A #GdkDisplay
* @atom: A #GdkAtom
*
* Converts from a #GdkAtom to the X atom for a #GdkDisplay
* with the same string value.
*
* Return value: the X atom corresponding to @atom.
**/
Atom
gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
GdkAtom atom)
{
GdkDisplayX11 *display_x11;
Atom xatom = None;
g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
display_x11 = GDK_DISPLAY_X11 (display);
if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
return ATOM_TO_INDEX (atom);
if (display_x11->atom_from_virtual)
xatom = GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual,
GDK_ATOM_TO_POINTER (atom)));
if (!xatom)
{
char *name;
g_return_val_if_fail (ATOM_TO_INDEX (atom) < virtual_atom_array->len, None);
name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
xatom = XInternAtom (GDK_DISPLAY_XDISPLAY (display), name, FALSE);
insert_atom_pair (display, atom, xatom);
}
return xatom;
}
/**
@ -147,48 +196,35 @@ insert_atom_pair (GdkAtom virtual_atom,
Atom
gdk_x11_atom_to_xatom (GdkAtom atom)
{
Atom xatom = None;
if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
return ATOM_TO_INDEX (atom);
if (atom_from_virtual)
xatom = GPOINTER_TO_UINT (g_hash_table_lookup (atom_from_virtual,
GDK_ATOM_TO_POINTER (atom)));
if (!xatom)
{
char *name;
g_return_val_if_fail (ATOM_TO_INDEX (atom) < virtual_atom_array->len, None);
name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
xatom = XInternAtom (gdk_display, name, FALSE);
insert_atom_pair (atom, xatom);
}
return xatom;
return gdk_x11_atom_to_xatom_for_display (gdk_get_default_display (), atom);
}
/**
* gdk_x11_xatom_to_atom:
* @xatom: an X atom for the default GDK display
* gdk_x11_xatom_to_atom_for_display:
* @display: A #GdkDisplay
* @xatom: an X atom
*
* Converts from an X atom for the default display to the corresponding
* Convert from an X atom for a #GdkDisplay to the corresponding
* #GdkAtom.
*
* Return value: the corresponding #GdkAtom.
**/
GdkAtom
gdk_x11_xatom_to_atom (Atom xatom)
gdk_x11_xatom_to_atom_for_display (GdkDisplay *display,
Atom xatom)
{
GdkDisplayX11 *display_x11;
GdkAtom virtual_atom = GDK_NONE;
g_return_val_if_fail (GDK_IS_DISPLAY (display), virtual_atom);
display_x11 = GDK_DISPLAY_X11 (display);
if (xatom < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
return INDEX_TO_ATOM (xatom);
if (atom_to_virtual)
virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (atom_to_virtual,
if (display_x11->atom_to_virtual)
virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (display_x11->atom_to_virtual,
GUINT_TO_POINTER (xatom)));
if (!virtual_atom)
@ -198,7 +234,7 @@ gdk_x11_xatom_to_atom (Atom xatom)
*/
char *name;
gdk_error_trap_push ();
name = XGetAtomName (gdk_display, xatom);
name = XGetAtomName (GDK_DISPLAY_XDISPLAY (display), xatom);
if (gdk_error_trap_pop ())
{
g_warning (G_STRLOC " invalid X atom: %ld", xatom);
@ -208,13 +244,28 @@ gdk_x11_xatom_to_atom (Atom xatom)
virtual_atom = gdk_atom_intern (name, FALSE);
XFree (name);
insert_atom_pair (virtual_atom, xatom);
insert_atom_pair (display, virtual_atom, xatom);
}
}
return virtual_atom;
}
/**
* gdk_x11_xatom_to_atom:
* @xatom: an X atom for the default GDK display
*
* Convert from an X atom for the default display to the corresponding
* #GdkAtom.
*
* Return value: the corresponding G#dkAtom.
**/
GdkAtom
gdk_x11_xatom_to_atom (Atom xatom)
{
return gdk_x11_xatom_to_atom_for_display (gdk_get_default_display (), xatom);
}
static void
virtual_atom_check_init (void)
{
@ -274,6 +325,26 @@ gdk_atom_name (GdkAtom atom)
return g_strdup (get_atom_name (atom));
}
/**
* gdk_x11_get_xatom_by_name_for_display:
* @display: a #GdkDisplay
* @atom_name: a string
*
* Returns the X atom for a #GdkDisplay corresponding to @atom_name.
* This function caches the result, so if called repeatedly it is much
* faster than XInternAtom, which is a round trip to the server each time.
*
* Return value: a X atom for a #GdkDisplay
**/
Atom
gdk_x11_get_xatom_by_name_for_display (GdkDisplay *display,
const gchar *atom_name)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
return gdk_x11_atom_to_xatom_for_display (display,
gdk_atom_intern (atom_name, FALSE));
}
/**
* gdk_x11_get_xatom_by_name:
* @atom_name: a string
@ -288,7 +359,30 @@ gdk_atom_name (GdkAtom atom)
Atom
gdk_x11_get_xatom_by_name (const gchar *atom_name)
{
return gdk_x11_atom_to_xatom (gdk_atom_intern (atom_name, FALSE));
return gdk_x11_get_xatom_by_name_for_display (gdk_get_default_display (),
atom_name);
}
/**
* gdk_x11_get_xatom_name_for_display:
* @display : the #GdkDisplay where @xatom is defined
* @xatom: an X atom
*
* Returns the name of an X atom for its display. This
* function is meant mainly for debugging, so for convenience, unlike
* XAtomName() and gdk_atom_name(), the result doesn't need to
* be freed.
*
* Return value: name of the X atom; this string is owned by GTK+,
* so it shouldn't be modifed or freed.
**/
G_CONST_RETURN gchar *
gdk_x11_get_xatom_name_for_display (GdkDisplay *display,
Atom xatom)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return get_atom_name (gdk_x11_xatom_to_atom_for_display (display, xatom));
}
/**
@ -322,59 +416,55 @@ gdk_property_get (GdkWindow *window,
gint *actual_length,
guchar **data)
{
Display *xdisplay;
Window xwindow;
Atom xproperty;
Atom xtype;
GdkDisplay *display;
Atom ret_prop_type;
gint ret_format;
gulong ret_nitems;
gulong ret_bytes_after;
gulong ret_length;
guchar *ret_data;
Atom xproperty;
Atom xtype;
g_return_val_if_fail (!window || GDK_IS_WINDOW (window), FALSE);
xproperty = gdk_x11_atom_to_xatom (property);
xtype = gdk_x11_atom_to_xatom (type);
if (window)
if (!window)
{
if (GDK_WINDOW_DESTROYED (window))
return FALSE;
GdkScreen *screen = gdk_get_default_screen ();
window = gdk_screen_get_root_window (screen);
GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n"));
}
xdisplay = GDK_WINDOW_XDISPLAY (window);
xwindow = GDK_WINDOW_XID (window);
}
else
{
xdisplay = gdk_display;
xwindow = _gdk_root_window;
}
display = gdk_drawable_get_display (window);
xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
xtype = gdk_x11_atom_to_xatom_for_display (display, type);
ret_data = NULL;
XGetWindowProperty (xdisplay, xwindow, xproperty,
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
GDK_WINDOW_XWINDOW (window), xproperty,
offset, (length + 3) / 4, pdelete,
xtype, &ret_prop_type, &ret_format,
&ret_nitems, &ret_bytes_after,
&ret_data);
if ((ret_prop_type == None) && (ret_format == 0)) {
return FALSE;
}
if ((ret_prop_type == None) && (ret_format == 0))
{
return FALSE;
}
if (actual_property_type)
*actual_property_type = gdk_x11_xatom_to_atom (ret_prop_type);
*actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type);
if (actual_format_type)
*actual_format_type = ret_format;
if ((type != AnyPropertyType) && (ret_prop_type != xtype))
if ((xtype != AnyPropertyType) && (ret_prop_type != xtype))
{
XFree (ret_data);
g_warning("Couldn't match property type %s to %s\n",
gdk_x11_get_xatom_name (ret_prop_type),
gdk_x11_get_xatom_name (xtype));
g_warning ("Couldn't match property type %s to %s\n",
gdk_x11_get_xatom_name_for_display (display, ret_prop_type),
gdk_x11_get_xatom_name_for_display (display, xtype));
return FALSE;
}
@ -383,7 +473,7 @@ gdk_property_get (GdkWindow *window,
if (data)
{
if (ret_prop_type == XA_ATOM ||
ret_prop_type == gdk_x11_get_xatom_by_name ("ATOM_PAIR"))
ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
{
/*
* data is an array of X atom, we need to convert it
@ -396,8 +486,8 @@ gdk_property_get (GdkWindow *window,
*data = (guchar *)ret_atoms;
for (i = 0; i < ret_nitems; i++)
ret_atoms[i] = gdk_x11_xatom_to_atom (xatoms[i]);
ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]);
if (actual_length)
*actual_length = ret_nitems * sizeof (GdkAtom);
}
@ -441,31 +531,32 @@ gdk_property_change (GdkWindow *window,
const guchar *data,
gint nelements)
{
Display *xdisplay;
GdkDisplay *display;
Window xwindow;
Atom xproperty;
Atom xtype;
g_return_if_fail (!window || GDK_IS_WINDOW (window));
xproperty = gdk_x11_atom_to_xatom (property);
xtype = gdk_x11_atom_to_xatom (type);
if (window)
if (!window)
{
if (GDK_WINDOW_DESTROYED (window))
return;
xdisplay = GDK_WINDOW_XDISPLAY (window);
xwindow = GDK_WINDOW_XID (window);
}
else
{
xdisplay = gdk_display;
xwindow = _gdk_root_window;
GdkScreen *screen;
screen = gdk_get_default_screen ();
window = gdk_screen_get_root_window (screen);
GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n"));
}
if (xtype == XA_ATOM || xtype == gdk_x11_get_xatom_by_name ("ATOM_PAIR"))
display = gdk_drawable_get_display (window);
xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
xtype = gdk_x11_atom_to_xatom_for_display (display, type);
xwindow = GDK_WINDOW_XID (window);
if (xtype == XA_ATOM ||
xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
{
/*
* data is an array of GdkAtom, we need to convert it
@ -477,39 +568,37 @@ gdk_property_change (GdkWindow *window,
xatoms = g_new (Atom, nelements);
for (i = 0; i < nelements; i++)
xatoms[i] = gdk_x11_atom_to_xatom (atoms[i]);
xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);
XChangeProperty (xdisplay, xwindow, xproperty, xtype,
format, mode, (guchar *)xatoms, nelements);
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
xproperty, xtype,
format, mode, (guchar *)xatoms, nelements);
g_free (xatoms);
}
else
XChangeProperty (xdisplay, xwindow, xproperty, xtype,
format, mode, (guchar *)data, nelements);
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty,
xtype, format, mode, (guchar *)data, nelements);
}
void
gdk_property_delete (GdkWindow *window,
GdkAtom property)
{
Display *xdisplay;
Window xwindow;
g_return_if_fail (!window || GDK_IS_WINDOW (window));
if (window)
if (!window)
{
if (GDK_WINDOW_DESTROYED (window))
return;
xdisplay = GDK_WINDOW_XDISPLAY (window);
xwindow = GDK_WINDOW_XID (window);
}
else
{
xdisplay = gdk_display;
xwindow = _gdk_root_window;
GdkScreen *screen = gdk_get_default_screen ();
window = gdk_screen_get_root_window (screen);
GDK_NOTE (MULTIHEAD,
g_message ("gdk_property_delete(): window is NULL\n"));
}
XDeleteProperty (xdisplay, xwindow, gdk_x11_atom_to_xatom (property));
if (GDK_WINDOW_DESTROYED (window))
return;
XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window),
gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window),
property));
}

350
gdk/x11/gdkscreen-x11.c Normal file
View File

@ -0,0 +1,350 @@
/*
* gdkscreen-x11.c
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <glib.h>
#include "gdkscreen.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay.h"
#include "gdkdisplay-x11.h"
#include "gdkx.h"
static void gdk_screen_x11_class_init (GdkScreenX11Class *klass);
static GdkDisplay * gdk_screen_x11_get_display (GdkScreen *screen);
static gint gdk_screen_x11_get_width (GdkScreen *screen);
static gint gdk_screen_x11_get_height (GdkScreen *screen);
static gint gdk_screen_x11_get_width_mm (GdkScreen *screen);
static gint gdk_screen_x11_get_height_mm (GdkScreen *screen);
static gint gdk_screen_x11_get_default_depth (GdkScreen *screen);
static GdkWindow * gdk_screen_x11_get_root_window (GdkScreen *screen);
static gint gdk_screen_x11_get_screen_num (GdkScreen *screen);
static GdkColormap *gdk_screen_x11_get_default_colormap (GdkScreen *screen);
static void gdk_screen_x11_set_default_colormap (GdkScreen *screen,
GdkColormap *colormap);
static GdkWindow * gdk_screen_x11_get_window_at_pointer (GdkScreen *screen,
gint *win_x,
gint *win_y);
static void gdk_screen_x11_finalize (GObject *object);
static gboolean gdk_screen_x11_use_virtual_screen (GdkScreen *screen);
static gint gdk_screen_x11_get_n_monitors (GdkScreen *screen);
static GdkRectangle *gdk_screen_x11_get_monitor_geometry (GdkScreen *screen,
gint num_monitor);
static gint gdk_screen_x11_get_monitor_at_point (GdkScreen *screen,
gint x,
gint y);
static gint gdk_screen_x11_get_monitor_at_window (GdkScreen *screen,
GdkNativeWindow anid);
GType gdk_screen_x11_get_type ();
static gpointer parent_class = NULL;
GType
gdk_screen_x11_get_type ()
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GdkScreenX11Class),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) gdk_screen_x11_finalize,
(GClassInitFunc) gdk_screen_x11_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkScreenX11),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
object_type = g_type_register_static (GDK_TYPE_SCREEN,
"GdkScreenX11",
&object_info, 0);
}
return object_type;
}
void
gdk_screen_x11_class_init (GdkScreenX11Class * klass)
{
GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
screen_class->get_display = gdk_screen_x11_get_display;
screen_class->get_width = gdk_screen_x11_get_width;
screen_class->get_height = gdk_screen_x11_get_height;
screen_class->get_width_mm = gdk_screen_x11_get_width_mm;
screen_class->get_height_mm = gdk_screen_x11_get_height_mm;
screen_class->get_root_depth = gdk_screen_x11_get_default_depth;
screen_class->get_screen_num = gdk_screen_x11_get_screen_num;
screen_class->get_root_window = gdk_screen_x11_get_root_window;
screen_class->get_default_colormap = gdk_screen_x11_get_default_colormap;
screen_class->set_default_colormap = gdk_screen_x11_set_default_colormap;
screen_class->get_window_at_pointer = gdk_screen_x11_get_window_at_pointer;
screen_class->use_virtual_screen = gdk_screen_x11_use_virtual_screen;
screen_class->get_n_monitors = gdk_screen_x11_get_n_monitors;
screen_class->get_monitor_geometry = gdk_screen_x11_get_monitor_geometry;
screen_class->get_monitor_at_point = gdk_screen_x11_get_monitor_at_point;
screen_class->get_monitor_at_window = gdk_screen_x11_get_monitor_at_window;
G_OBJECT_CLASS (klass)->finalize = gdk_screen_x11_finalize;
parent_class = g_type_class_peek_parent (klass);
}
static GdkDisplay *
gdk_screen_x11_get_display (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return screen_x11->display;
}
static gint
gdk_screen_x11_get_width (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return WidthOfScreen (screen_x11->xscreen);
}
static gint
gdk_screen_x11_get_height (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return HeightOfScreen (screen_x11->xscreen);
}
static gint
gdk_screen_x11_get_width_mm (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return WidthMMOfScreen (screen_x11->xscreen);
}
static gint
gdk_screen_x11_get_height_mm (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return HeightMMOfScreen (screen_x11->xscreen);
}
static gint
gdk_screen_x11_get_default_depth (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return DefaultDepthOfScreen (screen_x11->xscreen);
}
static gint
gdk_screen_x11_get_screen_num (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return screen_x11->screen_num;
}
static GdkWindow *
gdk_screen_x11_get_root_window (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
gdk_drawable_ref (screen_x11->root_window);
return screen_x11->root_window;
}
static GdkColormap *
gdk_screen_x11_get_default_colormap (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
return screen_x11->default_colormap;
}
static void
gdk_screen_x11_set_default_colormap (GdkScreen *screen,
GdkColormap * colormap)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
screen_x11->default_colormap = colormap;
}
static GdkWindow *
gdk_screen_x11_get_window_at_pointer (GdkScreen *screen,
gint *win_x,
gint *win_y)
{
GdkWindow *window;
Window root;
Window xwindow;
Window xwindow_last = 0;
Display *xdisplay;
int rootx = -1, rooty = -1;
int winx, winy;
unsigned int xmask;
xwindow = GDK_SCREEN_XROOTWIN (screen);
xdisplay = GDK_SCREEN_XDISPLAY (screen);
XGrabServer (xdisplay);
while (xwindow)
{
xwindow_last = xwindow;
XQueryPointer (xdisplay, xwindow,
&root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
}
XUngrabServer (xdisplay);
window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
xwindow_last);
if (win_x)
*win_x = window ? winx : -1;
if (win_y)
*win_y = window ? winy : -1;
return window;
}
static void
gdk_screen_x11_finalize (GObject *object)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
/* int i; */
g_object_unref (G_OBJECT (screen_x11->root_window));
/* Visual Part (Need to implement finalize for Visuals for a clean
* finalize) */
/* for (i=0;i<screen_x11->nvisuals;i++)
g_object_unref (G_OBJECT (screen_x11->visuals[i]));*/
g_free (screen_x11->visuals);
g_hash_table_destroy (screen_x11->visual_hash);
/* X settings */
g_free (screen_x11->xsettings_client);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
gdk_screen_x11_use_virtual_screen (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
return GDK_SCREEN_X11 (screen)->use_virtual_screen;
}
static gint
gdk_screen_x11_get_n_monitors (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 1);
return GDK_SCREEN_X11 (screen)->num_monitors;
}
static GdkRectangle *
gdk_screen_x11_get_monitor_geometry (GdkScreen *screen,
gint num_monitor)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
g_return_val_if_fail (num_monitor < GDK_SCREEN_X11 (screen)->num_monitors, NULL);
return &GDK_SCREEN_X11 (screen)->monitors[num_monitor];
}
static gint
gdk_screen_x11_get_monitor_at_point (GdkScreen *screen,
gint x,
gint y)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
int i;
GdkRectangle *monitor;
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
for (i = 0, monitor = screen_x11->monitors;
i < screen_x11->num_monitors;
i++, monitor++)
{
if (x >= monitor->x &&
x < monitor->x + monitor->width &&
y >= monitor->y &&
y < (monitor->y + monitor->height))
return i;
}
return -1;
}
static gint
gdk_screen_x11_get_monitor_at_window (GdkScreen *screen,
GdkNativeWindow anid)
{
gint x, y, width, height, depth;
gint left_monitor, right_monitor, diff_monitor;
GdkRectangle *left_monitor_rect, *right_monitor_rect;
GdkWindow *window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY (screen), anid);
gdk_window_get_geometry (window, &x, &y, &width, &height, &depth);
gdk_window_get_position (window, &x, &y);
left_monitor = gdk_screen_x11_get_monitor_at_point (screen, x, y);
right_monitor = gdk_screen_x11_get_monitor_at_point (screen, x + width,
y + height);
left_monitor_rect = gdk_screen_x11_get_monitor_geometry (screen,
left_monitor);
right_monitor_rect = gdk_screen_x11_get_monitor_geometry (screen,
right_monitor);
diff_monitor = right_monitor - left_monitor;
if (diff_monitor == 0)
{
return left_monitor;
}
if (diff_monitor == 1)
{
int dist_left, dist_right;
dist_left = left_monitor_rect->x + left_monitor_rect->width - x;
dist_right = x + width - right_monitor_rect->x;
if (dist_left >= dist_right)
return left_monitor;
return right_monitor;
}
/* Window window span on at least 3 monitors */
return left_monitor + 1;
}
Screen *
gdk_x11_screen_get_xscreen (GdkScreen *screen)
{
return GDK_SCREEN_X11 (screen)->xscreen;
}
int
gdk_x11_screen_get_screen_number (GdkScreen *screen)
{
return GDK_SCREEN_X11 (screen)->screen_num;
}

92
gdk/x11/gdkscreen-x11.h Normal file
View File

@ -0,0 +1,92 @@
/*
* gdkscreen-x11.h
*
* Copyright 2001 Sun Microsystems Inc.
*
* Erwann Chenede <erwann.chenede@sun.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GDK_SCREEN_X11_H__
#define __GDK_SCREEN_X11_H__
#include "gdkprivate-x11.h"
#include "xsettings-client.h"
#include <gdk/gdkscreen.h>
#include <gdk/gdkvisual.h>
#include <X11/X.h>
#include <X11/Xlib.h>
G_BEGIN_DECLS
typedef struct _GdkScreenX11 GdkScreenX11;
typedef struct _GdkScreenX11Class GdkScreenX11Class;
#define GDK_TYPE_SCREEN_X11 (gdk_screen_x11_get_type ())
#define GDK_SCREEN_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_X11, GdkScreenX11))
#define GDK_SCREEN_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN_X11, GdkScreenX11Class))
#define GDK_IS_SCREEN_X11(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN_X11))
#define GDK_IS_SCREEN_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN_X11))
#define GDK_SCREEN_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN_X11, GdkScreenX11Class))
struct _GdkScreenX11
{
GdkScreen parent_instance;
GdkDisplay *display;
Display *xdisplay;
Screen *xscreen;
gint screen_num;
Window xroot_window;
GdkWindow *root_window;
Window wmspec_check_window;
/* Visual Part */
gboolean visual_initialised;
GdkVisualPrivate *system_visual;
GdkVisualPrivate **visuals;
gint nvisuals;
gint available_depths[7];
gint navailable_depths;
GdkVisualType available_types[6];
gint navailable_types;
GHashTable *visual_hash;
/* Colormap Part */
gboolean colormap_initialised;
GdkColormap *default_colormap;
GdkColormap *system_colormap;
/* X settings */
XSettingsClient *xsettings_client;
/* Xinerama */
gboolean use_virtual_screen;
gint num_monitors;
GdkRectangle *monitors;
};
struct _GdkScreenX11Class
{
GdkScreenClass parent_class;
};
GType gdk_screen_x11_get_type ();
G_END_DECLS
#endif /* __GDK_SCREEN_X11_H__ */

View File

@ -28,10 +28,12 @@
#include <X11/Xatom.h>
#include <string.h>
#include "gdkx.h"
#include "gdkproperty.h"
#include "gdkselection.h"
#include "gdkprivate.h"
#include "gdkprivate-x11.h"
#include "gdkdisplay-x11.h"
typedef struct _OwnerInfo OwnerInfo;
@ -73,11 +75,14 @@ gboolean
_gdk_selection_filter_clear_event (XSelectionClearEvent *event)
{
GSList *tmp_list = owner_list;
GdkDisplay *display = gdk_x11_lookup_xdisplay (event->display);
while (tmp_list)
{
OwnerInfo *info = tmp_list->data;
if (info->selection == gdk_x11_xatom_to_atom (event->selection))
if (gdk_drawable_get_display (info->owner) == display &&
info->selection == gdk_x11_xatom_to_atom_for_display (display, event->selection))
{
if ((GDK_DRAWABLE_XID (info->owner) == event->window &&
event->serial >= info->serial))
@ -94,12 +99,29 @@ _gdk_selection_filter_clear_event (XSelectionClearEvent *event)
return FALSE;
}
/**
* gdk_selection_owner_set_for_display:
* @display : the #GdkDisplay.
* @owner : a GdkWindow or NULL to indicate that the the owner for
* the given should be unset.
* @selection : an atom identifying a selection.
* @time : timestamp to use when setting the selection.
* If this is older than the timestamp given last time the owner was
* set for the given selection, the request will be ignored.
* @send_event : if TRUE, and the new owner is different from the current
* owner, the current owner will be sent a SelectionClear event.
*
* Sets the #GdkWindow @owner as the current owner of the selection @selection.
*
* Returns : TRUE if the selection owner was succesfully changed to owner,
* otherwise FALSE.
*/
gboolean
gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
gboolean send_event)
gdk_selection_owner_set_for_display (GdkDisplay *display,
GdkWindow *owner,
GdkAtom selection,
guint32 time,
gboolean send_event)
{
Display *xdisplay;
Window xwindow;
@ -107,27 +129,29 @@ gdk_selection_owner_set (GdkWindow *owner,
GSList *tmp_list;
OwnerInfo *info;
xselection = gdk_x11_atom_to_xatom (selection);
if (owner)
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
if (owner)
{
if (GDK_WINDOW_DESTROYED (owner))
return FALSE;
xdisplay = GDK_WINDOW_XDISPLAY (owner);
xwindow = GDK_WINDOW_XID (owner);
}
else
else
{
xdisplay = gdk_display;
xdisplay = GDK_DISPLAY_XDISPLAY (display);
xwindow = None;
}
xselection = gdk_x11_atom_to_xatom_for_display (display, selection);
tmp_list = owner_list;
while (tmp_list)
{
info = tmp_list->data;
if (info->selection == selection)
if (info->selection == selection)
{
owner_list = g_slist_remove (owner_list, info);
g_free (info);
@ -151,16 +175,55 @@ gdk_selection_owner_set (GdkWindow *owner,
return (XGetSelectionOwner (xdisplay, xselection) == xwindow);
}
GdkWindow*
gdk_selection_owner_get (GdkAtom selection)
gboolean
gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
gboolean send_event)
{
return gdk_selection_owner_set_for_display (gdk_get_default_display (),
owner, selection,
time, send_event);
}
/**
* gdk_selection_owner_get_for_display :
* @display : a #GdkDisplay.
* @selection : an atom indentifying a selection.
*
* Determine the owner of the given selection.
*
* <para> Note that the return value may be owned by a different
* process if a foreign window was previously created for that
* window, but a new foreign window will never be created by this call.
* </para>
*
* Returns :if there is a selection owner for this window,
* and it is a window known to the current process, the GdkWindow that owns
* the selection, otherwise NULL.
*/
GdkWindow *
gdk_selection_owner_get_for_display (GdkDisplay *display,
GdkAtom selection)
{
Window xwindow;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
xwindow = XGetSelectionOwner (gdk_display, gdk_x11_atom_to_xatom (selection));
xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display),
gdk_x11_atom_to_xatom_for_display (display,
selection));
if (xwindow == None)
return NULL;
return gdk_window_lookup (xwindow);
return gdk_window_lookup_for_display (display, xwindow);
}
GdkWindow*
gdk_selection_owner_get (GdkAtom selection)
{
return gdk_selection_owner_get_for_display (gdk_get_default_display (),
selection);
}
void
@ -169,13 +232,17 @@ gdk_selection_convert (GdkWindow *requestor,
GdkAtom target,
guint32 time)
{
GdkDisplay *display;
if (GDK_WINDOW_DESTROYED (requestor))
return;
display = GDK_WINDOW_DISPLAY (requestor);
XConvertSelection (GDK_WINDOW_XDISPLAY (requestor),
gdk_x11_atom_to_xatom (selection),
gdk_x11_atom_to_xatom (target),
gdk_x11_atom_to_xatom (_gdk_selection_property),
gdk_x11_atom_to_xatom_for_display (display, selection),
gdk_x11_atom_to_xatom_for_display (display, target),
gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property),
GDK_WINDOW_XID (requestor), time);
}
@ -191,9 +258,12 @@ gdk_selection_property_get (GdkWindow *requestor,
Atom prop_type;
gint prop_format;
guchar *t = NULL;
GdkDisplay *display;
g_return_val_if_fail (requestor != NULL, 0);
g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0);
display = GDK_WINDOW_DISPLAY (requestor);
/* If retrieved chunks are typically small, (and the ICCCM says the
should be) it would be a win to try first with a buffer of
@ -205,13 +275,12 @@ gdk_selection_property_get (GdkWindow *requestor,
t = NULL;
XGetWindowProperty (GDK_WINDOW_XDISPLAY (requestor),
GDK_WINDOW_XID (requestor),
gdk_x11_atom_to_xatom (_gdk_selection_property),
gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property),
0, 0, False,
AnyPropertyType, &prop_type, &prop_format,
&nitems, &nbytes, &t);
AnyPropertyType, &prop_type,
&prop_format, &nitems, &nbytes, &t);
if (ret_type)
*ret_type = gdk_x11_xatom_to_atom (prop_type);
*ret_type = gdk_x11_xatom_to_atom_for_display (display, prop_type);
if (ret_format)
*ret_format = prop_format;
@ -237,14 +306,17 @@ gdk_selection_property_get (GdkWindow *requestor,
Otherwise there's no guarantee we'll win the race ... */
XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (requestor),
GDK_DRAWABLE_XID (requestor),
gdk_x11_atom_to_xatom (_gdk_selection_property),
gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property),
0, (nbytes + 3) / 4, False,
AnyPropertyType, &prop_type, &prop_format,
&nitems, &nbytes, &t);
if (prop_type != None)
{
if (prop_type == XA_ATOM || prop_type == gdk_x11_get_xatom_by_name ("ATOM_PAIR"))
*data = g_new (guchar, length);
if (prop_type == XA_ATOM ||
prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
{
Atom* atoms = (Atom*) t;
GdkAtom* atoms_dest;
@ -257,7 +329,7 @@ gdk_selection_property_get (GdkWindow *requestor,
atoms_dest = (GdkAtom *)(*data);
for (i=0; i < num_atom; i++)
atoms_dest[i] = gdk_x11_xatom_to_atom (atoms[i]);
atoms_dest[i] = gdk_x11_xatom_to_atom_for_display (display, atoms[i]);
}
else
{
@ -275,6 +347,41 @@ gdk_selection_property_get (GdkWindow *requestor,
}
}
/**
* gdk_selection_send_notify_for_display :
* @display : the #GdkDisplay where @requestor is realized
* @requestor : window to which to deliver response.
* @selection : selection that was requested.
* @target : target that was selected.
* @property : property in which the selection owner stored the data,
* or GDK_NONE to indicate that the request was rejected.
* @time : timestamp.
*
* Send a response to SelectionRequest event.
**/
void
gdk_selection_send_notify_for_display (GdkDisplay *display,
guint32 requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time)
{
XSelectionEvent xevent;
g_return_if_fail (GDK_IS_DISPLAY (display));
xevent.type = SelectionNotify;
xevent.serial = 0;
xevent.send_event = True;
xevent.requestor = requestor;
xevent.selection = gdk_x11_atom_to_xatom_for_display (display, selection);
xevent.target = gdk_x11_atom_to_xatom_for_display (display, target);
xevent.property = gdk_x11_atom_to_xatom_for_display (display, property);
xevent.time = time;
_gdk_send_xevent (display, requestor, False, NoEventMask, (XEvent*) & xevent);
}
void
gdk_selection_send_notify (guint32 requestor,
@ -283,40 +390,55 @@ gdk_selection_send_notify (guint32 requestor,
GdkAtom property,
guint32 time)
{
XSelectionEvent xevent;
xevent.type = SelectionNotify;
xevent.serial = 0;
xevent.send_event = True;
xevent.display = gdk_display;
xevent.requestor = requestor;
xevent.selection = gdk_x11_atom_to_xatom (selection);
xevent.target = gdk_x11_atom_to_xatom (target);
xevent.property = gdk_x11_atom_to_xatom (property);
xevent.time = time;
gdk_send_xevent (requestor, False, NoEventMask, (XEvent*) &xevent);
gdk_selection_send_notify_for_display (gdk_get_default_display (),
requestor, selection,
target, property, time);
}
/**
* gdk_text_property_to_text_list_for_display:
* @display: The #GdkDisplay where the encoding is defined.
* @encoding: an atom representing the encoding. The most
* common values for this are STRING, or COMPOUND_TEXT.
* This is value used as the type for the property.
* @format: the format of the property.
* @text: The text data.
* @length: The number of items to transform.
* @list: location to store a terminated array of strings in
* the encoding of the current locale. This array should be
* freed using gdk_free_text_list().
*
* Convert a text string from the encoding as it is stored
* in a property into an array of strings in the encoding of
* the current local. (The elements of the array represent the
* null-separated elements of the original text string.)
*
* Returns : he number of strings stored in list, or 0,
* if the conversion failed.
*/
gint
gdk_text_property_to_text_list (GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
gdk_text_property_to_text_list_for_display (GdkDisplay *display,
GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
{
XTextProperty property;
gint count = 0;
gint res;
gchar **local_list;
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
property.value = (guchar *)text;
property.encoding = gdk_x11_atom_to_xatom (encoding);
property.encoding = gdk_x11_atom_to_xatom_for_display (display, encoding);
property.format = format;
property.nitems = length;
res = XmbTextPropertyToTextList (GDK_DISPLAY(), &property, &local_list, &count);
res = XmbTextPropertyToTextList (GDK_DISPLAY_XDISPLAY (display), &property,
&local_list, &count);
if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound)
if (res == XNoMemory || res == XLocaleNotSupported ||
res == XConverterNotFound)
{
if (list)
*list = NULL;
@ -334,6 +456,17 @@ gdk_text_property_to_text_list (GdkAtom encoding,
}
}
gint
gdk_text_property_to_text_list (GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
{
return gdk_text_property_to_text_list_for_display (gdk_get_default_display (),
encoding, format, text, length, list);
}
void
gdk_free_text_list (gchar **list)
{
@ -412,7 +545,8 @@ make_list (const gchar *text,
}
/**
* gdk_text_property_to_utf8_list:
* gdk_text_property_to_utf8_list_for_display:
* @display: a #GdkDisplay
* @encoding: an atom representing the encoding of the text
* @format: the format of the property
* @text: the text to convert
@ -427,14 +561,16 @@ make_list (const gchar *text,
* list.
**/
gint
gdk_text_property_to_utf8_list (GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
{
g_return_val_if_fail (text != NULL, 0);
g_return_val_if_fail (length >= 0, 0);
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
if (encoding == GDK_TARGET_STRING)
{
@ -456,11 +592,12 @@ gdk_text_property_to_utf8_list (GdkAtom encoding,
/* Probably COMPOUND text, we fall back to Xlib routines
*/
local_count = gdk_text_property_to_text_list (encoding,
format,
text,
length,
&local_list);
local_count = gdk_text_property_to_text_list_for_display (display,
encoding,
format,
text,
length,
&local_list);
if (list)
*list = g_new (gchar *, local_count + 1);
@ -504,17 +641,61 @@ gdk_text_property_to_utf8_list (GdkAtom encoding,
}
}
/**
* gdk_text_property_to_utf8_list:
* @encoding: an atom representing the encoding of the text
* @format: the format of the property
* @text: the text to convert
* @length: the length of @text, in bytes
* @list: location to store the list of strings or %NULL. The
* list should be freed with g_strfreev().
*
* Convert a text property in the giving encoding to
* a list of UTF-8 strings.
*
* Return value: the number of strings in the resulting
* list.
**/
gint
gdk_text_property_to_utf8_list (GdkAtom encoding,
gint format,
const guchar *text,
gint length,
gchar ***list)
{
return gdk_text_property_to_utf8_list_for_display (gdk_get_default_display (),
encoding, format, text, length, list);
}
/**
* gdk_string_to_compound_text_for_display:
* @display : the #GdkDisplay where the encoding is defined.
* @str : a null-terminated string.
* @encoding: location to store the encoding atom
* (to be used as the type for the property).
* @format: location to store the format of the property
* @ctext: location to store newly allocated data for the property.
* @length: the length of @text, in bytes
*
* Convert a string from the encoding of the current
* locale into a form suitable for storing in a window property.
*
* Returns : 0 upon sucess, non-zero upon failure.
**/
gint
gdk_string_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
gdk_string_to_compound_text_for_display (GdkDisplay *display,
const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
gint res;
XTextProperty property;
res = XmbTextListToTextProperty (GDK_DISPLAY(),
g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
res = XmbTextListToTextProperty (GDK_DISPLAY_XDISPLAY (display),
(char **)&str, 1, XCompoundTextStyle,
&property);
if (res != Success)
@ -526,7 +707,7 @@ gdk_string_to_compound_text (const gchar *str,
}
if (encoding)
*encoding = gdk_x11_xatom_to_atom (property.encoding);
*encoding = gdk_x11_xatom_to_atom_for_display (display, property.encoding);
if (format)
*format = property.format;
if (ctext)
@ -537,6 +718,18 @@ gdk_string_to_compound_text (const gchar *str,
return res;
}
gint
gdk_string_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
return gdk_string_to_compound_text_for_display (gdk_get_default_display (),
str, encoding, format,
ctext, length);
}
/* The specifications for COMPOUND_TEXT and STRING specify that C0 and
* C1 are not allowed except for \n and \t, however the X conversions
* routines for COMPOUND_TEXT only enforce this in one direction,
@ -615,7 +808,8 @@ gdk_utf8_to_string_target (const gchar *str)
}
/**
* gdk_utf8_to_compound_text:
* gdk_utf8_to_compound_text_for_display:
* @display: a #GdkDisplay
* @str: a UTF-8 string
* @encoding: location to store resulting encoding
* @format: location to store format of the result
@ -629,11 +823,12 @@ gdk_utf8_to_string_target (const gchar *str)
* %FALSE.
**/
gboolean
gdk_utf8_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
gboolean need_conversion;
const gchar *charset;
@ -642,6 +837,7 @@ gdk_utf8_to_compound_text (const gchar *str,
gboolean result;
g_return_val_if_fail (str != NULL, FALSE);
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
need_conversion = !g_get_charset (&charset);
@ -675,8 +871,9 @@ gdk_utf8_to_compound_text (const gchar *str,
else
locale_str = tmp_str;
result = gdk_string_to_compound_text (locale_str,
encoding, format, ctext, length);
result = gdk_string_to_compound_text_for_display (display, locale_str,
encoding, format,
ctext, length);
result = (result == Success? TRUE : FALSE);
g_free (locale_str);
@ -684,6 +881,32 @@ gdk_utf8_to_compound_text (const gchar *str,
return result;
}
/**
* gdk_utf8_to_compound_text:
* @str: a UTF-8 string
* @encoding: location to store resulting encoding
* @format: location to store format of the result
* @ctext: location to store the data of the result
* @length: location to store the length of the data
* stored in @ctext
*
* Convert from UTF-8 to compound text.
*
* Return value: %TRUE if the conversion succeeded, otherwise
* false.
**/
gboolean
gdk_utf8_to_compound_text (const gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
return gdk_utf8_to_compound_text_for_display (gdk_get_default_display (),
str, encoding, format,
ctext, length);
}
void gdk_free_compound_text (guchar *ctext)
{
if (ctext)

View File

@ -29,6 +29,7 @@
#include "gdkvisual.h"
#include "gdkprivate-x11.h"
#include "gdkscreen-x11.h"
#include "gdkinternals.h"
struct _GdkVisualClass
@ -45,16 +46,6 @@ static gboolean gdk_visual_equal (Visual *a,
Visual *b);
static GdkVisualPrivate *system_visual;
static GdkVisualPrivate **visuals;
static gint nvisuals;
static gint available_depths[7];
static gint navailable_depths;
static GdkVisualType available_types[6];
static gint navailable_types;
#ifdef G_ENABLE_DEBUG
static const gchar* visual_names[] =
@ -69,8 +60,6 @@ static const gchar* visual_names[] =
#endif /* G_ENABLE_DEBUG */
static GHashTable *visual_hash = NULL;
static void
gdk_visual_finalize (GObject *object)
{
@ -114,7 +103,7 @@ gdk_visual_get_type (void)
void
_gdk_visual_init (void)
_gdk_visual_init (GdkScreen *screen)
{
static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
static const GdkVisualType possible_types[6] =
@ -127,28 +116,33 @@ _gdk_visual_init (void)
GDK_VISUAL_STATIC_GRAY
};
static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
GdkScreenX11 *screen_x11;
XVisualInfo *visual_list;
XVisualInfo visual_template;
GdkVisualPrivate *temp_visual;
Visual *default_xvisual;
GdkVisualPrivate **visuals;
int nxvisuals;
int nvisuals;
int i, j;
g_return_if_fail (GDK_IS_SCREEN (screen));
screen_x11 = GDK_SCREEN_X11 (screen);
visual_template.screen = _gdk_screen;
visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
visual_template.screen = screen_x11->screen_num;
visual_list = XGetVisualInfo (screen_x11->xdisplay, VisualScreenMask, &visual_template, &nxvisuals);
visuals = g_new (GdkVisualPrivate *, nxvisuals);
for (i = 0; i < nxvisuals; i++)
visuals[i] = g_object_new (GDK_TYPE_VISUAL, NULL);
default_xvisual = DefaultVisual (gdk_display, _gdk_screen);
default_xvisual = DefaultVisual (screen_x11->xdisplay, screen_x11->screen_num);
nvisuals = 0;
for (i = 0; i < nxvisuals; i++)
{
visuals[nvisuals]->visual.screen = screen;
if (visual_list[i].depth >= 1)
{
#ifdef __cplusplus
@ -179,7 +173,7 @@ _gdk_visual_init (void)
visuals[nvisuals]->visual.depth = visual_list[i].depth;
visuals[nvisuals]->visual.byte_order =
(ImageByteOrder(gdk_display) == LSBFirst) ?
(ImageByteOrder(screen_x11->xdisplay) == LSBFirst) ?
GDK_LSB_FIRST : GDK_MSB_FIRST;
visuals[nvisuals]->visual.red_mask = visual_list[i].red_mask;
visuals[nvisuals]->visual.green_mask = visual_list[i].green_mask;
@ -217,7 +211,7 @@ _gdk_visual_init (void)
visuals[nvisuals]->visual.blue_shift = 0;
visuals[nvisuals]->visual.blue_prec = 0;
}
nvisuals += 1;
}
}
@ -262,7 +256,7 @@ _gdk_visual_init (void)
for (i = 0; i < nvisuals; i++)
if (default_xvisual->visualid == visuals[i]->xvisual->visualid)
{
system_visual = visuals[i];
screen_x11->system_visual = visuals[i];
break;
}
@ -274,30 +268,30 @@ _gdk_visual_init (void)
visuals[i]->visual.depth);
#endif /* G_ENABLE_DEBUG */
navailable_depths = 0;
for (i = 0; i < npossible_depths; i++)
screen_x11->navailable_depths = 0;
for (i = 0; i < G_N_ELEMENTS (possible_depths); i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j]->visual.depth == possible_depths[i])
{
available_depths[navailable_depths++] = visuals[j]->visual.depth;
screen_x11->available_depths[screen_x11->navailable_depths++] = visuals[j]->visual.depth;
break;
}
}
}
if (navailable_depths == 0)
if (screen_x11->navailable_depths == 0)
g_error ("unable to find a usable depth");
navailable_types = 0;
for (i = 0; i < npossible_types; i++)
screen_x11->navailable_types = 0;
for (i = 0; i < G_N_ELEMENTS (possible_types); i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j]->visual.type == possible_types[i])
{
available_types[navailable_types++] = visuals[j]->visual.type;
screen_x11->available_types[screen_x11->navailable_types++] = visuals[j]->visual.type;
break;
}
}
@ -306,14 +300,18 @@ _gdk_visual_init (void)
for (i = 0; i < nvisuals; i++)
gdk_visual_add ((GdkVisual*) visuals[i]);
if (npossible_types == 0)
if (screen_x11->navailable_types == 0)
g_error ("unable to find a usable visual type");
screen_x11->visuals = visuals;
screen_x11->nvisuals = nvisuals;
screen_x11->visual_initialised = TRUE;
}
/**
* gdk_visual_get_best_depth:
*
* Get the best available depth for the default GDK display. "Best"
* Get the best available depth for the default GDK screen. "Best"
* means "largest," i.e. 32 preferred over 24 preferred over 8 bits
* per pixel.
*
@ -322,27 +320,48 @@ _gdk_visual_init (void)
gint
gdk_visual_get_best_depth (void)
{
return available_depths[0];
GdkScreen *screen = gdk_get_default_screen();
return GDK_SCREEN_X11 (screen)->available_depths[0];
}
/**
* gdk_visual_get_best_type:
*
* Return the best available visual type (the one with the most
* colors) for the default GDK display.
* Return the best available visual type for the default GDK screen.
*
* Return value: best visual type
**/
GdkVisualType
gdk_visual_get_best_type (void)
{
return available_types[0];
GdkScreen *screen = gdk_get_default_screen();
return GDK_SCREEN_X11 (screen)->available_types[0];
}
/**
* gdk_screen_get_system_visual:
* @screen : a #GdkScreen.
*
* Get the system's default visual for @screen.
* This is the visual for the root window of the display.
* The return value should not be freed.
*
* Return value: system visual
**/
GdkVisual *
gdk_screen_get_system_visual (GdkScreen * screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return ((GdkVisual *) GDK_SCREEN_X11 (screen)->system_visual);
}
/**
* gdk_visual_get_system:
*
* Get the default or system visual for the default GDK display.
* Get the system'sdefault visual for the default GDK screen.
* This is the visual for the root window of the display.
* The return value should not be freed.
*
@ -351,28 +370,30 @@ gdk_visual_get_best_type (void)
GdkVisual*
gdk_visual_get_system (void)
{
return ((GdkVisual*) system_visual);
return gdk_screen_get_system_visual (gdk_get_default_screen());
}
/**
* gdk_visual_get_best:
*
* Get the visual with the most available colors for the default
* GDK display. The return value should not be freed.
* GDK screen. The return value should not be freed.
*
* Return value: best visual
**/
GdkVisual*
gdk_visual_get_best (void)
{
return ((GdkVisual*) visuals[0]);
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen());
return (GdkVisual *)screen_x11->visuals[0];
}
/**
* gdk_visual_get_best_with_depth:
* @depth: a bit depth
*
* Get the best visual with depth @depth for the default GDK display.
* Get the best visual with depth @depth for the default GDK screen.
* Color visuals and visuals with mutable colormaps are preferred
* over grayscale or fixed-colormap visuals. The return value should not
* be freed. %NULL may be returned if no visual supports @depth.
@ -382,14 +403,15 @@ gdk_visual_get_best (void)
GdkVisual*
gdk_visual_get_best_with_depth (gint depth)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (depth == visuals[i]->visual.depth)
for (i = 0; i < screen_x11->nvisuals; i++)
if (depth == screen_x11->visuals[i]->visual.depth)
{
return_val = (GdkVisual*) visuals[i];
return_val = (GdkVisual *) & (screen_x11->visuals[i]);
break;
}
@ -400,7 +422,7 @@ gdk_visual_get_best_with_depth (gint depth)
* gdk_visual_get_best_with_type:
* @visual_type: a visual type
*
* Get the best visual of the given @visual_type for the default GDK display.
* Get the best visual of the given @visual_type for the default GDK screen.
* Visuals with higher color depths are considered better. The return value
* should not be freed. %NULL may be returned if no visual has type
* @visual_type.
@ -410,14 +432,15 @@ gdk_visual_get_best_with_depth (gint depth)
GdkVisual*
gdk_visual_get_best_with_type (GdkVisualType visual_type)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (visual_type == visuals[i]->visual.type)
for (i = 0; i < screen_x11->nvisuals; i++)
if (visual_type == screen_x11->visuals[i]->visual.type)
{
return_val = (GdkVisual*) visuals[i];
return_val = (GdkVisual *) screen_x11->visuals[i];
break;
}
@ -437,15 +460,16 @@ GdkVisual*
gdk_visual_get_best_with_both (gint depth,
GdkVisualType visual_type)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if ((depth == visuals[i]->visual.depth) &&
(visual_type == visuals[i]->visual.type))
for (i = 0; i < screen_x11->nvisuals; i++)
if ((depth == screen_x11->visuals[i]->visual.depth) &&
(visual_type == screen_x11->visuals[i]->visual.type))
{
return_val = (GdkVisual*) visuals[i];
return_val = (GdkVisual *) screen_x11->visuals[i];
break;
}
@ -458,7 +482,7 @@ gdk_visual_get_best_with_both (gint depth,
* @count: return location for number of available depths
*
* This function returns the available bit depths for the default
* display. It's equivalent to listing the visuals
* screen. It's equivalent to listing the visuals
* (gdk_list_visuals()) and then looking at the depth field in each
* visual, removing duplicates.
*
@ -469,8 +493,10 @@ void
gdk_query_depths (gint **depths,
gint *count)
{
*count = navailable_depths;
*depths = available_depths;
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
*count = screen_x11->navailable_depths;
*depths = screen_x11->available_depths;
}
/**
@ -479,25 +505,58 @@ gdk_query_depths (gint **depths,
* @count: return location for the number of available visual types
*
* This function returns the available visual types for the default
* display. It's equivalent to listing the visuals
* screen. It's equivalent to listing the visuals
* (gdk_list_visuals()) and then looking at the type field in each
* visual, removing duplicates.
*
* The array returned by this function should not be freed.
*
**/
void
gdk_query_visual_types (GdkVisualType **visual_types,
gint *count)
{
*count = navailable_types;
*visual_types = available_types;
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
*count = screen_x11->navailable_types;
*visual_types = screen_x11->available_types;
}
/**
* gdk_screen_list_visuals:
* @screen : the relevant #GdkScreen.
*
* Lists the available visuals for the specified @screen.
* A visual describes a hardware image data format.
* For example, a visual might support 24-bit color, or 8-bit color,
* and might expect pixels to be in a certain format.
*
* Call g_list_free() on the return value when you're finished with it.
*
* Return value: a list of visuals; the list must be freed, but not its contents
**/
GList *
gdk_screen_list_visuals (GdkScreen *screen)
{
GList *list;
GdkScreenX11 *screen_x11;
guint i;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
list = NULL;
for (i = 0; i < screen_x11->nvisuals; ++i)
list = g_list_append (list, screen_x11->visuals[i]);
return list;
}
/**
* gdk_list_visuals:
*
* Lists the available visuals for the default display.
* Lists the available visuals for the default screen.
* (See gdk_screen_list_visuals())
* A visual describes a hardware image data format.
* For example, a visual might support 24-bit color, or 8-bit color,
* and might expect pixels to be in a certain format.
@ -509,54 +568,63 @@ gdk_query_visual_types (GdkVisualType **visual_types,
GList*
gdk_list_visuals (void)
{
GList *list;
guint i;
list = NULL;
for (i = 0; i < nvisuals; ++i)
list = g_list_append (list, (gpointer) visuals[i]);
return list;
return gdk_screen_list_visuals (gdk_get_default_screen ());
}
GdkVisual*
gdk_visual_lookup (Visual *xvisual)
gdk_visual_lookup (Visual *xvisual)
{
GdkVisual *visual;
if (!visual_hash)
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_get_default_screen ());
if (!screen_x11->visual_hash)
return NULL;
visual = g_hash_table_lookup (visual_hash, xvisual);
return visual;
return g_hash_table_lookup (screen_x11->visual_hash, xvisual);
}
/**
* gdkx_visual_get_for_screen:
* @screen: a #GdkScreen.
* @xvisualid: an X Visual ID.
*
* Returns a #GdkVisual from and X Visual id.
*
* Returns: a #GdkVisual.
*/
GdkVisual *
gdkx_visual_get_for_screen (GdkScreen *screen,
VisualID xvisualid)
{
int i;
GdkScreenX11 *screen_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
for (i = 0; i < screen_x11->nvisuals; i++)
if (xvisualid == screen_x11->visuals[i]->xvisual->visualid)
return (GdkVisual *) screen_x11->visuals[i];
return NULL;
}
GdkVisual*
gdkx_visual_get (VisualID xvisualid)
{
int i;
for (i = 0; i < nvisuals; i++)
if (xvisualid == visuals[i]->xvisual->visualid)
return (GdkVisual*) visuals[i];
return NULL;
return gdkx_visual_get_for_screen (gdk_get_default_screen (), xvisualid);
}
static void
gdk_visual_add (GdkVisual *visual)
{
GdkVisualPrivate *private;
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (visual->screen);
if (!screen_x11->visual_hash)
screen_x11->visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
(GEqualFunc) gdk_visual_equal);
if (!visual_hash)
visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
(GEqualFunc) gdk_visual_equal);
private = (GdkVisualPrivate*) visual;
g_hash_table_insert (visual_hash, private->xvisual, visual);
private = (GdkVisualPrivate *) visual;
g_hash_table_insert (screen_x11->visual_hash, private->xvisual, visual);
}
static void

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,9 @@
G_BEGIN_DECLS
extern Display *gdk_display;
#ifndef GDK_MULTIHEAD_SAFE
extern Display *gdk_display;
#endif
Display *gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable);
XID gdk_x11_drawable_get_xid (GdkDrawable *drawable);
@ -45,77 +47,122 @@ Display *gdk_x11_colormap_get_xdisplay (GdkColormap *colormap);
Colormap gdk_x11_colormap_get_xcolormap (GdkColormap *colormap);
Display *gdk_x11_cursor_get_xdisplay (GdkCursor *cursor);
Cursor gdk_x11_cursor_get_xcursor (GdkCursor *cursor);
Display *gdk_x11_display_get_xdisplay (GdkDisplay *display);
Visual * gdk_x11_visual_get_xvisual (GdkVisual *visual);
Display *gdk_x11_gc_get_xdisplay (GdkGC *gc);
GC gdk_x11_gc_get_xgc (GdkGC *gc);
Screen * gdk_x11_screen_get_xscreen (GdkScreen *screen);
int gdk_x11_screen_get_screen_number (GdkScreen *screen);
#ifndef GDK_MULTIHEAD_SAFE
Window gdk_x11_get_default_root_xwindow (void);
Display *gdk_x11_get_default_xdisplay (void);
gint gdk_x11_get_default_screen (void);
#endif
#define GDK_COLORMAP_XDISPLAY(cmap) (gdk_x11_colormap_get_xdisplay (cmap))
#define GDK_COLORMAP_XCOLORMAP(cmap) (gdk_x11_colormap_get_xcolormap (cmap))
#define GDK_CURSOR_XDISPLAY(cursor) (gdk_x11_cursor_get_xdisplay (cursor))
#define GDK_CURSOR_XCURSOR(cursor) (gdk_x11_cursor_get_xcursor (cursor))
#define GDK_DISPLAY() gdk_display
#define GDK_IMAGE_XDISPLAY(image) (gdk_x11_image_get_xdisplay (image))
#define GDK_IMAGE_XIMAGE(image) (gdk_x11_image_get_ximage (image))
#ifndef GDK_MULTIHEAD_SAFE
#define GDK_DISPLAY() gdk_display
#endif
#ifdef INSIDE_GDK_X11
#include "gdkprivate-x11.h"
#include "gdkscreen-x11.h"
#define GDK_ROOT_WINDOW() _gdk_root_window
#undef GDK_ROOT_PARENT
#define GDK_ROOT_PARENT() ((GdkWindow *)_gdk_parent_root)
#define GDK_WINDOW_XDISPLAY(win) (GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)win)->impl)->xdisplay)
#define GDK_DISPLAY_XDISPLAY(display) (GDK_DISPLAY_X11(display)->xdisplay)
#define GDK_WINDOW_XDISPLAY(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xdisplay)
#define GDK_WINDOW_XID(win) (GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)win)->impl)->xid)
#define GDK_PIXMAP_XDISPLAY(win) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)win)->impl)->xdisplay)
#define GDK_PIXMAP_XID(win) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)win)->impl)->xid)
#define GDK_PIXMAP_XDISPLAY(pix) (GDK_SCREEN_X11 (GDK_PIXMAP_SCREEN (pix))->xdisplay)
#define GDK_PIXMAP_XID(pix) (GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)pix)->impl)->xid)
#define GDK_DRAWABLE_XDISPLAY(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XDISPLAY (win) : GDK_PIXMAP_XDISPLAY (win))
#define GDK_DRAWABLE_XID(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XID (win) : GDK_PIXMAP_XID (win))
#define GDK_GC_XDISPLAY(gc) (GDK_GC_X11(gc)->xdisplay)
#define GDK_GC_XDISPLAY(gc) (GDK_SCREEN_XDISPLAY(GDK_GC_X11(gc)->screen))
#define GDK_GC_XGC(gc) (GDK_GC_X11(gc)->xgc)
#define GDK_SCREEN_XDISPLAY(screen) (GDK_SCREEN_X11 (screen)->xdisplay)
#define GDK_SCREEN_XSCREEN(screen) (GDK_SCREEN_X11 (screen)->xscreen)
#define GDK_SCREEN_XNUMBER(screen) (GDK_SCREEN_X11 (screen)->screen_number)
#define GDK_VISUAL_XVISUAL(vis) (((GdkVisualPrivate *) vis)->xvisual)
#define GDK_GC_XGC(gc) (GDK_GC_X11(gc)->xgc)
#define GDK_GC_GET_XGC(gc) (GDK_GC_X11(gc)->dirty_mask ? _gdk_x11_gc_flush (gc) : ((GdkGCX11 *)(gc))->xgc)
#define GDK_WINDOW_XWINDOW GDK_DRAWABLE_XID
#define GDK_GC_GET_XGC(gc) (GDK_GC_X11(gc)->dirty_mask ? _gdk_x11_gc_flush (gc) : ((GdkGCX11 *)(gc))->xgc)
#define GDK_WINDOW_XWINDOW GDK_DRAWABLE_XID
#else /* INSIDE_GDK_X11 */
#ifndef GDK_MULTIHEAD_SAFE
#define GDK_ROOT_WINDOW() (gdk_x11_get_default_root_xwindow ())
#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win))
#endif
#define GDK_DISPLAY_XDISPLAY(display) (gdk_x11_display_get_xdisplay (display))
#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkWindowObject *)win)->impl))
#define GDK_WINDOW_XID(win) (gdk_x11_drawable_get_xid (win))
#define GDK_WINDOW_XWINDOW(win) (gdk_x11_drawable_get_xid (win))
#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win))
#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkPixmapObject *)win)->impl))
#define GDK_PIXMAP_XID(win) (gdk_x11_drawable_get_xid (win))
#define GDK_DRAWABLE_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win))
#define GDK_DRAWABLE_XID(win) (gdk_x11_drawable_get_xid (win))
#define GDK_VISUAL_XVISUAL(visual) (gdk_x11_visual_get_xvisual (visual))
#define GDK_GC_XDISPLAY(gc) (gdk_x11_gc_get_xdisplay (gc))
#define GDK_GC_XGC(gc) (gdk_x11_gc_get_xgc (gc))
#define GDK_SCREEN_XDISPLAY(screen) (gdk_x11_display_get_xdisplay (gdk_screen_get_display (screen)))
#define GDK_SCREEN_XSCREEN(screen) (gdk_x11_screen_get_xscreen (screen))
#define GDK_SCREEN_XNUMBER(screen) (gdk_x11_screen_get_screen_number (screen))
#define GDK_VISUAL_XVISUAL(visual) (gdk_x11_visual_get_xvisual (visual))
#endif /* INSIDE_GDK_X11 */
GdkVisual* gdkx_visual_get (VisualID xvisualid);
GdkVisual* gdkx_visual_get_for_screen (GdkScreen *screen,
VisualID xvisualid);
#ifndef GDK_MULTIHEAD_SAFE
GdkVisual* gdkx_visual_get (VisualID xvisualid);
#endif
/* XXX: Do not use this function until it is fixed. An X Colormap
* is useless unless we also have the visual. */
GdkColormap* gdkx_colormap_get (Colormap xcolormap);
/* Return the Gdk* for a particular XID */
gpointer gdk_xid_table_lookup (XID xid);
gpointer gdk_xid_table_lookup_for_display (GdkDisplay *display,
XID xid);
guint32 gdk_x11_get_server_time (GdkWindow *window);
/* FIXME should take a GdkDisplay* */
void gdk_x11_grab_server (void);
void gdk_x11_ungrab_server (void);
/* returns TRUE if we support the given WM spec feature */
gboolean gdk_net_wm_supports (GdkAtom property);
gboolean gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
GdkAtom property);
#ifndef GDK_MULTIHEAD_SAFE
gpointer gdk_xid_table_lookup (XID xid);
gboolean gdk_net_wm_supports (GdkAtom property);
void gdk_x11_grab_server ();
void gdk_x11_ungrab_server ();
#endif
GdkDisplay *gdk_x11_lookup_xdisplay (Display *xdisplay);
GList *gdk_list_visuals_for_screen (GdkScreen *screen);
/* Functions to get the X Atom equivalent to the GdkAtom */
Atom gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
GdkAtom virtual_atom);
GdkAtom gdk_x11_xatom_to_atom_for_display (GdkDisplay *display,
Atom xatom);
Atom gdk_x11_get_xatom_by_name_for_display (GdkDisplay *display,
const gchar *atom_name);
G_CONST_RETURN gchar *gdk_x11_get_xatom_name_for_display (GdkDisplay *display,
Atom xatom);
#ifndef GDK_MULTIHEAD_SAFE
Atom gdk_x11_atom_to_xatom (GdkAtom atom);
GdkAtom gdk_x11_xatom_to_atom (Atom xatom);
Atom gdk_x11_get_xatom_by_name (const gchar *atom_name);
G_CONST_RETURN gchar *gdk_x11_get_xatom_name (Atom xatom);
#endif
#ifndef GDK_DISABLE_DEPRECATED
@ -126,8 +173,13 @@ G_CONST_RETURN char *gdk_x11_font_get_name (GdkFont *font);
#define GDK_FONT_XDISPLAY(font) (gdk_x11_font_get_xdisplay (font))
#define GDK_FONT_XFONT(font) (gdk_x11_font_get_xfont (font))
#ifndef GDK_MULTIHEAD_SAFE
#define gdk_font_lookup(xid) ((GdkFont*) gdk_xid_table_lookup (xid))
#endif /* GDK_MULTIHEAD_SAFE */
#define gdk_font_lookup_for_display(display, xid) ((GdkFont*) gdk_xid_table_lookup_for_display (display, xid))
#endif /* GDK_DISABLE_DEPRECATED */
G_END_DECLS

View File

@ -25,6 +25,7 @@
*/
#include "gdkprivate-x11.h"
#include "gdkdisplay-x11.h"
#include <stdio.h>
static guint gdk_xid_hash (XID *xid);
@ -32,44 +33,74 @@ static gboolean gdk_xid_equal (XID *a,
XID *b);
static GHashTable *xid_ht = NULL;
void
gdk_xid_table_insert (XID *xid,
gpointer data)
_gdk_xid_table_insert (GdkDisplay *display,
XID *xid,
gpointer data)
{
GdkDisplayX11 *display_x11;
g_return_if_fail (xid != NULL);
g_return_if_fail (GDK_IS_DISPLAY (display));
display_x11 = GDK_DISPLAY_X11 (display);
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GEqualFunc) gdk_xid_equal);
if (!display_x11->xid_ht)
display_x11->xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GEqualFunc) gdk_xid_equal);
g_hash_table_insert (xid_ht, xid, data);
g_hash_table_insert (display_x11->xid_ht, xid, data);
}
void
gdk_xid_table_remove (XID xid)
_gdk_xid_table_remove (GdkDisplay *display,
XID xid)
{
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GEqualFunc) gdk_xid_equal);
GdkDisplayX11 *display_x11;
g_return_if_fail (GDK_IS_DISPLAY (display));
display_x11 = GDK_DISPLAY_X11 (display);
if (!display_x11->xid_ht)
display_x11->xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GEqualFunc) gdk_xid_equal);
g_hash_table_remove (xid_ht, &xid);
g_hash_table_remove (display_x11->xid_ht, &xid);
}
/**
* gdk_xid_table_lookup_for_display:
* @display : the #GdkDisplay.
* @xid : an X id.
*
* Returns the Gdk object associated with the given X id.
*
* Returns: an GdkObject associated with the given X id.
*/
gpointer
gdk_xid_table_lookup_for_display (GdkDisplay *display,
XID xid)
{
GdkDisplayX11 *display_x11;
gpointer data = NULL;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
display_x11 = GDK_DISPLAY_X11 (display);
if (display_x11->xid_ht)
data = g_hash_table_lookup (display_x11->xid_ht, &xid);
return data;
}
gpointer
gdk_xid_table_lookup (XID xid)
{
gpointer data = NULL;
if (xid_ht)
data = g_hash_table_lookup (xid_ht, &xid);
return data;
return gdk_xid_table_lookup_for_display (gdk_get_default_display (), xid);
}
static guint
gdk_xid_hash (XID *xid)
{

View File

@ -1,865 +0,0 @@
/*
* gxid version 0.3
*
* Copyright 1997 Owen Taylor <owt1@cornell.edu>
*/
#undef G_LOG_DOMAIN
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>
#include "gxid_proto.h"
/* #define DEBUG_CLIENTS */
/* #define DEBUG_EVENTS */
char *program_name;
Display *dpy;
Window root_window; /* default root window of dpy */
int port = 0; /* port to listen on */
int socket_fd = 0; /* file descriptor of socket */
typedef struct GxidWindow_ GxidWindow;
typedef struct GxidDevice_ GxidDevice;
struct GxidDevice_ {
XID id;
int exclusive;
int ispointer;
XDevice *xdevice;
int motionnotify_type;
int changenotify_type;
};
struct GxidWindow_ {
Window xwindow;
/* Immediate child of root that is ancestor of window */
Window root_child;
int num_devices;
GxidDevice **devices;
};
GxidDevice **devices = NULL;
int num_devices = 0;
GxidWindow **windows = NULL;
int num_windows = 0;
void
handler(int signal)
{
fprintf(stderr,"%s: dying on signal %d\n",program_name,signal);
if (socket_fd)
close(socket_fd);
exit(1);
}
void
init_socket(void)
{
struct sockaddr_in sin;
socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (socket_fd < 0)
{
fprintf (stderr, "%s: error getting socket\n",
program_name);
exit(1);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(socket_fd,(struct sockaddr *)(&sin),
sizeof(struct sockaddr_in)) < 0)
{
fprintf (stderr,"%s: cannot bind to port %d\n",
program_name,port);
exit(1);
}
if (listen(socket_fd,5) < 0)
{
fprintf (stderr,"%s: error listening on socket\n",
program_name);
exit(1);
};
}
#define NUM_EVENTC 2
static void
enable_device(GxidDevice *dev)
{
XEventClass xevc[NUM_EVENTC];
int num_eventc = NUM_EVENTC;
int i,j;
if (!dev->xdevice)
{
if (dev->ispointer) return;
dev->xdevice = XOpenDevice(dpy, dev->id);
if (!dev->xdevice) return;
DeviceMotionNotify (dev->xdevice, dev->motionnotify_type,
xevc[0]);
ChangeDeviceNotify (dev->xdevice, dev->changenotify_type,
xevc[1]);
/* compress out zero event classes */
for (i=0,j=0;i<NUM_EVENTC;i++)
{
if (xevc[i]) {
xevc[j] = xevc[i];
j++;
}
}
num_eventc = j;
XSelectExtensionEvent (dpy, root_window, xevc, num_eventc);
}
}
/* switch the core pointer from whatever it is now to something else,
return true on success, false otherwise */
static int
switch_core_pointer(void)
{
GxidDevice *old_pointer = 0;
GxidDevice *new_pointer = 0;
int result;
int i;
for (i=0;i<num_devices;i++)
{
if (devices[i]->ispointer)
old_pointer = devices[i];
else
if (!new_pointer && !devices[i]->exclusive)
new_pointer = devices[i];
}
if (!old_pointer || !new_pointer)
return 0;
#ifdef DEBUG_EVENTS
fprintf(stderr,"gxid: Switching core from %ld to %ld\n",
old_pointer->id,new_pointer->id);
#endif
result = XChangePointerDevice(dpy,new_pointer->xdevice, 0, 1);
if (result != Success)
{
fprintf(stderr,"gxid: Error %d switching core from %ld to %ld\n",
result, old_pointer->id, new_pointer->id);
}
else
{
new_pointer->ispointer = 1;
old_pointer->ispointer = 0;
if (!old_pointer->xdevice)
enable_device(old_pointer);
}
return 1;
}
void
disable_device(GxidDevice *dev)
{
if (dev->xdevice)
{
if (dev->ispointer)
return;
XCloseDevice(dpy,dev->xdevice);
dev->xdevice = 0;
}
}
GxidDevice *
init_device(XDeviceInfo *xdevice)
{
GxidDevice *dev = (GxidDevice *)malloc(sizeof(GxidDevice));
XAnyClassPtr class;
int num_axes, i;
dev->id = xdevice->id;
dev->exclusive = 0;
dev->xdevice = NULL;
dev->ispointer = (xdevice->use == IsXPointer);
/* step through the classes */
num_axes = 0;
class = xdevice->inputclassinfo;
for (i=0;i<xdevice->num_classes;i++)
{
if (class->class == ValuatorClass)
{
XValuatorInfo *xvi = (XValuatorInfo *)class;
num_axes = xvi->num_axes;
}
class = (XAnyClassPtr)(((char *)class) + class->length);
}
/* return NULL if insufficient axes */
if (num_axes < 2)
{
free((void *)dev);
return NULL;
}
if (!dev->ispointer)
enable_device(dev);
return dev;
}
void
init_xinput(void)
{
char **extensions;
XDeviceInfo *xdevices;
int num_xdevices;
int num_extensions;
int i;
extensions = XListExtensions(dpy, &num_extensions);
for (i = 0; i < num_extensions &&
(strcmp(extensions[i], "XInputExtension") != 0); i++);
XFreeExtensionList(extensions);
if (i == num_extensions) /* XInput extension not found */
{
fprintf(stderr,"XInput extension not found\n");
exit(1);
}
xdevices = XListInputDevices(dpy, &num_xdevices);
devices = (GxidDevice **)malloc(num_xdevices * sizeof(GxidDevice *));
num_devices = 0;
for(i=0; i<num_xdevices; i++)
{
GxidDevice *dev = init_device(&xdevices[i]);
if (dev)
devices[num_devices++] = dev;
}
XFreeDeviceList(xdevices);
}
/* If this routine needs fixing, the corresponding routine
in gdkinputgxi.h will need it too. */
Window
gxi_find_root_child(Display *dpy, Window w)
{
Window root,parent;
Window *children;
int nchildren;
parent = w;
do
{
w = parent;
XQueryTree (dpy, w, &root, &parent, &children, &nchildren);
if (children)
XFree (children);
}
while (parent != root);
return w;
}
int
handle_claim_device(GxidClaimDevice *msg)
{
int i,j;
XID devid;
XID winid;
int exclusive;
GxidDevice *device = NULL;
GxidWindow *window = NULL;
if (msg->length != sizeof(GxidClaimDevice))
{
fprintf(stderr,"Bad length for ClaimDevice message\n");
return GXID_RETURN_ERROR;
}
devid = ntohl(msg->device);
winid = ntohl(msg->window);
exclusive = ntohl(msg->exclusive);
#ifdef DEBUG_CLIENTS
fprintf(stderr,"device %ld claimed (window 0x%lx)\n",devid,winid);
#endif
for (i=0;i<num_devices;i++)
{
if (devices[i]->id == devid)
{
device = devices[i];
break;
}
}
if (!device)
{
fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
return GXID_RETURN_ERROR;
}
if (device->exclusive)
{
/* already in use */
fprintf(stderr,
"%s: Device %ld already claimed in exclusive mode\n",
program_name,devid);
return GXID_RETURN_ERROR;
}
if (exclusive)
{
for (i=0;i<num_windows;i++)
{
for (j=0;j<windows[i]->num_devices;j++)
if (windows[i]->devices[j]->id == devid)
{
/* already in use */
fprintf(stderr,
"%s: Can't establish exclusive use of device %ld\n",
program_name,devid);
return GXID_RETURN_ERROR;
}
}
if (device->ispointer)
if (!switch_core_pointer())
{
fprintf(stderr,
"%s: Can't free up core pointer %ld\n",
program_name,devid);
return GXID_RETURN_ERROR;
}
device->exclusive = 1;
disable_device(device);
XSelectInput(dpy,winid,StructureNotifyMask);
}
else /* !exclusive */
{
/* FIXME: this is a bit improper. We probably should do this only
when a window is first claimed. But we might be fooled if
an old client died without releasing it's windows. So until
we look for client-window closings, do it here
(We do look for closings now...)
*/
XSelectInput(dpy,winid,EnterWindowMask|StructureNotifyMask);
}
for (i=0;i<num_windows;i++)
{
if (windows[i]->xwindow == winid)
{
window = windows[i];
break;
}
}
/* Create window structure if no devices have been previously
claimed on it */
if (!window)
{
num_windows++;
windows = (GxidWindow **)realloc(windows,
sizeof(GxidWindow*)*num_windows);
window = (GxidWindow *)malloc(sizeof(GxidWindow));
windows[num_windows-1] = window;
window->xwindow = winid;
window->root_child = gxi_find_root_child(dpy,winid);
window->num_devices = 0;
window->devices = 0;
}
for (i=0;i<window->num_devices;i++)
{
if (window->devices[i] == device)
return GXID_RETURN_OK;
}
window->num_devices++;
window->devices = (GxidDevice **)realloc(window->devices,
sizeof(GxidDevice*)*num_devices);
/* we need add the device to the window */
window->devices[i] = device;
return GXID_RETURN_OK;
}
int
handle_release_device(GxidReleaseDevice *msg)
{
int i,j;
XID devid;
XID winid;
GxidDevice *device = NULL;
if (msg->length != sizeof(GxidReleaseDevice))
{
fprintf(stderr,"Bad length for ReleaseDevice message\n");
return GXID_RETURN_ERROR;
}
devid = ntohl(msg->device);
winid = ntohl(msg->window);
#ifdef DEBUG_CLIENTS
fprintf(stderr,"device %ld released (window 0x%lx)\n",devid,winid);
#endif
for (i=0;i<num_devices;i++)
{
if (devices[i]->id == devid)
{
device = devices[i];
break;
}
}
if (!device)
{
fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
return GXID_RETURN_ERROR;
}
for (i=0;i<num_windows;i++)
{
GxidWindow *w = windows[i];
if (w->xwindow == winid)
for (j=0;j<w->num_devices;j++)
if (w->devices[j]->id == devid)
{
if (j<w->num_devices-1)
w->devices[j] = w->devices[w->num_devices-1];
w->num_devices--;
if (w->num_devices == 0)
{
if (i<num_windows-1)
windows[i] = windows[num_windows-1];
num_windows--;
free((void *)w);
/* FIXME: should we deselect input? But what
what if window is already destroyed */
}
if (device->exclusive)
{
device->exclusive = 0;
enable_device(device);
}
return GXID_RETURN_OK;
}
}
/* device/window combination not found */
fprintf(stderr,
"%s: Device %ld not claimed for window 0x%lx\n",
program_name,devid,winid);
return GXID_RETURN_ERROR;
}
void
handle_connection (void)
{
GxidMessage msg;
GxidU32 type;
GxidU32 length;
GxidI32 retval;
int conn_fd;
struct sockaddr_in sin;
int sin_length;
int count;
sin_length = sizeof(struct sockaddr_in);
conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length);
if (conn_fd < 0)
{
fprintf(stderr,"%s: Error accepting connection\n",
program_name);
exit(1);
}
/* read type and length of message */
count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32));
if (count != 2*sizeof(GxidU32))
{
fprintf(stderr,"%s: Error reading message header\n",
program_name);
close(conn_fd);
return;
}
type = ntohl(msg.any.type);
length = ntohl(msg.any.length);
/* read rest of message */
if ((length > sizeof(GxidMessage)) || (length < 2*sizeof(GxidU32)))
{
fprintf(stderr,"%s: Bad message length\n",
program_name);
close(conn_fd);
return;
}
count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg,
length - 2*sizeof(GxidU32));
if (count != length - 2*sizeof(GxidU32))
{
fprintf(stderr,"%s: Error reading message body\n",
program_name);
close(conn_fd);
return;
}
switch (type)
{
case GXID_CLAIM_DEVICE:
retval = handle_claim_device((GxidClaimDevice *)&msg);
break;
case GXID_RELEASE_DEVICE:
retval = handle_release_device((GxidReleaseDevice *)&msg);
break;
default:
fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n",
program_name,type);
close(conn_fd);
return;
}
count = write(conn_fd,&retval,sizeof(GxidI32));
if (count != sizeof(GxidI32))
{
fprintf(stderr,"%s: Error writing return code\n",
program_name);
}
close(conn_fd);
}
void
handle_motion_notify(XDeviceMotionEvent *event)
{
int i,j;
GxidDevice *old_device = NULL;
GxidDevice *new_device = NULL;
Window w, root, child;
int root_x, root_y, x, y, mask;
for (j=0;j<num_devices;j++)
{
if (devices[j]->ispointer)
old_device = devices[j];
if (devices[j]->id == event->deviceid)
new_device = devices[j];
}
if (new_device && !new_device->exclusive && !new_device->ispointer)
{
/* make sure we aren't stealing the pointer back from a slow
client */
child = root_window;
do
{
w = child;
/* FIXME: this fails disasterously if child vanishes between
calls. (Which is prone to happening since we get events
on root just as the client exits) */
XQueryPointer(dpy,w,&root,&child,&root_x,&root_y,
&x,&y,&mask);
}
while (child != None);
for (i=0;i<num_windows;i++)
if (windows[i]->xwindow == w)
for (j=0;j<windows[i]->num_devices;j++)
if (windows[i]->devices[j] == new_device)
return;
/* FIXME: do something smarter with axes */
XChangePointerDevice(dpy,new_device->xdevice, 0, 1);
new_device->ispointer = 1;
old_device->ispointer = 0;
if (!old_device->xdevice)
enable_device(old_device);
}
}
void
handle_change_notify(XChangeDeviceNotifyEvent *event)
{
int j;
GxidDevice *old_device = NULL;
GxidDevice *new_device = NULL;
for (j=0;j<num_devices;j++)
{
if (devices[j]->ispointer)
old_device = devices[j];
if (devices[j]->id == event->deviceid)
new_device = devices[j];
}
#ifdef DEBUG_EVENTS
fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n",
old_device->id, new_device->id);
#endif
if (old_device != new_device)
{
new_device->ispointer = 1;
old_device->ispointer = 0;
if (!old_device->xdevice)
enable_device(old_device);
}
}
void
handle_enter_notify(XEnterWindowEvent *event, GxidWindow *window)
{
int i;
GxidDevice *old_pointer = NULL;
for (i=0;i<num_devices;i++)
{
if (devices[i]->ispointer)
{
old_pointer = devices[i];
break;
}
}
#ifdef DEBUG_EVENTS
fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n",
old_pointer->id);
#endif
if (old_pointer)
for (i=0;i<window->num_devices;i++)
{
if (window->devices[i] == old_pointer)
{
switch_core_pointer();
break;
}
}
}
void
handle_destroy_notify(XDestroyWindowEvent *event)
{
int i,j;
for (i=0;i<num_windows;i++)
if (windows[i]->xwindow == event->window)
{
GxidWindow *w = windows[i];
for (j=0;j<w->num_devices;j++)
{
#ifdef DEBUG_CLIENTS
fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n",
w->devices[j]->id,w->xwindow);
#endif
if (w->devices[j]->exclusive)
{
w->devices[j]->exclusive = 0;
enable_device(devices[j]);
}
}
if (i<num_windows-1)
windows[i] = windows[num_windows-1];
num_windows--;
if (w->devices)
free((void *)w->devices);
free((void *)w);
/* FIXME: should we deselect input? But what
what if window is already destroyed */
return;
}
}
void
handle_xevent(void)
{
int i;
XEvent event;
XNextEvent (dpy, &event);
#ifdef DEBUG_EVENTS
fprintf(stderr,"Event - type = %d; window = 0x%lx\n",
event.type,event.xany.window);
#endif
if (event.type == ConfigureNotify)
{
#ifdef DEBUG_EVENTS
XConfigureEvent *xce = (XConfigureEvent *)&event;
fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window);
#endif
}
else if (event.type == EnterNotify)
{
/* pointer entered a claimed window */
for (i=0;i<num_windows;i++)
{
if (event.xany.window == windows[i]->xwindow)
handle_enter_notify((XEnterWindowEvent *)&event,windows[i]);
}
}
else if (event.type == DestroyNotify)
{
/* A claimed window was destroyed */
for (i=0;i<num_windows;i++)
{
if (event.xany.window == windows[i]->xwindow)
handle_destroy_notify((XDestroyWindowEvent *)&event);
}
}
else
for (i=0;i<num_devices;i++)
{
if (event.type == devices[i]->motionnotify_type)
{
handle_motion_notify((XDeviceMotionEvent *)&event);
break;
}
else if (event.type == devices[i]->changenotify_type)
{
handle_change_notify((XChangeDeviceNotifyEvent *)&event);
break;
}
}
}
void
usage(void)
{
fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n",
program_name);
exit(1);
}
int
main(int argc, char **argv)
{
int i;
char *display_name = NULL;
fd_set readfds;
program_name = argv[0];
for (i=1;i<argc;i++)
{
if (!strcmp(argv[i],"-d"))
{
if (++i >= argc) usage();
display_name = argv[i];
}
else if (!strcmp(argv[i],"--gxid-port") ||
!strcmp(argv[i],"-p"))
{
if (++i >= argc) usage();
port = atoi(argv[i]);
break;
}
else
usage();
}
if (!port)
{
char *t = getenv("GXID_PORT");
if (t)
port = atoi(t);
else
port = 6951;
}
/* set up a signal handler so we can clean up if killed */
signal(SIGTERM,handler);
signal(SIGINT,handler);
/* initialize the X connection */
dpy = XOpenDisplay (display_name);
if (!dpy)
{
fprintf (stderr, "%s: unable to open display '%s'\n",
program_name, XDisplayName (display_name));
exit (1);
}
root_window = DefaultRootWindow(dpy);
/* We'll want to do this in the future if we are to support
gxid monitoring visibility information for clients */
#if 0
XSelectInput(dpy,root_window,SubstructureNotifyMask);
#endif
init_xinput();
/* set up our server connection */
init_socket();
/* main loop */
if (XPending(dpy)) /* this seems necessary to get things
in sync */
handle_xevent();
while (1)
{
FD_ZERO(&readfds);
FD_SET(ConnectionNumber(dpy),&readfds);
FD_SET(socket_fd,&readfds);
if (select(8*sizeof(readfds),&readfds,
(fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0)
{
fprintf(stderr,"Error in select\n");
exit(1);
}
if (FD_ISSET(socket_fd,&readfds))
handle_connection();
while (XPending(dpy))
handle_xevent();
}
XCloseDisplay (dpy);
exit (0);
}

View File

@ -1,110 +0,0 @@
/*
* gxid version 0.3
*
* Copyright 1997 Owen Taylor <owt1@cornell.edu>
*/
#include "config.h"
#include "gxid_lib.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
/* handles mechanics of communicating with a client */
static int
gxid_send_message(char *host, int port, GxidMessage *msg)
{
int socket_fd;
struct sockaddr_in sin;
int count;
GxidI32 retval;
struct hostent *he;
if (!port) port = 6951;
if (!host || strcmp(host,"localhost") )
{
/* looking it up as localhost can be _SLOW_ on ppp systems */
/* FIXME: Could localhost be anything other than loopback? */
host = "127.0.0.1";
}
he = gethostbyname(host);
if (!he)
{
fprintf(stderr,"gxid_lib: error looking up %s\n",host);
return GXID_RETURN_ERROR;
}
sin.sin_family = he->h_addrtype;
sin.sin_port = htons(port);
memcpy(&sin.sin_addr,he->h_addr_list[0],he->h_length);
socket_fd = socket(AF_INET,SOCK_STREAM,0);
if (socket_fd < 0)
{
fprintf(stderr,"gxid_lib: can't get socket");
return GXID_RETURN_ERROR;
}
if (connect(socket_fd, (struct sockaddr *)&sin,
sizeof sin) < 0)
{
fprintf(stderr,"gxid_lib: can't connect to %s:%d\n",host,port);
close(socket_fd);
return GXID_RETURN_ERROR;
}
count = write(socket_fd,(char *)msg,ntohl(msg->any.length));
if (count != ntohl(msg->any.length))
{
fprintf(stderr,"gxid_lib: error writing");
close(socket_fd);
return GXID_RETURN_ERROR;
}
/* now read the return code */
count = read(socket_fd,(char *)&retval,sizeof(GxidI32));
if (count != sizeof(GxidI32))
{
fprintf(stderr,"gxid_lib: error reading return code");
close(socket_fd);
return GXID_RETURN_ERROR;
}
close (socket_fd);
return ntohl(retval);
}
/* claim a device. If exclusive, device is claimed exclusively */
int
_gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window,
int exclusive)
{
GxidClaimDevice msg;
msg.type = htonl(GXID_CLAIM_DEVICE);
msg.length = htonl(sizeof(GxidClaimDevice));
msg.device = htonl(device);
msg.window = htonl(window);
msg.exclusive = htonl(exclusive);
return gxid_send_message(host,port,(GxidMessage *)&msg);
}
/* release a device/window pair */
int
_gxid_release_device(char *host, int port, GxidU32 device, GxidU32 window)
{
GxidReleaseDevice msg;
msg.type = htonl(GXID_RELEASE_DEVICE);
msg.length = htonl(sizeof(GxidReleaseDevice));
msg.device = htonl(device);
msg.window = htonl(window);
return gxid_send_message(host,port,(GxidMessage *)&msg);
}

View File

@ -1,6 +0,0 @@
#include "gxid_proto.h"
int _gxid_claim_device(char *host, int port,
GxidU32 device, GxidU32 window, int exclusive);
int _gxid_release_device(char *host, int port, GxidU32 device,
GxidU32 window);

View File

@ -1036,9 +1036,11 @@ gtk_main_iteration_do (gboolean blocking)
/* private libgtk to libgdk interfaces
*/
gboolean gdk_pointer_grab_info_libgtk_only (GdkWindow **grab_window,
gboolean gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
GdkWindow **grab_window,
gboolean *owner_events);
gboolean gdk_keyboard_grab_info_libgtk_only (GdkWindow **grab_window,
gboolean gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
GdkWindow **grab_window,
gboolean *owner_events);
static void
@ -1123,14 +1125,14 @@ rewrite_event_for_grabs (GdkEvent *event)
case GDK_MOTION_NOTIFY:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
if (!gdk_pointer_grab_info_libgtk_only (&grab_window, &owner_events) ||
if (!gdk_pointer_grab_info_libgtk_only (gdk_get_default_display(), &grab_window, &owner_events) ||
!owner_events)
return NULL;
break;
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
if (!gdk_keyboard_grab_info_libgtk_only (&grab_window, &owner_events) ||
if (!gdk_keyboard_grab_info_libgtk_only (gdk_get_default_display(), &grab_window, &owner_events) ||
!owner_events)
return NULL;
break;