libcvd-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcvd-members] libcvd Makefile.in cvd/glwindow.h cvd_src/glwin...


From: Ethan Eade
Subject: [libcvd-members] libcvd Makefile.in cvd/glwindow.h cvd_src/glwin...
Date: Fri, 02 Mar 2007 15:31:19 +0000

CVSROOT:        /cvsroot/libcvd
Module name:    libcvd
Changes by:     Ethan Eade <ethaneade>  07/03/02 15:31:19

Modified files:
        .              : Makefile.in 
Added files:
        cvd            : glwindow.h 
        cvd_src        : glwindow.cc 

Log message:
        Added GLWindow.  This is a richer implementation of VideoDisplay that 
hides
        the XEvent system from the user.  
        
        The GLWindow class makes a window and an associated GL context.  When
        requested, events on the queue are either processed with a passed event
        handler (with callback virtual methods such as on_key_down and 
on_resize) 
        or enumerated in a vector<GLWindow::Event> or GLWindow::EventSummary.
        
        Otherwise the functionality is the same as VideoDisplay.
        
        Feel free to add to the interface; I just got tired of linking against a
        separate library in order to have a reasonable display interface.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/glwindow.h?cvsroot=libcvd&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd_src/glwindow.cc?cvsroot=libcvd&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libcvd/Makefile.in?cvsroot=libcvd&r1=1.51&r2=1.52

Patches:
Index: Makefile.in
===================================================================
RCS file: /cvsroot/libcvd/libcvd/Makefile.in,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -b -r1.51 -r1.52
--- Makefile.in 20 Jan 2007 15:42:21 -0000      1.51
+++ Makefile.in 2 Mar 2007 15:31:19 -0000       1.52
@@ -150,6 +150,7 @@
 
 ifeq (@have_videodisplay@,yes)
        CVD_OBJS+=cvd_src/videodisplay.o
+       CVD_OBJS+=cvd_src/glwindow.o
 endif
 
 
################################################################################

Index: cvd/glwindow.h
===================================================================
RCS file: cvd/glwindow.h
diff -N cvd/glwindow.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ cvd/glwindow.h      2 Mar 2007 15:31:19 -0000       1.1
@@ -0,0 +1,128 @@
+#ifndef GLWINDOW_H
+#define GLWINDOW_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cvd/image_ref.h>
+
+namespace CVD {
+    
+    namespace Exceptions
+    {
+       /// %Exceptions specific to CVD::GLWindow
+       /// @ingroup gException
+       namespace GLWindow
+       {
+           /// Base class for all CVD::GLWindow exceptions
+           /// @ingroup gException
+           struct All: public CVD::Exceptions::All{
+           };
+           
+           /// An exception occurred during initialisation
+           /// @ingroup gException
+           struct CreationError: public All
+           {
+               CreationError(std::string w); ///< Construct from error string
+           };
+           
+           /// An exception occurred during run-time
+           /// @ingroup gException
+           struct RuntimeError: public All
+           {
+               RuntimeError(std::string w); ///< Construct from error string
+           };
+       }
+    }
+    
+    /// An object that creates a window and a GL context attached to that 
window, and manages its events.
+    class GLWindow {
+    public:
+       /// Symbols for mouse buttons and modifiers
+       enum MouseButton { BUTTON_LEFT=1, BUTTON_MIDDLE=2, BUTTON_RIGHT=4, 
BUTTON_MOD_CTRL=8, BUTTON_MOD_SHIFT=0x10 };
+       /// Symbols for window events
+       enum EventType { EVENT_CLOSE };
+
+       /// Abstract base class for event handlers.  Subclass this and override 
to implement a handler.
+       class EventHandler {
+       public:
+           virtual ~EventHandler() {}
+           /// Called for key press events
+           virtual void on_key_down(GLWindow& win, int key) {}
+           /// Called for key release events
+           virtual void on_key_up(GLWindow& win, int key) {}
+           /// Called for mouse movement events
+           virtual void on_mouse_move(GLWindow& win, ImageRef where, int 
state) {}
+           /// Called for mouse button press events
+           virtual void on_mouse_down(GLWindow& win, ImageRef where, int 
state, int button) {}
+           /// Called for mouse button release events
+           virtual void on_mouse_up(GLWindow& win, ImageRef where, int state, 
int button) {}
+           /// Called for window resize events
+           virtual void on_resize(GLWindow& win, ImageRef size) {}
+           /// Called for general window events (such as EVENT_CLOSE)
+           virtual void on_event(GLWindow& win, int event) {}
+       };
+
+       struct Event {
+           enum Type { KEY_DOWN, KEY_UP, MOUSE_MOVE, MOUSE_DOWN, MOUSE_UP, 
RESIZE, EVENT };
+           Type type;
+           int which, state;
+           ImageRef where, size;
+       };
+
+       /// A summary of multiple events
+       struct EventSummary {
+           /// key->frequency mapping for key presses and releases
+           std::map<int,int> key_down, key_up;
+           /// button->frequency mapping for mouse presses and releases
+           std::map<int,std::pair<ImageRef,int> > mouse_down, mouse_up;
+           /// Generic window events -> frequency
+           std::map<int,int> events;
+           /// Reset the summary
+           void clear() { *this = EventSummary(); }
+           /// Has escape been pressed or the close button pressed?
+           bool should_quit() const;
+       };
+
+       /// Construct a GLWindow of the given size and colour depth, with the 
given title.
+       /// A double-buffered GL context is associated with the window.
+       GLWindow(const ImageRef& size, int bpp, const std::string& 
title="GLWindow");
+       ~GLWindow();
+       /// Get the size
+       ImageRef size() const;
+       /// Set the mouse cursor position
+       void set_cursor_position(const ImageRef& where);
+       /// Get the mouse cursor position
+       ImageRef cursor_position() const;
+       /// Show (or hide) the cursor
+       void show_cursor(bool show=true);
+       /// Hide the cursor
+       void hide_cursor() { show_cursor(false); }
+       /// Get the title
+       std::string title() const;
+       /// Set the title
+       void set_title(const std::string& title);
+       /// Swap the front and back buffers
+       void swap_buffers();
+       /// Handle events in the event queue by calling back to the specified 
handler.
+       void handle_events(EventHandler& handler);
+       /// Store all events in the event queue into Event objects.
+       void get_events(std::vector<Event>& events);
+       /// Make a summary of the events in the queue.
+       void get_events(EventSummary& summary);
+       /// @returns true if events are pending
+       bool has_events() const;
+       /// Make this GL context active
+       void activate();
+       /// Make this GL context active
+       void make_current() { activate(); }
+    private:
+       struct State;
+       State* state;
+    };
+
+    
+}
+
+
+#endif

