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
20 keltar@users.sourceforge.net
26 #include "x11viewport.h"
27 #include "x11viewportdata.h"
28 #include "x11renderer.h"
29 #include "f_helpers.h"
32 #include "f_application.h"
33 #include "f_baserenderer.h"
35 #include <X11/keysym.h>
41 // table to translate x11 keycodes into native fe codes
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
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
,
80 x11ViewportData::x11ViewportData (void)
84 x11ViewportData::~x11ViewportData (void)
88 uint16
x11ViewportData::xkeyToUcs4 (XKeyEvent
*xkey
)
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);
103 void x11ViewportData::handleEvent (XEvent
*event
)
105 x11Renderer
*rend
= checked_cast
<x11Renderer
*> (g_engine
->getRenderer ());
109 onMouseMove (event
->xmotion
.x
, event
->xmotion
.y
);
112 onMouseBtnDown (event
->xbutton
.button
);
115 onMouseBtnUp (event
->xbutton
.button
);
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
);
126 onKeyUp (XKeycodeToKeysym (rend
->getData ()->mpDisplay
, event
->xkey
.keycode
, 0) & 0xff);
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 ();
144 case Button4
: // wheel up
145 g_engine
->getApplication ()->mouseWheel (1);
147 case Button5
: // wheel down
148 g_engine
->getApplication ()->mouseWheel (-1);
150 case Button1
: // left button
151 mouse
->lButtonDown ();
152 g_engine
->getApplication ()->mouseDown (Key_Mouse1
);
154 case Button3
: // right button
155 mouse
->rButtonDown ();
156 g_engine
->getApplication ()->mouseDown (Key_Mouse2
);
158 case Button2
: // middle button
159 mouse
->mButtonDown ();
160 g_engine
->getApplication ()->mouseDown (Key_Mouse3
);
165 void x11ViewportData::onMouseBtnUp (int x11_btn
)
167 smartPtr
<inputDevice
> mouse
= g_engine
->getInputDevice ();
173 g_engine
->getApplication ()->mouseUp (Key_Mouse1
);
177 g_engine
->getApplication ()->mouseUp (Key_Mouse2
);
181 g_engine
->getApplication ()->mouseUp (Key_Mouse3
);
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)
196 void x11ViewportData::onKeyDown (int x11_key
, int unicode
)
198 if (filterSpecialCases (x11_key
, unicode
))
202 smartPtr
<inputDevice
> keyb
= g_engine
->getInputDevice ();
203 // FIXME: we need to check keys such as alt, super, shift, etc
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)
215 keyb
->keyDown (x11_key
); // this should never happen
218 fprintf (stderr
, "WARNING: onKeyDown got unhandled x11 keycode %d\n", x11_key
);
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)
234 keyb
->keyUp (x11_key
);
237 fprintf (stderr
, "WARNING: onKeyUp got unhandled x11 keycode %d\n", x11_key
);
242 keyb
->keyUp (x11_to_key
[x11_key
]);
246 void x11ViewportData::init (const char *appname
)
252 x11Viewport::x11Viewport (void)
254 mpViewportData
= new x11ViewportData ();
255 init (g_engine
->getApplication ()->getTitle ());
258 x11Viewport::~x11Viewport (void)
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
286 int x11Viewport::getTop (void) const
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
)
308 x11Renderer
*rend
= checked_cast
<x11Renderer
*> (g_engine
->getRenderer ());
309 x11RendererData
*rd
= rend
->getData();
312 XSendEvent (rd
->mpDisplay
, rd
->mWindow
, false, 0, (XEvent
*)&event
);
315 void x11Viewport::mainLoop (void)
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);
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
))
335 mpViewportData
->handleEvent (&event
);
343 /* // run system loop
344 bool mbRunning = true;
345 Display *display = g_engine->getRenderer ().dynamicCast <x11Renderer> ()->getData ()->mpDisplay;
350 while (XPending (display))
352 XNextEvent(display, &event);
353 mpViewportData->handleEvent (&event);
361 x11ViewportData
* x11Viewport::getViewportData (void)
363 return mpViewportData
;