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

@ -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;
}