1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/palette.cpp 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  15  * When constructed with the default constructor, we start from 
  16  * the wxApp::GetMainColormap, allocating additional read-only cells 
  17  * in Create().  The cells are freed on the next call to Create() 
  18  * or when the destructor is called. 
  21 /* Wolfram Gloger <u7y22ab@sunmail.lrz-muenchen.de> 
  22 I have implemented basic colormap support for the X11 versions of 
  23 wxWidgets, notably wxPalette::Create().  The way I did it is to 
  24 allocate additional read-only color cells in the default colormap.  In 
  25 general you will get arbitrary pixel values assigned to these new 
  26 cells and therefore I added a method wxPalette::TransferBitmap() 
  27 which maps the pixel values 0..n to the real ones obtained with 
  28 Create().  This is only implemented for the popular case of 8-bit 
  31 Allocating read-write color cells would involve installing a private 
  32 X11 colormap for a particular window, and AFAIK this is not 
  33 recommended; only the window manager should do this...  Also, it is 
  34 not the functionality that wxPalette::Create() aims to provide. 
  37 // For compilers that support precompilation, includes "wx.h". 
  38 #include "wx/wxprec.h" 
  40 #include "wx/palette.h" 
  45     #include "wx/window.h" 
  49 #pragma message disable nosimpint 
  53 #pragma message enable nosimpint 
  55 #include "wx/motif/private.h" 
  57 IMPLEMENT_DYNAMIC_CLASS(wxPalette
, wxGDIObject
) 
  58 IMPLEMENT_DYNAMIC_CLASS(wxXPalette
, wxObject
) 
  65 wxXPalette::wxXPalette() 
  67     m_cmap 
= (WXColormap
) 0; 
  69     m_pix_array 
= (unsigned long*) 0; 
  70     m_display 
= (WXDisplay
*) 0; 
  71     m_destroyable 
= false; 
  74 wxPaletteRefData::wxPaletteRefData() 
  78 wxPaletteRefData::~wxPaletteRefData() 
  80     Display 
*display 
= (Display
*) NULL
; 
  82     wxList::compatibility_iterator node
, next
; 
  84     for (node 
= m_palettes
.GetFirst(); node
; node 
= next
) { 
  85         wxXPalette 
*c 
= (wxXPalette 
*)node
->GetData(); 
  86         unsigned long *pix_array 
= c
->m_pix_array
; 
  87         Colormap cmap 
= (Colormap
) c
->m_cmap
; 
  88         bool destroyable 
= c
->m_destroyable
; 
  89         int pix_array_n 
= c
->m_pix_array_n
; 
  90         display 
= (Display
*) c
->m_display
; 
  94             //      XFreeColors(display, cmap, pix_array, pix_array_n, 0); 
  95             // Be careful not to free '0' pixels... 
  97             for(i
=j
=0; i
<pix_array_n
; i
=j
) { 
  98                 while(j
<pix_array_n 
&& pix_array
[j
]!=0) j
++; 
  99                 if(j 
> i
) XFreeColors(display
, cmap
, &pix_array
[i
], j
-i
, 0); 
 100                 while(j
<pix_array_n 
&& pix_array
[j
]==0) j
++; 
 106             XFreeColormap(display
, cmap
); 
 108         next 
= node
->GetNext(); 
 109         m_palettes
.Erase(node
); 
 114 wxPalette::wxPalette() 
 118 wxPalette::wxPalette(int n
, const unsigned char *red
, const unsigned char *green
, const unsigned char *blue
) 
 120     Create(n
, red
, green
, blue
); 
 123 wxPalette::~wxPalette() 
 127 bool wxPalette::Create(int n
, const unsigned char *red
, const unsigned char *green
, const unsigned char *blue
) 
 135     m_refData 
= new wxPaletteRefData
; 
 138     Display
* display 
= (Display
*) wxGetDisplay(); 
 140     unsigned long *pix_array
; 
 144     cmap 
= (Colormap
) wxTheApp
->GetMainColormap(display
); 
 146     pix_array 
= new unsigned long[n
]; 
 151     xcol
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 152     for(int i 
= 0; i 
< n
; i
++) { 
 153         xcol
.red 
= (unsigned short)(red
[i
] << 8); 
 154         xcol
.green 
= (unsigned short)(green
[i
] << 8); 
 155         xcol
.blue 
= (unsigned short)(blue
[i
] << 8); 
 156         pix_array
[i
] = (XAllocColor(display
, cmap
, &xcol
) == 0) ? 0 : xcol
.pixel
; 
 159     wxXPalette 
*c 
= new wxXPalette
; 
 161     c
->m_pix_array_n 
= pix_array_n
; 
 162     c
->m_pix_array 
= pix_array
; 
 163     c
->m_cmap 
= (WXColormap
) cmap
; 
 164     c
->m_display 
= (WXDisplay
*) display
; 
 165     c
->m_destroyable 
= false; 
 166     M_PALETTEDATA
->m_palettes
.Append(c
); 
 171 int wxPalette::GetPixel(unsigned char WXUNUSED(red
), 
 172                         unsigned char WXUNUSED(green
), 
 173                         unsigned char WXUNUSED(blue
)) const 
 182 bool wxPalette::GetRGB(int index
, unsigned char *WXUNUSED(red
), unsigned char *WXUNUSED(green
), unsigned char *WXUNUSED(blue
)) const 
 187     if (index 
< 0 || index 
> 255) 
 194 WXColormap 
wxPalette::GetXColormap(WXDisplay
* display
) const 
 196     if (!M_PALETTEDATA 
|| (M_PALETTEDATA
->m_palettes
.GetCount() == 0)) 
 197         return wxTheApp
->GetMainColormap(display
); 
 199     wxList::compatibility_iterator node 
= M_PALETTEDATA
->m_palettes
.GetFirst(); 
 200     if (!display 
&& node
) 
 202         wxXPalette
* p 
= (wxXPalette
*) node
->GetData(); 
 207         wxXPalette
* p 
= (wxXPalette
*) node
->GetData(); 
 208         if (p
->m_display 
== display
) 
 211         node 
= node
->GetNext(); 
 214     /* Make a new one: */ 
 215     wxXPalette 
