2ac1ab721b4ab837705a66aaa5522601f985aa2b
[xscreensaver] / hacks / bsod.c
1 /* xscreensaver, Copyright (c) 1998-2002 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  *
11  * Blue Screen of Death: the finest in personal computer emulation.
12  * Concept cribbed from Stephen Martin <smartin@mks.com>;
13  * this version written by jwz, 4-Jun-98.
14  */
15
16 #include "screenhack.h"
17 #include "xpm-pixmap.h"
18 #include <stdio.h>
19 #include <time.h>
20 #include <sys/time.h>
21 #include <X11/Xutil.h>
22
23 #ifdef HAVE_UNAME
24 # include <sys/utsname.h>
25 #endif /* HAVE_UNAME */
26
27 #include "images/amiga.xpm"
28 #include "images/atari.xbm"
29 #include "images/mac.xbm"
30 #include "images/macbomb.xbm"
31 #include "images/hmac.xpm"
32
33
34 static int
35 draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
36              XFontStruct *font,
37              int xoff, int yoff,
38              int win_width, int win_height,
39              const char *string, int delay)
40 {
41   int x, y;
42   int width = 0, height = 0, cw = 0;
43   int char_width, line_height;
44
45   const char *s = string;
46   const char *se = string;
47
48   /* This pretty much assumes fixed-width fonts */
49   char_width = (font->per_char
50                 ? font->per_char['n'-font->min_char_or_byte2].width
51                 : font->min_bounds.width);
52   line_height = font->ascent + font->descent + 1;
53
54   while (1)
55     {
56       if (*s == '\n' || !*s)
57         {
58           height++;
59           if (cw > width) width = cw;
60           cw = 0;
61           if (!*s) break;
62         }
63       else
64         cw++;
65       s++;
66     }
67
68   x = (win_width - (width * char_width)) / 2;
69   y = (win_height - (height * line_height)) / 2;
70
71   if (x < 0) x = 2;
72   if (y < 0) y = 2;
73
74   x += xoff;
75   y += yoff;
76
77   se = s = string;
78   while (1)
79     {
80       if (*s == '\n' || !*s)
81         {
82           int off = 0;
83           Bool flip = False;
84
85           if (*se == '@' || *se == '_')
86             {
87               if (*se == '@') flip = True;
88               se++;
89               off = (char_width * (width - (s - se))) / 2;
90             }
91
92           if (flip)
93             {
94               XSetForeground(dpy, gc, gcv->background);
95               XSetBackground(dpy, gc, gcv->foreground);
96             }
97
98           if (s != se)
99             XDrawImageString(dpy, window, gc, x+off, y+font->ascent, se, s-se);
100
101           if (flip)
102             {
103               XSetForeground(dpy, gc, gcv->foreground);
104               XSetBackground(dpy, gc, gcv->background);
105             }
106
107           se = s;
108           y += line_height;
109           if (!*s) break;
110           se = s+1;
111
112           if (delay)
113             {
114               XSync(dpy, False);
115               usleep(delay);
116             }
117         }
118       s++;
119     }
120
121   return width * char_width;
122 }
123
124
125 static Pixmap
126 double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
127              int pix_w, int pix_h)
128 {
129   int x, y;
130   Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth);
131   XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap);
132   XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0,
133                             pix_w*2, pix_h*2, 8, 0);
134   i2->data = (char *) calloc(i2->height, i2->bytes_per_line);
135   for (y = 0; y < pix_h; y++)
136     for (x = 0; x < pix_w; x++)
137       {
138         unsigned long p = XGetPixel(i1, x, y);
139         XPutPixel(i2, x*2,   y*2,   p);
140         XPutPixel(i2, x*2+1, y*2,   p);
141         XPutPixel(i2, x*2,   y*2+1, p);
142         XPutPixel(i2, x*2+1, y*2+1, p);
143       }
144   free(i1->data); i1->data = 0;
145   XDestroyImage(i1);
146   XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height);
147   free(i2->data); i2->data = 0;
148   XDestroyImage(i2);
149   XFreePixmap(dpy, pixmap);
150   return p2;
151 }
152
153
154 /* Sleep for N seconds and return False.  But if a key or mouse event is
155    seen, discard all pending key or mouse events, and return True.
156  */
157 static Bool
158 bsod_sleep(Display *dpy, int seconds)
159 {
160   int q = seconds * 4;
161   int quantum = 250000;
162
163   if (seconds == -1)
164     q = 1, quantum = 100000;
165
166   do
167     {
168       XSync(dpy, False);
169       while (XPending (dpy))
170         {
171           XEvent event;
172           XNextEvent (dpy, &event);
173           if (event.xany.type == ButtonPress)
174             return True;
175           if (event.xany.type == KeyPress)
176             {
177               KeySym keysym;
178               char c = 0;
179               XLookupString (&event.xkey, &c, 1, &keysym, 0);
180               if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
181                 return True;
182             }
183           screenhack_handle_event (dpy, &event);
184         }
185
186       if (q > 0)
187         {
188           q--;
189           usleep(quantum);
190         }
191     }
192   while (q > 0);
193
194   return False; 
195 }
196
197
198 static Bool
199 windows (Display *dpy, Window window, int delay, int which)
200 {
201   XGCValues gcv;
202   XWindowAttributes xgwa;
203   char *fontname;
204   const char *def_font = "fixed";
205   XFontStruct *font;
206   GC gc;
207
208   const char *w95 =
209     ("@Windows\n"
210      "A fatal exception 0E has occured at F0AD:42494C4C\n"
211      "the current application will be terminated.\n"
212      "\n"
213      "* Press any key to terminate the current application.\n"
214      "* Press CTRL+ALT+DELETE again to restart your computer.\n"
215      "  You will lose any unsaved information in all applications.\n"
216      "\n"
217      "\n"
218      "_Press any key to continue");
219
220   const char *wnt = /* from Jim Niemira <urmane@urmane.org> */
221     ("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
222    "Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
223    "\n"
224    "Dll Base Date Stamp - Name             Dll Base Date Stamp - Name\n"
225    "80100000 2be154c9 - ntoskrnl.exe       80400000 2bc153b0 - hal.dll\n"
226    "80258000 2bd49628 - ncrc710.sys        8025c000 2bd49688 - SCSIPORT.SYS \n"
227    "80267000 2bd49683 - scsidisk.sys       802a6000 2bd496b9 - Fastfat.sys\n"
228    "fa800000 2bd49666 - Floppy.SYS         fa810000 2bd496db - Hpfs_Rec.SYS\n"
229    "fa820000 2bd49676 - Null.SYS           fa830000 2bd4965a - Beep.SYS\n"
230    "fa840000 2bdaab00 - i8042prt.SYS       fa850000 2bd5a020 - SERMOUSE.SYS\n"
231    "fa860000 2bd4966f - kbdclass.SYS       fa870000 2bd49671 - MOUCLASS.SYS\n"
232    "fa880000 2bd9c0be - Videoprt.SYS       fa890000 2bd49638 - NCC1701E.SYS\n"
233    "fa8a0000 2bd4a4ce - Vga.SYS            fa8b0000 2bd496d0 - Msfs.SYS\n"
234    "fa8c0000 2bd496c3 - Npfs.SYS           fa8e0000 2bd496c9 - Ntfs.SYS\n"
235    "fa940000 2bd496df - NDIS.SYS           fa930000 2bd49707 - wdlan.sys\n"
236    "fa970000 2bd49712 - TDI.SYS            fa950000 2bd5a7fb - nbf.sys\n"
237    "fa980000 2bd72406 - streams.sys        fa9b0000 2bd4975f - ubnb.sys\n"
238    "fa9c0000 2bd5bfd7 - usbser.sys         fa9d0000 2bd4971d - netbios.sys\n"
239    "fa9e0000 2bd49678 - Parallel.sys       fa9f0000 2bd4969f - serial.SYS\n"
240    "faa00000 2bd49739 - mup.sys            faa40000 2bd4971f - SMBTRSUP.SYS\n"
241    "faa10000 2bd6f2a2 - srv.sys            faa50000 2bd4971a - afd.sys\n"
242    "faa60000 2bd6fd80 - rdr.sys            faaa0000 2bd49735 - bowser.sys\n"
243    "\n"
244    "Address dword dump Dll Base                                      - Name\n"
245    "801afc20 80106fc0 80106fc0 00000000 00000000 80149905 : "
246      "fa840000 - i8042prt.SYS\n"
247    "801afc24 80149905 80149905 ff8e6b8c 80129c2c ff8e6b94 : "
248      "8025c000 - SCSIPORT.SYS\n"
249    "801afc2c 80129c2c 80129c2c ff8e6b94 00000000 ff8e6b94 : "
250      "80100000 - ntoskrnl.exe\n"
251    "801afc34 801240f2 80124f02 ff8e6df4 ff8e6f60 ff8e6c58 : "
252      "80100000 - ntoskrnl.exe\n"
253    "801afc54 80124f16 80124f16 ff8e6f60 ff8e6c3c 8015ac7e : "
254      "80100000 - ntoskrnl.exe\n"
255    "801afc64 8015ac7e 8015ac7e ff8e6df4 ff8e6f60 ff8e6c58 : "
256      "80100000 - ntoskrnl.exe\n"
257    "801afc70 80129bda 80129bda 00000000 80088000 80106fc0 : "
258      "80100000 - ntoskrnl.exe\n"
259    "\n"
260    "Kernel Debugger Using: COM2 (Port 0x2f8, Baud Rate 19200)\n"
261    "Restart and set the recovery options in the system control panel\n"
262    "or the /CRASHDEBUG system start option. If this message reappears,\n"
263    "contact your system administrator or technical support group."
264      );
265
266   const char *w2ka =
267     ("*** STOP: 0x000000D1 (0xE1D38000,0x0000001C,0x00000000,0xF09D42DA)\n"
268      "DRIVER_IRQL_NOT_LESS_OR_EQUAL \n"
269      "\n"
270     "*** Address F09D42DA base at F09D4000, DateStamp 39f459ff - CRASHDD.SYS\n"
271      "\n"
272      "Beginning dump of physical memory\n");
273   const char *w2kb =
274     ("Physical memory dump complete. Contact your system administrator or\n"
275      "technical support group.\n");
276
277   if (which < 0 || which > 2) abort();
278
279   if (!get_boolean_resource((which == 0 ? "doWindows" :
280                              which == 1 ? "doNT" :
281                                           "doWin2K"),
282                             "DoWindows"))
283     return False;
284
285   XGetWindowAttributes (dpy, window, &xgwa);
286
287   fontname = get_string_resource ((xgwa.height > 600
288                                    ? (which == 0 ? "windows95.font2" :
289                                       which == 1 ? "windowsNT.font2" :
290                                                    "windows2K.font2")
291                                    : (which == 0 ? "windows95.font" :
292                                       which == 1 ? "windowsNT.font" :
293                                                    "windows2K.font")),
294                                   "Windows.Font");
295   if (!fontname || !*fontname) fontname = (char *)def_font;
296   font = XLoadQueryFont (dpy, fontname);
297   if (!font) font = XLoadQueryFont (dpy, def_font);
298   if (!font) exit(-1);
299   if (fontname && fontname != def_font)
300     free (fontname);
301
302   gcv.font = font->fid;
303   gcv.foreground = get_pixel_resource((which == 0 ? "windows95.foreground" :
304                                        which == 1 ? "windowsNT.foreground" :
305                                                     "windows2K.foreground"),
306                                       "Windows.Foreground",
307                                       dpy, xgwa.colormap);
308   gcv.background = get_pixel_resource((which == 0 ? "windows95.background" :
309                                        which == 1 ? "windowsNT.background" :
310                                                     "windows2K.background"),
311                                       "Windows.Background",
312                                       dpy, xgwa.colormap);
313   XSetWindowBackground(dpy, window, gcv.background);
314   XClearWindow(dpy, window);
315
316   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
317
318   if (which == 0)
319     draw_string(dpy, window, gc, &gcv, font,
320                 0, 0, xgwa.width, xgwa.height, w95, 0);
321   else if (which == 1)
322     draw_string(dpy, window, gc, &gcv, font, 0, 0, 10, 10, wnt, 750);
323   else
324     {
325       int line_height = font->ascent + font->descent + 1;
326       int x = 20;
327       int y = (xgwa.height / 4);
328
329       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, w2ka, 750);
330       y += line_height * 6;
331       bsod_sleep(dpy, 4);
332       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, w2kb, 750);
333     }
334
335   XFreeGC(dpy, gc);
336   XSync(dpy, False);
337   bsod_sleep(dpy, delay);
338   XClearWindow(dpy, window);
339   XFreeFont(dpy, font);
340   return True;
341 }
342
343 /* SCO OpenServer 5 panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
344  */
345 static Bool
346 sco (Display *dpy, Window window, int delay)
347 {
348   XGCValues gcv;
349   XWindowAttributes xgwa;
350   char *fontname;
351   const char *def_font = "fixed";
352   XFontStruct *font;
353   GC gc;
354   int lines_1 = 0, lines_2 = 0, lines_3 = 0, lines_4 = 0;
355   const char *s;
356
357   const char *sco_panic_1 =
358     ("Unexpected trap in kernel mode:\n"
359      "\n"
360      "cr0 0x80010013     cr2  0x00000014     cr3 0x00000000  tlb  0x00000000\n"
361      "ss  0x00071054    uesp  0x00012055     efl 0x00080888  ipl  0x00000005\n"
362      "cs  0x00092585     eip  0x00544a4b     err 0x004d4a47  trap 0x0000000E\n"
363      "eax 0x0045474b     ecx  0x0042544b     edx 0x57687920  ebx  0x61726520\n"
364      "esp 0x796f7520     ebp  0x72656164     esi 0x696e6720  edi  0x74686973\n"
365      "ds  0x3f000000     es   0x43494c48     fs  0x43525343  gs   0x4f4d4b53\n"
366      "\n"
367      "PANIC: k_trap - kernel mode trap type 0x0000000E\n"
368      "Trying to dump 5023 pages to dumpdev hd (1/41), 63 pages per '.'\n"
369     );
370   const char *sco_panic_2 =
371    ("...............................................................................\n"
372     );
373   const char *sco_panic_3 =
374     ("5023 pages dumped\n"
375      "\n"
376      "\n"
377      );
378   const char *sco_panic_4 =
379     ("**   Safe to Power Off   **\n"
380      "           - or -\n"
381      "** Press Any Key to Reboot **\n"
382     );
383
384   if (!get_boolean_resource("doSCO", "DoSCO"))
385     return False;
386
387   for (s = sco_panic_1; *s; s++) if (*s == '\n') lines_1++;
388   for (s = sco_panic_2; *s; s++) if (*s == '\n') lines_2++;
389   for (s = sco_panic_3; *s; s++) if (*s == '\n') lines_3++;
390   for (s = sco_panic_4; *s; s++) if (*s == '\n') lines_4++;
391
392   XGetWindowAttributes (dpy, window, &xgwa);
393
394   fontname = get_string_resource ((xgwa.height > 600
395                                    ? "sco.font2"
396                                    : "sco.font"),
397                                   "SCO.Font");
398   if (!fontname || !*fontname) fontname = (char *)def_font;
399   font = XLoadQueryFont (dpy, fontname);
400   if (!font) font = XLoadQueryFont (dpy, def_font);
401   if (!font) exit(-1);
402   if (fontname && fontname != def_font)
403     free (fontname);
404
405   gcv.font = font->fid;
406   gcv.foreground = get_pixel_resource(("sco.foreground"),
407                                       "SCO.Foreground",
408                                       dpy, xgwa.colormap);
409   gcv.background = get_pixel_resource(("sco.background"),
410                                       "SCO.Background",
411                                       dpy, xgwa.colormap);
412   XSetWindowBackground(dpy, window, gcv.background);
413   XClearWindow(dpy, window);
414
415   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
416
417   draw_string(dpy, window, gc, &gcv, font,
418               10, xgwa.height - ((lines_1 + lines_2 + lines_3 + lines_4 + 1) *
419                                  (font->ascent + font->descent + 1)),
420               10, 10,
421               sco_panic_1, 0);
422   XSync(dpy, False);
423   for (s = sco_panic_2; *s; s++)
424     {
425       char *ss = strdup(sco_panic_2);
426       ss[s - sco_panic_2] = 0;
427       draw_string(dpy, window, gc, &gcv, font,
428                   10, xgwa.height - ((lines_2 + lines_3 + lines_4 + 1) *
429                                      (font->ascent + font->descent + 1)),
430                   10, 10,
431                   ss, 0);
432       XSync(dpy, False);
433       free(ss);
434       if (bsod_sleep (dpy, -1))
435         goto DONE;
436     }
437
438   draw_string(dpy, window, gc, &gcv, font,
439               10, xgwa.height - ((lines_3 + lines_4 + 1) *
440                                  (font->ascent + font->descent + 1)),
441               10, 10,
442               sco_panic_3, 0);
443   XSync(dpy, False);
444   if (bsod_sleep(dpy, 1))
445     goto DONE;
446   draw_string(dpy, window, gc, &gcv, font,
447               10, xgwa.height - ((lines_4 + 1) *
448                                  (font->ascent + font->descent + 1)),
449               10, 10,
450               sco_panic_4, 0);
451   XSync(dpy, False);
452
453   bsod_sleep(dpy, delay);
454  DONE:
455   XClearWindow(dpy, window);
456   XFreeGC(dpy, gc);
457   XFreeFont(dpy, font);
458   return True;
459 }
460
461
462 /* Linux (sparc) panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
463  */
464 static Bool
465 sparc_linux (Display *dpy, Window window, int delay)
466 {
467   XGCValues gcv;
468   XWindowAttributes xgwa;
469   char *fontname;
470   const char *def_font = "fixed";
471   XFontStruct *font;
472   GC gc;
473   int lines = 1;
474   const char *s;
475
476   const char *linux_panic =
477     ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
478         "Unable to handle kernel paging request at virtual address f0d4a000\n"
479         "tsk->mm->context = 00000014\n"
480         "tsk->mm->pgd = f26b0000\n"
481         "              \\|/ ____ \\|/\n"
482         "              \"@'/ ,. \\`@\"\n"
483         "              /_| \\__/ |_\\\n"
484         "                 \\__U_/\n"
485         "gawk(22827): Oops\n"
486         "PSR: 044010c1 PC: f001c2cc NPC: f001c2d0 Y: 00000000\n"
487         "g0: 00001000 g1: fffffff7 g2: 04401086 g3: 0001eaa0\n"
488         "g4: 000207dc g5: f0130400 g6: f0d4a018 g7: 00000001\n"
489         "o0: 00000000 o1: f0d4a298 o2: 00000040 o3: f1380718\n"
490         "o4: f1380718 o5: 00000200 sp: f1b13f08 ret_pc: f001c2a0\n"
491         "l0: efffd880 l1: 00000001 l2: f0d4a230 l3: 00000014\n"
492         "l4: 0000ffff l5: f0131550 l6: f012c000 l7: f0130400\n"
493         "i0: f1b13fb0 i1: 00000001 i2: 00000002 i3: 0007c000\n"
494         "i4: f01457c0 i5: 00000004 i6: f1b13f70 i7: f0015360\n"
495         "Instruction DUMP:\n"
496     );
497
498   if (!get_boolean_resource("doSparcLinux", "DoSparcLinux"))
499     return False;
500
501   for (s = linux_panic; *s; s++) if (*s == '\n') lines++;
502
503   XGetWindowAttributes (dpy, window, &xgwa);
504
505   fontname = get_string_resource ((xgwa.height > 600
506                                    ? "sparclinux.font2"
507                                    : "sparclinux.font"),
508                                   "SparcLinux.Font");
509   if (!fontname || !*fontname) fontname = (char *)def_font;
510   font = XLoadQueryFont (dpy, fontname);
511   if (!font) font = XLoadQueryFont (dpy, def_font);
512   if (!font) exit(-1);
513   if (fontname && fontname != def_font)
514     free (fontname);
515
516   gcv.font = font->fid;
517   gcv.foreground = get_pixel_resource(("sparclinux.foreground"),
518                                       "SparcLinux.Foreground",
519                                       dpy, xgwa.colormap);
520   gcv.background = get_pixel_resource(("sparclinux.background"),
521                                       "SparcLinux.Background",
522                                       dpy, xgwa.colormap);
523   XSetWindowBackground(dpy, window, gcv.background);
524   XClearWindow(dpy, window);
525
526   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
527
528   draw_string(dpy, window, gc, &gcv, font,
529               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
530               10, 10,
531               linux_panic, 0);
532   XFreeGC(dpy, gc);
533   XSync(dpy, False);
534   bsod_sleep(dpy, delay);
535   XClearWindow(dpy, window);
536   XFreeFont(dpy, font);
537   return True;
538 }
539
540 /* BSD Panic by greywolf@starwolf.com - modeled after the Linux panic above.
541    By Grey Wolf <greywolf@siteROCK.com>
542  */
543 static Bool
544 bsd (Display *dpy, Window window, int delay)
545 {
546   XGCValues gcv;
547   XWindowAttributes xgwa;
548   char *fontname;
549   const char *def_font = "fixed";
550   XFontStruct *font;
551   GC gc;
552   int lines = 1;
553   int i, n, b;
554   const char *rbstr, *panicking;
555   char syncing[80], bbuf[5], *bp;
556
557   const char *panicstr[] =
558    {"panic: ifree: freeing free inode",
559     "panic: blkfree: freeing free block",
560     "panic: improbability coefficient below zero",
561     "panic: cgsixmmap",
562     "panic: crazy interrupts",
563     "panic: nmi",
564     "panic: attempted windows install",
565     "panic: don't",
566     "panic: free inode isn't",
567     "panic: cpu_fork: curproc",
568     "panic: malloc: out of space in kmem_map",
569     "panic: vogon starship detected",
570     "panic: teleport chamber: out of order",
571     "panic: Brain fried - core dumped"};
572      
573   if (!get_boolean_resource("doBSD", "DoBSD"))
574     return False;
575
576   for (i = 0; i < sizeof(syncing); i++)
577     syncing[i] = 0;
578
579   i = (random() & 0xffff) % (sizeof(panicstr) / sizeof(*panicstr));
580
581   panicking = panicstr[i];
582   strcpy(syncing, "Syncing disks: ");
583
584   b = (random() & 0xff) % 40;
585   for (n = 0; (n < 20) && (b > 0); n++)
586     {
587       if (i)
588         {
589           i = (random() & 0x7);
590           b -= (random() & 0xff) % 20;
591           if (b < 0)
592             b = 0;
593         }
594       sprintf (bbuf, "%d ", b);
595       strcat (syncing, bbuf);
596     }
597
598   if (b)
599     rbstr = "damn!";
600   else
601     rbstr = "sunk!";
602
603   lines = 5;
604
605   XGetWindowAttributes (dpy, window, &xgwa);
606
607   fontname = get_string_resource ((xgwa.height > 600
608                                    ? "bsd.font2"
609                                    : "bsd.font"),
610                                   "BSD.Font");
611   if (!fontname || !*fontname) fontname = (char *)def_font;
612   font = XLoadQueryFont (dpy, fontname);
613   if (!font) font = XLoadQueryFont (dpy, def_font);
614   if (!font) exit(-1);
615   if (fontname && fontname != def_font)
616     free (fontname);
617
618   gcv.font = font->fid;
619   gcv.foreground = get_pixel_resource(("bsd.foreground"),
620                                       "BSD.Foreground",
621                                       dpy, xgwa.colormap);
622   gcv.background = get_pixel_resource(("bsd.background"),
623                                       "BSD.Background",
624                                       dpy, xgwa.colormap);
625   XSetWindowBackground(dpy, window, gcv.background);
626   XClearWindow(dpy, window);
627
628   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
629
630   draw_string(dpy, window, gc, &gcv, font,
631               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
632               10, 10,
633               panicking, 0);
634   XSync(dpy, False);
635   lines--;
636
637   for (bp = syncing; *bp;)
638     {
639       char *bsd_bufs, oc = 0;
640       for (;*bp && (*bp != ' '); bp++)
641         ;
642       if (*bp == ' ')
643         {
644           oc = *bp;
645           *bp = 0;
646         }
647       bsd_bufs = strdup(syncing);
648       draw_string(dpy, window, gc, &gcv, font,
649                   10,
650                   xgwa.height - (lines * (font->ascent + font->descent + 1)),
651                   10, 10,
652                   bsd_bufs, 0);
653       XSync(dpy, False);
654       free(bsd_bufs);
655       if (oc)
656         *bp = oc;
657       if (bsod_sleep(dpy, -1))
658         goto DONE;
659       bp++;
660     }
661
662   lines--;
663   
664   draw_string(dpy, window, gc, &gcv, font,
665               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
666               10, 10,
667               rbstr, 0);
668   lines--;
669   draw_string(dpy, window, gc, &gcv, font,
670               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
671               10, 10,
672               "Rebooting", 0);
673
674   XFreeGC(dpy, gc);
675   XSync(dpy, False);
676   bsod_sleep(dpy, delay);
677
678 DONE:
679   XClearWindow(dpy, window);
680   XFreeFont(dpy, font);
681   return True;
682 }
683
684 static Bool
685 amiga (Display *dpy, Window window, int delay)
686 {
687   XGCValues gcv;
688   XWindowAttributes xgwa;
689   char *fontname;
690   const char *def_font = "fixed";
691   XFontStruct *font;
692   GC gc, gc2;
693   int height;
694   unsigned long fg, bg, bg2;
695   Pixmap pixmap = 0;
696   int pix_w = 0, pix_h = 0;
697   int string_width;
698   int margin;
699
700   const char *string =
701     ("_Software failure.  Press left mouse button to continue.\n"
702      "_Guru Meditation #00000003.00C01570");
703
704   if (!get_boolean_resource("doAmiga", "DoAmiga"))
705     return False;
706
707   XGetWindowAttributes (dpy, window, &xgwa);
708
709   fontname = get_string_resource ((xgwa.height > 600
710                                    ? "amiga.font2" : "amiga.font"),
711                                   "Amiga.Font");
712   if (!fontname || !*fontname) fontname = (char *)def_font;
713   font = XLoadQueryFont (dpy, fontname);
714   if (!font) font = XLoadQueryFont (dpy, def_font);
715   if (!font) exit(-1);
716   if (fontname && fontname != def_font)
717     free (fontname);
718
719   gcv.font = font->fid;
720   fg = gcv.foreground = get_pixel_resource("amiga.foreground",
721                                            "Amiga.Foreground",
722                                            dpy, xgwa.colormap);
723   bg = gcv.background = get_pixel_resource("amiga.background",
724                                            "Amiga.Background",
725                                            dpy, xgwa.colormap);
726   bg2 = get_pixel_resource("amiga.background2", "Amiga.Background",
727                            dpy, xgwa.colormap);
728   XSetWindowBackground(dpy, window, bg2);
729   XClearWindow(dpy, window);
730
731   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
732   gcv.background = fg; gcv.foreground = bg;
733   gc2 = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
734
735   height = (font->ascent + font->descent) * 6;
736
737 #if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
738   pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand,
739                                &pix_w, &pix_h, 0);
740 #endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
741
742   if (pixmap && xgwa.height > 600)      /* scale up the bitmap */
743     {
744       pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
745                              pixmap, pix_w, pix_h);
746       pix_w *= 2;
747       pix_h *= 2;
748     }
749
750   if (pixmap)
751     {
752       int x = (xgwa.width - pix_w) / 2;
753       int y = ((xgwa.height - pix_h) / 2);
754       XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
755
756       XSync(dpy, False);
757       bsod_sleep(dpy, 2);
758
759       XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y + height);
760       XClearArea(dpy, window, 0, 0, xgwa.width, y + height, False);
761       XFreePixmap(dpy, pixmap);
762     }
763
764   XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
765   margin = font->ascent;
766   string_width = draw_string(dpy, window, gc, &gcv, font,
767                              margin, 0,
768                              xgwa.width - (margin * 2), height,
769                              string, 0);
770   {
771     GC gca = gc;
772     while (delay > 0)
773       {
774         int x2;
775         XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, margin);
776         XFillRectangle(dpy, window, gca, 0, 0, margin, height);
777         XFillRectangle(dpy, window, gca,
778                        0, height - margin, xgwa.width, margin);
779         x2 = margin + string_width;
780         if (x2 < xgwa.width - margin) x2 = xgwa.width - margin;
781         XFillRectangle(dpy, window, gca, x2, 0, margin, height);
782
783         gca = (gca == gc ? gc2 : gc);
784         XSync(dpy, False);
785         if (bsod_sleep(dpy, 1))
786           break;
787         delay--;
788       }
789   }
790
791   XFreeGC(dpy, gc);
792   XFreeGC(dpy, gc2);
793   XSync(dpy, False);
794   XClearWindow(dpy, window);
795   XFreeFont(dpy, font);
796   return True;
797 }
798
799
800 /* Atari ST, by Marcus Herbert <rhoenie@nobiscum.de>
801    Marcus had this to say:
802
803         Though I still have my Atari somewhere, I hardly remember
804         the meaning of the bombs. I think 9 bombs was "bus error" or
805         something like that.  And you often had a few bombs displayed
806         quickly and then the next few ones coming up step by step.
807         Perhaps somebody else can tell you more about it..  its just
808         a quick hack :-}
809  */
810 static Bool
811 atari (Display *dpy, Window window, int delay)
812 {
813         
814   XGCValues gcv;
815   XWindowAttributes xgwa;
816   const char *def_font = "fixed";
817   XFontStruct *font;
818   GC gc;
819   Pixmap pixmap = 0;
820   int pix_w = atari_width;
821   int pix_h = atari_height;
822   int offset;
823   int i, x, y;
824
825   if (!get_boolean_resource("doAtari", "DoAtari"))
826     return False;
827
828   XGetWindowAttributes (dpy, window, &xgwa);
829
830   font = XLoadQueryFont (dpy, def_font);
831   if (!font) exit(-1);
832                 
833   gcv.font = font->fid;
834   gcv.foreground = get_pixel_resource("atari.foreground", "Atari.Foreground",
835                                       dpy, xgwa.colormap);
836   gcv.background = get_pixel_resource("atari.background", "Atari.Background",
837                                       dpy, xgwa.colormap);
838
839   XSetWindowBackground(dpy, window, gcv.background);
840   XClearWindow(dpy, window);
841
842   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
843
844   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) atari_bits,
845                                        pix_w, pix_h,
846                                        gcv.foreground, gcv.background,
847                                        xgwa.depth);
848   pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
849                          pixmap, pix_w, pix_h);
850   pix_w *= 2;
851   pix_h *= 2;
852
853   offset = pix_w + 2;
854   x = 5;
855   y = (xgwa.height - (xgwa.height / 5));
856   if (y < 0) y = 0;
857
858   for (i=0 ; i<7 ; i++) {
859     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
860               (x + (i*offset)), y);
861   }  
862   
863   for (i=7 ; i<10 ; i++) {
864     if (bsod_sleep(dpy, 1))
865       goto DONE;
866     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
867               (x + (i*offset)), y);
868   }
869
870   bsod_sleep(dpy, delay);
871  DONE:
872   XFreePixmap(dpy, pixmap);
873   XFreeGC(dpy, gc);
874   XSync(dpy, False);
875   XClearWindow(dpy, window);
876   XFreeFont(dpy, font);
877   return True;
878 }
879
880
881 static Bool
882 mac (Display *dpy, Window window, int delay)
883 {
884   XGCValues gcv;
885   XWindowAttributes xgwa;
886   char *fontname;
887   const char *def_font = "fixed";
888   XFontStruct *font;
889   GC gc;
890   Pixmap pixmap = 0;
891   int pix_w = mac_width;
892   int pix_h = mac_height;
893   int offset = mac_height * 4;
894   int i;
895
896   const char *string = ("0 0 0 0 0 0 0 F\n"
897                         "0 0 0 0 0 0 0 3");
898
899   if (!get_boolean_resource("doMac", "DoMac"))
900     return False;
901
902   XGetWindowAttributes (dpy, window, &xgwa);
903
904   fontname = get_string_resource ("mac.font", "Mac.Font");
905   if (!fontname || !*fontname) fontname = (char *)def_font;
906   font = XLoadQueryFont (dpy, fontname);
907   if (!font) font = XLoadQueryFont (dpy, def_font);
908   if (!font) exit(-1);
909   if (fontname && fontname != def_font)
910     free (fontname);
911
912   gcv.font = font->fid;
913   gcv.foreground = get_pixel_resource("mac.foreground", "Mac.Foreground",
914                                       dpy, xgwa.colormap);
915   gcv.background = get_pixel_resource("mac.background", "Mac.Background",
916                                       dpy, xgwa.colormap);
917   XSetWindowBackground(dpy, window, gcv.background);
918   XClearWindow(dpy, window);
919
920   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
921
922   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits,
923                                        mac_width, mac_height,
924                                        gcv.foreground,
925                                        gcv.background,
926                                        xgwa.depth);
927
928   for(i = 0; i < 2; i++)
929     {
930       pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
931                              pixmap, pix_w, pix_h);
932       pix_w *= 2; pix_h *= 2;
933     }
934
935   {
936     int x = (xgwa.width - pix_w) / 2;
937     int y = (((xgwa.height + offset) / 2) -
938              pix_h -
939              (font->ascent + font->descent) * 2);
940     if (y < 0) y = 0;
941     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
942     XFreePixmap(dpy, pixmap);
943   }
944
945   draw_string(dpy, window, gc, &gcv, font, 0, 0,
946               xgwa.width, xgwa.height + offset, string, 0);
947
948   XFreeGC(dpy, gc);
949   XSync(dpy, False);
950   bsod_sleep(dpy, delay);
951   XClearWindow(dpy, window);
952   XFreeFont(dpy, font);
953   return True;
954 }
955
956 static Bool
957 macsbug (Display *dpy, Window window, int delay)
958 {
959   XGCValues gcv;
960   XWindowAttributes xgwa;
961   char *fontname;
962   const char *def_font = "fixed";
963   XFontStruct *font;
964   GC gc, gc2;
965
966   int char_width, line_height;
967   int col_right, row_top, row_bottom, page_right, page_bottom, body_top;
968   int xoff, yoff;
969
970   const char *left = ("    SP     \n"
971                       " 04EB0A58  \n"
972                       "58 00010000\n"
973                       "5C 00010000\n"
974                       "   ........\n"
975                       "60 00000000\n"
976                       "64 000004EB\n"
977                       "   ........\n"
978                       "68 0000027F\n"
979                       "6C 2D980035\n"
980                       "   ....-..5\n"
981                       "70 00000054\n"
982                       "74 0173003E\n"
983                       "   ...T.s.>\n"
984                       "78 04EBDA76\n"
985                       "7C 04EBDA8E\n"
986                       "   .S.L.a.U\n"
987                       "80 00000000\n"
988                       "84 000004EB\n"
989                       "   ........\n"
990                       "88 00010000\n"
991                       "8C 00010000\n"
992                       "   ...{3..S\n"
993                       "\n"
994                       "\n"
995                       " CurApName \n"
996                       "  Finder   \n"
997                       "\n"
998                       " 32-bit VM \n"
999                       "SR Smxnzvc0\n"
1000                       "D0 04EC0062\n"
1001                       "D1 00000053\n"
1002                       "D2 FFFF0100\n"
1003                       "D3 00010000\n"
1004                       "D4 00010000\n"
1005                       "D5 04EBDA76\n"
1006                       "D6 04EBDA8E\n"
1007                       "D7 00000001\n"
1008                       "\n"
1009                       "A0 04EBDA76\n"
1010                       "A1 04EBDA8E\n"
1011                       "A2 A0A00060\n"
1012                       "A3 027F2D98\n"
1013                       "A4 027F2E58\n"
1014                       "A5 04EC04F0\n"
1015                       "A6 04EB0A86\n"
1016                       "A7 04EB0A58");
1017   const char *bottom = ("  _A09D\n"
1018                         "     +00884    40843714     #$0700,SR         "
1019                         "                  ; A973        | A973\n"
1020                         "     +00886    40843765     *+$0400           "
1021                         "                                | 4A1F\n"
1022                         "     +00888    40843718     $0004(A7),([0,A7[)"
1023                         "                  ; 04E8D0AE    | 66B8");
1024
1025 #if 0
1026   const char *body = ("Bus Error at 4BF6D6CC\n"
1027                       "while reading word from 4BF6D6CC in User data space\n"
1028                       " Unable to access that address\n"
1029                       "  PC: 2A0DE3E6\n"
1030                       "  Frame Type: B008");
1031 #else
1032   const char * body = ("PowerPC unmapped memory exception at 003AFDAC "
1033                                                 "BowelsOfTheMemoryMgr+04F9C\n"
1034                       " Calling chain using A6/R1 links\n"
1035                       "  Back chain  ISA  Caller\n"
1036                       "  00000000    PPC  28C5353C  __start+00054\n"
1037                       "  24DB03C0    PPC  28B9258C  main+0039C\n"
1038                       "  24DB0350    PPC  28B9210C  MainEvent+00494\n"
1039                       "  24DB02B0    PPC  28B91B40  HandleEvent+00278\n"
1040                       "  24DB0250    PPC  28B83DAC  DoAppleEvent+00020\n"
1041                       "  24DB0210    PPC  FFD3E5D0  "
1042                                                 "AEProcessAppleEvent+00020\n"
1043                       "  24DB0132    68K  00589468\n"
1044                       "  24DAFF8C    68K  00589582\n"
1045                       "  24DAFF26    68K  00588F70\n"
1046                       "  24DAFEB3    PPC  00307098  "
1047                                                 "EmToNatEndMoveParams+00014\n"
1048                       "  24DAFE40    PPC  28B9D0B0  DoScript+001C4\n"
1049                       "  24DAFDD0    PPC  28B9C35C  RunScript+00390\n"
1050                       "  24DAFC60    PPC  28BA36D4  run_perl+000E0\n"
1051                       "  24DAFC10    PPC  28BC2904  perl_run+002CC\n"
1052                       "  24DAFA80    PPC  28C18490  Perl_runops+00068\n"
1053                       "  24DAFA30    PPC  28BE6CC0  Perl_pp_backtick+000FC\n"
1054                       "  24DAF9D0    PPC  28BA48B8  Perl_my_popen+00158\n"
1055                       "  24DAF980    PPC  28C5395C  sfclose+00378\n"
1056                       "  24DAF930    PPC  28BA568C  free+0000C\n"
1057                       "  24DAF8F0    PPC  28BA6254  pool_free+001D0\n"
1058                       "  24DAF8A0    PPC  FFD48F14  DisposePtr+00028\n"
1059                       "  24DAF7C9    PPC  00307098  "
1060                                                 "EmToNatEndMoveParams+00014\n"
1061                       "  24DAF780    PPC  003AA180  __DisposePtr+00010");
1062 #endif
1063
1064   const char *s;
1065   int body_lines = 1;
1066
1067   if (!get_boolean_resource("doMacsBug", "DoMacsBug"))
1068     return False;
1069
1070   for (s = body; *s; s++) if (*s == '\n') body_lines++;
1071
1072   XGetWindowAttributes (dpy, window, &xgwa);
1073
1074   fontname = get_string_resource ((xgwa.height > 850
1075                                    ? "macsbug.font3"
1076                                    : (xgwa.height > 700
1077                                       ? "macsbug.font2"
1078                                       : "macsbug.font")),
1079                                   "MacsBug.Font");
1080   if (!fontname || !*fontname) fontname = (char *)def_font;
1081   font = XLoadQueryFont (dpy, fontname);
1082   if (!font) font = XLoadQueryFont (dpy, def_font);
1083   if (!font) exit(-1);
1084   if (fontname && fontname != def_font)
1085     free (fontname);
1086
1087   gcv.font = font->fid;
1088   gcv.foreground = get_pixel_resource("macsbug.foreground",
1089                                       "MacsBug.Foreground",
1090                                       dpy, xgwa.colormap);
1091   gcv.background = get_pixel_resource("macsbug.background",
1092                                       "MacsBug.Background",
1093                                       dpy, xgwa.colormap);
1094
1095   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
1096
1097   gcv.foreground = gcv.background;
1098   gc2 = XCreateGC(dpy, window, GCForeground, &gcv);
1099
1100   XSetWindowBackground(dpy, window,
1101                        get_pixel_resource("macsbug.borderColor",
1102                                           "MacsBug.BorderColor",
1103                                           dpy, xgwa.colormap));
1104   XClearWindow(dpy, window);
1105
1106   char_width = (font->per_char
1107                 ? font->per_char['n'-font->min_char_or_byte2].width
1108                 : font->min_bounds.width);
1109   line_height = font->ascent + font->descent + 1;
1110
1111   col_right = char_width * 12;
1112   page_bottom = line_height * 47;
1113
1114   if (page_bottom > xgwa.height) page_bottom = xgwa.height;
1115
1116   row_bottom = page_bottom - line_height;
1117   row_top = row_bottom - (line_height * 4);
1118   page_right = col_right + (char_width * 88);
1119   body_top = row_top - (line_height * body_lines);
1120
1121   page_bottom += 2;
1122   row_bottom += 2;
1123   body_top -= 4;
1124
1125   xoff = (xgwa.width - page_right) / 2;
1126   yoff = (xgwa.height - page_bottom) / 2;
1127   if (xoff < 0) xoff = 0;
1128   if (yoff < 0) yoff = 0;
1129
1130   XFillRectangle(dpy, window, gc2, xoff, yoff, page_right, page_bottom);
1131
1132   draw_string(dpy, window, gc, &gcv, font, xoff, yoff, 10, 10, left, 0);
1133   draw_string(dpy, window, gc, &gcv, font, xoff+col_right, yoff+row_top,
1134               10, 10, bottom, 0);
1135
1136   XFillRectangle(dpy, window, gc, xoff + col_right, yoff, 2, page_bottom);
1137   XDrawLine(dpy, window, gc,
1138             xoff+col_right, yoff+row_top, xoff+page_right, yoff+row_top);
1139   XDrawLine(dpy, window, gc,
1140             xoff+col_right, yoff+row_bottom, xoff+page_right, yoff+row_bottom);
1141   XDrawRectangle(dpy, window, gc,  xoff, yoff, page_right, page_bottom);
1142
1143   if (body_top > 4)
1144     body_top = 4;
1145
1146   draw_string(dpy, window, gc, &gcv, font,
1147               xoff + col_right + char_width, yoff + body_top, 10, 10, body,
1148               500);
1149
1150   while (delay > 0)
1151     {
1152       XDrawLine(dpy, window, gc,
1153                 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1154                 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1155       XSync(dpy, False);
1156       usleep(666666L);
1157       XDrawLine(dpy, window, gc2,
1158                 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1159                 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1160       XSync(dpy, False);
1161       usleep(333333L);
1162       if (bsod_sleep(dpy, 0))
1163         break;
1164       delay--;
1165     }
1166
1167   XFreeGC(dpy, gc);
1168   XFreeGC(dpy, gc2);
1169   XClearWindow(dpy, window);
1170   XFreeFont(dpy, font);
1171   return True;
1172 }
1173
1174 static Bool
1175 mac1 (Display *dpy, Window window, int delay)
1176 {
1177   XGCValues gcv;
1178   XWindowAttributes xgwa;
1179   GC gc;
1180   Pixmap pixmap = 0;
1181   int pix_w = macbomb_width;
1182   int pix_h = macbomb_height;
1183
1184   if (!get_boolean_resource("doMac1", "DoMac1"))
1185     return False;
1186
1187   XGetWindowAttributes (dpy, window, &xgwa);
1188
1189   gcv.foreground = get_pixel_resource("mac1.foreground", "Mac.Foreground",
1190                                       dpy, xgwa.colormap);
1191   gcv.background = get_pixel_resource("mac1.background", "Mac.Background",
1192                                       dpy, xgwa.colormap);
1193   XSetWindowBackground(dpy, window, gcv.background);
1194   XClearWindow(dpy, window);
1195
1196   gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
1197
1198   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) macbomb_bits,
1199                                        macbomb_width, macbomb_height,
1200                                        gcv.foreground,
1201                                        gcv.background,
1202                                        xgwa.depth);
1203
1204   {
1205     int x = (xgwa.width - pix_w) / 2;
1206     int y = (xgwa.height - pix_h) / 2;
1207     if (y < 0) y = 0;
1208     XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
1209     XSync(dpy, False);
1210     if (bsod_sleep(dpy, 1))
1211       goto DONE;
1212     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
1213   }
1214
1215  DONE:
1216   XFreeGC(dpy, gc);
1217   XFreePixmap(dpy, pixmap);
1218   XSync(dpy, False);
1219   bsod_sleep(dpy, delay);
1220   XClearWindow(dpy, window);
1221   return True;
1222 }
1223
1224
1225 static Bool
1226 macx (Display *dpy, Window window, int delay)
1227 {
1228   XGCValues gcv;
1229   XWindowAttributes xgwa;
1230   char *fontname = 0;
1231   const char *def_font = "fixed";
1232   XFontStruct *font;
1233   GC gc;
1234
1235   const char *macx_panic =
1236    ("panic(cpu 0): Unable to find driver for this platform: "
1237     "\"PowerMac 3,5\".\n"
1238     "\n"
1239     "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
1240     "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
1241     "\n"
1242     "\n"
1243     "\n"
1244     "No debugger configured - dumping debug information\n"
1245     "\n"
1246     "version string : Darwin Kernel Version 1.3:\n"
1247     "Thu Mar  1 06:56:40 PST 2001; root:xnu/xnu-123.5.obj~1/RELEASE_PPC\n"
1248     "\n"
1249     "\n"
1250     "\n"
1251     "\n"
1252     "DBAT0: 00000000 00000000\n"
1253     "DBAT1: 00000000 00000000\n"
1254     "DBAT2: 80001FFE 8000003A\n"
1255     "DBAT3: 90001FFE 9000003A\n"
1256     "MSR=00001030\n"
1257     "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
1258     "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
1259     "\n"
1260     "panic: We are hanging here...\n");
1261
1262   if (!get_boolean_resource("doMacX", "DoMacX"))
1263     return False;
1264
1265   XGetWindowAttributes (dpy, window, &xgwa);
1266
1267   gcv.background = get_pixel_resource("macX.background",
1268                                       "MacX.Background",
1269                                       dpy, xgwa.colormap);
1270   XSetWindowBackground(dpy, window, gcv.background);
1271   XClearWindow(dpy, window);
1272
1273   fontname = get_string_resource ((xgwa.height > 900
1274                                    ? "macX.font2"
1275                                    : "macX.font"),
1276                                   "MacX.Font");
1277   if (!fontname || !*fontname) fontname = (char *)def_font;
1278   font = XLoadQueryFont (dpy, fontname);
1279   if (!font) font = XLoadQueryFont (dpy, def_font);
1280   if (!font) exit(-1);
1281   if (fontname && fontname != def_font)
1282     free (fontname);
1283
1284   gcv.font = font->fid;
1285   gcv.foreground = get_pixel_resource("macsbug.foreground",
1286                                       "MacsBug.Foreground",
1287                                       dpy, xgwa.colormap);
1288   gcv.background = get_pixel_resource("macsbug.background",
1289                                       "MacsBug.Background",
1290                                       dpy, xgwa.colormap);
1291
1292
1293   gcv.foreground = get_pixel_resource("macX.textForeground",
1294                                       "MacX.TextForeground",
1295                                       dpy, xgwa.colormap);
1296   gcv.background = get_pixel_resource("macX.textBackground",
1297                                       "MacX.TextBackground",
1298                                       dpy, xgwa.colormap);
1299   gc = XCreateGC(dpy, window, GCForeground|GCBackground|GCFont, &gcv);
1300
1301 #if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
1302   {
1303     Pixmap pixmap = 0;
1304     Pixmap mask = 0;
1305     int x, y, pix_w, pix_h;
1306     pixmap = xpm_data_to_pixmap (dpy, window, (char **) happy_mac,
1307                                  &pix_w, &pix_h, &mask);
1308
1309     x = (xgwa.width - pix_w) / 2;
1310     y = (xgwa.height - pix_h) / 2;
1311     if (y < 0) y = 0;
1312     XSync(dpy, False);
1313     bsod_sleep(dpy, 2);
1314     XSetClipMask (dpy, gc, mask);
1315     XSetClipOrigin (dpy, gc, x, y);
1316     XCopyArea (dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
1317     XSetClipMask (dpy, gc, None);
1318     XFreePixmap (dpy, pixmap);
1319   }
1320 #endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
1321
1322   bsod_sleep(dpy, 3);
1323
1324   {
1325     const char *s;
1326     int x = 0, y = 0;
1327     int char_width, line_height;
1328     char_width = (font->per_char
1329                   ? font->per_char['n'-font->min_char_or_byte2].width
1330                   : font->min_bounds.width);
1331     line_height = font->ascent + font->descent;
1332
1333     s = macx_panic;
1334     y = font->ascent;
1335     while (*s)
1336       {
1337         int ox = x;
1338         int oy = y;
1339         if (*s == '\n' || x + char_width >= xgwa.width)
1340           {
1341             x = 0;
1342             y += line_height;
1343           }
1344
1345         if (*s == '\n')
1346           {
1347             /* Note that to get this goofy effect, they must be actually
1348                emitting LF CR at the end of each line instead of CR LF!
1349              */
1350             XDrawImageString (dpy, window, gc, ox, oy, " ", 1);
1351             XDrawImageString (dpy, window, gc, ox, y, " ", 1);
1352           }
1353         else
1354           {
1355             XDrawImageString (dpy, window, gc, x, y, s, 1);
1356             x += char_width;
1357           }
1358         s++;
1359       }
1360   }
1361
1362   XFreeGC(dpy, gc);
1363   XSync(dpy, False);
1364   bsod_sleep(dpy, delay);
1365   XClearWindow(dpy, window);
1366   return True;
1367 }
1368
1369
1370
1371
1372 \f
1373 /* blit damage
1374  *
1375  * by Martin Pool <mbp@samba.org>, Feb 2000.
1376  *
1377  * This is meant to look like the preferred failure mode of NCD
1378  * Xterms.  The parameters for choosing what to copy where might not
1379  * be quite right, but it looks about ugly enough.
1380  */
1381 static Bool
1382 blitdamage (Display *dpy, Window window, int delay)
1383 {
1384   XGCValues gcv;
1385   XWindowAttributes xwa;
1386   GC gc0;
1387   int i;
1388   int delta_x = 0, delta_y = 0;
1389   int w, h;
1390   int chunk_h, chunk_w;
1391   int steps;
1392   long gc_mask = 0;
1393   int src_x, src_y;
1394   int x, y;
1395   
1396   if (!get_boolean_resource("doBlitDamage", "DoBlitDamage"))
1397     return False;
1398
1399   XGetWindowAttributes(dpy, window, &xwa);
1400
1401   grab_screen_image(xwa.screen, window);
1402
1403   w = xwa.width;
1404   h = xwa.height;
1405
1406   gc_mask = GCForeground;
1407   
1408   gcv.plane_mask = random();
1409   gc_mask |= GCPlaneMask;
1410   
1411   gc0 = XCreateGC(dpy, window, gc_mask, &gcv);
1412
1413   steps = 50;
1414   chunk_w = w / (random() % 1 + 1);
1415   chunk_h = h / (random() % 1 + 1);
1416   if (random() & 0x1000) 
1417     delta_y = random() % 600;
1418   if (!delta_y || (random() & 0x2000))
1419     delta_x = random() % 600;
1420   src_x = 0; 
1421   src_y = 0; 
1422   x = 0;
1423   y = 0;
1424   
1425   for (i = 0; i < steps; i++) {
1426     if (x + chunk_w > w) 
1427       x -= w;
1428     else
1429       x += delta_x;
1430     
1431     if (y + chunk_h > h)
1432       y -= h;
1433     else
1434       y += delta_y;
1435     
1436     XCopyArea(dpy, window, window, gc0,
1437               src_x, src_y, 
1438               chunk_w, chunk_h,
1439               x, y);
1440
1441     if (bsod_sleep(dpy, 0))
1442       goto DONE;
1443   }
1444
1445   bsod_sleep(dpy, delay);
1446
1447  DONE:
1448   XFreeGC(dpy, gc0);
1449
1450   return True;
1451 }
1452
1453 \f
1454 /*
1455  * SPARC Solaris panic. Should look pretty authentic on Solaris boxes.
1456  * Anton Solovyev <solovam@earthlink.net>
1457  */ 
1458
1459 typedef struct
1460 {
1461   Display *dpy;
1462   Window window;
1463   GC gc, erase_gc;
1464   XFontStruct *xfs;
1465   int sub_width;                /* Text subwindow width in pixels */
1466   int sub_height;               /* Text subwindow height in pixels */
1467   int sub_x;                    /* upper left corner of the text subwindow */
1468   int sub_y;                    /* upper left corner of the text subwindow */
1469   int char_width;               /* Char width in pixels */
1470   int line_height;              /* Line height in pixels */
1471   int columns;                  /* Number of columns in the text screen */
1472   int x;                        /* horizontal position of the cursor */
1473 } scrolling_window;
1474
1475
1476 static scrolling_window *
1477 make_scrolling_window (Display *dpy, Window window,
1478                        const char *name,
1479                        Bool grab_screen_p)
1480 {
1481   const char *def_font = "fixed";
1482   scrolling_window* ts;
1483   XWindowAttributes xgwa;
1484   XGCValues gcv;
1485   char* fn;
1486   char buf1[100], buf2[100];
1487
1488   ts = malloc (sizeof (*ts));
1489   ts->window = window;
1490   ts->dpy = dpy;
1491
1492   ts->x = 0;
1493
1494   XGetWindowAttributes (dpy, window, &xgwa);
1495
1496   if (grab_screen_p)
1497     {
1498       ts->sub_width = xgwa.width * 0.8;
1499       ts->sub_height = xgwa.height * 0.8;
1500     }
1501   else
1502     {
1503       ts->sub_width  = xgwa.width - 20;
1504       ts->sub_height = xgwa.height - 20;
1505       if (ts->sub_width  < 20) ts->sub_width  = 20;
1506       if (ts->sub_height < 20) ts->sub_height = 20;
1507     }
1508
1509   sprintf (buf1, "%.50s.font", name);
1510   sprintf (buf2, "%.50s.Font", name);
1511   fn = get_string_resource (buf1, buf2);
1512   ts->xfs = XLoadQueryFont (dpy, fn);
1513   if (!ts->xfs)
1514     {
1515       sprintf (buf1, "%.50s.font2", name);
1516       fn = get_string_resource(buf1, buf2);
1517       ts->xfs = XLoadQueryFont(dpy, fn);
1518     }
1519   if (!ts->xfs)
1520     ts->xfs = XLoadQueryFont(dpy, def_font);
1521   if (!ts->xfs)
1522     exit (1);
1523   gcv.font = ts->xfs->fid;
1524   ts->char_width = (ts->xfs->per_char
1525                     ? ts->xfs->per_char['n'-ts->xfs->min_char_or_byte2].width
1526                     : ts->xfs->min_bounds.width);
1527   ts->line_height = ts->xfs->ascent + ts->xfs->descent + 1;
1528
1529   ts->columns = ts->sub_width / ts->char_width;
1530
1531   ts->sub_x = (xgwa.width - ts->sub_width) / 2;
1532   ts->sub_y = (xgwa.height - ts->sub_height) / 2;
1533
1534   if (!grab_screen_p) ts->sub_height += ts->sub_y, ts->sub_y = 0;
1535
1536   if (grab_screen_p)
1537     grab_screen_image (xgwa.screen, window);
1538
1539   sprintf (buf1, "%.50s.background", name);
1540   sprintf (buf2, "%.50s.Background", name);
1541   gcv.background = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
1542
1543   sprintf (buf1, "%.50s.foreground", name);
1544   sprintf (buf2, "%.50s.Foreground", name);
1545   gcv.foreground = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
1546
1547   ts->gc = XCreateGC (dpy, window,
1548                       GCForeground | GCBackground | GCFont,
1549                       &gcv);
1550   gcv.foreground = gcv.background;
1551   ts->erase_gc = XCreateGC (dpy, window,
1552                             GCForeground | GCBackground,
1553                             &gcv);
1554   XSetWindowBackground (dpy, window, gcv.background);
1555   return(ts);
1556 }
1557
1558 static void
1559 free_scrolling_window (scrolling_window* ts)
1560 {
1561   XFreeGC (ts->dpy, ts->gc);
1562   XFreeGC (ts->dpy, ts->erase_gc);
1563   XFreeFont (ts->dpy, ts->xfs);
1564   free (ts);
1565 }
1566
1567 static void
1568 scrolling_putc (scrolling_window* ts, const char aChar)
1569 {
1570   switch (aChar)
1571     {
1572     case '\n':
1573       ts->x = 0;
1574       XCopyArea (ts->dpy, ts->window, ts->window, ts->gc,
1575                  ts->sub_x, ts->sub_y + ts->line_height,
1576                  ts->sub_width, ts->sub_height,
1577                  ts->sub_x, ts->sub_y);
1578       XFillRectangle (ts->dpy, ts->window, ts->erase_gc,
1579                       ts->sub_x, ts->sub_y + ts->sub_height - ts->line_height,
1580                       ts->sub_width, ts->line_height);
1581       break;
1582     case '\b':
1583       if(ts->x > 0)
1584         ts->x--;
1585       break;
1586     default:
1587       if (ts->x >= ts->columns)
1588         scrolling_putc (ts, '\n');
1589       XDrawImageString (ts->dpy, ts->window, ts->gc,
1590                         (ts->sub_x +
1591                          (ts->x * ts->char_width)
1592                          - ts->xfs->min_bounds.lbearing),
1593                         (ts->sub_y + ts->sub_height - ts->xfs->descent),
1594                         &aChar, 1);
1595       ts->x++;
1596       break;
1597     }
1598 }
1599
1600 static Bool
1601 scrolling_puts (scrolling_window *ts, const char* aString, int delay)
1602 {
1603   const char *c;
1604   for (c = aString; *c; ++c)
1605     {
1606       scrolling_putc (ts, *c);
1607       if (delay)
1608         {
1609           XSync(ts->dpy, 0);
1610           usleep(delay);
1611           if (bsod_sleep (ts->dpy, 0))
1612             return True;
1613         }
1614     }
1615   XSync (ts->dpy, 0);
1616   return False;
1617 }
1618
1619 static Bool
1620 sparc_solaris (Display* dpy, Window window, int delay)
1621 {
1622   const char *msg1 =
1623     "BAD TRAP: cpu=0 type=0x31 rp=0x2a10043b5e0 addr=0xf3880 mmu_fsr=0x0\n"
1624     "BAD TRAP occured in module \"unix\" due to an illegal access to a"
1625     " user address.\n"
1626     "adb: trap type = 0x31\n"
1627     "addr=0xf3880\n"
1628     "pid=307, pc=0x100306e4, sp=0x2a10043ae81, tstate=0x4480001602,"
1629     " context=0x87f\n"
1630     "g1-g7: 1045b000, 32f, 10079440, 180, 300000ebde8, 0, 30000953a20\n"
1631     "Begin traceback... sp = 2a10043ae81\n"
1632     "Called from 100bd060, fp=2a10043af31, args=f3700 300008cc988 f3880 0"
1633     " 1 300000ebde0.\n"
1634     "Called from 101fe1bc, fp=2a10043b011, args=3000045a240 104465a0"
1635     " 300008e47d0 300008e48fa 300008ae350 300008ae410\n"
1636     "Called from 1007c520, fp=2a10043b0c1, args=300008e4878 300003596e8 0"
1637     " 3000045a320 0 3000045a220\n"
1638     "Called from 1007c498, fp=2a10043b171, args=1045a000 300007847f0 20"
1639     " 3000045a240 1 0\n"
1640     "Called from 1007972c, fp=2a10043b221, args=1 300009517c0 30000951e58 1"
1641     " 300007847f0 0\n"
1642     "Called from 10031e10, fp=2a10043b2d1, args=3000095b0c8 0 300009396a8"
1643     " 30000953a20 0 1\n"
1644     "Called from 10000bdd8, fp=ffffffff7ffff1c1, args=0 57 100131480"
1645     " 100131480 10012a6e0 0\n"
1646     "End traceback...\n"
1647     "panic[cpu0]/thread=30000953a20: trap\n"
1648     "syncing file systems...";
1649   const char *msg2 =
1650     " 1 done\n"
1651     "dumping to /dev/dsk/c0t0d0s3, offset 26935296\n";
1652   const char *msg3 =
1653     ": 2803 pages dumped, compression ratio 2.88, dump succeeded\n";
1654   const char *msg4 =
1655     "rebooting...\n"
1656     "Resetting ...";
1657
1658   scrolling_window *ts;
1659   int i;
1660   char buf[256];
1661
1662   if (!get_boolean_resource("doSolaris", "DoSolaris"))
1663     return False;
1664
1665   ts = make_scrolling_window (dpy, window, "Solaris", True);
1666
1667   scrolling_puts (ts, msg1, 0);
1668   if (bsod_sleep (dpy, 3))
1669     goto DONE;
1670
1671   scrolling_puts (ts, msg2, 0);
1672   if (bsod_sleep (dpy, 2))
1673     goto DONE;
1674
1675   for (i = 1; i <= 100; ++i)
1676     {
1677       sprintf(buf, "\b\b\b\b\b\b\b\b\b\b\b%3d%% done", i);
1678       scrolling_puts (ts, buf, 0);
1679       if (bsod_sleep (dpy, -1))
1680         goto DONE;
1681     }
1682
1683   scrolling_puts (ts, msg3, 0);
1684   if (bsod_sleep (dpy, 2))
1685     goto DONE;
1686
1687   scrolling_puts (ts, msg4, 0);
1688   if (bsod_sleep(dpy, 3))
1689     goto DONE;
1690
1691   bsod_sleep (dpy, 3);
1692
1693  DONE:
1694   free_scrolling_window (ts);
1695
1696   return True;
1697 }
1698
1699 /* Linux panic and fsck, by jwz
1700  */
1701 static Bool
1702 linux_fsck (Display *dpy, Window window, int delay)
1703 {
1704   XWindowAttributes xgwa;
1705   scrolling_window *ts;
1706   int i;
1707   const char *sysname;
1708   char buf[1024];
1709
1710   const char *linux_panic[] = {
1711    " kernel: Unable to handle kernel paging request at virtual "
1712      "address 0000f0ad\n",
1713    " kernel:  printing eip:\n",
1714    " kernel: c01becd7\n",
1715    " kernel: *pde = 00000000\n",
1716    " kernel: Oops: 0000\n",
1717    " kernel: CPU:    0\n",
1718    " kernel: EIP:    0010:[<c01becd7>]    Tainted: P \n",
1719    " kernel: EFLAGS: 00010286\n",
1720    " kernel: eax: 0000ff00   ebx: ca6b7e00   ecx: ce1d7a60   edx: ce1d7a60\n",
1721    " kernel: esi: ca6b7ebc   edi: 00030000   ebp: d3655ca0   esp: ca6b7e5c\n",
1722    " kernel: ds: 0018   es: 0018   ss: 0018\n",
1723    " kernel: Process crond (pid: 1189, stackpage=ca6b7000)\n",
1724    " kernel: Stack: d3655ca0 ca6b7ebc 00030054 ca6b7e7c c01c1e5b "
1725        "00000287 00000020 c01c1fbf \n",
1726    "",
1727    " kernel:        00005a36 000000dc 000001f4 00000000 00000000 "
1728        "ce046d40 00000001 00000000 \n",
1729    "", "", "",
1730    " kernel:        ffffffff d3655ca0 d3655b80 00030054 c01bef93 "
1731        "d3655ca0 ca6b7ebc 00030054 \n",
1732    "", "", "",
1733    " kernel: Call Trace:    [<c01c1e5b>] [<c01c1fbf>] [<c01bef93>] "
1734        "[<c01bf02b>] [<c0134c4f>]\n",
1735    "", "", "",
1736    " kernel:   [<c0142562>] [<c0114f8c>] [<c0134de3>] [<c010891b>]\n",
1737    " kernel: \n",
1738    " kernel: Code: 2a 00 75 08 8b 44 24 2c 85 c0 74 0c 8b 44 24 58 83 48 18 "
1739       "08 \n",
1740    0
1741   };
1742
1743   if (!get_boolean_resource("doLinux", "DoLinux"))
1744     return False;
1745
1746   XGetWindowAttributes (dpy, window, &xgwa);
1747   XSetWindowBackground (dpy, window, 
1748                         get_pixel_resource("Linux.background",
1749                                            "Linux.Background",
1750                                            dpy, xgwa.colormap));
1751   XClearWindow(dpy, window);
1752
1753   sysname = "linux";
1754 # ifdef HAVE_UNAME
1755   {
1756     struct utsname uts;
1757     char *s;
1758     if (uname (&uts) >= 0)
1759       sysname = uts.nodename;
1760     s = strchr (sysname, '.');
1761     if (s) *s = 0;
1762   }
1763 # endif /* !HAVE_UNAME */
1764
1765
1766   ts = make_scrolling_window (dpy, window, "Linux", False);
1767
1768   scrolling_puts (ts, "waiting for X server to shut down ", 0);
1769   usleep (100000);
1770   if (bsod_sleep (dpy, 0))
1771     goto PANIC;
1772   scrolling_puts (ts,
1773                   "XIO:  fatal IO error 2 (broken pipe) on X server \":0.0\"\n"
1774                   "        after 339471 requests (339471 known processed) "
1775                   "with 0 events remaining\n",
1776                   0);
1777   if (scrolling_puts (ts, ".........\n", 300000))
1778     goto PANIC;
1779   if (bsod_sleep (dpy, 0))
1780     goto PANIC;
1781   scrolling_puts (ts,
1782                   "xinit:  X server slow to shut down, sending KILL signal.\n",
1783                   0);
1784   scrolling_puts (ts, "waiting for server to die ", 0);
1785   if (scrolling_puts (ts, "...\n", 300000))
1786     goto PANIC;
1787   if (bsod_sleep (dpy, 0))
1788     goto PANIC;
1789   scrolling_puts (ts, "xinit:  Can't kill server\n", 0);
1790
1791   if (bsod_sleep (dpy, 2))
1792     goto PANIC;
1793
1794   sprintf (buf, "\n%s Login: ", sysname);
1795   scrolling_puts (ts, buf, 0);
1796   if (bsod_sleep (dpy, 1))
1797     goto PANIC;
1798   scrolling_puts (ts,
1799     "\n\n"
1800     "Parallelizing fsck version 1.22 (22-Jun-2001)\n"
1801     "e2fsck 1.22, 22-Jun-2001 for EXT2 FS 0.5b, 95/08/09\n"
1802     "Warning!  /dev/hda1 is mounted.\n"
1803     "/dev/hda1 contains a file system with errors, check forced.\n",
1804                 0);
1805   if (bsod_sleep (dpy, 1))
1806     goto PANIC;
1807
1808   if (0 == random() % 2)
1809   scrolling_puts (ts,
1810      "Couldn't find ext2 superblock, trying backup blocks...\n"
1811      "The filesystem size (according to the superblock) is 3644739 blocks\n"
1812      "The physical size of the device is 3636706 blocks\n"
1813      "Either the superblock or the partition table is likely to be corrupt!\n"
1814      "Abort<y>? no\n",
1815                 0);
1816   if (bsod_sleep (dpy, 1))
1817     goto PANIC;
1818
1819  AGAIN:
1820
1821   scrolling_puts (ts, "Pass 1: Checking inodes, blocks, and sizes\n", 0);
1822   if (bsod_sleep (dpy, 2))
1823     goto PANIC;
1824
1825   i = (random() % 60) - 20;
1826   while (--i > 0)
1827     {
1828       int b = random() % 0xFFFF;
1829       sprintf (buf, "Deleted inode %d has zero dtime.  Fix<y>? yes\n\n", b);
1830       scrolling_puts (ts, buf, 0);
1831     }
1832
1833   i = (random() % 40) - 10;
1834   if (i > 0)
1835     {
1836       int g = random() % 0xFFFF;
1837       int b = random() % 0xFFFFFFF;
1838
1839       if (bsod_sleep (dpy, 1))
1840         goto PANIC;
1841
1842       sprintf (buf, "Warning: Group %d's copy of the group descriptors "
1843                "has a bad block (%d).\n", g, b);
1844       scrolling_puts (ts, buf, 0);
1845
1846       b = random() % 0x3FFFFF;
1847       while (--i > 0)
1848         {
1849           b += random() % 0xFFFF;
1850           sprintf (buf,
1851                    "Error reading block %d (Attempt to read block "
1852                    "from filesystem resulted in short read) while doing "
1853                    "inode scan.  Ignore error<y>?",
1854                    b);
1855           scrolling_puts (ts, buf, 0);
1856           usleep (10000);
1857           scrolling_puts (ts, " yes\n\n", 0);
1858         }
1859     }
1860
1861   if (0 == (random() % 10))
1862     {
1863
1864       if (bsod_sleep (dpy, 1))
1865         goto PANIC;
1866
1867       i = 3 + (random() % 10);
1868       while (--i > 0)
1869         scrolling_puts (ts, "Could not allocate 256 block(s) for inode table: "
1870                         "No space left on device\n", 0);
1871       scrolling_puts (ts, "Restarting e2fsck from the beginning...\n", 0);
1872
1873       if (bsod_sleep (dpy, 2))
1874         goto PANIC;
1875
1876       goto AGAIN;
1877     }
1878
1879   i = (random() % 20) - 5;
1880
1881   if (i > 0)
1882     if (bsod_sleep (dpy, 1))
1883       goto PANIC;
1884
1885   while (--i > 0)
1886     {
1887       int j = 5 + (random() % 10);
1888       int w = random() % 4;
1889
1890       while (--j > 0)
1891         {
1892           int b = random() % 0xFFFFF;
1893           int g = random() % 0xFFF;
1894
1895           if (0 == (random() % 10))
1896             b = 0;
1897           else if (0 == (random() % 10))
1898             b = -1;
1899
1900           if (w == 0)
1901             sprintf (buf,
1902                      "Inode table for group %d not in group.  (block %d)\n"
1903                      "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
1904                      "Relocate<y>?",
1905                      g, b);
1906           else if (w == 1)
1907             sprintf (buf,
1908                      "Block bitmap for group %d not in group.  (block %d)\n"
1909                      "Relocate<y>?",
1910                      g, b);
1911           else if (w == 2)
1912             sprintf (buf,
1913                      "Inode bitmap %d for group %d not in group.\n"
1914                      "Continue<y>?",
1915                      b, g);
1916           else /* if (w == 3) */
1917             sprintf (buf,
1918                      "Bad block %d in group %d's inode table.\n"
1919                      "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
1920                      "Relocate<y>?",
1921                      b, g);
1922
1923           scrolling_puts (ts, buf, 0);
1924           scrolling_puts (ts, " yes\n\n", 0);
1925         }
1926       if (bsod_sleep (dpy, 0))
1927         goto PANIC;
1928       usleep (1000);
1929     }
1930
1931
1932   if (0 == random() % 10) goto PANIC;
1933   scrolling_puts (ts, "Pass 2: Checking directory structure\n", 0);
1934   if (bsod_sleep (dpy, 2))
1935     goto PANIC;
1936
1937   i = (random() % 20) - 5;
1938   while (--i > 0)
1939     {
1940       int n = random() % 0xFFFFF;
1941       int o = random() % 0xFFF;
1942       sprintf (buf, "Directory inode %d, block 0, offset %d: "
1943                "directory corrupted\n"
1944                "Salvage<y>? ",
1945                n, o);
1946       scrolling_puts (ts, buf, 0);
1947       usleep (1000);
1948       scrolling_puts (ts, " yes\n\n", 0);
1949
1950       if (0 == (random() % 100))
1951         {
1952           sprintf (buf, "Missing '.' in directory inode %d.\nFix<y>?", n);
1953           scrolling_puts (ts, buf, 0);
1954           usleep (1000);
1955           scrolling_puts (ts, " yes\n\n", 0);
1956         }
1957
1958       if (bsod_sleep (dpy, 0))
1959         goto PANIC;
1960     }
1961
1962   if (0 == random() % 10) goto PANIC;
1963   scrolling_puts (ts,
1964                   "Pass 3: Checking directory connectivity\n"
1965                   "/lost+found not found.  Create? yes\n",
1966                 0);
1967   if (bsod_sleep (dpy, 2))
1968     goto PANIC;
1969
1970   /* Unconnected directory inode 4949 (/var/spool/squid/06/???)
1971      Connect to /lost+found<y>? yes
1972
1973      '..' in /var/spool/squid/06/08 (20351) is <The NULL inode> (0), should be 
1974      /var/spool/squid/06 (20350).
1975      Fix<y>? yes
1976
1977      Unconnected directory inode 128337 (/var/spool/squid/06/???)
1978      Connect to /lost+found<y>? yes
1979    */
1980
1981
1982   if (0 == random() % 10) goto PANIC;
1983   scrolling_puts (ts, "Pass 4: Checking reference counts\n", 0);
1984   if (bsod_sleep (dpy, 2))
1985     goto PANIC;
1986
1987   /* Inode 2 ref count is 19, should be 20.  Fix<y>? yes
1988
1989      Inode 4949 ref count is 3, should be 2.  Fix<y>? yes
1990
1991         ...
1992
1993      Inode 128336 ref count is 3, should be 2.  Fix<y>? yes
1994
1995      Inode 128337 ref count is 3, should be 2.  Fix<y>? yes
1996
1997    */
1998
1999
2000   if (0 == random() % 10) goto PANIC;
2001   scrolling_puts (ts, "Pass 5: Checking group summary information\n", 0);
2002   if (bsod_sleep (dpy, 2))
2003     goto PANIC;
2004
2005   i = (random() % 200) - 50;
2006   if (i > 0)
2007     {
2008       scrolling_puts (ts, "Block bitmap differences: ", 0);
2009       while (--i > 0)
2010         {
2011           sprintf (buf, " %d", -(random() % 0xFFF));
2012           scrolling_puts (ts, buf, 0);
2013           usleep (1000);
2014         }
2015       scrolling_puts (ts, "\nFix? yes\n\n", 0);
2016     }
2017
2018
2019   i = (random() % 100) - 50;
2020   if (i > 0)
2021     {
2022       scrolling_puts (ts, "Inode bitmap differences: ", 0);
2023       while (--i > 0)
2024         {
2025           sprintf (buf, " %d", -(random() % 0xFFF));
2026           scrolling_puts (ts, buf, 0);
2027           usleep (1000);
2028         }
2029       scrolling_puts (ts, "\nFix? yes\n\n", 0);
2030     }
2031
2032   i = (random() % 20) - 5;
2033   while (--i > 0)
2034     {
2035       int g = random() % 0xFFFF;
2036       int c = random() % 0xFFFF;
2037       sprintf (buf,
2038                "Free blocks count wrong for group #0 (%d, counted=%d).\nFix? ",
2039                g, c);
2040       scrolling_puts (ts, buf, 0);
2041       usleep (1000);
2042       scrolling_puts (ts, " yes\n\n", 0);
2043       if (bsod_sleep (dpy, 0))
2044         goto PANIC;
2045     }
2046
2047  PANIC:
2048
2049   i = 0;
2050   scrolling_puts (ts, "\n\n", 0);
2051   while (linux_panic[i])
2052     {
2053       time_t t = time ((time_t *) 0);
2054       struct tm *tm = localtime (&t);
2055       char prefix[100];
2056
2057       if (*linux_panic[i])
2058         {
2059           strftime (prefix, sizeof(prefix)-1, "%b %d %k:%M:%S ", tm);
2060           scrolling_puts (ts, prefix, 0);
2061           scrolling_puts (ts, sysname, 0);
2062           scrolling_puts (ts, linux_panic[i], 0);
2063           XSync(dpy, False);
2064           usleep(1000);
2065         }
2066       else
2067         usleep (300000);
2068
2069       if (bsod_sleep (dpy, 0))
2070         goto DONE;
2071       i++;
2072     }
2073
2074   if (bsod_sleep (dpy, 4))
2075     goto DONE;
2076
2077
2078   XSync(dpy, False);
2079   bsod_sleep(dpy, delay);
2080
2081  DONE:
2082   free_scrolling_window (ts);
2083   XClearWindow(dpy, window);
2084   return True;
2085 }
2086
2087
2088 \f
2089 char *progclass = "BSOD";
2090
2091 char *defaults [] = {
2092   "*delay:                 30",
2093
2094   "*doWindows:             True",
2095   "*doNT:                  True",
2096   "*doWin2K:               True",
2097   "*doAmiga:               True",
2098   "*doMac:                 True",
2099   "*doMacsBug:             True",
2100   "*doMac1:                True",
2101   "*doMacX:                True",
2102   "*doSCO:                 True",
2103   "*doAtari:               False",      /* boring */
2104   "*doBSD:                 False",      /* boring */
2105   "*doLinux:               True",
2106   "*doSparcLinux:          False",      /* boring */
2107   "*doBlitDamage:          True",
2108   "*doSolaris:             True",
2109
2110   ".Windows.font:          -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2111   ".Windows.font2:         -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
2112   ".Windows.foreground:    White",
2113   ".Windows.background:    #0000AA",    /* EGA color 0x01. */
2114
2115   ".Amiga.font:            -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2116   ".Amiga.font2:           -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
2117   ".Amiga.foreground:      Red",
2118   ".Amiga.background:      Black",
2119   ".Amiga.background2:     White",
2120
2121   ".Mac.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2122   ".Mac.foreground:        PaleTurquoise1",
2123   ".Mac.background:        Black",
2124
2125   ".Atari.foreground:      Black",
2126   ".Atari.background:      White",
2127
2128   ".MacsBug.font:          -*-courier-medium-r-*-*-*-100-*-*-m-*-*-*",
2129   ".MacsBug.font2:         -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2130   ".MacsBug.font3:         -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2131   ".MacsBug.foreground:    Black",
2132   ".MacsBug.background:    White",
2133   ".MacsBug.borderColor:   #AAAAAA",
2134
2135   ".mac1.foreground:       Black",
2136   ".mac1.background:       White",
2137
2138   ".macX.textForeground:   White",
2139   ".macX.textBackground:   Black",
2140   ".macX.background:       #888888",
2141   ".macX.font:             -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2142   ".macX.font2:            -*-courier-bold-r-*-*-*-240-*-*-m-*-*-*",
2143
2144   ".SCO.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2145   ".SCO.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2146   ".SCO.foreground:        White",
2147   ".SCO.background:        Black",
2148
2149   ".Linux.font:            9x15bold",
2150   ".Linux.font2:           -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2151   ".Linux.foreground: White",
2152   ".Linux.background: Black",
2153
2154   ".SparcLinux.font:       -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2155   ".SparcLinux.font2:      -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2156   ".SparcLinux.foreground: White",
2157   ".SparcLinux.background: Black",
2158
2159   ".BSD.font:               vga",
2160   ".BSD.font:               -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
2161   ".BSD.font2:              -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2162 /* ".BSD.font2:             -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", */
2163   ".BSD.foreground:         #c0c0c0",
2164   ".BSD.background:         Black",
2165
2166   ".Solaris.font:           -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
2167   ".Solaris.font2:          -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
2168   ".Solaris.foreground:     Black",
2169   ".Solaris.background:     White",
2170   "*dontClearRoot:          True",
2171   0
2172 };
2173
2174 XrmOptionDescRec options [] = {
2175   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
2176   { "-windows",         ".doWindows",           XrmoptionNoArg,  "True"  },
2177   { "-no-windows",      ".doWindows",           XrmoptionNoArg,  "False" },
2178   { "-nt",              ".doNT",                XrmoptionNoArg,  "True"  },
2179   { "-no-nt",           ".doNT",                XrmoptionNoArg,  "False" },
2180   { "-2k",              ".doWin2K",             XrmoptionNoArg,  "True"  },
2181   { "-no-2k",           ".doWin2K",             XrmoptionNoArg,  "False" },
2182   { "-amiga",           ".doAmiga",             XrmoptionNoArg,  "True"  },
2183   { "-no-amiga",        ".doAmiga",             XrmoptionNoArg,  "False" },
2184   { "-mac",             ".doMac",               XrmoptionNoArg,  "True"  },
2185   { "-no-mac",          ".doMac",               XrmoptionNoArg,  "False" },
2186   { "-mac1",            ".doMac1",              XrmoptionNoArg,  "True"  },
2187   { "-no-mac1",         ".doMac1",              XrmoptionNoArg,  "False" },
2188   { "-no-macx",         ".doMacX",              XrmoptionNoArg,  "False" },
2189   { "-atari",           ".doAtari",             XrmoptionNoArg,  "True"  },
2190   { "-no-atari",        ".doAtari",             XrmoptionNoArg,  "False" },
2191   { "-macsbug",         ".doMacsBug",           XrmoptionNoArg,  "True"  },
2192   { "-no-macsbug",      ".doMacsBug",           XrmoptionNoArg,  "False" },
2193   { "-sco",             ".doSCO",               XrmoptionNoArg,  "True"  },
2194   { "-no-sco",          ".doSCO",               XrmoptionNoArg,  "False" },
2195   { "-bsd",             ".doBSD",               XrmoptionNoArg,  "True"  },
2196   { "-no-bsd",          ".doBSD",               XrmoptionNoArg,  "False" },
2197   { "-linux",           ".doLinux",             XrmoptionNoArg,  "True" },
2198   { "-no-linux",        ".doLinux",             XrmoptionNoArg,  "False" },
2199   { "-sparclinux",      ".doSparcLinux",        XrmoptionNoArg,  "True"  },
2200   { "-no-sparclinux",   ".doSparcLinux",        XrmoptionNoArg,  "False" },
2201   { "-blitdamage",      ".doBlitDamage",        XrmoptionNoArg,  "True"  },
2202   { "-no-blitdamage",   ".doBlitDamage",        XrmoptionNoArg,  "False" },
2203   { "-solaris",         ".doSolaris",           XrmoptionNoArg,  "True"  },
2204   { "-no-solaris",      ".doSolaris",           XrmoptionNoArg,  "False" },
2205   { 0, 0, 0, 0 }
2206 };
2207
2208
2209 void
2210 screenhack (Display *dpy, Window window)
2211 {
2212   int loop = 0;
2213   int i = -1;
2214   int j = -1;
2215   int delay = get_integer_resource ("delay", "Integer");
2216   if (delay < 3) delay = 3;
2217
2218   if (!get_boolean_resource ("root", "Boolean"))
2219     {
2220       XWindowAttributes xgwa;
2221       XGetWindowAttributes (dpy, window, &xgwa);
2222       XSelectInput (dpy, window,
2223                     xgwa.your_event_mask | KeyPressMask | ButtonPressMask);
2224     }
2225
2226   while (1)
2227     {
2228       Bool did;
2229       do {  i = (random() & 0xFF) % 15; } while (i == j);
2230       switch (i)
2231         {
2232         case 0:  did = windows(dpy, window, delay, 0); break;
2233         case 1:  did = windows(dpy, window, delay, 1); break;
2234         case 2:  did = windows(dpy, window, delay, 2); break;
2235         case 3:  did = amiga(dpy, window, delay); break;
2236         case 4:  did = mac(dpy, window, delay); break;
2237         case 5:  did = macsbug(dpy, window, delay); break;
2238         case 6:  did = mac1(dpy, window, delay); break;
2239         case 7:  did = macx(dpy, window, delay); break;
2240         case 8:  did = sco(dpy, window, delay); break;
2241         case 9:  did = sparc_linux(dpy, window, delay); break;
2242         case 10: did = bsd(dpy, window, delay); break;
2243         case 11: did = atari(dpy, window, delay); break;
2244         case 12: did = blitdamage(dpy, window, delay); break;
2245         case 13: did = sparc_solaris(dpy, window, delay); break;
2246         case 14: did = linux_fsck(dpy, window, delay); break;
2247         default: abort(); break;
2248         }
2249       loop++;
2250       if (loop > 100) j = -1;
2251       if (loop > 200)
2252         {
2253           fprintf (stderr, "%s: no display modes enabled?\n", progname);
2254           exit(-1);
2255         }
2256       if (!did) continue;
2257       XSync (dpy, False);
2258       j = i;
2259       loop = 0;
2260     }
2261 }