1 /** 2 * TODO 3 */ 4 module dash.graphics.adapters.linux; 5 6 version( linux ): 7 8 import dash.core, dash.graphics, dash.utility; 9 10 import x11.X, x11.Xlib, x11.Xutil; 11 public import derelict.opengl3.glx; 12 import derelict.opengl3.gl3, derelict.opengl3.glxext; 13 14 import std.traits; 15 16 /** 17 * TODO 18 */ 19 final class Linux : OpenGL 20 { 21 private: 22 // Because the XVisualStyle type returned from this function is 23 // seemingly not defined, we can get it with templates. 24 alias PointerTarget!(ReturnType!(glXChooseVisual)) GLXVisualInfo; 25 26 /// Events we want to listen for 27 enum EventMask = ExposureMask | KeyPressMask; 28 29 /// The display to render to. 30 Display* display; 31 Window root; 32 Window window; 33 GLXContext context; 34 XSetWindowAttributes windowAttributes; 35 XVisualInfo* xvi; 36 GLXVisualInfo* glvi; 37 Colormap cmap; 38 39 public: 40 41 /// TODO 42 static @property Linux get() { return cast(Linux)Graphics.adapter; } 43 44 /** 45 * TODO 46 */ 47 override void initialize() 48 { 49 // Load opengl functions 50 DerelictGL3.load(); 51 52 int[ 10 ] attrList = 53 [ 54 GLX_RGBA, 55 GLX_RED_SIZE, 4, 56 GLX_GREEN_SIZE, 4, 57 GLX_BLUE_SIZE, 4, 58 GLX_DEPTH_SIZE, 16, 59 None 60 ]; 61 62 int screen; 63 64 // Get display and screen 65 display = XOpenDisplay( null ); 66 screen = DefaultScreen( display ); 67 68 // Setup the window 69 screenWidth = DisplayWidth( display, screen ); 70 screenHeight = DisplayHeight( display, screen ); 71 72 loadProperties(); 73 74 if( display is null ) 75 { 76 logFatal( "Cannot connect to X server." ); 77 return; 78 } 79 80 // Get root monitor window 81 root = DefaultRootWindow( display ); 82 83 // Chose visual based on attributes and display 84 glvi = glXChooseVisual( display, 0, attrList.ptr ); 85 xvi = cast(XVisualInfo*)glvi; 86 87 if( xvi is null ) 88 { 89 logFatal( "No appropriate visual found." ); 90 return; 91 } 92 93 cmap = XCreateColormap( display, root, xvi.visual, AllocNone ); 94 95 // Set attributes for window 96 windowAttributes.colormap = cmap; 97 windowAttributes.event_mask = EventMask; 98 99 openWindow(); 100 101 // Get address of gl functions 102 DerelictGL3.reload(); 103 } 104 105 /** 106 * TODO 107 */ 108 override void shutdown() 109 { 110 closeWindow(); 111 XCloseDisplay( display ); 112 } 113 114 /** 115 * TODO 116 */ 117 override void resize() 118 { 119 XResizeWindow( display, window, width, height ); 120 glViewport( 0, 0, width, height ); 121 } 122 123 /** 124 * TODO 125 */ 126 override void refresh() 127 { 128 resize(); 129 130 // Enable back face culling 131 if( backfaceCulling ) 132 { 133 glEnable( GL_CULL_FACE ); 134 glCullFace( GL_BACK ); 135 } 136 137 // Turn on of off the v sync 138 glXSwapIntervalEXT( display, glXGetCurrentDrawable(), vsync ); 139 } 140 141 /** 142 * TODO 143 */ 144 override void swapBuffers() 145 { 146 glXSwapBuffers( display, cast(uint)window ); 147 } 148 149 /** 150 * TODO 151 */ 152 override void openWindow() 153 { 154 window = XCreateWindow( 155 display, root, 156 0, 0, width, height, 0, 157 xvi.depth, InputOutput, xvi.visual, 158 CWColormap | CWEventMask, &windowAttributes ); 159 160 XMapWindow( display, window ); 161 XStoreName( display, window, DGame.instance.title.dup.ptr ); 162 163 context = glXCreateContext( display, glvi, null, GL_TRUE ); 164 glXMakeCurrent( display, cast(uint)window, context ); 165 } 166 167 /** 168 * TODO 169 */ 170 override void closeWindow() 171 { 172 glXMakeCurrent( display, None, null ); 173 glXDestroyContext( display, context ); 174 XDestroyWindow( display, window ); 175 } 176 177 /** 178 * TODO 179 */ 180 override void messageLoop() 181 { 182 XEvent event; 183 while( XCheckWindowEvent( display, window, EventMask, &event ) ) 184 { 185 switch( event.type ) 186 { 187 case KeyPress: 188 break; 189 case Expose: 190 break; 191 default: 192 break; 193 } 194 } 195 } 196 }