gdkpixmap-x11.c 9.28 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 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 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
15
16
17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18
 */
19
20
21
22
23
24
25
26

/*
 * Modified by the GTK+ Team and others 1997-1999.  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/. 
 */

27
#include "config.h"
Elliot Lee's avatar
Elliot Lee committed
28
29
30
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
31
32
/* Needed for SEEK_END in SunOS */
#include <unistd.h>
Elliot Lee's avatar
Elliot Lee committed
33
34
#include <X11/Xlib.h>

35
36
#include <gdk/gdkpixmap.h>
#include "gdkpixmap-x11.h"
37
#include "gdkprivate-x11.h"
Elliot Lee's avatar
Elliot Lee committed
38
39
40
41
42
43
44
45

typedef struct
{
  gchar *color_string;
  GdkColor color;
  gint transparent;
} _GdkPixmapColor;

46
47
48
49
50
51
52
typedef struct
{
  guint ncolors;
  GdkColormap *colormap;
  gulong pixels[1];
} _GdkPixmapInfo;

53
54
55
static void gdk_pixmap_impl_x11_get_size   (GdkDrawable        *drawable,
                                        gint               *width,
                                        gint               *height);
56

57
58
59
static void gdk_pixmap_impl_x11_init       (GdkPixmapImplX11      *pixmap);
static void gdk_pixmap_impl_x11_class_init (GdkPixmapImplX11Class *klass);
static void gdk_pixmap_impl_x11_finalize   (GObject            *object);
60

61
static gpointer parent_class = NULL;
62

63
64
GType
gdk_pixmap_impl_x11_get_type (void)
65
{
66
  static GType object_type = 0;
67

68
  if (!object_type)
69
    {
70
71
72
73
74
75
76
77
78
79
80
81
      static const GTypeInfo object_info =
      {
        sizeof (GdkPixmapImplX11Class),
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc) gdk_pixmap_impl_x11_class_init,
        NULL,           /* class_finalize */
        NULL,           /* class_data */
        sizeof (GdkPixmapImplX11),
        0,              /* n_preallocs */
        (GInstanceInitFunc) gdk_pixmap_impl_x11_init,
      };
82
      
83
84
85
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
                                            "GdkPixmapImplX11",
                                            &object_info);
86
    }
87
88
89
  
  return object_type;
}
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
GType
_gdk_pixmap_impl_get_type (void)
{
  return gdk_pixmap_impl_x11_get_type ();
}

static void
gdk_pixmap_impl_x11_init (GdkPixmapImplX11 *impl)
{
  impl->width = 1;
  impl->height = 1;
}

static void
gdk_pixmap_impl_x11_class_init (GdkPixmapImplX11Class *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
  
  parent_class = g_type_class_peek_parent (klass);

  object_class->finalize = gdk_pixmap_impl_x11_finalize;

  drawable_class->get_size = gdk_pixmap_impl_x11_get_size;
}

static void
gdk_pixmap_impl_x11_finalize (GObject *object)
{
  GdkPixmapImplX11 *impl = GDK_PIXMAP_IMPL_X11 (object);
  GdkPixmap *wrapper = GDK_PIXMAP (GDK_DRAWABLE_IMPL_X11 (impl)->wrapper);
123
124
125

  if (!impl->is_foreign)
    XFreePixmap (GDK_PIXMAP_XDISPLAY (wrapper), GDK_PIXMAP_XID (wrapper));
126
127
128
129
130
  
  gdk_xid_table_remove (GDK_PIXMAP_XID (wrapper));
  
  G_OBJECT_CLASS (parent_class)->finalize (object);
}
131

132
133
134
135
136
137
138
139
140
static void
gdk_pixmap_impl_x11_get_size   (GdkDrawable *drawable,
                                gint        *width,
                                gint        *height)
{
  if (width)
    *width = GDK_PIXMAP_IMPL_X11 (drawable)->width;
  if (height)
    *height = GDK_PIXMAP_IMPL_X11 (drawable)->height;
141
142
}

Elliot Lee's avatar
Elliot Lee committed
143
144
145
146
147
148
149
GdkPixmap*
gdk_pixmap_new (GdkWindow *window,
		gint       width,
		gint       height,
		gint       depth)
{
  GdkPixmap *pixmap;
150
151
152
  GdkDrawableImplX11 *draw_impl;
  GdkPixmapImplX11 *pix_impl;
  
153
  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
154
  g_return_val_if_fail ((window != NULL) || (depth != -1), NULL);
155
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
156
  
Elliot Lee's avatar
Elliot Lee committed
157
  if (!window)
158
    window = gdk_parent_root;
Elliot Lee's avatar
Elliot Lee committed
159

160
  if (GDK_WINDOW_DESTROYED (window))
161
162
    return NULL;

Elliot Lee's avatar
Elliot Lee committed
163
  if (depth == -1)
164
    depth = gdk_drawable_get_depth (GDK_DRAWABLE (window));
Elliot Lee's avatar
Elliot Lee committed
165

166
167
168
169
170
171
172
173
174
175
  pixmap = GDK_PIXMAP (g_type_create_instance (gdk_pixmap_get_type ()));
  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_WINDOW_XDISPLAY (window);
  draw_impl->xid = XCreatePixmap (GDK_PIXMAP_XDISPLAY (pixmap),
                                  GDK_WINDOW_XID (window),
                                  width, height, depth);
  
176
  pix_impl->is_foreign = FALSE;
177
178
179
  pix_impl->width = width;
  pix_impl->height = height;
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
180
  
181
  gdk_xid_table_insert (&GDK_PIXMAP_XID (pixmap), pixmap);
Elliot Lee's avatar
Elliot Lee committed
182
183
184
185
186

  return pixmap;
}