*c 
= new wxXPalette
; 
 217         (wxXPalette 
*)M_PALETTEDATA
->m_palettes
.GetFirst()->GetData(); 
 219     int pix_array_n 
= first
->m_pix_array_n
; 
 221     c
->m_pix_array_n 
= pix_array_n
; 
 222     c
->m_pix_array 
= new unsigned long[pix_array_n
]; 
 223     c
->m_display 
= display
; 
 224     c
->m_cmap 
= wxTheApp
->GetMainColormap(display
); 
 225     c
->m_destroyable 
= false; 
 227     xcol
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 229     for (i 
= 0; i 
< pix_array_n
; i
++) 
 231         xcol
.pixel 
= first
->m_pix_array
[i
]; 
 232         XQueryColor((Display
*) first
->m_display
, 
 233                     (Colormap
) first
->m_cmap
, &xcol
); 
 235             (XAllocColor((Display
*) display
, (Colormap
) c
->m_cmap
, &xcol
) == 0) 
 239     //    wxPalette* nonConstThis = (wxPalette*) this; 
 241     M_PALETTEDATA
->m_palettes
.Append(c
); 
 246 bool wxPalette::TransferBitmap(void *data
, int depth
, int size
) 
 251             unsigned char *uptr 
= (unsigned char *)data
; 
 253             unsigned long *pix_array 
= GetXPixArray((Display
*) wxGetDisplay(), &pix_array_n
); 
 256                 if((int)*uptr 
< pix_array_n
) 
 257                     *uptr 
= (unsigned char)pix_array
[*uptr
]; 
 268 bool wxPalette::TransferBitmap8(unsigned char *data
, unsigned long sz
, 
 269                                 void *dest
, unsigned int bpp
) 
 272     unsigned long *pix_array 
= GetXPixArray((Display
*) wxGetDisplay(), &pix_array_n
); 
 275         unsigned char *dptr 
= (unsigned char *)dest
; 
 277             if((int)*data 
< pix_array_n
) 
 278                 *dptr 
= (unsigned char)pix_array
[*data
]; 
 285         unsigned short *dptr 
= (unsigned short *)dest
; 
 287             if((int)*data 
< pix_array_n
) 
 288                 *dptr 
= (unsigned short)pix_array
[*data
]; 
 295         struct rgb24 
{ unsigned char r
, g
, b
; } *dptr 
= (struct rgb24 
*)dest
; 
 297             if((int)*data 
< pix_array_n
) { 
 298                 dptr
->r 
= (unsigned char)(pix_array
[*data
] & 0xFF); 
 299                 dptr
->g 
= (unsigned char)((pix_array
[*data
] >> 8) & 0xFF); 
 300                 dptr
->b 
= (unsigned char)((pix_array
[*data
] >> 16) & 0xFF); 
 308         unsigned long *dptr 
= (unsigned long *)dest
; 
 310             if((int)*data 
< pix_array_n
) 
 311                 *dptr 
= pix_array
[*data
]; 
 323 unsigned long *wxPalette::GetXPixArray(WXDisplay 
*display
, int *n
) 
 326         return (unsigned long*) 0; 
 327     wxList::compatibility_iterator node
; 
 329     for (node 
= M_PALETTEDATA
->m_palettes
.GetFirst(); node
; 
 330          node 
= node
->GetNext()) 
 332         wxXPalette 
*c 
= (wxXPalette 
*)node
->GetData(); 
 333         if (c
->m_display 
== display
) 
 336                 *n 
= c
->m_pix_array_n
; 
 337             return c
->m_pix_array
; 
 341     /* Not found; call GetXColormap, which will create it, then this again */ 
 342     if (GetXColormap(display
)) 
 343         return GetXPixArray(display
, n
); 
 345         return (unsigned long*) 0; 
 348 void wxPalette::PutXColormap(WXDisplay
* display
, WXColormap cm
, bool dp
) 
 352     m_refData 
= new wxPaletteRefData
; 
 354     wxXPalette 
*c 
= new wxXPalette
; 
 356     c
->m_pix_array_n 
= 0; 
 357     c
->m_pix_array 
= (unsigned long*) NULL
; 
 358     c
->m_display 
= display
; 
 360     c
->m_destroyable 
= dp
; 
 362     M_PALETTEDATA
->m_palettes
.Append(c
);