Nano-X: added function to copy from a drawable to a wxImage
[wxWidgets.git] / src / x11 / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: Julian Smart, Robert Roebling
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart, Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14 #endif
15
16 #include "wx/bitmap.h"
17 #include "wx/icon.h"
18 #include "wx/log.h"
19 #include "wx/image.h"
20 #include "wx/app.h"
21 #if wxUSE_NANOX
22 #include "wx/dcmemory.h"
23 #endif
24
25 #include "wx/x11/private.h"
26
27 /* No point in using libXPM for NanoX */
28 #if wxUSE_NANOX
29 #undef wxHAVE_LIB_XPM
30 #define wxHAVE_LIB_XPM 0
31
32 // Copy from the drawable to the wxImage
33 bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image);
34 #endif
35
36 #if wxUSE_XPM
37 #if wxHAVE_LIB_XPM
38 #include <X11/xpm.h>
39 #else
40 #include "wx/xpmdecod.h"
41 #include "wx/wfstream.h"
42 #endif
43 #endif
44 #include <math.h>
45
46 //-----------------------------------------------------------------------------
47 // wxMask
48 //-----------------------------------------------------------------------------
49
50 IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
51
52 wxMask::wxMask()
53 {
54 m_bitmap = NULL;
55 m_display = NULL;
56 }
57
58 wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
59 {
60 m_bitmap = NULL;
61 Create( bitmap, colour );
62 }
63
64 wxMask::wxMask( const wxBitmap& bitmap, int paletteIndex )
65 {
66 m_bitmap = NULL;
67 Create( bitmap, paletteIndex );
68 }
69
70 wxMask::wxMask( const wxBitmap& bitmap )
71 {
72 m_bitmap = NULL;
73 Create( bitmap );
74 }
75
76 wxMask::~wxMask()
77 {
78 if (m_bitmap)
79 XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
80 }
81
82 bool wxMask::Create( const wxBitmap& bitmap,
83 const wxColour& colour )
84 {
85 #if !wxUSE_NANOX
86 if (m_bitmap)
87 {
88 XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
89 m_bitmap = NULL;
90 }
91
92 m_display = bitmap.GetDisplay();
93
94 wxImage image( bitmap );
95 if (!image.Ok()) return FALSE;
96
97 m_display = bitmap.GetDisplay();
98
99 Display *xdisplay = (Display*) m_display;
100
101 int xscreen = DefaultScreen( xdisplay );
102 Window xroot = RootWindow( xdisplay, xscreen );
103 Visual* xvisual = DefaultVisual( xdisplay, xscreen );
104 int bpp = DefaultDepth( xdisplay, xscreen );
105
106 m_bitmap = (WXPixmap) XCreatePixmap( xdisplay, xroot, image.GetWidth(), image.GetHeight(), 1 );
107 GC gc = XCreateGC( xdisplay, (Pixmap) m_bitmap, 0, NULL );
108
109 XSetForeground( xdisplay, gc, WhitePixel(xdisplay,xscreen) );
110 XSetFillStyle( xdisplay, gc, FillSolid );
111 XFillRectangle( xdisplay, (Pixmap) m_bitmap, gc, 0, 0, image.GetWidth(), image.GetHeight() );
112
113 unsigned char *data = image.GetData();
114 int index = 0;
115
116 unsigned char red = colour.Red();
117 unsigned char green = colour.Green();
118 unsigned char blue = colour.Blue();
119
120 XVisualInfo vinfo_template;
121 XVisualInfo *vi;
122
123 vinfo_template.visual = xvisual;
124 vinfo_template.visualid = XVisualIDFromVisual( xvisual );
125 vinfo_template.depth = bpp;
126 int nitem = 0;
127
128 vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
129 wxASSERT_MSG( vi, wxT("No visual info") );
130
131 if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
132 if (bpp == 15)
133 {
134 red = red & 0xf8;
135 green = green & 0xf8;
136 blue = blue & 0xf8;
137 } else
138 if (bpp == 16)
139 {
140 red = red & 0xf8;
141 green = green & 0xfc;
142 blue = blue & 0xf8;
143 } else
144 if (bpp == 12)
145 {
146 red = red & 0xf0;
147 green = green & 0xf0;
148 blue = blue & 0xf0;
149 }
150
151 XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) );
152
153 for (int j = 0; j < image.GetHeight(); j++)
154 {
155 int start_x = -1;
156 int i;
157 for (i = 0; i < image.GetWidth(); i++)
158 {
159 if ((data[index] == red) &&
160 (data[index+1] == green) &&
161 (data[index+2] == blue))
162 {
163 if (start_x == -1)
164 start_x = i;
165 }
166 else
167 {
168 if (start_x != -1)
169 {
170 XDrawLine( xdisplay, (Pixmap) m_bitmap, gc, start_x, j, i-1, j );
171 start_x = -1;
172 }
173 }
174 index += 3;
175 }
176 if (start_x != -1)
177 XDrawLine( xdisplay, (Pixmap) m_bitmap, gc, start_x, j, i, j );
178 }
179
180 XFreeGC( xdisplay, gc );
181
182 return TRUE;
183 #else
184 return FALSE;
185 #endif
186 // wxUSE_NANOX
187 }
188
189 bool wxMask::Create( const wxBitmap& bitmap, int paletteIndex )
190 {
191 unsigned char r,g,b;
192 wxPalette *pal = bitmap.GetPalette();
193
194 wxCHECK_MSG( pal, FALSE, wxT("Cannot create mask from bitmap without palette") );
195
196 pal->GetRGB(paletteIndex, &r, &g, &b);
197
198 return Create(bitmap, wxColour(r, g, b));
199 }
200
201 bool wxMask::Create( const wxBitmap& bitmap )
202 {
203 #if !wxUSE_NANOX
204 if (m_bitmap)
205 {
206 XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
207 m_bitmap = NULL;
208 }
209
210 if (!bitmap.Ok()) return FALSE;
211
212 wxCHECK_MSG( bitmap.GetBitmap(), FALSE, wxT("Cannot create mask from colour bitmap") );
213
214 m_display = bitmap.GetDisplay();
215
216 int xscreen = DefaultScreen( (Display*) m_display );
217 Window xroot = RootWindow( (Display*) m_display, xscreen );
218
219 m_bitmap = (WXPixmap) XCreatePixmap( (Display*) m_display, xroot, bitmap.GetWidth(), bitmap.GetHeight(), 1 );
220
221 if (!m_bitmap) return FALSE;
222
223 GC gc = XCreateGC( (Display*) m_display, (Pixmap) m_bitmap, 0, NULL );
224
225 XCopyPlane( (Display*) m_display, (Pixmap) bitmap.GetBitmap(), (Pixmap) m_bitmap,
226 gc, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), 0, 0, 1 );
227
228 XFreeGC( (Display*) m_display, gc );
229
230 return TRUE;
231 #else
232 return FALSE;
233 #endif
234 // wxUSE_NANOX
235 }
236
237 //-----------------------------------------------------------------------------
238 // wxBitmap
239 //-----------------------------------------------------------------------------
240
241 class wxBitmapRefData: public wxObjectRefData
242 {
243 public:
244 wxBitmapRefData();
245 ~wxBitmapRefData();
246
247 WXPixmap m_pixmap;
248 WXPixmap m_bitmap;
249 WXDisplay *m_display;
250 wxMask *m_mask;
251 int m_width;
252 int m_height;
253 int m_bpp;
254 wxPalette *m_palette;
255 };
256
257 wxBitmapRefData::wxBitmapRefData()
258 {
259 m_pixmap = NULL;
260 m_bitmap = NULL;
261 m_display = NULL;
262 m_mask = (wxMask *) NULL;
263 m_width = 0;
264 m_height = 0;
265 m_bpp = 0;
266 m_palette = (wxPalette *) NULL;
267 }
268
269 wxBitmapRefData::~wxBitmapRefData()
270 {
271 if (m_pixmap) XFreePixmap( (Display*) m_display, (Pixmap) m_pixmap );
272 if (m_bitmap) XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
273 if (m_mask) delete m_mask;
274 if (m_palette) delete m_palette;
275 }
276
277 //-----------------------------------------------------------------------------
278
279 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
280
281 IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxGDIObject)
282
283 wxBitmap::wxBitmap()
284 {
285 }
286
287 wxBitmap::wxBitmap( int width, int height, int depth )
288 {
289 Create( width, height, depth );
290 }
291
292 bool wxBitmap::Create( int width, int height, int depth )
293 {
294 UnRef();
295
296 wxCHECK_MSG( (width > 0) && (height > 0), FALSE, wxT("invalid bitmap size") )
297
298 m_refData = new wxBitmapRefData();
299
300 M_BMPDATA->m_display = wxGlobalDisplay();
301
302 wxASSERT_MSG( M_BMPDATA->m_display, wxT("No display") );
303
304 int xscreen = DefaultScreen( (Display*) M_BMPDATA->m_display );
305 Window xroot = RootWindow( (Display*) M_BMPDATA->m_display, xscreen );
306
307 int bpp = DefaultDepth( (Display*) M_BMPDATA->m_display, xscreen );
308 if (depth == -1) depth = bpp;
309
310 wxCHECK_MSG( (depth == bpp) ||
311 (depth == 1), FALSE, wxT("invalid bitmap depth") )
312
313 M_BMPDATA->m_mask = (wxMask *) NULL;
314 M_BMPDATA->m_width = width;
315 M_BMPDATA->m_height = height;
316
317 #if wxUSE_NANOX
318 M_BMPDATA->m_pixmap = (WXPixmap) GrNewPixmap(width, height, NULL);
319 M_BMPDATA->m_bpp = bpp;
320
321 wxASSERT_MSG( M_BMPDATA->m_pixmap, wxT("Bitmap creation failed") );
322 #else
323 if (depth == 1)
324 {
325 M_BMPDATA->m_bitmap = (WXPixmap) XCreatePixmap( (Display*) M_BMPDATA->m_display, xroot, width, height, 1 );
326
327 wxASSERT_MSG( M_BMPDATA->m_bitmap, wxT("Bitmap creation failed") );
328
329 M_BMPDATA->m_bpp = 1;
330 }
331 else
332 {
333 M_BMPDATA->m_pixmap = (WXPixmap) XCreatePixmap( (Display*) M_BMPDATA->m_display, xroot, width, height, depth );
334
335 wxASSERT_MSG( M_BMPDATA->m_pixmap, wxT("Pixmap creation failed") );
336
337 M_BMPDATA->m_bpp = depth;
338 }
339 #endif
340 return Ok();
341 }
342
343 bool wxBitmap::CreateFromXpm( const char **bits )
344 {
345 #if wxUSE_XPM
346 #if wxHAVE_LIB_XPM
347 UnRef();
348
349 wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
350
351 m_refData = new wxBitmapRefData();
352
353 M_BMPDATA->m_display = wxGlobalDisplay();
354
355 Display *xdisplay = (Display*) M_BMPDATA->m_display;
356
357 int xscreen = DefaultScreen( xdisplay );
358 Window xroot = RootWindow( xdisplay, xscreen );
359
360 int bpp = DefaultDepth( xdisplay, xscreen );
361
362 XpmAttributes xpmAttr;
363 xpmAttr.valuemask = XpmReturnInfos; // nothing yet, but get infos back
364
365 Pixmap pixmap;
366 Pixmap mask = 0;
367
368 int ErrorStatus = XpmCreatePixmapFromData( xdisplay, xroot, (char**) bits, &pixmap, &mask, &xpmAttr );
369
370 if (ErrorStatus == XpmSuccess)
371 {
372 M_BMPDATA->m_width = xpmAttr.width;
373 M_BMPDATA->m_height = xpmAttr.height;
374
375 M_BMPDATA->m_bpp = bpp; // mono as well?
376
377 #if __WXDEBUG__
378 unsigned int depthRet;
379 int xRet, yRet;
380 unsigned int widthRet, heightRet, borderWidthRet;
381 XGetGeometry( xdisplay, pixmap, &xroot, &xRet, &yRet,
382 &widthRet, &heightRet, &borderWidthRet, &depthRet);
383
384 wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") )
385 #endif
386
387 XpmFreeAttributes(&xpmAttr);
388
389 M_BMPDATA->m_pixmap = (WXPixmap) pixmap;
390
391 if (mask)
392 {
393 M_BMPDATA->m_mask = new wxMask;
394 M_BMPDATA->m_mask->SetBitmap( (WXPixmap) mask );
395 M_BMPDATA->m_mask->SetDisplay( xdisplay );
396 }
397 return TRUE;
398 }
399 else
400 {
401 UnRef();
402
403 return FALSE;
404 }
405 #else
406 wxXPMDecoder decoder;
407 wxImage image(decoder.ReadData(bits));
408 if (image.Ok())
409 return CreateFromImage(image);
410 else
411 return FALSE;
412 #endif
413 #endif
414 return FALSE;
415 }
416
417 bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
418 {
419 #if wxUSE_NANOX
420 if (!image.Ok())
421 {
422 wxASSERT_MSG(image.Ok(), "Invalid wxImage passed to wxBitmap::CreateFromImage.");
423 return FALSE;
424 }
425
426 int w = image.GetWidth();
427 int h = image.GetHeight();
428
429 if (!Create(w, h, depth))
430 return FALSE;
431
432 // Unfortunately the mask has to be screen-depth since
433 // 1-bpp bitmaps don't seem to be supported
434 // TODO: implement transparent drawing, presumably
435 // by doing several blits as per the Windows
436 // implementation because Nano-X doesn't support
437 // XSetClipMask.
438
439 bool hasMask = image.HasMask();
440
441 GC pixmapGC = GrNewGC();
442 Pixmap pixmap = (Pixmap) GetPixmap();
443
444 GC maskGC = 0;
445 Pixmap maskPixmap = 0;
446
447 unsigned char maskR = 0;
448 unsigned char maskG = 0;
449 unsigned char maskB = 0;
450
451 if (hasMask)
452 {
453 maskR = image.GetMaskRed();
454 maskG = image.GetMaskGreen();
455 maskB = image.GetMaskBlue();
456
457 maskGC = GrNewGC();
458 maskPixmap = GrNewPixmap(w, h, 0);
459 if (!maskPixmap)
460 hasMask = FALSE;
461 else
462 {
463 wxMask* mask = new wxMask;
464 mask->SetBitmap((WXPixmap) maskPixmap);
465 SetMask(mask);
466 }
467 }
468
469 GR_COLOR lastPixmapColour = 0;
470 GR_COLOR lastMaskColour = 0;
471
472 int i, j;
473 for (i = 0; i < w; i++)
474 {
475 for (j = 0; j < h; j++)
476 {
477 unsigned char red = image.GetRed(i, j);
478 unsigned char green = image.GetGreen(i, j);
479 unsigned char blue = image.GetBlue(i, j);
480
481 GR_COLOR colour = GR_RGB(red, green, blue);
482
483 // Efficiency measure
484 if (colour != lastPixmapColour || (i == 0 && j == 0))
485 {
486 GrSetGCForeground(pixmapGC, colour);
487 lastPixmapColour = colour;
488 }
489
490 GrPoint(pixmap, pixmapGC, i, j);
491
492 if (hasMask)
493 {
494 // scan the bitmap for the transparent colour and set the corresponding
495 // pixels in the mask to BLACK and the rest to WHITE
496 if (maskR == red && maskG == green && maskB == blue)
497 {
498 colour = GR_RGB(0, 0, 0);
499 }
500 else
501 {
502 colour = GR_RGB(255, 255, 255);
503 }
504 if (colour != lastMaskColour || (i == 0 && j == 0))
505 {
506 GrSetGCForeground(maskGC, colour);
507 lastMaskColour = colour;
508 }
509 GrPoint(maskPixmap, maskGC, i, j);
510 }
511 }
512 }
513
514 GrDestroyGC(pixmapGC);
515 if (hasMask)
516 GrDestroyGC(maskGC);
517
518 return TRUE;
519 #else
520 // !wxUSE_NANOX
521
522 UnRef();
523
524 wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
525 wxCHECK_MSG( depth == -1, FALSE, wxT("invalid bitmap depth") )
526
527 m_refData = new wxBitmapRefData();
528
529 M_BMPDATA->m_display = wxGlobalDisplay();
530
531 Display *xdisplay = (Display*) M_BMPDATA->m_display;
532
533 int xscreen = DefaultScreen( xdisplay );
534 Window xroot = RootWindow( xdisplay, xscreen );
535 Visual* xvisual = DefaultVisual( xdisplay, xscreen );
536
537 int bpp = DefaultDepth( xdisplay, xscreen );
538
539 int width = image.GetWidth();
540 int height = image.GetHeight();
541 M_BMPDATA->m_width = width;
542 M_BMPDATA->m_height = height;
543
544 if (depth != 1) depth = bpp;
545 M_BMPDATA->m_bpp = depth;
546
547 if (depth == 1)
548 {
549 wxFAIL_MSG( "mono images later" );
550 }
551 else
552 {
553 // Create image
554
555 XImage *data_image = XCreateImage( xdisplay, xvisual, bpp, ZPixmap, 0, 0, width, height, 32, 0 );
556 data_image->data = (char*) malloc( data_image->bytes_per_line * data_image->height );
557
558 if (data_image->data == NULL)
559 {
560 wxLogError( wxT("Out of memory.") ); // TODO clean
561 return FALSE;
562 }
563
564 M_BMPDATA->m_pixmap = (WXPixmap) XCreatePixmap( xdisplay, xroot, width, height, depth );
565
566 // Create mask
567
568 XImage *mask_image = (XImage*) NULL;
569 if (image.HasMask())
570 {
571 mask_image = XCreateImage( xdisplay, xvisual, 1, ZPixmap, 0, 0, width, height, 32, 0 );
572 mask_image->data = (char*) malloc( mask_image->bytes_per_line * mask_image->height );
573
574 if (mask_image->data == NULL)
575 {
576 wxLogError( wxT("Out of memory.") ); // TODO clean
577 return FALSE;
578 }
579
580 wxMask *mask = new wxMask();
581 mask->SetDisplay( xdisplay );
582 mask->SetBitmap( (WXPixmap) XCreatePixmap( xdisplay, xroot, width, height, 1 ) );
583
584 SetMask( mask );
585 }
586
587 // Retrieve info
588
589 XVisualInfo vinfo_template;
590 XVisualInfo *vi;
591
592 vinfo_template.visual = xvisual;
593 vinfo_template.visualid = XVisualIDFromVisual( xvisual );
594 vinfo_template.depth = bpp;
595 int nitem = 0;
596
597 vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
598 wxASSERT_MSG( vi, wxT("No visual info") );
599
600 if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
601 if (bpp < 8) bpp = 8;
602
603 // Render
604
605 enum byte_order { RGB, RBG, BRG, BGR, GRB, GBR };
606 byte_order b_o = RGB;
607
608 if (bpp > 8)
609 {
610 if ((vi->red_mask > vi->green_mask) && (vi->green_mask > vi->blue_mask)) b_o = RGB;
611 else if ((vi->red_mask > vi->blue_mask) && (vi->blue_mask > vi->green_mask)) b_o = RBG;
612 else if ((vi->blue_mask > vi->red_mask) && (vi->red_mask > vi->green_mask)) b_o = BRG;
613 else if ((vi->blue_mask > vi->green_mask) && (vi->green_mask > vi->red_mask)) b_o = BGR;
614 else if ((vi->green_mask > vi->red_mask) && (vi->red_mask > vi->blue_mask)) b_o = GRB;
615 else if ((vi->green_mask > vi->blue_mask) && (vi->blue_mask > vi->red_mask)) b_o = GBR;
616 }
617
618 XFree( vi );
619
620 int r_mask = image.GetMaskRed();
621 int g_mask = image.GetMaskGreen();
622 int b_mask = image.GetMaskBlue();
623
624 unsigned char* data = image.GetData();
625 wxASSERT_MSG( data, "No image data" );
626
627 bool hasMask = image.HasMask();
628
629 int index = 0;
630 for (int y = 0; y < height; y++)
631 {
632 for (int x = 0; x < width; x++)
633 {
634 int r = data[index];
635 index++;
636 int g = data[index];
637 index++;
638 int b = data[index];
639 index++;
640
641 if (hasMask)
642 {
643 if ((r == r_mask) && (b == b_mask) && (g == g_mask))
644 XPutPixel( mask_image, x, y, 0 );
645 else
646 XPutPixel( mask_image, x, y, 1 );
647 }
648
649 switch (bpp)
650 {
651 case 8:
652 {
653 int pixel = 0;
654 #if 0
655 if (wxTheApp->m_colorCube)
656 {
657 pixel = wxTheApp->m_colorCube[ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
658 }
659 else
660 {
661 GdkColormap *cmap = gtk_widget_get_default_colormap();
662 GdkColor *colors = cmap->colors;
663 int max = 3 * (65536);
664
665 for (int i = 0; i < cmap->size; i++)
666 {
667 int rdiff = (r << 8) - colors[i].red;
668 int gdiff = (g << 8) - colors[i].green;
669 int bdiff = (b << 8) - colors[i].blue;
670 int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
671 if (sum < max) { pixel = i; max = sum; }
672 }
673 }
674 #endif
675 XPutPixel( data_image, x, y, pixel );
676 break;
677 }
678 case 12: // SGI only
679 {
680 int pixel = 0;
681 switch (b_o)
682 {
683 case RGB: pixel = ((r & 0xf0) << 4) | (g & 0xf0) | ((b & 0xf0) >> 4); break;
684 case RBG: pixel = ((r & 0xf0) << 4) | (b & 0xf0) | ((g & 0xf0) >> 4); break;
685 case GRB: pixel = ((g & 0xf0) << 4) | (r & 0xf0) | ((b & 0xf0) >> 4); break;
686 case GBR: pixel = ((g & 0xf0) << 4) | (b & 0xf0) | ((r & 0xf0) >> 4); break;
687 case BRG: pixel = ((b & 0xf0) << 4) | (r & 0xf0) | ((g & 0xf0) >> 4); break;
688 case BGR: pixel = ((b & 0xf0) << 4) | (g & 0xf0) | ((r & 0xf0) >> 4); break;
689 }
690 XPutPixel( data_image, x, y, pixel );
691 break;
692 }
693 case 15:
694 {
695 int pixel = 0;
696 switch (b_o)
697 {
698 case RGB: pixel = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3); break;
699 case RBG: pixel = ((r & 0xf8) << 7) | ((b & 0xf8) << 2) | ((g & 0xf8) >> 3); break;
700 case GRB: pixel = ((g & 0xf8) << 7) | ((r & 0xf8) << 2) | ((b & 0xf8) >> 3); break;
701 case GBR: pixel = ((g & 0xf8) << 7) | ((b & 0xf8) << 2) | ((r & 0xf8) >> 3); break;
702 case BRG: pixel = ((b & 0xf8) << 7) | ((r & 0xf8) << 2) | ((g & 0xf8) >> 3); break;
703 case BGR: pixel = ((b & 0xf8) << 7) | ((g & 0xf8) << 2) | ((r & 0xf8) >> 3); break;
704 }
705 XPutPixel( data_image, x, y, pixel );
706 break;
707 }
708 case 16:
709 {
710 // I actually don't know if for 16-bit displays, it is alway the green
711 // component or the second component which has 6 bits.
712 int pixel = 0;
713 switch (b_o)
714 {
715 case RGB: pixel = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3); break;
716 case RBG: pixel = ((r & 0xf8) << 8) | ((b & 0xfc) << 3) | ((g & 0xf8) >> 3); break;
717 case GRB: pixel = ((g & 0xf8) << 8) | ((r & 0xfc) << 3) | ((b & 0xf8) >> 3); break;
718 case GBR: pixel = ((g & 0xf8) << 8) | ((b & 0xfc) << 3) | ((r & 0xf8) >> 3); break;
719 case BRG: pixel = ((b & 0xf8) << 8) | ((r & 0xfc) << 3) | ((g & 0xf8) >> 3); break;
720 case BGR: pixel = ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3); break;
721 }
722 XPutPixel( data_image, x, y, pixel );
723 break;
724 }
725 case 32:
726 case 24:
727 {
728 int pixel = 0;
729 switch (b_o)
730 {
731 case RGB: pixel = (r << 16) | (g << 8) | b; break;
732 case RBG: pixel = (r << 16) | (b << 8) | g; break;
733 case BRG: pixel = (b << 16) | (r << 8) | g; break;
734 case BGR: pixel = (b << 16) | (g << 8) | r; break;
735 case GRB: pixel = (g << 16) | (r << 8) | b; break;
736 case GBR: pixel = (g << 16) | (b << 8) | r; break;
737 }
738 XPutPixel( data_image, x, y, pixel );
739 }
740 default: break;
741 }
742 } // for
743 } // for
744
745 // Blit picture
746
747 GC gc = XCreateGC( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, 0, NULL );
748 XPutImage( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, gc, data_image, 0, 0, 0, 0, width, height );
749 #ifdef __WXDEBUG__
750 XSync(wxGlobalDisplay(), False);
751 #endif
752
753 XDestroyImage( data_image );
754 XFreeGC( xdisplay, gc );
755
756 // Blit mask
757
758 if (image.HasMask())
759 {
760 GC gc = XCreateGC( xdisplay, (Pixmap) GetMask()->GetBitmap(), 0, NULL );
761 XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, mask_image, 0, 0, 0, 0, width, height );
762
763 XDestroyImage( mask_image );
764 XFreeGC( xdisplay, gc );
765 }
766 }
767
768 return TRUE;
769 #endif
770 // wxUSE_NANOX
771 }
772
773 static void wxCalcPrecAndShift( unsigned long mask, int *shift, int *prec )
774 {
775 *shift = 0;
776 *prec = 0;
777
778 while (!(mask & 0x1))
779 {
780 (*shift)++;
781 mask >>= 1;
782 }
783
784 while (mask & 0x1)
785 {
786 (*prec)++;
787 mask >>= 1;
788 }
789 }
790
791 wxImage wxBitmap::ConvertToImage() const
792 {
793 wxImage image;
794
795 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
796
797 Display *xdisplay = (Display*) M_BMPDATA->m_display;
798 wxASSERT_MSG( xdisplay, wxT("No display") );
799
800 int xscreen = DefaultScreen( xdisplay );
801 Visual* xvisual = DefaultVisual( xdisplay, xscreen );
802
803 int bpp = DefaultDepth( xdisplay, xscreen );
804
805 #if wxUSE_NANOX
806 int w = image.GetWidth();
807 int h = image.GetHeight();
808
809 wxMemoryDC memDC;
810 memDC.SelectObject(*this);
811
812 wxColour pixelCol;
813
814 // Warning: this is very inefficient.
815 // TODO: use GrReadArea to get an array of pixels
816 int i, j;
817 for (i = 0; i < w; i++)
818 {
819 for (j = 0; j < h; j++)
820 {
821 memDC.GetPixel(i, j, & pixelCol);
822
823 // TODO: make wxColour accessors more efficient
824 // by inlining, if possible
825 image.SetRGB(i, j,
826 pixelCol.Red(), pixelCol.Green(),
827 pixelCol.Blue());
828 }
829 }
830 memDC.SelectObject(wxNullBitmap);
831
832 return image;
833
834 #else
835 // !wxUSE_NANOX
836 XImage *x_image = NULL;
837 if (GetPixmap())
838 {
839 x_image = XGetImage( xdisplay, (Pixmap) GetPixmap(),
840 0, 0,
841 GetWidth(), GetHeight(),
842 AllPlanes, ZPixmap );
843 } else
844 if (GetBitmap())
845 {
846 x_image = XGetImage( xdisplay, (Pixmap) GetBitmap(),
847 0, 0,
848 GetWidth(), GetHeight(),
849 AllPlanes, ZPixmap );
850 } else
851 {
852 wxFAIL_MSG( wxT("Ill-formed bitmap") );
853 }
854
855 wxCHECK_MSG( x_image, wxNullImage, wxT("couldn't create image") );
856
857 image.Create( GetWidth(), GetHeight() );
858 char unsigned *data = image.GetData();
859
860 if (!data)
861 {
862 XDestroyImage( x_image );
863 wxFAIL_MSG( wxT("couldn't create image") );
864 return wxNullImage;
865 }
866
867 XImage *x_image_mask = NULL;
868 if (GetMask())
869 {
870 x_image_mask = XGetImage( xdisplay, (Pixmap) GetMask()->GetBitmap(),
871 0, 0,
872 GetWidth(), GetHeight(),
873 AllPlanes, ZPixmap );
874
875 image.SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
876 }
877
878 int red_shift_right = 0;
879 int green_shift_right = 0;
880 int blue_shift_right = 0;
881 int red_shift_left = 0;
882 int green_shift_left = 0;
883 int blue_shift_left = 0;
884 bool use_shift = FALSE;
885
886 if (GetPixmap())
887 {
888 // Retrieve info
889
890 XVisualInfo vinfo_template;
891 XVisualInfo *vi;
892
893 vinfo_template.visual = xvisual;
894 vinfo_template.visualid = XVisualIDFromVisual( xvisual );
895 vinfo_template.depth = bpp;
896 int nitem = 0;
897
898 vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
899 wxASSERT_MSG( vi, wxT("No visual info") );
900
901 int red_prec,green_prec,blue_prec;
902 int red_shift,green_shift,blue_shift;
903 wxCalcPrecAndShift( vi->red_mask, &red_shift, &red_prec );
904 wxCalcPrecAndShift( vi->green_mask, &green_shift, &green_prec );
905 wxCalcPrecAndShift( vi->blue_mask, &blue_shift, &blue_prec );
906 if (bpp == 16) bpp = red_prec + green_prec + blue_prec;
907
908 red_shift_right = red_shift;
909 red_shift_left = 8-red_prec;
910 green_shift_right = green_shift;
911 green_shift_left = 8-green_prec;
912 blue_shift_right = blue_shift;
913 blue_shift_left = 8-blue_prec;
914
915 #if 0
916 use_shift = (vi->visual->c_class == TrueColor) || (vi->visual->c_class == DirectColor);
917 #else
918 use_shift = TRUE;
919 #endif
920
921 XFree( vi );
922 }
923 if (GetBitmap())
924 {
925 bpp = 1;
926 }
927
928
929 // GdkColormap *cmap = gtk_widget_get_default_colormap();
930
931 long pos = 0;
932 for (int j = 0; j < GetHeight(); j++)
933 {
934 for (int i = 0; i < GetWidth(); i++)
935 {
936 unsigned long pixel = XGetPixel( x_image, i, j );
937 if (bpp == 1)
938 {
939 if (pixel == 0)
940 {
941 data[pos] = 0;
942 data[pos+1] = 0;
943 data[pos+2] = 0;
944 }
945 else
946 {
947 data[pos] = 255;
948 data[pos+1] = 255;
949 data[pos+2] = 255;
950 }
951 }
952 else if (use_shift)
953 {
954 data[pos] = (pixel >> red_shift_right) << red_shift_left;
955 data[pos+1] = (pixel >> green_shift_right) << green_shift_left;
956 data[pos+2] = (pixel >> blue_shift_right) << blue_shift_left;
957 }
958 #if 0
959 else if (cmap->colors)
960 {
961 data[pos] = cmap->colors[pixel].red >> 8;
962 data[pos+1] = cmap->colors[pixel].green >> 8;
963 data[pos+2] = cmap->colors[pixel].blue >> 8;
964 }
965 #endif
966 else
967 {
968 wxFAIL_MSG( wxT("Image conversion failed. Unknown visual type.") );
969 }
970
971 if (x_image_mask)
972 {
973 int mask_pixel = XGetPixel( x_image_mask, i, j );
974 if (mask_pixel == 0)
975 {
976 data[pos] = 16;
977 data[pos+1] = 16;
978 data[pos+2] = 16;
979 }
980 }
981
982 pos += 3;
983 }
984 }
985
986 XDestroyImage( x_image );
987 if (x_image_mask) XDestroyImage( x_image_mask );
988 return image;
989 #endif
990 // wxUSE_NANOX
991 }
992
993 wxBitmap::wxBitmap( const wxBitmap& bmp )
994 {
995 Ref( bmp );
996 }
997
998 wxBitmap::wxBitmap( const wxString &filename, int type )
999 {
1000 LoadFile( filename, type );
1001 }
1002
1003 wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth) )
1004 {
1005 #if !wxUSE_NANOX
1006 m_refData = new wxBitmapRefData();
1007
1008 M_BMPDATA->m_display = wxGlobalDisplay();
1009
1010 Display *xdisplay = (Display*) M_BMPDATA->m_display;
1011
1012 int xscreen = DefaultScreen( xdisplay );
1013 Window xroot = RootWindow( xdisplay, xscreen );
1014
1015 M_BMPDATA->m_mask = (wxMask *) NULL;
1016 M_BMPDATA->m_bitmap = (WXPixmap) XCreateBitmapFromData( xdisplay, xroot, (char *) bits, width, height );
1017 M_BMPDATA->m_width = width;
1018 M_BMPDATA->m_height = height;
1019 M_BMPDATA->m_bpp = 1;
1020 #endif
1021 wxCHECK_RET( M_BMPDATA->m_bitmap, wxT("couldn't create bitmap") );
1022 }
1023
1024 wxBitmap::~wxBitmap()
1025 {
1026 }
1027
1028 wxBitmap& wxBitmap::operator = ( const wxBitmap& bmp )
1029 {
1030 if ( m_refData != bmp.m_refData )
1031 Ref( bmp );
1032
1033 return *this;
1034 }
1035
1036 bool wxBitmap::operator == ( const wxBitmap& bmp ) const
1037 {
1038 return m_refData == bmp.m_refData;
1039 }
1040
1041 bool wxBitmap::operator != ( const wxBitmap& bmp ) const
1042 {
1043 return m_refData != bmp.m_refData;
1044 }
1045
1046 bool wxBitmap::Ok() const
1047 {
1048 return (m_refData != NULL);
1049 }
1050
1051 int wxBitmap::GetHeight() const
1052 {
1053 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
1054
1055 return M_BMPDATA->m_height;
1056 }
1057
1058 int wxBitmap::GetWidth() const
1059 {
1060 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
1061
1062 return M_BMPDATA->m_width;
1063 }
1064
1065 int wxBitmap::GetDepth() const
1066 {
1067 wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
1068
1069 return M_BMPDATA->m_bpp;
1070 }
1071
1072 wxMask *wxBitmap::GetMask() const
1073 {
1074 wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
1075
1076 return M_BMPDATA->m_mask;
1077 }
1078
1079 void wxBitmap::SetMask( wxMask *mask )
1080 {
1081 wxCHECK_RET( Ok(), wxT("invalid bitmap") );
1082
1083 if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
1084
1085 M_BMPDATA->m_mask = mask;
1086 }
1087
1088 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
1089 {
1090 *this = icon;
1091 return TRUE;
1092 }
1093
1094 wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
1095 {
1096 wxCHECK_MSG( Ok() &&
1097 (rect.x >= 0) && (rect.y >= 0) &&
1098 (rect.x+rect.width <= M_BMPDATA->m_width) && (rect.y+rect.height <= M_BMPDATA->m_height),
1099 wxNullBitmap, wxT("invalid bitmap or bitmap region") );
1100
1101 wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
1102 wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
1103
1104
1105 wxFAIL_MSG( "wxBitmap::GetSubBitmap not yet implemented" );
1106
1107 #if 0
1108 if (ret.GetPixmap())
1109 {
1110 GdkGC *gc = gdk_gc_new( ret.GetPixmap() );
1111 gdk_draw_pixmap( ret.GetPixmap(), gc, GetPixmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
1112 gdk_gc_destroy( gc );
1113 }
1114 else
1115 {
1116 GdkGC *gc = gdk_gc_new( ret.GetBitmap() );
1117 gdk_wx_draw_bitmap( ret.GetBitmap(), gc, GetBitmap(), rect.x, rect.y, 0, 0, rect.width, rect.height );
1118 gdk_gc_destroy( gc );
1119 }
1120
1121 if (GetMask())
1122 {
1123 wxMask *mask = new wxMask;
1124 mask->m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, rect.width, rect.height, 1 );
1125
1126 GdkGC *gc = gdk_gc_new( mask->m_bitmap );
1127 gdk_wx_draw_bitmap( mask->m_bitmap, gc, M_BMPDATA->m_mask->m_bitmap, 0, 0, rect.x, rect.y, rect.width, rect.height );
1128 gdk_gc_destroy( gc );
1129
1130 ret.SetMask( mask );
1131 }
1132 #endif
1133
1134 return ret;
1135 }
1136
1137 bool wxBitmap::SaveFile( const wxString &name, int type, wxPalette *WXUNUSED(palette) )
1138 {
1139 wxCHECK_MSG( Ok(), FALSE, wxT("invalid bitmap") );
1140
1141 // Try to save the bitmap via wxImage handlers:
1142 {
1143 wxImage image( *this );
1144 if (image.Ok()) return image.SaveFile( name, type );
1145 }
1146
1147 return FALSE;
1148 }
1149
1150 bool wxBitmap::LoadFile( const wxString &name, int type )
1151 {
1152 UnRef();
1153
1154 if (!wxFileExists(name)) return FALSE;
1155
1156
1157 if (type == wxBITMAP_TYPE_XPM)
1158 {
1159 #if wxUSE_XPM
1160 #if wxHAVE_LIB_XPM
1161 m_refData = new wxBitmapRefData();
1162
1163 M_BMPDATA->m_display = wxGlobalDisplay();
1164
1165 Display *xdisplay = (Display*) M_BMPDATA->m_display;
1166
1167 int xscreen = DefaultScreen( xdisplay );
1168 Window xroot = RootWindow( xdisplay, xscreen );
1169
1170 int bpp = DefaultDepth( xdisplay, xscreen );
1171
1172 XpmAttributes xpmAttr;
1173 xpmAttr.valuemask = XpmReturnInfos; // nothing yet, but get infos back
1174
1175 Pixmap pixmap;
1176 Pixmap mask = 0;
1177
1178 int ErrorStatus = XpmReadFileToPixmap( xdisplay, xroot, (char*) name.c_str(), &pixmap, &mask, &xpmAttr);
1179
1180 if (ErrorStatus == XpmSuccess)
1181 {
1182 M_BMPDATA->m_width = xpmAttr.width;
1183 M_BMPDATA->m_height = xpmAttr.height;
1184
1185 M_BMPDATA->m_bpp = bpp; // mono as well?
1186
1187 XpmFreeAttributes(&xpmAttr);
1188
1189 M_BMPDATA->m_bitmap = (WXPixmap) pixmap;
1190
1191 if (mask)
1192 {
1193 M_BMPDATA->m_mask = new wxMask;
1194 M_BMPDATA->m_mask->SetBitmap( (WXPixmap) mask );
1195 M_BMPDATA->m_mask->SetDisplay( xdisplay );
1196 }
1197 }
1198 else
1199 {
1200 UnRef();
1201
1202 return FALSE;
1203 }
1204 #else
1205 #if wxUSE_STREAMS
1206 wxXPMDecoder decoder;
1207 wxFileInputStream stream(name);
1208 if (stream.Ok())
1209 {
1210 wxImage image(decoder.ReadFile(stream));
1211 if (image.Ok())
1212 return CreateFromImage(image);
1213 else
1214 return FALSE;
1215 }
1216 else
1217 return FALSE;
1218 #else
1219 return FALSE;
1220 #endif
1221 // wxUSE_STREAMS
1222 #endif
1223 // wxHAVE_LIB_XPM
1224 #endif
1225 // wxUSE_XPM
1226 return FALSE;
1227 }
1228 else // try if wxImage can load it
1229 {
1230 wxImage image;
1231 if (!image.LoadFile( name, type )) return FALSE;
1232 if (image.Ok()) *this = image.ConvertToBitmap();
1233 else return FALSE;
1234 }
1235
1236 return TRUE;
1237 }
1238
1239 wxPalette *wxBitmap::GetPalette() const
1240 {
1241 if (!Ok()) return (wxPalette *) NULL;
1242
1243 return M_BMPDATA->m_palette;
1244 }
1245
1246 void wxBitmap::SetHeight( int height )
1247 {
1248 if (!m_refData) m_refData = new wxBitmapRefData();
1249
1250 M_BMPDATA->m_height = height;
1251 }
1252
1253 void wxBitmap::SetWidth( int width )
1254 {
1255 if (!m_refData) m_refData = new wxBitmapRefData();
1256
1257 M_BMPDATA->m_width = width;
1258 }
1259
1260 void wxBitmap::SetDepth( int depth )
1261 {
1262 if (!m_refData) m_refData = new wxBitmapRefData();
1263
1264 M_BMPDATA->m_bpp = depth;
1265 }
1266
1267 void wxBitmap::SetPixmap( WXPixmap pixmap )
1268 {
1269 if (!m_refData) m_refData = new wxBitmapRefData();
1270
1271 M_BMPDATA->m_pixmap = pixmap;
1272 }
1273
1274 void wxBitmap::SetBitmap( WXPixmap bitmap )
1275 {
1276 if (!m_refData) m_refData = new wxBitmapRefData();
1277
1278 M_BMPDATA->m_bitmap = bitmap;
1279 }
1280
1281 WXPixmap wxBitmap::GetPixmap() const
1282 {
1283 wxCHECK_MSG( Ok(), (WXPixmap) NULL, wxT("invalid bitmap") );
1284
1285 return M_BMPDATA->m_pixmap;
1286 }
1287
1288 WXPixmap wxBitmap::GetBitmap() const
1289 {
1290 wxCHECK_MSG( Ok(), (WXPixmap) NULL, wxT("invalid bitmap") );
1291
1292 return M_BMPDATA->m_bitmap;
1293 }
1294
1295 WXDisplay *wxBitmap::GetDisplay() const
1296 {
1297 wxCHECK_MSG( Ok(), (WXDisplay*) NULL, wxT("invalid bitmap") );
1298
1299 return M_BMPDATA->m_display;
1300 }
1301
1302 #if wxUSE_NANOX
1303 // Copy from the drawable to the wxImage
1304 bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image)
1305 {
1306 GR_SCREEN_INFO sinfo;
1307 int x, y;
1308 GR_PIXELVAL *pixels;
1309 GR_PIXELVAL pixel;
1310 GR_COLOR colour;
1311 GR_PALETTE* palette = NULL;
1312
1313 GrGetScreenInfo(&sinfo);
1314
1315 if (sinfo.pixtype == MWPF_PALETTE) {
1316 if(!(palette = malloc(sizeof(GR_PALETTE)))) {
1317 return FALSE;
1318 }
1319 GrGetSystemPalette(palette);
1320 }
1321
1322 if(!(pixels = (GR_PIXELVAL*) malloc(sizeof(GR_PIXELVAL) * width * height)))
1323 {
1324 return FALSE;
1325 }
1326
1327 if (!image.Create(width, height))
1328 {
1329 free(pixels);
1330 return FALSE;
1331 }
1332
1333 GrReadArea(drawable, srcX, srcY, width, height,
1334 pixels);
1335
1336
1337 for(x = 0; x < sinfo.cols; x++) {
1338
1339 pp = (unsigned char *)pixels +
1340 ((x + (y * sinfo.cols)) *
1341 sizeof(GR_PIXELVAL));
1342
1343 switch(sinfo.pixtype) {
1344 /* FIXME: These may need modifying on big endian. */
1345 case MWPF_TRUECOLOR0888:
1346 case MWPF_TRUECOLOR888:
1347 rgb[0] = pp[2];
1348 rgb[1] = pp[1];
1349 rgb[2] = pp[0];
1350 break;
1351 case MWPF_PALETTE:
1352 rgb[0] = palette->palette[pp[0]].r;
1353 rgb[1] = palette->palette[pp[0]].g;
1354 rgb[2] = palette->palette[pp[0]].b;
1355 break;
1356 case MWPF_TRUECOLOR565:
1357 rgb[0] = pp[1] & 0xf8;
1358 rgb[1] = ((pp[1] & 0x07) << 5) |
1359 ((pp[0] & 0xe0) >> 3);
1360 rgb[2] = (pp[0] & 0x1f) << 3;
1361 break;
1362 case MWPF_TRUECOLOR555:
1363 rgb[0] = (pp[1] & 0x7c) << 1;
1364 rgb[1] = ((pp[1] & 0x03) << 6) |
1365 ((pp[0] & 0xe0) >> 2);
1366 rgb[2] = (pp[0] & 0x1f) << 3;
1367 break;
1368 case MWPF_TRUECOLOR332:
1369 rgb[0] = pp[0] & 0xe0;
1370 rgb[1] = (pp[0] & 0x1c) << 3;
1371 rgb[2] = (pp[0] & 0x03) << 6;
1372 break;
1373 default:
1374 fprintf(stderr, "Unsupported pixel "
1375 "format\n");
1376 return 1;
1377 }
1378
1379 image.SetRGB(x, y, rgb[0], rgb[1], rgb[2]);
1380
1381 }
1382 }
1383
1384 free(pixels);
1385 if(palette) free(palette);
1386
1387 return TRUE;
1388 }
1389
1390 #if 0
1391 int GrGetPixelColor(GR_SCREEN_INFO* sinfo, GR_PALETTE* palette, GR_PIXELVAL pixel,
1392 unsigned char* red, unsigned char* green, unsigned char* blue)
1393 {
1394 unsigned char rgb[3], *pp;
1395
1396 pp = (unsigned char*) & pixel ;
1397
1398 switch (sinfo.pixtype)
1399 {
1400 /* FIXME: These may need modifying on big endian. */
1401 case MWPF_TRUECOLOR0888:
1402 case MWPF_TRUECOLOR888:
1403 rgb[0] = pp[2];
1404 rgb[1] = pp[1];
1405 rgb[2] = pp[0];
1406 break;
1407 case MWPF_PALETTE:
1408 rgb[0] = palette->palette[pp[0]].r;
1409 rgb[1] = palette->palette[pp[0]].g;
1410 rgb[2] = palette->palette[pp[0]].b;
1411 break;
1412 case MWPF_TRUECOLOR565:
1413 rgb[0] = pp[1] & 0xf8;
1414 rgb[1] = ((pp[1] & 0x07) << 5) |
1415 ((pp[0] & 0xe0) >> 3);
1416 rgb[2] = (pp[0] & 0x1f) << 3;
1417 break;
1418 case MWPF_TRUECOLOR555:
1419 rgb[0] = (pp[1] & 0x7c) << 1;
1420 rgb[1] = ((pp[1] & 0x03) << 6) |
1421 ((pp[0] & 0xe0) >> 2);
1422 rgb[2] = (pp[0] & 0x1f) << 3;
1423 break;
1424 case MWPF_TRUECOLOR332:
1425 rgb[0] = pp[0] & 0xe0;
1426 rgb[1] = (pp[0] & 0x1c) << 3;
1427 rgb[2] = (pp[0] & 0x03) << 6;
1428 break;
1429 default:
1430 fprintf(stderr, "Unsupported pixel format\n");
1431 return 0;
1432 }
1433
1434
1435 *(red) = rgb[0];
1436 *(green) = rgb[1];
1437 *(blue) = rgb[2];
1438 return 1;
1439 }
1440 #endif
1441 #endif
1442 // wxUSE_NANOX
1443