92
95
std::cerr << "Unable to open a display" << std::endl;
93
abort(); //was return before, but this would just mean it will crash later
96
abort(); /* was return before, but this would just mean it will crash later */
96
/* Open a connection to the X input manager */
99
#ifdef USE_X11_ERROR_HANDLERS
100
(void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
101
(void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
97
104
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
98
m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
102
= XInternAtom(m_display, "WM_DELETE_WINDOW", True);
104
m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False);
105
m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False);
106
m_wm_state= XInternAtom(m_display, "WM_STATE", False);
107
m_wm_change_state= XInternAtom(m_display, "WM_CHANGE_STATE", False);
108
m_net_state= XInternAtom(m_display, "_NET_WM_STATE", False);
109
m_net_max_horz= XInternAtom(m_display,
110
"_NET_WM_STATE_MAXIMIZED_HORZ", False);
111
m_net_max_vert= XInternAtom(m_display,
112
"_NET_WM_STATE_MAXIMIZED_VERT", False);
113
m_net_fullscreen= XInternAtom(m_display,
114
"_NET_WM_STATE_FULLSCREEN", False);
115
m_motif= XInternAtom(m_display, "_MOTIF_WM_HINTS", False);
116
m_targets= XInternAtom(m_display, "TARGETS", False);
117
m_string= XInternAtom(m_display, "STRING", False);
118
m_compound_text= XInternAtom(m_display, "COMPOUND_TEXT", False);
119
m_text= XInternAtom(m_display, "TEXT", False);
120
m_clipboard= XInternAtom(m_display, "CLIPBOARD", False);
121
m_primary= XInternAtom(m_display, "PRIMARY", False);
122
m_xclip_out= XInternAtom(m_display, "XCLIP_OUT", False);
123
m_incr= XInternAtom(m_display, "INCR", False);
124
m_utf8_string= XInternAtom(m_display, "UTF8_STRING", False);
105
/* note -- don't open connection to XIM server here, because the locale
106
* has to be set before opening the connection but setlocale() has not
107
* been called yet. the connection will be opened after entering
112
#define GHOST_INTERN_ATOM_IF_EXISTS(atom) { m_atom.atom = XInternAtom(m_display, #atom , True); } (void)0
113
#define GHOST_INTERN_ATOM(atom) { m_atom.atom = XInternAtom(m_display, #atom , False); } (void)0
115
GHOST_INTERN_ATOM_IF_EXISTS(WM_DELETE_WINDOW);
116
GHOST_INTERN_ATOM(WM_PROTOCOLS);
117
GHOST_INTERN_ATOM(WM_TAKE_FOCUS);
118
GHOST_INTERN_ATOM(WM_STATE);
119
GHOST_INTERN_ATOM(WM_CHANGE_STATE);
120
GHOST_INTERN_ATOM(_NET_WM_STATE);
121
GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
122
GHOST_INTERN_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
124
GHOST_INTERN_ATOM(_NET_WM_STATE_FULLSCREEN);
125
GHOST_INTERN_ATOM(_MOTIF_WM_HINTS);
126
GHOST_INTERN_ATOM(TARGETS);
127
GHOST_INTERN_ATOM(STRING);
128
GHOST_INTERN_ATOM(COMPOUND_TEXT);
129
GHOST_INTERN_ATOM(TEXT);
130
GHOST_INTERN_ATOM(CLIPBOARD);
131
GHOST_INTERN_ATOM(PRIMARY);
132
GHOST_INTERN_ATOM(XCLIP_OUT);
133
GHOST_INTERN_ATOM(INCR);
134
GHOST_INTERN_ATOM(UTF8_STRING);
135
#ifdef WITH_X11_XINPUT
136
m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
139
#undef GHOST_INTERN_ATOM_IF_EXISTS
140
#undef GHOST_INTERN_ATOM
128
// compute the initial time
144
/* compute the initial time */
130
if (gettimeofday(&tv,NULL) == -1) {
131
GHOST_ASSERT(false,"Could not instantiate timer!");
146
if (gettimeofday(&tv, NULL) == -1) {
147
GHOST_ASSERT(false, "Could not instantiate timer!");
134
// Taking care not to overflow the tv.tv_sec*1000
135
m_start_time = GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000;
150
/* Taking care not to overflow the tv.tv_sec * 1000 */
151
m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
138
154
/* use detectable autorepeate, mac and windows also do this */
178
211
return GHOST_kFailure;
182
215
GHOST_SystemX11::
216
getMilliSeconds() const
186
if (gettimeofday(&tv,NULL) == -1) {
187
GHOST_ASSERT(false,"Could not compute time!");
219
if (gettimeofday(&tv, NULL) == -1) {
220
GHOST_ASSERT(false, "Could not compute time!");
190
// Taking care not to overflow the tv.tv_sec*1000
191
return GHOST_TUns64(tv.tv_sec)*1000 + tv.tv_usec/1000 - m_start_time;
223
/* Taking care not to overflow the tv.tv_sec * 1000 */
224
return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
195
228
GHOST_SystemX11::
229
getNumDisplays() const
198
231
return GHOST_TUns8(1);
202
* Returns the dimensions of the main display on this system.
203
* @return The dimension of the main display.
235
* Returns the dimensions of the main display on this system.
236
* \return The dimension of the main display.
206
239
GHOST_SystemX11::
207
240
getMainDisplayDimensions(
242
GHOST_TUns32& height) const
245
/* note, for this to work as documented,
246
* we would need to use Xinerama check r54370 for code that did thia,
247
* we've since removed since its not worth the extra dep - campbell */
248
getAllDisplayDimensions(width, height);
254
* Returns the dimensions of the main display on this system.
255
* \return The dimension of the main display.
259
getAllDisplayDimensions(
261
GHOST_TUns32& height) const
212
264
width = DisplayWidth(m_display, DefaultScreen(m_display));
213
265
height = DisplayHeight(m_display, DefaultScreen(m_display));
218
* Create a new window.
219
* The new window is added to the list of windows managed.
220
* Never explicitly delete the window, use disposeWindow() instead.
221
* @param title The name of the window (displayed in the title bar of the window if the OS supports it).
222
* @param left The coordinate of the left edge of the window.
223
* @param top The coordinate of the top edge of the window.
224
* @param width The width the window.
225
* @param height The height the window.
226
* @param state The state of the window when opened.
227
* @param type The type of drawing context installed in this window.
228
* @param stereoVisual Stereo visual for quad buffered stereo.
229
* @param numOfAASamples Number of samples used for AA (zero if no AA)
230
* @param parentWindow Parent (embedder) window
231
* @return The new window (or 0 if creation failed).
270
* Create a new window.
271
* The new window is added to the list of windows managed.
272
* Never explicitly delete the window, use disposeWindow() instead.
273
* \param title The name of the window (displayed in the title bar of the window if the OS supports it).
274
* \param left The coordinate of the left edge of the window.
275
* \param top The coordinate of the top edge of the window.
276
* \param width The width the window.
277
* \param height The height the window.
278
* \param state The state of the window when opened.
279
* \param type The type of drawing context installed in this window.
280
* \param stereoVisual Stereo visual for quad buffered stereo.
281
* \param numOfAASamples Number of samples used for AA (zero if no AA)
282
* \param parentWindow Parent (embedder) window
283
* \return The new window (or 0 if creation failed).
234
286
GHOST_SystemX11::
236
const STR_String& title,
241
GHOST_TWindowState state,
242
GHOST_TDrawingContextType type,
244
const GHOST_TUns16 numOfAASamples,
245
const GHOST_TEmbedderWindowID parentWindow
247
GHOST_WindowX11 * window = 0;
288
const STR_String& title,
293
GHOST_TWindowState state,
294
GHOST_TDrawingContextType type,
296
const GHOST_TUns16 numOfAASamples,
297
const GHOST_TEmbedderWindowID parentWindow)
299
GHOST_WindowX11 *window = 0;
249
301
if (!m_display) return 0;
254
window = new GHOST_WindowX11 (
255
this,m_display,title, left, top, width, height, state, parentWindow, type, stereoVisual
306
window = new GHOST_WindowX11(this, m_display, title,
307
left, top, width, height,
308
state, parentWindow, type, stereoVisual, numOfAASamples);
259
// Both are now handle in GHOST_WindowX11.cpp
260
// Focus and Delete atoms.
311
/* Both are now handle in GHOST_WindowX11.cpp
312
* Focus and Delete atoms. */
262
314
if (window->getValid()) {
263
// Store the pointer to the window
315
/* Store the pointer to the window */
264
316
m_windowManager->addWindow(window);
265
317
m_windowManager->setActiveWindow(window);
266
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
318
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
1057
1344
GHOST_TKey type;
1059
1346
if ((key >= XK_A) && (key <= XK_Z)) {
1060
type = GHOST_TKey( key - XK_A + int(GHOST_kKeyA));
1061
} else if ((key >= XK_a) && (key <= XK_z)) {
1347
type = GHOST_TKey(key - XK_A + int(GHOST_kKeyA));
1349
else if ((key >= XK_a) && (key <= XK_z)) {
1062
1350
type = GHOST_TKey(key - XK_a + int(GHOST_kKeyA));
1063
} else if ((key >= XK_0) && (key <= XK_9)) {
1352
else if ((key >= XK_0) && (key <= XK_9)) {
1064
1353
type = GHOST_TKey(key - XK_0 + int(GHOST_kKey0));
1065
} else if ((key >= XK_F1) && (key <= XK_F24)) {
1355
else if ((key >= XK_F1) && (key <= XK_F24)) {
1066
1356
type = GHOST_TKey(key - XK_F1 + int(GHOST_kKeyF1));
1067
1357
#if defined(__sun) || defined(__sun__)
1068
1358
/* This is a bit of a hack, but it looks like sun
1069
Used F11 and friends for its special keys Stop,again etc..
1070
So this little patch enables F11 and F12 to work as expected
1071
following link has documentation on it:
1072
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4734408
1073
also from /usr/include/X11/Sunkeysym.h
1074
#define SunXK_F36 0x1005FF10 // Labeled F11
1075
#define SunXK_F37 0x1005FF11 // Labeled F12
1359
* Used F11 and friends for its special keys Stop,again etc..
1360
* So this little patch enables F11 and F12 to work as expected
1361
* following link has documentation on it:
1362
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4734408
1363
* also from /usr/include/X11/Sunkeysym.h
1364
* #define SunXK_F36 0x1005FF10 // Labeled F11
1365
* #define SunXK_F37 0x1005FF11 // Labeled F12
1080
} else if (key == 268828432) {
1371
else if (key == 268828432) {
1081
1372
type = GHOST_kKeyF11;
1082
} else if (key == 268828433) {
1374
else if (key == 268828433) {
1083
1375
type = GHOST_kKeyF12;
1087
GXMAP(type,XK_BackSpace, GHOST_kKeyBackSpace);
1088
GXMAP(type,XK_Tab, GHOST_kKeyTab);
1089
GXMAP(type,XK_Return, GHOST_kKeyEnter);
1090
GXMAP(type,XK_Escape, GHOST_kKeyEsc);
1091
GXMAP(type,XK_space, GHOST_kKeySpace);
1093
GXMAP(type,XK_Linefeed, GHOST_kKeyLinefeed);
1094
GXMAP(type,XK_semicolon, GHOST_kKeySemicolon);
1095
GXMAP(type,XK_period, GHOST_kKeyPeriod);
1096
GXMAP(type,XK_comma, GHOST_kKeyComma);
1097
GXMAP(type,XK_quoteright, GHOST_kKeyQuote);
1098
GXMAP(type,XK_quoteleft, GHOST_kKeyAccentGrave);
1099
GXMAP(type,XK_minus, GHOST_kKeyMinus);
1100
GXMAP(type,XK_slash, GHOST_kKeySlash);
1101
GXMAP(type,XK_backslash, GHOST_kKeyBackslash);
1102
GXMAP(type,XK_equal, GHOST_kKeyEqual);
1103
GXMAP(type,XK_bracketleft, GHOST_kKeyLeftBracket);
1104
GXMAP(type,XK_bracketright, GHOST_kKeyRightBracket);
1105
GXMAP(type,XK_Pause, GHOST_kKeyPause);
1107
GXMAP(type,XK_Shift_L, GHOST_kKeyLeftShift);
1108
GXMAP(type,XK_Shift_R, GHOST_kKeyRightShift);
1109
GXMAP(type,XK_Control_L, GHOST_kKeyLeftControl);
1110
GXMAP(type,XK_Control_R, GHOST_kKeyRightControl);
1111
GXMAP(type,XK_Alt_L, GHOST_kKeyLeftAlt);
1112
GXMAP(type,XK_Alt_R, GHOST_kKeyRightAlt);
1113
GXMAP(type,XK_Super_L, GHOST_kKeyOS);
1114
GXMAP(type,XK_Super_R, GHOST_kKeyOS);
1116
GXMAP(type,XK_Insert, GHOST_kKeyInsert);
1117
GXMAP(type,XK_Delete, GHOST_kKeyDelete);
1118
GXMAP(type,XK_Home, GHOST_kKeyHome);
1119
GXMAP(type,XK_End, GHOST_kKeyEnd);
1120
GXMAP(type,XK_Page_Up, GHOST_kKeyUpPage);
1121
GXMAP(type,XK_Page_Down, GHOST_kKeyDownPage);
1123
GXMAP(type,XK_Left, GHOST_kKeyLeftArrow);
1124
GXMAP(type,XK_Right, GHOST_kKeyRightArrow);
1125
GXMAP(type,XK_Up, GHOST_kKeyUpArrow);
1126
GXMAP(type,XK_Down, GHOST_kKeyDownArrow);
1128
GXMAP(type,XK_Caps_Lock, GHOST_kKeyCapsLock);
1129
GXMAP(type,XK_Scroll_Lock, GHOST_kKeyScrollLock);
1130
GXMAP(type,XK_Num_Lock, GHOST_kKeyNumLock);
1134
GXMAP(type,XK_KP_0, GHOST_kKeyNumpad0);
1135
GXMAP(type,XK_KP_1, GHOST_kKeyNumpad1);
1136
GXMAP(type,XK_KP_2, GHOST_kKeyNumpad2);
1137
GXMAP(type,XK_KP_3, GHOST_kKeyNumpad3);
1138
GXMAP(type,XK_KP_4, GHOST_kKeyNumpad4);
1139
GXMAP(type,XK_KP_5, GHOST_kKeyNumpad5);
1140
GXMAP(type,XK_KP_6, GHOST_kKeyNumpad6);
1141
GXMAP(type,XK_KP_7, GHOST_kKeyNumpad7);
1142
GXMAP(type,XK_KP_8, GHOST_kKeyNumpad8);
1143
GXMAP(type,XK_KP_9, GHOST_kKeyNumpad9);
1144
GXMAP(type,XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
1146
GXMAP(type,XK_KP_Insert, GHOST_kKeyNumpad0);
1147
GXMAP(type,XK_KP_End, GHOST_kKeyNumpad1);
1148
GXMAP(type,XK_KP_Down, GHOST_kKeyNumpad2);
1149
GXMAP(type,XK_KP_Page_Down, GHOST_kKeyNumpad3);
1150
GXMAP(type,XK_KP_Left, GHOST_kKeyNumpad4);
1151
GXMAP(type,XK_KP_Begin, GHOST_kKeyNumpad5);
1152
GXMAP(type,XK_KP_Right, GHOST_kKeyNumpad6);
1153
GXMAP(type,XK_KP_Home, GHOST_kKeyNumpad7);
1154
GXMAP(type,XK_KP_Up, GHOST_kKeyNumpad8);
1155
GXMAP(type,XK_KP_Page_Up, GHOST_kKeyNumpad9);
1156
GXMAP(type,XK_KP_Delete, GHOST_kKeyNumpadPeriod);
1158
GXMAP(type,XK_KP_Enter, GHOST_kKeyNumpadEnter);
1159
GXMAP(type,XK_KP_Add, GHOST_kKeyNumpadPlus);
1160
GXMAP(type,XK_KP_Subtract, GHOST_kKeyNumpadMinus);
1161
GXMAP(type,XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
1162
GXMAP(type,XK_KP_Divide, GHOST_kKeyNumpadSlash);
1380
GXMAP(type, XK_BackSpace, GHOST_kKeyBackSpace);
1381
GXMAP(type, XK_Tab, GHOST_kKeyTab);
1382
GXMAP(type, XK_Return, GHOST_kKeyEnter);
1383
GXMAP(type, XK_Escape, GHOST_kKeyEsc);
1384
GXMAP(type, XK_space, GHOST_kKeySpace);
1386
GXMAP(type, XK_Linefeed, GHOST_kKeyLinefeed);
1387
GXMAP(type, XK_semicolon, GHOST_kKeySemicolon);
1388
GXMAP(type, XK_period, GHOST_kKeyPeriod);
1389
GXMAP(type, XK_comma, GHOST_kKeyComma);
1390
GXMAP(type, XK_quoteright, GHOST_kKeyQuote);
1391
GXMAP(type, XK_quoteleft, GHOST_kKeyAccentGrave);
1392
GXMAP(type, XK_minus, GHOST_kKeyMinus);
1393
GXMAP(type, XK_slash, GHOST_kKeySlash);
1394
GXMAP(type, XK_backslash, GHOST_kKeyBackslash);
1395
GXMAP(type, XK_equal, GHOST_kKeyEqual);
1396
GXMAP(type, XK_bracketleft, GHOST_kKeyLeftBracket);
1397
GXMAP(type, XK_bracketright, GHOST_kKeyRightBracket);
1398
GXMAP(type, XK_Pause, GHOST_kKeyPause);
1400
GXMAP(type, XK_Shift_L, GHOST_kKeyLeftShift);
1401
GXMAP(type, XK_Shift_R, GHOST_kKeyRightShift);
1402
GXMAP(type, XK_Control_L, GHOST_kKeyLeftControl);
1403
GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
1404
GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
1405
GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
1406
GXMAP(type, XK_Super_L, GHOST_kKeyOS);
1407
GXMAP(type, XK_Super_R, GHOST_kKeyOS);
1409
GXMAP(type, XK_Insert, GHOST_kKeyInsert);
1410
GXMAP(type, XK_Delete, GHOST_kKeyDelete);
1411
GXMAP(type, XK_Home, GHOST_kKeyHome);
1412
GXMAP(type, XK_End, GHOST_kKeyEnd);
1413
GXMAP(type, XK_Page_Up, GHOST_kKeyUpPage);
1414
GXMAP(type, XK_Page_Down, GHOST_kKeyDownPage);
1416
GXMAP(type, XK_Left, GHOST_kKeyLeftArrow);
1417
GXMAP(type, XK_Right, GHOST_kKeyRightArrow);
1418
GXMAP(type, XK_Up, GHOST_kKeyUpArrow);
1419
GXMAP(type, XK_Down, GHOST_kKeyDownArrow);
1421
GXMAP(type, XK_Caps_Lock, GHOST_kKeyCapsLock);
1422
GXMAP(type, XK_Scroll_Lock, GHOST_kKeyScrollLock);
1423
GXMAP(type, XK_Num_Lock, GHOST_kKeyNumLock);
1427
GXMAP(type, XK_KP_0, GHOST_kKeyNumpad0);
1428
GXMAP(type, XK_KP_1, GHOST_kKeyNumpad1);
1429
GXMAP(type, XK_KP_2, GHOST_kKeyNumpad2);
1430
GXMAP(type, XK_KP_3, GHOST_kKeyNumpad3);
1431
GXMAP(type, XK_KP_4, GHOST_kKeyNumpad4);
1432
GXMAP(type, XK_KP_5, GHOST_kKeyNumpad5);
1433
GXMAP(type, XK_KP_6, GHOST_kKeyNumpad6);
1434
GXMAP(type, XK_KP_7, GHOST_kKeyNumpad7);
1435
GXMAP(type, XK_KP_8, GHOST_kKeyNumpad8);
1436
GXMAP(type, XK_KP_9, GHOST_kKeyNumpad9);
1437
GXMAP(type, XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
1439
GXMAP(type, XK_KP_Insert, GHOST_kKeyNumpad0);
1440
GXMAP(type, XK_KP_End, GHOST_kKeyNumpad1);
1441
GXMAP(type, XK_KP_Down, GHOST_kKeyNumpad2);
1442
GXMAP(type, XK_KP_Page_Down, GHOST_kKeyNumpad3);
1443
GXMAP(type, XK_KP_Left, GHOST_kKeyNumpad4);
1444
GXMAP(type, XK_KP_Begin, GHOST_kKeyNumpad5);
1445
GXMAP(type, XK_KP_Right, GHOST_kKeyNumpad6);
1446
GXMAP(type, XK_KP_Home, GHOST_kKeyNumpad7);
1447
GXMAP(type, XK_KP_Up, GHOST_kKeyNumpad8);
1448
GXMAP(type, XK_KP_Page_Up, GHOST_kKeyNumpad9);
1449
GXMAP(type, XK_KP_Delete, GHOST_kKeyNumpadPeriod);
1451
GXMAP(type, XK_KP_Enter, GHOST_kKeyNumpadEnter);
1452
GXMAP(type, XK_KP_Add, GHOST_kKeyNumpadPlus);
1453
GXMAP(type, XK_KP_Subtract, GHOST_kKeyNumpadMinus);
1454
GXMAP(type, XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
1455
GXMAP(type, XK_KP_Divide, GHOST_kKeyNumpadSlash);
1164
1457
/* Media keys in some keyboards and laptops with XFree86/Xorg */
1165
1458
#ifdef WITH_XF86KEYSYM
1166
GXMAP(type,XF86XK_AudioPlay, GHOST_kKeyMediaPlay);
1167
GXMAP(type,XF86XK_AudioStop, GHOST_kKeyMediaStop);
1168
GXMAP(type,XF86XK_AudioPrev, GHOST_kKeyMediaFirst);
1169
GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
1170
GXMAP(type,XF86XK_AudioNext, GHOST_kKeyMediaLast);
1459
GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay);
1460
GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop);
1461
GXMAP(type, XF86XK_AudioPrev, GHOST_kKeyMediaFirst);
1462
GXMAP(type, XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
1463
GXMAP(type, XF86XK_AudioNext, GHOST_kKeyMediaLast);
1171
1464
#ifdef XF86XK_AudioForward /* Debian lenny's XF86keysym.h has no XF86XK_AudioForward define */
1172
GXMAP(type,XF86XK_AudioForward, GHOST_kKeyMediaLast);
1465
GXMAP(type, XF86XK_AudioForward, GHOST_kKeyMediaLast);
1176
/* some extra sun cruft (NICE KEYBOARD!) */
1469
/* some extra sun cruft (NICE KEYBOARD!) */
1178
GXMAP(type,0xffde, GHOST_kKeyNumpad1);
1179
GXMAP(type,0xffe0, GHOST_kKeyNumpad3);
1180
GXMAP(type,0xffdc, GHOST_kKeyNumpad5);
1181
GXMAP(type,0xffd8, GHOST_kKeyNumpad7);
1182
GXMAP(type,0xffda, GHOST_kKeyNumpad9);
1471
GXMAP(type, 0xffde, GHOST_kKeyNumpad1);
1472
GXMAP(type, 0xffe0, GHOST_kKeyNumpad3);
1473
GXMAP(type, 0xffdc, GHOST_kKeyNumpad5);
1474
GXMAP(type, 0xffd8, GHOST_kKeyNumpad7);
1475
GXMAP(type, 0xffda, GHOST_kKeyNumpad9);
1184
GXMAP(type,0xffd6, GHOST_kKeyNumpadSlash);
1185
GXMAP(type,0xffd7, GHOST_kKeyNumpadAsterisk);
1477
GXMAP(type, 0xffd6, GHOST_kKeyNumpadSlash);
1478
GXMAP(type, 0xffd7, GHOST_kKeyNumpadAsterisk);
1189
1482
type = GHOST_kKeyUnknown;
1278
1571
// not using INCR mechanism, just read the property
1279
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
1280
False, AnyPropertyType, &pty_type,
1281
&pty_format, &pty_items, &pty_size, &buffer);
1283
// finished with property, delete it
1284
XDeleteProperty(m_display, win, m_xclip_out);
1286
// copy the buffer to the pointer for returned data
1572
XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
1573
False, AnyPropertyType, &pty_type,
1574
&pty_format, &pty_items, &pty_size, &buffer);
1576
/* finished with property, delete it */
1577
XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1579
/* copy the buffer to the pointer for returned data */
1287
1580
ltxt = (unsigned char *) malloc(pty_items);
1288
1581
memcpy(ltxt, buffer, pty_items);
1290
// set the length of the returned data
1583
/* set the length of the returned data */
1291
1584
*len = pty_items;
1587
/* free the buffer */
1297
1590
*context = XCLIB_XCOUT_NONE;
1299
// complete contents of selection fetched, return 1
1592
/* complete contents of selection fetched, return 1 */
1302
1595
case XCLIB_XCOUT_INCR:
1303
// To use the INCR method, we basically delete the
1304
// property with the selection in it, wait for an
1305
// event indicating that the property has been created,
1306
// then read it, delete it, etc.
1596
/* To use the INCR method, we basically delete the
1597
* property with the selection in it, wait for an
1598
* event indicating that the property has been created,
1599
* then read it, delete it, etc. */
1308
// make sure that the event is relevant
1601
/* make sure that the event is relevant */
1309
1602
if (evt.type != PropertyNotify)
1312
// skip unless the property has a new value
1605
/* skip unless the property has a new value */
1313
1606
if (evt.xproperty.state != PropertyNewValue)
1316
// check size and format of the property
1317
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
1318
AnyPropertyType, &pty_type, &pty_format,
1319
&pty_items, &pty_size, (unsigned char **) &buffer);
1609
/* check size and format of the property */
1610
XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, 0, False,
1611
AnyPropertyType, &pty_type, &pty_format,
1612
&pty_items, &pty_size, &buffer);
1321
1614
if (pty_format != 8) {
1322
// property does not contain text, delete it
1323
// to tell the other X client that we have read
1324
// it and to send the next property
1615
/* property does not contain text, delete it
1616
* to tell the other X client that we have read
1617
* it and to send the next property */
1326
XDeleteProperty(m_display, win, m_xclip_out);
1619
XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1330
1623
if (pty_size == 0) {
1331
// no more data, exit from loop
1624
/* no more data, exit from loop */
1333
XDeleteProperty(m_display, win, m_xclip_out);
1626
XDeleteProperty(m_display, win, m_atom.XCLIP_OUT);
1334
1627
*context = XCLIB_XCOUT_NONE;
1336
// this means that an INCR transfer is now
1337
// complete, return 1
1629
/* this means that an INCR transfer is now
1630
* complete, return 1 */
1343
// if we have come this far, the propery contains
1344
// text, we know the size.
1345
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
1346
False, AnyPropertyType, &pty_type, &pty_format,
1347
&pty_items, &pty_size, (unsigned char **) &buffer);
1636
/* if we have come this far, the property contains
1637
* text, we know the size. */
1638
XGetWindowProperty(m_display, win, m_atom.XCLIP_OUT, 0, (long) pty_size,
1639
False, AnyPropertyType, &pty_type, &pty_format,
1640
&pty_items, &pty_size, &buffer);
1349
// allocate memory to accommodate data in *txt
1642
/* allocate memory to accommodate data in *txt */
1350
1643
if (*len == 0) {
1351
1644
*len = pty_items;
1352
1645
ltxt = (unsigned char *) malloc(*len);
1495
1789
#ifdef WITH_XDND
1496
1790
GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
1497
GHOST_TDragnDropTypes draggedObjectType,
1498
GHOST_IWindow* window,
1499
int mouseX, int mouseY,
1791
GHOST_TDragnDropTypes draggedObjectType,
1792
GHOST_IWindow *window,
1793
int mouseX, int mouseY,
1502
GHOST_SystemX11* system = ((GHOST_SystemX11*)getSystem());
1796
GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem());
1503
1797
return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
1506
window,mouseX,mouseY,data)
1800
window, mouseX, mouseY, data)
1805
#ifdef WITH_X11_XINPUT
1807
* Dummy function to get around IO Handler exiting if device invalid
1808
* Basically it will not crash blender now if you have a X device that
1809
* is configured but not plugged in.
1811
int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
1813
fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
1814
theEvent->error_code, theEvent->request_code);
1816
/* No exit! - but keep lint happy */
1820
int GHOST_X11_ApplicationIOErrorHandler(Display *display)
1822
fprintf(stderr, "Ignoring Xlib error: error IO\n");
1824
/* No exit! - but keep lint happy */
1828
/* These C functions are copied from Wine 1.1.13's wintab.c */
1833
static bool match_token(const char *haystack, const char *needle)
1836
for (p = haystack; *p; )
1838
while (*p && isspace(*p))
1843
for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
1845
if (!*q && (isspace(*p) || !*p))
1848
while (*p && !isspace(*p))
1855
/* Determining if an X device is a Tablet style device is an imperfect science.
1856
* We rely on common conventions around device names as well as the type reported
1857
* by Wacom tablets. This code will likely need to be expanded for alternate tablet types
1859
* Wintab refers to any device that interacts with the tablet as a cursor,
1860
* (stylus, eraser, tablet mouse, airbrush, etc)
1861
* this is not to be confused with wacom x11 configuration "cursor" device.
1862
* Wacoms x11 config "cursor" refers to its device slot (which we mirror with
1863
* our gSysCursors) for puck like devices (tablet mice essentially).
1866
static BOOL is_tablet_cursor(const char *name, const char *type)
1869
static const char *tablet_cursor_whitelist[] = {
1881
for (i = 0; tablet_cursor_whitelist[i] != NULL; i++) {
1882
if (name && match_token(name, tablet_cursor_whitelist[i]))
1884
if (type && match_token(type, tablet_cursor_whitelist[i]))
1890
static BOOL is_stylus(const char *name, const char *type)
1893
static const char *tablet_stylus_whitelist[] = {
1900
for (i = 0; tablet_stylus_whitelist[i] != NULL; i++) {
1901
if (name && match_token(name, tablet_stylus_whitelist[i]))
1903
if (type && match_token(type, tablet_stylus_whitelist[i]))
1910
static BOOL is_eraser(const char *name, const char *type)
1912
if (name && match_token(name, "eraser"))
1914
if (type && match_token(type, "eraser"))
1921
/* end code copied from wine */
1923
void GHOST_SystemX11::initXInputDevices()
1925
static XErrorHandler old_handler = (XErrorHandler) 0;
1926
static XIOErrorHandler old_handler_io = (XIOErrorHandler) 0;
1928
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
1930
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
1931
if (version->present) {
1933
XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
1934
m_xtablet.StylusDevice = NULL;
1935
m_xtablet.EraserDevice = NULL;
1937
/* Install our error handler to override Xlib's termination behavior */
1938
old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
1939
old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
1941
for (int i = 0; i < device_count; ++i) {
1942
char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
1944
// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
1947
if ((m_xtablet.StylusDevice == NULL) &&
1948
(is_stylus(device_info[i].name, device_type) || (device_info[i].type == m_atom.TABLET)))
1950
// printf("\tfound stylus\n");
1951
m_xtablet.StylusID = device_info[i].id;
1952
m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
1954
if (m_xtablet.StylusDevice != NULL) {
1955
/* Find how many pressure levels tablet has */
1956
XAnyClassPtr ici = device_info[i].inputclassinfo;
1957
for (int j = 0; j < m_xtablet.StylusDevice->num_classes; ++j) {
1958
if (ici->c_class == ValuatorClass) {
1959
// printf("\t\tfound ValuatorClass\n");
1960
XValuatorInfo *xvi = (XValuatorInfo *)ici;
1961
m_xtablet.PressureLevels = xvi->axes[2].max_value;
1963
if (xvi->num_axes > 3) {
1964
/* this is assuming that the tablet has the same tilt resolution in both
1965
* positive and negative directions. It would be rather weird if it didn't.. */
1966
m_xtablet.XtiltLevels = xvi->axes[3].max_value;
1967
m_xtablet.YtiltLevels = xvi->axes[4].max_value;
1970
m_xtablet.XtiltLevels = 0;
1971
m_xtablet.YtiltLevels = 0;
1977
ici = (XAnyClassPtr)(((char *)ici) + ici->length);
1981
m_xtablet.StylusID = 0;
1984
else if ((m_xtablet.EraserDevice == NULL) &&
1985
(is_eraser(device_info[i].name, device_type)))
1987
// printf("\tfound eraser\n");
1988
m_xtablet.EraserID = device_info[i].id;
1989
m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
1990
if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID = 0;
1994
XFree((void *)device_type);
1998
/* Restore handler */
1999
(void) XSetErrorHandler(old_handler);
2000
(void) XSetIOErrorHandler(old_handler_io);
2002
XFreeDeviceList(device_info);
2008
#endif /* WITH_X11_XINPUT */