#include "GLCtrl.h" #ifdef PLATFORM_POSIX #include #include #define Time XTime #define Font XFont #define Display XDisplay #define Picture XPicture #define Status int #ifdef GUI_GTK #include #endif #undef Time #undef Font #undef Display #undef Picture #undef Status namespace Upp { static XVisualInfo *s_XVisualInfo; static Colormap s_Colormap; static GLXContext s_GLXContext; static ::XDisplay *s_Display; void GLCtrl::Create() { MemoryIgnoreLeaksBlock __; Ctrl *top = GetTopCtrl(); if(!top) return; #ifdef GUI_GTK GdkWindow *gdk = top->gdk(); if(!gdk) return; Window w = gdk_x11_window_get_xid(gdk); #else Window w = top->GetWindow(); #endif ONCELOCK { #ifdef GUI_GTK s_Display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); #else s_Display = Xdisplay; #endif int samples = numberOfSamples; do { Vector attr; attr << GLX_RGBA << GLX_DEPTH_SIZE << depthSize << GLX_STENCIL_SIZE << stencilSize; if(doubleBuffering) attr << GLX_DOUBLEBUFFER; if(samples > 1) attr << GLX_SAMPLE_BUFFERS_ARB << 1 << GLX_SAMPLES_ARB << samples; attr << 0; samples >>= 1; s_XVisualInfo = glXChooseVisual(s_Display, DefaultScreen(s_Display), attr); } while(!s_XVisualInfo && samples > 0); if(!s_XVisualInfo) return; s_Colormap = XCreateColormap(s_Display, RootWindow(s_Display, s_XVisualInfo->screen), s_XVisualInfo->visual, AllocNone); s_GLXContext = glXCreateContext(s_Display, s_XVisualInfo, NULL, GL_TRUE); } if(!s_GLXContext) return; XSetWindowAttributes swa; swa.colormap = s_Colormap; swa.border_pixel = 0; swa.event_mask = 0; win = XCreateWindow(s_Display, w, 0, 0, 1, 1, 0, s_XVisualInfo->depth, InputOutput, s_XVisualInfo->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); visible = false; position = Null; } void GLCtrl::Sync() { MemoryIgnoreLeaksBlock __; if(win) { Rect r = GetScreenView() - GetTopCtrl()->GetScreenRect().TopLeft(); bool b = IsVisible() && r.GetWidth() > 0 && r.GetHeight() > 0; if(b != visible) { visible = b; position = Null; if(b) XMapWindow(s_Display, win); else XUnmapWindow(s_Display, win); } if(r != position && visible) { position = r; XMoveResizeWindow(s_Display, win, r.left, r.top, r.Width(), r.Height()); } } } void GLCtrl::State(int reason) { switch(reason) { case CLOSE: XDestroyWindow(s_Display, win); break; case OPEN: Create(); default: Sync(); break; } } void GLCtrl::ExecuteGL(Event<> paint, bool swap_buffers) { MemoryIgnoreLeaksBlock __; glXMakeCurrent(s_Display, win, s_GLXContext); ONCELOCK { glewInit(); } paint(); if(swap_buffers) glXSwapBuffers(s_Display, win); else glFlush(); glXMakeCurrent(s_Display, None, NULL); } void GLCtrl::Paint(Draw& w) { Size sz = GetSize(); if(!s_GLXContext || sz.cx == 0 || sz.cy == 0) return; ExecuteGL([&] { DoGLPaint(); }, doubleBuffering); } } #endif