Import Geant4 10.6.0 source tree
This commit is contained in:
@@ -0,0 +1,429 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_X11_base_session
|
||||
#define tools_X11_base_session
|
||||
|
||||
// pure X11 code, no GL.
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#include "dispatcher"
|
||||
#include <tools/forit>
|
||||
|
||||
#include <X11/Xatom.h> //XA_INTEGER
|
||||
|
||||
#include <X11/Xutil.h> //XVisualInfo
|
||||
|
||||
namespace tools {
|
||||
namespace X11 {
|
||||
|
||||
class base_session {
|
||||
public:
|
||||
//virtual bool make_current(Window) const {
|
||||
// if(!m_display) return false;
|
||||
// return true;
|
||||
//}
|
||||
//virtual bool swap_buffers(Window) const {
|
||||
// if(!m_display) return false;
|
||||
// return true;
|
||||
//}
|
||||
public:
|
||||
base_session(std::ostream& a_out,unsigned int a_monitor = 0)
|
||||
:m_out(a_out)
|
||||
,m_monitor(a_monitor)
|
||||
,m_display(0)
|
||||
,m_WM_DELETE_WINDOW_atom(None)
|
||||
,m_SESSION_EXIT_STEER_atom(None)
|
||||
{
|
||||
if(!initialize()) {} //throw
|
||||
}
|
||||
virtual ~base_session() {
|
||||
clear_dispatchers();
|
||||
finalize();
|
||||
//std::cout << "debug : ~base_session" << std::endl;
|
||||
}
|
||||
public:
|
||||
base_session(const base_session& a_from)
|
||||
:m_out(a_from.m_out)
|
||||
,m_monitor(a_from.m_monitor)
|
||||
,m_display(0)
|
||||
,m_WM_DELETE_WINDOW_atom(None)
|
||||
,m_SESSION_EXIT_STEER_atom(None)
|
||||
{
|
||||
copy_dispatchers(a_from.m_dispatchers);
|
||||
if(!initialize()) {} //throw
|
||||
}
|
||||
base_session& operator=(const base_session& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
m_monitor = a_from.m_monitor;
|
||||
clear_dispatchers();
|
||||
finalize();
|
||||
copy_dispatchers(a_from.m_dispatchers);
|
||||
if(!initialize()) {} //throw
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
bool initialize() {
|
||||
if(m_display) return true; //done.
|
||||
|
||||
//NOTE : macOS : XOpenDisplay leaks 128 bytes.
|
||||
m_display = ::XOpenDisplay(NULL);
|
||||
if(!m_display) {
|
||||
m_out << "tools::X11::base_session::initialize : can't open display." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int monitors = ::XScreenCount(m_display);
|
||||
if(int(m_monitor)>=monitors) {
|
||||
m_out << "tools::X11::base_session::initialize : bad monitor index " << m_monitor << ". (#monitors " << monitors << ")." << std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_WM_DELETE_WINDOW_atom = ::XInternAtom(m_display,"WM_DELETE_WINDOW",False);
|
||||
if(m_WM_DELETE_WINDOW_atom==None) {
|
||||
m_out << "tools::X11::base_session::initialize : can't create/get WM_DELETE_WINDOW Atom." << std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_SESSION_EXIT_STEER_atom = ::XInternAtom(m_display,"TOOLS_X11_SESSION_EXIT_STEER",False);
|
||||
if(m_SESSION_EXIT_STEER_atom==None) {
|
||||
m_out << "tools::X11::base_session::initialize : can't create/get TOOLS_X11_SESSION_EXIT_STEER Atom." << std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void finalize() {
|
||||
if(!m_display) return;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
}
|
||||
public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
|
||||
Atom WM_DELETE_WINDOW_atom() const {return m_WM_DELETE_WINDOW_atom;}
|
||||
Atom SESSION_EXIT_STEER_atom() const {return m_SESSION_EXIT_STEER_atom;}
|
||||
|
||||
bool is_valid() const {return m_display?true:false;}
|
||||
|
||||
Display* display() const {return m_display;}
|
||||
|
||||
bool steer() {
|
||||
if(!m_display) return false;
|
||||
|
||||
while(true) {
|
||||
XEvent xevent;
|
||||
::XNextEvent(m_display,&xevent);
|
||||
if(xevent.type==ClientMessage) {
|
||||
if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) break;
|
||||
}
|
||||
dispatch(xevent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sync() {
|
||||
if(!m_display) return false;
|
||||
//::glXWaitX();
|
||||
::XSync(m_display,False);
|
||||
while(true) {
|
||||
XEvent xevent;
|
||||
if(::XPending(m_display)) {
|
||||
::XNextEvent(m_display,&xevent);
|
||||
if(xevent.type==ClientMessage) {
|
||||
if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) return false;
|
||||
}
|
||||
dispatch(xevent);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool event_pending(bool& a_is) {
|
||||
if(!m_display) {a_is = false;return false;}
|
||||
a_is = ::XPending(m_display)?true:false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool next_event(bool& a_to_exit) {
|
||||
if(!m_display) {a_to_exit = false;return false;}
|
||||
XEvent xevent;
|
||||
::XNextEvent(m_display,&xevent);
|
||||
if(xevent.type==ClientMessage) {
|
||||
if(xevent.xclient.data.l[0]==(long)m_SESSION_EXIT_STEER_atom) {
|
||||
a_to_exit = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dispatch(xevent);
|
||||
a_to_exit = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flush() {
|
||||
if(!m_display) return false;
|
||||
::XFlush(m_display);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////
|
||||
Window create_window(const char* a_title,int a_x,int a_y,unsigned int a_width,unsigned int a_height) {
|
||||
if(!m_display) return 0L;
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
swa.event_mask = StructureNotifyMask | ExposureMask
|
||||
| ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
|
||||
| PointerMotionMask
|
||||
| KeyPressMask;
|
||||
|
||||
swa.background_pixel = ::XWhitePixel(m_display,m_monitor);
|
||||
|
||||
Window window = ::XCreateWindow(m_display,
|
||||
::XRootWindow(m_display,m_monitor),
|
||||
a_x,a_y,a_width,a_height,
|
||||
0,
|
||||
(int)CopyFromParent,
|
||||
InputOutput,
|
||||
(Visual*)CopyFromParent,
|
||||
CWEventMask|CWBackPixel,&swa);
|
||||
if(window==0L) {
|
||||
m_out << "tools::X11::base_session::create_window : can't create a X11 window." << std::endl;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
XTextProperty tp;
|
||||
::XStringListToTextProperty((char**)&a_title,1,&tp);
|
||||
XSizeHints sh;
|
||||
sh.flags = USPosition | USSize;
|
||||
::XSetWMProperties(m_display,window,&tp,&tp,0,0,&sh,0,0);
|
||||
::XFree(tp.value);
|
||||
|
||||
::XSetWMProtocols(m_display,window,&m_WM_DELETE_WINDOW_atom,1);
|
||||
return window;
|
||||
}
|
||||
|
||||
void map_raise_window(Window a_window) const {
|
||||
if(!m_display) return;
|
||||
::XMapWindow(m_display,a_window);
|
||||
::XRaiseWindow(m_display,a_window);
|
||||
}
|
||||
|
||||
void show_window(Window a_window) const {
|
||||
if(!m_display) return;
|
||||
// we should test if already mapped ! Else we are going to forever wait in the below XIfEvent.
|
||||
::XMapWindow(m_display,a_window);
|
||||
::XRaiseWindow(m_display,a_window);
|
||||
{XEvent event;
|
||||
::XIfEvent(m_display,&event,wait_map_notify,(char*)a_window);}
|
||||
}
|
||||
|
||||
void hide_window(Window a_window) const {
|
||||
if(!m_display) return;
|
||||
::XUnmapWindow(m_display,a_window);
|
||||
{XEvent event;
|
||||
::XIfEvent(m_display,&event,wait_unmap_notify,(char*)a_window);}
|
||||
}
|
||||
|
||||
void resize_window(Window a_window,unsigned int a_width,unsigned int a_height) const {
|
||||
if(!m_display) return;
|
||||
unsigned int mask = CWWidth | CWHeight | CWBorderWidth;
|
||||
XWindowChanges changes;
|
||||
changes.border_width = 0;
|
||||
changes.width = a_width;
|
||||
changes.height = a_height;
|
||||
::XConfigureWindow(m_display,a_window,mask,&changes);
|
||||
}
|
||||
|
||||
bool window_size(Window a_window,int& a_width,int& a_height) const {
|
||||
if(!m_display) {a_width = 0;a_height = 0;return false;}
|
||||
XWindowAttributes watbs;
|
||||
if(!XGetWindowAttributes(m_display,a_window,&watbs)) {a_width = 0;a_height = 0;return false;}
|
||||
a_width = watbs.width;
|
||||
a_height = watbs.height;
|
||||
return true;
|
||||
}
|
||||
|
||||
void delete_window(Window a_window) const {
|
||||
if(!m_display) return;
|
||||
::XDestroyWindow(m_display,a_window);
|
||||
}
|
||||
|
||||
void set_override_redirect(Window a_window) const {
|
||||
//must be executed before window is mapped.
|
||||
if(!m_display) return;
|
||||
XSetWindowAttributes swa;
|
||||
swa.override_redirect = True;
|
||||
::XChangeWindowAttributes(m_display,a_window,CWOverrideRedirect,&swa);
|
||||
}
|
||||
|
||||
void set_wm_no_decorations(Window a_window) const {
|
||||
//must be executed before window is mapped.
|
||||
if(!m_display) return;
|
||||
|
||||
// struct, mwm_hints_decorations taken from OpenMotif MwmUtils.h.
|
||||
struct{
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
unsigned long decorations;
|
||||
long inputMode;
|
||||
unsigned long status;
|
||||
} prop;
|
||||
|
||||
//unsigned long mwm_hints_functions = 1L << 0;
|
||||
unsigned long mwm_hints_decorations = 1L << 1;
|
||||
|
||||
Atom atom = ::XInternAtom(m_display,"_MOTIF_WM_HINTS",False);
|
||||
if(atom==None) {
|
||||
m_out << "tools::X11::base_session::set_wm_no_decorations : can't create/get _MOTIF_WM_HINTS Atom." << std::endl;
|
||||
return;
|
||||
}
|
||||
prop.flags = mwm_hints_decorations;
|
||||
prop.functions = 0;
|
||||
prop.decorations = 0;
|
||||
|
||||
::XChangeProperty(m_display,a_window,atom,atom,32,PropModeReplace,(unsigned char*)&prop,5);
|
||||
}
|
||||
|
||||
bool post(Window a_win,
|
||||
long a_0 = 0,long a_1 = 0,
|
||||
long a_2 = 0,long a_3 = 0,
|
||||
long a_4 = 0) const {
|
||||
if(!m_display) return false;
|
||||
XEvent event;
|
||||
event.type = ClientMessage;
|
||||
event.xclient.display = m_display;
|
||||
event.xclient.window = a_win;
|
||||
event.xclient.message_type = XA_INTEGER;
|
||||
event.xclient.format = 8; /* put 8 because bug with 32 on VMCMS */
|
||||
event.xclient.data.l[0] = a_0;
|
||||
event.xclient.data.l[1] = a_1;
|
||||
event.xclient.data.l[2] = a_2;
|
||||
event.xclient.data.l[3] = a_3;
|
||||
event.xclient.data.l[4] = a_4;
|
||||
//lock();
|
||||
Status stat = ::XSendEvent(m_display,a_win,False,0L,&event);
|
||||
::XFlush(m_display);
|
||||
//unlock();
|
||||
return (stat==0?false:true);
|
||||
}
|
||||
|
||||
bool post_EXIT_STEER(Window a_win) {
|
||||
return post(a_win,SESSION_EXIT_STEER_atom());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////
|
||||
void add_dispatcher(dispatcher* a_dispatcher) {
|
||||
m_dispatchers.push_back(a_dispatcher); //take ownership.
|
||||
}
|
||||
|
||||
void invalidate_dispatchers_with_window(Window a_win){
|
||||
tools_vforit(dispatcher*,m_dispatchers,it) {
|
||||
if((*it)->window()==a_win) (*it)->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void remove_dispatchers_with_window(Window a_win){
|
||||
tools_vforit_npp(dispatcher*,m_dispatchers,it) {
|
||||
if((*it)->window()==a_win) {
|
||||
dispatcher* obj = *it;
|
||||
it = m_dispatchers.erase(it);
|
||||
delete obj;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dispatch(XEvent& a_event) {
|
||||
{tools_vforit_npp(dispatcher*,m_dispatchers,it) {
|
||||
if(!(*it)->is_valid()) {
|
||||
dispatcher* obj = *it;
|
||||
it = m_dispatchers.erase(it);
|
||||
delete obj;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}}
|
||||
tools_vforit(dispatcher*,m_dispatchers,it) {
|
||||
if((*it)->is_valid()) {
|
||||
if((*it)->dispatch(a_event)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
static Bool wait_map_notify(Display*,XEvent* a_event,char* a_arg){
|
||||
return (a_event->type == MapNotify) && (a_event->xmap.window == (Window)a_arg);
|
||||
}
|
||||
static Bool wait_unmap_notify(Display*,XEvent* a_event,char* a_arg){
|
||||
return (a_event->type == UnmapNotify) && (a_event->xmap.window == (Window)a_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
void wait_xxx(Window a_window) {
|
||||
if(!m_display) return;
|
||||
{wait_what arg;
|
||||
arg.m_event_type = ConfigureNotify;
|
||||
arg.m_window = a_window;
|
||||
XEvent event;
|
||||
::XIfEvent(m_display,&event,wait_for,(char*)&arg);
|
||||
dispatch(event);}
|
||||
}
|
||||
|
||||
struct wait_what {
|
||||
int m_event_type;
|
||||
Window m_window;
|
||||
};
|
||||
static Bool wait_for(Display*,XEvent* a_event,char* a_arg){
|
||||
wait_what* arg = (wait_what*)a_arg;
|
||||
return (a_event->type == arg->m_event_type) &&
|
||||
(a_event->xmap.window == arg->m_window);
|
||||
}
|
||||
*/
|
||||
|
||||
void clear_dispatchers() {
|
||||
tools_vforit_npp(dispatcher*,m_dispatchers,it) {
|
||||
dispatcher* obj = *it;
|
||||
it = m_dispatchers.erase(it);
|
||||
delete obj;
|
||||
}
|
||||
m_dispatchers.clear();
|
||||
}
|
||||
|
||||
void copy_dispatchers(const std::vector<dispatcher*>& a_from) {
|
||||
clear_dispatchers();
|
||||
tools_vforcit(dispatcher*,a_from,it) {
|
||||
m_dispatchers.push_back((*it)->copy());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
unsigned int m_monitor;
|
||||
Display* m_display;
|
||||
Atom m_WM_DELETE_WINDOW_atom;
|
||||
Atom m_SESSION_EXIT_STEER_atom;
|
||||
std::vector<dispatcher*> m_dispatchers;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_X11_dispatcher
|
||||
#define tools_X11_dispatcher
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include <tools/mem>
|
||||
#endif
|
||||
|
||||
namespace tools {
|
||||
namespace X11 {
|
||||
|
||||
class dispatcher {
|
||||
protected:
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::X11::dispatcher");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
virtual bool dispatch(XEvent&) = 0;
|
||||
virtual Window window() const = 0;
|
||||
virtual dispatcher* copy() const = 0;
|
||||
public:
|
||||
dispatcher():m_is_valid(true){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
virtual ~dispatcher(){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
dispatcher(const dispatcher& a_from):m_is_valid(a_from.m_is_valid){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
dispatcher& operator=(const dispatcher& a_from) { m_is_valid = a_from.m_is_valid;return *this;}
|
||||
public:
|
||||
bool is_valid() const {return m_is_valid;}
|
||||
void invalidate() {m_is_valid = false;}
|
||||
protected:
|
||||
bool m_is_valid;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,223 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_X11_session
|
||||
#define tools_X11_session
|
||||
|
||||
#include "base_session"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
namespace tools {
|
||||
namespace X11 {
|
||||
|
||||
class session : public base_session {
|
||||
typedef base_session parent;
|
||||
public:
|
||||
//virtual bool make_current(Window a_window) const {
|
||||
// if(!m_display) return false;
|
||||
// if(::glXMakeCurrent(m_display,a_window,m_ctx)==False) {
|
||||
// m_out << "tools::X11::session::make_current : glXMakeCurrent failed." << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
//virtual bool swap_buffers(Window a_window) const {
|
||||
// if(!m_display) return false;
|
||||
// ::glXSwapBuffers(m_display,a_window);
|
||||
// return true;
|
||||
//}
|
||||
public:
|
||||
session(std::ostream& a_out,unsigned int a_monitor = 0)
|
||||
:parent(a_out,a_monitor)
|
||||
,m_vinfo(0)
|
||||
,m_ctx(0)
|
||||
,m_colormap(0)
|
||||
{
|
||||
if(!initialize_gl()) {} //throw
|
||||
}
|
||||
virtual ~session() {
|
||||
finalize_gl();
|
||||
//std::cout << "debug : ~session" << std::endl;
|
||||
}
|
||||
public:
|
||||
session(const session& a_from)
|
||||
:parent(a_from)
|
||||
,m_vinfo(0)
|
||||
,m_ctx(0)
|
||||
,m_colormap(0)
|
||||
{
|
||||
if(!initialize_gl()) {} //throw
|
||||
}
|
||||
session& operator=(const session& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
finalize_gl();
|
||||
if(!initialize_gl()) {} //throw
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
bool initialize_gl() {
|
||||
if(!m_display) {
|
||||
m_display = 0;
|
||||
m_vinfo = 0;
|
||||
m_ctx = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{int glxMajor, glxMinor;
|
||||
::glXQueryVersion(m_display,&glxMajor,&glxMinor);
|
||||
if(glxMajor<=0) {
|
||||
m_out << "tools::X11::session::initialize : bad GLX-Version " << glxMajor << "." << glxMinor << std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
m_vinfo = 0;
|
||||
m_ctx = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
static const int atbs_alpha[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_ALPHA_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None};
|
||||
|
||||
//NOTE : macOS : glXChooseVisual leaks 640 bytes.
|
||||
m_vinfo = ::glXChooseVisual(m_display,m_monitor,(int*)atbs_alpha);
|
||||
if(!m_vinfo) {
|
||||
//m_out << "tools::X11::session::initialize :"
|
||||
// << " can't get a visual with alpha on screen " << m_monitor << ". Try without alpha..."
|
||||
// << std::endl;
|
||||
//m_out << "tools::X11::session::initialize :"
|
||||
// << " DefaultScreen(m_display): " << DefaultScreen(m_display) << "."
|
||||
// << std::endl;
|
||||
|
||||
static const int atbs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None};
|
||||
|
||||
m_vinfo = ::glXChooseVisual(m_display,m_monitor,(int*)atbs);
|
||||
if(!m_vinfo) {
|
||||
m_out << "tools::X11::session::initialize :"
|
||||
<< " can't choose a visual on screen " << m_monitor << "."
|
||||
<< std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
m_vinfo = 0;
|
||||
m_ctx = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_ctx = ::glXCreateContext(m_display,m_vinfo,NULL,GL_TRUE);
|
||||
if(!m_ctx) {
|
||||
m_out << "tools::X11::session::initialize :"
|
||||
<< " can't create a glX context with direct rendering."
|
||||
<< std::endl;
|
||||
m_ctx = ::glXCreateContext(m_display,m_vinfo,NULL,GL_FALSE);
|
||||
if(!m_ctx) {
|
||||
m_out << "tools::X11::session::initialize :"
|
||||
<< " can't create a glX context."
|
||||
<< std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
m_vinfo = 0;
|
||||
m_ctx = 0;
|
||||
return false;
|
||||
}
|
||||
//} else {
|
||||
//m_out << "tools::X11::session::initialize :"
|
||||
// << " glX context with direct rendering created."
|
||||
// << std::endl;
|
||||
}
|
||||
|
||||
// It is better to create a colormap adapted to the visual.
|
||||
m_colormap = ::XCreateColormap(m_display,::XRootWindow(m_display,m_monitor),m_vinfo->visual,AllocNone);
|
||||
//m_colormap = ::XDefaultColormap(m_display,m_monitor);
|
||||
if(m_colormap==0L) {
|
||||
m_out << "tools::X11::session::initialize : XCreateColormap failed." << std::endl;
|
||||
::XCloseDisplay(m_display);
|
||||
m_display = 0;
|
||||
m_vinfo = 0;
|
||||
m_ctx = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void finalize_gl() {
|
||||
if(!m_display) return;
|
||||
if(m_ctx) {
|
||||
::glXDestroyContext(m_display,m_ctx);
|
||||
m_ctx = 0;
|
||||
}
|
||||
if(m_vinfo) {
|
||||
::XFree(m_vinfo);
|
||||
m_vinfo = 0;
|
||||
}
|
||||
if(m_colormap) {
|
||||
::XFreeColormap(m_display,m_colormap);
|
||||
m_colormap = 0;
|
||||
}
|
||||
}
|
||||
public:
|
||||
GLXContext context() const {return m_ctx;}
|
||||
|
||||
Window create_window(const char* a_title,int a_x,int a_y,unsigned int a_width,unsigned int a_height) {
|
||||
if(!m_display) return 0L;
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
swa.event_mask = StructureNotifyMask | ExposureMask
|
||||
| ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
|
||||
| PointerMotionMask
|
||||
| KeyPressMask;
|
||||
|
||||
swa.colormap = m_colormap;
|
||||
swa.border_pixel = 0L;
|
||||
|
||||
Window window = ::XCreateWindow(m_display,
|
||||
::XRootWindow(m_display,m_monitor),
|
||||
a_x,a_y,a_width,a_height,
|
||||
0,
|
||||
m_vinfo->depth,
|
||||
InputOutput,
|
||||
m_vinfo->visual,
|
||||
CWBorderPixel|CWColormap|CWEventMask,&swa);
|
||||
|
||||
if(window==0L) {
|
||||
m_out << "tools::X11::session::create_window :"
|
||||
<< " can't create a X11 window."
|
||||
<< std::endl;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
XTextProperty tp;
|
||||
::XStringListToTextProperty((char**)&a_title,1,&tp);
|
||||
XSizeHints sh;
|
||||
sh.flags = USPosition | USSize;
|
||||
::XSetWMProperties(m_display,window,&tp,&tp,0,0,&sh,0,0);
|
||||
::XFree(tp.value);
|
||||
|
||||
::XSetWMProtocols(m_display,window,&m_WM_DELETE_WINDOW_atom,1);
|
||||
return window;
|
||||
}
|
||||
protected:
|
||||
XVisualInfo* m_vinfo;
|
||||
GLXContext m_ctx;
|
||||
Colormap m_colormap;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_X11_simple_dispatcher
|
||||
#define tools_X11_simple_dispatcher
|
||||
|
||||
#include "base_session"
|
||||
|
||||
#include <tools/saui>
|
||||
|
||||
namespace tools {
|
||||
namespace X11 {
|
||||
|
||||
class simple_dispatcher : public dispatcher {
|
||||
typedef dispatcher parent;
|
||||
public:
|
||||
virtual void win_render() = 0;
|
||||
virtual void set_size(unsigned int a_width,unsigned int a_height) = 0;
|
||||
public:
|
||||
virtual bool dispatch(XEvent& a_event) {
|
||||
if(!m_win) return false;
|
||||
if(a_event.xany.window!=m_win) return false;
|
||||
if( (a_event.type==Expose) || (a_event.type==ConfigureNotify) ){
|
||||
int width,height;
|
||||
m_session.window_size(m_win,width,height);
|
||||
set_size(width,height); //viewer::set_size()
|
||||
win_render();
|
||||
return true;
|
||||
} else if(a_event.type==ClientMessage) {
|
||||
if(a_event.xclient.data.l[0]==(long)m_session.WM_DELETE_WINDOW_atom()) {
|
||||
m_session.post(m_win,m_session.SESSION_EXIT_STEER_atom());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual Window window() const {return m_win;}
|
||||
public:
|
||||
simple_dispatcher(base_session& a_session,Window a_win)
|
||||
:parent()
|
||||
,m_session(a_session)
|
||||
,m_win(a_win)
|
||||
{}
|
||||
virtual ~simple_dispatcher(){}
|
||||
public:
|
||||
simple_dispatcher(const simple_dispatcher& a_from)
|
||||
:parent(a_from)
|
||||
,m_session(a_from.m_session)
|
||||
,m_win(a_from.m_win)
|
||||
{}
|
||||
simple_dispatcher& operator=(const simple_dispatcher& a_from) {
|
||||
parent::operator=(a_from);
|
||||
m_win = a_from.m_win;
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
base_session& m_session;
|
||||
Window m_win;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user