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 #include "../sg/GL_viewer"
0010
0011 #include "OpenGLArea"
0012
0013 #include <X11/Shell.h>
0014 #include <X11/StringDefs.h>
0015 #include <X11/IntrinsicP.h>
0016
0017 #include <tools/num2s>
0018 #include <tools/sg/device_interactor>
0019 #include <tools/sg/keys>
0020
0021 namespace toolx {
0022 namespace Xt {
0023
0024 class sg_viewer : public sg::GL_viewer {
0025 typedef sg::GL_viewer parent;
0026 public:
0027 sg_viewer(session& a_session,
0028 int a_x = 0,int a_y = 0,
0029 unsigned int a_width = 500,unsigned int a_height = 500,
0030 const std::string& a_win_title = "")
0031 :parent(a_session.out(),a_width,a_height)
0032 ,m_session(a_session)
0033 ,m_shell(0)
0034 ,m_glarea(0)
0035 ,m_interactor(0)
0036 {
0037 Widget app_widget = a_session.get_app_widget();
0038 if(!app_widget) return;
0039
0040 std::string sgeom;
0041 tools::numas(a_width,sgeom);
0042 sgeom += "x";
0043 tools::numas(a_height,sgeom);
0044 sgeom += "+";
0045 tools::numas(a_x,sgeom);
0046 sgeom += "+";
0047 tools::numas(a_y,sgeom);
0048
0049 Arg args[2];
0050 XtSetArg(args[0],XtNgeometry,XtNewString(sgeom.c_str()));
0051 XtSetArg(args[1],XtNborderWidth,0);
0052
0053 m_shell = ::XtAppCreateShell((char*)a_win_title.c_str(),
0054 (char*)"sg_viewer_shell",
0055 topLevelShellWidgetClass,XtDisplay(app_widget),args,2);
0056 ::XtSetMappedWhenManaged(m_shell,True);
0057
0058 m_glarea = ::XtCreateManagedWidget("glarea",OpenGLArea::widget_class(),m_shell,args,0);
0059 ::XtAddCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
0060 ::XtAddCallback(m_glarea,XoNeventCallback,event_cbk,(XtPointer)this);
0061
0062 ::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0063
0064 ::XtRealizeWidget(m_shell);
0065
0066 //Atom WM_DELETE_WINDOW_atom = ::XInternAtom(XtDisplay(m_shell),"WM_DELETE_WINDOW",False);
0067 //::XSetWMProtocols(XtDisplay(m_shell),XtWindow(m_shell),&WM_DELETE_WINDOW_atom,1);
0068 }
0069 virtual ~sg_viewer() {
0070 if(m_shell) {
0071 ::XtRemoveCallback(m_glarea,XoNpaintCallback,paint_cbk,(XtPointer)this);
0072 ::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0073 ::XtDestroyWidget(m_shell);
0074 }
0075 m_shell = 0;
0076 m_glarea = 0;
0077 }
0078 protected:
0079 sg_viewer(const sg_viewer& a_from)
0080 :parent(a_from)
0081 ,m_session(a_from.m_session)
0082 ,m_shell(0)
0083 ,m_glarea(0)
0084 ,m_interactor(0)
0085 {}
0086 sg_viewer& operator=(const sg_viewer& a_from){
0087 parent::operator=(a_from);
0088 return *this;
0089 }
0090 public:
0091 bool has_window() const {return m_glarea?true:false;}
0092
0093 bool show() {
0094 if(!m_shell) return false;
0095 ::XtRealizeWidget(m_shell);
0096 ::XtMapWidget(m_shell);
0097 // Raise window :
0098 if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) {
0099 Display* display = XtDisplay(m_shell);
0100 Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False);
0101 ::XSetWMProtocols(display,XtWindow(m_shell),&atom,1);
0102 ::XRaiseWindow(display,XtWindow(m_shell));
0103 }
0104 return true;
0105 }
0106
0107 void win_render() {
0108 if(m_glarea) OpenGLArea::paint(m_glarea);
0109 }
0110
0111 public:
0112 void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
0113 protected:
0114 static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
0115 unsigned int width = a_widget->core.width;
0116 unsigned int height = a_widget->core.height;
0117 //::printf("debug : toolx::Xt::sg_viewer::paint_cbk : %d %d\n",width,height);
0118 sg_viewer* _this = (sg_viewer*)a_tag;
0119 _this->set_size(width,height);
0120 _this->render();
0121 }
0122 static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){
0123 sg_viewer* _this = (sg_viewer*)a_tag;
0124 if(!_this->m_interactor) return;
0125 XoAnyCallbackStruct* data = (XoAnyCallbackStruct*)a_data;
0126 XEvent* xevent = data->event;
0127 switch( xevent->type ) {
0128 case KeyPress:{
0129 KeySym key_sym;
0130 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0131 tools::sg::key_down_event event(_this->convert(key_sym));
0132 _this->m_interactor->key_press(event);
0133 }return;
0134 case KeyRelease:{
0135 KeySym key_sym;
0136 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0137 tools::sg::key_up_event event(_this->convert(key_sym));
0138 _this->m_interactor->key_release(event);
0139 }return;
0140 case ButtonPress:{
0141 if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
0142 tools::sg::wheel_rotate_event event(8); //8=cooking.
0143 _this->m_interactor->wheel_rotate(event);
0144 } else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
0145 tools::sg::wheel_rotate_event event(-8); //8=cooking.
0146 _this->m_interactor->wheel_rotate(event);
0147 } else {
0148 tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y);
0149 _this->m_interactor->mouse_press(event);
0150 }
0151 }return;
0152 case ButtonRelease:{
0153 tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y);
0154 _this->m_interactor->mouse_release(event);
0155 }return;
0156 case MotionNotify:{
0157 tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false);
0158 _this->m_interactor->mouse_move(event);
0159 }return;
0160 default:return;}
0161 }
0162 static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) {
0163 sg_viewer* _this = (sg_viewer*)a_tag;
0164 _this->m_shell = 0;
0165 _this->m_glarea = 0;
0166 }
0167 protected:
0168 tools::key_code convert(KeySym a_key) {
0169 if(a_key==XK_Shift_L) return tools::sg::key_shift();
0170 if(a_key==XK_Shift_R) return tools::sg::key_shift();
0171 return (tools::key_code)a_key;
0172 }
0173 protected:
0174 session& m_session;
0175 Widget m_shell;
0176 Widget m_glarea;
0177 tools::sg::device_interactor* m_interactor;
0178 };
0179
0180 }}
0181
0182 #endif
0183