removed tchar.h usage
[fegdk.git] / core / code / video / x11 / x11viewport.cpp
blob3e2ba8a1408734880d54a5e369f41c7e47184f6b
1 /*
2 fegdk: FE Game Development Kit
3 Copyright (C) 2001-2008 Alexey "waker" Yakovenko
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 Alexander Maltsev
20 keltar@users.sourceforge.net
23 #include "pch.h"
24 #include "config.h"
26 #include "x11viewport.h"
27 #include "x11viewportdata.h"
28 #include "x11renderer.h"
29 #include "f_helpers.h"
30 #include "f_engine.h"
31 #include "f_input.h"
32 #include "f_application.h"
33 #include "f_baserenderer.h"
34 #include "f_util.h"
35 #include <X11/keysym.h>
36 #include "utf8.h"
38 namespace fe
41 // table to translate x11 keycodes into native fe codes
42 int x11_to_key[] = {
43 0, 0, 0, 0, 0, 0, 0, 0, Key_BackSpace, Key_Tab,
44 0, 0, 0, Key_CR, 0, 0, 0, 0, 0, Key_Pause,
45 Key_ScrollLock, 0, 0, 0, 0, 0, 0, Key_Esc, 0, 0,
46 0, 0, Key_Space, 0, 0, 0, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 Key_Home, Key_LeftArrow, Key_UpArrow, Key_RightArrow, Key_DownArrow, Key_PgUp, Key_PgDn, Key_End, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0, 0, Key_Kp_Ins,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, Key_Kp_NumLock, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, Key_Kp_Enter, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10,
63 Key_F11, Key_F12, Key_F13, Key_F14, Key_F15, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, Key_LShift, Key_RShift, Key_RCtrl, Key_LCtrl, Key_CapsLock,
66 Key_LMeta, Key_RMeta, Key_LAlt, Key_RAlt, Key_LSuper, Key_RSuper, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, Key_Del, // 255
70 // keypad
72 0, Key_Kp_DownArrow, 0, Key_Kp_PgDn,
73 Key_Kp_LeftArrow, Key_Kp_5, Key_Kp_RightArrow,
74 0, Key_Kp_UpArrow, Key_Kp_PgUp,
75 Key_Kp_Del, Key_Kp_Slash, Key_Kp_Star,
76 Key_Kp_Minus, Key_Kp_Plus, Key_Kp_Enter, Key_Kp_Equals,
79 // viewport data
80 x11ViewportData::x11ViewportData (void)
84 x11ViewportData::~x11ViewportData (void)
88 uint16 x11ViewportData::xkeyToUcs4 (XKeyEvent *xkey)
90 Status state;
91 char keybuf[7];
92 x11RendererData *rd = checked_cast <x11Renderer*> (g_engine->getRenderer ())->getData ();
93 if (Xutf8LookupString (rd->mXIC, xkey, keybuf, sizeof (keybuf), NULL, &state))
95 char *utf8 = (char*)keybuf;
96 uint32 ucs4[2] = { 0, 0 };
97 u8_toucs (ucs4, 2, utf8, 6);
98 return ucs4[0];
100 return 0;
103 void x11ViewportData::handleEvent (XEvent *event)
105 x11Renderer *rend = checked_cast <x11Renderer*> (g_engine->getRenderer ());
106 switch (event->type)
108 case MotionNotify:
109 onMouseMove (event->xmotion.x, event->xmotion.y);
110 break;
111 case ButtonPress:
112 onMouseBtnDown (event->xbutton.button);
113 break;
114 case ButtonRelease:
115 onMouseBtnUp (event->xbutton.button);
116 break;
117 case KeyPress:
119 int keysym = XKeycodeToKeysym (rend->getData ()->mpDisplay, event->xkey.keycode, 0) & 0xff;
120 int unicode = xkeyToUcs4 (&event->xkey);
121 onKeyDown (keysym, unicode);
122 fprintf (stderr, "INFO: keycode=%d, keysym=%d, unicode=%d\n", event->xkey.keycode, keysym, unicode);
124 break;
125 case KeyRelease:
126 onKeyUp (XKeycodeToKeysym (rend->getData ()->mpDisplay, event->xkey.keycode, 0) & 0xff);
127 break;
131 void x11ViewportData::onMouseMove (int x, int y)
133 smartPtr <inputDevice> mouse = g_engine->getInputDevice ();
134 mouse->mouseMove (x, y);
135 g_engine->getApplication ()->mouseMove (x, y);
138 void x11ViewportData::onMouseBtnDown (int x11_btn)
140 smartPtr <inputDevice> mouse = g_engine->getInputDevice ();
142 switch (x11_btn)
144 case Button4: // wheel up
145 g_engine->getApplication ()->mouseWheel (1);
146 break;
147 case Button5: // wheel down
148 g_engine->getApplication ()->mouseWheel (-1);
149 break;
150 case Button1: // left button
151 mouse->lButtonDown ();
152 g_engine->getApplication ()->mouseDown (Key_Mouse1);
153 break;
154 case Button3: // right button
155 mouse->rButtonDown ();
156 g_engine->getApplication ()->mouseDown (Key_Mouse2);
157 break;
158 case Button2: // middle button
159 mouse->mButtonDown ();
160 g_engine->getApplication ()->mouseDown (Key_Mouse3);
161 break;
165 void x11ViewportData::onMouseBtnUp (int x11_btn)
167 smartPtr <inputDevice> mouse = g_engine->getInputDevice ();
169 switch (x11_btn)
171 case Button1:
172 mouse->lButtonUp ();
173 g_engine->getApplication ()->mouseUp (Key_Mouse1);
174 break;
175 case Button3:
176 mouse->rButtonUp ();
177 g_engine->getApplication ()->mouseUp (Key_Mouse2);
178 break;
179 case Button2:
180 mouse->mButtonUp ();
181 g_engine->getApplication ()->mouseUp (Key_Mouse3);
182 break;
186 static bool filterSpecialCases (int x11_key, int unicode)
188 // capslock sends this when we have
189 // 'Option "XkbOptions" "grp:caps_toggle,grp_led:caps"' in xorg.conf
190 if (x11_key == 8 && unicode == 0)
191 return true;
193 return false;
196 void x11ViewportData::onKeyDown (int x11_key, int unicode)
198 if (filterSpecialCases (x11_key, unicode))
200 return;
202 smartPtr <inputDevice> keyb = g_engine->getInputDevice ();
203 // FIXME: we need to check keys such as alt, super, shift, etc
204 if (unicode >= 0x20
205 && unicode != 0x7f // del should not be passed
208 keyb->printableChar (unicode);
211 // remap x11 codes to fe codes
212 if (x11_key >= (sizeof (x11_to_key) / sizeof (int)) || x11_to_key[x11_key] == 0)
214 if (x11_key < 127)
215 keyb->keyDown (x11_key); // this should never happen
216 else
218 fprintf (stderr, "WARNING: onKeyDown got unhandled x11 keycode %d\n", x11_key);
221 else
223 keyb->keyDown (x11_to_key[x11_key]);
227 void x11ViewportData::onKeyUp (int x11_key)
229 smartPtr <inputDevice> keyb = g_engine->getInputDevice ();
230 // remap x11 codes to fe codes
231 if (x11_key >= (sizeof (x11_to_key) / sizeof (int)) || x11_to_key[x11_key] == 0)
233 if (x11_key < 127)
234 keyb->keyUp (x11_key);
235 else
237 fprintf (stderr, "WARNING: onKeyUp got unhandled x11 keycode %d\n", x11_key);
240 else
242 keyb->keyUp (x11_to_key[x11_key]);
246 void x11ViewportData::init (const char *appname)
251 // viewport base
252 x11Viewport::x11Viewport (void)
254 mpViewportData = new x11ViewportData ();
255 init (g_engine->getApplication ()->getTitle ());
258 x11Viewport::~x11Viewport (void)
260 if (mpViewportData)
262 delete mpViewportData;
263 mpViewportData = NULL;
267 void x11Viewport::init (const char *appName)
269 mpViewportData->init (appName);
272 // common window access
273 void x11Viewport::setPosition (int x, int y)
277 void x11Viewport::setSize (int w, int h)
281 int x11Viewport::getLeft (void) const
283 return 0;
286 int x11Viewport::getTop (void) const
288 return 0;
291 int x11Viewport::getWidth (void) const
293 x11Renderer *rend = checked_cast <x11Renderer*> (g_engine->getRenderer ());
294 x11RendererData *rd = rend->getData();
295 return rd->mVidModes[rd->mLastMode].w;
298 int x11Viewport::getHeight (void) const
300 x11Renderer *rend = checked_cast <x11Renderer*> (g_engine->getRenderer ());
301 x11RendererData *rd = rend->getData();
302 return rd->mVidModes[rd->mLastMode].h;
305 void x11Viewport::close (ulong flags)
307 // emulate QUIT
308 x11Renderer *rend = checked_cast <x11Renderer*> (g_engine->getRenderer ());
309 x11RendererData *rd = rend->getData();
310 XExposeEvent event;
311 event.type = Expose;
312 XSendEvent (rd->mpDisplay, rd->mWindow, false, 0, (XEvent*)&event);
315 void x11Viewport::mainLoop (void)
317 // run system loop
318 bool mbRunning = true;
319 x11Renderer *rend = checked_cast <x11Renderer*> (g_engine->getRenderer ());
320 Display *display = rend->getData ()->mpDisplay;
321 Atom wm_delete_window = XInternAtom (display, "WM_DELETE_WINDOW", false);
322 while (mbRunning)
324 XEvent event;
326 while (XPending (display))
328 XNextEvent(display, &event);
329 if (event.type == Expose || (event.type == ClientMessage && event.xclient.format == 32 && event.xclient.data.l[0] == (long)wm_delete_window))
331 mbRunning = false;
332 break;
335 mpViewportData->handleEvent (&event);
338 if (mbRunning)
340 g_engine->tick ();
343 /* // run system loop
344 bool mbRunning = true;
345 Display *display = g_engine->getRenderer ().dynamicCast <x11Renderer> ()->getData ()->mpDisplay;
346 while (mbRunning)
348 XEvent event;
350 while (XPending (display))
352 XNextEvent(display, &event);
353 mpViewportData->handleEvent (&event);
356 if (mbRunning)
357 g_engine->tick ();
361 x11ViewportData* x11Viewport::getViewportData (void)
363 return mpViewportData;