Warning, /include/Geant4/toolx/Xt/zb_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_zb_viewer
0005 #define toolx_Xt_zb_viewer
0006
0007 #include "session"
0008 #include "ImageArea"
0009 #include "../X11/pixwin"
0010
0011 #include <X11/Shell.h>
0012 #include <X11/StringDefs.h>
0013 #include <X11/IntrinsicP.h>
0014
0015 #include <tools/sg/zb_viewer>
0016 #include <tools/num2s>
0017 #include <tools/sg/device_interactor>
0018 #include <tools/sg/keys>
0019
0020 namespace toolx {
0021 namespace Xt {
0022
0023 class zb_viewer: public tools::sg::zb_viewer {
0024 typedef tools::sg::zb_viewer parent;
0025 public:
0026 zb_viewer(session& a_session,
0027 int a_x = 0,int a_y = 0,
0028 unsigned int a_width = 500,unsigned int a_height = 500,
0029 const std::string& a_win_title = "")
0030 :parent(a_session.out(),a_width,a_height)
0031 ,m_session(a_session)
0032 ,m_shell(0)
0033 ,m_image_area(0)
0034 ,m_pixwin(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*)"zb_viewer_shell",
0055 topLevelShellWidgetClass,XtDisplay(app_widget),args,2);
0056 ::XtSetMappedWhenManaged(m_shell,True);
0057
0058 m_image_area = ::XtCreateManagedWidget("imagearea",ImageArea::widget_class(),m_shell,args,0);
0059 ::XtAddCallback(m_image_area,ImageArea::XoN_resizeCallback(),resize_cbk,(XtPointer)this);
0060 ::XtAddCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this);
0061 ::XtAddCallback(m_image_area,ImageArea::XoN_eventCallback(),event_cbk,(XtPointer)this);
0062
0063 ::XtAddCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0064
0065 ::XtRealizeWidget(m_shell);
0066
0067 {int iscreen;
0068 Screen* screen = XtScreen(m_image_area);
0069 iscreen = XScreenNumberOfScreen(screen);
0070 m_pixwin = new toolx::X11::pixwin(a_session.out(),iscreen,XtDisplay(app_widget));
0071 m_pixwin->set_size(m_image_area->core.width,m_image_area->core.height);}
0072
0073 //Atom WM_DELETE_WINDOW_atom = ::XInternAtom(XtDisplay(m_shell),"WM_DELETE_WINDOW",False);
0074 //::XSetWMProtocols(XtDisplay(m_shell),XtWindow(m_shell),&WM_DELETE_WINDOW_atom,1);
0075 }
0076 virtual ~zb_viewer() {
0077 delete m_pixwin;
0078 if(m_shell) {
0079 ::XtRemoveCallback(m_image_area,ImageArea::XoN_paintCallback(),paint_cbk,(XtPointer)this);
0080 ::XtRemoveCallback(m_shell,XtNdestroyCallback,destroy_shell_callback,(XtPointer)this);
0081 ::XtDestroyWidget(m_shell);
0082 }
0083 m_shell = 0;
0084 m_image_area = 0;
0085 }
0086 protected:
0087 zb_viewer(const zb_viewer& a_from)
0088 :parent(a_from)
0089 ,m_session(a_from.m_session)
0090 ,m_shell(0)
0091 ,m_image_area(0)
0092 ,m_interactor(0)
0093 {}
0094 zb_viewer& operator=(const zb_viewer& a_from){
0095 parent::operator=(a_from);
0096 return *this;
0097 }
0098 public:
0099 bool has_window() const {return m_image_area?true:false;}
0100
0101 bool show() {
0102 if(!m_shell) return false;
0103 ::XtRealizeWidget(m_shell);
0104 ::XtMapWidget(m_shell);
0105 // Raise window :
0106 if(XtIsWidget(m_shell) && XtIsRealized(m_shell) ) {
0107 Display* display = XtDisplay(m_shell);
0108 Atom atom = ::XInternAtom(display,"WM_DELETE_WINDOW",False);
0109 ::XSetWMProtocols(display,XtWindow(m_shell),&atom,1);
0110 ::XRaiseWindow(display,XtWindow(m_shell));
0111 }
0112 return true;
0113 }
0114
0115 void win_render() {
0116 if(m_image_area) ImageArea::paint(m_image_area);
0117 }
0118
0119 void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
0120 protected:
0121 static void resize_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
0122 if(!XtIsRealized(a_widget)) return;
0123 unsigned int width = a_widget->core.width;
0124 unsigned int height = a_widget->core.height;
0125 //::printf("debug: toolx::Xt::zb_viewer::resize_cbk: %d %d\n",width,height);
0126 zb_viewer* _this = (zb_viewer*)a_tag;
0127 _this->set_size(width,height);
0128 _this->m_pixwin->set_size(width,height);
0129 }
0130 static void paint_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
0131 if(!XtIsRealized(a_widget)) return;
0132 unsigned int width = a_widget->core.width;
0133 unsigned int height = a_widget->core.height;
0134 //::printf("debug: toolx::Xt::zb_viewer::paint_cbk: %d %d\n",width,height);
0135 zb_viewer* _this = (zb_viewer*)a_tag;
0136 if(!_this->render(tools::sg::zb_viewer::get_rgbas,false)) return; //rgbas because Qt wants an image 32 bits aligned.
0137 _this->m_pixwin->put_buffer(XtWindow(a_widget),width,height,tools::vec_data(_this->out_buffer()));
0138 //parent::after_render();
0139 _this->out_buffer_clear();
0140 }
0141 static void event_cbk(Widget,XtPointer a_tag,XtPointer a_data){
0142 zb_viewer* _this = (zb_viewer*)a_tag;
0143 if(!_this->m_interactor) return;
0144 ImageArea::XoAnyCallbackStruct* data = (ImageArea::XoAnyCallbackStruct*)a_data;
0145 XEvent* xevent = data->event;
0146 switch( xevent->type ) {
0147 case KeyPress:{
0148 KeySym key_sym;
0149 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0150 tools::sg::key_down_event event(_this->convert_key(key_sym));
0151 _this->m_interactor->key_press(event);
0152 }return;
0153 case KeyRelease:{
0154 KeySym key_sym;
0155 ::XLookupString(&(xevent->xkey),NULL,0,&key_sym,NULL);
0156 tools::sg::key_up_event event(_this->convert_key(key_sym));
0157 _this->m_interactor->key_release(event);
0158 }return;
0159 case ButtonPress:{
0160 if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
0161 tools::sg::wheel_rotate_event event(8); //8=cooking.
0162 _this->m_interactor->wheel_rotate(event);
0163 } else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
0164 tools::sg::wheel_rotate_event event(-8); //8=cooking.
0165 _this->m_interactor->wheel_rotate(event);
0166 } else if(xevent->xbutton.button==Button1) {
0167 tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y);
0168 _this->m_interactor->mouse_press(event);
0169 }
0170 }return;
0171 case ButtonRelease:{
0172 if(xevent->xbutton.button==Button1) {
0173 tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y);
0174 _this->m_interactor->mouse_release(event);
0175 }
0176 }return;
0177 case MotionNotify:{
0178 if((xevent->xmotion.state & Button1MotionMask)==Button1MotionMask) {
0179 tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false);
0180 _this->m_interactor->mouse_move(event);
0181 }
0182 }return;
0183 default:return;}
0184 }
0185 static void destroy_shell_callback(Widget,XtPointer a_tag,XtPointer) {
0186 zb_viewer* _this = (zb_viewer*)a_tag;
0187 _this->m_shell = 0;
0188 _this->m_image_area = 0;
0189 }
0190 protected:
0191 tools::key_code convert_key(KeySym a_key) {
0192 if(a_key==XK_Shift_L) return tools::sg::key_shift();
0193 if(a_key==XK_Shift_R) return tools::sg::key_shift();
0194 return (tools::key_code)a_key;
0195 }
0196 protected:
0197 session& m_session;
0198 Widget m_shell;
0199 Widget m_image_area;
0200 toolx::X11::pixwin* m_pixwin;
0201 tools::sg::device_interactor* m_interactor;
0202 };
0203
0204 }}
0205
0206
0207 #endif
0208