1 module ws.wm.x11.wm;
2 
3 version(Posix):
4 
5 import
6 	std.stdio,
7 	derelict.opengl3.gl,
8 	ws.wm,
9 	ws.wm.baseWindowManager,
10 	ws.wm.x11.api,
11 	ws.wm.x11.window,
12 	ws.list,
13 	ws.wm.baseWindowManager;
14 
15 
16 __gshared:
17 
18 
19 struct EventMaskMapping {
20 	int mask;
21 	int type;
22 }
23 
24 enum eventMaskMap = [
25 	EventMaskMapping(ExposureMask, Expose),
26 	EventMaskMapping(EnterWindowMask, EnterNotify),
27 	EventMaskMapping(LeaveWindowMask, LeaveNotify),
28 	EventMaskMapping(ButtonPressMask, ButtonPress),
29 	EventMaskMapping(ButtonReleaseMask, ButtonRelease),
30 	EventMaskMapping(PointerMotionMask, MotionNotify)
31 ];
32 
33 class X11WindowManager: BaseWindowManager {
34 
35 	this(){
36 		XInitThreads();
37 		super();
38 		DerelictGL3.load();
39 		displayHandle = XOpenDisplay(null);
40 		debug {
41 			XSynchronize(displayHandle, true);
42 		}
43 		glCore = true;
44 		//load!("glXCreateContextAttribsARB");
45 		if(!glXCreateContextAttribsARB)
46 			glCore = false;
47 		/*if(glCore){
48 			// Initialize
49 			int configCount = 0;
50 			int fbAttribs[] = [
51 				GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
52 				GLX_X_RENDERABLE, True,
53 				GLX_RENDER_TYPE, GLX_RGBA_BIT,
54 				GLX_RED_SIZE, 8,
55 				GLX_BLUE_SIZE, 8,
56 				GLX_GREEN_SIZE, 8,
57 				GLX_DEPTH_SIZE, 16,
58 				GLX_STENCIL_SIZE, 8,
59 				GLX_DOUBLEBUFFER, True,
60 				GLX_SAMPLE_BUFFERS, True,
61 				GLX_SAMPLES, 2,
62 				0
63 			];
64 			GLXFBConfig* mFBConfig = glXChooseFBConfig(displayHandle, DefaultScreen(*displayHandle), fbAttribs.ptr, &configCount);
65 			if(!configCount)
66 				throw new Exception("osWindow Initialisation: Failed to get frame buffer configuration. Are your drivers up to date?");
67 			graphicsInfo = cast(XVisualInfo*)glXGetVisualFromFBConfig(displayHandle, mFBConfig[0]);
68 		}else{*/{
69 
70 			if(true){
71 				GLint[] att = [GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_ALPHA_SIZE, 8, GLX_DOUBLEBUFFER, 0];
72 				graphicsInfo = cast(XVisualInfo*)glXChooseVisual(displayHandle, 0, att.ptr);
73 			}else{
74 				graphicsInfo = new XVisualInfo;
75 				if(!XMatchVisualInfo(displayHandle, DefaultScreen(displayHandle), 32, TrueColor, graphicsInfo))
76 					writeln("XMatchVisualInfo failed");
77 			}
78 			if(!graphicsInfo)
79 				writeln("glXChooseVisual failed");
80 		}
81 	}
82 
83 	Display* displayHandle;
84 	XVisualInfo* graphicsInfo;
85 	bool glCore;
86 	GLXFBConfig* mFBConfig;
87 	T_glXCreateContextAttribsARB glXCreateContextAttribsARB;
88 
89 	void delegate(XEvent*)[][int][x11.X.Window] handler;
90 	void delegate(XEvent*)[][int] handlerAll;
91 
92 	void on(void delegate(XEvent*)[int] handlers){
93 		foreach(ev, dg; handlers){
94 			handlerAll[ev] ~= dg;
95 		}
96 	}
97 
98 	void on(x11.X.Window window, void delegate(XEvent*)[int] handlers){
99 		int mask;
100 		foreach(ev, dg; handlers){
101 			foreach(mapping; eventMaskMap){
102 				if(mapping.type == ev)
103 					mask |= mapping.mask;
104 			}
105 			handler[window][ev] ~= dg;
106 		}
107 		//XSelectInput(displayHandle, window, mask);
108 	}
109 
110 	~this(){
111 		XCloseDisplay(displayHandle);
112 	}
113 
114 	void processEvents(){
115 		while(XPending(wm.displayHandle)){
116 			XEvent e;
117 			XNextEvent(wm.displayHandle, &e);
118 			foreach(win; wm.windows){
119 				if(e.xany.window == win.windowHandle){
120 					activeWindow = win;
121 					win.gcActivate;
122 					win.processEvent(&e);
123 				}
124 			}
125 			if(e.type in handlerAll)
126 				foreach(handler; handlerAll[e.type])
127 					handler(&e);
128 			if(e.xany.window in handler){
129 				auto handlerWindow = handler[e.xany.window];
130 				if(e.type in handlerWindow)
131 					foreach(handlerWindowType; handlerWindow[e.type])
132 						handlerWindowType(&e);
133 			}
134 		}
135 	}
136 
137 }