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