/usr/share/openscenegraph/examples/osgviewerGTK/osggtkdrawingarea.h is in openscenegraph-examples 3.2.0~rc1-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | #include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
// This is an implementation of SimpleViewer that is designed to be subclassed
// and used as a GtkDrawingArea in a GTK application. Because of the implemention
// of GTK, I was unable to derive from GtkWidget and instead had to "wrap" it.
// Conceptually, however, you can think of an OSGGTKDrawingArea as both an OSG
// Viewer AND GtkDrawingArea.
//
// While it is possible to use this class directly, it won't end up doing anything
// interesting without calls to queueDraw, which ideally are done in the user's
// subclass implementation (see: osgviewerGTK).
class OSGGTKDrawingArea : public osgViewer::Viewer {
GtkWidget* _widget;
GdkGLConfig* _glconfig;
GdkGLContext* _context;
GdkGLDrawable* _drawable;
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
unsigned int _state;
osgGA::EventQueue& _queue;
static OSGGTKDrawingArea* _self(gpointer self) {
return static_cast<OSGGTKDrawingArea*>(self);
}
// A simple helper function to connect us to the various GTK signals.
void _connect(const char* name, GCallback callback) {
g_signal_connect(G_OBJECT(_widget), name, callback, this);
}
void _realize (GtkWidget*);
void _unrealize (GtkWidget*);
bool _expose_event (GtkWidget*, GdkEventExpose*);
bool _configure_event (GtkWidget*, GdkEventConfigure*);
bool _motion_notify_event (GtkWidget*, GdkEventMotion*);
bool _button_press_event (GtkWidget*, GdkEventButton*);
bool _key_press_event (GtkWidget*, GdkEventKey*);
// The following functions are static "wrappers" so that we can invoke the
// bound methods of a class instance by passing the "this" pointer as the
// self argument and invoking it explicitly.
static void _srealize(GtkWidget* widget, gpointer self) {
_self(self)->_realize(widget);
}
static void _sunrealize(GtkWidget* widget, gpointer self) {
_self(self)->_unrealize(widget);
}
static bool _sexpose_event(GtkWidget* widget, GdkEventExpose* expose, gpointer self) {
return _self(self)->_expose_event(widget, expose);
}
static bool _sconfigure_event(
GtkWidget* widget,
GdkEventConfigure* event,
gpointer self
) {
return _self(self)->_configure_event(widget, event);
}
static bool _smotion_notify_event(
GtkWidget* widget,
GdkEventMotion* event,
gpointer self
) {
return _self(self)->_motion_notify_event(widget, event);
}
static bool _sbutton_press_event(
GtkWidget* widget,
GdkEventButton* event,
gpointer self
) {
return _self(self)->_button_press_event(widget, event);
}
static bool _skey_press_event(
GtkWidget* widget,
GdkEventKey* event,
gpointer self
) {
return _self(self)->_key_press_event(widget, event);
}
protected:
// You can override these in your subclass if you'd like. :)
// Right now they're fairly uninformative, but they could be easily extended.
// Note that the "state" information isn't passed around to each function
// but is instead stored and abstracted internally. See below.
virtual void gtkRealize () {};
virtual void gtkUnrealize () {};
virtual bool gtkExpose () {
return true;
};
// The new width and height.
virtual bool gtkConfigure(int, int) {
return true;
};
// The "normalized" coordinates of the mouse.
virtual bool gtkMotionNotify(double, double) {
return true;
};
// The "normalized" coordinates of the mouse and the mouse button code on down.
virtual bool gtkButtonPress(double, double, unsigned int) {
return true;
};
// The "normalized" coordinates of the mouse and mouse button code on release.
virtual bool gtkButtonRelease(double, double, unsigned int) {
return true;
}
// The X key value on down.
virtual bool gtkKeyPress(unsigned int) {
return true;
};
// The X key value on release.
virtual bool gtkKeyRelease(unsigned int) {
return true;
};
// These functions wrap state tests of the most recent state in the
// GtkDrawingArea.
inline bool stateShift() {
return _state & GDK_SHIFT_MASK;
}
inline bool stateLock() {
return _state & GDK_LOCK_MASK;
}
inline bool stateControl() {
return _state & GDK_CONTROL_MASK;
}
inline bool stateMod() {
return _state & (
GDK_MOD1_MASK |
GDK_MOD2_MASK |
GDK_MOD3_MASK |
GDK_MOD4_MASK |
GDK_MOD5_MASK
);
}
inline bool stateButton() {
return _state & (
GDK_BUTTON1_MASK |
GDK_BUTTON2_MASK |
GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK |
GDK_BUTTON5_MASK
);
}
public:
OSGGTKDrawingArea ();
~OSGGTKDrawingArea ();
bool createWidget(int, int);
GtkWidget* getWidget() {
return _widget;
}
bool gtkGLBegin() {
if(_drawable and _context) return gdk_gl_drawable_gl_begin(_drawable, _context);
else return false;
}
void gtkGLEnd() {
if(_drawable) gdk_gl_drawable_gl_end(_drawable);
}
// Because of GTK's internal double buffering, I'm not sure if we're really
// taking advantage of OpenGL's internal swapping.
bool gtkGLSwap() {
if(_drawable and gdk_gl_drawable_is_double_buffered(_drawable)) {
gdk_gl_drawable_swap_buffers(_drawable);
return true;
}
else {
glFlush();
return false;
}
}
void queueDraw() {
gtk_widget_queue_draw(_widget);
}
};
|