]> git.saurik.com Git - wxWidgets.git/blame - src/motif/cursor.cpp
latest CW additions
[wxWidgets.git] / src / motif / cursor.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: cursor.cpp
3// Purpose: wxCursor class
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "cursor.h"
14#endif
15
16#include "wx/cursor.h"
f97c9854 17#include "wx/gdicmn.h"
4bb6408c 18#include "wx/icon.h"
f97c9854
JS
19#include "wx/app.h"
20#include "wx/utils.h"
21
22#include <Xm/Xm.h>
23#include <X11/cursorfont.h>
24
25#include "wx/motif/private.h"
4bb6408c
JS
26
27#if !USE_SHARED_LIBRARIES
28IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
f97c9854 29IMPLEMENT_DYNAMIC_CLASS(wxXCursor, wxObject)
4bb6408c
JS
30#endif
31
32wxCursorRefData::wxCursorRefData()
33{
34 m_width = 32; m_height = 32;
f97c9854 35 m_cursorId = wxCURSOR_NONE;
4bb6408c
JS
36}
37
38wxCursorRefData::~wxCursorRefData()
39{
f97c9854
JS
40 wxNode* node = m_cursors.First();
41 while (node)
42 {
43 wxXCursor* c = (wxXCursor*) node->Data();
44 // TODO: how to delete cursor?
45 // XDestroyCursor((Display*) c->m_display, (Cursor) c->m_cursor); // ??
46 delete c;
47 node = node->Next();
48 }
4bb6408c
JS
49}
50
4bb6408c
JS
51wxCursor::wxCursor()
52{
53}
54
f97c9854
JS
55wxCursor::wxCursor(const char bits[], int width, int height,
56 int hotSpotX, int hotSpotY, const char maskBits[])
4bb6408c 57{
f97c9854 58 m_refData = new wxCursorRefData;
4bb6408c 59
f97c9854
JS
60 Display *dpy = (Display*) wxGetDisplay();
61 int screen_num = DefaultScreen (dpy);
4bb6408c 62
f97c9854
JS
63 Pixmap pixmap = XCreatePixmapFromBitmapData (dpy,
64 RootWindow (dpy, DefaultScreen(dpy)),
65 (char*) bits, width, height,
66 1 , 0 , 1);
4bb6408c 67
f97c9854
JS
68 Pixmap mask_pixmap = None;
69 if (maskBits != NULL)
4bb6408c 70 {
f97c9854
JS
71 mask_pixmap = XCreatePixmapFromBitmapData (dpy,
72 RootWindow (dpy, DefaultScreen(dpy)),
73 (char*) maskBits, width, height,
74 1 , 0 , 1);
4bb6408c 75 }
f97c9854
JS
76
77 XColor foreground_color;
78 XColor background_color;
79 foreground_color.pixel = BlackPixel(dpy, screen_num);
80 background_color.pixel = WhitePixel(dpy, screen_num);
81 Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
82 XQueryColor(dpy, cmap, &foreground_color);
83 XQueryColor(dpy, cmap, &background_color);
84
85 Cursor cursor = XCreatePixmapCursor (dpy,
86 pixmap,
87 mask_pixmap,
88 &foreground_color,
89 &background_color,
90 hotSpotX ,
91 hotSpotY);
92
93 XFreePixmap( dpy, pixmap );
94 if (mask_pixmap != None)
4bb6408c 95 {
f97c9854 96 XFreePixmap( dpy, mask_pixmap );
4bb6408c 97 }
f97c9854
JS
98
99 if (cursor)
4bb6408c 100 {
f97c9854
JS
101 wxXCursor *c = new wxXCursor;
102
103 c->m_cursor = (WXCursor) cursor;
104 c->m_display = (WXDisplay*) dpy;
105 M_CURSORDATA->m_cursors.Append(c);
106 M_CURSORDATA->m_ok = TRUE;
4bb6408c 107 }
f97c9854 108 else
4bb6408c 109 {
f97c9854 110 M_CURSORDATA->m_ok = TRUE;
4bb6408c 111 }
f97c9854
JS
112}
113
114wxCursor::wxCursor(const wxString& name, long flags, int hotSpotX, int hotSpotY)
115{
116 // Must be an XBM file
117 if (flags != wxBITMAP_TYPE_XBM)
118 return;
119
120 m_refData = new wxCursorRefData;
121
122 int hotX = -1, hotY = -1;
123 unsigned int w, h;
124 Pixmap pixmap;
125
126 Display *dpy = (Display*) wxGetDisplay();
127 int screen_num = DefaultScreen (dpy);
128
129 int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
130 (char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
131
132 M_BITMAPDATA->m_width = w;
133 M_BITMAPDATA->m_height = h;
134 M_BITMAPDATA->m_depth = 1;
135
136 if ((value == BitmapFileInvalid) ||
137 (value == BitmapOpenFailed) ||
138 (value == BitmapNoMemory))
4bb6408c 139 {
4bb6408c 140 }
f97c9854 141 else
4bb6408c 142 {
f97c9854
JS
143 XColor foreground_color;
144 XColor background_color;
145 foreground_color.pixel = BlackPixel(dpy, screen_num);
146 background_color.pixel = WhitePixel(dpy, screen_num);
147 Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
148 XQueryColor(dpy, cmap, &foreground_color);
149 XQueryColor(dpy, cmap, &background_color);
150
151 // TODO: how do we determine whether hotX, hotY were read correctly?
152 if (hotX < 0 || hotY < 0)
153 {
154 hotX = hotSpotX;
155 hotY = hotSpotY;
156 }
157 if (hotX < 0 || hotY < 0)
158 {
159 hotX = 0;
160 hotY = 0;
161 }
162
163 Pixmap mask_pixmap = None;
164 Cursor cursor = XCreatePixmapCursor (dpy,
165 pixmap,
166 mask_pixmap,
167 &foreground_color,
168 &background_color,
169 hotX,
170 hotY);
171
172 XFreePixmap( dpy, pixmap );
173 if (cursor)
174 {
175 wxXCursor *c = new wxXCursor;
176
177 c->m_cursor = (WXCursor) cursor;
178 c->m_display = (WXDisplay*) dpy;
179 M_CURSORDATA->m_cursors.Append(c);
180 M_CURSORDATA->m_ok = TRUE;
181 }
4bb6408c 182 }
f97c9854
JS
183
184}
185
186// Cursors by stock number
187wxCursor::wxCursor(wxStockCursor id)
188{
189 m_refData = new wxCursorRefData;
190 M_CURSORDATA->m_cursorId = id;
47bc1060 191 M_CURSORDATA->m_ok = TRUE;
f97c9854 192
47bc1060
JS
193 WXDisplay* display = wxGetDisplay();
194 if (!display)
195 return;
196
197 WXCursor cursor = GetXCursor(display);
f97c9854 198 if (cursor)
4bb6408c 199 {
f97c9854
JS
200 wxXCursor* c = new wxXCursor;
201 c->m_cursor = cursor;
202 c->m_display = wxGetDisplay();
203 M_CURSORDATA->m_cursors.Append(c);
204 M_CURSORDATA->m_ok = TRUE;
4bb6408c 205 }
f97c9854
JS
206}
207
208wxCursor::~wxCursor()
209{
210}
211
212// Motif-specific: create/get a cursor for the current display
213WXCursor wxCursor::GetXCursor(WXDisplay* display)
214{
215 if (!M_CURSORDATA)
216 return (WXCursor) 0;
217 wxNode* node = M_CURSORDATA->m_cursors.First();
218 while (node)
4bb6408c 219 {
f97c9854
JS
220 wxXCursor* c = (wxXCursor*) node->Data();
221 if (c->m_display == display)
222 return c->m_cursor;
223 node = node->Next();
4bb6408c 224 }
f97c9854
JS
225
226 // No cursor for this display, so let's see if we're an id-type cursor.
227
228 if (M_CURSORDATA->m_cursorId != wxCURSOR_NONE)
4bb6408c 229 {
f97c9854
JS
230 WXCursor cursor = MakeCursor(display, M_CURSORDATA->m_cursorId);
231 if (cursor)
232 {
233 wxXCursor* c = new wxXCursor;
234 c->m_cursor = cursor;
235 c->m_display = display;
236 M_CURSORDATA->m_cursors.Append(c);
237 return cursor;
238 }
239 else
240 return (WXCursor) 0;
4bb6408c 241 }
4bb6408c 242
f97c9854
JS
243 // Not an id-type cursor, so we don't know how to create it.
244 return (WXCursor) 0;
4bb6408c
JS
245}
246
f97c9854
JS
247// Make a cursor from standard id
248WXCursor wxCursor::MakeCursor(WXDisplay* display, wxStockCursor id)
4bb6408c 249{
f97c9854
JS
250 Display* dpy = (Display*) display;
251 Cursor cursor = (Cursor) 0;
252
253 switch (id)
254 {
255 case wxCURSOR_WAIT:
256 {
257 cursor = XCreateFontCursor (dpy, XC_watch);
258 break;
259 }
260 case wxCURSOR_CROSS:
261 {
262 cursor = XCreateFontCursor (dpy, XC_crosshair);
263 break;
264 }
265 case wxCURSOR_CHAR:
266 {
267 // Nothing
268 break;
269 }
270 case wxCURSOR_HAND:
271 {
272 cursor = XCreateFontCursor (dpy, XC_hand1);
273 break;
274 }
275 case wxCURSOR_BULLSEYE:
276 {
277 cursor = XCreateFontCursor (dpy, XC_target);
278 break;
279 }
280 case wxCURSOR_PENCIL:
281 {
282 cursor = XCreateFontCursor (dpy, XC_pencil);
283 break;
284 }
285 case wxCURSOR_MAGNIFIER:
286 {
287 cursor = XCreateFontCursor (dpy, XC_sizing);
288 break;
289 }
290 case wxCURSOR_IBEAM:
291 {
292 cursor = XCreateFontCursor (dpy, XC_xterm);
293 break;
294 }
295 case wxCURSOR_NO_ENTRY:
296 {
297 cursor = XCreateFontCursor (dpy, XC_pirate);
298 break;
299 }
300 case wxCURSOR_LEFT_BUTTON:
301 {
302 cursor = XCreateFontCursor (dpy, XC_leftbutton);
303 break;
304 }
305 case wxCURSOR_RIGHT_BUTTON:
306 {
307 cursor = XCreateFontCursor (dpy, XC_rightbutton);
308 break;
309 }
310 case wxCURSOR_MIDDLE_BUTTON:
311 {
312 cursor = XCreateFontCursor (dpy, XC_middlebutton);
313 break;
314 }
315 case wxCURSOR_QUESTION_ARROW:
316 {
317 cursor = XCreateFontCursor (dpy, XC_question_arrow);
318 break;
319 }
320 case wxCURSOR_SIZING:
321 {
322 cursor = XCreateFontCursor (dpy, XC_sizing);
323 break;
324 }
325 case wxCURSOR_WATCH:
326 {
327 cursor = XCreateFontCursor (dpy, XC_watch);
328 break;
329 }
330 case wxCURSOR_SPRAYCAN:
331 {
332 cursor = XCreateFontCursor (dpy, XC_spraycan);
333 break;
334 }
335 case wxCURSOR_PAINT_BRUSH:
336 {
337 cursor = XCreateFontCursor (dpy, XC_spraycan);
338 break;
339 }
340 case wxCURSOR_SIZENWSE:
341 case wxCURSOR_SIZENESW:
342 {
343 // Not available in X
344 cursor = XCreateFontCursor (dpy, XC_crosshair);
345 break;
346 }
347 case wxCURSOR_SIZEWE:
348 {
349 cursor = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
350 break;
351 }
352 case wxCURSOR_SIZENS:
353 {
354 cursor = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
355 break;
356 }
357 case wxCURSOR_POINT_LEFT:
358 {
359 cursor = XCreateFontCursor (dpy, XC_sb_left_arrow);
360 break;
361 }
362 case wxCURSOR_POINT_RIGHT:
363 {
364 cursor = XCreateFontCursor (dpy, XC_sb_right_arrow);
365 break;
366 }
367 // (JD Huggins) added more stock cursors for X
368 // X-only cursors BEGIN
369 case wxCURSOR_CROSS_REVERSE:
370 {
371 cursor = XCreateFontCursor(dpy, XC_cross_reverse);
372 break;
373 }
374 case wxCURSOR_DOUBLE_ARROW:
375 {
376 cursor = XCreateFontCursor(dpy, XC_double_arrow);
377 break;
378 }
379 case wxCURSOR_BASED_ARROW_UP:
380 {
381 cursor = XCreateFontCursor(dpy, XC_based_arrow_up);
382 break;
383 }
384 case wxCURSOR_BASED_ARROW_DOWN:
385 {
386 cursor = XCreateFontCursor(dpy, XC_based_arrow_down);
387 break;
388 }
389 default:
390 case wxCURSOR_ARROW:
391 {
392 cursor = XCreateFontCursor (dpy, XC_top_left_arrow);
393 break;
394 }
395 case wxCURSOR_BLANK:
396 {
397 GC gc;
398 XGCValues gcv;
399 Pixmap empty_pixmap;
400 XColor blank_color;
401
402 empty_pixmap = XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
403 16, 16, 1);
404 gcv.function = GXxor;
405 gc = XCreateGC (dpy,
406 empty_pixmap,
407 GCFunction,
408 &gcv);
409 XCopyArea (dpy,
410 empty_pixmap,
411 empty_pixmap,
412 gc,
413 0, 0,
414 16, 16,
415 0, 0);
416 XFreeGC (dpy, gc);
417 cursor = XCreatePixmapCursor (dpy,
418 empty_pixmap,
419 empty_pixmap,
420 &blank_color,
421 &blank_color,
422 8, 8);
423
424 break;
425 }
426 }
427 return (WXCursor) cursor;
4bb6408c
JS
428}
429
430// Global cursor setting
f9e02ac7 431void wxSetCursor(const wxCursor& WXUNUSED(cursor))
4bb6408c 432{
f97c9854 433 // Nothing to do for Motif (no global cursor)
4bb6408c
JS
434}
435
436