+++ /dev/null
-#ifndef MSP_GRAPHICS_EVENTSOURCE_H_
-#define MSP_GRAPHICS_EVENTSOURCE_H_
-
-namespace Msp {
-namespace Graphics {
-
-class EventSource
-{
-public:
- sigc::signal<void, unsigned, unsigned, unsigned> signal_key_press;
- sigc::signal<void, unsigned, unsigned> signal_key_release;
- sigc::signal<void, int, int, unsigned, unsigned> signal_button_press;
- sigc::signal<void, int, int, unsigned, unsigned> signal_button_release;
- sigc::signal<void, int, int> signal_pointer_motion;
- sigc::signal<void, unsigned, unsigned> signal_resize;
-
-protected:
- EventSource() { }
-public:
- virtual ~EventSource() { }
-
- virtual unsigned get_width() const = 0;
- virtual unsigned get_height() const = 0;
-};
-
-} // namespace Graphics
-} // namespace Msp
-
-#endif
#include <windowsx.h>
#endif
#include <msp/core/application.h>
+#include <msp/core/systemerror.h>
#include "display.h"
#include "window.h"
#include "display_priv.h"
bool Window::event(const Event &evnt)
{
#ifdef WIN32
- WPARAM wp = evnt.wparam;
- LPARAM lp = evnt.lparam;
switch(evnt.msg)
{
case WM_KEYDOWN:
- signal_key_press.emit(wp, 0, wp);
- break;
case WM_KEYUP:
- signal_key_release.emit(wp, 0);
- break;
case WM_LBUTTONDOWN:
- signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0);
- break;
case WM_LBUTTONUP:
- signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0);
- break;
case WM_MBUTTONDOWN:
- signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 2, 0);
- break;
case WM_MBUTTONUP:
- signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 2, 0);
- break;
case WM_RBUTTONDOWN:
- signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 3, 0);
- break;
case WM_RBUTTONUP:
- signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 3, 0);
- break;
case WM_MOUSEWHEEL:
- {
- unsigned btn = (HIWORD(wp)&0x8000) ? 5 : 4;
- signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), btn, 0);
- signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), btn, 0);
- }
- break;
case WM_MOUSEMOVE:
- signal_pointer_motion.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
+ signal_input_event.emit(evnt);
break;
case WM_SIZE:
- options.width = LOWORD(lp);
- options.height = HIWORD(lp);
+ options.width = LOWORD(evnt.lparam);
+ options.height = HIWORD(evnt.lparam);
signal_resize.emit(options.width, options.height);
break;
case WM_CLOSE:
switch(ev.type)
{
case ButtonPress:
- signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
- break;
case ButtonRelease:
- signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
- break;
case MotionNotify:
- signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y);
- break;
case KeyPress:
- {
- char buf[16];
- XLookupString(const_cast<XKeyEvent *>(&ev.xkey), buf, sizeof(buf), 0, 0);
- // XXX Handle the result according to locale
- signal_key_press.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state, buf[0]);
- }
- break;
case KeyRelease:
- signal_key_release.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state);
+ signal_input_event.emit(evnt);
break;
case ConfigureNotify:
if((ev.xconfigure.width==static_cast<int>(options.width) && ev.xconfigure.height==static_cast<int>(options.height)) == resizing)
#include <string>
#include <sigc++/signal.h>
-#include "eventsource.h"
namespace Msp {
namespace Graphics {
WindowOptions();
};
-class Window: public EventSource
+class Window
{
public:
struct Private;
struct Event;
+ /** Provides input events. The event structure contents are platform-
+ specific. Applications will want to use the enclosed Keyboard and Mouse
+ objects instead. */
+ sigc::signal<void, const Event &> signal_input_event;
+
+ sigc::signal<void, unsigned, unsigned> signal_resize;
sigc::signal<void> signal_close;
protected:
#include <windows.h>
#else
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
#endif
#include <msp/graphics/display.h>
+#include <msp/graphics/window.h>
+#include <msp/graphics/display_priv.h>
+#include <msp/graphics/window_priv.h>
#include <msp/strings/format.h>
#include "keyboard.h"
#include "keys.h"
namespace Msp {
namespace Input {
-Keyboard::Keyboard(Graphics::EventSource &s):
- source(s)
+Keyboard::Keyboard(Graphics::Window &w):
+ window(w)
{
name = "Keyboard";
buttons.resize(N_KEYS_, false);
- source.signal_key_press.connect(sigc::mem_fun(this, &Keyboard::key_press));
- source.signal_key_release.connect(sigc::mem_fun(this, &Keyboard::key_release));
+ window.signal_input_event.connect(sigc::mem_fun(this, &Keyboard::input_event));
}
std::string Keyboard::get_button_name(unsigned btn) const
#endif
}
-void Keyboard::key_press(unsigned key, unsigned, unsigned)
+void Keyboard::input_event(const Graphics::Window::Event &event)
{
- set_button_state(key_from_sys(key), true, true);
-}
-
-void Keyboard::key_release(unsigned key, unsigned)
-{
- set_button_state(key_from_sys(key), false, true);
+#ifdef WIN32
+ switch(event.msg)
+ {
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ set_button_state(key_from_sys(event.wparam), event.msg==WM_KEYDOWN, true);
+ break;
+ case WM_CHAR:
+ signal_character.emit(event.wparam);
+ break;
+ }
+#else
+ switch(event.xevent.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ {
+ KeySym keysym = XKeycodeToKeysym(window.get_display().get_private().display, event.xevent.xkey.keycode, 0);
+ if(keysym!=NoSymbol)
+ set_button_state(key_from_sys(keysym), event.xevent.type==KeyPress, true);
+ if(event.xevent.type==KeyPress)
+ {
+ char ch;
+ if(XLookupString(const_cast<XKeyEvent *>(&event.xevent.xkey), &ch, 1, 0, 0))
+ // XLookupString always returns Latin-1
+ signal_character.emit(static_cast<unsigned char>(ch));
+ }
+ }
+ break;
+ }
+#endif
}
} // namespace Input
#define MSP_INPUT_KEYBOARD_H_
#include <msp/graphics/window.h>
+#include <msp/stringcodec/ustring.h>
#include "device.h"
namespace Msp {
*/
class Keyboard: public Device
{
+public:
+ sigc::signal<void, StringCodec::unichar> signal_character;
+
private:
- Graphics::EventSource &source;
+ Graphics::Window &window;
public:
- Keyboard(Graphics::EventSource &);
+ Keyboard(Graphics::Window &);
virtual std::string get_button_name(unsigned) const;
private:
- void key_press(unsigned, unsigned, unsigned);
- void key_release(unsigned, unsigned);
+ void input_event(const Graphics::Window::Event &);
};
} // namespace Input
+#include <msp/graphics/window.h>
+#include <msp/graphics/window_priv.h>
#include <msp/strings/format.h>
#include "mouse.h"
namespace Msp {
namespace Input {
-Mouse::Mouse(Graphics::EventSource &s):
- source(s)
+Mouse::Mouse(Graphics::Window &w):
+ window(w)
{
name = "Mouse";
buttons.resize(3);
axes.resize(2);
- source.signal_button_press.connect(sigc::mem_fun(this, &Mouse::button_press));
- source.signal_button_release.connect(sigc::mem_fun(this, &Mouse::button_release));
- source.signal_pointer_motion.connect(sigc::mem_fun(this, &Mouse::pointer_motion));
+ window.signal_input_event.connect(sigc::mem_fun(this, &Mouse::input_event));
}
std::string Mouse::get_button_name(unsigned btn) const
};
}
-void Mouse::button_press(int, int, unsigned btn, unsigned)
+void Mouse::input_event(const Graphics::Window::Event &event)
{
- set_button_state(btn, true, true);
-}
-
-void Mouse::button_release(int, int, unsigned btn, unsigned)
-{
- set_button_state(btn, false, true);
-}
-
-void Mouse::pointer_motion(int x, int y)
-{
- set_axis_value(0, x*2.0f/source.get_width()-1.0f, true);
- set_axis_value(1, 1.0f-y*2.0f/source.get_height(), true);
+#ifdef WIN32
+ switch(event.msg)
+ {
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ set_button_state(1, event.msg==WM_LBUTTONDOWN, true);
+ break;
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ set_button_state(2, event.msg==WM_LBUTTONDOWN, true);
+ break;
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ set_button_state(3, event.msg==WM_LBUTTONDOWN, true);
+ break;
+ case WM_MOUSEWHEEL:
+ {
+ unsigned btn = (HIWORD(wp)&0x8000) ? 5 : 4;
+ set_button_state(btn, true, true);
+ set_button_state(btn, false, true);
+ }
+ break;
+ case WM_MOUSEMOVE:
+ set_axis_value(0, GET_X_LPARAM(event.lparam)*2.0/window.get_width()-1.0, true);
+ set_axis_value(1, 1.0-GET_Y_LPARAM(event.lparam)*2.0/window.get_height(), true);
+ break;
+ }
+#else
+ switch(event.xevent.type)
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ set_button_state(event.xevent.xbutton.button, event.xevent.type==ButtonPress, true);
+ break;
+ case MotionNotify:
+ set_axis_value(0, event.xevent.xmotion.x*2.0/window.get_width()-1.0, true);
+ set_axis_value(1, 1.0-event.xevent.xmotion.y*2.0/window.get_height(), true);
+ break;
+ }
+#endif
}
} // namespace Input
class Mouse: public Device
{
private:
- Graphics::EventSource &source;
+ Graphics::Window &window;
public:
- Mouse(Graphics::EventSource &);
+ Mouse(Graphics::Window &);
virtual std::string get_button_name(unsigned) const;
virtual std::string get_axis_name(unsigned) const;
private:
- void button_press(int, int, unsigned, unsigned);
- void button_release(int, int, unsigned, unsigned);
- void pointer_motion(int, int);
+ void input_event(const Graphics::Window::Event &);
};
} // namespace Input