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