1 module dinu.main;
2 
3 
4 import dinu;
5 
6 
7 __gshared:
8 
9 
10 Options options;
11 
12 CommandBuilder commandBuilder;
13 
14 bool runProgram = true;
15 
16 void delegate() close;
17 
18 Display* display;
19 x11.X.Window root;
20 
21 extern(C) nothrow int function(Display *, XErrorEvent *) xerror_default;
22 extern(C) nothrow int function(Display*) xerror_fatal_default;
23 
24 shared static this(){
25     debug(XSynchronize){
26 	    XSynchronize(wm.displayHandle, true);
27     }
28     display = wm.displayHandle;
29     XSynchronize(display, true);
30 	xerror_default = XSetErrorHandler(&xerror);
31     xerror_fatal_default = XSetIOErrorHandler(&xerror_fatal);
32 	root = RootWindow(display, 0);
33 }
34 
35 
36 enum XRequestCode {
37     X_CreateWindow                   = 1,
38     X_ChangeWindowAttributes         = 2,
39     X_GetWindowAttributes            = 3,
40     X_DestroyWindow                  = 4,
41     X_DestroySubwindows              = 5,
42     X_ChangeSaveSet                  = 6,
43     X_ReparentWindow                 = 7,
44     X_MapWindow                      = 8,
45     X_MapSubwindows                  = 9,
46     X_UnmapWindow                   = 10,
47     X_UnmapSubwindows               = 11,
48     X_ConfigureWindow               = 12,
49     X_CirculateWindow               = 13,
50     X_GetGeometry                   = 14,
51     X_QueryTree                     = 15,
52     X_InternAtom                    = 16,
53     X_GetAtomName                   = 17,
54     X_ChangeProperty                = 18,
55     X_DeleteProperty                = 19,
56     X_GetProperty                   = 20,
57     X_ListProperties                = 21,
58     X_SetSelectionOwner             = 22,
59     X_GetSelectionOwner             = 23,
60     X_ConvertSelection              = 24,
61     X_SendEvent                     = 25,
62     X_GrabPointer                   = 26,
63     X_UngrabPointer                 = 27,
64     X_GrabButton                    = 28,
65     X_UngrabButton                  = 29,
66     X_ChangeActivePointerGrab       = 30,
67     X_GrabKeyboard                  = 31,
68     X_UngrabKeyboard                = 32,
69     X_GrabKey                       = 33,
70     X_UngrabKey                     = 34,
71     X_AllowEvents                   = 35,
72     X_GrabServer                    = 36,
73     X_UngrabServer                  = 37,
74     X_QueryPointer                  = 38,
75     X_GetMotionEvents               = 39,
76     X_TranslateCoords               = 40,
77     X_WarpPointer                   = 41,
78     X_SetInputFocus                 = 42,
79     X_GetInputFocus                 = 43,
80     X_QueryKeymap                   = 44,
81     X_OpenFont                      = 45,
82     X_CloseFont                     = 46,
83     X_QueryFont                     = 47,
84     X_QueryTextExtents              = 48,
85     X_ListFonts                     = 49,
86     X_ListFontsWithInfo             = 50,
87     X_SetFontPath                   = 51,
88     X_GetFontPath                   = 52,
89     X_CreatePixmap                  = 53,
90     X_FreePixmap                    = 54,
91     X_CreateGC                      = 55,
92     X_ChangeGC                      = 56,
93     X_CopyGC                        = 57,
94     X_SetDashes                     = 58,
95     X_SetClipRectangles             = 59,
96     X_FreeGC                        = 60,
97     X_ClearArea                     = 61,
98     X_CopyArea                      = 62,
99     X_CopyPlane                     = 63,
100     X_PolyPoint                     = 64,
101     X_PolyLine                      = 65,
102     X_PolySegment                   = 66,
103     X_PolyRectangle                 = 67,
104     X_PolyArc                       = 68,
105     X_FillPoly                      = 69,
106     X_PolyFillRectangle             = 70,
107     X_PolyFillArc                   = 71,
108     X_PutImage                      = 72,
109     X_GetImage                      = 73,
110     X_PolyText8                     = 74,
111     X_PolyText16                    = 75,
112     X_ImageText8                    = 76,
113     X_ImageText16                   = 77,
114     X_CreateColormap                = 78,
115     X_FreeColormap                  = 79,
116     X_CopyColormapAndFree           = 80,
117     X_InstallColormap               = 81,
118     X_UninstallColormap             = 82,
119     X_ListInstalledColormaps        = 83,
120     X_AllocColor                    = 84,
121     X_AllocNamedColor               = 85,
122     X_AllocColorCells               = 86,
123     X_AllocColorPlanes              = 87,
124     X_FreeColors                    = 88,
125     X_StoreColors                   = 89,
126     X_StoreNamedColor               = 90,
127     X_QueryColors                   = 91,
128     X_LookupColor                   = 92,
129     X_CreateCursor                  = 93,
130     X_CreateGlyphCursor             = 94,
131     X_FreeCursor                    = 95,
132     X_RecolorCursor                 = 96,
133     X_QueryBestSize                 = 97,
134     X_QueryExtension                = 98,
135     X_ListExtensions                = 99,
136     X_ChangeKeyboardMapping         = 100,
137     X_GetKeyboardMapping            = 101,
138     X_ChangeKeyboardControl         = 102,
139     X_GetKeyboardControl            = 103,
140     X_Bell                          = 104,
141     X_ChangePointerControl          = 105,
142     X_GetPointerControl             = 106,
143     X_SetScreenSaver                = 107,
144     X_GetScreenSaver                = 108,
145     X_ChangeHosts                   = 109,
146     X_ListHosts                     = 110,
147     X_SetAccessControl              = 111,
148     X_SetCloseDownMode              = 112,
149     X_KillClient                    = 113,
150     X_RotateProperties              = 114,
151     X_ForceScreenSaver              = 115,
152     X_SetPointerMapping             = 116,
153     X_GetPointerMapping             = 117,
154     X_SetModifierMapping            = 118,
155     X_GetModifierMapping            = 119,
156     X_NoOperation                   = 127
157 }
158 
159 extern(C) nothrow int xerror(Display* dpy, XErrorEvent* ee){
160 	if(ee.error_code == XErrorCode.BadWindow
161 	|| (ee.request_code == X_SetInputFocus && ee.error_code == XErrorCode.BadMatch)
162 	|| (ee.request_code == X_PolyText8 && ee.error_code == XErrorCode.BadDrawable)
163 	|| (ee.request_code == X_PolyFillRectangle && ee.error_code == XErrorCode.BadDrawable)
164 	|| (ee.request_code == X_PolySegment && ee.error_code == XErrorCode.BadDrawable)
165 	|| (ee.request_code == X_ConfigureWindow && ee.error_code == XErrorCode.BadMatch)
166 	|| (ee.request_code == X_GrabButton && ee.error_code == XErrorCode.BadAccess)
167 	|| (ee.request_code == X_GrabKey && ee.error_code == XErrorCode.BadAccess)
168 	|| (ee.request_code == X_CopyArea && ee.error_code == XErrorCode.BadDrawable))
169 		return 0;
170 	try{
171 		defaultTraceHandler.toString.writeln;
172 		"dinu: X11 error: request code=%d %s, error code=%d %s".format(
173                 ee.request_code,
174                 cast(XRequestCode)ee.request_code,
175                 ee.error_code,
176                 cast(XErrorCode)ee.error_code
177         ).writeln;
178 	}catch(Throwable) {}
179 	return xerror_default(dpy, ee); /* may call exit */
180 }
181 
182 extern(C) nothrow int xerror_fatal(Display* dpy){
183     try{
184         defaultTraceHandler.toString.writeln;
185         "dinu: X11 fatal i/o error".writeln;
186     }catch(Throwable) {}
187     return xerror_fatal_default(dpy);
188 }
189 
190 struct Options {
191 
192 	@("-h") bool help;
193 
194 	@("-x") int x;
195 	@("-y") int y;
196 	@("-w") int w;
197 	@("-s") int screen = 0;
198 	@("-l") int lines = 15;
199 	@("-fn") string font = "Monospace-10";
200 	@("-fo") string fontOutput = "Monospace-10";
201 	@("-c") string configPath = "~/.dinu/default";
202 
203 	@("-r") double ratio = 0.25;
204 
205 	@("-e") string execute;
206 
207 	@("-a") double animations = 1;
208 	@("-as") double animationMove = 1;
209 
210 	@("-f") bool flatman;
211 
212 	@("-cb") float[3] colorBg = "#222222".color;
213 	@("-ci") float[3] colorInput = "#ffffff".color;
214 	@("-cib") float[3] colorInputBg = "#454545".color;
215 	@("-co") float[3] colorOutput = "#eeeeee".color;
216 	@("-cob") float[3] colorOutputBg = "#111111".color;
217 	@("-ce") float[3] colorError = "#ff7777".color;
218 	@("-cs") float[3] colorSelected = "#005577".color;
219 	@("-ch") float[3] colorHint = "#999999".color;
220 	@("-chb") float[3] colorHintBg = "#444444".color;
221 	@("-cd") float[3] colorDir = "#bbeebb".color;
222 	@("-cf") float[3] colorFile = "#eeeeee".color;
223 	@("-ce") float[3] colorExec = "#bbbbff".color;
224 	@("-cde") float[3] colorDesktop = "#bdddff".color;
225 	@("-cde") float[3] colorWindow = "#ffdd88".color;
226 
227     @("-dd") int directoryDepth = -1;
228 
229 }
230 
231 
232 void main(string[] args){
233 	try {
234         writeln(args);
235 		options.fill(args);
236 		if(options.help){
237 			options.usage;
238 			return;
239 		}
240 		try{
241 			options.configPath = options.configPath.expandTilde;
242 			if(!options.configPath.dirName.exists)
243 				mkdirRecurse(options.configPath.dirName);
244 			if(options.configPath.exists)
245 				chdir(options.configPath.expandTilde.readText.strip);
246 		}catch(Exception e){
247 			writeln(e);
248 		}
249 		windowLoop;
250 	}catch(Throwable t){
251 		writeln(t);
252 	}
253 }
254 
255 void windowLoop(){
256 	commandBuilder = new CommandBuilder;
257 
258 	auto windowMain = new WindowMain;
259     wm.add(windowMain);
260     windowMain.show;
261 	windowMain.draw;
262 
263 	auto windowResults = new ResultWindow;
264     wm.add(windowResults);
265 	windowMain.resultWindow = windowResults;
266 
267 	close = {
268         windowMain.close;
269         windowResults.close;
270 		runProgram = false;
271 	};
272 
273 	if(options.execute.length){
274 		commandBuilder.text = options.execute.to!dstring;
275 		commandBuilder.run;
276 	}
277 
278 	scope(exit)
279 		close();
280 
281 	long last = (now*1000).lround;
282 	while(wm.hasActiveWindows){
283         wm.processEvents;
284         if(windowMain.isActive){
285             windowMain.update;
286             windowMain.onDraw;
287             if(windowResults.isActive){
288                 windowResults.update(windowMain);
289                 windowResults.onDraw;
290             }
291         }
292 		auto curr = (now*1000).lround;
293 		last = curr;
294 		Thread.sleep((15 - max(0, min(15, curr-last))).msecs);
295 	}
296 }
297 
298 
299