1 /* xscreensaver, Copyright (c) 1998-2001 Jamie Zawinski <jwz@jwz.org>
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
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.
16 * - Should simulate a Unix kernel panic and reboot.
17 * - Making various boot noises would be fun, too.
18 * - Should randomize the various hex numbers printed.
21 #include "screenhack.h"
22 #include "xpm-pixmap.h"
24 #include <X11/Xutil.h>
27 #include "images/amiga.xpm"
28 #include "images/atari.xbm"
29 #include "images/mac.xbm"
33 draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
36 int win_width, int win_height,
37 const char *string, int delay)
40 int width = 0, height = 0, cw = 0;
41 int char_width, line_height;
43 const char *s = string;
44 const char *se = string;
46 /* This pretty much assumes fixed-width fonts */
47 char_width = (font->per_char
48 ? font->per_char['n'-font->min_char_or_byte2].width
49 : font->min_bounds.width);
50 line_height = font->ascent + font->descent + 1;
54 if (*s == '\n' || !*s)
57 if (cw > width) width = cw;
66 x = (win_width - (width * char_width)) / 2;
67 y = (win_height - (height * line_height)) / 2;
78 if (*s == '\n' || !*s)
83 if (*se == '@' || *se == '_')
85 if (*se == '@') flip = True;
87 off = (char_width * (width - (s - se))) / 2;
92 XSetForeground(dpy, gc, gcv->background);
93 XSetBackground(dpy, gc, gcv->foreground);
97 XDrawImageString(dpy, window, gc, x+off, y+font->ascent, se, s-se);
101 XSetForeground(dpy, gc, gcv->foreground);
102 XSetBackground(dpy, gc, gcv->background);
119 return width * char_width;
124 double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
125 int pix_w, int pix_h)
128 Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth);
129 XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap);
130 XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0,
131 pix_w*2, pix_h*2, 8, 0);
132 i2->data = (char *) calloc(i2->height, i2->bytes_per_line);
133 for (y = 0; y < pix_h; y++)
134 for (x = 0; x < pix_w; x++)
136 unsigned long p = XGetPixel(i1, x, y);
137 XPutPixel(i2, x*2, y*2, p);
138 XPutPixel(i2, x*2+1, y*2, p);
139 XPutPixel(i2, x*2, y*2+1, p);
140 XPutPixel(i2, x*2+1, y*2+1, p);
142 free(i1->data); i1->data = 0;
144 XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height);
145 free(i2->data); i2->data = 0;
147 XFreePixmap(dpy, pixmap);
152 /* Sleep for N seconds and return False. But if a key or mouse event is
153 seen, discard all pending key or mouse events, and return True.
156 bsod_sleep(Display *dpy, int seconds)
159 int quantum = 250000;
162 q = 1, quantum = 100000;
167 while (XPending (dpy))
170 XNextEvent (dpy, &event);
171 if (event.xany.type == ButtonPress)
173 if (event.xany.type == KeyPress)
177 XLookupString (&event.xkey, &c, 1, &keysym, 0);
178 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
181 screenhack_handle_event (dpy, &event);
197 windows (Display *dpy, Window window, int delay, Bool w95p)
200 XWindowAttributes xgwa;
202 const char *def_font = "fixed";
208 "A fatal exception 0E has occured at F0AD:42494C4C\n"
209 "the current application will be terminated.\n"
211 "* Press any key to terminate the current application.\n"
212 "* Press CTRL+ALT+DELETE again to restart your computer.\n"
213 " You will lose any unsaved information in all applications.\n"
216 "_Press any key to continue");
218 const char *wnt = /* from Jim Niemira <urmane@urmane.org> */
219 ("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
220 "Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
222 "Dll Base Date Stamp - Name Dll Base Date Stamp - Name\n"
223 "80100000 2be154c9 - ntoskrnl.exe 80400000 2bc153b0 - hal.dll\n"
224 "80258000 2bd49628 - ncrc710.sys 8025c000 2bd49688 - SCSIPORT.SYS \n"
225 "80267000 2bd49683 - scsidisk.sys 802a6000 2bd496b9 - Fastfat.sys\n"
226 "fa800000 2bd49666 - Floppy.SYS fa810000 2bd496db - Hpfs_Rec.SYS\n"
227 "fa820000 2bd49676 - Null.SYS fa830000 2bd4965a - Beep.SYS\n"
228 "fa840000 2bdaab00 - i8042prt.SYS fa850000 2bd5a020 - SERMOUSE.SYS\n"
229 "fa860000 2bd4966f - kbdclass.SYS fa870000 2bd49671 - MOUCLASS.SYS\n"
230 "fa880000 2bd9c0be - Videoprt.SYS fa890000 2bd49638 - NCC1701E.SYS\n"
231 "fa8a0000 2bd4a4ce - Vga.SYS fa8b0000 2bd496d0 - Msfs.SYS\n"
232 "fa8c0000 2bd496c3 - Npfs.SYS fa8e0000 2bd496c9 - Ntfs.SYS\n"
233 "fa940000 2bd496df - NDIS.SYS fa930000 2bd49707 - wdlan.sys\n"
234 "fa970000 2bd49712 - TDI.SYS fa950000 2bd5a7fb - nbf.sys\n"
235 "fa980000 2bd72406 - streams.sys fa9b0000 2bd4975f - ubnb.sys\n"
236 "fa9c0000 2bd5bfd7 - usbser.sys fa9d0000 2bd4971d - netbios.sys\n"
237 "fa9e0000 2bd49678 - Parallel.sys fa9f0000 2bd4969f - serial.SYS\n"
238 "faa00000 2bd49739 - mup.sys faa40000 2bd4971f - SMBTRSUP.SYS\n"
239 "faa10000 2bd6f2a2 - srv.sys faa50000 2bd4971a - afd.sys\n"
240 "faa60000 2bd6fd80 - rdr.sys faaa0000 2bd49735 - bowser.sys\n"
242 "Address dword dump Dll Base - Name\n"
243 "801afc20 80106fc0 80106fc0 00000000 00000000 80149905 : "
244 "fa840000 - i8042prt.SYS\n"
245 "801afc24 80149905 80149905 ff8e6b8c 80129c2c ff8e6b94 : "
246 "8025c000 - SCSIPORT.SYS\n"
247 "801afc2c 80129c2c 80129c2c ff8e6b94 00000000 ff8e6b94 : "
248 "80100000 - ntoskrnl.exe\n"
249 "801afc34 801240f2 80124f02 ff8e6df4 ff8e6f60 ff8e6c58 : "
250 "80100000 - ntoskrnl.exe\n"
251 "801afc54 80124f16 80124f16 ff8e6f60 ff8e6c3c 8015ac7e : "
252 "80100000 - ntoskrnl.exe\n"
253 "801afc64 8015ac7e 8015ac7e ff8e6df4 ff8e6f60 ff8e6c58 : "
254 "80100000 - ntoskrnl.exe\n"
255 "801afc70 80129bda 80129bda 00000000 80088000 80106fc0 : "
256 "80100000 - ntoskrnl.exe\n"
258 "Kernel Debugger Using: COM2 (Port 0x2f8, Baud Rate 19200)\n"
259 "Restart and set the recovery options in the system control panel\n"
260 "or the /CRASHDEBUG system start option. If this message reappears,\n"
261 "contact your system administrator or technical support group."
264 if (!get_boolean_resource((w95p? "doWindows" : "doNT"), "DoWindows"))
267 XGetWindowAttributes (dpy, window, &xgwa);
269 fontname = get_string_resource ((xgwa.height > 600
275 : "windowsNT.font")),
277 if (!fontname || !*fontname) fontname = (char *)def_font;
278 font = XLoadQueryFont (dpy, fontname);
279 if (!font) font = XLoadQueryFont (dpy, def_font);
281 if (fontname && fontname != def_font)
284 gcv.font = font->fid;
285 gcv.foreground = get_pixel_resource((w95p
286 ? "windows95.foreground"
287 : "windowsNT.foreground"),
288 "Windows.Foreground",
290 gcv.background = get_pixel_resource((w95p
291 ? "windows95.background"
292 : "windowsNT.background"),
293 "Windows.Background",
295 XSetWindowBackground(dpy, window, gcv.background);
296 XClearWindow(dpy, window);
298 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
301 draw_string(dpy, window, gc, &gcv, font,
302 0, 0, xgwa.width, xgwa.height, w95, 0);
304 draw_string(dpy, window, gc, &gcv, font, 0, 0, 10, 10, wnt, 750);
308 bsod_sleep(dpy, delay);
309 XClearWindow(dpy, window);
310 XFreeFont(dpy, font);
314 /* SCO OpenServer 5 panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
317 sco (Display *dpy, Window window, int delay)
320 XWindowAttributes xgwa;
322 const char *def_font = "fixed";
325 int lines_1 = 0, lines_2 = 0, lines_3 = 0, lines_4 = 0;
328 const char *sco_panic_1 =
329 ("Unexpected trap in kernel mode:\n"
331 "cr0 0x80010013 cr2 0x00000014 cr3 0x00000000 tlb 0x00000000\n"
332 "ss 0x00071054 uesp 0x00012055 efl 0x00080888 ipl 0x00000005\n"
333 "cs 0x00092585 eip 0x00544a4b err 0x004d4a47 trap 0x0000000E\n"
334 "eax 0x0045474b ecx 0x0042544b edx 0x57687920 ebx 0x61726520\n"
335 "esp 0x796f7520 ebp 0x72656164 esi 0x696e6720 edi 0x74686973\n"
336 "ds 0x3f000000 es 0x43494c48 fs 0x43525343 gs 0x4f4d4b53\n"
338 "PANIC: k_trap - kernel mode trap type 0x0000000E\n"
339 "Trying to dump 5023 pages to dumpdev hd (1/41), 63 pages per '.'\n"
341 const char *sco_panic_2 =
342 ("...............................................................................\n"
344 const char *sco_panic_3 =
345 ("5023 pages dumped\n"
349 const char *sco_panic_4 =
350 ("** Safe to Power Off **\n"
352 "** Press Any Key to Reboot **\n"
355 if (!get_boolean_resource("doSCO", "DoSCO"))
358 for (s = sco_panic_1; *s; s++) if (*s == '\n') lines_1++;
359 for (s = sco_panic_2; *s; s++) if (*s == '\n') lines_2++;
360 for (s = sco_panic_3; *s; s++) if (*s == '\n') lines_3++;
361 for (s = sco_panic_4; *s; s++) if (*s == '\n') lines_4++;
363 XGetWindowAttributes (dpy, window, &xgwa);
365 fontname = get_string_resource ((xgwa.height > 600
369 if (!fontname || !*fontname) fontname = (char *)def_font;
370 font = XLoadQueryFont (dpy, fontname);
371 if (!font) font = XLoadQueryFont (dpy, def_font);
373 if (fontname && fontname != def_font)
376 gcv.font = font->fid;
377 gcv.foreground = get_pixel_resource(("sco.foreground"),
380 gcv.background = get_pixel_resource(("sco.background"),
383 XSetWindowBackground(dpy, window, gcv.background);
384 XClearWindow(dpy, window);
386 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
388 draw_string(dpy, window, gc, &gcv, font,
389 10, xgwa.height - ((lines_1 + lines_2 + lines_3 + lines_4 + 1) *
390 (font->ascent + font->descent + 1)),
394 for (s = sco_panic_2; *s; s++)
396 char *ss = strdup(sco_panic_2);
397 ss[s - sco_panic_2] = 0;
398 draw_string(dpy, window, gc, &gcv, font,
399 10, xgwa.height - ((lines_2 + lines_3 + lines_4 + 1) *
400 (font->ascent + font->descent + 1)),
405 if (bsod_sleep (dpy, -1))
409 draw_string(dpy, window, gc, &gcv, font,
410 10, xgwa.height - ((lines_3 + lines_4 + 1) *
411 (font->ascent + font->descent + 1)),
415 if (bsod_sleep(dpy, 1))
417 draw_string(dpy, window, gc, &gcv, font,
418 10, xgwa.height - ((lines_4 + 1) *
419 (font->ascent + font->descent + 1)),
424 bsod_sleep(dpy, delay);
426 XClearWindow(dpy, window);
428 XFreeFont(dpy, font);
433 /* Linux (sparc) panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
436 sparc_linux (Display *dpy, Window window, int delay)
439 XWindowAttributes xgwa;
441 const char *def_font = "fixed";
447 const char *linux_panic =
448 ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
449 "Unable to handle kernel paging request at virtual address f0d4a000\n"
450 "tsk->mm->context = 00000014\n"
451 "tsk->mm->pgd = f26b0000\n"
456 "gawk(22827): Oops\n"
457 "PSR: 044010c1 PC: f001c2cc NPC: f001c2d0 Y: 00000000\n"
458 "g0: 00001000 g1: fffffff7 g2: 04401086 g3: 0001eaa0\n"
459 "g4: 000207dc g5: f0130400 g6: f0d4a018 g7: 00000001\n"
460 "o0: 00000000 o1: f0d4a298 o2: 00000040 o3: f1380718\n"
461 "o4: f1380718 o5: 00000200 sp: f1b13f08 ret_pc: f001c2a0\n"
462 "l0: efffd880 l1: 00000001 l2: f0d4a230 l3: 00000014\n"
463 "l4: 0000ffff l5: f0131550 l6: f012c000 l7: f0130400\n"
464 "i0: f1b13fb0 i1: 00000001 i2: 00000002 i3: 0007c000\n"
465 "i4: f01457c0 i5: 00000004 i6: f1b13f70 i7: f0015360\n"
466 "Instruction DUMP:\n"
469 if (!get_boolean_resource("doSparcLinux", "DoSparcLinux"))
472 for (s = linux_panic; *s; s++) if (*s == '\n') lines++;
474 XGetWindowAttributes (dpy, window, &xgwa);
476 fontname = get_string_resource ((xgwa.height > 600
478 : "sparclinux.font"),
480 if (!fontname || !*fontname) fontname = (char *)def_font;
481 font = XLoadQueryFont (dpy, fontname);
482 if (!font) font = XLoadQueryFont (dpy, def_font);
484 if (fontname && fontname != def_font)
487 gcv.font = font->fid;
488 gcv.foreground = get_pixel_resource(("sparclinux.foreground"),
489 "SparcLinux.Foreground",
491 gcv.background = get_pixel_resource(("sparclinux.background"),
492 "SparcLinux.Background",
494 XSetWindowBackground(dpy, window, gcv.background);
495 XClearWindow(dpy, window);
497 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
499 draw_string(dpy, window, gc, &gcv, font,
500 10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
505 bsod_sleep(dpy, delay);
506 XClearWindow(dpy, window);
507 XFreeFont(dpy, font);
511 /* BSD Panic by greywolf@starwolf.com - modeled after the Linux panic above.
512 By Grey Wolf <greywolf@siteROCK.com>
515 bsd (Display *dpy, Window window, int delay)
518 XWindowAttributes xgwa;
520 const char *def_font = "fixed";
525 const char *rbstr, *panicking;
526 char syncing[80], bbuf[5], *bp;
528 const char *panicstr[] =
529 {"panic: ifree: freeing free inode",
530 "panic: blkfree: freeing free block",
531 "panic: improbability coefficient below zero",
533 "panic: crazy interrupts",
535 "panic: attempted windows install",
537 "panic: free inode isn't",
538 "panic: cpu_fork: curproc",
539 "panic: malloc: out of space in kmem_map",
540 "panic: vogon starship detected",
541 "panic: teleport chamber: out of order",
542 "panic: Brain fried - core dumped"};
544 if (!get_boolean_resource("doBSD", "DoBSD"))
547 for (i = 0; i < sizeof(syncing); i++)
550 i = (random() & 0xffff) % (sizeof(panicstr) / sizeof(*panicstr));
552 panicking = panicstr[i];
553 strcpy(syncing, "Syncing disks: ");
555 b = (random() & 0xff) % 40;
556 for (n = 0; (n < 20) && (b > 0); n++)
560 i = (random() & 0x7);
561 b -= (random() & 0xff) % 20;
565 sprintf (bbuf, "%d ", b);
566 strcat (syncing, bbuf);
576 XGetWindowAttributes (dpy, window, &xgwa);
578 fontname = get_string_resource ((xgwa.height > 600
582 if (!fontname || !*fontname) fontname = (char *)def_font;
583 font = XLoadQueryFont (dpy, fontname);
584 if (!font) font = XLoadQueryFont (dpy, def_font);
586 if (fontname && fontname != def_font)
589 gcv.font = font->fid;
590 gcv.foreground = get_pixel_resource(("bsd.foreground"),
593 gcv.background = get_pixel_resource(("bsd.background"),
596 XSetWindowBackground(dpy, window, gcv.background);
597 XClearWindow(dpy, window);
599 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
601 draw_string(dpy, window, gc, &gcv, font,
602 10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
608 for (bp = syncing; *bp;)
610 char *bsd_bufs, oc = 0;
611 for (;*bp && (*bp != ' '); bp++)
618 bsd_bufs = strdup(syncing);
619 draw_string(dpy, window, gc, &gcv, font,
621 xgwa.height - (lines * (font->ascent + font->descent + 1)),
628 if (bsod_sleep(dpy, -1))
635 draw_string(dpy, window, gc, &gcv, font,
636 10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
640 draw_string(dpy, window, gc, &gcv, font,
641 10, xgwa.height - (lines * (font->ascent + font->descent + 1)),
647 bsod_sleep(dpy, delay);
650 XClearWindow(dpy, window);
651 XFreeFont(dpy, font);
656 amiga (Display *dpy, Window window, int delay)
659 XWindowAttributes xgwa;
661 const char *def_font = "fixed";
665 unsigned long fg, bg, bg2;
667 int pix_w = 0, pix_h = 0;
672 ("_Software failure. Press left mouse button to continue.\n"
673 "_Guru Meditation #00000003.00C01570");
675 if (!get_boolean_resource("doAmiga", "DoAmiga"))
678 XGetWindowAttributes (dpy, window, &xgwa);
680 fontname = get_string_resource ((xgwa.height > 600
681 ? "amiga.font2" : "amiga.font"),
683 if (!fontname || !*fontname) fontname = (char *)def_font;
684 font = XLoadQueryFont (dpy, fontname);
685 if (!font) font = XLoadQueryFont (dpy, def_font);
687 if (fontname && fontname != def_font)
690 gcv.font = font->fid;
691 fg = gcv.foreground = get_pixel_resource("amiga.foreground",
694 bg = gcv.background = get_pixel_resource("amiga.background",
697 bg2 = get_pixel_resource("amiga.background2", "Amiga.Background",
699 XSetWindowBackground(dpy, window, bg2);
700 XClearWindow(dpy, window);
702 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
703 gcv.background = fg; gcv.foreground = bg;
704 gc2 = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
706 height = (font->ascent + font->descent) * 6;
708 #if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
709 pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand,
711 #endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
713 if (pixmap && xgwa.height > 600) /* scale up the bitmap */
715 pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
716 pixmap, pix_w, pix_h);
723 int x = (xgwa.width - pix_w) / 2;
724 int y = ((xgwa.height - pix_h) / 2);
725 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
730 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y + height);
731 XClearArea(dpy, window, 0, 0, xgwa.width, y + height, False);
732 XFreePixmap(dpy, pixmap);
735 XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
736 margin = font->ascent;
737 string_width = draw_string(dpy, window, gc, &gcv, font,
739 xgwa.width - (margin * 2), height,
746 XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, margin);
747 XFillRectangle(dpy, window, gca, 0, 0, margin, height);
748 XFillRectangle(dpy, window, gca,
749 0, height - margin, xgwa.width, margin);
750 x2 = margin + string_width;
751 if (x2 < xgwa.width - margin) x2 = xgwa.width - margin;
752 XFillRectangle(dpy, window, gca, x2, 0, margin, height);
754 gca = (gca == gc ? gc2 : gc);
756 if (bsod_sleep(dpy, 1))
765 XClearWindow(dpy, window);
766 XFreeFont(dpy, font);
771 /* Atari ST, by Marcus Herbert <rhoenie@nobiscum.de>
772 Marcus had this to say:
774 Though I still have my Atari somewhere, I hardly remember
775 the meaning of the bombs. I think 9 bombs was "bus error" or
776 something like that. And you often had a few bombs displayed
777 quickly and then the next few ones coming up step by step.
778 Perhaps somebody else can tell you more about it.. its just
782 atari (Display *dpy, Window window, int delay)
786 XWindowAttributes xgwa;
787 const char *def_font = "fixed";
791 int pix_w = atari_width;
792 int pix_h = atari_height;
796 if (!get_boolean_resource("doAtari", "DoAtari"))
799 XGetWindowAttributes (dpy, window, &xgwa);
801 font = XLoadQueryFont (dpy, def_font);
804 gcv.font = font->fid;
805 gcv.foreground = get_pixel_resource("atari.foreground", "Atari.Foreground",
807 gcv.background = get_pixel_resource("atari.background", "Atari.Background",
810 XSetWindowBackground(dpy, window, gcv.background);
811 XClearWindow(dpy, window);
813 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
815 pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) atari_bits,
817 gcv.foreground, gcv.background,
819 pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
820 pixmap, pix_w, pix_h);
826 y = (xgwa.height - (xgwa.height / 5));
829 for (i=0 ; i<7 ; i++) {
830 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
831 (x + (i*offset)), y);
834 for (i=7 ; i<10 ; i++) {
835 if (bsod_sleep(dpy, 1))
837 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
838 (x + (i*offset)), y);
841 bsod_sleep(dpy, delay);
843 XFreePixmap(dpy, pixmap);
846 XClearWindow(dpy, window);
847 XFreeFont(dpy, font);
853 mac (Display *dpy, Window window, int delay)
856 XWindowAttributes xgwa;
858 const char *def_font = "fixed";
862 int pix_w = mac_width;
863 int pix_h = mac_height;
864 int offset = mac_height * 4;
867 const char *string = ("0 0 0 0 0 0 0 F\n"
870 if (!get_boolean_resource("doMac", "DoMac"))
873 XGetWindowAttributes (dpy, window, &xgwa);
875 fontname = get_string_resource ("mac.font", "Mac.Font");
876 if (!fontname || !*fontname) fontname = (char *)def_font;
877 font = XLoadQueryFont (dpy, fontname);
878 if (!font) font = XLoadQueryFont (dpy, def_font);
880 if (fontname && fontname != def_font)
883 gcv.font = font->fid;
884 gcv.foreground = get_pixel_resource("mac.foreground", "Mac.Foreground",
886 gcv.background = get_pixel_resource("mac.background", "Mac.Background",
888 XSetWindowBackground(dpy, window, gcv.background);
889 XClearWindow(dpy, window);
891 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
893 pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits,
894 mac_width, mac_height,
899 for(i = 0; i < 2; i++)
901 pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
902 pixmap, pix_w, pix_h);
903 pix_w *= 2; pix_h *= 2;
907 int x = (xgwa.width - pix_w) / 2;
908 int y = (((xgwa.height + offset) / 2) -
910 (font->ascent + font->descent) * 2);
912 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
913 XFreePixmap(dpy, pixmap);
916 draw_string(dpy, window, gc, &gcv, font, 0, 0,
917 xgwa.width, xgwa.height + offset, string, 0);
921 bsod_sleep(dpy, delay);
922 XClearWindow(dpy, window);
923 XFreeFont(dpy, font);
928 macsbug (Display *dpy, Window window, int delay)
931 XWindowAttributes xgwa;
933 const char *def_font = "fixed";
937 int char_width, line_height;
938 int col_right, row_top, row_bottom, page_right, page_bottom, body_top;
941 const char *left = (" SP \n"
988 const char *bottom = (" _A09D\n"
989 " +00884 40843714 #$0700,SR "
991 " +00886 40843765 *+$0400 "
993 " +00888 40843718 $0004(A7),([0,A7[)"
994 " ; 04E8D0AE | 66B8");
997 const char *body = ("Bus Error at 4BF6D6CC\n"
998 "while reading word from 4BF6D6CC in User data space\n"
999 " Unable to access that address\n"
1001 " Frame Type: B008");
1003 const char * body = ("PowerPC unmapped memory exception at 003AFDAC "
1004 "BowelsOfTheMemoryMgr+04F9C\n"
1005 " Calling chain using A6/R1 links\n"
1006 " Back chain ISA Caller\n"
1007 " 00000000 PPC 28C5353C __start+00054\n"
1008 " 24DB03C0 PPC 28B9258C main+0039C\n"
1009 " 24DB0350 PPC 28B9210C MainEvent+00494\n"
1010 " 24DB02B0 PPC 28B91B40 HandleEvent+00278\n"
1011 " 24DB0250 PPC 28B83DAC DoAppleEvent+00020\n"
1012 " 24DB0210 PPC FFD3E5D0 "
1013 "AEProcessAppleEvent+00020\n"
1014 " 24DB0132 68K 00589468\n"
1015 " 24DAFF8C 68K 00589582\n"
1016 " 24DAFF26 68K 00588F70\n"
1017 " 24DAFEB3 PPC 00307098 "
1018 "EmToNatEndMoveParams+00014\n"
1019 " 24DAFE40 PPC 28B9D0B0 DoScript+001C4\n"
1020 " 24DAFDD0 PPC 28B9C35C RunScript+00390\n"
1021 " 24DAFC60 PPC 28BA36D4 run_perl+000E0\n"
1022 " 24DAFC10 PPC 28BC2904 perl_run+002CC\n"
1023 " 24DAFA80 PPC 28C18490 Perl_runops+00068\n"
1024 " 24DAFA30 PPC 28BE6CC0 Perl_pp_backtick+000FC\n"
1025 " 24DAF9D0 PPC 28BA48B8 Perl_my_popen+00158\n"
1026 " 24DAF980 PPC 28C5395C sfclose+00378\n"
1027 " 24DAF930 PPC 28BA568C free+0000C\n"
1028 " 24DAF8F0 PPC 28BA6254 pool_free+001D0\n"
1029 " 24DAF8A0 PPC FFD48F14 DisposePtr+00028\n"
1030 " 24DAF7C9 PPC 00307098 "
1031 "EmToNatEndMoveParams+00014\n"
1032 " 24DAF780 PPC 003AA180 __DisposePtr+00010");
1038 if (!get_boolean_resource("doMacsBug", "DoMacsBug"))
1041 for (s = body; *s; s++) if (*s == '\n') body_lines++;
1043 XGetWindowAttributes (dpy, window, &xgwa);
1045 fontname = get_string_resource ((xgwa.height > 850
1047 : (xgwa.height > 700
1051 if (!fontname || !*fontname) fontname = (char *)def_font;
1052 font = XLoadQueryFont (dpy, fontname);
1053 if (!font) font = XLoadQueryFont (dpy, def_font);
1054 if (!font) exit(-1);
1055 if (fontname && fontname != def_font)
1058 gcv.font = font->fid;
1059 gcv.foreground = get_pixel_resource("macsbug.foreground",
1060 "MacsBug.Foreground",
1061 dpy, xgwa.colormap);
1062 gcv.background = get_pixel_resource("macsbug.background",
1063 "MacsBug.Background",
1064 dpy, xgwa.colormap);
1066 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
1068 gcv.foreground = gcv.background;
1069 gc2 = XCreateGC(dpy, window, GCForeground, &gcv);
1071 XSetWindowBackground(dpy, window,
1072 get_pixel_resource("macsbug.borderColor",
1073 "MacsBug.BorderColor",
1074 dpy, xgwa.colormap));
1075 XClearWindow(dpy, window);
1077 char_width = (font->per_char
1078 ? font->per_char['n'-font->min_char_or_byte2].width
1079 : font->min_bounds.width);
1080 line_height = font->ascent + font->descent + 1;
1082 col_right = char_width * 12;
1083 page_bottom = line_height * 47;
1085 if (page_bottom > xgwa.height) page_bottom = xgwa.height;
1087 row_bottom = page_bottom - line_height;
1088 row_top = row_bottom - (line_height * 4);
1089 page_right = col_right + (char_width * 88);
1090 body_top = row_top - (line_height * body_lines);
1096 xoff = (xgwa.width - page_right) / 2;
1097 yoff = (xgwa.height - page_bottom) / 2;
1098 if (xoff < 0) xoff = 0;
1099 if (yoff < 0) yoff = 0;
1101 XFillRectangle(dpy, window, gc2, xoff, yoff, page_right, page_bottom);
1103 draw_string(dpy, window, gc, &gcv, font, xoff, yoff, 10, 10, left, 0);
1104 draw_string(dpy, window, gc, &gcv, font, xoff+col_right, yoff+row_top,
1107 XFillRectangle(dpy, window, gc, xoff + col_right, yoff, 2, page_bottom);
1108 XDrawLine(dpy, window, gc,
1109 xoff+col_right, yoff+row_top, xoff+page_right, yoff+row_top);
1110 XDrawLine(dpy, window, gc,
1111 xoff+col_right, yoff+row_bottom, xoff+page_right, yoff+row_bottom);
1112 XDrawRectangle(dpy, window, gc, xoff, yoff, page_right, page_bottom);
1117 draw_string(dpy, window, gc, &gcv, font,
1118 xoff + col_right + char_width, yoff + body_top, 10, 10, body,
1123 XDrawLine(dpy, window, gc,
1124 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1125 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1128 XDrawLine(dpy, window, gc2,
1129 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
1130 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
1133 if (bsod_sleep(dpy, 0))
1140 XClearWindow(dpy, window);
1141 XFreeFont(dpy, font);
1148 * by Martin Pool <mbp@samba.org>, Feb 2000.
1150 * This is meant to look like the preferred failure mode of NCD
1151 * Xterms. The parameters for choosing what to copy where might not
1152 * be quite right, but it looks about ugly enough.
1155 blitdamage (Display *dpy, Window window, int delay)
1158 XWindowAttributes xwa;
1161 int delta_x = 0, delta_y = 0;
1163 int chunk_h, chunk_w;
1169 if (!get_boolean_resource("doBlitDamage", "DoBlitDamage"))
1172 XGetWindowAttributes(dpy, window, &xwa);
1174 grab_screen_image(xwa.screen, window);
1179 gc_mask = GCForeground;
1181 gcv.plane_mask = random();
1182 gc_mask |= GCPlaneMask;
1184 gc0 = XCreateGC(dpy, window, gc_mask, &gcv);
1187 chunk_w = w / (random() % 1 + 1);
1188 chunk_h = h / (random() % 1 + 1);
1189 if (random() & 0x1000)
1190 delta_y = random() % 600;
1191 if (!delta_y || (random() & 0x2000))
1192 delta_x = random() % 600;
1198 for (i = 0; i < steps; i++) {
1199 if (x + chunk_w > w)
1204 if (y + chunk_h > h)
1209 XCopyArea(dpy, window, window, gc0,
1217 bsod_sleep(dpy, delay);
1226 * SPARC Solaris panic. Should look pretty authentic on Solaris boxes.
1227 * Anton Solovyev <solovam@earthlink.net>
1230 static int solaris_max_scroll = 10;
1237 Pixmap subwindow; /* The text subwindow */
1239 int width; /* Window width in pixels */
1240 int height; /* Window height in pixels */
1241 int sub_width; /* Text subwindow width in pixels */
1242 int sub_height; /* Text subwindow height in pixels */
1243 int sub_x; /* upper left corner of the text subwindow */
1244 int sub_y; /* upper left corner of the text subwindow */
1245 int char_width; /* Char width in pixels */
1246 int line_height; /* Line height in pixels */
1247 int columns; /* Number of columns in the text screen */
1248 int lines; /* Number of lines in the text screen */
1249 int x; /* position of the cursor */
1250 int y; /* position of the cursor */
1254 static solaris_console *
1255 make_solaris_console (Display *dpy, Window window)
1257 const char *def_font = "fixed";
1258 solaris_console* ts;
1260 XWindowAttributes xgwa;
1264 ts = malloc(sizeof(solaris_console));
1266 ts->window = window;
1272 XGetWindowAttributes (dpy, window, &xgwa);
1273 ts->width = xgwa.width;
1274 ts->height = xgwa.height;
1275 ts->sub_width = ts->width * 0.8;
1276 ts->sub_height = ts->height * 0.8;
1278 fontname = get_string_resource ("solaris.font", "Solaris.Font");
1279 ts->xfs = XLoadQueryFont (dpy, fontname);
1282 fontname = get_string_resource("solaris.font2", "Solaris.Font");
1283 ts->xfs = XLoadQueryFont(dpy, fontname);
1286 ts->xfs = XLoadQueryFont(dpy, def_font);
1289 fprintf (stderr, "Can't load font\n");
1290 XFreeFont (dpy, ts->xfs);
1294 gcv.font = ts->xfs->fid;
1295 ts->char_width = (ts->xfs->per_char
1296 ? ts->xfs->per_char[ts->xfs->min_char_or_byte2 +
1297 ts->xfs->default_char].width
1298 : ts->xfs->max_bounds.width);
1299 ts->line_height = ts->xfs->ascent + ts->xfs->descent + 1;
1301 ts->columns = ts->sub_width / ts->char_width;
1302 ts->lines = ts->sub_height / ts->line_height;
1304 ts->sub_x = (ts->width - ts->sub_width) / 2;
1305 ts->sub_y = (ts->height - ts->sub_height) / 2;
1307 ts->subwindow = XCreatePixmap (dpy, window, ts->sub_width,
1308 ts->sub_height * (solaris_max_scroll + 1),
1310 grab_screen_image (xgwa.screen, window);
1311 gcv.function = GXcopy;
1312 gcv.background = XBlackPixel (dpy, XDefaultScreen(dpy));
1313 gcv.foreground = XWhitePixel (dpy, XDefaultScreen(dpy));
1314 ts->gc = XCreateGC (dpy, window,
1315 GCFunction | GCBackground | GCForeground | GCFont,
1317 XCopyArea (dpy, window, ts->subwindow, ts->gc,
1318 ts->sub_x, ts->sub_y, ts->sub_width, ts->sub_height,
1320 XFillRectangle (dpy, ts->subwindow, ts->gc, 0, ts->sub_height,
1321 ts->sub_width, ts->sub_height * solaris_max_scroll);
1323 gcv.background = XWhitePixel (dpy, XDefaultScreen (dpy));
1324 gcv.foreground = XBlackPixel (dpy, XDefaultScreen (dpy));
1325 XChangeGC (dpy, ts->gc, GCBackground | GCForeground, &gcv);
1331 free_solaris_console (solaris_console* ts)
1333 XFreePixmap (ts->dpy, ts->subwindow);
1334 XFreeGC (ts->dpy, ts->gc);
1335 XFreeFont (ts->dpy, ts->xfs);
1340 solaris_draw (solaris_console* ts)
1342 XCopyArea (ts->dpy, ts->subwindow, ts->window, ts->gc, 0,
1343 (ts->y + 1) * ts->line_height, ts->sub_width,
1344 ts->sub_height, ts->sub_x, ts->sub_y);
1348 solaris_putc (solaris_console* ts, const char aChar)
1350 if (ts->y >= solaris_max_scroll * ts->lines)
1353 if (!ts->y && !ts->x)
1368 XDrawImageString (ts->dpy, ts->subwindow, ts->gc,
1369 (ts->x * ts->char_width -
1370 ts->xfs->min_bounds.lbearing),
1371 (ts->sub_height + (ts->y + 1) *
1372 ts->line_height - ts->xfs->descent),
1374 XCopyArea (ts->dpy, ts->subwindow, ts->window, ts->gc,
1375 ts->x * ts->char_width,
1376 ts->y * ts->line_height + ts->sub_height,
1377 ts->xfs->max_bounds.rbearing - ts->xfs->min_bounds.lbearing,
1378 ts->line_height, ts->sub_x + ts->x * ts->char_width,
1379 ts->sub_y + ts->sub_height - ts->line_height);
1381 if (ts->x >= ts->columns)
1384 solaris_putc(ts, '\n');
1391 solaris_puts (solaris_console* ts, const char* aString, int delay)
1394 for (c = aString; *c; ++c)
1396 solaris_putc (ts, *c);
1407 sparc_solaris (Display* dpy, Window window, int delay)
1410 "BAD TRAP: cpu=0 type=0x31 rp=0x2a10043b5e0 addr=0xf3880 mmu_fsr=0x0\n"
1411 "BAD TRAP occured in module \"unix\" due to an illegal access to a"
1413 "adb: trap type = 0x31\n"
1415 "pid=307, pc=0x100306e4, sp=0x2a10043ae81, tstate=0x4480001602,"
1417 "g1-g7: 1045b000, 32f, 10079440, 180, 300000ebde8, 0, 30000953a20\n"
1418 "Begin traceback... sp = 2a10043ae81\n"
1419 "Called from 100bd060, fp=2a10043af31, args=f3700 300008cc988 f3880 0"
1421 "Called from 101fe1bc, fp=2a10043b011, args=3000045a240 104465a0"
1422 " 300008e47d0 300008e48fa 300008ae350 300008ae410\n"
1423 "Called from 1007c520, fp=2a10043b0c1, args=300008e4878 300003596e8 0"
1424 " 3000045a320 0 3000045a220\n"
1425 "Called from 1007c498, fp=2a10043b171, args=1045a000 300007847f0 20"
1426 " 3000045a240 1 0\n"
1427 "Called from 1007972c, fp=2a10043b221, args=1 300009517c0 30000951e58 1"
1429 "Called from 10031e10, fp=2a10043b2d1, args=3000095b0c8 0 300009396a8"
1430 " 30000953a20 0 1\n"
1431 "Called from 10000bdd8, fp=ffffffff7ffff1c1, args=0 57 100131480"
1432 " 100131480 10012a6e0 0\n"
1433 "End traceback...\n"
1434 "panic[cpu0]/thread=30000953a20: trap\n"
1435 "syncing file systems...";
1438 "dumping to /dev/dsk/c0t0d0s3, offset 26935296\n";
1440 ": 2803 pages dumped, compression ratio 2.88, dump succeeded\n";
1445 solaris_console* ts;
1449 if (!get_boolean_resource("doSolaris", "DoSolaris"))
1452 ts = make_solaris_console (dpy, window);
1454 solaris_puts (ts, msg1, 0);
1455 bsod_sleep (dpy, 3);
1457 solaris_puts (ts, msg2, 0);
1458 bsod_sleep (dpy, 2);
1460 for (i = 1; i <= 100; ++i)
1462 sprintf(buf, "\b\b\b\b\b\b\b\b\b\b\b%3d%% done", i);
1463 solaris_puts(ts, buf, 0);
1467 solaris_puts (ts, msg3, 0);
1468 bsod_sleep (dpy, 2);
1470 solaris_puts (ts, msg4, 0);
1473 XFillRectangle (ts->dpy, ts->window, ts->gc, 0, 0,
1474 ts->width, ts->height);
1476 bsod_sleep (dpy, 3);
1478 free_solaris_console (ts);
1484 char *progclass = "BSOD";
1486 char *defaults [] = {
1493 "*doAtari: False", /* boring */
1496 "*doBSD: False", /* boring */
1497 "*doSparcLinux: False", /* boring */
1498 "*doBlitDamage: True",
1501 ".Windows.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1502 ".Windows.font2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
1503 ".Windows.foreground: White",
1504 ".Windows.background: Blue",
1506 ".Amiga.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1507 ".Amiga.font2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
1508 ".Amiga.foreground: Red",
1509 ".Amiga.background: Black",
1510 ".Amiga.background2: White",
1512 ".Mac.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1513 ".Mac.foreground: PaleTurquoise1",
1514 ".Mac.background: Black",
1516 ".Atari.foreground: Black",
1517 ".Atari.background: White",
1519 ".MacsBug.font: -*-courier-medium-r-*-*-*-100-*-*-m-*-*-*",
1520 ".MacsBug.font2: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1521 ".MacsBug.font3: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
1522 ".MacsBug.foreground: Black",
1523 ".MacsBug.background: White",
1524 ".MacsBug.borderColor: #AAAAAA",
1526 ".SCO.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1527 ".SCO.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
1528 ".SCO.foreground: White",
1529 ".SCO.background: Black",
1531 ".SparcLinux.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1532 ".SparcLinux.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
1533 ".SparcLinux.foreground: White",
1534 ".SparcLinux.background: Black",
1537 ".BSD.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
1538 ".BSD.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
1539 /* ".BSD.font2: -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", */
1540 ".BSD.foreground: #c0c0c0",
1541 ".BSD.background: Black",
1543 ".Solaris.font: -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
1544 ".Solaris.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
1545 "*dontClearRoot: True",
1549 XrmOptionDescRec options [] = {
1550 { "-delay", ".delay", XrmoptionSepArg, 0 },
1551 { "-windows", ".doWindows", XrmoptionNoArg, "True" },
1552 { "-no-windows", ".doWindows", XrmoptionNoArg, "False" },
1553 { "-nt", ".doNT", XrmoptionNoArg, "True" },
1554 { "-no-nt", ".doNT", XrmoptionNoArg, "False" },
1555 { "-amiga", ".doAmiga", XrmoptionNoArg, "True" },
1556 { "-no-amiga", ".doAmiga", XrmoptionNoArg, "False" },
1557 { "-mac", ".doMac", XrmoptionNoArg, "True" },
1558 { "-no-mac", ".doMac", XrmoptionNoArg, "False" },
1559 { "-atari", ".doAtari", XrmoptionNoArg, "True" },
1560 { "-no-atari", ".doAtari", XrmoptionNoArg, "False" },
1561 { "-macsbug", ".doMacsBug", XrmoptionNoArg, "True" },
1562 { "-no-macsbug", ".doMacsBug", XrmoptionNoArg, "False" },
1563 { "-sco", ".doSCO", XrmoptionNoArg, "True" },
1564 { "-no-sco", ".doSCO", XrmoptionNoArg, "False" },
1565 { "-bsd", ".doBSD", XrmoptionNoArg, "True" },
1566 { "-no-bsd", ".doBSD", XrmoptionNoArg, "False" },
1567 { "-sparclinux", ".doSparcLinux", XrmoptionNoArg, "True" },
1568 { "-no-sparclinux", ".doSparcLinux", XrmoptionNoArg, "False" },
1569 { "-blitdamage", ".doBlitDamage", XrmoptionNoArg, "True" },
1570 { "-no-blitdamage", ".doBlitDamage", XrmoptionNoArg, "False" },
1571 { "-solaris", ".doSolaris", XrmoptionNoArg, "True" },
1572 { "-no-solaris", ".doSolaris", XrmoptionNoArg, "False" },
1578 screenhack (Display *dpy, Window window)
1583 int delay = get_integer_resource ("delay", "Integer");
1584 if (delay < 3) delay = 3;
1586 if (!get_boolean_resource ("root", "Boolean"))
1588 XWindowAttributes xgwa;
1589 XGetWindowAttributes (dpy, window, &xgwa);
1590 XSelectInput (dpy, window,
1591 xgwa.your_event_mask | KeyPressMask | ButtonPressMask);
1597 do { i = (random() & 0xFF) % 11; } while (i == j);
1600 case 0: did = windows(dpy, window, delay, True); break;
1601 case 1: did = windows(dpy, window, delay, False); break;
1602 case 2: did = amiga(dpy, window, delay); break;
1603 case 3: did = mac(dpy, window, delay); break;
1604 case 4: did = macsbug(dpy, window, delay); break;
1605 case 5: did = sco(dpy, window, delay); break;
1606 case 6: did = sparc_linux(dpy, window, delay); break;
1607 case 7: did = bsd(dpy, window, delay); break;
1608 case 8: did = atari(dpy, window, delay); break;
1609 case 9: did = blitdamage(dpy, window, delay); break;
1610 case 10: did = sparc_solaris(dpy, window, delay); break;
1611 default: abort(); break;
1614 if (loop > 100) j = -1;
1617 fprintf (stderr, "%s: no display modes enabled?\n", progname);