From 1fbd1b60d9fffe40febe499315347762da007269 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 25 Aug 2007 22:02:01 +0000 Subject: [PATCH] Initial revision --- Build | 18 +++++ source/glwindow.cpp | 89 ++++++++++++++++++++++++ source/glwindow.h | 45 +++++++++++++ source/inputdevice.cpp | 64 ++++++++++++++++++ source/inputdevice.h | 45 +++++++++++++ source/inputhub.h | 23 +++++++ source/keyboard.cpp | 32 +++++++++ source/keyboard.h | 31 +++++++++ source/mouse.cpp | 43 ++++++++++++ source/mouse.h | 36 ++++++++++ source/window.cpp | 149 +++++++++++++++++++++++++++++++++++++++++ source/window.h | 64 ++++++++++++++++++ 12 files changed, 639 insertions(+) create mode 100644 Build create mode 100644 source/glwindow.cpp create mode 100644 source/glwindow.h create mode 100644 source/inputdevice.cpp create mode 100644 source/inputdevice.h create mode 100644 source/inputhub.h create mode 100644 source/keyboard.cpp create mode 100644 source/keyboard.h create mode 100644 source/mouse.cpp create mode 100644 source/mouse.h create mode 100644 source/window.cpp create mode 100644 source/window.h diff --git a/Build b/Build new file mode 100644 index 0000000..612f9be --- /dev/null +++ b/Build @@ -0,0 +1,18 @@ +/* $Id$ */ + +package "mspgbase" +{ + description "Mikkosoft Productions graphics base library"; + version "0.0"; + + require "mspcore"; + require "sigc++-2.0"; + require "Xlib"; + + library "mspgbase" + { + source "source"; + install true; + install_headers "msp/gbase"; + }; +}; diff --git a/source/glwindow.cpp b/source/glwindow.cpp new file mode 100644 index 0000000..530d337 --- /dev/null +++ b/source/glwindow.cpp @@ -0,0 +1,89 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include +#include "glwindow.h" + +using namespace std; + +#include + +namespace Msp { + +GLDisplayOptions::GLDisplayOptions(): + alpha(false), + doublebuffer(true), + multisample(0) +{ } + + +GLWindow::GLWindow(unsigned w, unsigned h) +{ + options.width=w; + options.height=h; + init(); +} + +GLWindow::GLWindow(const DisplayOptions &dopt, const GLDisplayOptions &gl_dopt) +{ + options=dopt; + gl_options=gl_dopt; + init(); +} + +GLWindow::~GLWindow() +{ + glXMakeCurrent(display, window, 0); + glXDestroyContext(display, context); +} + +void GLWindow::swap_buffers() +{ + glXSwapBuffers(display, window); +} + +void GLWindow::init() +{ + prepare(); + + vector attribs; + attribs.push_back(GLX_RGBA); + attribs.push_back(GLX_BUFFER_SIZE); + attribs.push_back(24); + if(gl_options.alpha) + { + attribs.push_back(GLX_ALPHA_SIZE); + attribs.push_back(1); + } + if(gl_options.doublebuffer) + attribs.push_back(GLX_DOUBLEBUFFER); + if(gl_options.multisample>0) + { + attribs.push_back(GLX_SAMPLE_BUFFERS_ARB); + attribs.push_back(gl_options.multisample); + } + attribs.push_back(0); + + XVisualInfo *visual=glXChooseVisual(display, DefaultScreen(display), &attribs.front()); + if(!visual) + throw Exception("Couldn't get a matching GLX visual"); + + context=glXCreateContext(display, visual, 0, true); + if(!context) + throw Exception("Couldn't create a GLX context"); + + window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0); + if(!window) + throw Exception("Couldn't create a window"); + + XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask); + + glXMakeCurrent(display, window, context); +} + +} // namespace Msp diff --git a/source/glwindow.h b/source/glwindow.h new file mode 100644 index 0000000..f79c673 --- /dev/null +++ b/source/glwindow.h @@ -0,0 +1,45 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_GLWINDOW_H_ +#define MSP_GBASE_GLWINDOW_H_ + +#include +#include "window.h" + +namespace Msp { + +struct GLDisplayOptions +{ + bool alpha; + bool doublebuffer; + unsigned multisample; + + GLDisplayOptions(); +}; + +class GLWindow: public Window +{ +protected: + typedef GLXContext Context; + + GLDisplayOptions gl_options; + Context context; + +public: + GLWindow(unsigned, unsigned); + GLWindow(const DisplayOptions &, const GLDisplayOptions &); + ~GLWindow(); + + void swap_buffers(); +protected: + void init(); +}; + +} // namespace Msp + +#endif diff --git a/source/inputdevice.cpp b/source/inputdevice.cpp new file mode 100644 index 0000000..f0f9aac --- /dev/null +++ b/source/inputdevice.cpp @@ -0,0 +1,64 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "inputdevice.h" + +namespace Msp { +namespace Input { + +bool Device::get_button_state(unsigned btn) +{ + if(btn>buttons.size()) + return false; + + return buttons[btn]; +} + +float Device::get_axis_value(unsigned axis) +{ + if(axis>axes.size()) + return 0; + + return axes[axis]; +} + +void Device::set_button_state(unsigned btn, bool state, bool event) +{ + if(btn>=buttons.size()) + buttons.resize(btn+1, false); + + if(state!=buttons[btn]) + { + buttons[btn]=state; + + if(event) + { + if(state) + signal_button_press.emit(btn); + else + signal_button_release.emit(btn); + } + } +} + +void Device::set_axis_value(unsigned axis, float value, bool event) +{ + if(axis>=axes.size()) + axes.resize(axis+1, 0); + + if(value!=axes[axis]) + { + float old=axes[axis]; + axes[axis]=value; + + if(event) + signal_axis_motion.emit(axis, value, value-old); + } +} + +} // namespace Input +} // namespace Msp diff --git a/source/inputdevice.h b/source/inputdevice.h new file mode 100644 index 0000000..60b25e9 --- /dev/null +++ b/source/inputdevice.h @@ -0,0 +1,45 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_INPUTDEVICE_H_ +#define MSP_GBASE_INPUTDEVICE_H_ + +#include +#include + +namespace Msp { +namespace Input { + +/** +Base class for input devices. Input devices have two types of controls: +buttons and axes. Buttons are either on or off. Axes have a floating-point +value, with range depending on the device. +*/ +class Device +{ +public: + sigc::signal signal_button_press; + sigc::signal signal_button_release; + sigc::signal signal_axis_motion; + +protected: + std::vector buttons; + std::vector axes; + +public: + virtual ~Device() { } + bool get_button_state(unsigned); + float get_axis_value(unsigned); +protected: + void set_button_state(unsigned, bool, bool); + void set_axis_value(unsigned, float, bool); +}; + +} // namespace Input +} // namespace Msp + +#endif diff --git a/source/inputhub.h b/source/inputhub.h new file mode 100644 index 0000000..1d4b465 --- /dev/null +++ b/source/inputhub.h @@ -0,0 +1,23 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_INPUTHUB_H_ +#define MSP_GBASE_INPUTHUB_H_ + +#include "inputdevice.h" + +namespace Msp { +namespace Input { + +class Hub: public Device +{ +}; + +} // namespace Input +} // namespace Msp + +#endif diff --git a/source/keyboard.cpp b/source/keyboard.cpp new file mode 100644 index 0000000..4bc586c --- /dev/null +++ b/source/keyboard.cpp @@ -0,0 +1,32 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "keyboard.h" +#include "window.h" + +namespace Msp { +namespace Input { + +Keyboard::Keyboard(Window &window) +{ + buttons.resize(256, false); + + window.signal_key_press.connect(sigc::mem_fun(this, &Keyboard::key_press)); +} + +void Keyboard::key_press(unsigned key, unsigned, unsigned) +{ + set_button_state(key, true, true); +} + +void Keyboard::key_release(unsigned key, unsigned) +{ + set_button_state(key, false, true); +} + +} // namespace Input +} // namespace Msp diff --git a/source/keyboard.h b/source/keyboard.h new file mode 100644 index 0000000..65b3dba --- /dev/null +++ b/source/keyboard.h @@ -0,0 +1,31 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_KEYBOARD_H_ +#define MSP_GBASE_KEYBOARD_H_ + +#include "inputdevice.h" + +namespace Msp { + +class Window; + +namespace Input { + +class Keyboard: public Device +{ +public: + Keyboard(Window &); +protected: + void key_press(unsigned, unsigned, unsigned); + void key_release(unsigned, unsigned); +}; + +} // namespace Input +} // namespace Msp + +#endif diff --git a/source/mouse.cpp b/source/mouse.cpp new file mode 100644 index 0000000..b32b70f --- /dev/null +++ b/source/mouse.cpp @@ -0,0 +1,43 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "mouse.h" +#include "window.h" + +namespace Msp { +namespace Input { + +Mouse::Mouse(Window &w): + window(w), + axis_scale(0.01) +{ + buttons.resize(3); + axes.resize(2); + + window.signal_button_press.connect(sigc::mem_fun(this, &Mouse::button_press)); + window.signal_button_release.connect(sigc::mem_fun(this, &Mouse::button_release)); + window.signal_pointer_motion.connect(sigc::mem_fun(this, &Mouse::pointer_motion)); +} + +void Mouse::button_press(int, int, unsigned btn, unsigned) +{ + 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*axis_scale, true); + set_axis_value(1, y*axis_scale, true); +} + +} // namespace Input +} // namespace Msp diff --git a/source/mouse.h b/source/mouse.h new file mode 100644 index 0000000..6260f3b --- /dev/null +++ b/source/mouse.h @@ -0,0 +1,36 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_MOUSE_H_ +#define MSP_GBASE_MOUSE_H_ + +#include "inputdevice.h" + +namespace Msp { + +class Window; + +namespace Input { + +class Mouse: public Device +{ +private: + Window &window; + float axis_scale; + +public: + Mouse(Window &); +private: + void button_press(int, int, unsigned, unsigned); + void button_release(int, int, unsigned, unsigned); + void pointer_motion(int, int); +}; + +} // namespace Input +} // namespace Msp + +#endif diff --git a/source/window.cpp b/source/window.cpp new file mode 100644 index 0000000..75a88dc --- /dev/null +++ b/source/window.cpp @@ -0,0 +1,149 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include +#include +#include "window.h" + +using namespace std; + +#include + +namespace Msp { + +DisplayOptions::DisplayOptions(): + width(640), + height(480), + fullscreen(false) +{ } + + +/** +Initializes the class but does not open the window. Intended for use by +derived classes. +*/ +Window::Window(): + display(0), + window(0) +{ } + +Window::Window(unsigned w, unsigned h) +{ + options.width=w; + options.height=h; + + init(); +} + +Window::Window(const DisplayOptions &dopt): + options(dopt) +{ + init(); +} + +Window::~Window() +{ + if(window) + XDestroyWindow(display, window); + if(display) + XCloseDisplay(display); +} + +void Window::show() +{ + XMapRaised(display, window); +} + +void Window::hide() +{ + XUnmapWindow(display, window); +} + +void Window::tick() +{ + while(1) + { + int pending=XPending(display); + if(pending==0) + break; + + for(int i=0; i(&event.xkey), buf, sizeof(buf), 0, 0); + // XXX Handle the result according to locale + signal_key_press.emit(event.xkey.keycode, event.xkey.state, buf[0]); + } + break; + case KeyRelease: + signal_key_release.emit(event.xkey.keycode, event.xkey.state); + break; + case ConfigureNotify: + options.width=event.xconfigure.width; + options.height=event.xconfigure.height; + break; + default:; + } +} + +int Window::x_error_handler(Display *display, XErrorEvent *error) +{ + char buf[128]; + XGetErrorText(display, error->error_code, buf, sizeof(buf)); + /*string request_code=lexical_cast(error->request_code); + char buf2[1024]; + XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), buf, buf2, sizeof(buf2));*/ + throw Exception(buf); +} + +} // namespace Msp diff --git a/source/window.h b/source/window.h new file mode 100644 index 0000000..6f1f0d1 --- /dev/null +++ b/source/window.h @@ -0,0 +1,64 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_WINDOW_H_ +#define MSP_GBASE_WINDOW_H_ + +#include +#include +#include + +namespace Msp { + +struct DisplayOptions +{ + std::string display; + unsigned width; + unsigned height; + bool fullscreen; + + DisplayOptions(); +}; + +class Window +{ +public: + sigc::signal signal_button_press; + sigc::signal signal_button_release; + sigc::signal signal_pointer_motion; + sigc::signal signal_key_press; + sigc::signal signal_key_release; + +protected: + typedef ::Window Handle; + + Display *display; + DisplayOptions options; + Handle window; + + Window(); +public: + Window(unsigned, unsigned); + Window(const DisplayOptions &); + virtual ~Window(); + + unsigned get_width() const { return options.width; } + unsigned get_height() const { return options.height; } + void show(); + void hide(); + void tick(); +protected: + void prepare(); + void init(); + void process_event(const XEvent &); + + static int x_error_handler(Display *, XErrorEvent *); +}; + +} // namespace Msp + +#endif -- 2.43.0