Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef toolx_Xt_zb_viewer 4 #ifndef toolx_Xt_zb_viewer 5 #define toolx_Xt_zb_viewer 5 #define toolx_Xt_zb_viewer 6 6 7 #include "session" 7 #include "session" 8 #include "ImageArea" 8 #include "ImageArea" 9 #include "../X11/pixwin" 9 #include "../X11/pixwin" 10 10 11 #include <X11/Shell.h> 11 #include <X11/Shell.h> 12 #include <X11/StringDefs.h> 12 #include <X11/StringDefs.h> 13 #include <X11/IntrinsicP.h> 13 #include <X11/IntrinsicP.h> 14 14 15 #include <tools/sg/zb_viewer> 15 #include <tools/sg/zb_viewer> 16 #include <tools/num2s> 16 #include <tools/num2s> 17 #include <tools/sg/device_interactor> 17 #include <tools/sg/device_interactor> 18 #include <tools/sg/keys> 18 #include <tools/sg/keys> 19 19 20 namespace toolx { 20 namespace toolx { 21 namespace Xt { 21 namespace Xt { 22 22 23 class zb_viewer: public tools::sg::zb_viewer { 23 class zb_viewer: public tools::sg::zb_viewer { 24 typedef tools::sg::zb_viewer parent; 24 typedef tools::sg::zb_viewer parent; 25 public: 25 public: 26 zb_viewer(session& a_session, 26 zb_viewer(session& a_session, 27 int a_x = 0,int a_y = 0, 27 int a_x = 0,int a_y = 0, 28 unsigned int a_width = 500,unsigne 28 unsigned int a_width = 500,unsigned int a_height = 500, 29 const std::string& a_win_title = " 29 const std::string& a_win_title = "") 30 :parent(a_session.out(),a_width,a_height) 30 :parent(a_session.out(),a_width,a_height) 31 ,m_session(a_session) 31 ,m_session(a_session) 32 ,m_shell(0) 32 ,m_shell(0) 33 ,m_image_area(0) 33 ,m_image_area(0) 34 ,m_pixwin(0) 34 ,m_pixwin(0) 35 ,m_interactor(0) 35 ,m_interactor(0) 36 { 36 { 37 Widget app_widget = a_session.get_app_widg 37 Widget app_widget = a_session.get_app_widget(); 38 if(!app_widget) return; 38 if(!app_widget) return; 39 39 40 std::string sgeom; 40 std::string sgeom; 41 tools::numas(a_width,sgeom); 41 tools::numas(a_width,sgeom); 42 sgeom += "x"; 42 sgeom += "x"; 43 tools::numas(a_height,sgeom); 43 tools::numas(a_height,sgeom); 44 sgeom += "+"; 44 sgeom += "+"; 45 tools::numas(a_x,sgeom); 45 tools::numas(a_x,sgeom); 46 sgeom += "+"; 46 sgeom += "+"; 47 tools::numas(a_y,sgeom); 47 tools::numas(a_y,sgeom); 48 48 49 Arg args[2]; 49 Arg args[2]; 50 XtSetArg(args[0],XtNgeometry,XtNewString(s 50 XtSetArg(args[0],XtNgeometry,XtNewString(sgeom.c_str())); 51 XtSetArg(args[1],XtNborderWidth,0); 51 XtSetArg(args[1],XtNborderWidth,0); 52 52 53 m_shell = ::XtAppCreateShell((char*)a_win_ 53 m_shell = ::XtAppCreateShell((char*)a_win_title.c_str(), 54 (char*)"zb_vi 54 (char*)"zb_viewer_shell", 55 topLevelShell 55 topLevelShellWidgetClass,XtDisplay(app_widget),args,2); 56 ::XtSetMappedWhenManaged(m_shell,True); 56 ::XtSetMappedWhenManaged(m_shell,True); 57 57 58 m_image_area = ::XtCreateManagedWidget("im 58 m_image_area = ::XtCreateManagedWidget("imagearea",ImageArea::widget_class(),m_shell,args,0); 59 ::XtAddCallback(m_image_area,ImageArea::Xo 59 ::XtAddCallback(m_image_area,ImageArea::XoN_resizeCallback(),resize_cbk,(XtPointer)this); 60 ::XtAddCallback(m_image_area,ImageArea::Xo 60 ::XtAddCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this); 61 ::XtAddCallback(m_image_area,ImageArea::Xo 61 ::XtAddCallback(m_image_area,ImageArea::XoN_eventCallback(),event_cbk,(XtPointer)this); 62 62 63 ::XtAddCallback(m_shell,XtNdestroyCallback 63 ::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this); 64 64 65 ::XtRealizeWidget(m_shell); 65 ::XtRealizeWidget(m_shell); 66 66 67 {int iscreen; 67 {int iscreen; 68 Screen* screen = XtScreen(m_image_area); 68 Screen* screen = XtScreen(m_image_area); 69 iscreen = XScreenNumberOfScreen(screen); 69 iscreen = XScreenNumberOfScreen(screen); 70 m_pixwin = new toolx::X11::pixwin(a_sessio 70 m_pixwin = new toolx::X11::pixwin(a_session.out(),iscreen,XtDisplay(app_widget)); 71 m_pixwin->set_size(m_image_area->core.widt 71 m_pixwin->set_size(m_image_area->core.width,m_image_area->core.height);} 72 72 73 //Atom WM_DELETE_WINDOW_atom = ::XInternAtom 73 //Atom WM_DELETE_WINDOW_atom = ::XInternAtom(XtDisplay(m_shell),"WM_DELETE_WINDOW",False); 74 //::XSetWMProtocols(XtDisplay(m_shell),XtWin 74 //::XSetWMProtocols(XtDisplay(m_shell),XtWindow(m_shell),&WM_DELETE_WINDOW_atom,1); 75 } 75 } 76 virtual ~zb_viewer() { 76 virtual ~zb_viewer() { 77 delete m_pixwin; 77 delete m_pixwin; 78 if(m_shell) { 78 if(m_shell) { 79 ::XtRemoveCallback(m_image_area,ImageAre 79 ::XtRemoveCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this); 80 ::XtRemoveCallback(m_shell,XtNdestroyCal 80 ::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this); 81 ::XtDestroyWidget(m_shell); 81 ::XtDestroyWidget(m_shell); 82 } 82 } 83 m_shell = 0; 83 m_shell = 0; 84 m_image_area = 0; 84 m_image_area = 0; 85 } 85 } 86 protected: 86 protected: 87 zb_viewer(const zb_viewer& a_from) 87 zb_viewer(const zb_viewer& a_from) 88 :parent(a_from) 88 :parent(a_from) 89 ,m_session(a_from.m_session) 89 ,m_session(a_from.m_session) 90 ,m_shell(0) 90 ,m_shell(0) 91 ,m_image_area(0) 91 ,m_image_area(0) 92 ,m_interactor(0) 92 ,m_interactor(0) 93 {} 93 {} 94 zb_viewer& operator=(const zb_viewer& a_from 94 zb_viewer& operator=(const zb_viewer& a_from){ 95 parent::operator=(a_from); 95 parent::operator=(a_from); 96 return *this; 96 return *this; 97 } 97 } 98 public: 98 public: 99 bool has_window() const {return m_image_area 99 bool has_window() const {return m_image_area?true:false;} 100 100 101 bool show() { 101 bool show() { 102 if(!m_shell) return false; 102 if(!m_shell) return false; 103 ::XtRealizeWidget(m_shell); 103 ::XtRealizeWidget(m_shell); 104 ::XtMapWidget(m_shell); 104 ::XtMapWidget(m_shell); 105 // Raise window : 105 // Raise window : 106 if(XtIsWidget(m_shell) && XtIsRealized(m_s 106 if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) { 107 Display* display = XtDisplay(m_shell); 107 Display* display = XtDisplay(m_shell); 108 Atom atom = ::XInternAtom(display,"WM_DE 108 Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False); 109 ::XSetWMProtocols(display,XtWindow(m_she 109 ::XSetWMProtocols(display,XtWindow(m_shell),&atom,1); 110 ::XRaiseWindow(display,XtWindow(m_shell) 110 ::XRaiseWindow(display,XtWindow(m_shell)); 111 } 111 } 112 return true; 112 return true; 113 } 113 } 114 114 115 void win_render() { 115 void win_render() { 116 if(m_image_area) ImageArea::paint(m_image_ 116 if(m_image_area) ImageArea::paint(m_image_area); 117 } 117 } 118 118 119 void set_device_interactor(tools::sg::device 119 void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership. 120 protected: 120 protected: 121 static void resize_cbk(Widget a_widget,XtPoi 121 static void resize_cbk(Widget a_widget,XtPointer a_tag,XtPointer){ 122 if(!XtIsRealized(a_widget)) return; 122 if(!XtIsRealized(a_widget)) return; 123 unsigned int width = a_widget->core.width; 123 unsigned int width = a_widget->core.width; 124 unsigned int height = a_widget->core.heigh 124 unsigned int height = a_widget->core.height; 125 //::printf("debug: toolx::Xt::zb_viewer::r 125 //::printf("debug: toolx::Xt::zb_viewer::resize_cbk: %d %d\n",width,height); 126 zb_viewer* _this = (zb_viewer*)a_tag; 126 zb_viewer* _this = (zb_viewer*)a_tag; 127 _this->set_size(width,height); 127 _this->set_size(width,height); 128 _this->m_pixwin->set_size(width,height); 128 _this->m_pixwin->set_size(width,height); 129 } 129 } 130 static void paint_cbk(Widget a_widget,XtPoin 130 static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){ 131 if(!XtIsRealized(a_widget)) return; 131 if(!XtIsRealized(a_widget)) return; 132 unsigned int width = a_widget->core.width; 132 unsigned int width = a_widget->core.width; 133 unsigned int height = a_widget->core.heigh 133 unsigned int height = a_widget->core.height; 134 //::printf("debug: toolx::Xt::zb_viewer::p 134 //::printf("debug: toolx::Xt::zb_viewer::paint_cbk: %d %d\n",width,height); 135 zb_viewer* _this = (zb_viewer*)a_tag; 135 zb_viewer* _this = (zb_viewer*)a_tag; 136 if(!_this->render(tools::sg::zb_viewer::ge 136 if(!_this->render(tools::sg::zb_viewer::get_rgbas,false)) return; //rgbas because Qt wants an image 32 bits aligned. 137 _this->m_pixwin->put_buffer(XtWindow(a_wid 137 _this->m_pixwin->put_buffer(XtWindow(a_widget),width,height,tools::vec_data(_this->out_buffer())); 138 //parent::after_render(); 138 //parent::after_render(); 139 _this->out_buffer_clear(); 139 _this->out_buffer_clear(); 140 } 140 } 141 static void event_cbk(Widget,XtPointer a_tag 141 static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){ 142 zb_viewer* _this = (zb_viewer*)a_tag; 142 zb_viewer* _this = (zb_viewer*)a_tag; 143 if(!_this->m_interactor) return; 143 if(!_this->m_interactor) return; 144 ImageArea::XoAnyCallbackStruct* data = (Im 144 ImageArea::XoAnyCallbackStruct* data = (ImageArea::XoAnyCallbackStruct*)a_data; 145 XEvent* xevent = data->event; 145 XEvent* xevent = data->event; 146 switch( xevent->type ) { 146 switch( xevent->type ) { 147 case KeyPress:{ 147 case KeyPress:{ 148 KeySym key_sym; 148 KeySym key_sym; 149 ::XLookupString(&(xevent->xkey),NULL,0,& 149 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL); 150 tools::sg::key_down_event event(_this->c 150 tools::sg::key_down_event event(_this->convert_key(key_sym)); 151 _this->m_interactor->key_press(event); 151 _this->m_interactor->key_press(event); 152 }return; 152 }return; 153 case KeyRelease:{ 153 case KeyRelease:{ 154 KeySym key_sym; 154 KeySym key_sym; 155 ::XLookupString(&(xevent->xkey),NULL,0,& 155 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL); 156 tools::sg::key_up_event event(_this->con 156 tools::sg::key_up_event event(_this->convert_key(key_sym)); 157 _this->m_interactor->key_release(event); 157 _this->m_interactor->key_release(event); 158 }return; 158 }return; 159 case ButtonPress:{ 159 case ButtonPress:{ 160 if(xevent->xbutton.button==Button4) { / 160 if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in. 161 tools::sg::wheel_rotate_event event(8) 161 tools::sg::wheel_rotate_event event(8); //8=cooking. 162 _this->m_interactor->wheel_rotate(even 162 _this->m_interactor->wheel_rotate(event); 163 } else if(xevent->xbutton.button==Button 163 } else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out. 164 tools::sg::wheel_rotate_event event(-8 164 tools::sg::wheel_rotate_event event(-8); //8=cooking. 165 _this->m_interactor->wheel_rotate(even 165 _this->m_interactor->wheel_rotate(event); 166 } else if(xevent->xbutton.button==Button 166 } else if(xevent->xbutton.button==Button1) { 167 tools::sg::mouse_down_event event(xeve 167 tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y); 168 _this->m_interactor->mouse_press(event 168 _this->m_interactor->mouse_press(event); 169 } 169 } 170 }return; 170 }return; 171 case ButtonRelease:{ 171 case ButtonRelease:{ 172 if(xevent->xbutton.button==Button1) { 172 if(xevent->xbutton.button==Button1) { 173 tools::sg::mouse_up_event event(xevent 173 tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y); 174 _this->m_interactor->mouse_release(eve 174 _this->m_interactor->mouse_release(event); 175 } 175 } 176 }return; 176 }return; 177 case MotionNotify:{ 177 case MotionNotify:{ 178 if((xevent->xmotion.state & Button1Motio 178 if((xevent->xmotion.state & Button1MotionMask)==Button1MotionMask) { 179 tools::sg::mouse_move_event event(xeve 179 tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false); 180 _this->m_interactor->mouse_move(event) 180 _this->m_interactor->mouse_move(event); 181 } 181 } 182 }return; 182 }return; 183 default:return;} 183 default:return;} 184 } 184 } 185 static void destroy_shell_callback(Widget,Xt 185 static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) { 186 zb_viewer* _this = (zb_viewer*)a_tag; 186 zb_viewer* _this = (zb_viewer*)a_tag; 187 _this->m_shell = 0; 187 _this->m_shell = 0; 188 _this->m_image_area = 0; 188 _this->m_image_area = 0; 189 } 189 } 190 protected: 190 protected: 191 tools::key_code convert_key(KeySym a_key) { 191 tools::key_code convert_key(KeySym a_key) { 192 if(a_key==XK_Shift_L) return tools::sg::ke 192 if(a_key==XK_Shift_L) return tools::sg::key_shift(); 193 if(a_key==XK_Shift_R) return tools::sg::ke 193 if(a_key==XK_Shift_R) return tools::sg::key_shift(); 194 return (tools::key_code)a_key; 194 return (tools::key_code)a_key; 195 } 195 } 196 protected: 196 protected: 197 session& m_session; 197 session& m_session; 198 Widget m_shell; 198 Widget m_shell; 199 Widget m_image_area; 199 Widget m_image_area; 200 toolx::X11::pixwin* m_pixwin; 200 toolx::X11::pixwin* m_pixwin; 201 tools::sg::device_interactor* m_interactor; 201 tools::sg::device_interactor* m_interactor; 202 }; 202 }; 203 203 204 }} 204 }} 205 205 206 206 207 #endif 207 #endif 208 208