1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/x11/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/x11/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
; 
  95             //      XFreeColors(display, cmap, pix_array, pix_array_n, 0); 
  96             // Be careful not to free '0' pixels... 
  98             for(i
=j
=0; i
<pix_array_n
; i
=j
) { 
  99                 while(j
<pix_array_n 
&& pix_array
[j
]!=0) j
++; 
 100                 if(j 
> i
) XFreeColors(display
, cmap
, &pix_array
[i
], j
-i
, 0); 
 101                 while(j
<pix_array_n 
&& pix_array
[j
]==0) j
++; 
 108             XFreeColormap(display
, cmap
); 
 110         next 
= node
->GetNext(); 
 111         m_palettes
.Erase(node
); 
 116 wxPalette::wxPalette() 
 120 wxPalette::wxPalette(int n
, const unsigned char *red
, const unsigned char *green
, const unsigned char *blue
) 
 122     Create(n
, red
, green
, blue
); 
 125 wxPalette::~wxPalette() 
 129 bool wxPalette::Create(int n
, const unsigned char *red
, const unsigned char *green
, const unsigned char *blue
) 
 137     m_refData 
= new wxPaletteRefData
; 
 140     Display
* display 
= (Display
*) wxGetDisplay(); 
 142     unsigned long *pix_array
; 
 146     cmap 
= (Colormap
) wxTheApp
->GetMainColormap(display
); 
 148     pix_array 
= new unsigned long[n
]; 
 153     xcol
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 154     for(int i 
= 0; i 
< n
; i
++) { 
 155         xcol
.red 
= (unsigned short)red
[i
] << 8; 
 156         xcol
.green 
= (unsigned short)green
[i
] << 8; 
 157         xcol
.blue 
= (unsigned short)blue
[i
] << 8; 
 158         pix_array
[i
] = (XAllocColor(display
, cmap
, &xcol
) == 0) ? 0 : xcol
.pixel
; 
 161     wxXPalette 
*c 
= new wxXPalette
; 
 163     c
->m_pix_array_n 
= pix_array_n
; 
 164     c
->m_pix_array 
= pix_array
; 
 165     c
->m_cmap 
= (WXColormap
) cmap
; 
 166     c
->m_display 
= (WXDisplay
*) display
; 
 167     c
->m_destroyable 
= false; 
 168     M_PALETTEDATA
->m_palettes
.Append(c
); 
 173 wxGDIRefData 
*wxPalette::CreateGDIRefData() const 
 175     return new wxPaletteRefData
; 
 178 wxGDIRefData 
*wxPalette::CloneGDIRefData(const wxGDIRefData 
*data
) const 
 180     return new wxPaletteRefData(*wx_static_cast(const wxPaletteRefData 
*, data
)); 
 183 int wxPalette::GetPixel(unsigned char WXUNUSED(red
), 
 184                         unsigned char WXUNUSED(green
), 
 185                         unsigned char WXUNUSED(blue
)) const 
 194 bool wxPalette::GetRGB(int index
, unsigned char *WXUNUSED(red
), unsigned char *WXUNUSED(green
), unsigned char *WXUNUSED(blue
)) const 
 199     if (index 
< 0 || index 
> 255) 
 206 WXColormap 
wxPalette::GetXColormap(WXDisplay
* display
) const 
 208     if (!M_PALETTEDATA 
|| (M_PALETTEDATA
->m_palettes
.GetCount() == 0)) 
 209         return wxTheApp
->GetMainColormap(display
); 
 211     wxList::compatibility_iterator node 
= M_PALETTEDATA
->m_palettes
.GetFirst(); 
 212     if (!display 
&& node
) 
 214         wxXPalette
* p 
= (wxXPalette
*) node
->GetData(); 
 219         wxXPalette
* p 
= (wxXPalette
*) node
->GetData(); 
 220         if (p
->m_display 
== display
) 
 223         node 
= node
->GetNext(); 
 226     /* Make a new one: */ 
 227     wxXPalette 
*c 
= new wxXPalette
; 
 228     wxXPalette 
*first 
= (wxXPalette 
*)M_PALETTEDATA
->m_palettes
.GetFirst()->GetData(); 
 230     int pix_array_n 
= first
->m_pix_array_n
; 
 232     c
->m_pix_array_n 
= pix_array_n
; 
 233     c
->m_pix_array 
= new unsigned long[pix_array_n
]; 
 234     c
->m_display 
= display
; 
 235     c
->m_cmap 
= wxTheApp
->GetMainColormap(display
); 
 236     c
->m_destroyable 
= false; 
 238     xcol
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 240     for (i 
= 0; i 
< pix_array_n
; i
++) 
 242         xcol
.pixel 
= first
->m_pix_array
[i
]; 
 243         XQueryColor((Display
*) first
->m_display
, (Colormap
) first
->m_cmap
, &xcol
); 
 245             (XAllocColor((Display
*) display
, (Colormap
) c
->m_cmap
, &xcol
) == 0) ? 0 : xcol
.pixel
; 
 248     //    wxPalette* nonConstThis = (wxPalette*) this; 
 250     M_PALETTEDATA
->m_palettes
.Append(c
); 
 255 bool wxPalette::TransferBitmap(void *data
, int depth
, int size
) 
 260             unsigned char *uptr 
= (unsigned char *)data
; 
 262             unsigned long *pix_array 
= GetXPixArray((Display
*) wxGetDisplay(), &pix_array_n
); 
 265                 if((int)*uptr 
< pix_array_n
) 
 266                     *uptr 
= (unsigned char)pix_array
[*uptr
]; 
 277 bool wxPalette::TransferBitmap8(unsigned char *data
, unsigned long sz
, 
 278                                 void *dest
, unsigned int bpp
) 
 281     unsigned long *pix_array 
= GetXPixArray((Display
*) wxGetDisplay(), &pix_array_n
); 
 284         unsigned char *dptr 
= (unsigned char *)dest
; 
 286             if((int)*data 
< pix_array_n
) 
 287                 *dptr 
= (unsigned char)pix_array
[*data
]; 
 294         unsigned short *dptr 
= (unsigned short *)dest
; 
 296             if((int)*data 
< pix_array_n
) 
 297                 *dptr 
= (unsigned short)pix_array
[*data
]; 
 304         struct rgb24 
{ unsigned char r
, g
, b
; } *dptr 
= (struct rgb24 
*)dest
; 
 306             if((int)*data 
< pix_array_n
) { 
 307                 dptr
->r 
= pix_array
[*data
] & 0xFF; 
 308                 dptr
->g 
= (pix_array
[*data
] >> 8) & 0xFF; 
 309                 dptr
->b 
= (pix_array
[*data
] >> 16) & 0xFF; 
 317         unsigned long *dptr 
= (unsigned long *)dest
; 
 319             if((int)*data 
< pix_array_n
) 
 320                 *dptr 
= pix_array
[*data
]; 
 332 unsigned long *wxPalette::GetXPixArray(WXDisplay 
*display
, int *n
) 
 335         return (unsigned long*) 0; 
 336     wxList::compatibility_iterator node
; 
 338     for (node 
= M_PALETTEDATA
->m_palettes
.GetFirst(); node
; node 
= node
->GetNext()) 
 340         wxXPalette 
*c 
= (wxXPalette 
*)node
->GetData(); 
 341         if (c
->m_display 
== display
) 
 344                 *n 
= c
->m_pix_array_n
; 
 345             return c
->m_pix_array
; 
 349     /* Not found; call GetXColormap, which will create it, then this again */ 
 350     if (GetXColormap(display
)) 
 351         return GetXPixArray(display
, n
); 
 353         return (unsigned long*) 0; 
 356 void wxPalette::PutXColormap(WXDisplay
* display
, WXColormap cm
, bool dp
) 
 360     m_refData 
= new wxPaletteRefData
; 
 362     wxXPalette 
*c 
= new wxXPalette
; 
 364     c
->m_pix_array_n 
= 0; 
 365     c
->m_pix_array 
= (unsigned long*) NULL
; 
 366     c
->m_display 
= display
; 
 368     c
->m_destroyable 
= dp
; 
 370     M_PALETTEDATA
->m_palettes
.Append(c
);