source: OGRE/trunk/ogrenew/PlatformManagers/gtk/src/GTKInput.cpp @ 657

Revision 657, 13.1 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://ogre.sourceforge.net/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25
26#include "GTKInput.h"
27#include "OgreInputEvent.h"
28#include "OgreRenderWindow.h"
29
30#include <sigc++/slot.h>
31
32#include <gdk/gdkkeysyms.h>
33#include <gdk/gdkx.h>
34#include <gdkmm/cursor.h>
35
36using namespace Ogre;
37
38GTKInput::GTKInput() : InputReader(),
39        _win(0),
40        _widget(0),
41        _kit(0)
42
43{
44    mEventQueue = 0;
45    mScale = 0.002;
46    _visible = false;
47
48    _key_map.insert(InputKeyMap::value_type(GDK_Escape,KC_ESCAPE));
49    _key_map.insert(InputKeyMap::value_type(GDK_1, KC_1));
50    _key_map.insert(InputKeyMap::value_type(GDK_2, KC_2));
51    _key_map.insert(InputKeyMap::value_type(GDK_3, KC_3));
52    _key_map.insert(InputKeyMap::value_type(GDK_4, KC_4));
53    _key_map.insert(InputKeyMap::value_type(GDK_5, KC_5));
54    _key_map.insert(InputKeyMap::value_type(GDK_6, KC_6));
55    _key_map.insert(InputKeyMap::value_type(GDK_7, KC_7));
56    _key_map.insert(InputKeyMap::value_type(GDK_8, KC_8));
57    _key_map.insert(InputKeyMap::value_type(GDK_9, KC_9));
58    _key_map.insert(InputKeyMap::value_type(GDK_0, KC_0));
59    _key_map.insert(InputKeyMap::value_type(GDK_minus, KC_MINUS));
60    _key_map.insert(InputKeyMap::value_type(GDK_equal, KC_EQUALS));
61    _key_map.insert(InputKeyMap::value_type(GDK_BackSpace, KC_BACK));
62    _key_map.insert(InputKeyMap::value_type(GDK_Tab, KC_TAB));
63    _key_map.insert(InputKeyMap::value_type(GDK_q, KC_Q));
64    _key_map.insert(InputKeyMap::value_type(GDK_w, KC_W));
65    _key_map.insert(InputKeyMap::value_type(GDK_e, KC_E));
66    _key_map.insert(InputKeyMap::value_type(GDK_r, KC_R));
67    _key_map.insert(InputKeyMap::value_type(GDK_t, KC_T));
68    _key_map.insert(InputKeyMap::value_type(GDK_y, KC_Y));
69    _key_map.insert(InputKeyMap::value_type(GDK_u, KC_U));
70    _key_map.insert(InputKeyMap::value_type(GDK_i, KC_I));
71    _key_map.insert(InputKeyMap::value_type(GDK_o, KC_O));
72    _key_map.insert(InputKeyMap::value_type(GDK_p, KC_P));
73    _key_map.insert(InputKeyMap::value_type(GDK_Return, KC_RETURN));
74    _key_map.insert(InputKeyMap::value_type(GDK_Control_L, KC_LCONTROL));
75    _key_map.insert(InputKeyMap::value_type(GDK_a, KC_A));
76    _key_map.insert(InputKeyMap::value_type(GDK_s, KC_S));
77    _key_map.insert(InputKeyMap::value_type(GDK_d, KC_D));
78    _key_map.insert(InputKeyMap::value_type(GDK_f, KC_F));
79    _key_map.insert(InputKeyMap::value_type(GDK_g, KC_G));
80    _key_map.insert(InputKeyMap::value_type(GDK_h, KC_H));
81    _key_map.insert(InputKeyMap::value_type(GDK_j, KC_J));
82    _key_map.insert(InputKeyMap::value_type(GDK_k, KC_K));
83    _key_map.insert(InputKeyMap::value_type(GDK_l, KC_L));
84    _key_map.insert(InputKeyMap::value_type(GDK_Shift_L, KC_LSHIFT));
85    _key_map.insert(InputKeyMap::value_type(GDK_backslash, KC_BACKSLASH));
86    _key_map.insert(InputKeyMap::value_type(GDK_z, KC_Z));
87    _key_map.insert(InputKeyMap::value_type(GDK_x, KC_X));
88    _key_map.insert(InputKeyMap::value_type(GDK_c, KC_C));
89    _key_map.insert(InputKeyMap::value_type(GDK_v, KC_V));
90    _key_map.insert(InputKeyMap::value_type(GDK_b, KC_B));
91    _key_map.insert(InputKeyMap::value_type(GDK_n, KC_N));
92    _key_map.insert(InputKeyMap::value_type(GDK_m, KC_M));
93    _key_map.insert(InputKeyMap::value_type(GDK_comma, KC_COMMA));
94    _key_map.insert(InputKeyMap::value_type(GDK_period, KC_PERIOD));
95    _key_map.insert(InputKeyMap::value_type(GDK_Shift_R, KC_RSHIFT));
96    _key_map.insert(InputKeyMap::value_type(GDK_KP_Multiply, KC_MULTIPLY));
97    _key_map.insert(InputKeyMap::value_type(GDK_Alt_L, KC_LMENU));
98    _key_map.insert(InputKeyMap::value_type(GDK_space, KC_SPACE));
99    _key_map.insert(InputKeyMap::value_type(GDK_Caps_Lock, KC_CAPITAL));
100    _key_map.insert(InputKeyMap::value_type(GDK_F1, KC_F1));
101    _key_map.insert(InputKeyMap::value_type(GDK_F2, KC_F2));
102    _key_map.insert(InputKeyMap::value_type(GDK_F3, KC_F3));
103    _key_map.insert(InputKeyMap::value_type(GDK_F4, KC_F4));
104    _key_map.insert(InputKeyMap::value_type(GDK_F5, KC_F5));
105    _key_map.insert(InputKeyMap::value_type(GDK_F6, KC_F6));
106    _key_map.insert(InputKeyMap::value_type(GDK_F7, KC_F7));
107    _key_map.insert(InputKeyMap::value_type(GDK_F8, KC_F8));
108    _key_map.insert(InputKeyMap::value_type(GDK_F9, KC_F9));
109    _key_map.insert(InputKeyMap::value_type(GDK_F10, KC_F10));
110    _key_map.insert(InputKeyMap::value_type(GDK_Num_Lock, KC_NUMLOCK));
111    _key_map.insert(InputKeyMap::value_type(GDK_Scroll_Lock, KC_SCROLL));
112    _key_map.insert(InputKeyMap::value_type(GDK_KP_7, KC_NUMPAD7));
113    _key_map.insert(InputKeyMap::value_type(GDK_KP_8, KC_NUMPAD8));
114    _key_map.insert(InputKeyMap::value_type(GDK_KP_9, KC_NUMPAD9));
115    _key_map.insert(InputKeyMap::value_type(GDK_KP_Subtract, KC_SUBTRACT));
116    _key_map.insert(InputKeyMap::value_type(GDK_KP_4, KC_NUMPAD4));
117    _key_map.insert(InputKeyMap::value_type(GDK_KP_5, KC_NUMPAD5));
118    _key_map.insert(InputKeyMap::value_type(GDK_KP_6, KC_NUMPAD6));
119    _key_map.insert(InputKeyMap::value_type(GDK_KP_Add, KC_ADD));
120    _key_map.insert(InputKeyMap::value_type(GDK_KP_1, KC_NUMPAD1));
121    _key_map.insert(InputKeyMap::value_type(GDK_KP_2, KC_NUMPAD2));
122    _key_map.insert(InputKeyMap::value_type(GDK_KP_3, KC_NUMPAD3));
123    _key_map.insert(InputKeyMap::value_type(GDK_KP_0, KC_NUMPAD0));
124    _key_map.insert(InputKeyMap::value_type(GDK_KP_Decimal, KC_DECIMAL));
125    _key_map.insert(InputKeyMap::value_type(GDK_F11, KC_F11));
126    _key_map.insert(InputKeyMap::value_type(GDK_F12, KC_F12));
127    _key_map.insert(InputKeyMap::value_type(GDK_F13, KC_F13));
128    _key_map.insert(InputKeyMap::value_type(GDK_F14, KC_F14));
129    _key_map.insert(InputKeyMap::value_type(GDK_F15, KC_F15));
130    _key_map.insert(InputKeyMap::value_type(GDK_KP_Equal, KC_NUMPADEQUALS));
131    _key_map.insert(InputKeyMap::value_type(GDK_KP_Divide, KC_DIVIDE));
132    _key_map.insert(InputKeyMap::value_type(GDK_Sys_Req, KC_SYSRQ));
133    _key_map.insert(InputKeyMap::value_type(GDK_Alt_R, KC_RMENU));
134    _key_map.insert(InputKeyMap::value_type(GDK_Home, KC_HOME));
135    _key_map.insert(InputKeyMap::value_type(GDK_Up, KC_UP));
136    _key_map.insert(InputKeyMap::value_type(GDK_Page_Up, KC_PGUP));
137    _key_map.insert(InputKeyMap::value_type(GDK_Left, KC_LEFT));
138    _key_map.insert(InputKeyMap::value_type(GDK_Right, KC_RIGHT));
139    _key_map.insert(InputKeyMap::value_type(GDK_End, KC_END));
140    _key_map.insert(InputKeyMap::value_type(GDK_Down, KC_DOWN));
141    _key_map.insert(InputKeyMap::value_type(GDK_Page_Down, KC_PGDOWN));
142    _key_map.insert(InputKeyMap::value_type(GDK_Insert, KC_INSERT));
143    _key_map.insert(InputKeyMap::value_type(GDK_Delete, KC_DELETE));
144    _key_map.insert(InputKeyMap::value_type(GDK_Super_L, KC_LWIN));
145    _key_map.insert(InputKeyMap::value_type(GDK_Super_R, KC_RWIN));
146
147    for(InputKeyMap::iterator it = _key_map.begin();
148        it != _key_map.end(); ++it)
149    {
150        _rkey_map.insert(RInputKeyMap::value_type(it->second, it->first));
151    }
152}
153
154GTKInput::~GTKInput()
155{
156        // XXX Do more?
157        // It's not needed to detach the various signals here, that
158        // happens automatically.
159}
160
161void GTKInput::initialise(RenderWindow* pWindow, bool useKeyboard,
162                          bool useMouse, bool useGameController)
163{
164        _kit = Gtk::Main::instance();
165        // Extract Window and DrawingArea from pWindow in magic way
166        pWindow->getCustomAttribute("GTKMMWINDOW", &_win);
167        pWindow->getCustomAttribute("GTKGLMMWIDGET", &_widget);
168
169        // Do mouse capture only when this is stated
170        mUseMouse = useMouse;
171
172        if(mUseMouse) {
173                unsigned int w, h, d;
174                int l, t;
175                pWindow->getMetrics(w, h, d, l, t);
176
177                mMouseCenterX = w / 2;
178                mMouseCenterY = h / 2;
179
180                Glib::RefPtr<Gdk::Window> win = _win->get_window();
181                Gdk::Color col;
182                char invisible_cursor_bits[] = { 0x0 };
183                Glib::RefPtr<Gdk::Pixmap> nada = Gdk::Pixmap::create_from_data(win,
184                        invisible_cursor_bits, 1, 1, 1, col, col);
185
186                win->set_cursor(Gdk::Cursor(nada, nada, col, col, 0, 0));
187        }
188
189        /**
190         * Connect key handlers before any other
191         */
192        _win->signal_key_press_event().connect(
193                SigC::slot(*this, &GTKInput::on_key_press), false);
194        _win->signal_key_release_event().connect(
195                SigC::slot(*this, &GTKInput::on_key_release), false);
196
197        if(mUseMouse) {
198                _widget->signal_motion_notify_event().connect(
199                        SigC::slot(*this, &GTKInput::on_mouse_motion));
200                _widget->signal_button_press_event().connect(
201                        SigC::slot(*this, &GTKInput::on_button_press));
202                _widget->signal_button_release_event().connect(
203                        SigC::slot(*this, &GTKInput::on_button_release));
204        }
205}
206
207void GTKInput::capture()
208{
209    _visible = true;
210    // We pump it a few times to make sure we get smooth operation
211    for (int x = 0; x < 10; ++x)
212    {
213        if (_kit->events_pending())
214        {
215                _kit->iteration(false);
216        } else break;
217    }
218    _captured_keys = _cur_keys;
219
220        if (mUseMouse) {
221                if (!mUseBufferedMouse) {
222                        mMouseState.Xabs = mMouseX;
223                        mMouseState.Yabs = mMouseY;
224                        mMouseState.Zabs = 0;
225
226                        mMouseState.Xrel = mMouseX - mMouseCenterX;
227                        mMouseState.Yrel = mMouseY - mMouseCenterY;
228                        mMouseState.Zrel = 0;
229                }
230
231#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
232                XWarpPointer(GDK_WINDOW_XDISPLAY(_win->get_window()->gobj()), None,
233                         GDK_WINDOW_XWINDOW(_win->get_window()->gobj()), 0, 0, 0, 0,
234                        mMouseCenterX, mMouseCenterY);
235#endif
236
237                mMouseX = mMouseCenterX;
238                mMouseY = mMouseCenterY;
239        }
240}
241
242bool GTKInput::isKeyDownImmediate( KeyCode kc ) const
243{
244    RInputKeyMap::const_iterator it = _rkey_map.find(kc);
245    // Make sure it's a mappable key
246    if (it == _rkey_map.end())
247        return false;
248
249    if (std::count(_captured_keys.begin(), _captured_keys.end(), it->second))
250        return true;
251    return false;
252}
253
254long GTKInput::getMouseRelX() const
255{
256    return mMouseState.Xrel;
257}
258
259long GTKInput::getMouseRelY() const
260{
261    return mMouseState.Yrel;
262}
263
264long GTKInput::getMouseRelZ() const
265{
266    return 0;
267}
268
269long GTKInput::getMouseAbsX() const
270{
271    return mMouseState.Xabs;
272}
273
274long GTKInput::getMouseAbsY() const
275{
276    return mMouseState.Yabs;
277}
278
279long GTKInput::getMouseAbsZ() const
280{
281    return 0;
282}
283
284bool GTKInput::getMouseButton( uchar button ) const
285{
286    return mMouseState.isButtonDown( button );
287}
288
289void GTKInput::getMouseState( MouseState& state) const
290{
291    state = mMouseState;
292}
293
294bool GTKInput::on_mouse_motion(GdkEventMotion* event)
295{
296    // Skip warps, might hit a regular movement, but that's acceptable
297    if (event->x == mMouseCenterX && event->y == mMouseCenterY)
298    {
299        return false;
300    }
301
302    mMouseX = static_cast<int>(event->x);
303    mMouseY = static_cast<int>(event->y);
304
305    //printf("MOUSE AT: %d,%d\n", mMouseX, mMouseY);
306
307    if (mUseBufferedMouse)
308    {
309        mouseMoved();
310    }
311
312    return false;
313}
314
315bool GTKInput::on_key_press(GdkEventKey* event)
316{
317    _cur_keys.insert(event->keyval);
318    if (mUseBufferedKeys)
319        keyChanged(_key_map[event->keyval], true);
320
321    return false;
322}
323
324bool GTKInput::on_key_release(GdkEventKey* event)
325{
326    _cur_keys.erase(event->keyval);
327    if (mUseBufferedKeys)
328        keyChanged(_key_map[event->keyval], false);
329
330    return false;
331}
332
333bool GTKInput::on_button_press(GdkEventButton* event)
334{
335    int button;
336
337    switch(event->button)
338    {
339    case 1:
340        button = InputEvent::BUTTON0_MASK;
341        break;
342    case 2:
343        button = InputEvent::BUTTON2_MASK;
344        break;
345    case 3:
346        button = InputEvent::BUTTON1_MASK;
347        break;
348    };
349
350    if (mUseBufferedMouse)
351        triggerMouseButton(button, true);
352
353    return false;
354}
355
356bool GTKInput::on_button_release(GdkEventButton* event)
357{
358    int button;
359
360    switch(event->button)
361    {
362    case 1:
363        button = InputEvent::BUTTON0_MASK;
364        break;
365    case 2:
366        button = InputEvent::BUTTON2_MASK;
367        break;
368    case 3:
369        button = InputEvent::BUTTON1_MASK;
370        break;
371    };
372
373    if (mUseBufferedMouse)
374        triggerMouseButton(button, false);
375
376    return false;
377}
Note: See TracBrowser for help on using the repository browser.