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