1 module dglx.glx;
2 
3 version(Posix):
4 version(Dynamic_GLX):
5 
6 import bindbc.loader;
7 import x11.X, x11.Xlib, x11.Xutil;
8 
9 alias GLXLibrary = SharedLib;
10 
11 __gshared GLXLibrary glxLib;
12 
13 struct __GLXFBConfigRec;
14 struct __GLXcontextRec;
15 
16 static immutable GLX_X_RENDERABLE = 0x8012;
17 static immutable GLX_DRAWABLE_TYPE = 0x8010;
18 static immutable GLX_RENDER_TYPE = 0x8011;
19 static immutable GLX_X_VISUAL_TYPE = 0x22;
20 static immutable GLX_RED_SIZE = 8;
21 static immutable GLX_GREEN_SIZE = 9;
22 static immutable GLX_BLUE_SIZE = 10;
23 static immutable GLX_ALPHA_SIZE = 11;
24 static immutable GLX_DEPTH_SIZE = 12;
25 static immutable GLX_STENCIL_SIZE = 13;
26 static immutable GLX_DOUBLEBUFFER = 5;
27 static immutable GLX_BUFFER_SIZE = 2;
28 static immutable GLX_RGBA = 4;
29 
30 static immutable GLX_WINDOW_BIT = 0x00000001;
31 static immutable GLX_RGBA_BIT = 0x00000001;
32 static immutable GLX_TRUE_COLOR = 0x8002;
33 static immutable GLX_RGBA_TYPE = 0x8014;
34 
35 static immutable GLX_SAMPLE_BUFFERS = 0x186a0;
36 static immutable GLX_SAMPLES = 0x186a1;
37 
38 alias GLXDrawable = ulong;
39 alias GLXFBConfig = __GLXFBConfigRec*;
40 alias GLXContext = __GLXcontextRec*;
41 
42 alias FglXQueryVersion = extern(C) bool function(Display *dpy,int *maj,int *min);
43 alias FglXChooseFBConfig = extern(C) GLXFBConfig* function(Display *dpy,int screen,const int *attribList, int *nitems);;
44 alias FglXGetVisualFromFBConfig = extern(C) XVisualInfo* function(Display *dpy, GLXFBConfig config);;
45 alias FglXGetFBConfigAttrib = extern(C) int function(Display *dpy, GLXFBConfig config,  int attribute, int *value);
46 alias FglXQueryExtensionsString = extern(C) const(char*) function(Display *dpy, int screen);
47 alias FglXCreateNewContext = extern(C) GLXContext function(Display *dpy, GLXFBConfig config,int renderType, 
48                                                  GLXContext shareList, bool direct);
49 
50 alias FglXMakeCurrent = extern(C) bool function(Display *dpy,GLXDrawable drawable, GLXContext ctx);
51 alias FglXDestroyContext = extern(C) void function(Display *dpy, GLXContext ctx);
52 alias FglXSwapBuffers = extern(C) void function(Display *dpy, GLXDrawable drawable);
53 alias FglXWaitX = extern(C) void function();
54 alias FglXChooseVisual = extern(C) XVisualInfo* function(Display *dpy,int ds,int* attribs);;
55 alias FglXCreateContext = extern(C) GLXContext function(Display *dpy,XVisualInfo* vis,GLXContext shareList,bool direct);
56 alias FglXIsDirect = extern(C) bool function(Display *dpy,GLXContext context);
57 
58 __gshared
59 {
60     FglXQueryVersion glXQueryVersion;
61     FglXChooseFBConfig glXChooseFBConfig;
62     FglXGetVisualFromFBConfig glXGetVisualFromFBConfig;
63     FglXGetFBConfigAttrib glXGetFBConfigAttrib;
64     FglXQueryExtensionsString glXQueryExtensionsString;
65     FglXCreateNewContext glXCreateNewContext;
66     FglXMakeCurrent glXMakeCurrent;
67     FglXDestroyContext glXDestroyContext;
68     FglXSwapBuffers glXSwapBuffers;
69     FglXWaitX glXWaitX;
70     FglXChooseVisual glXChooseVisual;
71     FglXCreateContext glXCreateContext;
72     FglXIsDirect glXIsDirect;
73 }
74 
75 /++
76     Load GLX library, which should open context in x11 environment.
77 
78     Throws: `Exception` if library is not load.
79 +/
80 void loadGLXLibrary() @trusted
81 {
82     import std.file : exists, dirEntries, SpanMode, DirEntry, isDir, isFile;
83     import std..string : toStringz;
84     import std.algorithm : reverse, canFind;
85     import std.parallelism : parallel;
86 
87     string[] pathes;
88 
89     string[] recurseFindGLX(string path)
90     {
91         string[] locateds;
92 
93         try
94         {
95             auto dirs = dirEntries(path, SpanMode.depth);
96 
97             foreach(DirEntry e; parallel(dirs, 1))
98             {
99                 if(e.name.isDir) {
100                     if(!pathes.canFind(e.name)) {
101                         locateds ~= recurseFindGLX(e.name ~ "/");
102                         pathes ~= e.name;
103                     }
104                 }
105 
106                 if(e.name.isFile)
107                 {
108                     if(e.name.canFind("libglx.so")) {
109                         locateds ~= e.name;
110                     }
111 
112                     if(e.name.canFind("libGL.so")) {
113                         locateds ~= e.name;
114                     }
115                 }
116             }
117         }catch(Exception e) {}
118 
119         return locateds;
120     }
121 
122     string[] paths = recurseFindGLX("/usr/lib/");
123 
124     bool isSucces = false;
125     bool ErrorFind = false;
126 
127     void bindOrError(void** ptr,string name) @trusted
128     {
129         bindSymbol(glxLib, ptr, name.toStringz);
130 
131         if(*ptr is null) throw new Exception("Not load library!");
132     }
133 
134     foreach(path; paths)
135     {
136         if(path.exists)
137         {
138             glxLib = load(path.toStringz);
139             if(glxLib == invalidHandle) {
140                 continue;
141             }
142 
143             try
144             {
145                 bindOrError(cast(void**) &glXQueryVersion, "glXQueryVersion");
146                 bindOrError(cast(void**) &glXChooseFBConfig, "glXChooseFBConfig");
147                 bindOrError(cast(void**) &glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig");
148                 bindOrError(cast(void**) &glXGetFBConfigAttrib, "glXGetFBConfigAttrib");
149                 bindOrError(cast(void**) &glXQueryExtensionsString, "glXQueryExtensionsString");
150                 bindOrError(cast(void**) &glXCreateNewContext, "glXCreateNewContext");
151                 bindOrError(cast(void**) &glXMakeCurrent, "glXMakeCurrent");
152                 bindOrError(cast(void**) &glXDestroyContext, "glXDestroyContext");
153                 bindOrError(cast(void**) &glXSwapBuffers, "glXSwapBuffers");
154                 bindOrError(cast(void**) &glXWaitX, "glXWaitX");
155                 bindOrError(cast(void**) &glXChooseVisual, "glXChooseVisual");
156                 bindOrError(cast(void**) &glXCreateContext, "glXCreateContext");
157                 bindOrError(cast(void**) &glXIsDirect, "glXIsDirect");
158 
159                 isSucces = true;
160             }catch(Exception e)
161             {
162                 continue;
163             }
164             break;
165         }
166     }
167 
168     if(!isSucces)
169         throw new Exception("Library `glx` is not load!");
170 }