"Fossies" - the Fresh Open Source Software Archive

Member "FreeBASIC-1.08.1-source/src/gfxlib2/unix/gfx_driver_opengl_x11.c" (6 Jul 2021, 7540 Bytes) of package /linux/privat/FreeBASIC-1.08.1-source.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gfx_driver_opengl_x11.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.08.0_vs_1.08.1.

    1 /* OpenGL gfx driver */
    2 
    3 #include "../fb_gfx.h"
    4 #include "fb_gfx_x11.h"
    5 #include "../fb_gfx_gl.h"
    6 
    7 #if !defined DISABLE_X11 && !defined DISABLE_OPENGL
    8 
    9 #include <GL/glx.h>
   10 
   11 /* For compatibility with old Mesa headers */
   12 #ifndef GLX_SAMPLE_BUFFERS_ARB
   13 # define GLX_SAMPLE_BUFFERS_ARB             100000
   14 #endif
   15 #ifndef GLX_SAMPLES_ARB
   16 # define GLX_SAMPLES_ARB                    100001
   17 #endif
   18 
   19 static int driver_init(char *title, int w, int h, int depth, int refresh_rate, int flags);
   20 static void driver_exit(void);
   21 static void driver_flip(void);
   22 
   23 GFXDRIVER fb_gfxDriverOpenGL =
   24 {
   25     "OpenGL",       /* char *name; */
   26     driver_init,        /* int (*init)(int w, int h, char *title, int fullscreen); */
   27     driver_exit,        /* void (*exit)(void); */
   28     fb_hX11Lock,        /* void (*lock)(void); */
   29     fb_hX11Unlock,      /* void (*unlock)(void); */
   30     fb_hGL_SetPalette,  /* void (*set_palette)(int index, int r, int g, int b); */
   31     fb_hX11WaitVSync,   /* void (*wait_vsync)(void); */
   32     fb_hX11GetMouse,    /* int (*get_mouse)(int *x, int *y, int *z, int *buttons, int *clip); */
   33     fb_hX11SetMouse,    /* void (*set_mouse)(int x, int y, int cursor, int clip); */
   34     fb_hX11SetWindowTitle,  /* void (*set_window_title)(char *title); */
   35     fb_hX11SetWindowPos,    /* int (*set_window_pos)(int x, int y); */
   36     fb_hX11FetchModes,  /* int *(*fetch_modes)(void); */
   37     driver_flip,        /* void (*flip)(void); */
   38     NULL            /* void (*poll_events)(void); */
   39 };
   40 
   41 
   42 typedef XVisualInfo *(*GLXCHOOSEVISUAL)(Display *, int, int *);
   43 typedef GLXContext (*GLXCREATECONTEXT)(Display *, XVisualInfo *, GLXContext, int);
   44 typedef void (*GLXDESTROYCONTEXT)(Display *, GLXContext);
   45 typedef int (*GLXMAKECURRENT)(Display *, GLXDrawable, GLXContext);
   46 typedef void (*GLXSWAPBUFFERS)(Display *, GLXDrawable);
   47 
   48 typedef struct {
   49     GLXCHOOSEVISUAL ChooseVisual;
   50     GLXCREATECONTEXT CreateContext;
   51     GLXDESTROYCONTEXT DestroyContext;
   52     GLXMAKECURRENT MakeCurrent;
   53     GLXSWAPBUFFERS SwapBuffers;
   54 } GLXFUNCS;
   55 
   56 static FB_DYLIB gl_lib = NULL;
   57 static GLXFUNCS __fb_glX = { NULL, NULL, NULL, NULL, NULL };
   58 static GLXContext context;
   59 
   60 void *fb_hGL_GetProcAddress(const char *proc)
   61 {
   62     void *addr;
   63     
   64     if (fb_hDynLoadAlso(gl_lib, &proc, &addr, 1))
   65         return NULL;
   66     
   67     return addr;
   68 }
   69 
   70 static int opengl_window_init(void)
   71 {
   72     int x = 0, y = 0;
   73     int h;
   74     char *display_name;
   75     
   76     if (!(fb_x11.flags & DRIVER_FULLSCREEN)) {
   77         x = (XDisplayWidth(fb_x11.display, fb_x11.screen) - fb_x11.w) >> 1;
   78         y = (XDisplayHeight(fb_x11.display, fb_x11.screen) - fb_x11.h) >> 1;
   79     }
   80     fb_hX11InitWindow(x, y);
   81     
   82     fb_x11.display_offset = 0;
   83     if (fb_x11.flags & DRIVER_FULLSCREEN) {
   84         display_name = XDisplayName(NULL);
   85         if ((!display_name[0]) || (display_name[0] == ':') || (!strncmp(display_name, "unix:", 5))) {
   86             if (fb_hX11EnterFullscreen(&h) || (h != fb_x11.h)) {
   87                 fb_hX11LeaveFullscreen();
   88                 return -1;
   89             }
   90             XReparentWindow(fb_x11.display, fb_x11.window, fb_x11.fswindow, 0, 0);
   91             XMoveResizeWindow(fb_x11.display, fb_x11.fswindow, 0,0,fb_x11.w, fb_x11.h);
   92             XMoveResizeWindow(fb_x11.display, fb_x11.window, 0,0,fb_x11.w, fb_x11.h);
   93         }
   94         else
   95             return -1;
   96     }
   97     
   98     XSync(fb_x11.display, False);
   99     
  100     return 0;
  101 }
  102 
  103 static void opengl_window_exit(void)
  104 {
  105     if (fb_x11.flags & DRIVER_FULLSCREEN)
  106         fb_hX11LeaveFullscreen();
  107         
  108     XUnmapWindow(fb_x11.display, fb_x11.window);
  109     fb_hX11WaitUnmapped(fb_x11.window);
  110     if (fb_x11.flags & DRIVER_FULLSCREEN) {
  111         XUnmapWindow(fb_x11.display, fb_x11.fswindow);
  112         XSync(fb_x11.display, False);
  113     } else {
  114         if( !(fb_x11.flags & DRIVER_NO_FRAME) ) {
  115             XUnmapWindow(fb_x11.display, fb_x11.wmwindow);
  116             fb_hX11WaitUnmapped(fb_x11.wmwindow);
  117         }
  118     }
  119     //usleep(500);
  120     XSync(fb_x11.display, False);
  121 }
  122 
  123 static void opengl_window_idle(void)
  124 {}
  125 
  126 static void opengl_window_update(void)
  127 {
  128 
  129     static int bind=FALSE;
  130 
  131     if (!bind){
  132         __fb_glX.MakeCurrent(fb_x11.display, fb_x11.window, context);
  133         bind=TRUE;
  134     }
  135 
  136     fb_hGL_SetupProjection();
  137     __fb_glX.SwapBuffers(fb_x11.display, fb_x11.window);
  138 }
  139 
  140 static int driver_init(char *title, int w, int h, int depth, int refresh_rate, int flags)
  141 {
  142     const char *glx_funcs[] = {
  143         "glXChooseVisual", "glXCreateContext", "glXDestroyContext",
  144         "glXMakeCurrent", "glXSwapBuffers", NULL
  145     };
  146     GLXFUNCS *funcs = &__fb_glX;
  147     void **funcs_ptr = (void **)funcs;
  148     XVisualInfo *info;
  149     int attribs[64] = { GLX_RGBA, GLX_DOUBLEBUFFER, 0 }, *attrib = &attribs[2], *samples_attrib = NULL;
  150     int result;
  151     
  152     fb_hMemSet(&fb_x11, 0, sizeof(fb_x11));
  153     
  154     context = NULL;
  155     info = NULL;
  156     
  157     if (!(flags & DRIVER_OPENGL))
  158         return -1;
  159     fb_hGL_NormalizeParameters(flags);
  160     *attrib++ = GLX_RED_SIZE;
  161     *attrib++ = __fb_gl_params.color_red_bits;
  162     *attrib++ = GLX_GREEN_SIZE;
  163     *attrib++ = __fb_gl_params.color_green_bits;
  164     *attrib++ = GLX_BLUE_SIZE;
  165     *attrib++ = __fb_gl_params.color_blue_bits;
  166     *attrib++ = GLX_ALPHA_SIZE;
  167     *attrib++ = __fb_gl_params.color_alpha_bits;
  168     *attrib++ = GLX_DEPTH_SIZE;
  169     *attrib++ = __fb_gl_params.depth_bits;
  170     if (__fb_gl_params.stencil_bits > 0) {
  171         *attrib++ = GLX_STENCIL_SIZE;
  172         *attrib++ = __fb_gl_params.stencil_bits;
  173     }
  174     if (__fb_gl_params.accum_bits > 0) {
  175         *attrib++ = GLX_ACCUM_RED_SIZE;
  176         *attrib++ = __fb_gl_params.accum_red_bits;
  177         *attrib++ = GLX_ACCUM_GREEN_SIZE;
  178         *attrib++ = __fb_gl_params.accum_green_bits;
  179         *attrib++ = GLX_ACCUM_BLUE_SIZE;
  180         *attrib++ = __fb_gl_params.accum_blue_bits;
  181         *attrib++ = GLX_ACCUM_ALPHA_SIZE;
  182         *attrib++ = __fb_gl_params.accum_alpha_bits;
  183     }
  184     if (__fb_gl_params.num_samples > 0) {
  185         *attrib++ = GLX_SAMPLE_BUFFERS_ARB;
  186         *attrib++ = GL_TRUE;
  187         *attrib++ = GLX_SAMPLES_ARB;
  188         samples_attrib = attrib;
  189         *attrib++ = 4;
  190     }
  191     *attrib = None;
  192     
  193     fb_x11.init = opengl_window_init;
  194     fb_x11.exit = opengl_window_exit;
  195     fb_x11.update = opengl_window_idle;
  196     fb_hXlibInit();
  197     fb_x11.display = XOpenDisplay(NULL);
  198     if (!fb_x11.display)
  199         return -1;
  200     fb_x11.screen = XDefaultScreen(fb_x11.display);
  201     if (!gl_lib) gl_lib = fb_hDynLoad("libGL.so.1", glx_funcs, funcs_ptr);
  202 
  203     if (!gl_lib)
  204         return -1;
  205 
  206     do {
  207         if ((info = __fb_glX.ChooseVisual(fb_x11.display, fb_x11.screen, attribs))) {
  208             fb_x11.visual = info->visual;
  209             context = __fb_glX.CreateContext(fb_x11.display, info, NULL, True);
  210             if (context)
  211                 break;
  212             XFree(info);
  213             info = NULL;
  214         }
  215     } while ((samples_attrib) && ((*samples_attrib -= 2) >= 0));
  216 
  217     if (!info) {
  218         return -1;
  219     }
  220 
  221     __fb_gl_params.mode_2d = __fb_gl_params.init_mode_2d;
  222 
  223     if (__fb_gl_params.init_scale>1){
  224         __fb_gl_params.scale = __fb_gl_params.init_scale;
  225         free(__fb_gfx->dirty);
  226         __fb_gfx->dirty = (char *)calloc(1, __fb_gfx->h * __fb_gfx->scanline_size* __fb_gl_params.scale);
  227     }
  228 
  229     result = fb_hX11Init(title, w * __fb_gl_params.scale, h * __fb_gl_params.scale, info->depth, refresh_rate, flags);
  230 
  231     XFree(info);
  232     info = NULL;
  233 
  234     if (result)
  235         return result;
  236 
  237     __fb_glX.MakeCurrent(fb_x11.display, fb_x11.window, context);
  238 
  239     if (fb_hGL_Init(gl_lib, NULL))
  240         return -1;
  241 
  242     if ((samples_attrib) && (*samples_attrib > 0))
  243         __fb_gl.Enable(GL_MULTISAMPLE_ARB);
  244 
  245     if (__fb_gl_params.mode_2d != DRIVER_OGL_2D_NONE)
  246         fb_hGL_ScreenCreate();
  247 
  248     if (__fb_gl_params.mode_2d == DRIVER_OGL_2D_AUTO_SYNC){
  249         __fb_glX.MakeCurrent(fb_x11.display, None, NULL);
  250         fb_x11.update = opengl_window_update;
  251     }
  252     return 0;
  253 }
  254 
  255 static void driver_exit(void)
  256 {
  257     if (context) {
  258         __fb_glX.MakeCurrent(fb_x11.display, None, NULL);
  259         __fb_glX.DestroyContext(fb_x11.display, context);
  260         context = NULL;
  261     }
  262     fb_hX11Exit();
  263     fb_hDynUnload(&gl_lib);
  264 }
  265 
  266 static void driver_flip(void)
  267 {
  268     fb_hX11Lock();
  269     if (__fb_gl_params.mode_2d == DRIVER_OGL_2D_MANUAL_SYNC)
  270         fb_hGL_SetupProjection();
  271 
  272     __fb_glX.SwapBuffers(fb_x11.display, fb_x11.window);
  273     fb_hX11Unlock();
  274 }
  275 
  276 #endif