http://ftp.ksu.edu.tw/FTP/FreeBSD/distfiles/xscreensaver-4.20.tar.gz
[xscreensaver] / hacks / bsod.c
1 /* xscreensaver, Copyright (c) 1998-2005 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 <math.h>
17 #include "screenhack.h"
18 #include "xpm-pixmap.h"
19 #include "apple2.h"
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <time.h>
23 #include <sys/time.h>
24 #include <X11/Xutil.h>
25
26 #ifdef HAVE_XSHM_EXTENSION
27 #include "xshm.h"
28 #endif
29
30 #ifdef HAVE_UNAME
31 # include <sys/utsname.h>
32 #endif /* HAVE_UNAME */
33
34 #include "images/amiga.xpm"
35 #include "images/atari.xbm"
36 #include "images/mac.xbm"
37 #include "images/macbomb.xbm"
38 #include "images/hmac.xpm"
39
40 #undef countof
41 #define countof(x) (sizeof((x))/sizeof((*x)))
42
43 static int
44 draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
45              XFontStruct *font,
46              int xoff, int yoff,
47              int win_width, int win_height,
48              const char *string, int delay)
49 {
50   int x, y;
51   int width = 0, height = 0, cw = 0;
52   int char_width, line_height;
53
54   const char *s = string;
55   const char *se = string;
56
57   /* This pretty much assumes fixed-width fonts */
58   char_width = (font->per_char
59                 ? font->per_char['n'-font->min_char_or_byte2].width
60                 : font->min_bounds.width);
61   line_height = font->ascent + font->descent + 1;
62
63   while (1)
64     {
65       if (*s == '\n' || !*s)
66         {
67           height++;
68           if (cw > width) width = cw;
69           cw = 0;
70           if (!*s) break;
71         }
72       else
73         cw++;
74       s++;
75     }
76
77   x = (win_width - (width * char_width)) / 2;
78   y = (win_height - (height * line_height)) / 2;
79
80   if (x < 0) x = 2;
81   if (y < 0) y = 2;
82
83   x += xoff;
84   y += yoff;
85
86   se = s = string;
87   while (1)
88     {
89       if (*s == '\n' || !*s)
90         {
91           int off = 0;
92           Bool flip = False;
93
94           if (*se == '@' || *se == '_')
95             {
96               if (*se == '@') flip = True;
97               se++;
98               off = (char_width * (width - (s - se))) / 2;
99             }
100
101           if (flip)
102             {
103               XSetForeground(dpy, gc, gcv->background);
104               XSetBackground(dpy, gc, gcv->foreground);
105             }
106
107           if (s != se)
108             XDrawImageString(dpy, window, gc, x+off, y+font->ascent, se, s-se);
109
110           if (flip)
111             {
112               XSetForeground(dpy, gc, gcv->foreground);
113               XSetBackground(dpy, gc, gcv->background);
114             }
115
116           se = s;
117           y += line_height;
118           if (!*s) break;
119           se = s+1;
120
121           if (delay)
122             {
123               XSync(dpy, False);
124               usleep(delay);
125             }
126         }
127       s++;
128     }
129
130   return width * char_width;
131 }
132
133
134 static Pixmap
135 double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
136              int pix_w, int pix_h)
137 {
138   int x, y;
139   Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth);
140   XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap);
141   XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0,
142                             pix_w*2, pix_h*2, 8, 0);
143   i2->data = (char *) calloc(i2->height, i2->bytes_per_line);
144   for (y = 0; y < pix_h; y++)
145     for (x = 0; x < pix_w; x++)
146       {
147         unsigned long p = XGetPixel(i1, x, y);
148         XPutPixel(i2, x*2,   y*2,   p);
149         XPutPixel(i2, x*2+1, y*2,   p);
150         XPutPixel(i2, x*2,   y*2+1, p);
151         XPutPixel(i2, x*2+1, y*2+1, p);
152       }
153   free(i1->data); i1->data = 0;
154   XDestroyImage(i1);
155   XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height);
156   free(i2->data); i2->data = 0;
157   XDestroyImage(i2);
158   XFreePixmap(dpy, pixmap);
159   return p2;
160 }
161
162
163 /* Sleep for N seconds and return False.  But if a key or mouse event is
164    seen, discard all pending key or mouse events, and return True.
165  */
166 static Bool
167 bsod_sleep(Display *dpy, int seconds)
168 {
169   int q = seconds * 4;
170   int quantum = 250000;
171
172   if (seconds == -1)
173     q = 1, quantum = 100000;
174
175   do
176     {
177       XSync(dpy, False);
178       while (XPending (dpy))
179         {
180           XEvent event;
181           XNextEvent (dpy, &event);
182           if (event.xany.type == ButtonPress)
183             return True;
184           if (event.xany.type == KeyPress)
185             {
186               KeySym keysym;
187               char c = 0;
188               XLookupString (&event.xkey, &c, 1, &keysym, 0);
189               if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
190                 return True;
191             }
192           screenhack_handle_event (dpy, &event);
193         }
194
195       if (q > 0)
196         {
197           q--;
198           usleep(quantum);
199         }
200     }
201   while (q > 0);
202
203   return False; 
204 }
205
206
207 static void
208 windows (Display *dpy, Window window, int delay, int which)
209 {
210   XGCValues gcv;
211   XWindowAttributes xgwa;
212   char *fontname;
213   const char *def_font = "fixed";
214   XFontStruct *font;
215   GC gc;
216
217   const char *w95 =
218     ("@Windows\n"
219      "A fatal exception 0E has occured at F0AD:42494C4C\n"
220      "the current application will be terminated.\n"
221      "\n"
222      "* Press any key to terminate the current application.\n"
223      "* Press CTRL+ALT+DELETE again to restart your computer.\n"
224      "  You will lose any unsaved information in all applications.\n"
225      "\n"
226      "\n"
227      "_Press any key to continue");
228
229 # ifdef __GNUC__
230   __extension__   /* don't warn about "string length is greater than the
231                      length ISO C89 compilers are required to support"
232                      in the following string constant... */
233 # endif
234
235   const char *wnt = /* from Jim Niemira <urmane@urmane.org> */
236     ("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
237    "Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
238    "\n"
239    "Dll Base Date Stamp - Name             Dll Base Date Stamp - Name\n"
240    "80100000 2be154c9 - ntoskrnl.exe       80400000 2bc153b0 - hal.dll\n"
241    "80258000 2bd49628 - ncrc710.sys        8025c000 2bd49688 - SCSIPORT.SYS \n"
242    "80267000 2bd49683 - scsidisk.sys       802a6000 2bd496b9 - Fastfat.sys\n"
243    "fa800000 2bd49666 - Floppy.SYS         fa810000 2bd496db - Hpfs_Rec.SYS\n"
244    "fa820000 2bd49676 - Null.SYS           fa830000 2bd4965a - Beep.SYS\n"
245    "fa840000 2bdaab00 - i8042prt.SYS       fa850000 2bd5a020 - SERMOUSE.SYS\n"
246    "fa860000 2bd4966f - kbdclass.SYS       fa870000 2bd49671 - MOUCLASS.SYS\n"
247    "fa880000 2bd9c0be - Videoprt.SYS       fa890000 2bd49638 - NCC1701E.SYS\n"
248    "fa8a0000 2bd4a4ce - Vga.SYS            fa8b0000 2bd496d0 - Msfs.SYS\n"
249    "fa8c0000 2bd496c3 - Npfs.SYS           fa8e0000 2bd496c9 - Ntfs.SYS\n"
250    "fa940000 2bd496df - NDIS.SYS           fa930000 2bd49707 - wdlan.sys\n"
251    "fa970000 2bd49712 - TDI.SYS            fa950000 2bd5a7fb - nbf.sys\n"
252    "fa980000 2bd72406 - streams.sys        fa9b0000 2bd4975f - ubnb.sys\n"
253    "fa9c0000 2bd5bfd7 - usbser.sys         fa9d0000 2bd4971d - netbios.sys\n"
254    "fa9e0000 2bd49678 - Parallel.sys       fa9f0000 2bd4969f - serial.SYS\n"
255    "faa00000 2bd49739 - mup.sys            faa40000 2bd4971f - SMBTRSUP.SYS\n"
256    "faa10000 2bd6f2a2 - srv.sys            faa50000 2bd4971a - afd.sys\n"
257    "faa60000 2bd6fd80 - rdr.sys            faaa0000 2bd49735 - bowser.sys\n"
258    "\n"
259    "Address dword dump Dll Base                                      - Name\n"
260    "801afc20 80106fc0 80106fc0 00000000 00000000 80149905 : "
261      "fa840000 - i8042prt.SYS\n"
262    "801afc24 80149905 80149905 ff8e6b8c 80129c2c ff8e6b94 : "
263      "8025c000 - SCSIPORT.SYS\n"
264    "801afc2c 80129c2c 80129c2c ff8e6b94 00000000 ff8e6b94 : "
265      "80100000 - ntoskrnl.exe\n"
266    "801afc34 801240f2 80124f02 ff8e6df4 ff8e6f60 ff8e6c58 : "
267      "80100000 - ntoskrnl.exe\n"
268    "801afc54 80124f16 80124f16 ff8e6f60 ff8e6c3c 8015ac7e : "
269      "80100000 - ntoskrnl.exe\n"
270    "801afc64 8015ac7e 8015ac7e ff8e6df4 ff8e6f60 ff8e6c58 : "
271      "80100000 - ntoskrnl.exe\n"
272    "801afc70 80129bda 80129bda 00000000 80088000 80106fc0 : "
273      "80100000 - ntoskrnl.exe\n"
274    "\n"
275    "Kernel Debugger Using: COM2 (Port 0x2f8, Baud Rate 19200)\n"
276    "Restart and set the recovery options in the system control panel\n"
277    "or the /CRASHDEBUG system start option. If this message reappears,\n"
278    "contact your system administrator or technical support group."
279      );
280
281   const char *w2ka =
282     ("*** STOP: 0x000000D1 (0xE1D38000,0x0000001C,0x00000000,0xF09D42DA)\n"
283      "DRIVER_IRQL_NOT_LESS_OR_EQUAL \n"
284      "\n"
285     "*** Address F09D42DA base at F09D4000, DateStamp 39f459ff - CRASHDD.SYS\n"
286      "\n"
287      "Beginning dump of physical memory\n");
288   const char *w2kb =
289     ("Physical memory dump complete. Contact your system administrator or\n"
290      "technical support group.\n");
291
292   const char *wmea =
293     ("    Windows protection error.  You need to restart your computer.");
294   const char *wmeb =
295     ("    System halted.");
296
297 # ifdef __GNUC__
298   __extension__   /* don't warn about "string length is greater than the
299                      length ISO C89 compilers are required to support"
300                      in the following string constant... */
301 # endif
302
303   const char *wxpa = /* From Wm. Rhodes <xscreensaver@27.org> */
304     ("A problem has been detected and windows has been shut down to prevent "
305       "damage\n"
306       "to your computer.\n"
307       "\n"
308       "If this is the first time you've seen this Stop error screen,\n"
309       "restart your computer. If this screen appears again, follow\n"
310       "these steps:\n"
311       "\n"
312       "Check to be sure you have adequate disk space. If a driver is\n"
313       "identified in the Stop message, disable the driver or check\n"
314       "with the manufacturer for driver updates. Try changing video\n"
315       "adapters.\n"
316       "\n"
317       "Check with your hardware vendor for any BIOS updates. Disable\n"
318       "BIOS memory options such as caching or shadowing. If you need\n"
319       "to use Safe Mode to remove or disable components, restart your\n"
320       "computer, press F8 to select Advanced Startup Options, and then\n"
321       "select Safe Mode.\n"
322       "\n"
323       "Technical information:\n"
324       "\n"
325       "*** STOP: 0x0000007E (0xC0000005,0xF88FF190,0x0xF8975BA0,0xF89758A0)\n"
326       "\n"
327       "\n"
328       "***  EPUSBDSK.sys - Address F88FF190 base at FF88FE000, datestamp "
329       "3b9f3248\n"
330       "\n"
331       "Beginning dump of physical memory\n");
332   const char *wxpb =
333     ("Physical memory dump complete.\n"
334      "Contact your system administrator or technical support group for "
335      "further\n"
336      "assitance.\n"
337      );
338
339   if (which < 0 || which > 2) abort();
340
341   /* kludge to lump Win2K, WinME, and WinXP together; seems silly to add
342      another preference/command line option just for these little ones. */
343   if (which == 2 && (random() % 2))
344     which = 3 + (random() % 2);
345
346   XGetWindowAttributes (dpy, window, &xgwa);
347
348   fontname = get_string_resource ((xgwa.height > 600
349                                    ? (which == 0 ? "windows95.font2" :
350                                       which == 1 ? "windowsNT.font2" :
351                                       which == 2 ? "windows2K.font2" :
352                                                    "windowsME.font2")
353                                    : (which == 0 ? "windows95.font" :
354                                       which == 1 ? "windowsNT.font" :
355                                       which == 2 ? "windows2K.font" :
356                                                    "windowsME.font")),
357                                   "Windows.Font");
358   if (!fontname || !*fontname) fontname = (char *)def_font;
359   font = XLoadQueryFont (dpy, fontname);
360   if (!font) font = XLoadQueryFont (dpy, def_font);
361   if (!font) exit(-1);
362   if (fontname && fontname != def_font)
363     free (fontname);
364
365   gcv.font = font->fid;
366   gcv.foreground = get_pixel_resource((which == 0 ? "windows95.foreground" :
367                                        which == 1 ? "windowsNT.foreground" :
368                                        which == 2 ? "windows2K.foreground" :
369                                                     "windowsME.foreground"),
370                                       "Windows.Foreground",
371                                       dpy, xgwa.colormap);
372   gcv.background = get_pixel_resource((which == 0 ? "windows95.background" :
373                                        which == 1 ? "windowsNT.background" :
374                                        which == 2 ? "windows2K.background" :
375                                                     "windowsME.background"),
376                                       "Windows.Background",
377                                       dpy, xgwa.colormap);
378   XSetWindowBackground(dpy, window, gcv.background);
379   XClearWindow(dpy, window);
380
381   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
382
383   if (which == 0)
384     draw_string(dpy, window, gc, &gcv, font,
385                 0, 0, xgwa.width, xgwa.height, w95, 0);
386   else if (which == 1)
387     draw_string(dpy, window, gc, &gcv, font, 0, 0, 10, 10, wnt, 750);
388   else if (which == 2)
389     {
390       int line_height = font->ascent + font->descent + 1;
391       int x = 20;
392       int y = (xgwa.height / 4);
393
394       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, w2ka, 750);
395       y += line_height * 6;
396       bsod_sleep(dpy, 4);
397       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, w2kb, 750);
398     }
399   else if (which == 3)
400     {
401       int line_height = font->ascent + font->descent + 1;
402       int x = 4;
403       int y = 4;
404       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, wxpa, 750);
405       y += line_height * 26;
406       bsod_sleep(dpy, 4);
407       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, wxpb, 750);
408     }
409   else if (which == 4)
410     {
411       int line_height = font->ascent + font->descent;
412       int x = 0;
413       int y = (xgwa.height - line_height * 3) / 2;
414       draw_string (dpy, window, gc, &gcv, font, x, y, 10, 10, wmea, 0);
415       y += line_height * 2;
416       x = draw_string (dpy, window, gc, &gcv, font, x, y, 10, 10, wmeb, 0);
417       y += line_height;
418       while (delay > 0)
419         {
420           XDrawImageString (dpy, window, gc, x, y, "_", 1);
421           XSync(dpy, False);
422           usleep(120000L);
423           XDrawImageString (dpy, window, gc, x, y, " ", 1);
424           XSync(dpy, False);
425           usleep(120000L);
426           if (bsod_sleep(dpy, 0))
427             delay = 0;
428           else
429             delay--;
430         }
431     }
432   else
433     abort();
434
435   XFreeGC(dpy, gc);
436   XSync(dpy, False);
437   bsod_sleep(dpy, delay);
438   XClearWindow(dpy, window);
439   XFreeFont(dpy, font);
440 }
441
442 static void
443 windows_31 (Display *dpy, Window window, int delay)
444 {
445   windows (dpy, window, delay, 0);
446 }
447
448 static void
449 windows_nt (Display *dpy, Window window, int delay)
450 {
451   windows (dpy, window, delay, 1);
452 }
453
454 static void
455 windows_2k (Display *dpy, Window window, int delay)
456 {
457   windows (dpy, window, delay, 2);
458 }
459
460
461 /* SCO OpenServer 5 panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
462  */
463 static void
464 sco (Display *dpy, Window window, int delay)
465 {
466   XGCValues gcv;
467   XWindowAttributes xgwa;
468   char *fontname;
469   const char *def_font = "fixed";
470   XFontStruct *font;
471   GC gc;
472   int lines_1 = 0, lines_2 = 0, lines_3 = 0, lines_4 = 0;
473   const char *s;
474
475 # ifdef __GNUC__
476   __extension__   /* don't warn about "string length is greater than the
477                      length ISO C89 compilers are required to support"
478                      in the following string constant... */
479 # endif
480
481   const char *sco_panic_1 =
482     ("Unexpected trap in kernel mode:\n"
483      "\n"
484      "cr0 0x80010013     cr2  0x00000014     cr3 0x00000000  tlb  0x00000000\n"
485      "ss  0x00071054    uesp  0x00012055     efl 0x00080888  ipl  0x00000005\n"
486      "cs  0x00092585     eip  0x00544a4b     err 0x004d4a47  trap 0x0000000E\n"
487      "eax 0x0045474b     ecx  0x0042544b     edx 0x57687920  ebx  0x61726520\n"
488      "esp 0x796f7520     ebp  0x72656164     esi 0x696e6720  edi  0x74686973\n"
489      "ds  0x3f000000     es   0x43494c48     fs  0x43525343  gs   0x4f4d4b53\n"
490      "\n"
491      "PANIC: k_trap - kernel mode trap type 0x0000000E\n"
492      "Trying to dump 5023 pages to dumpdev hd (1/41), 63 pages per '.'\n"
493     );
494   const char *sco_panic_2 =
495    ("................................................................."
496     "..............\n"
497     );
498   const char *sco_panic_3 =
499     ("5023 pages dumped\n"
500      "\n"
501      "\n"
502      );
503   const char *sco_panic_4 =
504     ("**   Safe to Power Off   **\n"
505      "           - or -\n"
506      "** Press Any Key to Reboot **\n"
507     );
508
509   for (s = sco_panic_1; *s; s++) if (*s == '\n') lines_1++;
510   for (s = sco_panic_2; *s; s++) if (*s == '\n') lines_2++;
511   for (s = sco_panic_3; *s; s++) if (*s == '\n') lines_3++;
512   for (s = sco_panic_4; *s; s++) if (*s == '\n') lines_4++;
513
514   XGetWindowAttributes (dpy, window, &xgwa);
515
516   fontname = get_string_resource ((xgwa.height > 600
517                                    ? "sco.font2"
518                                    : "sco.font"),
519                                   "SCO.Font");
520   if (!fontname || !*fontname) fontname = (char *)def_font;
521   font = XLoadQueryFont (dpy, fontname);
522   if (!font) font = XLoadQueryFont (dpy, def_font);
523   if (!font) exit(-1);
524   if (fontname && fontname != def_font)
525     free (fontname);
526
527   gcv.font = font->fid;
528   gcv.foreground = get_pixel_resource(("sco.foreground"),
529                                       "SCO.Foreground",
530                                       dpy, xgwa.colormap);
531   gcv.background = get_pixel_resource(("sco.background"),
532                                       "SCO.Background",
533                                       dpy, xgwa.colormap);
534   XSetWindowBackground(dpy, window, gcv.background);
535   XClearWindow(dpy, window);
536
537   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
538
539   draw_string(dpy, window, gc, &gcv, font,
540               10, xgwa.height - ((lines_1 + lines_2 + lines_3 + lines_4 + 1) *
541                                  (font->ascent + font->descent + 1)),
542               10, 10,
543               sco_panic_1, 0);
544   XSync(dpy, False);
545   for (s = sco_panic_2; *s; s++)
546     {
547       char *ss = strdup(sco_panic_2);
548       ss[s - sco_panic_2] = 0;
549       draw_string(dpy, window, gc, &gcv, font,
550                   10, xgwa.height - ((lines_2 + lines_3 + lines_4 + 1) *
551                                      (font->ascent + font->descent + 1)),
552                   10, 10,
553                   ss, 0);
554       XSync(dpy, False);
555       free(ss);
556       if (bsod_sleep (dpy, -1))
557         goto DONE;
558     }
559
560   draw_string(dpy, window, gc, &gcv, font,
561               10, xgwa.height - ((lines_3 + lines_4 + 1) *
562                                  (font->ascent + font->descent + 1)),
563               10, 10,
564               sco_panic_3, 0);
565   XSync(dpy, False);
566   if (bsod_sleep(dpy, 1))
567     goto DONE;
568   draw_string(dpy, window, gc, &gcv, font,
569               10, xgwa.height - ((lines_4 + 1) *
570                                  (font->ascent + font->descent + 1)),
571               10, 10,
572               sco_panic_4, 0);
573   XSync(dpy, False);
574
575   bsod_sleep(dpy, delay);
576  DONE:
577   XClearWindow(dpy, window);
578   XFreeGC(dpy, gc);
579   XFreeFont(dpy, font);
580 }
581
582
583 /* Linux (sparc) panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
584  */
585 static void
586 sparc_linux (Display *dpy, Window window, int delay)
587 {
588   XGCValues gcv;
589   XWindowAttributes xgwa;
590   char *fontname;
591   const char *def_font = "fixed";
592   XFontStruct *font;
593   GC gc;
594   int lines = 1;
595   const char *s;
596
597 # ifdef __GNUC__
598   __extension__   /* don't warn about "string length is greater than the
599                      length ISO C89 compilers are required to support"
600                      in the following string constant... */
601 # endif
602
603   const char *linux_panic =
604     ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
605         "Unable to handle kernel paging request at virtual address f0d4a000\n"
606         "tsk->mm->context = 00000014\n"
607         "tsk->mm->pgd = f26b0000\n"
608         "              \\|/ ____ \\|/\n"
609         "              \"@'/ ,. \\`@\"\n"
610         "              /_| \\__/ |_\\\n"
611         "                 \\__U_/\n"
612         "gawk(22827): Oops\n"
613         "PSR: 044010c1 PC: f001c2cc NPC: f001c2d0 Y: 00000000\n"
614         "g0: 00001000 g1: fffffff7 g2: 04401086 g3: 0001eaa0\n"
615         "g4: 000207dc g5: f0130400 g6: f0d4a018 g7: 00000001\n"
616         "o0: 00000000 o1: f0d4a298 o2: 00000040 o3: f1380718\n"
617         "o4: f1380718 o5: 00000200 sp: f1b13f08 ret_pc: f001c2a0\n"
618         "l0: efffd880 l1: 00000001 l2: f0d4a230 l3: 00000014\n"
619         "l4: 0000ffff l5: f0131550 l6: f012c000 l7: f0130400\n"
620         "i0: f1b13fb0 i1: 00000001 i2: 00000002 i3: 0007c000\n"
621         "i4: f01457c0 i5: 00000004 i6: f1b13f70 i7: f0015360\n"
622         "Instruction DUMP:\n"
623     );
624
625   for (s = linux_panic; *s; s++) if (*s == '\n') lines++;
626
627   XGetWindowAttributes (dpy, window, &xgwa);
628
629   fontname = get_string_resource ((xgwa.height > 600
630                                    ? "sparclinux.font2"
631                                    : "sparclinux.font"),
632                                   "SparcLinux.Font");
633   if (!fontname || !*fontname) fontname = (char *)def_font;
634   font = XLoadQueryFont (dpy, fontname);
635   if (!font) font = XLoadQueryFont (dpy, def_font);
636   if (!font) exit(-1);
637   if (fontname && fontname != def_font)
638     free (fontname);
639
640   gcv.font = font->fid;
641   gcv.foreground = get_pixel_resource(("sparclinux.foreground"),
642                                       "SparcLinux.Foreground",
643                                       dpy, xgwa.colormap);
644   gcv.background = get_pixel_resource(("sparclinux.background"),
645                                       "SparcLinux.Background",
646                                       dpy, xgwa.colormap);
647   XSetWindowBackground(dpy, window, gcv.background);
648   XClearWindow(dpy, window);
649
650   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
651
652   draw_string(dpy, window, gc, &gcv, font,
653               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
654               10, 10,
655               linux_panic, 0);
656   XFreeGC(dpy, gc);
657   XSync(dpy, False);
658   bsod_sleep(dpy, delay);
659   XClearWindow(dpy, window);
660   XFreeFont(dpy, font);
661 }
662
663 /* BSD Panic by greywolf@starwolf.com - modeled after the Linux panic above.
664    By Grey Wolf <greywolf@siteROCK.com>
665  */
666 static void
667 bsd (Display *dpy, Window window, int delay)
668 {
669   XGCValues gcv;
670   XWindowAttributes xgwa;
671   char *fontname;
672   const char *def_font = "fixed";
673   XFontStruct *font;
674   GC gc;
675   int lines = 1;
676   int i, n, b;
677   const char *rbstr, *panicking;
678   char syncing[80], bbuf[5], *bp;
679
680   const char *panicstr[] =
681    {"panic: ifree: freeing free inode",
682     "panic: blkfree: freeing free block",
683     "panic: improbability coefficient below zero",
684     "panic: cgsixmmap",
685     "panic: crazy interrupts",
686     "panic: nmi",
687     "panic: attempted windows install",
688     "panic: don't",
689     "panic: free inode isn't",
690     "panic: cpu_fork: curproc",
691     "panic: malloc: out of space in kmem_map",
692     "panic: vogon starship detected",
693     "panic: teleport chamber: out of order",
694     "panic: Brain fried - core dumped"};
695      
696   for (i = 0; i < sizeof(syncing); i++)
697     syncing[i] = 0;
698
699   i = (random() & 0xffff) % (sizeof(panicstr) / sizeof(*panicstr));
700
701   panicking = panicstr[i];
702   strcpy(syncing, "Syncing disks: ");
703
704   b = (random() & 0xff) % 40;
705   for (n = 0; (n < 20) && (b > 0); n++)
706     {
707       if (i)
708         {
709           i = (random() & 0x7);
710           b -= (random() & 0xff) % 20;
711           if (b < 0)
712             b = 0;
713         }
714       sprintf (bbuf, "%d ", b);
715       strcat (syncing, bbuf);
716     }
717
718   if (b)
719     rbstr = "damn!";
720   else
721     rbstr = "sunk!";
722
723   lines = 5;
724
725   XGetWindowAttributes (dpy, window, &xgwa);
726
727   fontname = get_string_resource ((xgwa.height > 600
728                                    ? "bsd.font2"
729                                    : "bsd.font"),
730                                   "BSD.Font");
731   if (!fontname || !*fontname) fontname = (char *)def_font;
732   font = XLoadQueryFont (dpy, fontname);
733   if (!font) font = XLoadQueryFont (dpy, def_font);
734   if (!font) exit(-1);
735   if (fontname && fontname != def_font)
736     free (fontname);
737
738   gcv.font = font->fid;
739   gcv.foreground = get_pixel_resource(("bsd.foreground"),
740                                       "BSD.Foreground",
741                                       dpy, xgwa.colormap);
742   gcv.background = get_pixel_resource(("bsd.background"),
743                                       "BSD.Background",
744                                       dpy, xgwa.colormap);
745   XSetWindowBackground(dpy, window, gcv.background);
746   XClearWindow(dpy, window);
747
748   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
749
750   draw_string(dpy, window, gc, &gcv, font,
751               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
752               10, 10,
753               panicking, 0);
754   XSync(dpy, False);
755   lines--;
756
757   for (bp = syncing; *bp;)
758     {
759       char *bsd_bufs, oc = 0;
760       for (;*bp && (*bp != ' '); bp++)
761         ;
762       if (*bp == ' ')
763         {
764           oc = *bp;
765           *bp = 0;
766         }
767       bsd_bufs = strdup(syncing);
768       draw_string(dpy, window, gc, &gcv, font,
769                   10,
770                   xgwa.height - (lines * (font->ascent + font->descent + 1)),
771                   10, 10,
772                   bsd_bufs, 0);
773       XSync(dpy, False);
774       free(bsd_bufs);
775       if (oc)
776         *bp = oc;
777       if (bsod_sleep(dpy, -1))
778         goto DONE;
779       bp++;
780     }
781
782   lines--;
783   
784   draw_string(dpy, window, gc, &gcv, font,
785               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
786               10, 10,
787               rbstr, 0);
788   lines--;
789   draw_string(dpy, window, gc, &gcv, font,
790               10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
791               10, 10,
792               "Rebooting", 0);
793
794   XFreeGC(dpy, gc);
795   XSync(dpy, False);
796   bsod_sleep(dpy, delay);
797
798 DONE:
799   XClearWindow(dpy, window);
800   XFreeFont(dpy, font);
801 }
802
803 static void
804 amiga (Display *dpy, Window window, int delay)
805 {
806   XGCValues gcv;
807   XWindowAttributes xgwa;
808   char *fontname;
809   const char *def_font = "fixed";
810   XFontStruct *font;
811   GC gc, gc2;
812   int height;
813   unsigned long fg, bg, bg2;
814   Pixmap pixmap = 0;
815   int pix_w = 0, pix_h = 0;
816   int string_width;
817   int margin;
818
819   const char *string =
820     ("_Software failure.  Press left mouse button to continue.\n"
821      "_Guru Meditation #00000003.00C01570");
822
823   XGetWindowAttributes (dpy, window, &xgwa);
824
825   fontname = get_string_resource ((xgwa.height > 600
826                                    ? "amiga.font2" : "amiga.font"),
827                                   "Amiga.Font");
828   if (!fontname || !*fontname) fontname = (char *)def_font;
829   font = XLoadQueryFont (dpy, fontname);
830   if (!font) font = XLoadQueryFont (dpy, def_font);
831   if (!font) exit(-1);
832   if (fontname && fontname != def_font)
833     free (fontname);
834
835   gcv.font = font->fid;
836   fg = gcv.foreground = get_pixel_resource("amiga.foreground",
837                                            "Amiga.Foreground",
838                                            dpy, xgwa.colormap);
839   bg = gcv.background = get_pixel_resource("amiga.background",
840                                            "Amiga.Background",
841                                            dpy, xgwa.colormap);
842   bg2 = get_pixel_resource("amiga.background2", "Amiga.Background",
843                            dpy, xgwa.colormap);
844   XSetWindowBackground(dpy, window, bg2);
845   XClearWindow(dpy, window);
846
847   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
848   gcv.background = fg; gcv.foreground = bg;
849   gc2 = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
850
851   height = (font->ascent + font->descent) * 6;
852
853 #if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
854   pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand,
855                                &pix_w, &pix_h, 0);
856 #endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
857
858   if (pixmap && xgwa.height > 600)      /* scale up the bitmap */
859     {
860       pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
861                              pixmap, pix_w, pix_h);
862       pix_w *= 2;
863       pix_h *= 2;
864     }
865
866   if (pixmap)
867     {
868       int x = (xgwa.width - pix_w) / 2;
869       int y = ((xgwa.height - pix_h) / 2);
870       XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
871
872       XSync(dpy, False);
873       bsod_sleep(dpy, 2);
874
875       XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y + height);
876       XClearArea(dpy, window, 0, 0, xgwa.width, y + height, False);
877       XFreePixmap(dpy, pixmap);
878     }
879
880   XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
881   margin = font->ascent;
882   string_width = draw_string(dpy, window, gc, &gcv, font,
883                              margin, 0,
884                              xgwa.width - (margin * 2), height,
885                              string, 0);
886   {
887     GC gca = gc;
888     while (delay > 0)
889       {
890         int x2;
891         XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, margin);
892         XFillRectangle(dpy, window, gca, 0, 0, margin, height);
893         XFillRectangle(dpy, window, gca,
894                        0, height - margin, xgwa.width, margin);
895         x2 = margin + string_width;
896         if (x2 < xgwa.width - margin) x2 = xgwa.width - margin;
897         XFillRectangle(dpy, window, gca, x2, 0, margin, height);
898
899         gca = (gca == gc ? gc2 : gc);
900         XSync(dpy, False);
901         if (bsod_sleep(dpy, 1))
902           break;
903         delay--;
904       }
905   }
906
907   XFreeGC(dpy, gc);
908   XFreeGC(dpy, gc2);
909   XSync(dpy, False);
910   XClearWindow(dpy, window);
911   XFreeFont(dpy, font);
912 }
913
914
915 /* Atari ST, by Marcus Herbert <rhoenie@nobiscum.de>
916    Marcus had this to say:
917
918         Though I still have my Atari somewhere, I hardly remember
919         the meaning of the bombs. I think 9 bombs was "bus error" or
920         something like that.  And you often had a few bombs displayed
921         quickly and then the next few ones coming up step by step.
922         Perhaps somebody else can tell you more about it..  its just
923         a quick hack :-}
924  */
925 static void
926 atari (Display *dpy, Window window, int delay)
927 {
928         
929   XGCValues gcv;
930   XWindowAttributes xgwa;
931   const char *def_font = "fixed";
932   XFontStruct *font;
933   GC gc;
934   Pixmap pixmap = 0;
935   int pix_w = atari_width;
936   int pix_h = atari_height;
937   int offset;
938   int i, x, y;
939
940   XGetWindowAttributes (dpy, window, &xgwa);
941
942   font = XLoadQueryFont (dpy, def_font);
943   if (!font) exit(-1);
944                 
945   gcv.font = font->fid;
946   gcv.foreground = get_pixel_resource("atari.foreground", "Atari.Foreground",
947                                       dpy, xgwa.colormap);
948   gcv.background = get_pixel_resource("atari.background", "Atari.Background",
949                                       dpy, xgwa.colormap);
950
951   XSetWindowBackground(dpy, window, gcv.background);
952   XClearWindow(dpy, window);
953
954   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
955
956   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) atari_bits,
957                                        pix_w, pix_h,
958                                        gcv.foreground, gcv.background,
959                                        xgwa.depth);
960   pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
961                          pixmap, pix_w, pix_h);
962   pix_w *= 2;
963   pix_h *= 2;
964
965   offset = pix_w + 2;
966   x = 5;
967   y = (xgwa.height - (xgwa.height / 5));
968   if (y < 0) y = 0;
969
970   for (i=0 ; i<7 ; i++) {
971     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
972               (x + (i*offset)), y);
973   }  
974   
975   for (i=7 ; i<10 ; i++) {
976     if (bsod_sleep(dpy, 1))
977       goto DONE;
978     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
979               (x + (i*offset)), y);
980   }
981
982   bsod_sleep(dpy, delay);
983  DONE:
984   XFreePixmap(dpy, pixmap);
985   XFreeGC(dpy, gc);
986   XSync(dpy, False);
987   XClearWindow(dpy, window);
988   XFreeFont(dpy, font);
989 }
990
991
992 static void
993 mac (Display *dpy, Window window, int delay)
994 {
995   XGCValues gcv;
996   XWindowAttributes xgwa;
997   char *fontname;
998   const char *def_font = "fixed";
999   XFontStruct *font;
1000   GC gc;
1001   Pixmap pixmap = 0;
1002   int pix_w = mac_width;
1003   int pix_h = mac_height;
1004   int offset = mac_height * 4;
1005   int i;
1006
1007   const char *string = ("0 0 0 0 0 0 0 F\n"
1008                         "0 0 0 0 0 0 0 3");
1009
1010   XGetWindowAttributes (dpy, window, &xgwa);
1011
1012   fontname = get_string_resource ("mac.font", "Mac.Font");
1013   if (!fontname || !*fontname) fontname = (char *)def_font;
1014   font = XLoadQueryFont (dpy, fontname);
1015   if (!font) font = XLoadQueryFont (dpy, def_font);
1016   if (!font) exit(-1);
1017   if (fontname && fontname != def_font)
1018     free (fontname);
1019
1020   gcv.font = font->fid;
1021   gcv.foreground = get_pixel_resource("mac.foreground", "Mac.Foreground",
1022                                       dpy, xgwa.colormap);
1023   gcv.background = get_pixel_resource("mac.background", "Mac.Background",
1024                                       dpy, xgwa.colormap);
1025   XSetWindowBackground(dpy, window, gcv.background);
1026   XClearWindow(dpy, window);
1027
1028   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
1029
1030   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits,
1031                                        mac_width, mac_height,
1032                                        gcv.foreground,
1033                                        gcv.background,
1034                                        xgwa.depth);
1035
1036   for(i = 0; i < 2; i++)
1037     {
1038       pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
1039                              pixmap, pix_w, pix_h);
1040       pix_w *= 2; pix_h *= 2;
1041     }
1042
1043   {
1044     int x = (xgwa.width - pix_w) / 2;
1045     int y = (((xgwa.height + offset) / 2) -
1046              pix_h -
1047              (font->ascent + font->descent) * 2);
1048     if (y < 0) y = 0;
1049     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
1050     XFreePixmap(dpy, pixmap);
1051   }
1052
1053   draw_string(dpy, window, gc, &gcv, font, 0, 0,
1054               xgwa.width, xgwa.height + offset, string, 0);
1055
1056   XFreeGC(dpy, gc);
1057   XSync(dpy, False);
1058   bsod_sleep(dpy, delay);
1059   XClearWindow(dpy, window);
1060   XFreeFont(dpy, font);
1061 }
1062
1063 static void
1064 macsbug (Display *dpy, Window window, int delay)
1065 {
1066   XGCValues gcv;
1067   XWindowAttributes xgwa;
1068   char *fontname;
1069   const char *def_font = "fixed";
1070   XFontStruct *font;
1071   GC gc, gc2;
1072
1073   int char_width, line_height;
1074   int col_right, row_top, row_bottom, page_right, page_bottom, body_top;
1075   int xoff, yoff;
1076
1077 # ifdef __GNUC__
1078   __extension__   /* don't warn about "string length is greater than the
1079                      length ISO C89 compilers are required to support"
1080                      in the following string constant... */
1081 # endif
1082
1083   const char *left = ("    SP     \n"
1084                       " 04EB0A58  \n"
1085                       "58 00010000\n"
1086                       "5C 00010000\n"
1087                       "   ........\n"
1088                       "60 00000000\n"
1089                       "64 000004EB\n"
1090                       "   ........\n"
1091                       "68 0000027F\n"
1092                       "6C 2D980035\n"
1093                       "   ....-..5\n"
1094                       "70 00000054\n"
1095                       "74 0173003E\n"
1096                       "   ...T.s.>\n"
1097                       "78 04EBDA76\n"
1098                       "7C 04EBDA8E\n"
1099                       "   .S.L.a.U\n"
1100                       "80 00000000\n"
1101                       "84 000004EB\n"
1102                       "   ........\n"
1103                       "88 00010000\n"
1104                       "8C 00010000\n"
1105                       "   ...{3..S\n"
1106                       "\n"
1107                       "\n"
1108                       " CurApName \n"
1109                       "  Finder   \n"
1110                       "\n"
1111                       " 32-bit VM \n"
1112                       "SR Smxnzvc0\n"
1113                       "D0 04EC0062\n"
1114                       "D1 00000053\n"
1115                       "D2 FFFF0100\n"
1116                       "D3 00010000\n"
1117                       "D4 00010000\n"
1118                       "D5 04EBDA76\n"
1119                       "D6 04EBDA8E\n"
1120                       "D7 00000001\n"
1121                       "\n"
1122                       "A0 04EBDA76\n"
1123                       "A1 04EBDA8E\n"
1124                       "A2 A0A00060\n"
1125                       "A3 027F2D98\n"
1126                       "A4 027F2E58\n"
1127                       "A5 04EC04F0\n"
1128                       "A6 04EB0A86\n"
1129                       "A7 04EB0A58");
1130   const char *bottom = ("  _A09D\n"
1131                         "     +00884    40843714     #$0700,SR         "
1132                         "                  ; A973        | A973\n"
1133                         "     +00886    40843765     *+$0400           "
1134                         "                                | 4A1F\n"
1135                         "     +00888    40843718     $0004(A7),([0,A7[)"
1136                         "                  ; 04E8D0AE    | 66B8");
1137
1138 #if 0
1139   const char *body = ("Bus Error at 4BF6D6CC\n"
1140                       "while reading word from 4BF6D6CC in User data space\n"
1141                       " Unable to access that address\n"
1142                       "  PC: 2A0DE3E6\n"
1143                       "  Frame Type: B008");
1144 #else
1145
1146 # ifdef __GNUC__
1147   __extension__   /* don't warn about "string length is greater than the
1148                      length ISO C89 compilers are required to support"
1149                      in the following string constant... */
1150 # endif
1151
1152   const char * body = ("PowerPC unmapped memory exception at 003AFDAC "
1153                                                 "BowelsOfTheMemoryMgr+04F9C\n"
1154                       " Calling chain using A6/R1 links\n"
1155                       "  Back chain  ISA  Caller\n"
1156                       "  00000000    PPC  28C5353C  __start+00054\n"
1157                       "  24DB03C0    PPC  28B9258C  main+0039C\n"
1158                       "  24DB0350    PPC  28B9210C  MainEvent+00494\n"
1159                       "  24DB02B0    PPC  28B91B40  HandleEvent+00278\n"
1160                       "  24DB0250    PPC  28B83DAC  DoAppleEvent+00020\n"
1161                       "  24DB0210    PPC  FFD3E5D0  "
1162                                                 "AEProcessAppleEvent+00020\n"
1163                       "  24DB0132    68K  00589468\n"
1164                       "  24DAFF8C    68K  00589582\n"
1165                       "  24DAFF26    68K  00588F70\n"
1166                       "  24DAFEB3    PPC  00307098  "
1167                                                 "EmToNatEndMoveParams+00014\n"
1168                       "  24DAFE40    PPC  28B9D0B0  DoScript+001C4\n"
1169                       "  24DAFDD0    PPC  28B9C35C  RunScript+00390\n"
1170                       "  24DAFC60    PPC  28BA36D4  run_perl+000E0\n"
1171                       "  24DAFC10    PPC  28BC2904  perl_run+002CC\n"
1172                       "  24DAFA80    PPC  28C18490  Perl_runops+00068\n"
1173                       "  24DAFA30    PPC  28BE6CC0  Perl_pp_backtick+000FC\n"
1174                       "  24DAF9D0    PPC  28BA48B8  Perl_my_popen+00158\n"
1175                       "  24DAF980    PPC  28C5395C  sfclose+00378\n"
1176                       "  24DAF930    PPC  28BA568C  free+0000C\n"
1177                       "  24DAF8F0    PPC  28BA6254  pool_free+001D0\n"
1178                       "  24DAF8A0    PPC  FFD48F14  DisposePtr+00028\n"
1179                       "  24DAF7C9    PPC  00307098  "
1180                                                 "EmToNatEndMoveParams+00014\n"
1181                       "  24DAF780    PPC  003AA180  __DisposePtr+00010");
1182 #endif
1183
1184   const char *s;
1185   int body_lines = 1;
1186
1187   for (s = body; *s; s++) if (*s == '\n') body_lines++;
1188
1189   XGetWindowAttributes (dpy, window, &xgwa);
1190
1191   fontname = get_string_resource ((xgwa.height > 850
1192                                    ? "macsbug.font3"
1193                                    : (xgwa.height > 700
1194                                       ? "macsbug.font2"
1195                                       : "macsbug.font")),
1196                                   "MacsBug.Font");
1197   if (!fontname || !*fontname) fontname = (char *)def_font;
1198   font = XLoadQueryFont (dpy, fontname);
1199   if (!font) font = XLoadQueryFont (dpy, def_font);
1200   if (!font) exit(-1);
1201   if (fontname && fontname != def_font)
1202     free (fontname);
1203
1204   gcv.font = font->fid;
1205   gcv.foreground = get_pixel_resource("macsbug.foreground",
1206                                       "MacsBug.Foreground",
1207                                       dpy, xgwa.colormap);
1208   gcv.background = get_pixel_resource("macsbug.background",
1209                                       "MacsBug.Background",
1210                                       dpy, xgwa.colormap);
1211
1212   gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
1213
1214   gcv.foreground = gcv.background;
1215   gc2 = XCreateGC(dpy, window, GCForeground, &gcv);
1216
1217   XSetWindowBackground(dpy, window,
1218                        get_pixel_resource("macsbug.borderColor",
1219                                           "MacsBug.BorderColor",
1220                                           dpy, xgwa.colormap));
1221   XClearWindow(dpy, window);
1222
1223   char_width = (font->per_char
1224                 ? font->per_char['n'-font->min_char_or_byte2].width
1225                 : font->min_bounds.width);
1226   line_height = font->ascent + font->descent + 1;
1227
1228   col_right = char_width * 12;
1229   page_bottom = line_height * 47;
1230
1231   if (page_bottom > xgwa.height) page_bottom = xgwa.height;
1232
1233   row_bottom = page_bottom - line_height;
1234   row_top = row_bottom - (line_height * 4);
1235   page_right = col_right + (char_width * 88);
1236   body_top = row_top - (line_height * body_lines);
1237
1238   page_bottom += 2;
1239   row_bottom += 2;
1240   body_top -= 4;
1241
1242   xoff = (xgwa.width - page_right) / 2;
1243   yoff = (xgwa.height - page_bottom) / 2;
1244   if (xoff < 0) xoff = 0;
1245   if (yoff < 0) yoff = 0;
1246
1247   XFillRectangle(dpy, window, gc2, xoff, yoff, page_right, page_bottom);
1248
1249   draw_string(dpy, window, gc, &gcv, font, xoff, yoff, 10, 10, left, 0);
1250   draw_string(dpy, window, gc, &gcv, font, xoff+col_right, yoff+row_top,
1251               10, 10, bottom, 0);
1252
1253   XFillRectangle(dpy, window, gc, xoff + col_right, yoff, 2, page_bottom);
1254   XDrawLine(dpy, window, gc,
1255             xoff+col_right, yoff+row_top, xoff+page_right, yoff+row_top);
1256   XDrawLine(dpy, window, gc,
1257             xoff+col_right, yoff+row_bottom, xoff+page_right, yoff+row_bottom);
1258   XDrawRectangle(dpy, window, gc,  xoff, yoff, page_right, page_bottom);
1259
1260   if (body_top > 4)
1261     body_top = 4;
1262
1263   draw_string(dpy, window, gc, &gcv, font,
1264               xoff + col_right + char_width, yoff + body_top, 10, 10, body,
1265               500);
1266
1267   while (delay > 0)
1268     {
1269       XDrawLine(dpy, window, gc,
1270                 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1271                 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1272       XSync(dpy, False);
1273       usleep(666666L);
1274       XDrawLine(dpy, window, gc2,
1275                 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1276                 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1277       XSync(dpy, False);
1278       usleep(333333L);
1279       if (bsod_sleep(dpy, 0))
1280         break;
1281       delay--;
1282     }
1283
1284   XFreeGC(dpy, gc);
1285   XFreeGC(dpy, gc2);
1286   XClearWindow(dpy, window);
1287   XFreeFont(dpy, font);
1288 }
1289
1290 static void
1291 mac1 (Display *dpy, Window window, int delay)
1292 {
1293   XGCValues gcv;
1294   XWindowAttributes xgwa;
1295   GC gc;
1296   Pixmap pixmap = 0;
1297   int pix_w = macbomb_width;
1298   int pix_h = macbomb_height;
1299
1300   XGetWindowAttributes (dpy, window, &xgwa);
1301
1302   gcv.foreground = get_pixel_resource("mac1.foreground", "Mac.Foreground",
1303                                       dpy, xgwa.colormap);
1304   gcv.background = get_pixel_resource("mac1.background", "Mac.Background",
1305                                       dpy, xgwa.colormap);
1306   XSetWindowBackground(dpy, window, gcv.background);
1307   XClearWindow(dpy, window);
1308
1309   gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
1310
1311   pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) macbomb_bits,
1312                                        macbomb_width, macbomb_height,
1313                                        gcv.foreground,
1314                                        gcv.background,
1315                                        xgwa.depth);
1316
1317   {
1318     int x = (xgwa.width - pix_w) / 2;
1319     int y = (xgwa.height - pix_h) / 2;
1320     if (y < 0) y = 0;
1321     XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
1322     XSync(dpy, False);
1323     if (bsod_sleep(dpy, 1))
1324       goto DONE;
1325     XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
1326   }
1327
1328  DONE:
1329   XFreeGC(dpy, gc);
1330   XFreePixmap(dpy, pixmap);
1331   XSync(dpy, False);
1332   bsod_sleep(dpy, delay);
1333   XClearWindow(dpy, window);
1334 }
1335
1336
1337 static void
1338 macx (Display *dpy, Window window, int delay)
1339 {
1340   XGCValues gcv;
1341   XWindowAttributes xgwa;
1342   char *fontname = 0;
1343   const char *def_font = "fixed";
1344   XFontStruct *font;
1345   GC gc;
1346
1347 # ifdef __GNUC__
1348   __extension__   /* don't warn about "string length is greater than the
1349                      length ISO C89 compilers are required to support"
1350                      in the following string constant... */
1351 # endif
1352
1353   const char *macx_panic =
1354    ("panic(cpu 0): Unable to find driver for this platform: "
1355     "\"PowerMac 3,5\".\n"
1356     "\n"
1357     "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
1358     "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
1359     "\n"
1360     "\n"
1361     "\n"
1362     "No debugger configured - dumping debug information\n"
1363     "\n"
1364     "version string : Darwin Kernel Version 1.3:\n"
1365     "Thu Mar  1 06:56:40 PST 2001; root:xnu/xnu-123.5.obj~1/RELEASE_PPC\n"
1366     "\n"
1367     "\n"
1368     "\n"
1369     "\n"
1370     "DBAT0: 00000000 00000000\n"
1371     "DBAT1: 00000000 00000000\n"
1372     "DBAT2: 80001FFE 8000003A\n"
1373     "DBAT3: 90001FFE 9000003A\n"
1374     "MSR=00001030\n"
1375     "backtrace: 0x0008c2f4 0x0002a7a0 0x001f0204 0x001d4e4c 0x001d4c5c "
1376     "0x001a56cc 0x01d5dbc 0x001c621c 0x00037430 0x00037364\n"
1377     "\n"
1378     "panic: We are hanging here...\n");
1379
1380   XGetWindowAttributes (dpy, window, &xgwa);
1381
1382   gcv.background = get_pixel_resource("macX.background",
1383                                       "MacX.Background",
1384                                       dpy, xgwa.colormap);
1385   XSetWindowBackground(dpy, window, gcv.background);
1386   XClearWindow(dpy, window);
1387
1388   fontname = get_string_resource ((xgwa.height > 900
1389                                    ? "macX.font2"
1390                                    : "macX.font"),
1391                                   "MacX.Font");
1392   if (!fontname || !*fontname) fontname = (char *)def_font;
1393   font = XLoadQueryFont (dpy, fontname);
1394   if (!font) font = XLoadQueryFont (dpy, def_font);
1395   if (!font) exit(-1);
1396   if (fontname && fontname != def_font)
1397     free (fontname);
1398
1399   gcv.font = font->fid;
1400   gcv.foreground = get_pixel_resource("macsbug.foreground",
1401                                       "MacsBug.Foreground",
1402                                       dpy, xgwa.colormap);
1403   gcv.background = get_pixel_resource("macsbug.background",
1404                                       "MacsBug.Background",
1405                                       dpy, xgwa.colormap);
1406
1407
1408   gcv.foreground = get_pixel_resource("macX.textForeground",
1409                                       "MacX.TextForeground",
1410                                       dpy, xgwa.colormap);
1411   gcv.background = get_pixel_resource("macX.textBackground",
1412                                       "MacX.TextBackground",
1413                                       dpy, xgwa.colormap);
1414   gc = XCreateGC(dpy, window, GCForeground|GCBackground|GCFont, &gcv);
1415
1416 #if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
1417   {
1418     Pixmap pixmap = 0;
1419     Pixmap mask = 0;
1420     int x, y, pix_w, pix_h;
1421     pixmap = xpm_data_to_pixmap (dpy, window, (char **) happy_mac,
1422                                  &pix_w, &pix_h, &mask);
1423
1424     x = (xgwa.width - pix_w) / 2;
1425     y = (xgwa.height - pix_h) / 2;
1426     if (y < 0) y = 0;
1427     XSync(dpy, False);
1428     bsod_sleep(dpy, 2);
1429     XSetClipMask (dpy, gc, mask);
1430     XSetClipOrigin (dpy, gc, x, y);
1431     XCopyArea (dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
1432     XSetClipMask (dpy, gc, None);
1433     XFreePixmap (dpy, pixmap);
1434   }
1435 #endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
1436
1437   bsod_sleep(dpy, 3);
1438
1439   {
1440     const char *s;
1441     int x = 0, y = 0;
1442     int char_width, line_height;
1443     char_width = (font->per_char
1444                   ? font->per_char['n'-font->min_char_or_byte2].width
1445                   : font->min_bounds.width);
1446     line_height = font->ascent + font->descent;
1447
1448     s = macx_panic;
1449     y = font->ascent;
1450     while (*s)
1451       {
1452         int ox = x;
1453         int oy = y;
1454         if (*s == '\n' || x + char_width >= xgwa.width)
1455           {
1456             x = 0;
1457             y += line_height;
1458           }
1459
1460         if (*s == '\n')
1461           {
1462             /* Note that to get this goofy effect, they must be actually
1463                emitting LF CR at the end of each line instead of CR LF!
1464              */
1465             XDrawImageString (dpy, window, gc, ox, oy, " ", 1);
1466             XDrawImageString (dpy, window, gc, ox, y, " ", 1);
1467           }
1468         else
1469           {
1470             XDrawImageString (dpy, window, gc, x, y, s, 1);
1471             x += char_width;
1472           }
1473         s++;
1474       }
1475   }
1476
1477   XFreeGC(dpy, gc);
1478   XSync(dpy, False);
1479   bsod_sleep(dpy, delay);
1480   XClearWindow(dpy, window);
1481 }
1482
1483 \f
1484 /* blit damage
1485  *
1486  * by Martin Pool <mbp@samba.org>, Feb 2000.
1487  *
1488  * This is meant to look like the preferred failure mode of NCD
1489  * Xterms.  The parameters for choosing what to copy where might not
1490  * be quite right, but it looks about ugly enough.
1491  */
1492 static void
1493 blitdamage (Display *dpy, Window window, int delay)
1494 {
1495   XGCValues gcv;
1496   XWindowAttributes xwa;
1497   GC gc0;
1498   int i;
1499   int delta_x = 0, delta_y = 0;
1500   int w, h;
1501   int chunk_h, chunk_w;
1502   int steps;
1503   long gc_mask = 0;
1504   int src_x, src_y;
1505   int x, y;
1506   
1507   XGetWindowAttributes(dpy, window, &xwa);
1508
1509   load_random_image (xwa.screen, window, window, NULL, NULL);
1510
1511   w = xwa.width;
1512   h = xwa.height;
1513
1514   gc_mask = GCForeground;
1515   
1516   gcv.plane_mask = random();
1517   gc_mask |= GCPlaneMask;
1518   
1519   gc0 = XCreateGC(dpy, window, gc_mask, &gcv);
1520
1521   steps = 50;
1522   chunk_w = w / (random() % 1 + 1);
1523   chunk_h = h / (random() % 1 + 1);
1524   if (random() & 0x1000) 
1525     delta_y = random() % 600;
1526   if (!delta_y || (random() & 0x2000))
1527     delta_x = random() % 600;
1528   src_x = 0; 
1529   src_y = 0; 
1530   x = 0;
1531   y = 0;
1532   
1533   for (i = 0; i < steps; i++) {
1534     if (x + chunk_w > w) 
1535       x -= w;
1536     else
1537       x += delta_x;
1538     
1539     if (y + chunk_h > h)
1540       y -= h;
1541     else
1542       y += delta_y;
1543     
1544     XCopyArea(dpy, window, window, gc0,
1545               src_x, src_y, 
1546               chunk_w, chunk_h,
1547               x, y);
1548
1549     if (bsod_sleep(dpy, 0))
1550       goto DONE;
1551   }
1552
1553   bsod_sleep(dpy, delay);
1554
1555  DONE:
1556   XFreeGC(dpy, gc0);
1557 }
1558
1559 \f
1560 /* nvidia, by jwz.
1561  *
1562  * This is what happens if an Nvidia card goes into some crazy text mode.
1563  * Most often seen on the second screen of a dual-head system when the
1564  * proper driver isn't loaded.
1565  */
1566 typedef struct { int fg; int bg; int bit; Bool blink; } nvcell;
1567
1568 static void
1569 nvspatter (nvcell *grid, int rows, int cols, int ncolors, int nbits,
1570            Bool fill_p)
1571 {
1572   int max = rows * cols;
1573   int from = fill_p ?   0 : random() % (max - 1);
1574   int len  = fill_p ? max : random() % (cols * 4);
1575   int to = from + len;
1576   int i;
1577   Bool noisy = ((random() % 4) == 0);
1578   Bool diag = (noisy || fill_p) ? 0 : ((random() % 4) == 0);
1579
1580   int fg = random() % ncolors;
1581   int bg = random() % ncolors;
1582   int blink = ((random() % 4) == 0);
1583   int bit = (random() % nbits);
1584
1585   if (to > max) to = max;
1586
1587   if (diag)
1588     {
1589       int src = random() % (rows * cols);
1590       int len2 = (cols / 2) - (random() % 5);
1591       int j = src;
1592       for (i = from; i < to; i++, j++)
1593         {
1594           if (j > src + len2 || j >= max)
1595             j = src;
1596           if (i >= max) abort();
1597           if (j >= max) abort();
1598           grid[j] = grid[i];
1599         }
1600     }
1601   else
1602     for (i = from; i < to; i++)
1603       {
1604         nvcell *cell = &grid[i];
1605         cell->fg = fg;
1606         cell->bg = bg;
1607         cell->bit = bit;
1608         cell->blink = blink;
1609
1610         if (noisy)
1611           {
1612             fg = random() % ncolors;
1613             bg = random() % ncolors;
1614             blink = ((random() % 8) == 0);
1615           }
1616       }
1617 }
1618
1619
1620 static void
1621 nvidia (Display *dpy, Window window, int delay)
1622 {
1623   XGCValues gcv;
1624   XWindowAttributes xgwa;
1625   int cols, rows;
1626   int cellw, cellh;
1627   unsigned long colors[256];
1628   int ncolors;
1629   GC gc, gc1 = 0;
1630   int x, y, i;
1631   int tick = 0;
1632   nvcell *grid;
1633   Pixmap bits[5];
1634
1635   XGetWindowAttributes (dpy, window, &xgwa);
1636
1637   cols = 80;
1638   rows = 25;
1639   cellw = xgwa.width  / cols;
1640   cellh = xgwa.height / rows;
1641   if (cellw < 8 || cellh < 18)
1642     cellw = 8, cellh = 18;
1643   cols = (xgwa.width  / cellw) + 1;
1644   rows = (xgwa.height / cellh) + 1;
1645
1646   grid = (nvcell *) calloc (sizeof(*grid), rows * cols);
1647   gc = XCreateGC (dpy, window, 0, &gcv);
1648
1649   /* Allocate colors
1650    */
1651   ncolors = 16;
1652   for (i = 0; i < ncolors; i++)
1653     {
1654       XColor c;
1655       c.red   = random() & 0xFFFF;
1656       c.green = random() & 0xFFFF;
1657       c.blue  = random() & 0xFFFF;
1658       c.flags = DoRed|DoGreen|DoBlue;
1659       XAllocColor (dpy, xgwa.colormap, &c);
1660       colors[i] = c.pixel;
1661     }
1662
1663   /* Construct corrupted character bitmaps
1664    */
1665   for (i = 0; i < countof(bits); i++)
1666     {
1667       int j;
1668
1669       bits[i] = XCreatePixmap (dpy, window, cellw, cellh, 1);
1670       if (!gc1) gc1 = XCreateGC (dpy, bits[i], 0, &gcv);
1671
1672       XSetForeground (dpy, gc1, 0);
1673       XFillRectangle (dpy, bits[i], gc1, 0, 0, cellw, cellh);
1674       XSetForeground (dpy, gc1, ~0L);
1675
1676       if ((random() % 40) != 0)
1677         for (j = 0; j < ((cellw * cellh) / 16); j++)
1678           XFillRectangle (dpy, bits[i], gc1,
1679                           (random() % (cellw-2)) & ~1,
1680                           (random() % (cellh-2)) & ~1,
1681                           2, 2);
1682     }
1683
1684   /* Randomize the grid
1685    */
1686   nvspatter (grid, rows, cols, ncolors, countof(bits), True);
1687   for (i = 0; i < 20; i++)
1688     nvspatter (grid, rows, cols, ncolors, countof(bits), False);
1689
1690
1691   /* Redisplay loop: blink 3x/second
1692    */
1693   while (1)
1694     {
1695       for (y = 0; y < rows; y++)
1696         for (x = 0; x < cols; x++)
1697           {
1698             nvcell *cell = &grid[y * cols + x];
1699             unsigned long fg = colors[cell->fg];
1700             unsigned long bg = colors[cell->bg];
1701             Bool flip = cell->blink && (tick & 1);
1702             XSetForeground (dpy, gc, flip ? fg : bg);
1703             XSetBackground (dpy, gc, flip ? bg : fg);
1704             XCopyPlane (dpy, bits[cell->bit], window, gc,
1705                         0, 0, cellw, cellh,
1706                         x * cellw, y * cellh, 1L);
1707           }
1708
1709       if ((random() % 5) == 0)    /* change the display */
1710         nvspatter (grid, rows, cols, ncolors, countof(bits), False);
1711
1712       XSync (dpy, False);
1713       usleep (333333);
1714       if (bsod_sleep(dpy, 0))
1715         goto DONE;
1716       if (tick / 3 >= delay)
1717         goto DONE;
1718       tick++;
1719     }
1720
1721  DONE:
1722   XFreeColors (dpy, xgwa.colormap, colors, ncolors, 0);
1723   for (i = 0; i < countof(bits); i++)
1724     XFreePixmap (dpy, bits[i]);
1725   XFreeGC (dpy, gc);
1726   XFreeGC (dpy, gc1);
1727   free (grid);
1728 }
1729
1730 \f
1731 /*
1732  * SPARC Solaris panic. Should look pretty authentic on Solaris boxes.
1733  * Anton Solovyev <solovam@earthlink.net>
1734  */ 
1735
1736 typedef struct
1737 {
1738   Display *dpy;
1739   Window window;
1740   GC gc, erase_gc;
1741   XFontStruct *xfs;
1742   int sub_width;                /* Text subwindow width in pixels */
1743   int sub_height;               /* Text subwindow height in pixels */
1744   int sub_x;                    /* upper left corner of the text subwindow */
1745   int sub_y;                    /* upper left corner of the text subwindow */
1746   int char_width;               /* Char width in pixels */
1747   int line_height;              /* Line height in pixels */
1748   int columns;                  /* Number of columns in the text screen */
1749   int x;                        /* horizontal position of the cursor */
1750 } scrolling_window;
1751
1752
1753 static scrolling_window *
1754 make_scrolling_window (Display *dpy, Window window,
1755                        const char *name,
1756                        Bool grab_screen_p)
1757 {
1758   const char *def_font = "fixed";
1759   scrolling_window* ts;
1760   XWindowAttributes xgwa;
1761   XGCValues gcv;
1762   char* fn;
1763   char buf1[100], buf2[100];
1764
1765   ts = malloc (sizeof (*ts));
1766   ts->window = window;
1767   ts->dpy = dpy;
1768
1769   ts->x = 0;
1770
1771   XGetWindowAttributes (dpy, window, &xgwa);
1772
1773   if (grab_screen_p)
1774     {
1775       ts->sub_width = xgwa.width * 0.8;
1776       ts->sub_height = xgwa.height * 0.8;
1777     }
1778   else
1779     {
1780       ts->sub_width  = xgwa.width - 20;
1781       ts->sub_height = xgwa.height - 20;
1782       if (ts->sub_width  < 20) ts->sub_width  = 20;
1783       if (ts->sub_height < 20) ts->sub_height = 20;
1784     }
1785
1786   sprintf (buf1, "%.50s.font", name);
1787   sprintf (buf2, "%.50s.Font", name);
1788   fn = get_string_resource (buf1, buf2);
1789   ts->xfs = XLoadQueryFont (dpy, fn);
1790   if (!ts->xfs)
1791     {
1792       sprintf (buf1, "%.50s.font2", name);
1793       fn = get_string_resource(buf1, buf2);
1794       ts->xfs = XLoadQueryFont(dpy, fn);
1795     }
1796   if (!ts->xfs)
1797     ts->xfs = XLoadQueryFont(dpy, def_font);
1798   if (!ts->xfs)
1799     exit (1);
1800   gcv.font = ts->xfs->fid;
1801   ts->char_width = (ts->xfs->per_char
1802                     ? ts->xfs->per_char['n'-ts->xfs->min_char_or_byte2].width
1803                     : ts->xfs->min_bounds.width);
1804   ts->line_height = ts->xfs->ascent + ts->xfs->descent + 1;
1805
1806   ts->columns = ts->sub_width / ts->char_width;
1807
1808   ts->sub_x = (xgwa.width - ts->sub_width) / 2;
1809   ts->sub_y = (xgwa.height - ts->sub_height) / 2;
1810
1811   if (!grab_screen_p) ts->sub_height += ts->sub_y, ts->sub_y = 0;
1812
1813   if (grab_screen_p)
1814     load_random_image (xgwa.screen, window, window, NULL, NULL);
1815
1816   sprintf (buf1, "%.50s.background", name);
1817   sprintf (buf2, "%.50s.Background", name);
1818   gcv.background = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
1819
1820   sprintf (buf1, "%.50s.foreground", name);
1821   sprintf (buf2, "%.50s.Foreground", name);
1822   gcv.foreground = get_pixel_resource (buf1, buf2, dpy, xgwa.colormap);
1823
1824   ts->gc = XCreateGC (dpy, window,
1825                       GCForeground | GCBackground | GCFont,
1826                       &gcv);
1827   gcv.foreground = gcv.background;
1828   ts->erase_gc = XCreateGC (dpy, window,
1829                             GCForeground | GCBackground,
1830                             &gcv);
1831   XSetWindowBackground (dpy, window, gcv.background);
1832   return(ts);
1833 }
1834
1835 static void
1836 free_scrolling_window (scrolling_window* ts)
1837 {
1838   XFreeGC (ts->dpy, ts->gc);
1839   XFreeGC (ts->dpy, ts->erase_gc);
1840   XFreeFont (ts->dpy, ts->xfs);
1841   free (ts);
1842 }
1843
1844 static void
1845 scrolling_putc (scrolling_window* ts, const char aChar)
1846 {
1847   switch (aChar)
1848     {
1849     case '\n':
1850       ts->x = 0;
1851       XCopyArea (ts->dpy, ts->window, ts->window, ts->gc,
1852                  ts->sub_x, ts->sub_y + ts->line_height,
1853                  ts->sub_width, ts->sub_height,
1854                  ts->sub_x, ts->sub_y);
1855       XFillRectangle (ts->dpy, ts->window, ts->erase_gc,
1856                       ts->sub_x, ts->sub_y + ts->sub_height - ts->line_height,
1857                       ts->sub_width, ts->line_height);
1858       break;
1859     case '\r':
1860       ts->x = 0;
1861     case '\b':
1862       if(ts->x > 0)
1863         ts->x--;
1864       break;
1865     default:
1866       if (ts->x >= ts->columns)
1867         scrolling_putc (ts, '\n');
1868       XDrawImageString (ts->dpy, ts->window, ts->gc,
1869                         (ts->sub_x +
1870                          (ts->x * ts->char_width)
1871                          - ts->xfs->min_bounds.lbearing),
1872                         (ts->sub_y + ts->sub_height - ts->xfs->descent),
1873                         &aChar, 1);
1874       ts->x++;
1875       break;
1876     }
1877 }
1878
1879 static Bool
1880 scrolling_puts (scrolling_window *ts, const char* aString, int delay)
1881 {
1882   const char *c;
1883   for (c = aString; *c; ++c)
1884     {
1885       scrolling_putc (ts, *c);
1886       if (delay)
1887         {
1888           XSync(ts->dpy, 0);
1889           usleep(delay);
1890           if (bsod_sleep (ts->dpy, 0))
1891             return True;
1892         }
1893     }
1894   XSync (ts->dpy, 0);
1895   return False;
1896 }
1897
1898 static void
1899 sparc_solaris (Display* dpy, Window window, int delay)
1900 {
1901 # ifdef __GNUC__
1902   __extension__   /* don't warn about "string length is greater than the
1903                      length ISO C89 compilers are required to support"
1904                      in the following string constant... */
1905 # endif
1906
1907   const char *msg1 =
1908     "BAD TRAP: cpu=0 type=0x31 rp=0x2a10043b5e0 addr=0xf3880 mmu_fsr=0x0\n"
1909     "BAD TRAP occurred in module \"unix\" due to an illegal access to a"
1910     " user address.\n"
1911     "adb: trap type = 0x31\n"
1912     "addr=0xf3880\n"
1913     "pid=307, pc=0x100306e4, sp=0x2a10043ae81, tstate=0x4480001602,"
1914     " context=0x87f\n"
1915     "g1-g7: 1045b000, 32f, 10079440, 180, 300000ebde8, 0, 30000953a20\n"
1916     "Begin traceback... sp = 2a10043ae81\n"
1917     "Called from 100bd060, fp=2a10043af31, args=f3700 300008cc988 f3880 0"
1918     " 1 300000ebde0.\n"
1919     "Called from 101fe1bc, fp=2a10043b011, args=3000045a240 104465a0"
1920     " 300008e47d0 300008e48fa 300008ae350 300008ae410\n"
1921     "Called from 1007c520, fp=2a10043b0c1, args=300008e4878 300003596e8 0"
1922     " 3000045a320 0 3000045a220\n"
1923     "Called from 1007c498, fp=2a10043b171, args=1045a000 300007847f0 20"
1924     " 3000045a240 1 0\n"
1925     "Called from 1007972c, fp=2a10043b221, args=1 300009517c0 30000951e58 1"
1926     " 300007847f0 0\n"
1927     "Called from 10031e10, fp=2a10043b2d1, args=3000095b0c8 0 300009396a8"
1928     " 30000953a20 0 1\n"
1929     "Called from 10000bdd8, fp=ffffffff7ffff1c1, args=0 57 100131480"
1930     " 100131480 10012a6e0 0\n"
1931     "End traceback...\n"
1932     "panic[cpu0]/thread=30000953a20: trap\n"
1933     "syncing file systems...";
1934   const char *msg2 =
1935     " 1 done\n"
1936     "dumping to /dev/dsk/c0t0d0s3, offset 26935296\n";
1937   const char *msg3 =
1938     ": 2803 pages dumped, compression ratio 2.88, dump succeeded\n";
1939   const char *msg4 =
1940     "rebooting...\n"
1941     "Resetting ...";
1942
1943   scrolling_window *ts;
1944   int i;
1945   char buf[256];
1946
1947   ts = make_scrolling_window (dpy, window, "Solaris", True);
1948
1949   scrolling_puts (ts, msg1, 0);
1950   if (bsod_sleep (dpy, 3))
1951     goto DONE;
1952
1953   scrolling_puts (ts, msg2, 0);
1954   if (bsod_sleep (dpy, 2))
1955     goto DONE;
1956
1957   for (i = 1; i <= 100; ++i)
1958     {
1959       sprintf(buf, "\b\b\b\b\b\b\b\b\b\b\b%3d%% done", i);
1960       scrolling_puts (ts, buf, 0);
1961       if (bsod_sleep (dpy, -1))
1962         goto DONE;
1963     }
1964
1965   scrolling_puts (ts, msg3, 0);
1966   if (bsod_sleep (dpy, 2))
1967     goto DONE;
1968
1969   scrolling_puts (ts, msg4, 0);
1970   if (bsod_sleep(dpy, 3))
1971     goto DONE;
1972
1973   bsod_sleep (dpy, 3);
1974
1975  DONE:
1976   free_scrolling_window (ts);
1977 }
1978
1979 /* Linux panic and fsck, by jwz
1980  */
1981 static void
1982 linux_fsck (Display *dpy, Window window, int delay)
1983 {
1984   XWindowAttributes xgwa;
1985   scrolling_window *ts;
1986   int i;
1987   const char *sysname;
1988   char buf[1024];
1989
1990   const char *linux_panic[] = {
1991    " kernel: Unable to handle kernel paging request at virtual "
1992      "address 0000f0ad\n",
1993    " kernel:  printing eip:\n",
1994    " kernel: c01becd7\n",
1995    " kernel: *pde = 00000000\n",
1996    " kernel: Oops: 0000\n",
1997    " kernel: CPU:    0\n",
1998    " kernel: EIP:    0010:[<c01becd7>]    Tainted: P \n",
1999    " kernel: EFLAGS: 00010286\n",
2000    " kernel: eax: 0000ff00   ebx: ca6b7e00   ecx: ce1d7a60   edx: ce1d7a60\n",
2001    " kernel: esi: ca6b7ebc   edi: 00030000   ebp: d3655ca0   esp: ca6b7e5c\n",
2002    " kernel: ds: 0018   es: 0018   ss: 0018\n",
2003    " kernel: Process crond (pid: 1189, stackpage=ca6b7000)\n",
2004    " kernel: Stack: d3655ca0 ca6b7ebc 00030054 ca6b7e7c c01c1e5b "
2005        "00000287 00000020 c01c1fbf \n",
2006    "",
2007    " kernel:        00005a36 000000dc 000001f4 00000000 00000000 "
2008        "ce046d40 00000001 00000000 \n",
2009    "", "", "",
2010    " kernel:        ffffffff d3655ca0 d3655b80 00030054 c01bef93 "
2011        "d3655ca0 ca6b7ebc 00030054 \n",
2012    "", "", "",
2013    " kernel: Call Trace:    [<c01c1e5b>] [<c01c1fbf>] [<c01bef93>] "
2014        "[<c01bf02b>] [<c0134c4f>]\n",
2015    "", "", "",
2016    " kernel:   [<c0142562>] [<c0114f8c>] [<c0134de3>] [<c010891b>]\n",
2017    " kernel: \n",
2018    " kernel: Code: 2a 00 75 08 8b 44 24 2c 85 c0 74 0c 8b 44 24 58 83 48 18 "
2019       "08 \n",
2020    0
2021   };
2022
2023   XGetWindowAttributes (dpy, window, &xgwa);
2024   XSetWindowBackground (dpy, window, 
2025                         get_pixel_resource("Linux.background",
2026                                            "Linux.Background",
2027                                            dpy, xgwa.colormap));
2028   XClearWindow(dpy, window);
2029
2030   sysname = "linux";
2031 # ifdef HAVE_UNAME
2032   {
2033     struct utsname uts;
2034     char *s;
2035     if (uname (&uts) >= 0)
2036       sysname = uts.nodename;
2037     s = strchr (sysname, '.');
2038     if (s) *s = 0;
2039   }
2040 # endif /* !HAVE_UNAME */
2041
2042
2043   ts = make_scrolling_window (dpy, window, "Linux", False);
2044
2045   scrolling_puts (ts, "waiting for X server to shut down ", 0);
2046   usleep (100000);
2047   if (bsod_sleep (dpy, 0))
2048     goto PANIC;
2049   scrolling_puts (ts,
2050                   "XIO:  fatal IO error 2 (broken pipe) on X server \":0.0\"\n"
2051                   "        after 339471 requests (339471 known processed) "
2052                   "with 0 events remaining\n",
2053                   0);
2054   if (scrolling_puts (ts, ".........\n", 300000))
2055     goto PANIC;
2056   if (bsod_sleep (dpy, 0))
2057     goto PANIC;
2058   scrolling_puts (ts,
2059                   "xinit:  X server slow to shut down, sending KILL signal.\n",
2060                   0);
2061   scrolling_puts (ts, "waiting for server to die ", 0);
2062   if (scrolling_puts (ts, "...\n", 300000))
2063     goto PANIC;
2064   if (bsod_sleep (dpy, 0))
2065     goto PANIC;
2066   scrolling_puts (ts, "xinit:  Can't kill server\n", 0);
2067
2068   if (bsod_sleep (dpy, 2))
2069     goto PANIC;
2070
2071   sprintf (buf, "\n%s Login: ", sysname);
2072   scrolling_puts (ts, buf, 0);
2073   if (bsod_sleep (dpy, 1))
2074     goto PANIC;
2075   scrolling_puts (ts,
2076     "\n\n"
2077     "Parallelizing fsck version 1.22 (22-Jun-2001)\n"
2078     "e2fsck 1.22, 22-Jun-2001 for EXT2 FS 0.5b, 95/08/09\n"
2079     "Warning!  /dev/hda1 is mounted.\n"
2080     "/dev/hda1 contains a file system with errors, check forced.\n",
2081                 0);
2082   if (bsod_sleep (dpy, 1))
2083     goto PANIC;
2084
2085   if (0 == random() % 2)
2086   scrolling_puts (ts,
2087      "Couldn't find ext2 superblock, trying backup blocks...\n"
2088      "The filesystem size (according to the superblock) is 3644739 blocks\n"
2089      "The physical size of the device is 3636706 blocks\n"
2090      "Either the superblock or the partition table is likely to be corrupt!\n"
2091      "Abort<y>? no\n",
2092                 0);
2093   if (bsod_sleep (dpy, 1))
2094     goto PANIC;
2095
2096  AGAIN:
2097
2098   scrolling_puts (ts, "Pass 1: Checking inodes, blocks, and sizes\n", 0);
2099   if (bsod_sleep (dpy, 2))
2100     goto PANIC;
2101
2102   i = (random() % 60) - 20;
2103   while (--i > 0)
2104     {
2105       int b = random() % 0xFFFF;
2106       sprintf (buf, "Deleted inode %d has zero dtime.  Fix<y>? yes\n\n", b);
2107       scrolling_puts (ts, buf, 0);
2108     }
2109
2110   i = (random() % 40) - 10;
2111   if (i > 0)
2112     {
2113       int g = random() % 0xFFFF;
2114       int b = random() % 0xFFFFFFF;
2115
2116       if (bsod_sleep (dpy, 1))
2117         goto PANIC;
2118
2119       sprintf (buf, "Warning: Group %d's copy of the group descriptors "
2120                "has a bad block (%d).\n", g, b);
2121       scrolling_puts (ts, buf, 0);
2122
2123       b = random() % 0x3FFFFF;
2124       while (--i > 0)
2125         {
2126           b += random() % 0xFFFF;
2127           sprintf (buf,
2128                    "Error reading block %d (Attempt to read block "
2129                    "from filesystem resulted in short read) while doing "
2130                    "inode scan.  Ignore error<y>?",
2131                    b);
2132           scrolling_puts (ts, buf, 0);
2133           usleep (10000);
2134           scrolling_puts (ts, " yes\n\n", 0);
2135         }
2136     }
2137
2138   if (0 == (random() % 10))
2139     {
2140
2141       if (bsod_sleep (dpy, 1))
2142         goto PANIC;
2143
2144       i = 3 + (random() % 10);
2145       while (--i > 0)
2146         scrolling_puts (ts, "Could not allocate 256 block(s) for inode table: "
2147                         "No space left on device\n", 0);
2148       scrolling_puts (ts, "Restarting e2fsck from the beginning...\n", 0);
2149
2150       if (bsod_sleep (dpy, 2))
2151         goto PANIC;
2152
2153       goto AGAIN;
2154     }
2155
2156   i = (random() % 20) - 5;
2157
2158   if (i > 0)
2159     if (bsod_sleep (dpy, 1))
2160       goto PANIC;
2161
2162   while (--i > 0)
2163     {
2164       int j = 5 + (random() % 10);
2165       int w = random() % 4;
2166
2167       while (--j > 0)
2168         {
2169           int b = random() % 0xFFFFF;
2170           int g = random() % 0xFFF;
2171
2172           if (0 == (random() % 10))
2173             b = 0;
2174           else if (0 == (random() % 10))
2175             b = -1;
2176
2177           if (w == 0)
2178             sprintf (buf,
2179                      "Inode table for group %d not in group.  (block %d)\n"
2180                      "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
2181                      "Relocate<y>?",
2182                      g, b);
2183           else if (w == 1)
2184             sprintf (buf,
2185                      "Block bitmap for group %d not in group.  (block %d)\n"
2186                      "Relocate<y>?",
2187                      g, b);
2188           else if (w == 2)
2189             sprintf (buf,
2190                      "Inode bitmap %d for group %d not in group.\n"
2191                      "Continue<y>?",
2192                      b, g);
2193           else /* if (w == 3) */
2194             sprintf (buf,
2195                      "Bad block %d in group %d's inode table.\n"
2196                      "WARNING: SEVERE DATA LOSS POSSIBLE.\n"
2197                      "Relocate<y>?",
2198                      b, g);
2199
2200           scrolling_puts (ts, buf, 0);
2201           scrolling_puts (ts, " yes\n\n", 0);
2202         }
2203       if (bsod_sleep (dpy, 0))
2204         goto PANIC;
2205       usleep (1000);
2206     }
2207
2208
2209   if (0 == random() % 10) goto PANIC;
2210   scrolling_puts (ts, "Pass 2: Checking directory structure\n", 0);
2211   if (bsod_sleep (dpy, 2))
2212     goto PANIC;
2213
2214   i = (random() % 20) - 5;
2215   while (--i > 0)
2216     {
2217       int n = random() % 0xFFFFF;
2218       int o = random() % 0xFFF;
2219       sprintf (buf, "Directory inode %d, block 0, offset %d: "
2220                "directory corrupted\n"
2221                "Salvage<y>? ",
2222                n, o);
2223       scrolling_puts (ts, buf, 0);
2224       usleep (1000);
2225       scrolling_puts (ts, " yes\n\n", 0);
2226
2227       if (0 == (random() % 100))
2228         {
2229           sprintf (buf, "Missing '.' in directory inode %d.\nFix<y>?", n);
2230           scrolling_puts (ts, buf, 0);
2231           usleep (1000);
2232           scrolling_puts (ts, " yes\n\n", 0);
2233         }
2234
2235       if (bsod_sleep (dpy, 0))
2236         goto PANIC;
2237     }
2238
2239   if (0 == random() % 10) goto PANIC;
2240   scrolling_puts (ts,
2241                   "Pass 3: Checking directory connectivity\n"
2242                   "/lost+found not found.  Create? yes\n",
2243                 0);
2244   if (bsod_sleep (dpy, 2))
2245     goto PANIC;
2246
2247   /* Unconnected directory inode 4949 (/var/spool/squid/06/???)
2248      Connect to /lost+found<y>? yes
2249
2250      '..' in /var/spool/squid/06/08 (20351) is <The NULL inode> (0), should be 
2251      /var/spool/squid/06 (20350).
2252      Fix<y>? yes
2253
2254      Unconnected directory inode 128337 (/var/spool/squid/06/???)
2255      Connect to /lost+found<y>? yes
2256    */
2257
2258
2259   if (0 == random() % 10) goto PANIC;
2260   scrolling_puts (ts, "Pass 4: Checking reference counts\n", 0);
2261   if (bsod_sleep (dpy, 2))
2262     goto PANIC;
2263
2264   /* Inode 2 ref count is 19, should be 20.  Fix<y>? yes
2265
2266      Inode 4949 ref count is 3, should be 2.  Fix<y>? yes
2267
2268         ...
2269
2270      Inode 128336 ref count is 3, should be 2.  Fix<y>? yes
2271
2272      Inode 128337 ref count is 3, should be 2.  Fix<y>? yes
2273
2274    */
2275
2276
2277   if (0 == random() % 10) goto PANIC;
2278   scrolling_puts (ts, "Pass 5: Checking group summary information\n", 0);
2279   if (bsod_sleep (dpy, 2))
2280     goto PANIC;
2281
2282   i = (random() % 200) - 50;
2283   if (i > 0)
2284     {
2285       scrolling_puts (ts, "Block bitmap differences: ", 0);
2286       while (--i > 0)
2287         {
2288           sprintf (buf, " %d", -(random() % 0xFFF));
2289           scrolling_puts (ts, buf, 0);
2290           usleep (1000);
2291         }
2292       scrolling_puts (ts, "\nFix? yes\n\n", 0);
2293     }
2294
2295
2296   i = (random() % 100) - 50;
2297   if (i > 0)
2298     {
2299       scrolling_puts (ts, "Inode bitmap differences: ", 0);
2300       while (--i > 0)
2301         {
2302           sprintf (buf, " %d", -(random() % 0xFFF));
2303           scrolling_puts (ts, buf, 0);
2304           usleep (1000);
2305         }
2306       scrolling_puts (ts, "\nFix? yes\n\n", 0);
2307     }
2308
2309   i = (random() % 20) - 5;
2310   while (--i > 0)
2311     {
2312       int g = random() % 0xFFFF;
2313       int c = random() % 0xFFFF;
2314       sprintf (buf,
2315                "Free blocks count wrong for group #0 (%d, counted=%d).\nFix? ",
2316                g, c);
2317       scrolling_puts (ts, buf, 0);
2318       usleep (1000);
2319       scrolling_puts (ts, " yes\n\n", 0);
2320       if (bsod_sleep (dpy, 0))
2321         goto PANIC;
2322     }
2323
2324  PANIC:
2325
2326   i = 0;
2327   scrolling_puts (ts, "\n\n", 0);
2328   while (linux_panic[i])
2329     {
2330       time_t t = time ((time_t *) 0);
2331       struct tm *tm = localtime (&t);
2332       char prefix[100];
2333
2334       if (*linux_panic[i])
2335         {
2336           strftime (prefix, sizeof(prefix)-1, "%b %d %H:%M:%S ", tm);
2337           scrolling_puts (ts, prefix, 0);
2338           scrolling_puts (ts, sysname, 0);
2339           scrolling_puts (ts, linux_panic[i], 0);
2340           XSync(dpy, False);
2341           usleep(1000);
2342         }
2343       else
2344         usleep (300000);
2345
2346       if (bsod_sleep (dpy, 0))
2347         goto DONE;
2348       i++;
2349     }
2350
2351   if (bsod_sleep (dpy, 4))
2352     goto DONE;
2353
2354
2355   XSync(dpy, False);
2356   bsod_sleep(dpy, delay);
2357
2358  DONE:
2359   free_scrolling_window (ts);
2360   XClearWindow(dpy, window);
2361 }
2362
2363 \f
2364
2365 /*
2366  * Linux (hppa) panic, by Stuart Brady <sdbrady@ntlworld.com>
2367  * Output courtesy of M. Grabert
2368  */
2369 static void
2370 hppa_linux (Display *dpy, Window window, int delay)
2371 {
2372   XWindowAttributes xgwa;
2373   scrolling_window *ts;
2374   int i=0;
2375   const char *sysname;
2376   long int linedelay=0;
2377
2378 # ifdef __GNUC__
2379   __extension__   /* don't warn about "string length is greater than the
2380                      length ISO C89 compilers are required to support"
2381                      in the following string constant... */
2382 # endif
2383
2384   struct { long int delay; const char *string; } linux_panic[] =
2385     {{ 0, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
2386           "\n\n\n\n\n\n\n\n\n\n\n\n\n" },
2387      { 0, "Linux version 2.6.0-test11-pa2 (root@%s) "
2388           "(gcc version 3.3.2 (Debian)) #2 Mon Dec 8 06:09:27 GMT 2003\n" },
2389      { 4000, "FP[0] enabled: Rev 1 Model 16\n" },
2390      { 10, "The 32-bit Kernel has started...\n" },
2391      { -1, "Determining PDC firmware type: System Map.\n" },
2392      { -1, "model 00005bb0 00000481 00000000 00000002 7778df9f 100000f0 "
2393            "00000008 000000b2 000000b2\n" },
2394      { -1, "vers  00000203\n" },
2395      { -1, "CPUID vers 17 rev 7 (0x00000227)\n" },
2396      { -1, "capabilities 0x3\n" },
2397      { -1, "model 9000/785/C3000\n" },
2398      { -1, "Total Memory: 1024 Mb\n" },
2399      { -1, "On node 0 totalpages: 262144\n" },
2400      { -1, "  DMA zone: 262144 pages, LIFO batch:16\n" },
2401      { -1, "  Normal zone: 0 pages, LIFO batch:1\n" },
2402      { -1, "  HighMem zone: 0 pages, LIFO batch:1\n" },
2403      { -1, "LCD display at f05d0008,f05d0000 registered\n" },
2404      { -1, "Building zonelist for node : 0\n" },
2405      { -1, "Kernel command line: ide=nodma root=/dev/sda3 HOME=/ ip=off "
2406            "console=ttyS0 TERM=vt102 palo_kernel=2/vmlinux-2.6\n" },
2407      { -1, "ide_setup: ide=nodmaIDE: Prevented DMA\n" },
2408      { -1, "PID hash table entries: 16 (order 4: 128 bytes)\n" },
2409      {500, "Console: colour dummy device 160x64\n" },
2410      { 10, "Memory: 1034036k available\n" },
2411      { -1, "Calibrating delay loop... 796.67 BogoMIPS\n" },
2412      { -1, "Dentry cache hash table entries: 131072 (order: 7, 524288 "
2413            "bytes)\n" },
2414      { -1, "Inode-cache hash table entries: 65536 (order: 6, 262144 "
2415            "bytes)\n" },
2416      { -1, "Mount-cache hash table entries: 512 (order: 0, 4096 bytes)\n" },
2417      { -1, "POSIX conformance testing by UNIFIX\n" },
2418      { -1, "NET: Registered protocol family 16\n" },
2419      { 100, "Searching for devices...\n" },
2420      { 25, "Found devices:\n" },
2421      { 10, "1. Astro BC Runway Port at 0xfed00000 [10] "
2422            "{ 12, 0x0, 0x582, 0x0000b }\n" },
2423      { -1, "2. Elroy PCI Bridge at 0xfed30000 [10/0] "
2424            "{ 13, 0x0, 0x782, 0x0000a }\n" },
2425      { -1, "3. Elroy PCI Bridge at 0xfed32000 [10/1] "
2426            "{ 13, 0x0, 0x782, 0x0000a }\n" },
2427      { -1, "4. Elroy PCI Bridge at 0xfed38000 [10/4] "
2428            "{ 13, 0x0, 0x782, 0x0000a }\n" },
2429      { -1, "5. Elroy PCI Bridge at 0xfed3c000 [10/6] "
2430            "{ 13, 0x0, 0x782, 0x0000a }\n" },
2431      { -1, "6. AllegroHigh W at 0xfffa0000 [32] "
2432            "{ 0, 0x0, 0x5bb, 0x00004 }\n" },
2433      { -1, "7. Memory at 0xfed10200 [49] { 1, 0x0, 0x086, 0x00009 }\n" },
2434      { -1, "CPU(s): 1 x PA8500 (PCX-W) at 400.000000 MHz\n" },
2435      { -1, "SBA found Astro 2.1 at 0xfed00000\n" },
2436      { -1, "lba version TR2.1 (0x2) found at 0xfed30000\n" },
2437      { -1, "lba version TR2.1 (0x2) found at 0xfed32000\n" },
2438      { -1, "lba version TR2.1 (0x2) found at 0xfed38000\n" },
2439      { -1, "lba version TR2.1 (0x2) found at 0xfed3c000\n" },
2440      { 100, "SCSI subsystem initialized\n" },
2441      { 10, "drivers/usb/core/usb.c: registered new driver usbfs\n" },
2442      { -1, "drivers/usb/core/usb.c: registered new driver hub\n" },
2443      { -1, "ikconfig 0.7 with /proc/config*\n" },
2444      { -1, "Initializing Cryptographic API\n" },
2445      { 250, "SuperIO: probe of 0000:00:0e.0 failed with error -1\n" },
2446      { 20, "SuperIO: Found NS87560 Legacy I/O device at 0000:00:0e.1 "
2447            "(IRQ 64)\n" },
2448      { -1, "SuperIO: Serial port 1 at 0x3f8\n" },
2449      { -1, "SuperIO: Serial port 2 at 0x2f8\n" },
2450      { -1, "SuperIO: Parallel port at 0x378\n" },
2451      { -1, "SuperIO: Floppy controller at 0x3f0\n" },
2452      { -1, "SuperIO: ACPI at 0x7e0\n" },
2453      { -1, "SuperIO: USB regulator enabled\n" },
2454      { -1, "SuperIO: probe of 0000:00:0e.2 failed with error -1\n" },
2455      { -1, "Soft power switch enabled, polling @ 0xf0400804.\n" },
2456      { -1, "pty: 256 Unix98 ptys configured\n" },
2457      { -1, "Generic RTC Driver v1.07\n" },
2458      { -1, "Serial: 8250/16550 driver $Revision: 1.63 $ 13 ports, "
2459            "IRQ sharing disabled\n" },
2460      { -1, "ttyS0 at I/O 0x3f8 (irq = 0) is a 16550A\n" },
2461      { -1, "ttyS1 at I/O 0x2f8 (irq = 0) is a 16550A\n" },
2462      { -1, "Linux Tulip driver version 1.1.13 (May 11, 2002)\n" },
2463      { 150, "tulip0: no phy info, aborting mtable build\n" },
2464      { 10, "tulip0:  MII transceiver #1 config 1000 status 782d "
2465            "advertising 01e1.\n" },
2466      { -1, "eth0: Digital DS21143 Tulip rev 65 at 0xf4008000, "
2467            "00:10:83:F9:B4:34, IRQ 66.\n" },
2468      { -1, "Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2\n" },
2469      { -1, "ide: Assuming 33MHz system bus speed for PIO modes; "
2470            "override with idebus=xx\n" },
2471      { 100, "SiI680: IDE controller at PCI slot 0000:01:06.0\n" },
2472      { 10, "SiI680: chipset revision 2\n" },
2473      { -1, "SiI680: BASE CLOCK == 133\n" },
2474      { -1, "SiI680: 100% native mode on irq 128\n" },
2475      { -1, "    ide0: MMIO-DMA at 0xf4800000-0xf4800007 -- "
2476            "Error, MMIO ports already in use.\n" },
2477      { -1, "    ide1: MMIO-DMA at 0xf4800008-0xf480000f -- "
2478            "Error, MMIO ports already in use.\n" },
2479      { 5, "hda: TS130220A2, ATA DISK drive\n" },
2480      { -1, "      _______________________________\n" },
2481      { -1, "     < Your System ate a SPARC! Gah! >\n" },
2482      { -1, "      -------------------------------\n" },
2483      { -1, "             \\   ^__^\n" },
2484      { -1, "              \\  (xx)\\_______\n" },
2485      { -1, "                 (__)\\       )\\/\\\n" },
2486      { -1, "                  U  ||----w |\n" },
2487      { -1, "                     ||     ||\n" },
2488      { -1, "swapper (pid 1): Breakpoint (code 0)\n" },
2489      { -1, "\n" },
2490      { -1, "     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n" },
2491      { -1, "PSW: 00000000000001001111111100001111 Not tainted\n" },
2492      { -1, "r00-03  4d6f6f21 1032f010 10208f34 103fc2e0\n" },
2493      { -1, "r04-07  103fc230 00000001 00000001 0000000f\n" },
2494      { -1, "r08-11  103454f8 000f41fa 372d3980 103ee404\n" },
2495      { -1, "r12-15  3ccbf700 10344810 103ee010 f0400004\n" },
2496      { -1, "r16-19  f00008c4 f000017c f0000174 00000000\n" },
2497      { -1, "r20-23  fed32840 fed32800 00000000 0000000a\n" },
2498      { -1, "r24-27  0000ffa0 000000ff 103fc2e0 10326010\n" },
2499      { -1, "r28-31  00000000 00061a80 4ff98340 10208f34\n" },
2500      { -1, "sr0-3   00000000 00000000 00000000 00000000\n" },
2501      { -1, "sr4-7   00000000 00000000 00000000 00000000\n" },
2502      { -1, "\n" },
2503      { -1, "IASQ: 00000000 00000000 IAOQ: 00000000 00000004\n" },
2504      { -1, " IIR: 00000000    ISR: 00000000  IOR: 00000000\n" },
2505      { -1, " CPU:        0   CR30: 4ff98000 CR31: 1037c000\n" },
2506      { -1, " ORIG_R28: 55555555\n" },
2507      { -1, " IAOQ[0]: 0x0\n" },
2508      { -1, " IAOQ[1]: 0x4\n" },
2509      { -1, " RP(r2): probe_hwif+0x218/0x44c\n" },
2510      { -1, "Kernel panic: Attempted to kill init!\n" },
2511      { 0, NULL }};
2512
2513   XGetWindowAttributes (dpy, window, &xgwa);
2514   XSetWindowBackground (dpy, window, 
2515                         get_pixel_resource("HPPALinux.background",
2516                                            "HPPALinux.Background",
2517                                            dpy, xgwa.colormap));
2518   XClearWindow(dpy, window);
2519
2520   sysname = "hppa";
2521 # ifdef HAVE_UNAME
2522   {
2523     struct utsname uts;
2524     char *s;
2525     if (uname (&uts) >= 0)
2526       sysname = uts.nodename;
2527     s = strchr (sysname, '.');
2528     if (s) *s = 0;
2529   }
2530 # endif /* !HAVE_UNAME */
2531
2532   /* Insert current host name into banner on line 2 */
2533   {
2534     static char ss[1024];
2535     sprintf (ss, linux_panic[1].string, sysname);
2536     linux_panic[1].string = ss;
2537   }
2538
2539   ts = make_scrolling_window (dpy, window, "HPPALinux", False);
2540
2541   usleep (100000);
2542   while (linux_panic[i].string)
2543     {
2544       if (linux_panic[i].delay != -1)
2545         linedelay = linux_panic[i].delay * 1000;
2546       usleep (linedelay);
2547       scrolling_puts (ts, linux_panic[i].string, 0);
2548       XSync(dpy, False);
2549       if (bsod_sleep (dpy, 0))
2550         goto DONE;
2551       i++;
2552     }
2553
2554   if (bsod_sleep (dpy, 4))
2555     goto DONE;
2556
2557   XSync(dpy, False);
2558   bsod_sleep(dpy, delay);
2559
2560  DONE:
2561   free_scrolling_window (ts);
2562   XClearWindow(dpy, window);
2563 }
2564
2565 /* VMS by jwz (text sent by Roland Barmettler <roli@barmettler.net>)
2566  */
2567 static void
2568 vms (Display *dpy, Window window, int delay)
2569 {
2570   XWindowAttributes xgwa;
2571   scrolling_window *ts;
2572   const char *sysname;
2573   int char_delay = 0;
2574   int dot_delay = 40000;
2575   int chunk_delay = 500000;
2576   char *s, *s1;
2577   int i;
2578   int arg_count;
2579
2580 # ifdef __GNUC__
2581   __extension__   /* don't warn about "string length is greater than the
2582                      length ISO C89 compilers are required to support"
2583                      in the following string constant... */
2584 # endif
2585
2586   const char *lines[] = {
2587     "%CNXMAN,  Lost connection to system #\n"
2588     "%SHADOW-I-VOLPROC, DSA0: shadow master has changed.  "
2589     "Dump file WILL be written if system crashes.\n"
2590     "\n",
2591     "",
2592
2593     "%CNXMAN,  Quorum lost, blocking activity\n"
2594     "%CNXMAN,  Timed-out lost connection to system #\n"
2595     "%CNXMAN,  Timed-out lost connection to system #\n"
2596     "%CNXMAN,  Timed-out lost connection to system #\n"
2597     "%CNXMAN,  Proposing reconfiguration of the VMScluster\n",
2598     "",
2599
2600     "%CNXMAN,  Removed from VMScluster system #\n"
2601     "%CNXMAN,  Removed from VMScluster system #\n"
2602     "%CNXMAN,  Removed from VMScluster system #\n"
2603     "%CNXMAN,  Completing VMScluster state transition\n",
2604
2605     "\n"
2606     "**** OpenVMS (TM) Alpha Operating system V7.3-1   - BUGCHECK ****\n"
2607     "\n"
2608     "** Bugcheck code = 000005DC: CLUEXIT, Node voluntarily exiting "
2609     "VMScluster\n"
2610     "** Crash CPU: 00    Primary CPU: 00    Active CPUs: 00000001\n"
2611     "** Current Process = NULL\n"
2612     "** Current PSB ID = 00000001\n"
2613     "** Image Name =\n"
2614     "\n"
2615     "** Dumping error log buffers to HBVS unit 0\n"
2616     "**** Unable to dump error log buffers to remaining shadow set members\n"
2617     "** Error log buffers not dumped to HBVS unit 200\n"
2618     "\n"
2619     "** Dumping memory to HBVS unit 0\n"
2620     "**** Starting compressed selective memory dump at #...\n",
2621
2622     "...",
2623
2624     "\n"
2625     "**** Memory dump complete - not all processes or global pages saved\n",
2626
2627     "\n"
2628     "halted CPU 0\n",
2629     "",
2630
2631     "\n"
2632     "halt code = 5\n"
2633     "HALT instruction executed\n"
2634     "PC = ffffffff800c3884\n",
2635
2636     "\n"
2637     "CPU 0 booting\n",
2638
2639     "\n"
2640     "resetting all I/O buses\n"
2641     "\n"
2642     "\n"
2643     };
2644   char *args[8];
2645   int ids[3];
2646
2647   XGetWindowAttributes (dpy, window, &xgwa);
2648   ts = make_scrolling_window (dpy, window, "VMS", False);
2649   XClearWindow(dpy,window);
2650   ts->sub_x = 0;
2651   ts->sub_y = 0;
2652   ts->sub_width = xgwa.width;
2653   ts->sub_height = xgwa.height;
2654
2655   sysname = "VMS001";
2656 # ifdef HAVE_UNAME
2657   {
2658     struct utsname uts;
2659     if (uname (&uts) >= 0)
2660       sysname = uts.nodename;
2661     s = strchr (sysname, '.');
2662     if (s) *s = 0;
2663   }
2664 # endif /* !HAVE_UNAME */
2665
2666   args[0] = malloc (strlen(sysname) + 7);
2667   strcpy (args[0], sysname);
2668   args[0][5] = 0;
2669
2670   /* Pick three numbers, 1-9, no overlaps. */
2671   ids[0] = 1 + (random() % 9);
2672   do { ids[1] = 1 + (random() % 9); } while (ids[1]==ids[0]);
2673   do { ids[2] = 1 + (random() % 9); } while (ids[2]==ids[0] || ids[2]==ids[1]);
2674
2675   i = strlen(args[0])-1;
2676   if (i < 6) i++;
2677   args[0][i] = '0' + ids[0];
2678   args[0][i+1] = 0;
2679
2680   for (s = args[0]; *s; s++)
2681     if (isalpha(*s)) *s = toupper (*s);
2682
2683   args[1] = strdup (args[0]);
2684   args[2] = strdup (args[0]); args[2][i] = '0' + ids[1];
2685   args[3] = strdup (args[0]); args[3][i] = '0' + ids[2];
2686
2687   args[4] = strdup (args[1]);
2688   args[5] = strdup (args[2]);
2689   args[6] = strdup (args[3]);
2690
2691   {
2692     time_t t = time ((time_t *) 0);
2693     struct tm *tm = localtime (&t);
2694     args[7] = malloc (30);
2695     strftime (args[7], 29, "%d-%b-%Y %H:%M", tm);
2696     for (s = args[7]; *s; s++)
2697       if (isalpha(*s)) *s = toupper (*s);
2698   }
2699
2700   arg_count = 0;
2701   for (i = 0; i < countof(lines); i++)
2702     {
2703       const char *fmt = lines[i];
2704       if (! strcmp (fmt, "..."))
2705         {
2706           int steps = 180 + (random() % 60);
2707           while (--steps >= 0)
2708             {
2709               scrolling_puts (ts, ".", 0);
2710               XSync (dpy, False);
2711               usleep (dot_delay);
2712               if (bsod_sleep (dpy, 0))
2713                 goto DONE;
2714             }
2715         }
2716       else
2717         {
2718           char *fmt2 = malloc (strlen (fmt) * 2 + 1);
2719           for (s = (char *) fmt, s1 = fmt2; *s; s++)
2720             {
2721               if (*s == '#')
2722                 {
2723                   strcpy (s1, args[arg_count++]);
2724                   s1 += strlen(s1);
2725                 }
2726               else
2727                 *s1++ = *s;
2728             }
2729           *s1 = 0;
2730           scrolling_puts (ts, fmt2, char_delay);
2731           free (fmt2);
2732           usleep (chunk_delay);
2733           if (bsod_sleep (dpy, 0))
2734             goto DONE;
2735         }
2736     }
2737
2738   XSync(dpy, False);
2739   bsod_sleep(dpy, delay);
2740
2741  DONE:
2742   free_scrolling_window (ts);
2743   for (i = 0; i < countof (args); i++)
2744     free (args[i]);
2745 }
2746
2747
2748 /* HVX (formerly GCOS6) and TPS6 crash
2749    by Brian Garratt <brian-m.garratt@bull.co.uk>
2750
2751    GCOS6 is a Unix-like operating system developed by Honeywell in the
2752    1970s in collaboration with MIT and AT&T (who called their version
2753    UNIX).  Both are very much like MULTICS which Honeywell got from GE.
2754
2755    HVX ("High-performance Virtual System on Unix") is an AIX application
2756    which emulates GCOS6 hardware on RS6000-like machines.
2757  */
2758 static void
2759 hvx (Display *dpy, Window window, int delay)
2760 {
2761   XWindowAttributes xgwa;
2762   scrolling_window *ts;
2763
2764   int delay1 = 10000;
2765   int delay2 = 100000;
2766   const char *hvx_panic_1 =
2767     ("(TP) Trap no E   Effective address 00000000   Instruction D7DE\n"
2768      "(TP)  Registers :\n"
2769      "(TP)  B1 -> B7  03801B02  00000000  03880D45  038BABDB  0388AFFD"
2770      "  0389B3F8  03972317\n"
2771      "(TP)  R1 -> R7  0001  0007  F10F  090F  0020  0106  0272\n"
2772      "(TP)  P I Z M1  0388A18B  3232  0000 FF00\n"
2773      "(TP) Program counter is at offset 0028 from string YTPAD\n"
2774      "(TP) User id of task which trapped is LT 626\n"
2775      "(TP)?\n"
2776      );
2777   const char *hvx_panic_2 =
2778     ("\n"
2779      "(TP)?\n"
2780      "Core dumps initiated for selected HVX processes ...\n"
2781      "Core dumps complete.\n"
2782      "Fri Jul 19 15:53:09 2002\n"
2783      "Live registers for cp 0:\n"
2784      " P    =     7de3  IW=0000     I=32    CI=30000000   S=80006013"
2785      "   IV=aa0      Level=13\n"
2786      " R1-7 =       1f      913       13        4        8        0        0\n"
2787      " B1-7 =   64e71b      a93      50e   64e73c     6c2c     7000      b54\n"
2788      "Memory dump starting to file /var/hvx/dp01/diag/Level2 ...\n"
2789      "Memory dump complete.\n"
2790     );
2791
2792   XGetWindowAttributes (dpy, window, &xgwa);
2793   ts = make_scrolling_window (dpy, window, "HVX", False);
2794   XClearWindow(dpy, window);
2795
2796   scrolling_puts (ts, hvx_panic_1,         delay1);
2797   if (bsod_sleep(dpy, 1)) goto DONE;
2798   scrolling_puts (ts, " TP CLOSE ALL",     delay2);
2799   scrolling_puts (ts, "\n(TP)?\n",         delay1);
2800   if (bsod_sleep(dpy, 1)) goto DONE;
2801   scrolling_puts (ts, " TP ABORT -LT ALL", delay2);
2802   scrolling_puts (ts, "\n(TP)?\n",         delay1);
2803   if (bsod_sleep(dpy, 1)) goto DONE;
2804   scrolling_puts (ts, "  TP STOP KILL",    delay2);
2805   scrolling_puts (ts, hvx_panic_2,         delay1);
2806
2807   bsod_sleep(dpy, delay);
2808  DONE:
2809   XClearWindow(dpy, window);
2810 }
2811
2812
2813 \f
2814
2815 /* HPUX panic, by Tobias Klausmann <klausman@schwarzvogel.de>
2816  */
2817
2818 static void
2819 hpux (Display* dpy, Window window, int delay)
2820 {
2821   XWindowAttributes xgwa;
2822   scrolling_window *ts;
2823   const char *sysname;
2824   char buf[2048];
2825
2826 # ifdef __GNUC__
2827   __extension__   /* don't warn about "string length is greater than the
2828                      length ISO C89 compilers are required to support"
2829                      in the following string constant... */
2830 # endif
2831
2832   const char *msg1 =
2833    "Console Login:\n"
2834    "\n"
2835    "     ******* Unexpected HPMC/TOC. Processor HPA FFFFFFFF'"
2836    "FFFA0000 *******\n"
2837    "                              GENERAL REGISTERS:\n"
2838    "r00/03 00000000'00000000 00000000'00000000 00000000'00000000 00000000'"
2839    "006C76C0\n"
2840    "r04/07 00000000'00000001 00000000'0126E328 00000000'00000000 00000000'"
2841    "0122B640\n"
2842    "r08/11 00000000'00000000 00000000'0198CFC0 00000000'000476FE 00000000'"
2843    "00000001\n"
2844    "r12/15 00000000'40013EE8 00000000'08000080 00000000'4002530C 00000000'"
2845    "4002530C\n"
2846    "r16/19 00000000'7F7F2A00 00000000'00000001 00000000'00000000 00000000'"
2847    "00000000\n"
2848    "r20/23 00000000'006C8048 00000000'00000001 00000000'00000000 00000000'"
2849    "00000000\n"
2850    "r24/27 00000000'00000000 00000000'00000000 00000000'00000000 00000000'"
2851    "00744378\n"
2852    "r28/31 00000000'00000000 00000000'007DD628 00000000'0199F2B0 00000000'"
2853    "00000000\n"
2854    "                              CONTROL REGISTERS:\n"
2855    "sr0/3  00000000'0F3B4000 00000000'0C2A2000 00000000'016FF800 00000000'"
2856    "00000000\n"
2857    "sr4/7  00000000'00000000 00000000'016FF800 00000000'0DBF1400 00000000'"
2858    "00000000\n"
2859    "pcq =  00000000'00000000.00000000'00104950 00000000'00000000.00000000'"
2860    "00104A14\n"
2861    "isr =  00000000'10240006 ior = 00000000'67D9E220 iir = 08000240 rctr = "
2862    "7FF10BB6\n"
2863    "\n"
2864    "pid reg cr8/cr9    00007700'0000B3A9 00000000'0000C5D8\n"
2865    "pid reg cr12/cr13  00000000'00000000 00000000'00000000\n"
2866    "ipsw = 000000FF'080CFF1F iva = 00000000'0002C000 sar = 3A ccr = C0\n"
2867    "tr0/3  00000000'006C76C0 00000000'00000001 00000000'00000000 00000000'"
2868    "7F7CE000\n"
2869    "tr4/7  00000000'03790000 0000000C'4FB68340 00000000'C07EE13F 00000000'"
2870    "0199F2B0\n"
2871    "eiem = FFFFFFF0'FFFFFFFF eirr = 80000000'00000000 itmr = 0000000C'"
2872    "4FD8EDE1\n"
2873    "cr1/4  00000000'00000000 00000000'00000000 00000000'00000000 00000000'"
2874    "00000000\n"
2875    "cr5/7  00000000'00000000 00000000'00000000 00000000'"
2876    "00000000\n"
2877    "                           MACHINE CHECK PARAMETERS:\n"
2878    "Check Type = 00000000 CPU STATE = 9E000001 Cache Check = 00000000\n"
2879    "TLB Check = 00000000 Bus Check = 00000000 PIM State = ? SIU "
2880    "Status = ????????\n"
2881    "Assists = 00000000 Processor = 00000000\n"
2882    "Slave Addr = 00000000'00000000 Master Addr = 00000000'00000000\n"
2883    "\n"
2884    "\n"
2885    "TOC,    pcsq.pcoq = 0'0.0'104950   , isr.ior = 0'10240006.0'67d9e220\n"
2886    "@(#)B2352B/9245XB HP-UX (B.11.00) #1: Wed Nov  5 22:38:19 PST 1997\n"
2887    "Transfer of control: (display==0xd904, flags==0x0)\n"
2888    "\n"
2889    "\n"
2890    "\n"
2891    "*** A system crash has occurred.  (See the above messages for details.)\n"
2892    "*** The system is now preparing to dump physical memory to disk, for use\n"
2893    "*** in debugging the crash.\n"
2894    "\n"
2895    "*** The dump will be a SELECTIVE dump:  40 of 256 megabytes.\n"
2896    "*** To change this dump type, press any key within 10 seconds.\n"
2897    "*** Proceeding with selective dump.\n"
2898    "\n"
2899    "*** The dump may be aborted at any time by pressing ESC.\n";
2900   const char *msg2 =
2901    "\n*** System rebooting.\n";
2902
2903   XGetWindowAttributes (dpy, window, &xgwa);
2904   ts = make_scrolling_window (dpy, window, "HPUX", False);
2905   XClearWindow(dpy,window);
2906   ts->columns = 10000;  /* never wrap */
2907   ts->sub_x = 0;
2908   ts->sub_y = 0;
2909   ts->sub_width = xgwa.width;
2910   ts->sub_height = xgwa.height;
2911
2912   sysname = "HPUX";
2913 # ifdef HAVE_UNAME
2914   {
2915     struct utsname uts;
2916     char *s;
2917     if (uname (&uts) >= 0)
2918       sysname = uts.nodename;
2919     s = strchr (sysname, '.');
2920     if (s) *s = 0;
2921   }
2922 # endif /* !HAVE_UNAME */
2923
2924   if (bsod_sleep (dpy, 1))
2925     goto DONE;
2926   
2927   scrolling_puts (ts,
2928                   "                                                       "
2929                   "                                                       "
2930                   "                                                       \n",
2931                   0);
2932   sprintf (buf, "%.100s [HP Release B.11.00] (see /etc/issue)\n", sysname);
2933   scrolling_puts (ts, buf, 0);
2934   if (bsod_sleep (dpy, 1))
2935     goto DONE;
2936   scrolling_puts (ts, msg1, 0);
2937   {
2938     int i;
2939     int steps = 11;
2940     int size = 40;
2941     for (i = 0; i <= steps; i++)
2942       {
2943         if (i > steps) i = steps;
2944         sprintf (buf, 
2945                "*** Dumping: %3d%% complete (%d of 40 MB) (device 64:0x2)\r",
2946                  i * 100 / steps,
2947                  i * size / steps);
2948         scrolling_puts (ts, buf, 0);
2949         XSync (dpy, False);
2950         usleep (1500000);
2951         if (bsod_sleep (dpy, 0))
2952           goto DONE;
2953       }
2954   }
2955
2956   scrolling_puts (ts, msg2, 0);
2957
2958   XSync(dpy, False);
2959   bsod_sleep(dpy, delay);
2960
2961  DONE:
2962   free_scrolling_window (ts);
2963 }
2964
2965 \f
2966
2967 /* IBM OS/390 aka MVS aka z/OS.
2968    Text from Dan Espen <dane@mk.telcordia.com>.
2969    Apparently this isn't actually a crash, just a random session...
2970    But who can tell.
2971  */
2972
2973 static void
2974 os390 (Display* dpy, Window window, int delay)
2975 {
2976   GC gc;
2977   XGCValues gcv;
2978   XWindowAttributes xgwa;
2979   scrolling_window *ts;
2980   int i;
2981
2982   const char *msg[] = {
2983    "* ISPF Subtask abend *\n",
2984    "SPF      ENDED DUE TO ERROR+\n",
2985    "READY\n",
2986    "\n",
2987    "IEA995I SYMPTOM DUMP OUTPUT\n",
2988    "  USER COMPLETION CODE=0222\n",
2989    " TIME=23.00.51  SEQ=03210  CPU=0000  ASID=00AE\n",
2990    " PSW AT TIME OF ERROR  078D1000   859DAF18  ILC 2  INTC 0D\n",
2991    "   NO ACTIVE MODULE FOUND\n",
2992    "   NAME=UNKNOWN\n",
2993    "   DATA AT PSW  059DAF12 - 00181610  0A0D9180  70644710\n",
2994    "   AR/GR 0: 00000000/80000000   1: 00000000/800000DE\n",
2995    "         2: 00000000/196504DC   3: 00000000/00037A78\n",
2996    "         4: 00000000/00037B78   5: 00000000/0003351C\n",
2997    "         6: 00000000/0000F0AD   7: 00000000/00012000\n",
2998    "         8: 00000000/059DAF10   9: 00000000/0002D098\n",
2999    "         A: 00000000/059D9F10   B: 00000000/059D8F10\n",
3000    "         C: 00000000/859D7F10   D: 00000000/00032D60\n",
3001    "         E: 00000000/00033005   F: 01000002/00000041\n",
3002    " END OF SYMPTOM DUMP\n",
3003    "ISPS014 - ** Logical screen request failed - abend 0000DE **\n",
3004    "ISPS015 - ** Contact your system programmer or dialog developer.**\n",
3005    "*** ISPF Main task abend ***\n",
3006    "IEA995I SYMPTOM DUMP OUTPUT\n",
3007    "  USER COMPLETION CODE=0222\n",
3008    " TIME=23.00.52  SEQ=03211  CPU=0000  ASID=00AE\n",
3009    " PSW AT TIME OF ERROR  078D1000   8585713C  ILC 2  INTC 0D\n",
3010    "   ACTIVE LOAD MODULE           ADDRESS=05855000  OFFSET=0000213C\n",
3011    "   NAME=ISPMAIN\n",
3012    "   DATA AT PSW  05857136 - 00181610  0A0D9180  D3304770\n",
3013    "   GR 0: 80000000   1: 800000DE\n",
3014    "      2: 00015260   3: 00000038\n",
3015    "      4: 00012508   5: 00000000\n",
3016    "      6: 000173AC   7: FFFFFFF8\n",
3017    "      8: 05858000   9: 00012CA0\n",
3018    "      A: 05857000   B: 05856000\n",
3019    "      C: 85855000   D: 00017020\n",
3020    "      E: 85857104   F: 00000000\n",
3021    " END OF SYMPTOM DUMP\n",
3022    "READY\n",
3023    "***_\n"
3024   };
3025
3026   XGetWindowAttributes (dpy, window, &xgwa);
3027   ts = make_scrolling_window (dpy, window, "OS390", False);
3028   ts->columns = 10000;  /* never wrap */
3029   ts->sub_x = 0;
3030   ts->sub_y = 0;
3031   ts->sub_width = xgwa.width;
3032   ts->sub_height = xgwa.height;
3033
3034   gcv.foreground = get_pixel_resource ("390.background", "390.Background",
3035                                        dpy, xgwa.colormap);
3036   gc = XCreateGC (dpy, window, GCForeground, &gcv);
3037   XFillRectangle (dpy, window, gc, 0, 0, xgwa.width, xgwa.height);
3038   XFreeGC (dpy, gc);
3039
3040   for (i = 0; i < countof (msg); i++)
3041     {
3042       scrolling_puts (ts, msg[i], 0);
3043       usleep (100000);
3044       if (bsod_sleep(dpy, 0)) goto DONE;
3045     }
3046
3047   XSync(dpy, False);
3048   bsod_sleep(dpy, delay);
3049 DONE:
3050   free_scrolling_window (ts);
3051 }
3052
3053
3054 \f
3055
3056 /* Compaq Tru64 Unix panic, by jwz as described by
3057    Tobias Klausmann <klausman@schwarzvogel.de>
3058  */
3059
3060 static void
3061 tru64 (Display* dpy, Window window, int delay)
3062 {
3063   XWindowAttributes xgwa;
3064   scrolling_window *ts;
3065   const char *sysname;
3066   char buf[2048];
3067
3068 # ifdef __GNUC__
3069   __extension__   /* don't warn about "string length is greater than the
3070                      length ISO C89 compilers are required to support"
3071                      in the following string constant... */
3072 # endif
3073
3074   const char *msg1 =
3075    ("panic (cpu 0): trap: illegal instruction\n"
3076     "kernel inst fault=gentrap, ps=0x5, pc=0xfffffc0000593878, inst=0xaa\n"
3077     "kernel inst fault=gentrap, ps=0x5, pc=0xfffffc0000593878, inst=0xaa\n"
3078     "                                                                   \n"
3079     "DUMP: blocks available:  1571600\n"
3080     "DUMP: blocks wanted:      100802 (partial compressed dump) [OKAY]\n"
3081     "DUMP: Device     Disk Blocks Available\n"
3082     "DUMP: ------     ---------------------\n"
3083     "DUMP: 0x1300023  1182795 - 1571597 (of 1571598) [primary swap]\n"
3084     "DUMP.prom: Open: dev 0x5100041, block 2102016: SCSI 0 11 0 2 200 0 0\n"
3085     "DUMP: Writing header... [1024 bytes at dev 0x1300023, block 1571598]\n"
3086     "DUMP: Writing data");
3087   const char *msg2 =
3088    ("DUMP: Writing header... [1024 bytes at dev 0x1300023, block 1571598]\n"
3089     "DUMP: crash dump complete.\n"
3090     "kernel inst fault=gentrap, ps=0x5, pc=0xfffffc0000593878, inst=0xaa\n"
3091     "                                                                   \n"
3092     "DUMP: second crash dump skipped: 'dump_savecnt' enforced.\n");
3093   const char *msg3 =
3094    ("\n"
3095     "halted CPU 0\n"
3096     "\n"
3097     "halt code = 5\n"
3098     "HALT instruction executed\n"
3099     "PC = fffffc00005863b0\n");
3100   const char *msg4 =
3101    ("\n"   
3102     "CPU 0 booting\n"
3103     "\n"
3104     "\n"
3105     "\n");
3106
3107   XGetWindowAttributes (dpy, window, &xgwa);
3108   ts = make_scrolling_window (dpy, window, "Tru64", False);
3109   XClearWindow(dpy,window);
3110   ts->columns = 10000;  /* never wrap */
3111   ts->sub_x = 0;
3112   ts->sub_y = 0;
3113   ts->sub_width = xgwa.width;
3114   ts->sub_height = xgwa.height;
3115
3116   sysname = "127.0.0.1";
3117 # ifdef HAVE_UNAME
3118   {
3119     struct utsname uts;
3120     if (uname (&uts) >= 0)
3121       sysname = uts.nodename;
3122   }
3123 # endif /* !HAVE_UNAME */
3124
3125   if (bsod_sleep (dpy, 1))
3126     goto DONE;
3127   
3128       
3129
3130   sprintf (buf,
3131            "Compaq Tru64 UNIX V5.1B (Rev. 2650) (%.100s) console\n"
3132            "\n"
3133            "login: ",
3134            sysname);
3135   scrolling_puts (ts, buf, 0);
3136   if (bsod_sleep (dpy, 6))
3137     goto DONE;
3138
3139   scrolling_puts (ts, msg1, 0);
3140   {
3141     int i;
3142     int steps = 4 + (random() % 8);
3143     for (i = 0; i < steps; i++)
3144       {
3145         scrolling_puts (ts, ".", 0);
3146         XSync (dpy, False);
3147         if (bsod_sleep (dpy, 1))
3148           goto DONE;
3149       }
3150     sprintf (buf, "[%dMB]\n", steps);
3151     scrolling_puts (ts, buf, 0);
3152   }
3153
3154   scrolling_puts (ts, msg2, 0);
3155   XSync(dpy, False);
3156   if (bsod_sleep (dpy, 4))
3157     goto DONE;
3158
3159   scrolling_puts (ts, msg3, 0);
3160   XSync(dpy, False);
3161   if (bsod_sleep (dpy, 3))
3162     goto DONE;
3163
3164   scrolling_puts (ts, msg4, 0);
3165   XSync(dpy, False);
3166   bsod_sleep(dpy, delay);
3167
3168  DONE:
3169   free_scrolling_window (ts);
3170 }
3171
3172
3173 \f
3174 /*
3175  * Simulate various Apple ][ crashes. The memory map encouraged many programs
3176  * to use the primary hi-res video page for various storage, and the secondary
3177  * hi-res page for active display. When it crashed into Applesoft or the
3178  * monitor, it would revert to the primary page and you'd see memory garbage on
3179  * the screen. Also, it was common for copy-protected games to use the primary
3180  * text page for important code, because that made it really hard to
3181  * reverse-engineer them. The result often looked like what this generates.
3182  *
3183  * The Apple ][ logic and video hardware is in apple2.c. The TV is emulated by
3184  * analogtv.c for maximum realism
3185  *
3186  * Trevor Blackwell <tlb@tlb.org> 
3187  */
3188
3189 static char * apple2_basic_errors[]={
3190   "BREAK",
3191   "NEXT WITHOUT FOR",
3192   "SYNTAX ERROR",
3193   "RETURN WITHOUT GOSUB",
3194   "ILLEGAL QUANTITY",
3195   "OVERFLOW",
3196   "OUT OF MEMORY",
3197   "BAD SUBSCRIPT ERROR",
3198   "DIVISION BY ZERO",
3199   "STRING TOO LONG",
3200   "FORMULA TOO COMPLEX",
3201   "UNDEF'D FUNCTION",
3202   "OUT OF DATA"
3203 #if 0
3204   ,
3205   "DEFAULT ARGUMENTS ARE NOT ALLOWED IN DECLARATION OF FRIEND "
3206   "TEMPLATE SPECIALIZATION"
3207 #endif
3208
3209 };
3210 static char * apple2_dos_errors[]={
3211   "VOLUME MISMATCH",
3212   "I/O ERROR",
3213   "DISK FULL",
3214   "NO BUFFERS AVAILABLE",
3215   "PROGRAM TOO LARGE",
3216 };
3217
3218 void a2controller_crash(apple2_sim_t *sim, int *stepno,
3219                         double *next_actiontime)
3220 {
3221   apple2_state_t *st=sim->st;
3222   char *s;
3223   int i;
3224
3225   struct mydata {
3226     int fillptr;
3227     int fillbyte;
3228   } *mine;
3229
3230   if (!sim->controller_data)
3231     sim->controller_data = calloc(sizeof(struct mydata),1);
3232   mine=(struct mydata *) sim->controller_data;
3233   
3234   switch(*stepno) {
3235   case 0:
3236     
3237     a2_init_memory_active(sim);
3238     sim->dec->powerup = 1000.0;
3239
3240     if (random()%3==0) {
3241       st->gr_mode=0;
3242       *next_actiontime+=0.4;
3243       *stepno=100;
3244     }
3245     else if (random()%4==0) {
3246       st->gr_mode=A2_GR_LORES;
3247       if (random()%3==0) st->gr_mode |= A2_GR_FULL;
3248       *next_actiontime+=0.4;
3249       *stepno=100;
3250     }
3251     else if (random()%2==0) {
3252       st->gr_mode=A2_GR_HIRES;
3253       *stepno=300;
3254     }
3255     else {
3256       st->gr_mode=A2_GR_HIRES;
3257       *next_actiontime+=0.4;
3258       *stepno=100;
3259     }
3260     break;
3261
3262   case 100:
3263     /* An illegal instruction or a reset caused it to drop into the
3264        assembly language monitor, where you could disassemble code & view
3265        data in hex. */
3266     if (random()%3==0) {
3267       char ibytes[128];
3268       char itext[128];
3269       int addr=0xd000+random()%0x3000;
3270       sprintf(ibytes,
3271               "%02X",random()%0xff);
3272       sprintf(itext,
3273               "???");
3274       sprintf(sim->printing_buf,
3275               "\n\n"
3276               "%04X: %-15s %s\n"
3277               " A=%02X X=%02X Y=%02X S=%02X F=%02X\n"
3278               "*",
3279               addr,ibytes,itext,
3280               random()%0xff, random()%0xff,
3281               random()%0xff, random()%0xff,
3282               random()%0xff);
3283       sim->printing=sim->printing_buf;
3284       a2_goto(st,23,1);
3285       if (st->gr_mode) {
3286         *stepno=180;
3287       } else {
3288         *stepno=200;
3289       }
3290       sim->prompt='*';
3291       *next_actiontime += 2.0 + (random()%1000)*0.0002;
3292     }
3293     else {
3294       /* Lots of programs had at least their main functionality in
3295          Applesoft Basic, which had a lot of limits (memory, string
3296          length, etc) and would sometimes crash unexpectedly. */
3297       sprintf(sim->printing_buf,
3298               "\n"
3299               "\n"
3300               "\n"
3301               "?%s IN %d\n"
3302               "\001]",
3303               apple2_basic_errors[random() %
3304                                   (sizeof(apple2_basic_errors)
3305                                    /sizeof(char *))],
3306               (1000*(random()%(random()%59+1)) +
3307                100*(random()%(random()%9+1)) +
3308                5*(random()%(random()%199+1)) +
3309                1*(random()%(random()%(random()%2+1)+1))));
3310       sim->printing=sim->printing_buf;
3311       a2_goto(st,23,1);
3312       *stepno=110;
3313       sim->prompt=']';
3314       *next_actiontime += 2.0 + (random()%1000)*0.0002;
3315     }
3316     break;
3317
3318   case 110:
3319     if (random()%3==0) {
3320       /* This was how you reset the Basic interpreter. The sort of
3321          incantation you'd have on a little piece of paper taped to the
3322          side of your machine */
3323       sim->typing="CALL -1370";
3324       *stepno=120;
3325     }
3326     else if (random()%2==0) {
3327       sim->typing="CATALOG\n";
3328       *stepno=170;
3329     }
3330     else {
3331       *next_actiontime+=1.0;
3332       *stepno=999;
3333     }
3334     break;
3335
3336   case 120:
3337     *stepno=130;
3338     *next_actiontime += 0.5;
3339     break;
3340
3341   case 130:
3342     st->gr_mode=0;
3343     a2_cls(st);
3344     a2_goto(st,0,16);
3345     for (s="APPLE ]["; *s; s++) a2_printc(st,*s);
3346     a2_goto(st,23,0);
3347     a2_printc(st,']');
3348     *next_actiontime+=1.0;
3349     *stepno=999;
3350     break;
3351
3352   case 170:
3353     if (random()%50==0) {
3354       sprintf(sim->printing_buf,
3355               "\nDISK VOLUME 254\n\n"
3356               " A 002 HELLO\n"
3357               "\n"
3358               "]");
3359       sim->printing=sim->printing_buf;
3360     }
3361     else {
3362       sprintf(sim->printing_buf,"\n?%s\n]",
3363               apple2_dos_errors[random()%
3364                                 (sizeof(apple2_dos_errors) /
3365                                  sizeof(char *))]);
3366       sim->printing=sim->printing_buf;
3367     }
3368     *stepno=999;
3369     *next_actiontime+=1.0;
3370     break;
3371
3372   case 180:
3373     if (random()%2==0) {
3374       /* This was how you went back to text mode in the monitor */
3375       sim->typing="FB4BG";
3376       *stepno=190;
3377     } else {
3378       *next_actiontime+=1.0;
3379       *stepno=999;
3380     }
3381     break;
3382
3383   case 190:
3384     st->gr_mode=0;
3385     a2_invalidate(st);
3386     a2_printc(st,'\n');
3387     a2_printc(st,'*');
3388     *stepno=200;
3389     *next_actiontime+=2.0;
3390     break;
3391
3392   case 200:
3393     /* This reset things into Basic */
3394     if (random()%2==0) {
3395       sim->typing="FAA6G";
3396       *stepno=120;
3397     }
3398     else {
3399       *stepno=999;
3400       *next_actiontime+=sim->delay;
3401     }
3402     break;
3403
3404   case 300:
3405     for (i=0; i<1500; i++) {
3406       a2_poke(st, mine->fillptr, mine->fillbyte);
3407       mine->fillptr++;
3408       mine->fillbyte = (mine->fillbyte+1)&0xff;
3409     }
3410     *next_actiontime += 0.08;
3411     /* When you hit c000, it changed video settings */
3412     if (mine->fillptr>=0xc000) {
3413       a2_invalidate(st);
3414       st->gr_mode=0;
3415     }
3416     /* And it seemed to reset around here, I dunno why */
3417     if (mine->fillptr>=0xcf00) *stepno=130;
3418     break;
3419
3420   case 999:
3421     break;
3422
3423   case A2CONTROLLER_FREE:
3424     free(mine);
3425     break;
3426   }
3427 }
3428
3429 static void
3430 apple2crash (Display* dpy, Window window, int delay)
3431 {
3432   apple2 (dpy, window, delay, a2controller_crash);
3433 }
3434
3435 /* MS-DOS, by jwz
3436  */
3437 static void
3438 msdos (Display *dpy, Window window, int delay)
3439 {
3440   XWindowAttributes xgwa;
3441   scrolling_window *ts;
3442
3443   int delay1 = 10000;
3444   int delay2 = 200000;
3445
3446 # define CURSOR "_\b \b"
3447 # define CURSOR2 CURSOR CURSOR CURSOR
3448
3449   XGetWindowAttributes (dpy, window, &xgwa);
3450   ts = make_scrolling_window (dpy, window, "MSDOS", False);
3451
3452   XClearWindow(dpy, window);
3453
3454   scrolling_puts (ts, "C:\\WINDOWS>", delay1);
3455   if (bsod_sleep(dpy, 1)) goto DONE;
3456
3457   scrolling_puts (ts, CURSOR2 "dir a:", delay2);
3458   if (bsod_sleep(dpy, 1)) goto DONE;
3459
3460   scrolling_puts (ts, "\nNot ready reading drive A\nAbort, Retry, Fail?",
3461                   delay1);
3462   if (bsod_sleep(dpy, 1)) goto DONE;
3463
3464   scrolling_puts (ts, CURSOR2 "f", delay2);
3465   if (bsod_sleep(dpy, 1)) goto DONE;
3466
3467   scrolling_puts (ts, "\n\n\nNot ready reading drive A\nAbort, Retry, Fail?",
3468                   delay1);
3469   if (bsod_sleep(dpy, 1)) goto DONE;
3470
3471   scrolling_puts (ts, CURSOR2 "f", delay2);
3472   if (bsod_sleep(dpy, 1)) goto DONE;
3473
3474   scrolling_puts (ts, "\nVolume in drive A has no label\n\n"
3475                   "Not ready reading drive A\nAbort, Retry, Fail?",
3476                   delay1);
3477   if (bsod_sleep(dpy, 1)) goto DONE;
3478
3479   scrolling_puts (ts, CURSOR2 "a", delay2);
3480   if (bsod_sleep(dpy, 1)) goto DONE;
3481
3482   scrolling_puts (ts, "\n\nC:\\WINDOWS>", delay1);
3483
3484   {
3485     time_t start = time((time_t *) 0);
3486     while (start + delay > time((time_t *) 0))
3487       if (scrolling_puts (ts, CURSOR, delay2))
3488         break;
3489   }
3490
3491  DONE:
3492   XClearWindow(dpy, window);
3493
3494 # undef CURSOR
3495 # undef CURSOR2
3496 }
3497
3498
3499
3500 \f
3501 char *progclass = "BSOD";
3502
3503 char *defaults [] = {
3504   "*delay:                 30",
3505
3506   "*doOnly:                ",
3507   "*doWindows:             True",
3508   "*doNT:                  True",
3509   "*doWin2K:               True",
3510   "*doAmiga:               True",
3511   "*doMac:                 True",
3512   "*doMacsBug:             True",
3513   "*doMac1:                True",
3514   "*doMacX:                True",
3515   "*doSCO:                 True",
3516   "*doAtari:               False",      /* boring */
3517   "*doBSD:                 False",      /* boring */
3518   "*doLinux:               True",
3519   "*doSparcLinux:          False",      /* boring */
3520   "*doHPPALinux:           True",
3521   "*doBlitDamage:          True",
3522   "*doSolaris:             True",
3523   "*doHPUX:                True",
3524   "*doTru64:               True",
3525   "*doApple2:              True",
3526   "*doOS390:               True",
3527   "*doVMS:                 True",
3528   "*doHVX:                 True",
3529   "*doMSDOS:               True",
3530
3531   ".Windows.font:          -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3532   ".Windows.font2:         -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
3533   ".Windows.foreground:    White",
3534   ".Windows.background:    #0000AA",    /* EGA color 0x01. */
3535
3536   ".Amiga.font:            -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3537   ".Amiga.font2:           -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
3538   ".Amiga.foreground:      Red",
3539   ".Amiga.background:      Black",
3540   ".Amiga.background2:     White",
3541
3542   ".Mac.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3543   ".Mac.foreground:        PaleTurquoise1",
3544   ".Mac.background:        Black",
3545
3546   ".Atari.foreground:      Black",
3547   ".Atari.background:      White",
3548
3549   ".MacsBug.font:          -*-courier-medium-r-*-*-*-100-*-*-m-*-*-*",
3550   ".MacsBug.font2:         -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3551   ".MacsBug.font3:         -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3552   ".MacsBug.foreground:    Black",
3553   ".MacsBug.background:    White",
3554   ".MacsBug.borderColor:   #AAAAAA",
3555
3556   ".mac1.foreground:       Black",
3557   ".mac1.background:       White",
3558
3559   ".macX.textForeground:   White",
3560   ".macX.textBackground:   Black",
3561   ".macX.background:       #888888",
3562   ".macX.font:             -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3563   ".macX.font2:            -*-courier-bold-r-*-*-*-240-*-*-m-*-*-*",
3564
3565   ".SCO.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3566   ".SCO.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3567   ".SCO.foreground:        White",
3568   ".SCO.background:        Black",
3569
3570   ".HVX.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3571   ".HVX.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3572   ".HVX.foreground:        White",
3573   ".HVX.background:        Black",
3574
3575   ".Linux.font:            9x15bold",
3576   ".Linux.font2:           -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3577   ".Linux.foreground:      White",
3578   ".Linux.background:      Black",
3579
3580   ".HPPALinux.font:        -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3581   ".HPPALinux.font2:       -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3582   ".HPPALinux.foreground:  White",
3583   ".HPPALinux.background:  Black",
3584
3585   ".SparcLinux.font:       -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3586   ".SparcLinux.font2:      -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3587   ".SparcLinux.foreground: White",
3588   ".SparcLinux.background: Black",
3589
3590   ".BSD.font:              vga",
3591   ".BSD.font:              -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
3592   ".BSD.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3593 /* ".BSD.font2:            -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", */
3594   ".BSD.foreground:        #c0c0c0",
3595   ".BSD.background:        Black",
3596
3597   ".Solaris.font:          -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
3598   ".Solaris.font2:         -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3599   ".Solaris.foreground:    Black",
3600   ".Solaris.background:    White",
3601   "*dontClearRoot:         True",
3602
3603   ".HPUX.font:             9x15bold",
3604   ".HPUX.font2:            -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3605   ".HPUX.foreground:       White",
3606   ".HPUX.background:       Black",
3607
3608   ".OS390.font:            9x15bold",
3609   ".OS390.font2:           -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3610   ".OS390.background:      Black",
3611   ".OS390.foreground:      Red",
3612
3613   ".Tru64.font:            9x15bold",
3614   ".Tru64.font2:           -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3615   ".Tru64.foreground:      White",
3616   ".Tru64.background:      #0000AA",    /* EGA color 0x01. */
3617
3618   "*apple2TVColor:         50",
3619   "*apple2TVTint:          5",
3620   "*apple2TVBrightness:    10",
3621   "*apple2TVContrast:      90",
3622   "*apple2SimulateUser:    True",
3623
3624   ".VMS.font:              9x15bold",
3625   ".VMS.font2:             -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3626   ".VMS.foreground:        White",
3627   ".VMS.background:        Black",
3628
3629   ".MSDOS.font:            9x15bold",
3630   ".MSDOS.font2:           -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
3631   ".MSDOS.foreground:      White",
3632   ".MSDOS.background:      Black",
3633
3634   ANALOGTV_DEFAULTS
3635
3636 #ifdef HAVE_XSHM_EXTENSION
3637   "*useSHM:                True",
3638 #endif
3639   0
3640 };
3641
3642 XrmOptionDescRec options [] = {
3643   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
3644   { "-only",            ".doOnly",              XrmoptionSepArg, 0 },
3645   { "-windows",         ".doWindows",           XrmoptionNoArg,  "True"  },
3646   { "-no-windows",      ".doWindows",           XrmoptionNoArg,  "False" },
3647   { "-nt",              ".doNT",                XrmoptionNoArg,  "True"  },
3648   { "-no-nt",           ".doNT",                XrmoptionNoArg,  "False" },
3649   { "-2k",              ".doWin2K",             XrmoptionNoArg,  "True"  },
3650   { "-no-2k",           ".doWin2K",             XrmoptionNoArg,  "False" },
3651   { "-amiga",           ".doAmiga",             XrmoptionNoArg,  "True"  },
3652   { "-no-amiga",        ".doAmiga",             XrmoptionNoArg,  "False" },
3653   { "-mac",             ".doMac",               XrmoptionNoArg,  "True"  },
3654   { "-no-mac",          ".doMac",               XrmoptionNoArg,  "False" },
3655   { "-mac1",            ".doMac1",              XrmoptionNoArg,  "True"  },
3656   { "-no-mac1",         ".doMac1",              XrmoptionNoArg,  "False" },
3657   { "-macx",            ".doMacX",              XrmoptionNoArg,  "True"  },
3658   { "-no-macx",         ".doMacX",              XrmoptionNoArg,  "False" },
3659   { "-atari",           ".doAtari",             XrmoptionNoArg,  "True"  },
3660   { "-no-atari",        ".doAtari",             XrmoptionNoArg,  "False" },
3661   { "-macsbug",         ".doMacsBug",           XrmoptionNoArg,  "True"  },
3662   { "-no-macsbug",      ".doMacsBug",           XrmoptionNoArg,  "False" },
3663   { "-apple2",          ".doApple2",            XrmoptionNoArg,  "True"  },
3664   { "-no-apple2",       ".doApple2",            XrmoptionNoArg,  "False" },
3665   { "-sco",             ".doSCO",               XrmoptionNoArg,  "True"  },
3666   { "-no-sco",          ".doSCO",               XrmoptionNoArg,  "False" },
3667   { "-hvx",             ".doHVX",               XrmoptionNoArg,  "True"  },
3668   { "-no-hvx",          ".doHVX",               XrmoptionNoArg,  "False" },
3669   { "-bsd",             ".doBSD",               XrmoptionNoArg,  "True"  },
3670   { "-no-bsd",          ".doBSD",               XrmoptionNoArg,  "False" },
3671   { "-linux",           ".doLinux",             XrmoptionNoArg,  "True"  },
3672   { "-no-linux",        ".doLinux",             XrmoptionNoArg,  "False" },
3673   { "-hppalinux",       ".doHPPALinux",         XrmoptionNoArg,  "True"  },
3674   { "-no-hppalinux",    ".doHPPALinux",         XrmoptionNoArg,  "False" },
3675   { "-sparclinux",      ".doSparcLinux",        XrmoptionNoArg,  "True"  },
3676   { "-no-sparclinux",   ".doSparcLinux",        XrmoptionNoArg,  "False" },
3677   { "-blitdamage",      ".doBlitDamage",        XrmoptionNoArg,  "True"  },
3678   { "-no-blitdamage",   ".doBlitDamage",        XrmoptionNoArg,  "False" },
3679   { "-nvidia",          ".doNvidia",            XrmoptionNoArg,  "True"  },
3680   { "-no-nvidia",       ".doNvidia",            XrmoptionNoArg,  "False" },
3681   { "-solaris",         ".doSolaris",           XrmoptionNoArg,  "True"  },
3682   { "-no-solaris",      ".doSolaris",           XrmoptionNoArg,  "False" },
3683   { "-hpux",            ".doHPUX",              XrmoptionNoArg,  "True"  },
3684   { "-no-hpux",         ".doHPUX",              XrmoptionNoArg,  "False" },
3685   { "-os390",           ".doOS390",             XrmoptionNoArg,  "True"  },
3686   { "-no-os390",        ".doOS390",             XrmoptionNoArg,  "False" },
3687   { "-tru64",           ".doHPUX",              XrmoptionNoArg,  "True"  },
3688   { "-no-tru64",        ".doTru64",             XrmoptionNoArg,  "False" },
3689   { "-vms",             ".doVMS",               XrmoptionNoArg,  "True"  },
3690   { "-no-vms",          ".doVMS",               XrmoptionNoArg,  "False" },
3691   { "-msdos",           ".doMSDOS",             XrmoptionNoArg,  "True"  },
3692   { "-no-msdos",        ".doMSDOS",             XrmoptionNoArg,  "False" },
3693   ANALOGTV_OPTIONS
3694   { 0, 0, 0, 0 }
3695 };
3696
3697
3698 static struct {
3699   const char *name;
3700   void (*fn) (Display *, Window, int delay);
3701 } all_modes[] = {
3702   { "Windows",          windows_31 },
3703   { "NT",              windows_nt },
3704   { "Win2K",           windows_2k },
3705   { "Amiga",            amiga },
3706   { "Mac",              mac },
3707   { "MacsBug",          macsbug },
3708   { "Mac1",             mac1 },
3709   { "MacX",             macx },
3710   { "SCO",              sco },
3711   { "HVX",              hvx },
3712   { "HPPALinux",        hppa_linux },
3713   { "SparcLinux",       sparc_linux },
3714   { "BSD",              bsd },
3715   { "Atari",            atari },
3716   { "BlitDamage",       blitdamage },
3717   { "Nvidia",           nvidia },
3718   { "Solaris",          sparc_solaris },
3719   { "Linux",            linux_fsck },
3720   { "HPUX",             hpux },
3721   { "OS390",            os390 },
3722   { "Tru64",            tru64 },
3723   { "Apple2",           apple2crash },
3724   { "VMS",              vms },
3725   { "MSDOS",            msdos },
3726 };
3727
3728
3729 void
3730 screenhack (Display *dpy, Window window)
3731 {
3732   int loop = 0;
3733   int i = -1;
3734   int j = -1;
3735   int only = -1;
3736   int delay = get_integer_resource ("delay", "Integer");
3737   if (delay < 3) delay = 3;
3738
3739   {
3740     char *s = get_string_resource("doOnly", "DoOnly");
3741     if (s && *s)
3742       {
3743         int count = countof(all_modes);
3744         for (only = 0; only < count; only++)
3745           if (!strcasecmp (s, all_modes[only].name))
3746             break;
3747         if (only >= count)
3748           {
3749             fprintf (stderr, "%s: unknown -only mode: \"%s\"\n", progname, s);
3750             only = -1;
3751           }
3752       }
3753     if (s) free (s);
3754   }
3755
3756   if (!get_boolean_resource ("root", "Boolean"))
3757     {
3758       XWindowAttributes xgwa;
3759       XGetWindowAttributes (dpy, window, &xgwa);
3760       XSelectInput (dpy, window,
3761                     xgwa.your_event_mask |
3762                     KeyPressMask | ButtonPressMask | ExposureMask);
3763     }
3764
3765   while (1)
3766     {
3767       Bool did;
3768       int count = countof(all_modes);
3769       char name[100], class[100];
3770
3771       if (only > 0)
3772         i = only;
3773       else
3774         do {  i = (random() & 0xFF) % count; } while (i == j);
3775
3776       sprintf (name,  "do%s", all_modes[i].name);
3777       sprintf (class, "Do%s", all_modes[i].name);
3778
3779       did = False;
3780       if (only > 0 || get_boolean_resource(name, class))
3781         {
3782           all_modes[i].fn (dpy, window, delay);
3783           did = True;
3784         }
3785
3786       loop++;
3787       if (loop > 100) j = -1;
3788       if (loop > 200)
3789         {
3790           fprintf (stderr, "%s: no display modes enabled?\n", progname);
3791           exit(-1);
3792         }
3793       if (!did) continue;
3794       XSync (dpy, False);
3795       j = i;
3796       loop = 0;
3797     }
3798 }