ROOT  6.05/03
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
gdkpixmap-win32.c
Go to the documentation of this file.
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-1999 Tor Lillqvist
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 /*
22  * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
23  * file for a list of people on the GTK+ Team. See the ChangeLog
24  * files for a list of changes. These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26  */
27 
28 #include "config.h"
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 
34 #include "gdkpixmap.h"
35 #include "gdkprivate.h"
36 #include "gdkwin32.h"
37 
38 typedef struct {
39  gchar *color_string;
40  GdkColor color;
41  gint transparent;
42 } _GdkPixmapColor;
43 
44 typedef struct {
45  guint ncolors;
46  GdkColormap *colormap;
47  gulong pixels[1];
48 } _GdkPixmapInfo;
49 
50 static void gdk_win32_pixmap_destroy(GdkPixmap * pixmap)
51 {
52  GdkDrawablePrivate *private = (GdkDrawablePrivate *) pixmap;
53 
54  GDK_NOTE(MISC, g_print("gdk_win32_pixmap_destroy: %#x\n",
55  GDK_DRAWABLE_XID(pixmap)));
56 
57  if (!DeleteObject(GDK_DRAWABLE_XID(pixmap)))
58  WIN32_GDI_FAILED("DeleteObject");
59 
61 
63 }
64 
66 {
67  GdkDrawable *drawable;
68  GdkDrawablePrivate *private;
69 
70  static GdkDrawableClass klass;
71  static gboolean initialized = FALSE;
72 
73  if (!initialized) {
74  initialized = TRUE;
75 
78  }
79 
80  drawable = gdk_drawable_alloc();
81  private = (GdkDrawablePrivate *) drawable;
82 
83  private->klass = &klass;
84  private->klass_data = g_new(GdkDrawableWin32Data, 1);
85  private->window_type = GDK_DRAWABLE_PIXMAP;
86 
87  return drawable;
88 }
89 
91  gint width, gint height, gint depth)
92 {
93  GdkPixmap *pixmap;
94  GdkDrawablePrivate *private;
95  struct {
96  BITMAPINFOHEADER bmiHeader;
97  union {
98  WORD bmiIndices[256];
99  DWORD bmiMasks[3];
100  RGBQUAD bmiColors[256];
101  } u;
102  } bmi;
103  UINT iUsage;
104  HDC hdc;
105  GdkVisual *visual;
106  guchar *bits;
107  gint i;
108 
109  g_return_val_if_fail(window == NULL || GDK_IS_WINDOW(window), NULL);
110  g_return_val_if_fail((window != NULL) || (depth != -1), NULL);
111  g_return_val_if_fail((width != 0) && (height != 0), NULL);
112 
113  if (!window)
114  window = gdk_parent_root;
115 
116  if (GDK_DRAWABLE_DESTROYED(window))
117  return NULL;
118 
119  if (depth == -1)
120  depth = gdk_drawable_get_visual(window)->depth;
121 
122  GDK_NOTE(MISC, g_print("gdk_pixmap_new: %dx%dx%d\n",
123  width, height, depth));
124 
125  pixmap = gdk_win32_pixmap_alloc();
126  private = (GdkDrawablePrivate *) pixmap;
127 
128  visual = gdk_drawable_get_visual(window);
129 
130  if ((hdc = GetDC(GDK_DRAWABLE_XID(window))) == NULL) {
131  WIN32_GDI_FAILED("GetDC");
132  g_free(private);
133  return NULL;
134  }
135 
136  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
137  bmi.bmiHeader.biWidth = width;
138  bmi.bmiHeader.biHeight = -height;
139  bmi.bmiHeader.biPlanes = 1;
140  if (depth == 15)
141  bmi.bmiHeader.biBitCount = 16;
142  else
143  bmi.bmiHeader.biBitCount = depth;
144 #if 1
145  if (depth == 16)
146  bmi.bmiHeader.biCompression = BI_BITFIELDS;
147  else
148 #endif
149  bmi.bmiHeader.biCompression = BI_RGB;
150  bmi.bmiHeader.biSizeImage = 0;
151  bmi.bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter = 0;
152  bmi.bmiHeader.biClrUsed = 0;
153  bmi.bmiHeader.biClrImportant = 0;
154 
155  iUsage = DIB_RGB_COLORS;
156  if (depth == 1) {
157  bmi.u.bmiColors[0].rgbBlue =
158  bmi.u.bmiColors[0].rgbGreen = bmi.u.bmiColors[0].rgbRed = 0x00;
159  bmi.u.bmiColors[0].rgbReserved = 0x00;
160 
161  bmi.u.bmiColors[1].rgbBlue =
162  bmi.u.bmiColors[1].rgbGreen = bmi.u.bmiColors[1].rgbRed = 0xFF;
163  bmi.u.bmiColors[1].rgbReserved = 0x00;
164  private->colormap = NULL;
165  } else {
166  private->colormap = ((GdkWindowPrivate *) window)->drawable.colormap;
167  if (private->colormap == NULL)
168  private->colormap = gdk_colormap_get_system();
169 
170  if (depth == 8) {
171  iUsage = DIB_PAL_COLORS;
172  for (i = 0; i < 256; i++)
173  bmi.u.bmiIndices[i] = i;
174  } else {
175  if (depth != visual->depth)
176  g_warning
177  ("gdk_pixmap_new: depth %d doesn't match display depth %d",
178  depth, visual->depth);
179 #if 1
180  if (depth == 16) {
181  bmi.u.bmiMasks[0] = visual->red_mask;
182  bmi.u.bmiMasks[1] = visual->green_mask;
183  bmi.u.bmiMasks[2] = visual->blue_mask;
184  }
185 #endif
186  }
187  }
188  if ((GDK_DRAWABLE_WIN32DATA(pixmap)->xid =
189  CreateDIBSection(hdc, (BITMAPINFO *) & bmi,
190  iUsage, (PVOID *) & bits, NULL, 0)) == NULL) {
191  WIN32_GDI_FAILED("CreateDIBSection");
192  ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
193  g_free(pixmap);
194  return NULL;
195  }
196  ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
197 
198  GDK_NOTE(MISC, g_print("... = %#x\n", GDK_DRAWABLE_XID(pixmap)));
199 
200  private->width = width;
201  private->height = height;
202 
203  gdk_xid_table_insert(&GDK_DRAWABLE_XID(pixmap), pixmap);
204 
205  return pixmap;
206 }
207 
209  GdkWindow * window,
210  GdkVisual * visual,
211  gint width,
212  gint height, gint depth)
213 {
214  GdkPixmap *pixmap;
215  GdkDrawablePrivate *private;
216 
217  g_return_val_if_fail(window != NULL, NULL);
218 
219 
220  if (depth == 1)
221  *image_return =
223  height);
224  else {
225  g_return_val_if_fail(depth == visual->depth, NULL);
226  *image_return =
227  gdk_image_new(GDK_IMAGE_SHARED_PIXMAP, visual, width, height);
228  }
229 
230  g_return_val_if_fail(*image_return != NULL, NULL);
231 
232  pixmap = gdk_win32_pixmap_alloc();
233  private = (GdkDrawablePrivate *) pixmap;
234 
235  GDK_DRAWABLE_WIN32DATA(pixmap)->xid =
236  ((GdkImagePrivateWin32 *) * image_return)->ximage;
237  private->colormap = ((GdkWindowPrivate *) window)->drawable.colormap;
238  private->width = width;
239  private->height = height;
240 
241  gdk_xid_table_insert(&GDK_DRAWABLE_XID(pixmap), pixmap);
242 
243  GDK_NOTE(MISC,
244  g_print("gdk_pixmap_create_on_shared_image: %dx%dx%d = %#x\n",
245  width, height, depth, GDK_DRAWABLE_XID(pixmap)));
246 
247  return pixmap;
248 }
249 
250 static unsigned char mirror[256] = {
251  0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
252  0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
253  0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
254  0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
255  0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
256  0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
257  0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
258  0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
259  0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
260  0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
261  0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
262  0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
263  0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
264  0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
265  0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
266  0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
267  0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
268  0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
269  0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
270  0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
271  0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
272  0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
273  0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
274  0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
275  0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
276  0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
277  0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
278  0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
279  0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
280  0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
281  0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
282  0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
283 };
284 
286  const gchar * data,
287  gint width, gint height)
288 {
289  GdkPixmap *pixmap;
290  GdkDrawablePrivate *private;
291  gint i, j, bpl, aligned_bpl;
292  guchar *bits;
293 
294  g_return_val_if_fail(data != NULL, NULL);
295  g_return_val_if_fail((width != 0) && (height != 0), NULL);
296  g_return_val_if_fail(window == NULL || GDK_IS_WINDOW(window), NULL);
297 
298  if (!window)
299  window = gdk_parent_root;
300 
301  if (GDK_DRAWABLE_DESTROYED(window))
302  return NULL;
303 
304  pixmap = gdk_win32_pixmap_alloc();
305  private = (GdkDrawablePrivate *) pixmap;
306 
307  private->width = width;
308  private->height = height;
309 
310  bpl = ((width - 1) / 8 + 1);
311  aligned_bpl = ((bpl - 1) / 2 + 1) * 2;
312  bits = g_malloc(aligned_bpl * height);
313  for (i = 0; i < height; i++)
314  for (j = 0; j < bpl; j++)
315  bits[i * aligned_bpl + j] = mirror[(guchar) data[i * bpl + j]];
316 
317  GDK_DRAWABLE_WIN32DATA(pixmap)->xid =
318  CreateBitmap(width, height, 1, 1, bits);
319 
320  GDK_NOTE(MISC, g_print("gdk_bitmap_create_from_data: %dx%d = %#x\n",
321  width, height, GDK_DRAWABLE_XID(pixmap)));
322 
323  g_free(bits);
324 
325  private->colormap = NULL;
326  gdk_xid_table_insert(&GDK_DRAWABLE_XID(pixmap), pixmap);
327 
328  return pixmap;
329 }
330 
332  const gchar * data,
333  gint width,
334  gint height,
335  gint depth,
336  GdkColor * fg, GdkColor * bg)
337 {
338  /* Oh wow. I struggled with dozens of lines of code trying to get
339  * this right using a monochrome Win32 bitmap created from data, and
340  * a colour DIB section as the result, trying setting pens,
341  * background colors, whatnot and BitBlt:ing. Nope. Then finally I
342  * realized it's much easier to do it using gdk...:
343  */
344 
345  GdkPixmap *result = gdk_pixmap_new(window, width, height, depth);
346  GdkPixmap *source =
347  gdk_bitmap_create_from_data(window, data, width, height);
348  GdkGC *gc = gdk_gc_new(result);
349  gdk_gc_set_foreground(gc, fg);
350  gdk_gc_set_background(gc, bg);
351  gdk_draw_drawable(result, gc, source, 0, 0, 0, 0, width, height);
352  gdk_drawable_unref(source);
353  gdk_gc_unref(gc);
354 
355  GDK_NOTE(MISC, g_print("gdk_pixmap_create_from_data: %dx%dx%d = %#x\n",
356  width, height, depth, GDK_DRAWABLE_XID(result)));
357  return result;
358 }
359 
360 static gint
362  const gchar * str, gint skip_comments)
363 {
364  char instr[1024];
365 
366  while (!feof(infile)) {
367  fscanf(infile, "%1023s", instr);
368  if (skip_comments == TRUE && strcmp(instr, "/*") == 0) {
369  fscanf(infile, "%1023s", instr);
370  while (!feof(infile) && strcmp(instr, "*/") != 0)
371  fscanf(infile, "%1023s", instr);
372  fscanf(infile, "%1023s", instr);
373  }
374  if (strcmp(instr, str) == 0)
375  return TRUE;
376  }
377 
378  return FALSE;
379 }
380 
381 static gint gdk_pixmap_seek_char(FILE * infile, gchar c)
382 {
383  gint b, oldb;
384 
385  while ((b = getc(infile)) != EOF) {
386  if (c != b && b == '/') {
387  b = getc(infile);
388  if (b == EOF)
389  return FALSE;
390  else if (b == '*') { /* we have a comment */
391  b = -1;
392  do {
393  oldb = b;
394  b = getc(infile);
395  if (b == EOF)
396  return FALSE;
397  }
398  while (!(oldb == '*' && b == '/'));
399  }
400  } else if (c == b)
401  return TRUE;
402  }
403  return FALSE;
404 }
405 
406 static gint
407 gdk_pixmap_read_string(FILE * infile, gchar ** buffer, guint * buffer_size)
408 {
409  gint c;
410  guint cnt = 0, bufsiz, ret = FALSE;
411  gchar *buf;
412 
413  buf = *buffer;
414  bufsiz = *buffer_size;
415  if (buf == NULL) {
416  bufsiz = 10 * sizeof(gchar);
417  buf = g_new(gchar, bufsiz);
418  }
419 
420  do
421  c = getc(infile);
422  while (c != EOF && c != '"');
423 
424  if (c != '"')
425  goto out;
426 
427  while ((c = getc(infile)) != EOF) {
428  if (cnt == bufsiz) {
429  guint new_size = bufsiz * 2;
430  if (new_size > bufsiz)
431  bufsiz = new_size;
432  else
433  goto out;
434 
435  buf = (gchar *) g_realloc(buf, bufsiz);
436  buf[bufsiz - 1] = '\0';
437  }
438 
439  if (c != '"')
440  buf[cnt++] = c;
441  else {
442  buf[cnt] = 0;
443  ret = TRUE;
444  break;
445  }
446  }
447 
448  out:
449  buf[bufsiz - 1] = '\0'; /* ensure null termination for errors */
450  *buffer = buf;
451  *buffer_size = bufsiz;
452  return ret;
453 }
454 
456 {
457  gint32 index = 0;
458 
459  while (buffer[index] != 0
460  && (buffer[index] == 0x20 || buffer[index] == 0x09))
461  index++;
462 
463  return &buffer[index];
464 }
465 
467 {
468  gint32 index = 0;
469 
470  while (buffer[index] != 0 && buffer[index] != 0x20
471  && buffer[index] != 0x09)
472  index++;
473 
474  return &buffer[index];
475 }
476 
477 #define MAX_COLOR_LEN 120
478 
480 {
481  gint counter, numnames;
482  gchar *ptr = NULL, ch, temp[128];
483  gchar color[MAX_COLOR_LEN], *retcol;
484  gint space;
485 
486  counter = 0;
487  while (ptr == NULL) {
488  if (buffer[counter] == 'c') {
489  ch = buffer[counter + 1];
490  if (ch == 0x20 || ch == 0x09)
491  ptr = &buffer[counter + 1];
492  } else if (buffer[counter] == 0)
493  return NULL;
494 
495  counter++;
496  }
497 
498  ptr = gdk_pixmap_skip_whitespaces(ptr);
499 
500  if (ptr[0] == 0)
501  return NULL;
502  else if (ptr[0] == '#') {
503  counter = 1;
504  while (ptr[counter] != 0 &&
505  ((ptr[counter] >= '0' && ptr[counter] <= '9') ||
506  (ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
507  (ptr[counter] >= 'A' && ptr[counter] <= 'F')))
508  counter++;
509 
510  retcol = g_new(gchar, counter + 1);
511  strncpy(retcol, ptr, counter);
512 
513  retcol[counter] = 0;
514 
515  return retcol;
516  }
517 
518  color[0] = 0;
519  numnames = 0;
520 
521  space = MAX_COLOR_LEN - 1;
522  while (space > 0) {
523  sscanf(ptr, "%127s", temp);
524 
525  if (((gint) ptr[0] == 0) ||
526  (strcmp("s", temp) == 0) || (strcmp("m", temp) == 0) ||
527  (strcmp("g", temp) == 0) || (strcmp("g4", temp) == 0)) {
528  break;
529  } else {
530  if (numnames > 0) {
531  space -= 1;
532  strcat(color, " ");
533  }
534  strncat(color, temp, space);
535  space -= MIN(space, (gint)strlen(temp));
536  ptr = gdk_pixmap_skip_string(ptr);
537  ptr = gdk_pixmap_skip_whitespaces(ptr);
538  numnames++;
539  }
540  }
541 
542  retcol = g_strdup(color);
543  return retcol;
544 }
545 
546 
547 enum buffer_op {
551 };
552 
553 
555 {
556  _GdkPixmapInfo *info = (_GdkPixmapInfo *) data;
557  GdkColor color;
558  guint i;
559 
560  for (i = 0; i < info->ncolors; i++) {
561  color.pixel = info->pixels[i];
562  gdk_colormap_free_colors(info->colormap, &color, 1);
563  }
564 
565  gdk_colormap_unref(info->colormap);
566  g_free(info);
567 }
568 
570  GdkColormap * colormap,
571  GdkBitmap ** mask,
572  GdkColor * transparent_color,
573  gchar *
574  (*get_buf) (enum buffer_op
575  op,
576  gpointer handle),
577  gpointer handle)
578 {
579  GdkPixmap *pixmap = NULL;
580  GdkImage *image = NULL;
581  GdkVisual *visual;
582  GdkGC *gc = NULL;
583  GdkColor tmp_color;
584  gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
585  gchar *buffer, pixel_str[32];
586  gchar *name_buf;
587  _GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
588  _GdkPixmapColor *colors = NULL;
589  gulong index;
590  GHashTable *color_hash = NULL;
591  _GdkPixmapInfo *color_info = NULL;
592 
593  if ((window == NULL) && (colormap == NULL))
594  g_warning("Creating pixmap from xpm with NULL window and colormap");
595 
596  if (window == NULL)
597  window = gdk_parent_root;
598 
599  if (colormap == NULL) {
600  colormap = gdk_drawable_get_colormap(window);
601  visual = gdk_drawable_get_visual(window);
602  } else
603  visual = ((GdkColormapPrivate *) colormap)->visual;
604 
605  buffer = (*get_buf) (op_header, handle);
606  if (buffer == NULL)
607  return NULL;
608 
609  sscanf(buffer, "%d %d %d %d", &width, &height, &num_cols, &cpp);
610  if (cpp >= 32) {
611  g_warning("Pixmap has more than 31 characters per color");
612  return NULL;
613  }
614 
615  color_hash = g_hash_table_new(g_str_hash, g_str_equal);
616 
617  if (transparent_color == NULL) {
618  gdk_color_white(colormap, &tmp_color);
619  transparent_color = &tmp_color;
620  }
621 
622  /* For pseudo-color and grayscale visuals, we have to remember
623  * the colors we allocated, so we can free them later.
624  */
625  if ((visual->type == GDK_VISUAL_PSEUDO_COLOR) ||
626  (visual->type == GDK_VISUAL_GRAYSCALE)) {
627  color_info = g_malloc(sizeof(_GdkPixmapInfo) +
628  sizeof(gulong) * (num_cols - 1));
629  color_info->ncolors = num_cols;
630  color_info->colormap = colormap;
631  gdk_colormap_ref(colormap);
632  }
633 
634  name_buf = g_new(gchar, num_cols * (cpp + 1));
635  colors = g_new(_GdkPixmapColor, num_cols);
636 
637  for (cnt = 0; cnt < num_cols; cnt++) {
638  gchar *color_name;
639 
640  buffer = (*get_buf) (op_cmap, handle);
641  if (buffer == NULL)
642  goto error;
643 
644  color = &colors[cnt];
645  color->color_string = &name_buf[cnt * (cpp + 1)];
646  strncpy(color->color_string, buffer, cpp);
647  color->color_string[cpp] = 0;
648  buffer += strlen(color->color_string);
649  color->transparent = FALSE;
650 
651  color_name = gdk_pixmap_extract_color(buffer);
652 
653  if (color_name == NULL ||
654  gdk_color_parse(color_name, &color->color) == FALSE) {
655  color->color = *transparent_color;
656  color->transparent = TRUE;
657  }
658 
659  g_free(color_name);
660 
661  /* FIXME: The remaining slowness appears to happen in this
662  function. */
663  gdk_color_alloc(colormap, &color->color);
664 
665  if (color_info)
666  color_info->pixels[cnt] = color->color.pixel;
667 
668  g_hash_table_insert(color_hash, color->color_string, color);
669  if (cnt == 0)
670  fallbackcolor = color;
671  }
672 
673  index = 0;
674  image = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height);
675 
676  if (mask) {
677  /* The pixmap mask is just a bits pattern.
678  * Color 0 is used for background and 1 for foreground.
679  * We don't care about the colormap, we just need 0 and 1.
680  */
681  GdkColor mask_pattern;
682 
683  *mask = gdk_pixmap_new(window, width, height, 1);
684  gc = gdk_gc_new(*mask);
685 
686  mask_pattern.pixel = 0;
687  gdk_gc_set_foreground(gc, &mask_pattern);
688  gdk_draw_rectangle(*mask, gc, TRUE, 0, 0, -1, -1);
689 
690  mask_pattern.pixel = 1;
691  gdk_gc_set_foreground(gc, &mask_pattern);
692  }
693 
694  wbytes = width * cpp;
695  for (ycnt = 0; ycnt < height; ycnt++) {
696  buffer = (*get_buf) (op_body, handle);
697 
698  /* FIXME: this slows things down a little - it could be
699  * integrated into the strncpy below, perhaps. OTOH, strlen
700  * is fast.
701  */
702  if ((buffer == NULL) || (gint)strlen(buffer) < wbytes)
703  continue;
704 
705  for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) {
706  strncpy(pixel_str, &buffer[n], cpp);
707  pixel_str[cpp] = 0;
708  ns = 0;
709 
710  color = g_hash_table_lookup(color_hash, pixel_str);
711 
712  if (!color) /* screwed up XPM file */
713  color = fallbackcolor;
714 
715  gdk_image_put_pixel(image, xcnt, ycnt, color->color.pixel);
716 
717  if (mask && color->transparent) {
718  if (cnt < xcnt)
719  gdk_draw_line(*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
720  cnt = xcnt + 1;
721  }
722  }
723 
724  if (mask && (cnt < xcnt))
725  gdk_draw_line(*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
726  }
727 
728  error:
729 
730  if (mask)
731  gdk_gc_unref(gc);
732 
733  if (image != NULL) {
734  pixmap = gdk_pixmap_new(window, width, height, visual->depth);
735 
736  if (color_info)
737  gdk_drawable_set_data(pixmap, "gdk-xpm", color_info,
739 
740  gc = gdk_gc_new(pixmap);
741  gdk_gc_set_foreground(gc, transparent_color);
742  gdk_draw_image(pixmap, gc, image, 0, 0, 0, 0, image->width,
743  image->height);
744  gdk_gc_unref(gc);
745  gdk_image_unref(image);
746  } else if (color_info)
747  gdk_xpm_destroy_notify(color_info);
748 
749  if (color_hash != NULL)
750  g_hash_table_destroy(color_hash);
751 
752  if (colors != NULL)
753  g_free(colors);
754 
755  if (name_buf != NULL)
756  g_free(name_buf);
757 
758  return pixmap;
759 }
760 
761 
762 struct file_handle {
763  FILE *infile;
764  gchar *buffer;
765  guint buffer_size;
766 };
767 
768 
769 static gchar *file_buffer(enum buffer_op op, gpointer handle)
770 {
771  struct file_handle *h = handle;
772 
773  switch (op) {
774  case op_header:
775  if (gdk_pixmap_seek_string(h->infile, "XPM", FALSE) != TRUE)
776  break;
777 
778  if (gdk_pixmap_seek_char(h->infile, '{') != TRUE)
779  break;
780  /* Fall through to the next gdk_pixmap_seek_char. */
781 
782  case op_cmap:
783  gdk_pixmap_seek_char(h->infile, '"');
784  fseek(h->infile, -1, SEEK_CUR);
785  /* Fall through to the gdk_pixmap_read_string. */
786 
787  case op_body:
788  gdk_pixmap_read_string(h->infile, &h->buffer, &h->buffer_size);
789  return h->buffer;
790  }
791  return 0;
792 }
793 
795  GdkColormap * colormap,
796  GdkBitmap ** mask,
797  GdkColor *
798  transparent_color,
799  const gchar * filename)
800 {
801  struct file_handle h;
802  GdkPixmap *pixmap = NULL;
803 
804  memset(&h, 0, sizeof(h));
805  h.infile = fopen(filename, "rb");
806  if (h.infile != NULL) {
807  pixmap = _gdk_pixmap_create_from_xpm(window, colormap, mask,
808  transparent_color,
809  file_buffer, &h);
810  fclose(h.infile);
811  g_free(h.buffer);
812  }
813 
814  return pixmap;
815 }
816 
818  GdkBitmap ** mask,
819  GdkColor * transparent_color,
820  const gchar * filename)
821 {
822  return gdk_pixmap_colormap_create_from_xpm(window, NULL, mask,
823  transparent_color, filename);
824 }
825 
826 struct mem_handle {
827  gchar **data;
828  int offset;
829 };
830 
831 
832 static gchar *mem_buffer(enum buffer_op op, gpointer handle)
833 {
834  struct mem_handle *h = handle;
835  switch (op) {
836  case op_header:
837  case op_cmap:
838  case op_body:
839  if (h->data[h->offset])
840  return h->data[h->offset++];
841  }
842  return 0;
843 }
844 
846  GdkColormap * colormap,
847  GdkBitmap ** mask,
848  GdkColor *
849  transparent_color,
850  gchar ** data)
851 {
852  struct mem_handle h;
853  GdkPixmap *pixmap = NULL;
854 
855  memset(&h, 0, sizeof(h));
856  h.data = data;
857  pixmap = _gdk_pixmap_create_from_xpm(window, colormap, mask,
858  transparent_color, mem_buffer, &h);
859  return pixmap;
860 }
861 
863  GdkBitmap ** mask,
864  GdkColor * transparent_color,
865  gchar ** data)
866 {
867  return gdk_pixmap_colormap_create_from_xpm_d(window, NULL, mask,
868  transparent_color, data);
869 }
870 
872 {
873  GdkPixmap *pixmap;
874  GdkDrawablePrivate *private;
875  HBITMAP xpixmap;
876  SIZE size;
877  unsigned int w_ret, h_ret;
878 
879  /* check to make sure we were passed something at
880  least a little sane */
881  g_return_val_if_fail((anid != 0), NULL);
882 
883  /* set the pixmap to the passed in value */
884  xpixmap = (HBITMAP) anid;
885 
886  /* get information about the BITMAP to fill in the structure for
887  the gdk window */
888  GetBitmapDimensionEx(xpixmap, &size);
889  w_ret = size.cx;
890  h_ret = size.cy;
891 
892  /* allocate a new gdk pixmap */
893  pixmap = gdk_win32_pixmap_alloc();
894  private = (GdkDrawablePrivate *) pixmap;
895 
896  GDK_DRAWABLE_WIN32DATA(pixmap)->xid = xpixmap;
897  private->colormap = NULL;
898  private->width = w_ret;
899  private->height = h_ret;
900 
901  gdk_xid_table_insert(&GDK_DRAWABLE_XID(pixmap), pixmap);
902 
903  return pixmap;
904 }
signed int gint32
guint32 red_mask
Definition: gdkvisual.h:46
#define MIN(a, b)
Definition: gmacros.h:137
#define GDK_DRAWABLE_DESTROYED(d)
Definition: gdkprivate.h:48
gint gdk_color_parse(const gchar *spec, GdkColor *color)
GdkPixmap * gdk_pixmap_create_from_xpm(GdkWindow *window, GdkBitmap **mask, GdkColor *transparent_color, const gchar *filename)
void gdk_gc_unref(GdkGC *gc)
Definition: gdkgc.c:78
virtual Pixmap_t CreateBitmap(Drawable_t id, const char *bitmap, UInt_t width, UInt_t height)
unsigned int guint
Definition: g_types.h:51
GHashTable * g_hash_table_new(GHashFunc hash_func, GEqualFunc key_equal_func)
g_hash_table_new: : a function to create a hash value from a key.
Definition: ghash.c:112
unsigned char guchar
Definition: g_types.h:48
GdkColormap * gdk_drawable_get_colormap(GdkDrawable *drawable)
GdkWindow * gdk_parent_root
Definition: gdkglobals.c:33
#define g_return_val_if_fail(expr, val)
Definition: gmessages.h:300
GdkPixmap * gdk_pixmap_new(GdkWindow *window, gint width, gint height, gint depth)
void g_hash_table_destroy(GHashTable *hash_table)
g_hash_table_destroy: : a GHashTable.
Definition: ghash.c:171
TH1 * h
Definition: legend2.C:5
#define GDK_NOTE(type, action)
Definition: gdkprivate.h:276
GdkDrawable * gdk_drawable_alloc(void)
Definition: gdkdraw.c:33
static const char * filename()
gpointer g_malloc(gulong n_bytes)
Definition: gmem.c:130
gboolean gdk_color_white(GdkColormap *colormap, GdkColor *color)
Definition: gdkcolor.c:133
void g_hash_table_insert(GHashTable *hash_table, gpointer key, gpointer value)
g_hash_table_insert: : a GHashTable.
Definition: ghash.c:285
GdkPixmap * gdk_pixmap_create_on_shared_image(GdkImage **image_return, GdkWindow *window, GdkVisual *visual, gint width, gint height, gint depth)
static gchar * gdk_pixmap_skip_string(gchar *buffer)
typedef PVOID
G_BEGIN_DECLS typedef char gchar
Definition: g_types.h:41
GdkPixmap * gdk_pixmap_colormap_create_from_xpm_d(GdkWindow *window, GdkColormap *colormap, GdkBitmap **mask, GdkColor *transparent_color, gchar **data)
static gchar * gdk_pixmap_skip_whitespaces(gchar *buffer)
GdkPixmap * gdk_pixmap_create_from_xpm_d(GdkWindow *window, GdkBitmap **mask, GdkColor *transparent_color, gchar **data)
#define MAX_COLOR_LEN
GdkPixmap * gdk_pixmap_colormap_create_from_xpm(GdkWindow *window, GdkColormap *colormap, GdkBitmap **mask, GdkColor *transparent_color, const gchar *filename)
const uint32_t SIZE
Definition: stressVdt.cxx:21
buffer_op
guint g_str_hash(gconstpointer v)
Definition: gstring.c:72
static void gdk_win32_pixmap_destroy(GdkPixmap *pixmap)
unsigned int guint32
gint gboolean
Definition: g_types.h:45
void gdk_draw_line(GdkDrawable *drawable, GdkGC *gc, gint x1, gint y1, gint x2, gint y2)
Definition: gdkdraw.c:148
static unsigned char mirror[256]
void gdk_xid_table_remove(HANDLE xid)
Definition: gdkwin32id.c:52
gboolean g_str_equal(gconstpointer v, gconstpointer v2)
Definition: gstring.c:61
void gdk_colormap_free_colors(GdkColormap *colormap, GdkColor *colors, gint ncolors)
GdkPixmap * gdk_pixmap_create_from_data(GdkWindow *window, const gchar *data, gint width, gint height, gint depth, GdkColor *fg, GdkColor *bg)
Definition: gdkgc.h:145
void gdk_xid_table_insert(HANDLE *hnd, gpointer data)
Definition: gdkwin32id.c:41
char * out
Definition: TBase64.cxx:29
unsigned long gulong
Definition: g_types.h:50
GdkGC * gdk_gc_new(GdkDrawable *drawable)
Definition: gdkgc.c:44
#define g_new(struct_type, n_structs)
Definition: gmem.h:60
GdkDrawableClass _gdk_win32_drawable_class
int gint
Definition: g_types.h:44
static GdkPixmap * _gdk_pixmap_create_from_xpm(GdkWindow *window, GdkColormap *colormap, GdkBitmap **mask, GdkColor *transparent_color, gchar *(*get_buf)(enum buffer_opop, gpointer handle), gpointer handle)
GdkPixmap * gdk_pixmap_foreign_new(guint32 anid)
guint16 width
Definition: gdkimage.h:35
typedefG_BEGIN_DECLS struct _GHashTable GHashTable
Definition: ghash.h:34
guint16 ch
#define FALSE
Definition: gmacros.h:126
GdkColormap * gdk_colormap_ref(GdkColormap *cmap)
Definition: gdkcolor.c:32
void * gpointer
Definition: g_types.h:67
static gint gdk_pixmap_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
void gdk_image_put_pixel(GdkImage *image, gint x, gint y, guint32 pixel)
static gchar * gdk_pixmap_extract_color(gchar *buffer)
void gdk_gc_set_background(GdkGC *gc, GdkColor *color)
Definition: gdkgc.c:120
GdkColormap * gdk_colormap_get_system(void)
#define GDK_IS_WINDOW(d)
Definition: gdkprivate.h:45
guint32 blue_mask
Definition: gdkvisual.h:54
#define WIN32_GDI_FAILED(api)
void gdk_drawable_set_data(GdkDrawable *drawable, const gchar *key, gpointer data, GDestroyNotify destroy_func)
Definition: gdkdraw.c:55
Color * colors
Definition: X3DBuffer.c:19
gchar data[7]
void g_free(gpointer mem)
Definition: gmem.c:183
gboolean gdk_color_alloc(GdkColormap *colormap, GdkColor *color)
Definition: gdkcolor.c:186
GdkPixmap * gdk_bitmap_create_from_data(GdkWindow *window, const gchar *data, gint width, gint height)
GdkImage * gdk_image_bitmap_new(GdkImageType type, GdkVisual *visual, gint width, gint height)
void gdk_draw_image(GdkDrawable *drawable, GdkGC *gc, GdkImage *image, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height)
Definition: gdkdraw.c:316
static gint gdk_pixmap_seek_string(FILE *infile, const gchar *str, gint skip_comments)
static gchar * file_buffer(enum buffer_op op, gpointer handle)
void gdk_image_unref(GdkImage *image)
Definition: gdkimage.c:44
gpointer g_realloc(gpointer mem, gulong n_bytes)
Definition: gmem.c:164
void(* destroy)(GdkDrawable *drawable)
Definition: gdkdrawable.h:48
static gchar * mem_buffer(enum buffer_op op, gpointer handle)
GdkVisualType type
Definition: gdkvisual.h:40
static int error(void)
Definition: testgdk.c:106
static void g_warning(const gchar *format,...)
Definition: gmessages.h:155
void gdk_gc_set_foreground(GdkGC *gc, GdkColor *color)
Definition: gdkgc.c:109
static gint gdk_pixmap_seek_char(FILE *infile, gchar c)
guint16 height
Definition: gdkimage.h:36
gulong pixel
Definition: gdkcolor.h:18
#define TRUE
Definition: gmacros.h:130
void gdk_colormap_unref(GdkColormap *cmap)
Definition: gdkcolor.c:42
void gdk_drawable_unref(GdkDrawable *drawable)
Definition: gdkdraw.c:108
#define NULL
Definition: Rtypes.h:82
guint32 green_mask
Definition: gdkvisual.h:50
double result[121]
gpointer g_hash_table_lookup(GHashTable *hash_table, gconstpointer key)
g_hash_table_lookup: : a GHashTable.
Definition: ghash.c:220
#define GDK_DRAWABLE_XID(win)
Definition: gdkwin32.h:42
void g_print(const gchar *format,...)
Definition: gmessages.c:788
gint depth
Definition: gdkvisual.h:41
void gdk_draw_drawable(GdkDrawable *drawable, GdkGC *gc, GdkDrawable *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height)
Definition: gdkdraw.c:290
gchar * g_strdup(const gchar *str)
Definition: gstrfuncs.c:82
void gdk_draw_rectangle(GdkDrawable *drawable, GdkGC *gc, gint filled, gint x, gint y, gint width, gint height)
Definition: gdkdraw.c:170
#define GDK_DRAWABLE_WIN32DATA(win)
const Int_t n
Definition: legend1.C:16
static void gdk_xpm_destroy_notify(gpointer data)
const char * cnt
Definition: TXMLSetup.cxx:75
static GdkDrawable * gdk_win32_pixmap_alloc(void)
GdkImage * gdk_image_new(GdkImageType type, GdkVisual *visual, gint width, gint height)
const char Int_t const char * image
Definition: TXSlave.cxx:46
GdkVisual * gdk_drawable_get_visual(GdkDrawable *drawable)
Definition: gdkdraw.c:89