Add wxEventLoop::ScheduleExit().
[wxWidgets.git] / src / x11 / utilsx.cpp
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$
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 #include "wx/x11/private/wrapxkb.h"
39
40 // ----------------------------------------------------------------------------
41 // XShape code
42 // ----------------------------------------------------------------------------
43
44 #ifdef HAVE_XSHAPE
45
46 bool wxDoSetShape( Display* xdisplay,
47 Window xwindow,
48 const wxRegion& region )
49 {
50 int dummy1, dummy2;
51
52 if( !XShapeQueryExtension( xdisplay, &dummy1, &dummy2 ) )
53 return false;
54
55 if( region.IsEmpty() )
56 {
57 XShapeCombineMask( xdisplay, xwindow, ShapeBounding, 0, 0,
58 None, ShapeSet );
59 }
60 else
61 {
62 // wxRegion::ConvertToBitmap gives us the wrong Pixmap:
63 // polychrome and with black and white reversed
64 wxRect box = region.GetBox();
65 wxBitmap bmp(box.GetRight(), box.GetBottom(), 1);
66 wxMemoryDC dc;
67 dc.SelectObject(bmp);
68 dc.SetBackground(*wxBLACK_BRUSH);
69 dc.Clear();
70 dc.SetDeviceClippingRegion(region);
71 dc.SetBackground(*wxWHITE_BRUSH);
72 dc.Clear();
73 dc.SelectObject(wxNullBitmap);
74
75 XShapeCombineMask( xdisplay, xwindow, ShapeBounding, 0, 0,
76 (Pixmap)bmp.GetDrawable(), ShapeSet );
77 }
78
79 return true;
80 }
81
82 #else
83
84 bool wxDoSetShape( Display* WXUNUSED(xdisplay),
85 Window WXUNUSED(xwindow),
86 const wxRegion& WXUNUSED(region) )
87 {
88 return false;
89 }
90
91 #endif
92
93 // ----------------------------------------------------------------------------
94 // wxXVisualInfo
95 // ----------------------------------------------------------------------------
96
97 #if !wxUSE_NANOX
98
99 bool wxFillXVisualInfo( wxXVisualInfo* vi, Display* dpy )
100 {
101 int xscreen = DefaultScreen( dpy );
102 Visual* vis = DefaultVisual( dpy, xscreen );
103 int bpp = DefaultDepth( dpy, xscreen );
104
105 XVisualInfo vinfo_template;
106 XVisualInfo *vinfo;
107
108 vinfo_template.visual = vis;
109 vinfo_template.visualid = XVisualIDFromVisual( vis );
110 vinfo_template.depth = bpp;
111 int nitem = 0;
112
113 vinfo = XGetVisualInfo( dpy, VisualIDMask|VisualDepthMask,
114 &vinfo_template, &nitem );
115
116 wxCHECK_MSG( vinfo, false, wxT("no visual") );
117
118 vi->Init( dpy, vinfo );
119
120 XFree(vinfo);
121
122 return true;
123 }
124
125 inline int ABS(int x) { return x < 0 ? -x : x; }
126
127 static void wxCalcPrecAndShift( unsigned long mask, int *shift, int *prec )
128 {
129 *shift = 0;
130 *prec = 0;
131
132 while (!(mask & 0x1))
133 {
134 (*shift)++;
135 mask >>= 1;
136 }
137
138 while (mask & 0x1)
139 {
140 (*prec)++;
141 mask >>= 1;
142 }
143 }
144
145 wxXVisualInfo::wxXVisualInfo()
146 {
147 m_visualColormap = NULL;
148 m_colorCube = NULL;
149 }
150
151 wxXVisualInfo::~wxXVisualInfo()
152 {
153 if (m_colorCube)
154 free( m_colorCube );
155
156 if (m_visualColormap)
157 delete [] (XColor*)m_visualColormap;
158 }
159
160 void wxXVisualInfo::Init( Display* dpy, XVisualInfo* vi )
161 {
162 m_visualType = vi->visual->c_class;
163 m_visualScreen = vi->screen;
164
165 m_visualRedMask = vi->red_mask;
166 m_visualGreenMask = vi->green_mask;
167 m_visualBlueMask = vi->blue_mask;
168
169 if (m_visualType != GrayScale && m_visualType != PseudoColor)
170 {
171 wxCalcPrecAndShift( m_visualRedMask, &m_visualRedShift,
172 &m_visualRedPrec );
173 wxCalcPrecAndShift( m_visualGreenMask, &m_visualGreenShift,
174 &m_visualGreenPrec );
175 wxCalcPrecAndShift( m_visualBlueMask, &m_visualBlueShift,
176 &m_visualBluePrec );
177 }
178
179 m_visualDepth = vi->depth;
180 if (vi->depth == 16)
181 vi->depth = m_visualRedPrec + m_visualGreenPrec + m_visualBluePrec;
182
183 m_visualColormapSize = vi->colormap_size;
184
185 if (m_visualDepth > 8)
186 return;
187
188 m_visualColormap = new XColor[m_visualColormapSize];
189 XColor* colors = (XColor*) m_visualColormap;
190
191 for (int i = 0; i < m_visualColormapSize; i++)
192 colors[i].pixel = i;
193
194 XQueryColors( dpy, DefaultColormap(dpy, vi->screen),
195 colors, m_visualColormapSize );
196
197 m_colorCube = (unsigned char*)malloc(32 * 32 * 32);
198
199 for (int r = 0; r < 32; r++)
200 {
201 for (int g = 0; g < 32; g++)
202 {
203 for (int b = 0; b < 32; b++)
204 {
205 int rr = (r << 3) | (r >> 2);
206 int gg = (g << 3) | (g >> 2);
207 int bb = (b << 3) | (b >> 2);
208
209 int index = -1;
210
211 if (colors)
212 {
213 int max = 3 * 65536;
214
215 for (int i = 0; i < m_visualColormapSize; i++)
216 {
217 int rdiff = ((rr << 8) - colors[i].red);
218 int gdiff = ((gg << 8) - colors[i].green);
219 int bdiff = ((bb << 8) - colors[i].blue);
220 int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
221 if (sum < max)
222 {
223 index = i; max = sum;
224 }
225 }
226 }
227 else
228 {
229 // assume 8-bit true or static colors. this really exists
230 index = (r >> (5 - m_visualRedPrec)) << m_visualRedShift;
231 index |= (g >> (5 - m_visualGreenPrec)) << m_visualGreenShift;
232 index |= (b >> (5 - m_visualBluePrec)) << m_visualBlueShift;
233 }
234 m_colorCube[ (r*1024) + (g*32) + b ] = (unsigned char)index;
235 }
236 }
237 }
238 }
239
240 #endif // !wxUSE_NANOX
241
242 /* Don't synthesize KeyUp events holding down a key and producing
243 KeyDown events with autorepeat. */
244 bool wxSetDetectableAutoRepeat( bool flag )
245 {
246 #ifdef HAVE_X11_XKBLIB_H
247 Bool result;
248 XkbSetDetectableAutoRepeat( (Display *)wxGetDisplay(), flag, &result );
249 return result; /* true if keyboard hardware supports this mode */
250 #else
251 wxUnusedVar(flag);
252 return false;
253 #endif
254 }
255