1///////////////////////////////////////////////////////////////////////////// 2// Name: src/x11/utilsx.cpp 3// Purpose: Private functions common to X11 and Motif ports 4// Author: Mattia Barbon 5// Modified by: 6// Created: 05/04/03 7// RCS-ID: $Id: utilsx.cpp 50982 2008-01-01 20:38:33Z VZ $ 8// Copyright: (c) Mattia Barbon 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// for compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __VMS 16#define XShapeQueryExtension XSHAPEQUERYEXTENSION 17#endif 18 19#include "wx/x11/privx.h" 20 21#ifdef HAVE_XSHAPE 22 23 #ifndef WX_PRECOMP 24 #include "wx/bitmap.h" 25 #include "wx/region.h" 26 #endif 27 28 #ifdef __VMS 29 #include "wx/vms_x_fix.h" 30 #include <X11/shape.h> 31 #else 32 #include <X11/extensions/shape.h> 33 #endif 34 35 #include "wx/dcmemory.h" 36#endif 37 38// ---------------------------------------------------------------------------- 39// XShape code 40// ---------------------------------------------------------------------------- 41 42#ifdef HAVE_XSHAPE 43 44bool wxDoSetShape( Display* xdisplay, 45 Window xwindow, 46 const wxRegion& region ) 47{ 48 int dummy1, dummy2; 49 50 if( !XShapeQueryExtension( xdisplay, &dummy1, &dummy2 ) ) 51 return false; 52 53 if( region.IsEmpty() ) 54 { 55 XShapeCombineMask( xdisplay, xwindow, ShapeBounding, 0, 0, 56 None, ShapeSet ); 57 } 58 else 59 { 60 // wxRegion::ConvertToBitmap gives us the wrong Pixmap: 61 // polichrome and with black and whire reversed 62 wxRect box = region.GetBox(); 63 wxBitmap bmp(box.GetRight(), box.GetBottom(), 1); 64 wxMemoryDC dc; 65 dc.SelectObject(bmp); 66 dc.SetBackground(*wxBLACK_BRUSH); 67 dc.Clear(); 68 dc.SetClippingRegion(region); 69 dc.SetBackground(*wxWHITE_BRUSH); 70 dc.Clear(); 71 dc.SelectObject(wxNullBitmap); 72 73 XShapeCombineMask( xdisplay, xwindow, ShapeBounding, 0, 0, 74 (Pixmap)bmp.GetDrawable(), ShapeSet ); 75 } 76 77 return true; 78} 79 80#else 81 82bool wxDoSetShape( Display* WXUNUSED(xdisplay), 83 Window WXUNUSED(xwindow), 84 const wxRegion& WXUNUSED(region) ) 85{ 86 return false; 87} 88 89#endif 90 91// ---------------------------------------------------------------------------- 92// wxXVisualInfo 93// ---------------------------------------------------------------------------- 94 95#if !wxUSE_NANOX 96 97bool wxFillXVisualInfo( wxXVisualInfo* vi, Display* dpy ) 98{ 99 int xscreen = DefaultScreen( dpy ); 100 Visual* vis = DefaultVisual( dpy, xscreen ); 101 int bpp = DefaultDepth( dpy, xscreen ); 102 103 XVisualInfo vinfo_template; 104 XVisualInfo *vinfo; 105 106 vinfo_template.visual = vis; 107 vinfo_template.visualid = XVisualIDFromVisual( vis ); 108 vinfo_template.depth = bpp; 109 int nitem = 0; 110 111 vinfo = XGetVisualInfo( dpy, VisualIDMask|VisualDepthMask, 112 &vinfo_template, &nitem ); 113 114 wxCHECK_MSG( vinfo, false, wxT("no visual") ); 115 116 vi->Init( dpy, vinfo ); 117 118 XFree(vinfo); 119 120 return true; 121} 122 123inline int ABS(int x) { return x < 0 ? -x : x; } 124 125static void wxCalcPrecAndShift( unsigned long mask, int *shift, int *prec ) 126{ 127 *shift = 0; 128 *prec = 0; 129 130 while (!(mask & 0x1)) 131 { 132 (*shift)++; 133 mask >>= 1; 134 } 135 136 while (mask & 0x1) 137 { 138 (*prec)++; 139 mask >>= 1; 140 } 141} 142 143wxXVisualInfo::wxXVisualInfo() 144{ 145 m_visualColormap = NULL; 146 m_colorCube = NULL; 147} 148 149wxXVisualInfo::~wxXVisualInfo() 150{ 151 if (m_colorCube) 152 free( m_colorCube ); 153 154 if (m_visualColormap) 155 delete [] (XColor*)m_visualColormap; 156} 157 158void wxXVisualInfo::Init( Display* dpy, XVisualInfo* vi ) 159{ 160 m_visualType = vi->visual->c_class; 161 m_visualScreen = vi->screen; 162 163 m_visualRedMask = vi->red_mask; 164 m_visualGreenMask = vi->green_mask; 165 m_visualBlueMask = vi->blue_mask; 166 167 if (m_visualType != GrayScale && m_visualType != PseudoColor) 168 { 169 wxCalcPrecAndShift( m_visualRedMask, &m_visualRedShift, 170 &m_visualRedPrec ); 171 wxCalcPrecAndShift( m_visualGreenMask, &m_visualGreenShift, 172 &m_visualGreenPrec ); 173 wxCalcPrecAndShift( m_visualBlueMask, &m_visualBlueShift, 174 &m_visualBluePrec ); 175 } 176 177 m_visualDepth = vi->depth; 178 if (vi->depth == 16) 179 vi->depth = m_visualRedPrec + m_visualGreenPrec + m_visualBluePrec; 180 181 m_visualColormapSize = vi->colormap_size; 182 183 if (m_visualDepth > 8) 184 return; 185 186 m_visualColormap = new XColor[m_visualColormapSize]; 187 XColor* colors = (XColor*) m_visualColormap; 188 189 for (int i = 0; i < m_visualColormapSize; i++) 190 colors[i].pixel = i; 191 192 XQueryColors( dpy, DefaultColormap(dpy, vi->screen), 193 colors, m_visualColormapSize ); 194 195 m_colorCube = (unsigned char*)malloc(32 * 32 * 32); 196 197 for (int r = 0; r < 32; r++) 198 { 199 for (int g = 0; g < 32; g++) 200 { 201 for (int b = 0; b < 32; b++) 202 { 203 int rr = (r << 3) | (r >> 2); 204 int gg = (g << 3) | (g >> 2); 205 int bb = (b << 3) | (b >> 2); 206 207 int index = -1; 208 209 if (colors) 210 { 211 int max = 3 * 65536; 212 213 for (int i = 0; i < m_visualColormapSize; i++) 214 { 215 int rdiff = ((rr << 8) - colors[i].red); 216 int gdiff = ((gg << 8) - colors[i].green); 217 int bdiff = ((bb << 8) - colors[i].blue); 218 int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff); 219 if (sum < max) 220 { 221 index = i; max = sum; 222 } 223 } 224 } 225 else 226 { 227 // assume 8-bit true or static colors. this really exists 228 index = (r >> (5 - m_visualRedPrec)) << m_visualRedShift; 229 index |= (g >> (5 - m_visualGreenPrec)) << m_visualGreenShift; 230 index |= (b >> (5 - m_visualBluePrec)) << m_visualBlueShift; 231 } 232 m_colorCube[ (r*1024) + (g*32) + b ] = (unsigned char)index; 233 } 234 } 235 } 236} 237 238#endif // !wxUSE_NANOX 239