]> git.saurik.com Git - wxWidgets.git/blob - src/motif/bitmap.cpp
Regenerated some more makefiles/filelists.
[wxWidgets.git] / src / motif / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14 #endif
15
16 #ifdef __VMS
17 #define XtParent XTPARENT
18 #endif
19
20 #include "wx/defs.h"
21 #include "wx/utils.h"
22 #include "wx/palette.h"
23 #include "wx/bitmap.h"
24 #include "wx/icon.h"
25 #include "wx/log.h"
26 #include "wx/dcmemory.h"
27 #include "wx/image.h"
28 #include "wx/app.h"
29
30 #if 0
31 #ifdef __VMS__
32 #pragma message disable nosimpint
33 #endif
34 #include <Xm/Xm.h>
35 #ifdef __VMS__
36 #pragma message enable nosimpint
37 #endif
38 #endif
39
40 #include <X11/Xlib.h>
41 #include <X11/Intrinsic.h>
42
43 #if wxHAVE_LIB_XPM
44 #include <X11/xpm.h>
45 #endif
46 #include <math.h>
47
48
49 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
50 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
51
52 wxBitmapRefData::wxBitmapRefData()
53 {
54 m_ok = FALSE;
55 m_width = 0;
56 m_height = 0;
57 m_depth = 0;
58 // XXX m_quality = 0;
59 // m_numColors = 0;
60 m_bitmapMask = NULL;
61
62 m_pixmap = (WXPixmap) 0;
63 m_display = (WXDisplay*) 0;
64
65 // m_freePixmap = TRUE; //TODO: necessary?
66 #if 0
67 m_freeColors = (unsigned long*) 0;
68 m_freeColorsCount = 0;
69 #endif
70
71 // These 5 variables are for wxControl
72 #if 0
73 m_insensPixmap = (WXPixmap) 0;
74 m_labelPixmap = (WXPixmap) 0;
75 m_armPixmap = (WXPixmap) 0;
76 #endif
77 #if 0
78 m_image = (WXImage*) 0;
79 m_insensImage = (WXImage*) 0;
80 #endif
81 }
82
83 wxBitmapRefData::~wxBitmapRefData()
84 {
85 #if 0
86 if (m_labelPixmap)
87 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_labelPixmap);
88
89 if (m_armPixmap)
90 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_armPixmap);
91
92 if (m_insensPixmap)
93 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_insensPixmap);
94 #endif
95
96 #if 0
97 if (m_image)
98 {
99 XmUninstallImage ((XImage*) m_image);
100 XtFree ((char *) (XImage*) m_image);
101 }
102 #endif
103
104 #if 0
105 if (m_insensImage)
106 {
107 XmUninstallImage ((XImage*) m_insensImage);
108 delete[] ((XImage*) m_insensImage)->data;
109 XtFree ((char *) (XImage*) m_insensImage);
110 }
111 #endif
112 if (m_pixmap /* && m_freePixmap */)
113 XFreePixmap ((Display*) m_display, (Pixmap) m_pixmap);
114
115 #if 0
116 if (m_freeColors)
117 {
118 int screen = DefaultScreen((Display*) m_display);
119 Colormap cmp = DefaultColormap((Display*) m_display,screen);
120 long llp;
121 for(llp = 0;llp < m_freeColorsCount;llp++)
122 XFreeColors((Display*) m_display, cmp, &m_freeColors[llp], 1, 0L);
123 delete m_freeColors;
124 };
125 #endif
126
127 if (m_bitmapMask)
128 delete m_bitmapMask;
129 m_bitmapMask = NULL;
130 }
131
132 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
133
134 wxBitmap::wxBitmap()
135 {
136 m_refData = NULL;
137 }
138
139 wxBitmap::~wxBitmap()
140 {
141 }
142
143 wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
144 {
145 m_refData = new wxBitmapRefData;
146
147 (void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, depth);
148 }
149
150 wxBitmap::wxBitmap(int w, int h, int d)
151 {
152 (void)Create(w, h, d);
153 }
154
155 wxBitmap::wxBitmap(void *data, wxBitmapType type,
156 int width, int height, int depth)
157 {
158 (void) Create(data, type, width, height, depth);
159 }
160
161 wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
162 {
163 LoadFile(filename, type);
164 }
165
166 #if 0
167 // Create from XPM data
168 static wxControl* sg_Control = NULL;
169 wxBitmap::wxBitmap(char **data, wxControl* control)
170 {
171 // Pass the control to the Create function using a global
172 sg_Control = control;
173
174 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
175
176 sg_Control = (wxControl*) NULL;
177 }
178 #endif
179
180 bool wxBitmap::CreateFromXpm(const char **bits)
181 {
182 wxCHECK_MSG( bits, FALSE, _T("NULL pointer in wxBitmap::CreateFromXpm") );
183
184 return Create(bits, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
185 }
186
187 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
188 {
189 *this = icon;
190 return TRUE;
191 }
192
193 bool wxBitmap::Create(int w, int h, int d)
194 {
195 UnRef();
196
197 m_refData = new wxBitmapRefData;
198
199 if (d < 1)
200 d = wxDisplayDepth();
201
202 M_BITMAPDATA->m_width = w;
203 M_BITMAPDATA->m_height = h;
204 M_BITMAPDATA->m_depth = d;
205 // M_BITMAPDATA->m_freePixmap = TRUE;
206
207 Display *dpy = (Display*) wxGetDisplay();
208
209 M_BITMAPDATA->m_display = dpy; /* MATTHEW: [4] Remember the display */
210
211 M_BITMAPDATA->m_pixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
212 w, h, d);
213
214 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_pixmap != (WXPixmap) 0) ;
215 return M_BITMAPDATA->m_ok;
216 }
217
218 bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
219 {
220 UnRef();
221
222 m_refData = new wxBitmapRefData;
223
224 wxBitmapHandler *handler = FindHandler(type);
225
226 if ( handler == NULL ) {
227 wxImage image;
228 if (!image.LoadFile( filename, type )) return FALSE;
229 if (image.Ok())
230 {
231 *this = wxBitmap(image);
232 return TRUE;
233 }
234 else return FALSE;
235 }
236
237 return handler->LoadFile(this, filename, type, -1, -1);
238 }
239
240 bool wxBitmap::Create(void *data, wxBitmapType type,
241 int width, int height, int depth)
242 {
243 UnRef();
244
245 m_refData = new wxBitmapRefData;
246
247 wxBitmapHandler *handler = FindHandler(type);
248
249 if ( handler == NULL ) {
250 wxLogWarning("no data bitmap handler for type %ld defined.",
251 (long)type);
252
253 return FALSE;
254 }
255
256 return handler->Create(this, data, type, width, height, depth);
257 }
258
259 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type,
260 const wxPalette *palette) const
261 {
262 wxBitmapHandler *handler = FindHandler(type);
263
264 if ( handler == NULL ) { // try wxImage
265 wxImage image = this->ConvertToImage();
266 if (image.Ok()) return image.SaveFile( filename, type );
267 else return FALSE;
268 }
269
270 return handler->SaveFile(this, filename, type, palette);
271 }
272
273 void wxBitmap::SetWidth(int w)
274 {
275 if (!M_BITMAPDATA)
276 m_refData = new wxBitmapRefData;
277
278 M_BITMAPDATA->m_width = w;
279 }
280
281 void wxBitmap::SetHeight(int h)
282 {
283 if (!M_BITMAPDATA)
284 m_refData = new wxBitmapRefData;
285
286 M_BITMAPDATA->m_height = h;
287 }
288
289 void wxBitmap::SetDepth(int d)
290 {
291 if (!M_BITMAPDATA)
292 m_refData = new wxBitmapRefData;
293
294 M_BITMAPDATA->m_depth = d;
295 }
296
297 #if 0
298
299 // XXX
300 void wxBitmap::SetQuality(int q)
301 {
302 if (!M_BITMAPDATA)
303 m_refData = new wxBitmapRefData;
304
305 M_BITMAPDATA->m_quality = q;
306 }
307
308 #endif
309
310 void wxBitmap::SetOk(bool isOk)
311 {
312 if (!M_BITMAPDATA)
313 m_refData = new wxBitmapRefData;
314
315 M_BITMAPDATA->m_ok = isOk;
316 }
317
318 void wxBitmap::SetPalette(const wxPalette& palette)
319 {
320 if (!M_BITMAPDATA)
321 m_refData = new wxBitmapRefData;
322
323 M_BITMAPDATA->m_bitmapPalette = palette ;
324 }
325
326 void wxBitmap::SetMask(wxMask *mask)
327 {
328 if (!M_BITMAPDATA)
329 m_refData = new wxBitmapRefData;
330
331 M_BITMAPDATA->m_bitmapMask = mask ;
332 }
333
334 wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
335 {
336 wxCHECK_MSG( Ok() &&
337 (rect.x >= 0) && (rect.y >= 0) &&
338 (rect.x+rect.width <= M_BMPDATA->m_width) && (rect.y+rect.height <= M_BMPDATA->m_height),
339 wxNullBitmap, wxT("invalid bitmap or bitmap region") );
340
341 wxBitmap ret( rect.width, rect.height, 0 );
342 wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
343
344 // The remaining still TODO
345 return ret;
346 }
347
348 /*
349 * wxMask
350 */
351
352 wxMask::wxMask()
353 {
354 m_pixmap = (WXPixmap) 0;
355 }
356
357 // Construct a mask from a bitmap and a colour indicating
358 // the transparent area
359 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
360 {
361 m_pixmap = (WXPixmap) 0;
362
363 Create(bitmap, colour);
364 }
365
366 // Construct a mask from a bitmap and a palette index indicating
367 // the transparent area
368 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
369 {
370 m_pixmap = (WXPixmap) 0;
371
372 Create(bitmap, paletteIndex);
373 }
374
375 // Construct a mask from a mono bitmap (copies the bitmap).
376 wxMask::wxMask(const wxBitmap& bitmap)
377 {
378 m_pixmap = (WXPixmap) 0;
379
380 Create(bitmap);
381 }
382
383 wxMask::~wxMask()
384 {
385 // TODO: this may be the wrong display
386 if ( m_pixmap )
387 XFreePixmap ((Display*) wxGetDisplay(), (Pixmap) m_pixmap);
388 }
389
390 // Create a mask from a mono bitmap (copies the bitmap).
391 bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap))
392 {
393 // TODO
394 return FALSE;
395 }
396
397 // Create a mask from a bitmap and a palette index indicating
398 // the transparent area
399 bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap), int WXUNUSED(paletteIndex))
400 {
401 // TODO
402 return FALSE;
403 }
404
405 // Create a mask from a bitmap and a colour indicating
406 // the transparent area
407 bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap), const wxColour& WXUNUSED(colour))
408 {
409 // TODO
410 return FALSE;
411 }
412
413 /*
414 * wxBitmapHandler
415 */
416
417 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
418
419 /*
420 * Standard handlers
421 */
422
423 class WXDLLEXPORT wxXBMFileHandler: public wxBitmapHandler
424 {
425 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler)
426 public:
427 inline wxXBMFileHandler()
428 {
429 m_name = "XBM file";
430 m_extension = "xbm";
431 m_type = wxBITMAP_TYPE_XBM;
432 };
433
434 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
435 int desiredWidth, int desiredHeight);
436 };
437
438 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
439
440 bool wxXBMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
441 long WXUNUSED(flags),
442 int WXUNUSED(desiredWidth),
443 int WXUNUSED(desiredHeight))
444 {
445 // M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
446
447 int hotX, hotY;
448 unsigned int w, h;
449 Pixmap pixmap;
450
451 Display *dpy = (Display*) wxGetDisplay();
452 M_BITMAPDATA->m_display = (WXDisplay*) dpy;
453
454 int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
455 wxConstCast(name.c_str(), char), &w, &h, &pixmap, &hotX, &hotY);
456 M_BITMAPHANDLERDATA->m_width = w;
457 M_BITMAPHANDLERDATA->m_height = h;
458 M_BITMAPHANDLERDATA->m_depth = 1;
459 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
460
461 if ((value == BitmapFileInvalid) ||
462 (value == BitmapOpenFailed) ||
463 (value == BitmapNoMemory))
464 {
465 M_BITMAPHANDLERDATA->m_ok = FALSE;
466 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) 0;
467 }
468 else
469 M_BITMAPHANDLERDATA->m_ok = TRUE;
470
471 return M_BITMAPHANDLERDATA->m_ok ;
472 }
473
474 class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
475 {
476 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
477 public:
478 inline wxXBMDataHandler()
479 {
480 m_name = "XBM data";
481 m_extension = "xbm";
482 m_type = wxBITMAP_TYPE_XBM_DATA;
483 };
484
485 virtual bool Create(wxBitmap *bitmap, void *data, long flags,
486 int width, int height, int depth = 1);
487 };
488 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
489
490 bool wxXBMDataHandler::Create( wxBitmap *bitmap, void *data,
491 long WXUNUSED(flags),
492 int width, int height, int WXUNUSED(depth))
493 {
494 M_BITMAPHANDLERDATA->m_width = width;
495 M_BITMAPHANDLERDATA->m_height = height;
496 M_BITMAPHANDLERDATA->m_depth = 1;
497 // M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
498
499 Display *dpy = (Display*) wxGetDisplay();
500 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
501
502 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) XCreateBitmapFromData (dpy, RootWindow (dpy, DefaultScreen (dpy)), (char*) data, width, height);
503 M_BITMAPHANDLERDATA->m_ok = (M_BITMAPHANDLERDATA->m_pixmap != (WXPixmap) 0) ;
504
505 #if 0
506 // code for wxControl. TODO: can we avoid doing this until we need it?
507 // E.g. have CreateButtonPixmaps which is called on demand.
508 XImage* image = (XImage *) XtMalloc (sizeof (XImage));
509 image->width = width;
510 image->height = height;
511 image->data = (char*) data;
512 image->depth = 1;
513 image->xoffset = 0;
514 image->format = XYBitmap;
515 image->byte_order = LSBFirst;
516 image->bitmap_unit = 8;
517 image->bitmap_bit_order = LSBFirst;
518 image->bitmap_pad = 8;
519 image->bytes_per_line = (width + 7) >> 3;
520
521 char tmp[128];
522 sprintf (tmp, "Im%x", (unsigned int) image);
523 XmInstallImage (image, tmp);
524
525 // Build our manually stipped pixmap.
526
527 int bpl = (width + 7) / 8;
528 char *data1 = new char[height * bpl];
529 char* bits = (char*) data;
530 int i;
531 for (i = 0; i < height; i++)
532 {
533 int mask = i % 2 ? 0x55 : 0xaa;
534 int j;
535 for (j = 0; j < bpl; j++)
536 data1[i * bpl + j] = bits[i * bpl + j] & mask;
537 }
538 XImage* insensImage = (XImage *) XtMalloc (sizeof (XImage));
539 insensImage->width = width;
540 insensImage->height = height;
541 insensImage->data = data1;
542 insensImage->depth = 1;
543 insensImage->xoffset = 0;
544 insensImage->format = XYBitmap;
545 insensImage->byte_order = LSBFirst;
546 insensImage->bitmap_unit = 8;
547 insensImage->bitmap_bit_order = LSBFirst;
548 insensImage->bitmap_pad = 8;
549 insensImage->bytes_per_line = bpl;
550
551 sprintf (tmp, "Not%x", (unsigned int)insensImage);
552 XmInstallImage (insensImage, tmp);
553
554 M_BITMAPHANDLERDATA->m_image = (WXImage*) image;
555 M_BITMAPHANDLERDATA->m_insensImage = (WXImage*) insensImage;
556 #endif
557
558
559
560 return TRUE;
561 }
562
563 #if wxHAVE_LIB_XPM
564 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
565 {
566 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
567 public:
568 inline wxXPMFileHandler()
569 {
570 m_name = "XPM file";
571 m_extension = "xpm";
572 m_type = wxBITMAP_TYPE_XPM;
573 };
574
575 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
576 int desiredWidth, int desiredHeight);
577 virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name,
578 wxBitmapType type, const wxPalette *palette = NULL);
579 };
580
581 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
582
583 bool wxXPMFileHandler::LoadFile( wxBitmap *bitmap, const wxString& name,
584 long WXUNUSED(flags),
585 int WXUNUSED(desiredWidth),
586 int WXUNUSED(desiredHeight) )
587 {
588 Display *dpy = (Display*) wxGetDisplay();
589 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
590
591 XpmAttributes xpmAttr;
592 Pixmap pixmap;
593 Pixmap mask = 0;
594
595 M_BITMAPHANDLERDATA->m_ok = FALSE;
596 xpmAttr.valuemask = XpmReturnInfos | XpmCloseness;
597 xpmAttr.closeness = 40000;
598 int errorStatus = XpmReadFileToPixmap(dpy,
599 RootWindow(dpy, DefaultScreen(dpy)),
600 wxConstCast(name.c_str(), char),
601 &pixmap, &mask, &xpmAttr);
602
603 if (errorStatus == XpmSuccess)
604 {
605 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
606 if ( mask )
607 {
608 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
609 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
610 }
611
612 unsigned int depthRet;
613 int xRet, yRet;
614 unsigned int widthRet, heightRet, borderWidthRet;
615 Window rootWindowRet;
616 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
617 &widthRet, &heightRet, &borderWidthRet, &depthRet);
618
619 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
620 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
621
622 /*
623 if ( xpmAttr.npixels > 2 )
624 {
625 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
626 } else
627 {
628 M_BITMAPHANDLERDATA->m_depth = 1; // mono
629 }
630 */
631
632 M_BITMAPHANDLERDATA->m_depth = depthRet;
633
634 // M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
635
636 XpmFreeAttributes(&xpmAttr);
637
638 M_BITMAPHANDLERDATA->m_ok = TRUE;
639 return TRUE;
640 } else
641 {
642 // XpmDebugError(errorStatus, name);
643 M_BITMAPHANDLERDATA->m_ok = FALSE;
644 return FALSE;
645 }
646 }
647
648 bool wxXPMFileHandler::SaveFile( const wxBitmap *bitmap, const wxString& name,
649 wxBitmapType WXUNUSED(type),
650 const wxPalette *WXUNUSED(palette))
651 {
652 if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
653 {
654 Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
655 int errorStatus = XpmWriteFileFromPixmap(dpy,
656 wxConstCast(name.c_str(), char),
657 (Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
658 (M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
659 (XpmAttributes *) NULL);
660 if (errorStatus == XpmSuccess)
661 return TRUE;
662 else
663 return FALSE;
664 }
665 else
666 return FALSE;
667 }
668
669 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
670 {
671 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
672 public:
673 inline wxXPMDataHandler()
674 {
675 m_name = "XPM data";
676 m_extension = "xpm";
677 m_type = wxBITMAP_TYPE_XPM_DATA;
678 };
679
680 virtual bool Create(wxBitmap *bitmap, void *data, long flags,
681 int width, int height, int depth = 1);
682 };
683 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
684
685 bool wxXPMDataHandler::Create( wxBitmap *bitmap, void *data,
686 long WXUNUSED(flags),
687 int width, int height, int WXUNUSED(depth))
688 {
689 M_BITMAPHANDLERDATA->m_width = width;
690 M_BITMAPHANDLERDATA->m_height = height;
691 M_BITMAPHANDLERDATA->m_depth = 1;
692 // M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
693
694 Display *dpy = (Display*) wxGetDisplay();
695 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
696
697 XpmAttributes xpmAttr;
698
699 xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
700
701 #if 0
702 XpmColorSymbol symbolicColors[4];
703 if (sg_Control && sg_Control->GetMainWidget())
704 {
705 symbolicColors[0].name = "foreground";
706 symbolicColors[0].value = NULL;
707 symbolicColors[1].name = "background";
708 symbolicColors[1].value = NULL;
709 XtVaGetValues((Widget) sg_Control->GetMainWidget(),
710 XmNforeground, &symbolicColors[0].pixel,
711 XmNbackground, &symbolicColors[1].pixel,NULL);
712 xpmAttr.numsymbols = 2;
713 xpmAttr.colorsymbols = symbolicColors;
714 xpmAttr.valuemask |= XpmColorSymbols; // add flag
715 }
716 #endif
717
718 Pixmap pixmap = 0;
719 Pixmap mask = 0;
720 int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
721 (char**) data, &pixmap, &mask, &xpmAttr);
722 if (ErrorStatus == XpmSuccess)
723 {
724 // Set attributes
725 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
726 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
727
728 unsigned int depthRet;
729 int xRet, yRet;
730 unsigned int widthRet, heightRet, borderWidthRet;
731 Window rootWindowRet;
732 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
733 &widthRet, &heightRet, &borderWidthRet, &depthRet);
734
735 /*
736 if ( xpmAttr.npixels > 2 )
737 {
738 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
739 } else
740 {
741 M_BITMAPHANDLERDATA->m_depth = 1; // mono
742 }
743 */
744
745 M_BITMAPHANDLERDATA->m_depth = depthRet;
746
747 // M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
748 XpmFreeAttributes(&xpmAttr);
749 M_BITMAPHANDLERDATA->m_ok = TRUE;
750 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
751 if ( mask )
752 {
753 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
754 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
755 }
756 }
757 else
758 {
759 // XpmDebugError(ErrorStatus, NULL);
760 M_BITMAPHANDLERDATA->m_ok = FALSE;
761 }
762 return M_BITMAPHANDLERDATA->m_ok ;
763 }
764
765 #endif // wxHAVE_LIB_XPM
766
767 void wxBitmap::InitStandardHandlers()
768 {
769 // Initialize all standard bitmap or derived class handlers here.
770 AddHandler(new wxXBMFileHandler);
771 AddHandler(new wxXBMDataHandler);
772
773 // XPM is considered standard for Motif, although it can be omitted if
774 // libXpm is not installed
775 #if wxHAVE_LIB_XPM
776 AddHandler(new wxXPMFileHandler);
777 AddHandler(new wxXPMDataHandler);
778 #endif // wxHAVE_LIB_XPM
779 }
780
781 #if 0
782 WXPixmap wxBitmap::GetLabelPixmap (WXWidget w)
783 {
784 if (!M_BITMAPDATA)
785 return (WXPixmap)NULL;
786 // if (M_BITMAPDATA->m_image == (WXPixmap) 0)
787 return M_BITMAPDATA->m_pixmap;
788
789 #if 0
790 Display *dpy = (Display*) M_BITMAPDATA->m_display;
791
792 #ifdef FOO
793 /*
794 If we do:
795 if (labelPixmap) return labelPixmap;
796 things can be wrong, because colors can have been changed.
797
798 If we do:
799 if (labelPixmap)
800 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
801 we got BadDrawable if the pixmap is referenced by multiples widgets
802
803 this is a catch22!!
804
805 So, before doing thing really clean, I just do nothing; if the pixmap is
806 referenced by many widgets, Motif performs caching functions.
807 And if pixmap is referenced with multiples colors, we just have some
808 memory leaks... I hope we can deal with them...
809 */
810 // Must be destroyed, because colours can have been changed!
811 if (M_BITMAPDATA->m_labelPixmap)
812 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_labelPixmap);
813 #endif
814
815 char tmp[128];
816 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
817
818 Pixel fg, bg;
819 Widget widget = (Widget) w;
820
821 while (XmIsGadget ( widget ))
822 widget = XtParent (widget);
823 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
824
825 M_BITMAPDATA->m_labelPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
826
827 return M_BITMAPDATA->m_labelPixmap;
828 #endif
829 }
830
831 WXPixmap wxBitmap::GetArmPixmap (WXWidget w)
832 {
833 // if (M_BITMAPDATA->m_image == (WXPixmap) 0)
834 return M_BITMAPDATA->m_pixmap;
835
836 #if 0
837 Display *dpy = (Display*) M_BITMAPDATA->m_display;
838 #ifdef FOO
839 // See GetLabelPixmap () comment
840
841 // Must be destroyed, because colours can have been changed!
842 if (M_BITMAPDATA->m_armPixmap)
843 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_armPixmap);
844 #endif
845
846 char tmp[128];
847 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
848
849 Pixel fg, bg;
850 Widget widget = (Widget) w;
851
852 XtVaGetValues (widget, XmNarmColor, &bg, NULL);
853 while (XmIsGadget (widget))
854 widget = XtParent (widget);
855 XtVaGetValues (widget, XmNforeground, &fg, NULL);
856
857 M_BITMAPDATA->m_armPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
858
859 return M_BITMAPDATA->m_armPixmap;
860 #endif
861 }
862
863 WXPixmap wxBitmap::GetInsensPixmap (WXWidget w)
864 {
865 Display *dpy = (Display*) M_BITMAPDATA->m_display;
866
867 if (!M_BITMAPDATA)
868 return (WXPixmap)NULL;
869 if (M_BITMAPDATA->m_insensPixmap)
870 return M_BITMAPDATA->m_insensPixmap;
871
872 if (!w)
873 {
874 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XCreateInsensitivePixmap(dpy, (Pixmap) M_BITMAPDATA->m_pixmap);
875 if (M_BITMAPDATA->m_insensPixmap)
876 return M_BITMAPDATA->m_insensPixmap;
877 else
878 return M_BITMAPDATA->m_pixmap;
879 }
880
881 // if (M_BITMAPDATA->m_insensImage == (WXPixmap) 0)
882 return M_BITMAPDATA->m_pixmap;
883
884 #if 0
885 #ifdef FOO
886 See GetLabelPixmap () comment
887 // Must be destroyed, because colours can have been changed!
888 if (M_BITMAPDATA->m_insensPixmap)
889 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), (Pixmap) M_BITMAPDATA->m_insensPixmap);
890 #endif
891
892 char tmp[128];
893 sprintf (tmp, "Not%x", (unsigned int) M_BITMAPDATA->m_insensImage);
894
895 Pixel fg, bg;
896 Widget widget = (Widget) w;
897
898 while (XmIsGadget (widget))
899 widget = XtParent (widget);
900 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
901
902 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
903
904 return M_BITMAPDATA->m_insensPixmap;
905 #endif
906 }
907 #endif
908
909 // Creates a bitmap with transparent areas drawn in
910 // the given colour.
911 wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, wxColour& colour)
912 {
913 wxBitmap newBitmap(bitmap.GetWidth(),
914 bitmap.GetHeight(),
915 bitmap.GetDepth());
916 wxMemoryDC destDC;
917 wxMemoryDC srcDC;
918 srcDC.SelectObject(bitmap);
919 destDC.SelectObject(newBitmap);
920
921 wxBrush brush(colour, wxSOLID);
922 destDC.SetOptimization(FALSE);
923 destDC.SetBackground(brush);
924 destDC.Clear();
925 destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
926
927 return newBitmap;
928 }
929
930
931
932
933 //-----------------------------------------------------------------------------
934 // wxImage conversion routines
935 //-----------------------------------------------------------------------------
936
937 /*
938
939 Date: Wed, 05 Jan 2000 11:45:40 +0100
940 From: Frits Boel <boel@niob.knaw.nl>
941 To: julian.smart@ukonline.co.uk
942 Subject: Patch for Motif ConvertToBitmap
943
944 Hi Julian,
945
946 I've been working on a wxWin application for image processing. From the
947 beginning, I was surprised by the (lack of) speed of ConvertToBitmap,
948 till I looked in the source code of image.cpp. I saw that converting a
949 wxImage to a bitmap with 8-bit pixels is done with comparing every pixel
950 to the 256 colors of the palet. A very time-consuming piece of code!
951
952 Because I wanted a faster application, I've made a 'patch' for this. In
953 short: every pixel of the image is compared to a sorted list with
954 colors. If the color is found in the list, the palette entry is
955 returned; if the color is not found, the color palette is searched and
956 then the palette entry is returned and the color added to the sorted
957 list.
958
959 Maybe there is another method for this, namely changing the palette
960 itself (if the colors are known, as is the case with tiffs with a
961 colormap). I did not look at this, maybe someone else did?
962
963 The code of the patch is attached, have a look on it, and maybe you will
964 ship it with the next release of wxMotif?
965
966 Regards,
967
968 Frits Boel
969 Software engineer at Hubrecht Laboratory, The Netherlands.
970
971 */
972
973 class wxSearchColor
974 {
975 public:
976 wxSearchColor( void );
977 wxSearchColor( int size, XColor *colors );
978 ~wxSearchColor( void );
979
980 int SearchColor( int r, int g, int b );
981 private:
982 int AddColor( unsigned int value, int pos );
983
984 int size;
985 XColor *colors;
986 unsigned int *color;
987 int *entry;
988
989 int bottom;
990 int top;
991 };
992
993 wxSearchColor::wxSearchColor( void )
994 {
995 size = 0;
996 colors = (XColor*) NULL;
997 color = (unsigned int *) NULL;
998 entry = (int*) NULL;
999
1000 bottom = 0;
1001 top = 0;
1002 }
1003
1004 wxSearchColor::wxSearchColor( int size_, XColor *colors_ )
1005 {
1006 int i;
1007 size = size_;
1008 colors = colors_;
1009 color = new unsigned int[size];
1010 entry = new int [size];
1011
1012 for (i = 0; i < size; i++ ) {
1013 entry[i] = -1;
1014 }
1015
1016 bottom = top = ( size >> 1 );
1017 }
1018
1019 wxSearchColor::~wxSearchColor( void )
1020 {
1021 if ( color ) delete[] color;
1022 if ( entry ) delete[] entry;
1023 }
1024
1025 int wxSearchColor::SearchColor( int r, int g, int b )
1026 {
1027 unsigned int value = ( ( ( r * 256 ) + g ) * 256 ) + b;
1028 int begin = bottom;
1029 int end = top;
1030 int middle = 0;
1031
1032 while ( begin <= end ) {
1033
1034 middle = ( begin + end ) >> 1;
1035
1036 if ( value == color[middle] ) {
1037 return( entry[middle] );
1038 } else if ( value < color[middle] ) {
1039 end = middle - 1;
1040 } else {
1041 begin = middle + 1;
1042 }
1043
1044 }
1045
1046 return AddColor( value, middle );
1047 }
1048
1049 int wxSearchColor::AddColor( unsigned int value, int pos )
1050 {
1051 int i;
1052 int pixel = -1;
1053 int max = 3 * (65536);
1054 for ( i = 0; i < 256; i++ ) {
1055 int rdiff = ((value >> 8) & 0xFF00 ) - colors[i].red;
1056 int gdiff = ((value ) & 0xFF00 ) - colors[i].green;
1057 int bdiff = ((value << 8) & 0xFF00 ) - colors[i].blue;
1058 int sum = abs (rdiff) + abs (gdiff) + abs (bdiff);
1059 if (sum < max) { pixel = i; max = sum; }
1060 }
1061
1062 if ( entry[pos] < 0 ) {
1063 color[pos] = value;
1064 entry[pos] = pixel;
1065 } else if ( value < color[pos] ) {
1066
1067 if ( bottom > 0 ) {
1068 for ( i = bottom; i < pos; i++ ) {
1069 color[i-1] = color[i];
1070 entry[i-1] = entry[i];
1071 }
1072 bottom--;
1073 color[pos-1] = value;
1074 entry[pos-1] = pixel;
1075 } else if ( top < size-1 ) {
1076 for ( i = top; i >= pos; i-- ) {
1077 color[i+1] = color[i];
1078 entry[i+1] = entry[i];
1079 }
1080 top++;
1081 color[pos] = value;
1082 entry[pos] = pixel;
1083 }
1084
1085 } else {
1086
1087 if ( top < size-1 ) {
1088 for ( i = top; i > pos; i-- ) {
1089 color[i+1] = color[i];
1090 entry[i+1] = entry[i];
1091 }
1092 top++;
1093 color[pos+1] = value;
1094 entry[pos+1] = pixel;
1095 } else if ( bottom > 0 ) {
1096 for ( i = bottom; i < pos; i++ ) {
1097 color[i-1] = color[i];
1098 entry[i-1] = entry[i];
1099 }
1100 bottom--;
1101 color[pos] = value;
1102 entry[pos] = pixel;
1103 }
1104
1105 }
1106
1107 return( pixel );
1108 }
1109
1110
1111 bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
1112 {
1113 wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
1114 wxCHECK_MSG( depth == -1, FALSE, wxT("invalid bitmap depth") )
1115
1116 m_refData = new wxBitmapRefData();
1117
1118 int width = image.GetWidth();
1119 int height = image.GetHeight();
1120
1121 SetHeight( height );
1122 SetWidth( width );
1123
1124 Display *dpy = (Display*) wxGetDisplay();
1125 Visual* vis = DefaultVisual( dpy, DefaultScreen( dpy ) );
1126 int bpp = DefaultDepth( dpy, DefaultScreen( dpy ) );
1127
1128 // Create image
1129
1130 XImage *data_image = XCreateImage( dpy, vis, bpp, ZPixmap, 0, 0, width, height, 32, 0 );
1131 data_image->data = (char*) malloc( data_image->bytes_per_line * data_image->height );
1132
1133 Create( width, height, bpp );
1134
1135 // Create mask
1136
1137 XImage *mask_image = (XImage*) NULL;
1138 if (image.HasMask())
1139 {
1140 mask_image = XCreateImage( dpy, vis, 1, ZPixmap, 0, 0, width, height, 32, 0 );
1141 mask_image->data = (char*) malloc( mask_image->bytes_per_line * mask_image->height );
1142 }
1143
1144 // Retrieve depth info
1145
1146 XVisualInfo vinfo_template;
1147 XVisualInfo *vi;
1148
1149 vinfo_template.visual = vis;
1150 vinfo_template.visualid = XVisualIDFromVisual( vis );
1151 vinfo_template.depth = bpp;
1152 int nitem = 0;
1153
1154 vi = XGetVisualInfo( dpy, VisualIDMask|VisualDepthMask,
1155 &vinfo_template, &nitem );
1156
1157 wxCHECK_MSG( vi, FALSE, wxT("no visual") );
1158
1159 if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
1160 if (bpp < 8) bpp = 8;
1161
1162 // Render
1163
1164 enum byte_order { RGB, RBG, BRG, BGR, GRB, GBR };
1165 byte_order b_o = RGB;
1166
1167 if (bpp >= 24)
1168 {
1169 if ((vi->red_mask > vi->green_mask) && (vi->green_mask > vi->blue_mask)) b_o = RGB;
1170 else if ((vi->red_mask > vi->blue_mask) && (vi->blue_mask > vi->green_mask)) b_o = RGB;
1171 else if ((vi->blue_mask > vi->red_mask) && (vi->red_mask > vi->green_mask)) b_o = BRG;
1172 else if ((vi->blue_mask > vi->green_mask) && (vi->green_mask > vi->red_mask)) b_o = BGR;
1173 else if ((vi->green_mask > vi->red_mask) && (vi->red_mask > vi->blue_mask)) b_o = GRB;
1174 else if ((vi->green_mask > vi->blue_mask) && (vi->blue_mask > vi->red_mask)) b_o = GBR;
1175 }
1176
1177 XFree( vi );
1178
1179 int r_mask = image.GetMaskRed();
1180 int g_mask = image.GetMaskGreen();
1181 int b_mask = image.GetMaskBlue();
1182
1183 XColor colors[256];
1184 if (bpp == 8)
1185 {
1186 Colormap cmap = (Colormap) wxTheApp->GetMainColormap( dpy );
1187
1188 for (int i = 0; i < 256; i++) colors[i].pixel = i;
1189 XQueryColors( dpy, cmap, colors, 256 );
1190 }
1191
1192 wxSearchColor scolor( 256, colors );
1193 unsigned char* data = image.GetData();
1194
1195 bool hasMask = image.HasMask();
1196
1197 int index = 0;
1198 for (int y = 0; y < height; y++)
1199 {
1200 for (int x = 0; x < width; x++)
1201 {
1202 int r = data[index];
1203 index++;
1204 int g = data[index];
1205 index++;
1206 int b = data[index];
1207 index++;
1208
1209 if (hasMask)
1210 {
1211 if ((r == r_mask) && (b == b_mask) && (g == g_mask))
1212 XPutPixel( mask_image, x, y, 0 );
1213 else
1214 XPutPixel( mask_image, x, y, 1 );
1215 }
1216
1217 switch (bpp)
1218 {
1219 case 8:
1220 {
1221 #if 0 // Old, slower code
1222 int pixel = -1;
1223 /*
1224 if (wxTheApp->m_colorCube)
1225 {
1226 pixel = wxTheApp->m_colorCube
1227 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
1228 }
1229 else
1230 {
1231 */
1232 int max = 3 * (65536);
1233 for (int i = 0; i < 256; i++)
1234 {
1235 int rdiff = (r << 8) - colors[i].red;
1236 int gdiff = (g << 8) - colors[i].green;
1237 int bdiff = (b << 8) - colors[i].blue;
1238 int sum = abs (rdiff) + abs (gdiff) + abs (bdiff);
1239 if (sum < max) { pixel = i; max = sum; }
1240 }
1241 /*
1242 }
1243 */
1244 #endif
1245
1246 // And this is all to get the 'right' color...
1247 int pixel = scolor.SearchColor( r, g, b );
1248 XPutPixel( data_image, x, y, pixel );
1249 break;
1250 }
1251 case 15:
1252 {
1253 int pixel = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
1254 XPutPixel( data_image, x, y, pixel );
1255 break;
1256 }
1257 case 16:
1258 {
1259 int pixel = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
1260 XPutPixel( data_image, x, y, pixel );
1261 break;
1262 }
1263 case 32:
1264 case 24:
1265 {
1266 int pixel = 0;
1267 switch (b_o)
1268 {
1269 case RGB: pixel = (r << 16) | (g << 8) | b; break;
1270 case RBG: pixel = (r << 16) | (b << 8) | g; break;
1271 case BRG: pixel = (b << 16) | (r << 8) | g; break;
1272 case BGR: pixel = (b << 16) | (g << 8) | r; break;
1273 case GRB: pixel = (g << 16) | (r << 8) | b; break;
1274 case GBR: pixel = (g << 16) | (b << 8) | r; break;
1275 }
1276 XPutPixel( data_image, x, y, pixel );
1277 }
1278 default: break;
1279 }
1280 } // for
1281 } // for
1282
1283 // Blit picture
1284
1285 XGCValues gcvalues;
1286 gcvalues.foreground = BlackPixel( dpy, DefaultScreen( dpy ) );
1287 GC gc = XCreateGC( dpy, RootWindow ( dpy, DefaultScreen(dpy) ), GCForeground, &gcvalues );
1288 XPutImage( dpy, (Drawable)GetPixmap(), gc, data_image, 0, 0, 0, 0, width, height );
1289
1290 XDestroyImage( data_image );
1291 XFreeGC( dpy, gc );
1292
1293 // Blit mask
1294 if (image.HasMask())
1295 {
1296 wxBitmap maskBitmap(width, height, 1);
1297
1298 GC gcMask = XCreateGC( dpy, (Pixmap) maskBitmap.GetPixmap(), (XtGCMask) 0, (XGCValues*)NULL );
1299 XPutImage( dpy, (Drawable)maskBitmap.GetPixmap(), gcMask, mask_image, 0, 0, 0, 0, width, height );
1300
1301 XDestroyImage( mask_image );
1302 XFreeGC( dpy, gcMask );
1303
1304 wxMask* mask = new wxMask;
1305 mask->SetPixmap(maskBitmap.GetPixmap());
1306
1307 SetMask(mask);
1308
1309 maskBitmap.SetPixmapNull();
1310 }
1311
1312
1313 return TRUE;
1314 }
1315
1316 wxImage wxBitmap::ConvertToImage() const
1317 {
1318 wxImage image;
1319
1320 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
1321
1322 Display *dpy = (Display*) wxGetDisplay();
1323 Visual* vis = DefaultVisual( dpy, DefaultScreen( dpy ) );
1324 int bpp = DefaultDepth( dpy, DefaultScreen( dpy ) );
1325
1326 XImage *ximage = XGetImage( dpy,
1327 (Drawable)GetPixmap(),
1328 0, 0,
1329 GetWidth(), GetHeight(),
1330 AllPlanes, ZPixmap );
1331
1332 wxCHECK_MSG( ximage, wxNullImage, wxT("couldn't create image") );
1333
1334 image.Create( GetWidth(), GetHeight() );
1335 char unsigned *data = image.GetData();
1336
1337 if (!data)
1338 {
1339 XDestroyImage( ximage );
1340 wxFAIL_MSG( wxT("couldn't create image") );
1341 return wxNullImage;
1342 }
1343
1344 /*
1345 GdkImage *gdk_image_mask = (GdkImage*) NULL;
1346 if (GetMask())
1347 {
1348 gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
1349 0, 0,
1350 GetWidth(), GetHeight() );
1351
1352 image.SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1353 }
1354 */
1355
1356 // Retrieve depth info
1357
1358 XVisualInfo vinfo_template;
1359 XVisualInfo *vi;
1360
1361 vinfo_template.visual = vis;
1362 vinfo_template.visualid = XVisualIDFromVisual( vis );
1363 vinfo_template.depth = bpp;
1364 int nitem = 0;
1365
1366 vi = XGetVisualInfo( dpy, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
1367
1368 wxCHECK_MSG( vi, wxNullImage, wxT("no visual") );
1369
1370 if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
1371
1372 XFree( vi );
1373
1374 XColor colors[256];
1375 if (bpp == 8)
1376 {
1377 Colormap cmap = (Colormap)wxTheApp->GetMainColormap( dpy );
1378
1379 for (int i = 0; i < 256; i++) colors[i].pixel = i;
1380 XQueryColors( dpy, cmap, colors, 256 );
1381 }
1382
1383 long pos = 0;
1384 for (int j = 0; j < GetHeight(); j++)
1385 {
1386 for (int i = 0; i < GetWidth(); i++)
1387 {
1388 int pixel = XGetPixel( ximage, i, j );
1389 if (bpp <= 8)
1390 {
1391 data[pos] = colors[pixel].red >> 8;
1392 data[pos+1] = colors[pixel].green >> 8;
1393 data[pos+2] = colors[pixel].blue >> 8;
1394 } else if (bpp == 15)
1395 {
1396 data[pos] = (pixel >> 7) & 0xf8;
1397 data[pos+1] = (pixel >> 2) & 0xf8;
1398 data[pos+2] = (pixel << 3) & 0xf8;
1399 } else if (bpp == 16)
1400 {
1401 data[pos] = (pixel >> 8) & 0xf8;
1402 data[pos+1] = (pixel >> 3) & 0xfc;
1403 data[pos+2] = (pixel << 3) & 0xf8;
1404 } else
1405 {
1406 data[pos] = (pixel >> 16) & 0xff;
1407 data[pos+1] = (pixel >> 8) & 0xff;
1408 data[pos+2] = pixel & 0xff;
1409 }
1410
1411 /*
1412 if (gdk_image_mask)
1413 {
1414 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1415 if (mask_pixel == 0)
1416 {
1417 data[pos] = 16;
1418 data[pos+1] = 16;
1419 data[pos+2] = 16;
1420 }
1421 }
1422 */
1423
1424 pos += 3;
1425 }
1426 }
1427
1428 XDestroyImage( ximage );
1429 /*
1430 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
1431 */
1432
1433 return image;
1434 }