PageRenderTime 63ms CodeModel.GetById 1ms app.highlight 57ms RepoModel.GetById 1ms app.codeStats 0ms

/platform/unix/scaffold/window.d

http://github.com/wilkie/djehuty
D | 382 lines | 222 code | 93 blank | 67 comment | 22 complexity | 6d41d84df9a8e74feef4c6029e31ad83 MD5 | raw file
  1/*
  2 * window.d
  3 *
  4 * This Scaffold holds the Window implementations for the Linux platform
  5 *
  6 * Author: Dave Wilkinson
  7 *
  8 */
  9
 10module scaffold.window;
 11
 12import platform.vars.window;
 13import platform.vars.view;
 14import platform.vars.brush;
 15import platform.vars.pen;
 16
 17import scaffold.graphics;
 18
 19import platform.unix.common;
 20import platform.unix.main;
 21
 22import graphics.view;
 23import graphics.graphics;
 24
 25import core.color;
 26import core.string;
 27import core.main;
 28import core.definitions;
 29
 30import io.file;
 31
 32import gui.application;
 33import gui.window;
 34
 35import io.console;
 36
 37struct MWMHints {
 38	Clong flags;
 39	Clong functions;
 40	Clong decorations;
 41	Clong input_mode;
 42	Clong status;
 43}
 44
 45const int PROP_MWM_HINTS_ELEMENTS = 5;
 46
 47const int MWM_HINTS_FUNCTIONS   = 1;
 48const int MWM_HINTS_DECORATIONS = 2;
 49const int MWM_HINTS_INPUT_MODE  = 4;
 50const int MWM_HINTS_STATUS      = 8;
 51
 52	/* functions */
 53const int MWM_FUNC_ALL          = 1;
 54const int MWM_FUNC_RESIZE       = 2;
 55const int MWM_FUNC_MOVE         = 4;
 56const int MWM_FUNC_MINIMIZE     = 8;
 57const int MWM_FUNC_MAXIMIZE     = 16;
 58const int MWM_FUNC_CLOSE        = 32;
 59
 60	/* decorations */
 61const int MWM_DECOR_ALL         = 1;
 62const int MWM_DECOR_BORDER      = 2;
 63const int MWM_DECOR_RESIZEH     = 4;
 64const int MWM_DECOR_TITLE       = 8;
 65const int MWM_DECOR_MENU        = 16;
 66const int MWM_DECOR_MINIMIZE    = 32;
 67const int MWM_DECOR_MAXIMIZE    = 64;
 68
 69
 70
 71const int USPosition    = 1;          /* user specified x, y */
 72const int USSize        = 2;          /* user specified width, height
 73                                           */
 74const int PPosition     = 4;          /* program specified position
 75                                           */
 76const int PSize         = 8;          /* program specified size */
 77const int PMinSize      = 16;          /* program specified minimum
 78                                           size */
 79
 80const int PMaxSize      = 32;          /* program specified maximum
 81                                           size */
 82const int PResizeInc    = 64;          /* program specified Size
 83                                           increments */
 84const int PAspect       = 128;          /* program specified min and
 85                                           max aspect ratios */
 86const int PBaseSize     = 256;
 87const int PWinGravity   = 512;
 88
 89const int PAllHints     = (PPosition|PSize|
 90                        PMinSize|PMaxSize|
 91                        PResizeInc|PAspect);
 92
 93
 94
 95
 96// all windows
 97void WindowCreate(ref Window window, WindowPlatformVars* windowVars) {
 98	// code to create the window
 99	windowVars.destroy_called = false;
100
101	X.XSetWindowAttributes attributes;
102
103	if (window.style == WindowStyle.Popup) {
104		attributes.override_redirect = X.Bool.True;
105	}
106
107	attributes.event_mask =	X.EventMask.ExposureMask | X.EventMask.ButtonPressMask | X.EventMask.KeyPressMask |
108		X.EventMask.ButtonReleaseMask | X.EventMask.PointerMotionMask | X.EventMask.KeyReleaseMask | X.EventMask.StructureNotifyMask |
109		X.EventMask.EnterWindowMask | X.EventMask.LeaveWindowMask | X.EventMask.FocusChangeMask;
110	attributes.win_gravity = X.BitGravity.StaticGravity;
111
112	X.Window parent = X.XRootWindow(_pfvars.display, _pfvars.screen);
113
114	uint w_x = window.x;
115	uint w_y = window.y;
116
117	if (window.position == WindowPosition.Center) {
118		// Get the display width and height and center the window
119		uint d_width = X.XDisplayWidth(_pfvars.display, _pfvars.screen);
120		uint d_height = X.XDisplayHeight(_pfvars.display, _pfvars.screen);
121
122		w_x = d_width - window.width;
123		w_x >>= 1;
124
125		w_y = d_height - window.height;
126		w_y >>= 1;
127
128	}
129
130	windowVars.window = X.XCreateWindow(_pfvars.display,
131		parent, w_x,w_y,window.width,window.height,0,
132		X.CopyFromParent,
133		X.WindowClass.InputOutput,
134		cast(X.Visual*)X.CopyFromParent,
135		X.WindowAttribute.CWOverrideRedirect | X.WindowAttribute.CWEventMask | X.WindowAttribute.CWWinGravity,
136		&attributes);
137
138	X.Window root;
139	X.Window* children;
140	uint childrenCount;
141	X.Window last = windowVars.window;
142
143	X.Status r = X.XSetWMProtocols(_pfvars.display, windowVars.window, &_pfvars.wm_destroy_window, 1);
144
145	WindowRebound(window, windowVars);
146
147	WindowSetTitle(window, windowVars);
148
149	if (window.visible) {
150		WindowSetVisible(window, windowVars, true);
151	}
152
153//	int x_return, y_return, width_return, height_return, grav_return;
154//	X.XSizeHints hints;
155//	X.XWMGeometry(_pfvars.display, _pfvars.screen, null, null, &hints, &x_return, &y_return, &width_return, &height_return, &grav_return);
156	if (window.position != WindowPosition.Default) {
157		X.XMoveWindow(_pfvars.display, windowVars.window, w_x, w_y);
158	}
159//	X.XMoveWindow(_pfvars.display, windowVars.wm_parent, window.x, window.y);
160
161	// Create View
162	window.onInitialize();
163
164	// Run Add
165	window.onAdd();
166}
167
168void WindowCreate(ref Window parent, WindowPlatformVars* parentHelper, ref Window window, WindowPlatformVars* windowVars) {
169	// code to create a child window
170	//int screen;
171
172	WindowCreate(window, windowVars);
173	return;
174}
175
176void WindowSetStyle(ref Window window, WindowPlatformVars* windowVars) {
177	// code to change the style of a window
178}
179
180void WindowReposition(ref Window window, WindowPlatformVars* windowVars) {
181	// code to move a window
182	X.Window wind = windowVars.window;
183	if (windowVars.wm_parent != 0) {
184		wind = windowVars.wm_parent;
185	}
186	X.XMoveWindow(_pfvars.display, wind, window.x, window.y);
187}
188
189void WindowSetState(ref Window window, WindowPlatformVars* windowVars) {
190	// code to change the state of a window
191}
192
193void WindowRebound(ref Window window, WindowPlatformVars* windowVars) {
194	// code to Size a window
195	int width, height;
196	width = window.width;
197	height = window.height;
198
199	MWMHints mwmhints;
200
201	X.XSizeHints* xhints;
202
203	X.Atom wm_normal_hints = X.XInternAtom(_pfvars.display, "WM_NORMAL_HINTS\0"c.ptr, X.Bool.True);
204	if (window.style == WindowStyle.Popup) {
205
206		X.Atom prop = X.XInternAtom(_pfvars.display, "_MOTIF_WM_HINTS\0"c.ptr, X.Bool.True);
207		if (prop != X.None) {
208			//set with MWM
209			mwmhints.flags = MWM_HINTS_DECORATIONS;
210			mwmhints.functions = MWM_FUNC_MOVE;
211			mwmhints.decorations = 0;
212
213			X.XChangeProperty(_pfvars.display, windowVars.window, prop, prop, 32, X.PropertyMode.PropModeReplace,
214                    cast(ubyte*)&mwmhints, PROP_MWM_HINTS_ELEMENTS);
215		}
216
217		//set with WM_NORMAL_HINTS (disable Size function)
218		xhints = X.XAllocSizeHints();
219
220		xhints.flags = PMinSize | PMaxSize | PResizeInc;
221		xhints.width_inc = 0;
222		xhints.height_inc = 0;
223		xhints.max_width = xhints.min_width = width;
224		xhints.max_height = xhints.min_height = height;
225
226		X.XSetWMNormalHints(_pfvars.display, windowVars.window, xhints);
227
228		X.XFree(xhints);
229
230	}
231	else if (window.style == WindowStyle.Fixed) {
232		X.Atom prop = X.XInternAtom(_pfvars.display, "_MOTIF_WM_HINTS\0"c.ptr, X.Bool.True);
233
234		if (prop != X.None) {
235			//set with MWM
236			mwmhints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
237			mwmhints.functions = MWM_FUNC_MINIMIZE | MWM_FUNC_CLOSE | MWM_FUNC_MOVE;
238			mwmhints.decorations = MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MAXIMIZE;
239
240			X.XChangeProperty(_pfvars.display, windowVars.window, prop, prop, 32, X.PropertyMode.PropModeReplace,
241                    cast(ubyte*)&mwmhints, PROP_MWM_HINTS_ELEMENTS);
242		}
243
244		//set with WM_NORMAL_HINTS (disable Size function)
245		xhints = X.XAllocSizeHints();
246
247		xhints.flags = PMinSize | PMaxSize | PResizeInc;
248		xhints.width_inc = 0;
249		xhints.height_inc = 0;
250		xhints.max_width = xhints.min_width = width;
251		xhints.max_height = xhints.min_height = height;
252
253		X.XSetWMNormalHints(_pfvars.display, windowVars.window, xhints);
254
255		X.XFree(xhints);
256
257	}
258}
259
260void WindowDestroy(ref Window window, WindowPlatformVars* windowVars) {
261	// code to destroy a window
262	windowVars.destroy_called = true;
263
264	//destroy window
265	X.XDestroyWindow(_pfvars.display, windowVars.window);
266}
267
268void WindowSetVisible(ref Window window, WindowPlatformVars* windowVars, bool bShow) {
269	// code to show or hide a window
270	if (bShow) {
271		X.XMapWindow(_pfvars.display, windowVars.window);
272	}
273	else {
274		X.XUnmapWindow(_pfvars.display, windowVars.window);
275	}
276}
277
278void WindowSetTitle(ref Window window, WindowPlatformVars* windowVars) {
279	// code to change a window's title
280
281	//Set the window's text
282
283	//Fill in a text property
284
285	string str = window.text.dup;
286	str ~= '\0';
287
288	// Alternative Syntax:
289
290	/*
291
292	X.XTextProperty tprop;
293
294	tprop.value = str.ptr;
295	tprop.encoding = _pfvars.utf8string;
296	tprop.format = 8;
297	tprop.nitems = str.array.length-1;
298
299	X.XSetTextProperty(_pfvars.display, windowVars.window, &tprop, _pfvars.wm_name);
300
301	*/
302
303	// Update the Property:
304
305	X.XChangeProperty(_pfvars.display, windowVars.window,
306			X.XInternAtom(_pfvars.display, "_NET_WM_NAME", X.Bool.False),
307			X.XInternAtom(_pfvars.display, "UTF8_STRING", X.Bool.False),
308			8, X.PropertyMode.PropModeReplace, cast(ubyte*)str.ptr, str.length-1);
309
310	X.XChangeProperty(_pfvars.display, windowVars.window,
311			X.XInternAtom(_pfvars.display, "_NET_WM_ICON_NAME", X.Bool.False),
312			X.XInternAtom(_pfvars.display, "UTF8_STRING", X.Bool.False),
313			8, X.PropertyMode.PropModeReplace, cast(ubyte*)str.ptr, str.length-1);
314
315}
316
317// CLIENT TO SCREEN
318
319// Takes a point on the window's client area and returns the actual screen
320// coordinates for that point.
321
322void WindowClientToScreen(ref Window window, WindowPlatformVars* windowVars, ref int x, ref int y) {
323	//Coord pt = {x,y};
324	//ClientToScreen(windowVars.hWnd, &pt);
325	Window wret;
326
327	X.XTranslateCoordinates(_pfvars.display, windowVars.window,
328		X.RootWindow(_pfvars.display, _pfvars.screen), x,y, &x, &y,cast(Culong*)&wret);
329}
330
331void WindowClientToScreen(ref Window window, WindowPlatformVars* windowVars, ref Coord pt) {
332	//ClientToScreen(windowVars.hWnd, &pt);
333	Window wret;
334
335	X.XTranslateCoordinates(_pfvars.display, windowVars.window,
336		X.RootWindow(_pfvars.display, _pfvars.screen), pt.x, pt.y, &pt.x, &pt.y, cast(Culong*)&wret);
337}
338
339void WindowClientToScreen(ref Window window, WindowPlatformVars* windowVars, ref Rect rt) {
340}
341
342
343// Viewable windows
344void WindowStartDraw(ref Window window, WindowPlatformVars* windowVars, ref WindowView view, ref ViewPlatformVars viewVars) {
345	X.XLockDisplay(_pfvars.display);
346	// code executed at the start of a redraw for a window
347	viewVars.textclr_red = 0.0;
348	viewVars.textclr_green = 0.0;
349	viewVars.textclr_blue = 0.0;
350	viewVars.textclr_alpha = 1.0;
351
352	viewVars.isOpaqueRendering = 0;
353
354	Cairo.cairo_new_path(viewVars.cr);
355	Cairo.cairo_identity_matrix(viewVars.cr);
356	if (viewVars.aa) {
357		Cairo.cairo_set_antialias(viewVars.cr, Cairo.cairo_antialias_t.CAIRO_ANTIALIAS_DEFAULT);
358	}
359	else {
360		Cairo.cairo_set_antialias(viewVars.cr, Cairo.cairo_antialias_t.CAIRO_ANTIALIAS_NONE);
361	}
362}
363
364void WindowEndDraw(ref Window window, WindowPlatformVars* windowVars, ref WindowView view, ref ViewPlatformVars viewVars) {
365	// code to reclaim resources, and executed after all components have drawn to the window
366
367	//copy over area
368	X.XFlush(_pfvars.display);
369
370	X.XCopyArea(_pfvars.display, viewVars.pixmap,
371		windowVars.window, viewVars.gc,
372		0, 0, window.width, window.height, 0, 0);
373	X.XUnlockDisplay(_pfvars.display);
374}
375
376void WindowCaptureMouse(ref Window window, WindowPlatformVars* windowVars) {
377	// capture the mouse
378}
379
380void WindowReleaseMouse(ref Window window, WindowPlatformVars* windowVars) {
381	// release the mouse
382}