Index: cvd_src/glwindow.cc
===================================================================
RCS file: cvd_src/glwindow.cc
diff -N cvd_src/glwindow.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ cvd_src/glwindow.cc 2 Mar 2007 15:31:19 -0000       1.1
@@ -0,0 +1,340 @@
+#include <cvd/glwindow.h>
+#include <exception>
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <GL/glx.h>
+
+using namespace CVD;
+
+CVD::Exceptions::GLWindow::CreationError::CreationError(std::string w)
+{
+    what="GLWindow creation error: " + w;
+}
+
+CVD::Exceptions::GLWindow::RuntimeError::RuntimeError(std::string w)
+{
+    what="GLWindow error: " + w;
+}
+    
+struct GLWindow::State {
+    ImageRef size;
+    std::string title;
+    Display* display;
+    Window window;
+    Atom delete_atom;
+    Cursor null_cursor;
+    GLXContext context;
+    int font;  
+};
+    
+CVD::GLWindow::GLWindow(const ImageRef& size, int bpp, const std::string& 
title)
+{
+    Display* display = XOpenDisplay(0);
+    if (display == 0)
+       throw Exceptions::GLWindow::CreationError("Cannot open X display");
+
+    int visualAttributes[] = {
+       GLX_RGBA,
+       GLX_DOUBLEBUFFER,
+       GLX_RED_SIZE,      bpp/3, 
+       GLX_GREEN_SIZE,    bpp/3, 
+       GLX_BLUE_SIZE,     bpp/3, 
+       GLX_DEPTH_SIZE,    8,
+       None
+    };
+    XVisualInfo* visualInfo = glXChooseVisual(display, 
DefaultScreen(display),visualAttributes);
+    if(visualAttributes == 0) {
+       XCloseDisplay(display);
+       throw Exceptions::GLWindow::CreationError("glXChooseVisual failed");
+    }
+
+    Window rootWindow = RootWindow(display, visualInfo->screen);
+    XWindowAttributes windowAttributes;
+       
+    XGetWindowAttributes(display, rootWindow, &windowAttributes);
+
+    XSetWindowAttributes attributes;
+    attributes.border_pixel = 0;
+    attributes.colormap = XCreateColormap(display, rootWindow, 
visualInfo->visual, AllocNone);
+    attributes.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | 
ButtonReleaseMask | PointerMotionMask | StructureNotifyMask;
+       
+    Window window = XCreateWindow(display, 
+                                 rootWindow, 
+                                 0, 0, size.x, size.y, 
+                                 0, visualInfo->depth, 
+                                 InputOutput, 
+                                 visualInfo->visual, 
+                                 CWBorderPixel | CWColormap | CWEventMask,
+                                 &attributes);
+    XStoreName(display, window, title.c_str());
+    XMapWindow(display, window);
+    XEvent ev;
+    do {       
+        XNextEvent(display,&ev);
+    } while (ev.type != MapNotify);
+   
+    Atom delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", True);
+    XSetWMProtocols(display, window, &delete_atom, 1);
+
+    GLXContext context = glXCreateContext(display, visualInfo, 0, True);
+    if (context == 0) {
+       XDestroyWindow(display, window);
+       XCloseDisplay(display);
+       throw Exceptions::GLWindow::CreationError("glXCreateContext failed");
+    }
+
+    if (glXMakeCurrent(display, window, context) == False) {
+       glXDestroyContext(display, context);
+       XDestroyWindow(display, window);
+       XCloseDisplay(display);
+       throw Exceptions::GLWindow::CreationError("glXMakeCurrent failed");
+    }
+    glLoadIdentity();
+    glViewport(0, 0, size.x, size.y);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glColor3f(1.0f,1.0f,1.0f);
+    glRasterPos2f(-1, 1);
+    glOrtho(0, size.x, size.y, 0, -1 , 1);
+    glPixelZoom(1,-1);
+
+    int font = glGenLists(256);
+    XColor black = {0, 0, 0, 0, 0, 0};
+    XFontStruct* fixed = XLoadQueryFont(display, 
"-misc-fixed-medium-r-*-*-12-*-*-*-*-*-*-1" );
+    Cursor null_cursor = XCreateGlyphCursor(display, fixed->fid, fixed->fid, ' 
', ' ', &black, &black);
+    glXUseXFont(fixed->fid, 0, 256, font);
+    XFreeFont(display, fixed);
+
+    state = new State();
+    state->size = size;
+    state->title = title;
+    state->display = display;
+    state->window = window;
+    state->delete_atom = delete_atom;
+    state->null_cursor = null_cursor;
+    state->context = context;
+    state->font = font;
+}
+
+CVD::GLWindow::~GLWindow()
+{
+    activate();
+    glDeleteLists(state->font,256);
+    glXDestroyContext(state->display, state->context);
+    XDestroyWindow(state->display, state->window);
+    XCloseDisplay(state->display);
+
+    delete state;
+}
+
+ImageRef CVD::GLWindow::size() const { return state->size; }
+
+void CVD::GLWindow::set_cursor_position(const ImageRef& where)
+{
+    XWarpPointer(state->display, None, state->window, 0, 0, 0, 0, where.x, 
where.y);
+}
+
+ImageRef CVD::GLWindow::cursor_position() const 
+{
+    Window wtmp;
+    int itmp; 
+    unsigned int utmp;
+    ImageRef where;
+    XQueryPointer(state->display, state->window, &wtmp, &wtmp, &itmp, &itmp, 
&where.x, &where.y, &utmp);
+    return where;
+}
+
+void CVD::GLWindow::show_cursor(bool show)
+{
+    if (show)
+       XUndefineCursor(state->display, state->window);
+    else
+       XDefineCursor(state->display, state->window, state->null_cursor);
+}
+
+std::string CVD::GLWindow::title() const
+{
+    return state->title;
+}
+
+void CVD::GLWindow::set_title(const std::string& title)
+{
+    state->title = title;
+    XStoreName(state->display, state->window, title.c_str());
+}
+
+void CVD::GLWindow::swap_buffers()
+{
+    glXSwapBuffers(state->display, state->window);
+}
+
+inline int convertButton(unsigned int button)
+{
+  switch (button) {
+  case Button1: return GLWindow::BUTTON_LEFT;
+  case Button2: return GLWindow::BUTTON_MIDDLE;
+  case Button3: return GLWindow::BUTTON_RIGHT;
+  }
+  return 0;
+}
+
+inline int convertButtonState(unsigned int state)
+{
+  int ret = 0;
+  if (state & Button1Mask) ret |= GLWindow::BUTTON_LEFT;
+  if (state & Button2Mask) ret |= GLWindow::BUTTON_MIDDLE;
+  if (state & Button3Mask) ret |= GLWindow::BUTTON_RIGHT;
+  if (state & ControlMask) ret |= GLWindow::BUTTON_MOD_CTRL;
+  if (state & ShiftMask) ret |= GLWindow::BUTTON_MOD_SHIFT;
+  return ret;
+}
+
+void CVD::GLWindow::handle_events(EventHandler& handler)
+{
+    XEvent event;
+    while (XPending(state->display)) {
+       XNextEvent(state->display, &event);
+       switch (event.type) {
+       case ButtonPress:
+           handler.on_mouse_down(*this, ImageRef(event.xbutton.x, 
event.xbutton.y), 
+                                 convertButtonState(event.xbutton.state), 
convertButton(event.xbutton.button));
+           break;
+       case ButtonRelease:
+           handler.on_mouse_up(*this, ImageRef(event.xbutton.x, 
event.xbutton.y), 
+                               convertButtonState(event.xbutton.state), 
convertButton(event.xbutton.button));
+           break;
+       case MotionNotify:
+           handler.on_mouse_move(*this, ImageRef(event.xmotion.x, 
event.xmotion.y), convertButtonState(event.xbutton.state));
+           break;
+       case KeyPress:
+           handler.on_key_down(*this, XLookupKeysym(&event.xkey, 0));
+           break;
+       case KeyRelease:
+           handler.on_key_up(*this, XLookupKeysym(&event.xkey, 0));
+           break;
+           //case UnmapNotify: active = 0; break;
+           //case MapNotify: active = 1; break;
+       case ConfigureNotify:
+           if (event.xconfigure.width != state->size.x || 
event.xconfigure.height != state->size.y) {
+               activate();
+               state->size = ImageRef(event.xconfigure.width & (~0x3), 
event.xconfigure.height & (~0x3));
+               glViewport(0, 0, state->size.x, state->size.y);
+               //glRasterPos2f(0,0);
+               
//glPixelZoom(float(event.xconfigure.width)/myWidth,-float(event.xconfigure.height)/myHeight);
+               handler.on_resize(*this, state->size);
+           }
+           break;
+       case ClientMessage:    
+           if (event.xclient.data.l[0] == (int)state->delete_atom)
+               handler.on_event(*this, EVENT_CLOSE);
+           else
+               handler.on_event(*this, event.xclient.message_type);
+           break;
+       default:
+           handler.on_event(*this, event.type);
+           break;
+       }
+    }
+}
+
+class SaveEvents : public GLWindow::EventHandler {
+private:
+    std::vector<GLWindow::Event>& events;
+public:
+    SaveEvents(std::vector<GLWindow::Event>& events_) : events(events_) {}
+    void on_key_down(GLWindow& win, int key) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::KEY_DOWN;
+       e.which = key;
+       events.push_back(e);
+    }
+    void on_key_up(GLWindow& win, int key) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::KEY_UP;
+       e.which = key;
+       events.push_back(e);
+    }
+
+    void on_mouse_move(GLWindow& win, ImageRef where, int state) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::MOUSE_MOVE;
+       e.state = state;
+       e.where = where;
+       events.push_back(e);
+    }
+
+    void on_mouse_down(GLWindow& win, ImageRef where, int state, int button) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::MOUSE_DOWN;
+       e.state = state;
+       e.which = button;
+       e.where = where;
+       events.push_back(e);
+    }
+
+    void on_mouse_up(GLWindow& win, ImageRef where, int state, int button) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::MOUSE_UP;
+       e.state = state;
+       e.which = button;
+       e.where = where;
+       events.push_back(e);
+    }
+
+    void on_resize(GLWindow& win, ImageRef size) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::RESIZE;
+       e.size = size;
+       events.push_back(e);
+    }
+    
+    void on_event(GLWindow& win, int event) {
+       GLWindow::Event e;
+       e.type = GLWindow::Event::EVENT;
+       e.which = event;
+       events.push_back(e);
+    }
+};
+
+void CVD::GLWindow::get_events(std::vector<Event>& events)
+{
+    SaveEvents saver(events);
+    handle_events(saver);
+}
+
+bool CVD::GLWindow::EventSummary::should_quit() const 
+{
+    return key_down.count(XK_Escape) || events.count(GLWindow::EVENT_CLOSE);
+}
+
+class MakeSummary : public GLWindow::EventHandler {
+private:
+    GLWindow::EventSummary& summary;
+public:
+    MakeSummary(GLWindow::EventSummary& summary_) : summary(summary_) {}
+
+    void on_key_down(GLWindow& win, int key) { ++summary.key_down[key]; }
+    void on_key_up(GLWindow& win, int key) { ++summary.key_up[key]; }
+    void on_mouse_down(GLWindow& win, ImageRef where, int state, int button) { 
summary.mouse_down[button] = std::make_pair(where,state); }
+    void on_mouse_up(GLWindow& win, ImageRef where, int state, int button) { 
summary.mouse_up[button] = std::make_pair(where,state); }
+    void on_event(GLWindow& win, int event) { ++summary.events[event]; }
+};
+
+void GLWindow::get_events(EventSummary& summary)
+{
+    MakeSummary ms(summary);
+    handle_events(ms);
+}
+
+bool CVD::GLWindow::has_events() const
+{
+    return XPending(state->display);
+}
+
+void CVD::GLWindow::activate()
+{
+    if (glXMakeCurrent(state->display, state->window, state->context) == False)
+       throw Exceptions::GLWindow::RuntimeError("glXMakeCurrent failed");
+}
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]