GdkPixmap *
Owen Taylor's avatar
Owen Taylor committed
187
188
189
190
gdk_bitmap_create_from_data (GdkWindow   *window,
			     const gchar *data,
			     gint         width,
			     gint         height)
Elliot Lee's avatar
Elliot Lee committed
191
192
{
  GdkPixmap *pixmap;
193
194
195
  GdkDrawableImplX11 *draw_impl;
  GdkPixmapImplX11 *pix_impl;
  
Elliot Lee's avatar
Elliot Lee committed
196
  g_return_val_if_fail (data != NULL, NULL);
197
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
198
  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
Elliot Lee's avatar
Elliot Lee committed
199
200

  if (!window)
201
    window = gdk_parent_root;
Elliot Lee's avatar
Elliot Lee committed
202

203
  if (GDK_WINDOW_DESTROYED (window))
204
205
    return NULL;

206
207
208
209
  pixmap = GDK_PIXMAP (g_type_create_instance (gdk_pixmap_get_type ()));
  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);
Elliot Lee's avatar
Elliot Lee committed
210

211
  pix_impl->is_foreign = FALSE;
212
213
214
  pix_impl->width = width;
  pix_impl->height = height;
  GDK_PIXMAP_OBJECT (pixmap)->depth = 1;
Elliot Lee's avatar
Elliot Lee committed
215

216
217
218
219
  draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (window);
  draw_impl->xid = XCreateBitmapFromData (GDK_WINDOW_XDISPLAY (window),
                                          GDK_WINDOW_XID (window),
                                          (char *)data, width, height);
Elliot Lee's avatar
Elliot Lee committed
220

221
222
  gdk_xid_table_insert (&GDK_PIXMAP_XID (pixmap), pixmap);
  
Elliot Lee's avatar
Elliot Lee committed
223
224
225
226
  return pixmap;
}

GdkPixmap*
Owen Taylor's avatar
Owen Taylor committed
227
228
229
230
231
232
233
gdk_pixmap_create_from_data (GdkWindow   *window,
			     const gchar *data,
			     gint         width,
			     gint         height,
			     gint         depth,
			     GdkColor    *fg,
			     GdkColor    *bg)
Elliot Lee's avatar
Elliot Lee committed
234
235
{
  GdkPixmap *pixmap;
236
237
  GdkDrawableImplX11 *draw_impl;
  GdkPixmapImplX11 *pix_impl;
Elliot Lee's avatar
Elliot Lee committed
238

239
  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
Elliot Lee's avatar
Elliot Lee committed
240
241
242
  g_return_val_if_fail (data != NULL, NULL);
  g_return_val_if_fail (fg != NULL, NULL);
  g_return_val_if_fail (bg != NULL, NULL);
243
  g_return_val_if_fail ((window != NULL) || (depth != -1), NULL);
244
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Elliot Lee's avatar
Elliot Lee committed
245
246

  if (!window)
247
    window = gdk_parent_root;
Elliot Lee's avatar
Elliot Lee committed
248

249
  if (GDK_WINDOW_DESTROYED (window))
250
251
    return NULL;

Elliot Lee's avatar
Elliot Lee committed
252
  if (depth == -1)
253
    depth = gdk_drawable_get_visual (window)->depth;
Elliot Lee's avatar
Elliot Lee committed
254

255
256
257
258
259
  pixmap = GDK_PIXMAP (g_type_create_instance (gdk_pixmap_get_type ()));
  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);
  
260
  pix_impl->is_foreign = FALSE;
261
262
263
  pix_impl->width = width;
  pix_impl->height = height;
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
Elliot Lee's avatar
Elliot Lee committed
264

265
266
267
268
269
  draw_impl->xdisplay = GDK_DRAWABLE_XDISPLAY (window);
  draw_impl->xid = XCreatePixmapFromBitmapData (GDK_WINDOW_XDISPLAY (window),
                                                GDK_WINDOW_XID (window),
                                                (char *)data, width, height,
                                                fg->pixel, bg->pixel, depth);
Elliot Lee's avatar
Elliot Lee committed
270

271
  gdk_xid_table_insert (&GDK_PIXMAP_XID (pixmap), pixmap);
Elliot Lee's avatar
Elliot Lee committed
272
273
274
275

  return pixmap;
}

276
GdkPixmap*
Elliot Lee's avatar
Elliot Lee committed
277
gdk_pixmap_foreign_new (GdkNativeWindow anid)
278
279
{
  GdkPixmap *pixmap;
280
281
  GdkDrawableImplX11 *draw_impl;
  GdkPixmapImplX11 *pix_impl;
282
283
284
285
286
287
288
289
290
291
292
293
294
  Pixmap xpixmap;
  Window root_return;
  unsigned int x_ret, y_ret, w_ret, h_ret, bw_ret, depth_ret;

  /* check to make sure we were passed something at
     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 */
295
296
  if (!XGetGeometry(GDK_DISPLAY(),
		    xpixmap, &root_return,
297
298
		    &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
      return NULL;
299

300
301
302
303
304
305
306
307
  pixmap = GDK_PIXMAP (g_type_create_instance (gdk_pixmap_get_type ()));
  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->xid = xpixmap;
308

309
  pix_impl->is_foreign = TRUE;
310
311
312
  pix_impl->width = w_ret;
  pix_impl->height = h_ret;
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth_ret;
313
  
314
  gdk_xid_table_insert(&GDK_PIXMAP_XID (pixmap), pixmap);
315
316
317

  return pixmap;
}