Warning, /include/Geant4/toolx/Xt/sg_viewer is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef toolx_Xt_sg_viewer
0005 #define toolx_Xt_sg_viewer
0006
0007 #include "session"
0008
0009 #ifndef GL_GLEXT_LEGACY
0010 #define GL_GLEXT_LEGACY
0011 #endif
0012 #include <GL/gl.h>
0013
0014 #ifdef TOOLS_USE_GL_VERSION_3_2
0015 #ifndef GL_GLEXT_PROTOTYPES
0016 #define GL_GLEXT_PROTOTYPES
0017 #endif
0018 #include <GL/glext.h>
0019 #endif
0020
0021 #include "../GL/gl_functions"
0022
0023 #include "../sg/GL_action"
0024 #include "../sg/GL_viewer"
0025
0026 namespace toolx {
0027 namespace sg {
0028 using GL_action = GL_action_T<GL::gl_functions>;
0029 using GL_manager = GL_manager_T<GL::gl_functions>;
0030 using GL_viewer = GL_viewer_T<GL_manager,GL_action>;
0031 }}
0032
0033 #include "OpenGLArea"
0034
0035 #include <X11/Shell.h>
0036 #include <X11/StringDefs.h>
0037 #include <X11/IntrinsicP.h>
0038
0039 #include <tools/num2s>
0040 #include <tools/sg/device_interactor>
0041 #include <tools/sg/keys>
0042
0043 namespace toolx {
0044 namespace Xt {
0045
0046 class sg_viewer : public sg::GL_viewer {
0047 typedef sg::GL_viewer parent;
0048 public:
0049 sg_viewer(session& a_session,
0050 int a_x = 0,int a_y = 0,
0051 unsigned int a_width = 500,unsigned int a_height = 500,
0052 const std::string& a_win_title = "")
0053 :parent(a_session.out(),a_width,a_height)
0054 ,m_session(a_session)
0055 ,m_shell(0)
0056 ,m_glarea(0)
0057 ,m_interactor(0)
0058 {
0059 Widget app_widget = a_session.get_app_widget();
0060 if(!app_widget) return;
0061
0062 std::string sgeom;
0063 tools::numas(a_width,sgeom);
0064 sgeom += "x";
0065 tools::numas(a_height,sgeom);
0066 sgeom += "+";
0067 tools::numas(a_x,sgeom);
0068 sgeom += "+";
0069 tools::numas(a_y,sgeom);
0070
0071 Arg args[2];
0072 XtSetArg(args[0],XtNgeometry,XtNewString(sgeom.c_str()));
0073 XtSetArg(args[1],XtNborderWidth,0);
0074
0075 m_shell = ::XtAppCreateShell((char*)a_win_title.c_str(),
0076 (char*)"sg_viewer_shell",
0077 topLevelShellWidgetClass,XtDisplay(app_widget),args,2);
0078 ::XtSetMappedWhenManaged(m_shell,True);
0079
0080 m_glarea = ::XtCreateManagedWidget("glarea",OpenGLArea::widget_class(),m_shell,args,0);
0081 ::XtAddCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
0082 ::XtAddCallback(m_glarea,XoNeventCallback,event_cbk,(XtPointer)this);
0083
0084 ::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0085
0086 ::XtRealizeWidget(m_shell);
0087 }
0088 virtual ~sg_viewer() {
0089 if(m_shell) {
0090 ::XtRemoveCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
0091 ::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0092 ::XtDestroyWidget(m_shell);
0093 }
0094 m_shell = 0;
0095 m_glarea = 0;
0096 }
0097 protected:
0098 sg_viewer(const sg_viewer& a_from)
0099 :parent(a_from)
0100 ,m_session(a_from.m_session)
0101 ,m_shell(0)
0102 ,m_glarea(0)
0103 ,m_interactor(0)
0104 {}
0105 sg_viewer& operator=(const sg_viewer& a_from){
0106 parent::operator=(a_from);
0107 return *this;
0108 }
0109 public:
0110 bool has_window() const {return m_glarea?true:false;}
0111
0112 bool show() {
0113 if(!m_shell) return false;
0114 ::XtRealizeWidget(m_shell);
0115 ::XtMapWidget(m_shell);
0116 // Raise window :
0117 if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) {
0118 Display* display = XtDisplay(m_shell);
0119 Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False);
0120 ::XSetWMProtocols(display,XtWindow(m_shell),&atom,1);
0121 ::XRaiseWindow(display,XtWindow(m_shell));
0122 }
0123 return true;
0124 }
0125
0126 void win_render() {
0127 if(!m_glarea) return;
0128 OpenGLArea::paint(m_glarea);
0129 m_session.sync();
0130 }
0131
0132 void emit_win_render() {
0133 if(!m_glarea) return;
0134 if(!post_expose(m_glarea)) {}
0135 }
0136
0137 bool window_size(unsigned int& a_w,unsigned int& a_h) {
0138 if(!m_glarea) {a_w = 0;a_h = 0;return false;}
0139 a_w = (unsigned int)m_glarea->core.width;
0140 a_h = (unsigned int)m_glarea->core.height;
0141 return true;
0142 }
0143 void render_area_size(unsigned int& a_w,unsigned int& a_h) {
0144 a_w = parent::width();
0145 a_h = parent::height();
0146 }
0147
0148 public:
0149 void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
0150 protected:
0151 static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
0152 unsigned int width = a_widget->core.width;
0153 unsigned int height = a_widget->core.height;
0154 sg_viewer* _this = (sg_viewer*)a_tag;
0155 _this->set_size(width,height);
0156 _this->render();
0157 }
0158 static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){
0159 sg_viewer* _this = (sg_viewer*)a_tag;
0160 if(!_this->m_interactor) return;
0161 XoAnyCallbackStruct* data = (XoAnyCallbackStruct*)a_data;
0162 XEvent* xevent = data->event;
0163 switch( xevent->type ) {
0164 case KeyPress:{
0165 KeySym key_sym;
0166 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0167 tools::sg::key_down_event event(_this->convert(key_sym));
0168 _this->m_interactor->key_press(event);
0169 }return;
0170 case KeyRelease:{
0171 KeySym key_sym;
0172 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0173 tools::sg::key_up_event event(_this->convert(key_sym));
0174 _this->m_interactor->key_release(event);
0175 }return;
0176 case ButtonPress:{
0177 bool shift_modifier = xevent->xkey.state & ShiftMask;
0178 bool control_modifier = xevent->xkey.state & ControlMask;
0179 if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
0180 tools::sg::wheel_rotate_event event(8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
0181 _this->m_interactor->wheel_rotate(event);
0182 } else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
0183 tools::sg::wheel_rotate_event event(-8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
0184 _this->m_interactor->wheel_rotate(event);
0185 } else if(xevent->xbutton.button==Button1) {
0186 tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
0187 _this->m_interactor->mouse_press(event);
0188 }
0189 }return;
0190 case ButtonRelease:{
0191 if(xevent->xbutton.button==Button1) {
0192 bool shift_modifier = xevent->xkey.state & ShiftMask;
0193 bool control_modifier = xevent->xkey.state & ControlMask;
0194 tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
0195 _this->m_interactor->mouse_release(event);
0196 }
0197 }return;
0198 case MotionNotify:{
0199 if((xevent->xmotion.state & Button1MotionMask)==Button1MotionMask) {
0200 bool shift_modifier = xevent->xkey.state & ShiftMask;
0201 bool control_modifier = xevent->xkey.state & ControlMask;
0202 tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,shift_modifier,control_modifier,0,0,false);
0203 _this->m_interactor->mouse_move(event);
0204 }
0205 }return;
0206 default:return;}
0207 }
0208 static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) {
0209 sg_viewer* _this = (sg_viewer*)a_tag;
0210 _this->m_shell = 0;
0211 _this->m_glarea = 0;
0212 }
0213 protected:
0214 tools::key_code convert(KeySym a_key) {
0215 if(a_key==XK_Shift_L) return tools::sg::key_shift();
0216 if(a_key==XK_Shift_R) return tools::sg::key_shift();
0217 return (tools::key_code)a_key;
0218 }
0219 protected:
0220 session& m_session;
0221 Widget m_shell;
0222 Widget m_glarea;
0223 tools::sg::device_interactor* m_interactor;
0224 };
0225
0226 }}
0227
0228 #endif