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 static string[] glxDefaultPaths = [
76 	"/usr/lib/libGLX.so",
77 	"/usr/lib/libGL.so",
78 	"/usr/lib/libGLX_nvidia.so"
79 ];
80 
81 /++
82     Load GLX library, which should open context in x11 environment.
83 
84     Throws: `Exception` if library is not load.
85 +/
86 void loadGLXLibrary() @trusted
87 {
88     import std.file : exists, dirEntries, SpanMode, DirEntry, isDir, isFile, write, read;
89     import std.string : toStringz;
90     import std.algorithm : reverse, canFind;
91     import std.parallelism : parallel;
92 
93     string[] pathes;
94 
95     string[] recurseFindGLX(string path)
96     {
97         import std.traits : ReturnType;
98 
99         string[] locateds;
100 
101         ReturnType!dirEntries dirs;
102 
103         try
104         {
105             dirs = dirEntries(path, SpanMode.depth);
106 
107             foreach(DirEntry e; parallel(dirs, 1))
108             {
109                 if(e.name.isDir)
110                 {
111                     if(!pathes.canFind(e.name))
112                     {
113                         locateds ~= recurseFindGLX(e.name ~ "/");
114                         pathes ~= e.name;
115                     }
116                 }
117 
118                 if(e.name.isFile)
119                 {
120                     if (e.name.canFind("libglx.so") || e.name.canFind("libGLX.so"))
121                     {
122                         locateds ~= e.name;
123                     }else
124                     if (e.name.canFind("libGL.so"))
125                     {
126                         if (!e.name.canFind("libGL.so.1.7.0"))
127                             locateds ~= e.name;
128                     }
129                 }
130             }
131         } catch (Exception e)
132         {
133             return locateds;
134         }
135 
136         return locateds;
137     }
138 
139     string[] paths;
140     
141     version (dglx_cachelib)
142     {
143     	if (exists(".dglxcachelib"))
144     	{
145     		paths ~= cast(string) read(".dglxcachelib");
146     	} else
147     	{
148 	    	paths ~= recurseFindGLX("/usr/lib/") ~ glxDefaultPaths;
149 	    	
150 	    	version(X86_64)
151 		    {
152 		        paths ~= recurseFindGLX("/usr/lib/x86_64-linux-gnu/");
153 		    }
154 		    else
155 		    version(X86)
156 		    {
157 		        paths ~= recurseFindGLX("/usr/lib/i386-linux-gnu/");
158 	    	}
159 	    }
160     } else
161     {
162     	paths ~= recurseFindGLX("/usr/lib/") ~ glxDefaultPaths;
163     	
164     	version(X86_64)
165 	    {
166 	        paths ~= recurseFindGLX("/usr/lib/x86_64-linux-gnu/");
167 	    }
168 	    else
169 	    version(X86)
170 	    {
171 	        paths ~= recurseFindGLX("/usr/lib/i386-linux-gnu/");
172     	}
173     }
174     
175     bool isSucces = false;
176     bool ErrorFind = false;
177 
178     void bindOrError(void** ptr,string name) @trusted
179     {
180         bindSymbol(glxLib, ptr, name.toStringz);
181 
182         if(*ptr is null) throw new Exception("Not load library!");
183     }
184     
185     version(dglx_cachelib)
186     {
187     	string cachelib;
188     }
189 
190     foreach(path; paths)
191     {
192         if(path.exists)
193         {
194             glxLib = load(path.toStringz);
195             if(glxLib == invalidHandle)
196             {
197                 continue;
198             }
199 
200             try
201             {
202                 bindOrError(cast(void**) &glXQueryVersion, "glXQueryVersion");
203                 bindOrError(cast(void**) &glXChooseFBConfig, "glXChooseFBConfig");
204                 bindOrError(cast(void**) &glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig");
205                 bindOrError(cast(void**) &glXGetFBConfigAttrib, "glXGetFBConfigAttrib");
206                 bindOrError(cast(void**) &glXQueryExtensionsString, "glXQueryExtensionsString");
207                 bindOrError(cast(void**) &glXCreateNewContext, "glXCreateNewContext");
208                 bindOrError(cast(void**) &glXMakeCurrent, "glXMakeCurrent");
209                 bindOrError(cast(void**) &glXDestroyContext, "glXDestroyContext");
210                 bindOrError(cast(void**) &glXSwapBuffers, "glXSwapBuffers");
211                 bindOrError(cast(void**) &glXWaitX, "glXWaitX");
212                 bindOrError(cast(void**) &glXChooseVisual, "glXChooseVisual");
213                 bindOrError(cast(void**) &glXCreateContext, "glXCreateContext");
214                 bindOrError(cast(void**) &glXIsDirect, "glXIsDirect");
215 
216                 isSucces = true;
217                 
218                 version (dglx_cachelib)
219                 {
220                 	cachelib = path;
221                 }
222                 
223             }catch(Exception e)
224             {
225                 continue;
226             }
227             break;
228         }
229     }
230     
231     version (dglx_cachelib)
232     {
233     	write (".dglxcachelib", cachelib);
234     }
235 
236     if(!isSucces)
237         throw new Exception("Library `glx` is not load!");
238 }