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