]> git.saurik.com Git - wxWidgets.git/blame - src/motif/bitmap.cpp
More Motif additions: mdi and sashtest samples now just about work!
[wxWidgets.git] / src / motif / bitmap.cpp
CommitLineData
4bb6408c
JS
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"
a4294b78 22#include "wx/control.h"
4bb6408c 23
f97c9854
JS
24#include <Xm/Xm.h>
25
26#include "wx/motif/private.h"
27
28// TODO: correct symbol, path?
a4294b78 29#if wxUSE_XPM
f97c9854
JS
30#include <X11/xpm.h>
31#endif
32
4bb6408c
JS
33#if !USE_SHARED_LIBRARIES
34IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
35IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
36#endif
37
38wxBitmapRefData::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;
16c1f7f3
JS
47
48 m_pixmap = (WXPixmap) 0;
49 m_display = (WXDisplay*) 0;
f97c9854
JS
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;
4bb6408c
JS
61}
62
63wxBitmapRefData::~wxBitmapRefData()
64{
f97c9854
JS
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 };
4bb6408c
JS
98
99 if (m_bitmapMask)
100 delete m_bitmapMask;
101 m_bitmapMask = NULL;
102}
103
104wxList wxBitmap::sm_handlers;
105
106wxBitmap::wxBitmap()
107{
108 m_refData = NULL;
109
110 if ( wxTheBitmapList )
111 wxTheBitmapList->AddBitmap(this);
112}
113
114wxBitmap::~wxBitmap()
115{
116 if (wxTheBitmapList)
117 wxTheBitmapList->DeleteObject(this);
118}
119
f97c9854 120wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
4bb6408c
JS
121{
122 m_refData = new wxBitmapRefData;
123
f97c9854 124 (void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, depth);
4bb6408c
JS
125
126 if ( wxTheBitmapList )
127 wxTheBitmapList->AddBitmap(this);
128}
129
130wxBitmap::wxBitmap(int w, int h, int d)
131{
132 (void)Create(w, h, d);
133
134 if ( wxTheBitmapList )
135 wxTheBitmapList->AddBitmap(this);
136}
137
138wxBitmap::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
146wxBitmap::wxBitmap(const wxString& filename, long type)
147{
148 LoadFile(filename, (int)type);
149
150 if ( wxTheBitmapList )
151 wxTheBitmapList->AddBitmap(this);
152}
153
f97c9854
JS
154// Create from XPM data
155static wxControl* sg_Control = NULL;
a4294b78 156wxBitmap::wxBitmap(char **data, wxControl* control)
4bb6408c 157{
f97c9854
JS
158 // Pass the control to the Create function using a global
159 sg_Control = control;
160
4bb6408c 161 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
f97c9854
JS
162
163 sg_Control = (wxControl*) NULL;
4bb6408c 164}
4bb6408c
JS
165
166bool wxBitmap::Create(int w, int h, int d)
167{
168 UnRef();
169
170 m_refData = new wxBitmapRefData;
171
f97c9854
JS
172 if (d < 1)
173 d = wxDisplayDepth();
174
4bb6408c
JS
175 M_BITMAPDATA->m_width = w;
176 M_BITMAPDATA->m_height = h;
177 M_BITMAPDATA->m_depth = d;
f97c9854 178 M_BITMAPDATA->m_freePixmap = TRUE;
4bb6408c 179
f97c9854 180 Display *dpy = (Display*) wxGetDisplay();
4bb6408c 181
f97c9854
JS
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) ;
4bb6408c
JS
188 return M_BITMAPDATA->m_ok;
189}
190
191bool 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
208bool 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
225bool 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
238void wxBitmap::SetWidth(int w)
239{
240 if (!M_BITMAPDATA)
241 m_refData = new wxBitmapRefData;
242
243 M_BITMAPDATA->m_width = w;
244}
245
246void wxBitmap::SetHeight(int h)
247{
248 if (!M_BITMAPDATA)
249 m_refData = new wxBitmapRefData;
250
251 M_BITMAPDATA->m_height = h;
252}
253
254void wxBitmap::SetDepth(int d)
255{
256 if (!M_BITMAPDATA)
257 m_refData = new wxBitmapRefData;
258
259 M_BITMAPDATA->m_depth = d;
260}
261
262void wxBitmap::SetQuality(int q)
263{
264 if (!M_BITMAPDATA)
265 m_refData = new wxBitmapRefData;
266
267 M_BITMAPDATA->m_quality = q;
268}
269
270void wxBitmap::SetOk(bool isOk)
271{
272 if (!M_BITMAPDATA)
273 m_refData = new wxBitmapRefData;
274
275 M_BITMAPDATA->m_ok = isOk;
276}
277
278void wxBitmap::SetPalette(const wxPalette& palette)
279{
280 if (!M_BITMAPDATA)
281 m_refData = new wxBitmapRefData;
282
283 M_BITMAPDATA->m_bitmapPalette = palette ;
284}
285
286void wxBitmap::SetMask(wxMask *mask)
287{
288 if (!M_BITMAPDATA)
289 m_refData = new wxBitmapRefData;
290
291 M_BITMAPDATA->m_bitmapMask = mask ;
292}
293
294void wxBitmap::AddHandler(wxBitmapHandler *handler)
295{
296 sm_handlers.Append(handler);
297}
298
299void wxBitmap::InsertHandler(wxBitmapHandler *handler)
300{
301 sm_handlers.Insert(handler);
302}
303
304bool 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
316wxBitmapHandler *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
329wxBitmapHandler *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
343wxBitmapHandler *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
360wxMask::wxMask()
361{
16c1f7f3 362 m_pixmap = (WXPixmap) 0;
4bb6408c
JS
363}
364
365// Construct a mask from a bitmap and a colour indicating
366// the transparent area
367wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
368{
16c1f7f3
JS
369 m_pixmap = (WXPixmap) 0;
370
4bb6408c
JS
371 Create(bitmap, colour);
372}
373
374// Construct a mask from a bitmap and a palette index indicating
375// the transparent area
376wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
377{
16c1f7f3 378 m_pixmap = (WXPixmap) 0;
4bb6408c
JS
379
380 Create(bitmap, paletteIndex);
381}
382
383// Construct a mask from a mono bitmap (copies the bitmap).
384wxMask::wxMask(const wxBitmap& bitmap)
385{
16c1f7f3 386 m_pixmap = (WXPixmap) 0;
4bb6408c
JS
387
388 Create(bitmap);
389}
390
391wxMask::~wxMask()
392{
f97c9854
JS
393 // TODO: this may be the wrong display
394 if ( m_pixmap )
395 XFreePixmap ((Display*) wxGetDisplay(), (Pixmap) m_pixmap);
4bb6408c
JS
396}
397
398// Create a mask from a mono bitmap (copies the bitmap).
399bool 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
407bool 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
415bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
416{
417// TODO
418 return FALSE;
419}
420
421/*
422 * wxBitmapHandler
423 */
424
425IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
426
427bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
428{
429 return FALSE;
430}
431
432bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
433 int desiredWidth, int desiredHeight)
434{
435 return FALSE;
436}
437
438bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
439{
440 return FALSE;
441}
442
443/*
444 * Standard handlers
445 */
446
f97c9854 447class WXDLLEXPORT wxXBMFileHandler: public wxBitmapHandler
4bb6408c 448{
f97c9854 449 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler)
4bb6408c 450public:
f97c9854 451 inline wxXBMFileHandler()
4bb6408c 452 {
f97c9854
JS
453 m_name = "XBM file";
454 m_extension = "xbm";
455 m_type = wxBITMAP_TYPE_XBM;
4bb6408c
JS
456 };
457
458 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
459 int desiredWidth, int desiredHeight);
460};
f97c9854
JS
461IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
462
463bool 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
495class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
496{
497 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
498public:
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};
508IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
509
510bool 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
a4294b78 577#if wxUSE_XPM
f97c9854
JS
578class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
579{
580 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
581public:
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
594IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
595
596bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
597 int desiredWidth, int desiredHeight)
598{
a4294b78 599 Display *dpy = (Display*) wxGetDisplay();
f97c9854
JS
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 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
623 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
624 if ( xpmAttr.npixels > 2 )
625 {
626 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
627 } else
628 {
629 M_BITMAPHANDLERDATA->m_depth = 1; // mono
630 }
631
632 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
633
634 XpmFreeAttributes(&xpmAttr);
635
636 M_BITMAPHANDLERDATA->m_ok = TRUE;
a4294b78 637 return TRUE;
f97c9854
JS
638 } else
639 {
640// XpmDebugError(errorStatus, name);
641 M_BITMAPHANDLERDATA->m_ok = FALSE;
642 return FALSE;
643 }
644}
645
646bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
647{
648 if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
649 {
650 Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
651 int errorStatus = XpmWriteFileFromPixmap(dpy, (char*) (const char*) name,
652 (Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
653 (M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
654 (XpmAttributes *) NULL);
655 if (errorStatus == XpmSuccess)
656 return TRUE;
657 else
658 return FALSE;
659 }
660 else
661 return FALSE;
662}
663
664class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
665{
666 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
667public:
a4294b78 668 inline wxXPMDataHandler()
f97c9854
JS
669 {
670 m_name = "XPM data";
671 m_extension = "xpm";
672 m_type = wxBITMAP_TYPE_XPM_DATA;
673 };
674
675 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
676};
677IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
678
679bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
680{
681 M_BITMAPHANDLERDATA->m_width = width;
682 M_BITMAPHANDLERDATA->m_height = height;
683 M_BITMAPHANDLERDATA->m_depth = 1;
684 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
685
a4294b78 686 Display *dpy = (Display*) wxGetDisplay();
f97c9854
JS
687 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
688
689 XpmAttributes xpmAttr;
690
691 xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
692
693 XpmColorSymbol symbolicColors[4];
694 if (sg_Control && sg_Control->GetMainWidget())
695 {
696 symbolicColors[0].name = "foreground";
697 symbolicColors[0].value = NULL;
698 symbolicColors[1].name = "background";
699 symbolicColors[1].value = NULL;
700 XtVaGetValues((Widget) sg_Control->GetMainWidget(),
701 XmNforeground, &symbolicColors[0].pixel,
702 XmNbackground, &symbolicColors[1].pixel,NULL);
703 xpmAttr.numsymbols = 2;
704 xpmAttr.colorsymbols = symbolicColors;
705 xpmAttr.valuemask |= XpmColorSymbols; // add flag
706 }
707
708 Pixmap pixmap;
709 Pixmap mask = 0;
710 int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
711 (char**) data, &pixmap, &mask, &xpmAttr);
712 if (ErrorStatus == XpmSuccess)
713 {
714 // Set attributes
715 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
716 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
717 if ( xpmAttr.npixels > 2 )
718 {
719 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
720 } else
721 {
722 M_BITMAPHANDLERDATA->m_depth = 1; // mono
723 }
724 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
725 XpmFreeAttributes(&xpmAttr);
726 M_BITMAPHANDLERDATA->m_ok = TRUE;
727 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
728 if ( mask )
729 {
730 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
731 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
732 }
733 }
734 else
735 {
736// XpmDebugError(ErrorStatus, NULL);
737 M_BITMAPHANDLERDATA->m_ok = FALSE;
738 }
739 return M_BITMAPHANDLERDATA->m_ok ;
740}
741
742#endif
4bb6408c
JS
743
744void wxBitmap::CleanUpHandlers()
745{
746 wxNode *node = sm_handlers.First();
747 while ( node )
748 {
749 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
750 wxNode *next = node->Next();
751 delete handler;
752 delete node;
753 node = next;
754 }
755}
756
757void wxBitmap::InitStandardHandlers()
758{
f97c9854
JS
759 // Initialize all standard bitmap or derived class handlers here.
760 AddHandler(new wxXBMFileHandler);
761 AddHandler(new wxXBMDataHandler);
762
763 // XPM is considered standard for Moif, although it can be omitted if absolutely
764 // necessary.
a4294b78 765#if wxUSE_XPM
4bb6408c
JS
766 AddHandler(new wxXPMFileHandler);
767 AddHandler(new wxXPMDataHandler);
f97c9854
JS
768#endif
769}
770
771WXPixmap wxBitmap::GetLabelPixmap (WXWidget w)
772{
773 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
774 return M_BITMAPDATA->m_pixmap;
775
776 Display *dpy = (Display*) M_BITMAPDATA->m_display;
777
778#ifdef FOO
779/*
780 If we do:
781 if (labelPixmap) return labelPixmap;
782 things can be wrong, because colors can have been changed.
783
784 If we do:
785 if (labelPixmap)
786 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
787 we got BadDrawable if the pixmap is referenced by multiples widgets
788
789 this is a catch22!!
790
791 So, before doing thing really clean, I just do nothing; if the pixmap is
792 referenced by many widgets, Motif performs caching functions.
793 And if pixmap is referenced with multiples colors, we just have some
794 memory leaks... I hope we can deal with them...
795 */
796 // Must be destroyed, because colours can have been changed!
797 if (M_BITMAPDATA->m_labelPixmap)
798 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_labelPixmap);
799#endif
800
801 char tmp[128];
802 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
803
804 Pixel fg, bg;
805 Widget widget = (Widget) w;
806
807 while (XmIsGadget ( widget ))
808 widget = XtParent (widget);
809 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
810
811 M_BITMAPDATA->m_labelPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
812
813 return M_BITMAPDATA->m_labelPixmap;
814}
815
816WXPixmap wxBitmap::GetArmPixmap (WXWidget w)
817{
818 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
819 return M_BITMAPDATA->m_pixmap;
820
821 Display *dpy = (Display*) M_BITMAPDATA->m_display;
822#ifdef FOO
823 See GetLabelPixmap () comment
824 // Must be destroyed, because colours can have been changed!
825 if (M_BITMAPDATA->m_armPixmap)
826 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_armPixmap);
827#endif
828
829 char tmp[128];
830 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
831
832 Pixel fg, bg;
833 Widget widget = (Widget) w;
834
835 XtVaGetValues (widget, XmNarmColor, &bg, NULL);
836 while (XmIsGadget (widget))
837 widget = XtParent (widget);
838 XtVaGetValues (widget, XmNforeground, &fg, NULL);
839
840 M_BITMAPDATA->m_armPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
841
842 return M_BITMAPDATA->m_armPixmap;
843}
844
845WXPixmap wxBitmap::GetInsensPixmap (WXWidget w)
846{
847 Display *dpy = (Display*) M_BITMAPDATA->m_display;
848
849 if (M_BITMAPDATA->m_insensImage == (WXPixmap) 0)
850 return M_BITMAPDATA->m_pixmap;
851
852#ifdef FOO
853 See GetLabelPixmap () comment
854 // Must be destroyed, because colours can have been changed!
855 if (M_BITMAPDATA->m_insensPixmap)
856 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), (Pixmap) M_BITMAPDATA->m_insensPixmap);
857#endif
858
859 char tmp[128];
860 sprintf (tmp, "Not%x", (unsigned int) M_BITMAPDATA->m_insensImage);
861
862 Pixel fg, bg;
863 Widget widget = (Widget) w;
864
865 while (XmIsGadget (widget))
866 widget = XtParent (widget);
867 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
868
869 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
870
871 return M_BITMAPDATA->m_insensPixmap;
872}
873
874// We may need this sometime...
875
876/****************************************************************************
877
878NAME
879 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
880
881SYNOPSIS
882 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
883
884DESCRIPTION
885 This function creates a grayed-out copy of the argument pixmap, suitable
886 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
887
888RETURN VALUES
889 The return value is the new Pixmap id or zero on error. Errors include
890 a NULL display argument or an invalid Pixmap argument.
891
892ERRORS
893 If one of the XLib functions fail, it will produce a X error. The
894 default X error handler prints a diagnostic and calls exit().
895
896SEE ALSO
897 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
898 XFillRectangle(3), exit(2)
899
900AUTHOR
901 John R Veregge - john@puente.jpl.nasa.gov
902 Advanced Engineering and Prototyping Group (AEG)
903 Information Systems Technology Section (395)
904 Jet Propulsion Lab - Calif Institute of Technology
905
906*****************************************************************************/
907
908Pixmap
909XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
910
911{
912static
913 char stipple_data[] =
914 {
915 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
916 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
917 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
918 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
919 };
920 GC gc;
921 Pixmap ipixmap, stipple;
922 unsigned width, height, depth;
923
924 Window window; /* These return values */
925 unsigned border; /* from XGetGeometry() */
926 int x, y; /* are not needed. */
927
928 ipixmap = 0;
929
930 if ( NULL == display || 0 == pixmap )
931 return ipixmap;
932
933 if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
934 &width, &height, &border, &depth )
935 )
936 return ipixmap; /* BadDrawable: probably an invalid pixmap */
937
938 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
939 */
940 stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
941 if ( 0 != stipple )
942 {
943 gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
944 if ( NULL != gc )
945 {
946 /* Create an identical copy of the argument pixmap.
947 */
948 ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
949 if ( 0 != ipixmap )
950 {
951 /* Copy the argument pixmap into the new pixmap.
952 */
953 XCopyArea( display, pixmap, ipixmap,
954 gc, 0, 0, width, height, 0, 0 );
955
956 /* Refill the new pixmap using the stipple algorithm/pixmap.
957 */
958 XSetStipple( display, gc, stipple );
959 XSetFillStyle( display, gc, FillStippled );
960 XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
961 }
962 XFreeGC( display, gc );
963 }
964 XFreePixmap( display, stipple );
965 }
966 return ipixmap;
4bb6408c 967}
f97c9854 968