]> git.saurik.com Git - wxWidgets.git/blob - src/motif/bitmap.cpp
More Motif stuff incl. beginnings of wxToolBar
[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 #include "wx/setup.h"
17 #include "wx/utils.h"
18 #include "wx/palette.h"
19 #include "wx/bitmap.h"
20 #include "wx/icon.h"
21 #include "wx/log.h"
22 #include "wx/control.h"
23
24 #include <Xm/Xm.h>
25
26 #include "wx/motif/private.h"
27
28 // TODO: correct symbol, path?
29 #if wxUSE_XPM
30 #include <X11/xpm.h>
31 #endif
32
33 #if !USE_SHARED_LIBRARIES
34 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
35 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
36 #endif
37
38 wxBitmapRefData::wxBitmapRefData()
39 {
40 m_ok = FALSE;
41 m_width = 0;
42 m_height = 0;
43 m_depth = 0;
44 m_quality = 0;
45 m_numColors = 0;
46 m_bitmapMask = NULL;
47
48 m_pixmap = (WXPixmap) 0;
49 m_display = (WXDisplay*) 0;
50
51 m_freePixmap = TRUE; //TODO: necessary?
52 m_freeColors = (unsigned long*) 0;
53 m_freeColorsCount = 0;
54
55 // These 5 variables are for wxControl
56 m_insensPixmap = (WXPixmap) 0;
57 m_labelPixmap = (WXPixmap) 0;
58 m_armPixmap = (WXPixmap) 0;
59 m_image = (WXImage*) 0;
60 m_insensImage = (WXImage*) 0;
61 }
62
63 wxBitmapRefData::~wxBitmapRefData()
64 {
65 if (m_labelPixmap)
66 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_labelPixmap);
67
68 if (m_armPixmap)
69 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_armPixmap);
70
71 if (m_insensPixmap)
72 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_insensPixmap);
73
74 if (m_image)
75 {
76 XmUninstallImage ((XImage*) m_image);
77 XtFree ((char *) (XImage*) m_image);
78 }
79
80 if (m_insensImage)
81 {
82 XmUninstallImage ((XImage*) m_insensImage);
83 delete[] ((XImage*) m_insensImage)->data;
84 XtFree ((char *) (XImage*) m_insensImage);
85 }
86 if (m_pixmap && m_freePixmap)
87 XFreePixmap ((Display*) m_display, (Pixmap) m_pixmap);
88
89 if (m_freeColors)
90 {
91 int screen = DefaultScreen((Display*) m_display);
92 Colormap cmp = DefaultColormap((Display*) m_display,screen);
93 long llp;
94 for(llp = 0;llp < m_freeColorsCount;llp++)
95 XFreeColors((Display*) m_display, cmp, &m_freeColors[llp], 1, 0L);
96 delete m_freeColors;
97 };
98
99 if (m_bitmapMask)
100 delete m_bitmapMask;
101 m_bitmapMask = NULL;
102 }
103
104 wxList wxBitmap::sm_handlers;
105
106 wxBitmap::wxBitmap()
107 {
108 m_refData = NULL;
109
110 if ( wxTheBitmapList )
111 wxTheBitmapList->AddBitmap(this);
112 }
113
114 wxBitmap::~wxBitmap()
115 {
116 if (wxTheBitmapList)
117 wxTheBitmapList->DeleteObject(this);
118 }
119
120 wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
121 {
122 m_refData = new wxBitmapRefData;
123
124 (void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, depth);
125
126 if ( wxTheBitmapList )
127 wxTheBitmapList->AddBitmap(this);
128 }
129
130 wxBitmap::wxBitmap(int w, int h, int d)
131 {
132 (void)Create(w, h, d);
133
134 if ( wxTheBitmapList )
135 wxTheBitmapList->AddBitmap(this);
136 }
137
138 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
139 {
140 (void) Create(data, type, width, height, depth);
141
142 if ( wxTheBitmapList )
143 wxTheBitmapList->AddBitmap(this);
144 }
145
146 wxBitmap::wxBitmap(const wxString& filename, long type)
147 {
148 LoadFile(filename, (int)type);
149
150 if ( wxTheBitmapList )
151 wxTheBitmapList->AddBitmap(this);
152 }
153
154 // Create from XPM data
155 static wxControl* sg_Control = NULL;
156 wxBitmap::wxBitmap(char **data, wxControl* control)
157 {
158 // Pass the control to the Create function using a global
159 sg_Control = control;
160
161 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
162
163 sg_Control = (wxControl*) NULL;
164 }
165
166 bool wxBitmap::Create(int w, int h, int d)
167 {
168 UnRef();
169
170 m_refData = new wxBitmapRefData;
171
172 if (d < 1)
173 d = wxDisplayDepth();
174
175 M_BITMAPDATA->m_width = w;
176 M_BITMAPDATA->m_height = h;
177 M_BITMAPDATA->m_depth = d;
178 M_BITMAPDATA->m_freePixmap = TRUE;
179
180 Display *dpy = (Display*) wxGetDisplay();
181
182 M_BITMAPDATA->m_display = dpy; /* MATTHEW: [4] Remember the display */
183
184 M_BITMAPDATA->m_pixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
185 w, h, d);
186
187 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_pixmap != (WXPixmap) 0) ;
188 return M_BITMAPDATA->m_ok;
189 }
190
191 bool wxBitmap::LoadFile(const wxString& filename, long type)
192 {
193 UnRef();
194
195 m_refData = new wxBitmapRefData;
196
197 wxBitmapHandler *handler = FindHandler(type);
198
199 if ( handler == NULL ) {
200 wxLogWarning("no bitmap handler for type %d defined.", type);
201
202 return FALSE;
203 }
204
205 return handler->LoadFile(this, filename, type, -1, -1);
206 }
207
208 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
209 {
210 UnRef();
211
212 m_refData = new wxBitmapRefData;
213
214 wxBitmapHandler *handler = FindHandler(type);
215
216 if ( handler == NULL ) {
217 wxLogWarning("no bitmap handler for type %d defined.", type);
218
219 return FALSE;
220 }
221
222 return handler->Create(this, data, type, width, height, depth);
223 }
224
225 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
226 {
227 wxBitmapHandler *handler = FindHandler(type);
228
229 if ( handler == NULL ) {
230 wxLogWarning("no bitmap handler for type %d defined.", type);
231
232 return FALSE;
233 }
234
235 return handler->SaveFile(this, filename, type, palette);
236 }
237
238 void wxBitmap::SetWidth(int w)
239 {
240 if (!M_BITMAPDATA)
241 m_refData = new wxBitmapRefData;
242
243 M_BITMAPDATA->m_width = w;
244 }
245
246 void wxBitmap::SetHeight(int h)
247 {
248 if (!M_BITMAPDATA)
249 m_refData = new wxBitmapRefData;
250
251 M_BITMAPDATA->m_height = h;
252 }
253
254 void wxBitmap::SetDepth(int d)
255 {
256 if (!M_BITMAPDATA)
257 m_refData = new wxBitmapRefData;
258
259 M_BITMAPDATA->m_depth = d;
260 }
261
262 void wxBitmap::SetQuality(int q)
263 {
264 if (!M_BITMAPDATA)
265 m_refData = new wxBitmapRefData;
266
267 M_BITMAPDATA->m_quality = q;
268 }
269
270 void wxBitmap::SetOk(bool isOk)
271 {
272 if (!M_BITMAPDATA)
273 m_refData = new wxBitmapRefData;
274
275 M_BITMAPDATA->m_ok = isOk;
276 }
277
278 void wxBitmap::SetPalette(const wxPalette& palette)
279 {
280 if (!M_BITMAPDATA)
281 m_refData = new wxBitmapRefData;
282
283 M_BITMAPDATA->m_bitmapPalette = palette ;
284 }
285
286 void wxBitmap::SetMask(wxMask *mask)
287 {
288 if (!M_BITMAPDATA)
289 m_refData = new wxBitmapRefData;
290
291 M_BITMAPDATA->m_bitmapMask = mask ;
292 }
293
294 void wxBitmap::AddHandler(wxBitmapHandler *handler)
295 {
296 sm_handlers.Append(handler);
297 }
298
299 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
300 {
301 sm_handlers.Insert(handler);
302 }
303
304 bool wxBitmap::RemoveHandler(const wxString& name)
305 {
306 wxBitmapHandler *handler = FindHandler(name);
307 if ( handler )
308 {
309 sm_handlers.DeleteObject(handler);
310 return TRUE;
311 }
312 else
313 return FALSE;
314 }
315
316 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
317 {
318 wxNode *node = sm_handlers.First();
319 while ( node )
320 {
321 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
322 if ( handler->GetName() == name )
323 return handler;
324 node = node->Next();
325 }
326 return NULL;
327 }
328
329 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
330 {
331 wxNode *node = sm_handlers.First();
332 while ( node )
333 {
334 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
335 if ( handler->GetExtension() == extension &&
336 (bitmapType == -1 || handler->GetType() == bitmapType) )
337 return handler;
338 node = node->Next();
339 }
340 return NULL;
341 }
342
343 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
344 {
345 wxNode *node = sm_handlers.First();
346 while ( node )
347 {
348 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
349 if (handler->GetType() == bitmapType)
350 return handler;
351 node = node->Next();
352 }
353 return NULL;
354 }
355
356 /*
357 * wxMask
358 */
359
360 wxMask::wxMask()
361 {
362 m_pixmap = (WXPixmap) 0;
363 }
364
365 // Construct a mask from a bitmap and a colour indicating
366 // the transparent area
367 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
368 {
369 m_pixmap = (WXPixmap) 0;
370
371 Create(bitmap, colour);
372 }
373
374 // Construct a mask from a bitmap and a palette index indicating
375 // the transparent area
376 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
377 {
378 m_pixmap = (WXPixmap) 0;
379
380 Create(bitmap, paletteIndex);
381 }
382
383 // Construct a mask from a mono bitmap (copies the bitmap).
384 wxMask::wxMask(const wxBitmap& bitmap)
385 {
386 m_pixmap = (WXPixmap) 0;
387
388 Create(bitmap);
389 }
390
391 wxMask::~wxMask()
392 {
393 // TODO: this may be the wrong display
394 if ( m_pixmap )
395 XFreePixmap ((Display*) wxGetDisplay(), (Pixmap) m_pixmap);
396 }
397
398 // Create a mask from a mono bitmap (copies the bitmap).
399 bool wxMask::Create(const wxBitmap& bitmap)
400 {
401 // TODO
402 return FALSE;
403 }
404
405 // Create a mask from a bitmap and a palette index indicating
406 // the transparent area
407 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
408 {
409 // TODO
410 return FALSE;
411 }
412
413 // Create a mask from a bitmap and a colour indicating
414 // the transparent area
415 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
416 {
417 // TODO
418 return FALSE;
419 }
420
421 /*
422 * wxBitmapHandler
423 */
424
425 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
426
427 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
428 {
429 return FALSE;
430 }
431
432 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
433 int desiredWidth, int desiredHeight)
434 {
435 return FALSE;
436 }
437
438 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
439 {
440 return FALSE;
441 }
442
443 /*
444 * Standard handlers
445 */
446
447 class WXDLLEXPORT wxXBMFileHandler: public wxBitmapHandler
448 {
449 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler)
450 public:
451 inline wxXBMFileHandler()
452 {
453 m_name = "XBM file";
454 m_extension = "xbm";
455 m_type = wxBITMAP_TYPE_XBM;
456 };
457
458 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
459 int desiredWidth, int desiredHeight);
460 };
461 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
462
463 bool wxXBMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
464 int desiredWidth, int desiredHeight)
465 {
466 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
467
468 int hotX, hotY;
469 unsigned int w, h;
470 Pixmap pixmap;
471
472 Display *dpy = (Display*) wxGetDisplay();
473 M_BITMAPDATA->m_display = (WXDisplay*) dpy;
474
475 int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
476 (char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
477 M_BITMAPHANDLERDATA->m_width = w;
478 M_BITMAPHANDLERDATA->m_height = h;
479 M_BITMAPHANDLERDATA->m_depth = 1;
480 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
481
482 if ((value == BitmapFileInvalid) ||
483 (value == BitmapOpenFailed) ||
484 (value == BitmapNoMemory))
485 {
486 M_BITMAPHANDLERDATA->m_ok = FALSE;
487 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) 0;
488 }
489 else
490 M_BITMAPHANDLERDATA->m_ok = TRUE;
491
492 return M_BITMAPHANDLERDATA->m_ok ;
493 }
494
495 class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
496 {
497 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
498 public:
499 inline wxXBMDataHandler()
500 {
501 m_name = "XBM data";
502 m_extension = "xbm";
503 m_type = wxBITMAP_TYPE_XBM_DATA;
504 };
505
506 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
507 };
508 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
509
510 bool wxXBMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
511 {
512 M_BITMAPHANDLERDATA->m_width = width;
513 M_BITMAPHANDLERDATA->m_height = height;
514 M_BITMAPHANDLERDATA->m_depth = 1;
515 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
516
517 Display *dpy = (Display*) wxGetDisplay();
518 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
519
520 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) XCreateBitmapFromData (dpy, RootWindow (dpy, DefaultScreen (dpy)), (char*) data, width, height);
521 M_BITMAPHANDLERDATA->m_ok = (M_BITMAPHANDLERDATA->m_pixmap != (WXPixmap) 0) ;
522
523 // code for wxControl. TODO: can we avoid doing this until we need it?
524 // E.g. have CreateButtonPixmaps which is called on demand.
525 XImage* image = (XImage *) XtMalloc (sizeof (XImage));
526 image->width = width;
527 image->height = height;
528 image->data = (char*) data;
529 image->depth = 1;
530 image->xoffset = 0;
531 image->format = XYBitmap;
532 image->byte_order = LSBFirst;
533 image->bitmap_unit = 8;
534 image->bitmap_bit_order = LSBFirst;
535 image->bitmap_pad = 8;
536 image->bytes_per_line = (width + 7) >> 3;
537
538 char tmp[128];
539 sprintf (tmp, "Im%x", (unsigned int) image);
540 XmInstallImage (image, tmp);
541
542 // Build our manually stipped pixmap.
543
544 int bpl = (width + 7) / 8;
545 char *data1 = new char[height * bpl];
546 char* bits = (char*) data;
547 int i;
548 for (i = 0; i < height; i++)
549 {
550 int mask = i % 2 ? 0x55 : 0xaa;
551 int j;
552 for (j = 0; j < bpl; j++)
553 data1[i * bpl + j] = bits[i * bpl + j] & mask;
554 }
555 XImage* insensImage = (XImage *) XtMalloc (sizeof (XImage));
556 insensImage->width = width;
557 insensImage->height = height;
558 insensImage->data = data1;
559 insensImage->depth = 1;
560 insensImage->xoffset = 0;
561 insensImage->format = XYBitmap;
562 insensImage->byte_order = LSBFirst;
563 insensImage->bitmap_unit = 8;
564 insensImage->bitmap_bit_order = LSBFirst;
565 insensImage->bitmap_pad = 8;
566 insensImage->bytes_per_line = bpl;
567
568 sprintf (tmp, "Not%x", (unsigned int)insensImage);
569 XmInstallImage (insensImage, tmp);
570
571 M_BITMAPHANDLERDATA->m_image = (WXImage*) image;
572 M_BITMAPHANDLERDATA->m_insensImage = (WXImage*) insensImage;
573
574 return TRUE;
575 }
576
577 #if wxUSE_XPM
578 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
579 {
580 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
581 public:
582 inline wxXPMFileHandler()
583 {
584 m_name = "XPM file";
585 m_extension = "xpm";
586 m_type = wxBITMAP_TYPE_XPM;
587 };
588
589 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
590 int desiredWidth, int desiredHeight);
591 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
592 };
593
594 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
595
596 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
597 int desiredWidth, int desiredHeight)
598 {
599 Display *dpy = (Display*) wxGetDisplay();
600 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
601
602 XpmAttributes xpmAttr;
603 Pixmap pixmap;
604 Pixmap mask = 0;
605
606 M_BITMAPHANDLERDATA->m_ok = FALSE;
607 xpmAttr.valuemask = XpmReturnInfos | XpmCloseness;
608 xpmAttr.closeness = 40000;
609 int errorStatus = XpmReadFileToPixmap(dpy,
610 RootWindow(dpy, DefaultScreen(dpy)), (char*) (const char*) name,
611 &pixmap, &mask, &xpmAttr);
612
613 if (errorStatus == XpmSuccess)
614 {
615 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
616 if ( mask )
617 {
618 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
619 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
620 }
621
622 unsigned int depthRet;
623 int xRet, yRet;
624 unsigned int widthRet, heightRet, borderWidthRet;
625 Window rootWindowRet;
626 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
627 &widthRet, &heightRet, &borderWidthRet, &depthRet);
628
629 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
630 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
631
632 /*
633 if ( xpmAttr.npixels > 2 )
634 {
635 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
636 } else
637 {
638 M_BITMAPHANDLERDATA->m_depth = 1; // mono
639 }
640 */
641
642 M_BITMAPHANDLERDATA->m_depth = depthRet;
643
644 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
645
646 XpmFreeAttributes(&xpmAttr);
647
648 M_BITMAPHANDLERDATA->m_ok = TRUE;
649 return TRUE;
650 } else
651 {
652 // XpmDebugError(errorStatus, name);
653 M_BITMAPHANDLERDATA->m_ok = FALSE;
654 return FALSE;
655 }
656 }
657
658 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
659 {
660 if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
661 {
662 Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
663 int errorStatus = XpmWriteFileFromPixmap(dpy, (char*) (const char*) name,
664 (Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
665 (M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
666 (XpmAttributes *) NULL);
667 if (errorStatus == XpmSuccess)
668 return TRUE;
669 else
670 return FALSE;
671 }
672 else
673 return FALSE;
674 }
675
676 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
677 {
678 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
679 public:
680 inline wxXPMDataHandler()
681 {
682 m_name = "XPM data";
683 m_extension = "xpm";
684 m_type = wxBITMAP_TYPE_XPM_DATA;
685 };
686
687 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
688 };
689 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
690
691 bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
692 {
693 M_BITMAPHANDLERDATA->m_width = width;
694 M_BITMAPHANDLERDATA->m_height = height;
695 M_BITMAPHANDLERDATA->m_depth = 1;
696 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
697
698 Display *dpy = (Display*) wxGetDisplay();
699 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
700
701 XpmAttributes xpmAttr;
702
703 xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
704
705 XpmColorSymbol symbolicColors[4];
706 if (sg_Control && sg_Control->GetMainWidget())
707 {
708 symbolicColors[0].name = "foreground";
709 symbolicColors[0].value = NULL;
710 symbolicColors[1].name = "background";
711 symbolicColors[1].value = NULL;
712 XtVaGetValues((Widget) sg_Control->GetMainWidget(),
713 XmNforeground, &symbolicColors[0].pixel,
714 XmNbackground, &symbolicColors[1].pixel,NULL);
715 xpmAttr.numsymbols = 2;
716 xpmAttr.colorsymbols = symbolicColors;
717 xpmAttr.valuemask |= XpmColorSymbols; // add flag
718 }
719
720 Pixmap pixmap;
721 Pixmap mask = 0;
722 int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
723 (char**) data, &pixmap, &mask, &xpmAttr);
724 if (ErrorStatus == XpmSuccess)
725 {
726 // Set attributes
727 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
728 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
729
730 unsigned int depthRet;
731 int xRet, yRet;
732 unsigned int widthRet, heightRet, borderWidthRet;
733 Window rootWindowRet;
734 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
735 &widthRet, &heightRet, &borderWidthRet, &depthRet);
736
737 /*
738 if ( xpmAttr.npixels > 2 )
739 {
740 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
741 } else
742 {
743 M_BITMAPHANDLERDATA->m_depth = 1; // mono
744 }
745 */
746
747 M_BITMAPHANDLERDATA->m_depth = depthRet;
748
749 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
750 XpmFreeAttributes(&xpmAttr);
751 M_BITMAPHANDLERDATA->m_ok = TRUE;
752 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
753 if ( mask )
754 {
755 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
756 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
757 }
758 }
759 else
760 {
761 // XpmDebugError(ErrorStatus, NULL);
762 M_BITMAPHANDLERDATA->m_ok = FALSE;
763 }
764 return M_BITMAPHANDLERDATA->m_ok ;
765 }
766
767 #endif
768
769 void wxBitmap::CleanUpHandlers()
770 {
771 wxNode *node = sm_handlers.First();
772 while ( node )
773 {
774 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
775 wxNode *next = node->Next();
776 delete handler;
777 delete node;
778 node = next;
779 }
780 }
781
782 void wxBitmap::InitStandardHandlers()
783 {
784 // Initialize all standard bitmap or derived class handlers here.
785 AddHandler(new wxXBMFileHandler);
786 AddHandler(new wxXBMDataHandler);
787
788 // XPM is considered standard for Moif, although it can be omitted if absolutely
789 // necessary.
790 #if wxUSE_XPM
791 AddHandler(new wxXPMFileHandler);
792 AddHandler(new wxXPMDataHandler);
793 #endif
794 }
795
796 WXPixmap wxBitmap::GetLabelPixmap (WXWidget w)
797 {
798 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
799 return M_BITMAPDATA->m_pixmap;
800
801 Display *dpy = (Display*) M_BITMAPDATA->m_display;
802
803 #ifdef FOO
804 /*
805 If we do:
806 if (labelPixmap) return labelPixmap;
807 things can be wrong, because colors can have been changed.
808
809 If we do:
810 if (labelPixmap)
811 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
812 we got BadDrawable if the pixmap is referenced by multiples widgets
813
814 this is a catch22!!
815
816 So, before doing thing really clean, I just do nothing; if the pixmap is
817 referenced by many widgets, Motif performs caching functions.
818 And if pixmap is referenced with multiples colors, we just have some
819 memory leaks... I hope we can deal with them...
820 */
821 // Must be destroyed, because colours can have been changed!
822 if (M_BITMAPDATA->m_labelPixmap)
823 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_labelPixmap);
824 #endif
825
826 char tmp[128];
827 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
828
829 Pixel fg, bg;
830 Widget widget = (Widget) w;
831
832 while (XmIsGadget ( widget ))
833 widget = XtParent (widget);
834 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
835
836 M_BITMAPDATA->m_labelPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
837
838 return M_BITMAPDATA->m_labelPixmap;
839 }
840
841 WXPixmap wxBitmap::GetArmPixmap (WXWidget w)
842 {
843 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
844 return M_BITMAPDATA->m_pixmap;
845
846 Display *dpy = (Display*) M_BITMAPDATA->m_display;
847 #ifdef FOO
848 See GetLabelPixmap () comment
849 // Must be destroyed, because colours can have been changed!
850 if (M_BITMAPDATA->m_armPixmap)
851 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_armPixmap);
852 #endif
853
854 char tmp[128];
855 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
856
857 Pixel fg, bg;
858 Widget widget = (Widget) w;
859
860 XtVaGetValues (widget, XmNarmColor, &bg, NULL);
861 while (XmIsGadget (widget))
862 widget = XtParent (widget);
863 XtVaGetValues (widget, XmNforeground, &fg, NULL);
864
865 M_BITMAPDATA->m_armPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
866
867 return M_BITMAPDATA->m_armPixmap;
868 }
869
870 WXPixmap wxBitmap::GetInsensPixmap (WXWidget w)
871 {
872 Display *dpy = (Display*) M_BITMAPDATA->m_display;
873
874 if (M_BITMAPDATA->m_insensPixmap)
875 return M_BITMAPDATA->m_insensPixmap;
876
877 if (!w)
878 {
879 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XCreateInsensitivePixmap(dpy, (Pixmap) M_BITMAPDATA->m_pixmap);
880 if (M_BITMAPDATA->m_insensPixmap)
881 return M_BITMAPDATA->m_insensPixmap;
882 else
883 return M_BITMAPDATA->m_pixmap;
884 }
885
886 if (M_BITMAPDATA->m_insensImage == (WXPixmap) 0)
887 return M_BITMAPDATA->m_pixmap;
888
889 #ifdef FOO
890 See GetLabelPixmap () comment
891 // Must be destroyed, because colours can have been changed!
892 if (M_BITMAPDATA->m_insensPixmap)
893 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), (Pixmap) M_BITMAPDATA->m_insensPixmap);
894 #endif
895
896 char tmp[128];
897 sprintf (tmp, "Not%x", (unsigned int) M_BITMAPDATA->m_insensImage);
898
899 Pixel fg, bg;
900 Widget widget = (Widget) w;
901
902 while (XmIsGadget (widget))
903 widget = XtParent (widget);
904 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
905
906 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
907
908 return M_BITMAPDATA->m_insensPixmap;
909 }
910
911 // We may need this sometime...
912
913 /****************************************************************************
914
915 NAME
916 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
917
918 SYNOPSIS
919 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
920
921 DESCRIPTION
922 This function creates a grayed-out copy of the argument pixmap, suitable
923 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
924
925 RETURN VALUES
926 The return value is the new Pixmap id or zero on error. Errors include
927 a NULL display argument or an invalid Pixmap argument.
928
929 ERRORS
930 If one of the XLib functions fail, it will produce a X error. The
931 default X error handler prints a diagnostic and calls exit().
932
933 SEE ALSO
934 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
935 XFillRectangle(3), exit(2)
936
937 AUTHOR
938 John R Veregge - john@puente.jpl.nasa.gov
939 Advanced Engineering and Prototyping Group (AEG)
940 Information Systems Technology Section (395)
941 Jet Propulsion Lab - Calif Institute of Technology
942
943 *****************************************************************************/
944
945 Pixmap
946 XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
947
948 {
949 static
950 char stipple_data[] =
951 {
952 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
953 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
954 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
955 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
956 };
957 GC gc;
958 Pixmap ipixmap, stipple;
959 unsigned width, height, depth;
960
961 Window window; /* These return values */
962 unsigned border; /* from XGetGeometry() */
963 int x, y; /* are not needed. */
964
965 ipixmap = 0;
966
967 if ( NULL == display || 0 == pixmap )
968 return ipixmap;
969
970 if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
971 &width, &height, &border, &depth )
972 )
973 return ipixmap; /* BadDrawable: probably an invalid pixmap */
974
975 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
976 */
977 stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
978 if ( 0 != stipple )
979 {
980 gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
981 if ( NULL != gc )
982 {
983 /* Create an identical copy of the argument pixmap.
984 */
985 ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
986 if ( 0 != ipixmap )
987 {
988 /* Copy the argument pixmap into the new pixmap.
989 */
990 XCopyArea( display, pixmap, ipixmap,
991 gc, 0, 0, width, height, 0, 0 );
992
993 /* Refill the new pixmap using the stipple algorithm/pixmap.
994 */
995 XSetStipple( display, gc, stipple );
996 XSetFillStyle( display, gc, FillStippled );
997 XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
998 }
999 XFreeGC( display, gc );
1000 }
1001 XFreePixmap( display, stipple );
1002 }
1003 return ipixmap;
1004 }
1005