1 /* xscreensaver, Copyright (c) 1998 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 have a "macsbug" mode.
17 * - Should simulate a Unix kernel panic and reboot.
18 * - Making various boot noises would be fun, too.
19 * - Maybe scatter some random bits across the screen,
20 * to simulate corruption of video ram?
21 * - Should randomize the various hex numbers printed.
24 #include "screenhack.h"
26 #include <X11/Xutil.h>
30 # include "images/amiga.xpm"
33 #include "images/atari.xbm"
34 #include "images/mac.xbm"
38 draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
41 int win_width, int win_height,
42 const char *string, int delay)
45 int width = 0, height = 0, cw = 0;
46 int char_width, line_height;
48 const char *s = string;
49 const char *se = string;
51 /* This pretty much assumes fixed-width fonts */
52 char_width = (font->per_char
53 ? font->per_char['n'-font->min_char_or_byte2].width
54 : font->min_bounds.width);
55 line_height = font->ascent + font->descent + 1;
59 if (*s == '\n' || !*s)
62 if (cw > width) width = cw;
71 x = (win_width - (width * char_width)) / 2;
72 y = (win_height - (height * line_height)) / 2;
83 if (*s == '\n' || !*s)
88 if (*se == '@' || *se == '_')
90 if (*se == '@') flip = True;
92 off = (char_width * (width - (s - se))) / 2;
97 XSetForeground(dpy, gc, gcv->background);
98 XSetBackground(dpy, gc, gcv->foreground);
102 XDrawImageString(dpy, window, gc, x+off, y+font->ascent, se, s-se);
106 XSetForeground(dpy, gc, gcv->foreground);
107 XSetBackground(dpy, gc, gcv->background);
127 double_pixmap(Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap,
128 int pix_w, int pix_h)
131 Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth);
132 XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap);
133 XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0,
134 pix_w*2, pix_h*2, 8, 0);
135 i2->data = (char *) calloc(i2->height, i2->bytes_per_line);
136 for (y = 0; y < pix_h; y++)
137 for (x = 0; x < pix_w; x++)
139 unsigned long p = XGetPixel(i1, x, y);
140 XPutPixel(i2, x*2, y*2, p);
141 XPutPixel(i2, x*2+1, y*2, p);
142 XPutPixel(i2, x*2, y*2+1, p);
143 XPutPixel(i2, x*2+1, y*2+1, p);
145 free(i1->data); i1->data = 0;
147 XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height);
148 free(i2->data); i2->data = 0;
150 XFreePixmap(dpy, pixmap);
155 /* Sleep for N seconds and return False. But if a key or mouse event is
156 seen, discard all pending key or mouse events, and return True.
159 bsod_sleep(Display *dpy, int seconds)
163 int mask = KeyPressMask|ButtonPressMask;
167 if (XCheckMaskEvent(dpy, mask, &event))
169 while (XCheckMaskEvent(dpy, mask, &event))
186 windows (Display *dpy, Window window, int delay, Bool w95p)
189 XWindowAttributes xgwa;
191 const char *def_font = "fixed";
197 "A fatal exception 0E has occured at F0AD:42494C4C\n"
198 "the current application will be terminated.\n"
200 "* Press any key to terminate the current application.\n"
201 "* Press CTRL+ALT+DELETE again to restart your computer.\n"
202 " You will lose any unsaved information in all applications.\n"
205 "_Press any key to continue");
208 ("*** STOP: 0x0000001E (0x80000003,0x80106fc0,0x8025ea21,0xfd6829e8)\n"
209 "Unhandled Kernel exception c0000047 from fa8418b4 (8025ea21,fd6829e8)\n"
211 "Dll Base Date Stamp - Name Dll Base Date Stamp - Name\n"
212 "80100000 2be154c9 - ntoskrnl.exe 80400000 2bc153b0 - hal.dll\n"
213 "80258000 2bd49628 - ncrc710.sys 8025c000 2bd49688 - SCSIPORT.SYS \n"
214 "80267000 2bd49683 - scsidisk.sys 802a6000 2bd496b9 - Fastfat.sys\n"
215 "fa800000 2bd49666 - Floppy.SYS fa810000 2bd496db - Hpfs_Rec.SYS\n"
216 "fa820000 2bd49676 - Null.SYS fa830000 2bd4965a - Beep.SYS\n"
217 "fa840000 2bdaab00 - i8042prt.SYS fa850000 2bd5a020 - SERMOUSE.SYS\n"
218 "fa860000 2bd4966f - kbdclass.SYS fa870000 2bd49671 - MOUCLASS.SYS\n"
219 "fa880000 2bd9c0be - Videoprt.SYS fa890000 2bd49638 - NCC1701E.SYS\n"
220 "fa8a0000 2bd4a4ce - Vga.SYS fa8b0000 2bd496d0 - Msfs.SYS\n"
221 "fa8c0000 2bd496c3 - Npfs.SYS fa8e0000 2bd496c9 - Ntfs.SYS\n"
222 "fa940000 2bd496df - NDIS.SYS fa930000 2bd49707 - wdlan.sys\n"
223 "fa970000 2bd49712 - TDI.SYS fa950000 2bd5a7fb - nbf.sys\n"
224 "fa980000 2bd72406 - streams.sys fa9b0000 2bd4975f - ubnb.sys\n"
225 "fa9c0000 2bd5bfd7 - usbser.sys fa9d0000 2bd4971d - netbios.sys\n"
226 "fa9e0000 2bd49678 - Parallel.sys fa9f0000 2bd4969f - serial.SYS\n"
227 "faa00000 2bd49739 - mup.sys faa40000 2bd4971f - SMBTRSUP.SYS\n"
228 "faa10000 2bd6f2a2 - srv.sys faa50000 2bd4971a - afd.sys\n"
229 "faa60000 2bd6fd80 - rdr.sys faaa0000 2bd49735 - bowser.sys\n"
231 "Address dword dump Dll Base - Name\n"
232 "801afc20 80106fc0 80106fc0 00000000 00000000 80149905 : "
233 "fa840000 - i8042prt.SYS\n"
234 "801afc24 80149905 80149905 ff8e6b8c 80129c2c ff8e6b94 : "
235 "8025c000 - SCSIPORT.SYS\n"
236 "801afc2c 80129c2c 80129c2c ff8e6b94 00000000 ff8e6b94 : "
237 "80100000 - ntoskrnl.exe\n"
238 "801afc34 801240f2 80124f02 ff8e6df4 ff8e6f60 ff8e6c58 : "
239 "80100000 - ntoskrnl.exe\n"
240 "801afc54 80124f16 80124f16 ff8e6f60 ff8e6c3c 8015ac7e : "
241 "80100000 - ntoskrnl.exe\n"
242 "801afc64 8015ac7e 8015ac7e ff8e6df4 ff8e6f60 ff8e6c58 : "
243 "80100000 - ntoskrnl.exe\n"
244 "801afc70 80129bda 80129bda 00000000 80088000 80106fc0 : "
245 "80100000 - ntoskrnl.exe\n"
247 "Kernel Debugger Using: COM2 (Port 0x2f8, Baud Rate 19200)\n"
248 "Restart and set the recovery options in the system control panel\n"
249 "or the /CRASHDEBUG system start option. If this message reappears,\n"
250 "contact your system administrator or technical support group."
253 XGetWindowAttributes (dpy, window, &xgwa);
255 fontname = get_string_resource ((xgwa.height > 600
261 : "windowsNT.font")),
263 if (!fontname || !*fontname) fontname = (char *)def_font;
264 font = XLoadQueryFont (dpy, fontname);
265 if (!font) font = XLoadQueryFont (dpy, def_font);
267 if (fontname && fontname != def_font)
270 gcv.font = font->fid;
271 gcv.foreground = get_pixel_resource((w95p
272 ? "windows95.foreground"
273 : "windowsNT.foreground"),
274 "Windows.Foreground",
276 gcv.background = get_pixel_resource((w95p
277 ? "windows95.background"
278 : "windowsNT.background"),
279 "Windows.Background",
281 XSetWindowBackground(dpy, window, gcv.background);
282 XClearWindow(dpy, window);
284 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
287 draw_string(dpy, window, gc, &gcv, font,
288 0, 0, xgwa.width, xgwa.height, w95, 0);
290 draw_string(dpy, window, gc, &gcv, font, 0, 0, 10, 10, wnt, 750);
294 bsod_sleep(dpy, delay);
295 XClearWindow(dpy, window);
296 XFreeFont(dpy, font);
299 /* SCO OpenServer 5 panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
302 openserver (Display *dpy, Window window, int delay)
305 XWindowAttributes xgwa;
307 const char *def_font = "fixed";
311 const char *openserver_panic =
312 ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
313 "Unexpected trap in kernel mode:\n"
315 "cr0 0x80010013 cr2 0x00000014 cr3 0x00000000 tlb 0x00000000\n"
316 "ss 0x00071054 uesp 0x00012055 efl 0x00080888 ipl 0x00000005\n"
317 "cs 0x00092585 eip 0x00544a4b err 0x004d4a47 trap 0x0000000E\n"
318 "eax 0x0045474b ecx 0x0042544b edx 0x57687920 ebx 0x61726520\n"
319 "esp 0x796f7520 ebp 0x72656164 esi 0x696e6720 edi 0x74686973\n"
320 "ds 0x3f000000 es 0x43494c48 fs 0x43525343 gs 0x4f4d4b53\n"
322 "PANIC: k_trap - kernel mode trap type 0x0000000E\n"
323 "Trying to dump 5023 pages to dumpdev hd (1/41), 63 pages per '.'\n"
324 "...............................................................................\n"
325 "5023 pages dumped\n"
328 "** Safe to Power Off **\n"
330 "** Press Any Key to Reboot **\n"
334 XGetWindowAttributes (dpy, window, &xgwa);
336 fontname = get_string_resource ((xgwa.height > 600
338 : "openserver.font"),
340 if (!fontname || !*fontname) fontname = (char *)def_font;
341 font = XLoadQueryFont (dpy, fontname);
342 if (!font) font = XLoadQueryFont (dpy, def_font);
344 if (fontname && fontname != def_font)
347 gcv.font = font->fid;
348 gcv.foreground = get_pixel_resource(("openserver.foreground"),
349 "OpenServer.Foreground",
351 gcv.background = get_pixel_resource(("openserver.background"),
352 "OpenServer.Background",
354 XSetWindowBackground(dpy, window, gcv.background);
355 XClearWindow(dpy, window);
357 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
359 draw_string(dpy, window, gc, &gcv, font,
360 0, 0, xgwa.width, xgwa.height, openserver_panic, 0);
363 bsod_sleep(dpy, delay);
364 XClearWindow(dpy, window);
365 XFreeFont(dpy, font);
369 /* Linux (sparc) panic, by Tom Kelly <tom@ancilla.toronto.on.ca>
372 sparc_linux (Display *dpy, Window window, int delay)
375 XWindowAttributes xgwa;
377 const char *def_font = "fixed";
381 const char *linux_panic =
382 ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
383 "Unable to handle kernel paging request at virtual address f0d4a000\n"
384 "tsk->mm->context = 00000014\n"
385 "tsk->mm->pgd = f26b0000\n"
390 "gawk(22827): Oops\n"
391 "PSR: 044010c1 PC: f001c2cc NPC: f001c2d0 Y: 00000000\n"
392 "g0: 00001000 g1: fffffff7 g2: 04401086 g3: 0001eaa0\n"
393 "g4: 000207dc g5: f0130400 g6: f0d4a018 g7: 00000001\n"
394 "o0: 00000000 o1: f0d4a298 o2: 00000040 o3: f1380718\n"
395 "o4: f1380718 o5: 00000200 sp: f1b13f08 ret_pc: f001c2a0\n"
396 "l0: efffd880 l1: 00000001 l2: f0d4a230 l3: 00000014\n"
397 "l4: 0000ffff l5: f0131550 l6: f012c000 l7: f0130400\n"
398 "i0: f1b13fb0 i1: 00000001 i2: 00000002 i3: 0007c000\n"
399 "i4: f01457c0 i5: 00000004 i6: f1b13f70 i7: f0015360\n"
405 XGetWindowAttributes (dpy, window, &xgwa);
407 fontname = get_string_resource ((xgwa.height > 600
409 : "sparclinux.font"),
411 if (!fontname || !*fontname) fontname = (char *)def_font;
412 font = XLoadQueryFont (dpy, fontname);
413 if (!font) font = XLoadQueryFont (dpy, def_font);
415 if (fontname && fontname != def_font)
418 gcv.font = font->fid;
419 gcv.foreground = get_pixel_resource(("sparclinux.foreground"),
420 "SparcLinux.Foreground",
422 gcv.background = get_pixel_resource(("sparclinux.background"),
423 "SparcLinux.Background",
425 XSetWindowBackground(dpy, window, gcv.background);
426 XClearWindow(dpy, window);
428 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
430 draw_string(dpy, window, gc, &gcv, font,
431 0, 0, xgwa.width, xgwa.height, linux_panic, 0);
434 bsod_sleep(dpy, delay);
435 XClearWindow(dpy, window);
436 XFreeFont(dpy, font);
440 amiga (Display *dpy, Window window, int delay)
443 XWindowAttributes xgwa;
445 const char *def_font = "fixed";
449 unsigned long fg, bg, bg2;
454 ("_Software failure. Press left mouse button to continue.\n"
455 "_Guru Meditation #00000003.00C01570");
457 XGetWindowAttributes (dpy, window, &xgwa);
459 fontname = get_string_resource ((xgwa.height > 600
460 ? "amiga.font2" : "amiga.font"),
462 if (!fontname || !*fontname) fontname = (char *)def_font;
463 font = XLoadQueryFont (dpy, fontname);
464 if (!font) font = XLoadQueryFont (dpy, def_font);
466 if (fontname && fontname != def_font)
469 gcv.font = font->fid;
470 fg = gcv.foreground = get_pixel_resource("amiga.foreground",
473 bg = gcv.background = get_pixel_resource("amiga.background",
476 bg2 = get_pixel_resource("amiga.background2", "Amiga.Background",
478 XSetWindowBackground(dpy, window, bg2);
479 XClearWindow(dpy, window);
481 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
482 gcv.background = fg; gcv.foreground = bg;
483 gc2 = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
485 height = (font->ascent + font->descent) * 6;
489 XpmAttributes xpmattrs;
491 xpmattrs.valuemask = 0;
494 xpmattrs.valuemask |= XpmCloseness;
495 xpmattrs.closeness = 40000;
498 xpmattrs.valuemask |= XpmVisual;
499 xpmattrs.visual = xgwa.visual;
502 xpmattrs.valuemask |= XpmDepth;
503 xpmattrs.depth = xgwa.depth;
506 xpmattrs.valuemask |= XpmColormap;
507 xpmattrs.colormap = xgwa.colormap;
510 result = XpmCreatePixmapFromData(dpy, window, amiga_hand,
511 &pixmap, 0 /* mask */, &xpmattrs);
512 if (!pixmap || (result != XpmSuccess && result != XpmColorError))
514 pix_w = xpmattrs.width;
515 pix_h = xpmattrs.height;
517 #endif /* HAVE_XPM */
519 if (pixmap && xgwa.height > 600) /* scale up the bitmap */
521 pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
522 pixmap, pix_w, pix_h);
529 int x = (xgwa.width - pix_w) / 2;
530 int y = ((xgwa.height - pix_h) / 2);
531 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
536 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y + height);
537 XClearArea(dpy, window, 0, 0, xgwa.width, y + height, False);
538 XFreePixmap(dpy, pixmap);
541 XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
542 draw_string(dpy, window, gc, &gcv, font, 0, 0, xgwa.width, height, string,0);
548 XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, font->ascent);
549 XFillRectangle(dpy, window, gca, 0, 0, font->ascent, height);
550 XFillRectangle(dpy, window, gca, xgwa.width-font->ascent, 0,
551 font->ascent, height);
552 XFillRectangle(dpy, window, gca, 0, height-font->ascent, xgwa.width,
554 gca = (gca == gc ? gc2 : gc);
556 if (bsod_sleep(dpy, 1))
565 XClearWindow(dpy, window);
566 XFreeFont(dpy, font);
570 /* Atari ST, by Marcus Herbert <rhoenie@nobiscum.de>
571 Marcus had this to say:
573 Though I still have my Atari somewhere, I hardly remember
574 the meaning of the bombs. I think 9 bombs was "bus error" or
575 something like that. And you often had a few bombs displayed
576 quickly and then the next few ones coming up step by step.
577 Perhaps somebody else can tell you more about it.. its just
581 atari (Display *dpy, Window window, int delay)
585 XWindowAttributes xgwa;
586 const char *def_font = "fixed";
590 int pix_w = atari_width;
591 int pix_h = atari_height;
592 int offset = atari_width + 2;
595 XGetWindowAttributes (dpy, window, &xgwa);
597 font = XLoadQueryFont (dpy, def_font);
600 gcv.font = font->fid;
601 gcv.foreground = get_pixel_resource("atari.foreground", "Atari.Foreground",
603 gcv.background = get_pixel_resource("atari.background", "Atari.Background",
606 XSetWindowBackground(dpy, window, gcv.background);
607 XClearWindow(dpy, window);
609 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
611 pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) atari_bits,
612 atari_width, atari_height,
618 y = (xgwa.height - (xgwa.height / 5));
621 for (i=0 ; i<7 ; i++) {
622 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
623 (x + (i*offset)), y);
626 for (i=7 ; i<10 ; i++) {
628 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h,
629 (x + (i*offset)), y);
632 XFreePixmap(dpy, pixmap);
635 bsod_sleep(dpy, delay);
636 XClearWindow(dpy, window);
637 XFreeFont(dpy, font);
642 mac (Display *dpy, Window window, int delay)
645 XWindowAttributes xgwa;
647 const char *def_font = "fixed";
651 int pix_w = mac_width;
652 int pix_h = mac_height;
653 int offset = mac_height * 4;
656 const char *string = ("0 0 0 0 0 0 0 F\n"
659 XGetWindowAttributes (dpy, window, &xgwa);
661 fontname = get_string_resource ("mac.font", "Mac.Font");
662 if (!fontname || !*fontname) fontname = (char *)def_font;
663 font = XLoadQueryFont (dpy, fontname);
664 if (!font) font = XLoadQueryFont (dpy, def_font);
666 if (fontname && fontname != def_font)
669 gcv.font = font->fid;
670 gcv.foreground = get_pixel_resource("mac.foreground", "Mac.Foreground",
672 gcv.background = get_pixel_resource("mac.background", "Mac.Background",
674 XSetWindowBackground(dpy, window, gcv.background);
675 XClearWindow(dpy, window);
677 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
679 pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits,
680 mac_width, mac_height,
685 draw_string(dpy, window, gc, &gcv, font, 0, 0,
686 xgwa.width, xgwa.height + offset, string, 0);
688 for(i = 0; i < 2; i++)
690 pixmap = double_pixmap(dpy, gc, xgwa.visual, xgwa.depth,
691 pixmap, pix_w, pix_h);
692 pix_w *= 2; pix_h *= 2;
696 int x = (xgwa.width - pix_w) / 2;
697 int y = (((xgwa.height + offset) / 2) -
699 (font->ascent + font->descent) * 2);
701 XCopyArea(dpy, pixmap, window, gc, 0, 0, pix_w, pix_h, x, y);
702 XFreePixmap(dpy, pixmap);
707 bsod_sleep(dpy, delay);
708 XClearWindow(dpy, window);
709 XFreeFont(dpy, font);
713 macsbug (Display *dpy, Window window, int delay)
716 XWindowAttributes xgwa;
718 const char *def_font = "fixed";
722 int char_width, line_height;
723 int col_right, row_top, row_bottom, page_right, page_bottom, body_top;
726 const char *left = (" SP \n"
773 const char *bottom = (" _A09D\n"
774 " +00884 40843714 #$0700,SR "
776 " +00886 40843765 *+$0400 "
778 " +00888 40843718 $0004(A7),([0,A7[)"
779 " ; 04E8D0AE | 66B8");
782 const char *body = ("Bus Error at 4BF6D6CC\n"
783 "while reading word from 4BF6D6CC in User data space\n"
784 " Unable to access that address\n"
786 " Frame Type: B008");
788 const char * body = ("PowerPC unmapped memory exception at 003AFDAC "
789 "BowelsOfTheMemoryMgr+04F9C\n"
790 " Calling chain using A6/R1 links\n"
791 " Back chain ISA Caller\n"
792 " 00000000 PPC 28C5353C __start+00054\n"
793 " 24DB03C0 PPC 28B9258C main+0039C\n"
794 " 24DB0350 PPC 28B9210C MainEvent+00494\n"
795 " 24DB02B0 PPC 28B91B40 HandleEvent+00278\n"
796 " 24DB0250 PPC 28B83DAC DoAppleEvent+00020\n"
797 " 24DB0210 PPC FFD3E5D0 "
798 "AEProcessAppleEvent+00020\n"
799 " 24DB0132 68K 00589468\n"
800 " 24DAFF8C 68K 00589582\n"
801 " 24DAFF26 68K 00588F70\n"
802 " 24DAFEB3 PPC 00307098 "
803 "EmToNatEndMoveParams+00014\n"
804 " 24DAFE40 PPC 28B9D0B0 DoScript+001C4\n"
805 " 24DAFDD0 PPC 28B9C35C RunScript+00390\n"
806 " 24DAFC60 PPC 28BA36D4 run_perl+000E0\n"
807 " 24DAFC10 PPC 28BC2904 perl_run+002CC\n"
808 " 24DAFA80 PPC 28C18490 Perl_runops+00068\n"
809 " 24DAFA30 PPC 28BE6CC0 Perl_pp_backtick+000FC\n"
810 " 24DAF9D0 PPC 28BA48B8 Perl_my_popen+00158\n"
811 " 24DAF980 PPC 28C5395C sfclose+00378\n"
812 " 24DAF930 PPC 28BA568C free+0000C\n"
813 " 24DAF8F0 PPC 28BA6254 pool_free+001D0\n"
814 " 24DAF8A0 PPC FFD48F14 DisposePtr+00028\n"
815 " 24DAF7C9 PPC 00307098 "
816 "EmToNatEndMoveParams+00014\n"
817 " 24DAF780 PPC 003AA180 __DisposePtr+00010");
823 for (s = body; *s; s++) if (*s == '\n') body_lines++;
825 XGetWindowAttributes (dpy, window, &xgwa);
827 fontname = get_string_resource ((xgwa.height > 850
833 if (!fontname || !*fontname) fontname = (char *)def_font;
834 font = XLoadQueryFont (dpy, fontname);
835 if (!font) font = XLoadQueryFont (dpy, def_font);
837 if (fontname && fontname != def_font)
840 gcv.font = font->fid;
841 gcv.foreground = get_pixel_resource("macsbug.foreground",
842 "MacsBug.Foreground",
844 gcv.background = get_pixel_resource("macsbug.background",
845 "MacsBug.Background",
848 gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
850 gcv.foreground = gcv.background;
851 gc2 = XCreateGC(dpy, window, GCForeground, &gcv);
853 XSetWindowBackground(dpy, window,
854 get_pixel_resource("macsbug.borderColor",
855 "MacsBug.BorderColor",
856 dpy, xgwa.colormap));
857 XClearWindow(dpy, window);
859 char_width = (font->per_char
860 ? font->per_char['n'-font->min_char_or_byte2].width
861 : font->min_bounds.width);
862 line_height = font->ascent + font->descent + 1;
864 col_right = char_width * 12;
865 page_bottom = line_height * 47;
867 if (page_bottom > xgwa.height) page_bottom = xgwa.height;
869 row_bottom = page_bottom - line_height;
870 row_top = row_bottom - (line_height * 4);
871 page_right = col_right + (char_width * 88);
872 body_top = row_top - (line_height * body_lines);
878 xoff = (xgwa.width - page_right) / 2;
879 yoff = (xgwa.height - page_bottom) / 2;
880 if (xoff < 0) xoff = 0;
881 if (yoff < 0) yoff = 0;
883 XFillRectangle(dpy, window, gc2, xoff, yoff, page_right, page_bottom);
885 draw_string(dpy, window, gc, &gcv, font, xoff, yoff, 10, 10, left, 0);
886 draw_string(dpy, window, gc, &gcv, font, xoff+col_right, yoff+row_top,
889 XFillRectangle(dpy, window, gc, xoff + col_right, yoff, 2, page_bottom);
890 XDrawLine(dpy, window, gc,
891 xoff+col_right, yoff+row_top, xoff+page_right, yoff+row_top);
892 XDrawLine(dpy, window, gc,
893 xoff+col_right, yoff+row_bottom, xoff+page_right, yoff+row_bottom);
894 XDrawRectangle(dpy, window, gc, xoff, yoff, page_right, page_bottom);
899 draw_string(dpy, window, gc, &gcv, font,
900 xoff + col_right + char_width, yoff + body_top, 10, 10, body,
905 XDrawLine(dpy, window, gc,
906 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
907 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
910 XDrawLine(dpy, window, gc2,
911 xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
912 xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
915 if (bsod_sleep(dpy, 0))
922 XClearWindow(dpy, window);
923 XFreeFont(dpy, font);
928 char *progclass = "BSOD";
930 char *defaults [] = {
933 ".Windows.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
934 ".Windows.font2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
935 ".Windows.foreground: White",
936 ".Windows.background: Blue",
938 ".Amiga.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
939 ".Amiga.font2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
940 ".Amiga.foreground: Red",
941 ".Amiga.background: Black",
942 ".Amiga.background2: White",
944 ".Mac.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
945 ".Mac.foreground: PaleTurquoise1",
946 ".Mac.background: Black",
948 ".Atari.foreground: Black",
949 ".Atari.background: White",
951 ".MacsBug.font: -*-courier-medium-r-*-*-*-100-*-*-m-*-*-*",
952 ".MacsBug.font2: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
953 ".MacsBug.font3: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
954 ".MacsBug.foreground: Black",
955 ".MacsBug.background: White",
956 ".MacsBug.borderColor: #AAAAAA",
958 ".OpenServer.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
959 ".OpenServer.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
960 ".OpenServer.foreground: White",
961 ".OpenServer.background: Black",
963 ".SparcLinux.font: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
964 ".SparcLinux.font2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
965 ".SparcLinux.foreground: White",
966 ".SparcLinux.background: Black",
970 XrmOptionDescRec options [] = {
971 { "-delay", ".delay", XrmoptionSepArg, 0 },
976 screenhack (Display *dpy, Window window)
980 int delay = get_integer_resource ("delay", "Integer");
981 if (delay < 3) delay = 3;
983 if (!get_boolean_resource ("root", "Boolean"))
984 XSelectInput(dpy, window, KeyPressMask|ButtonPressMask);
988 while (i == j) i = random() % 8;
993 case 0: windows(dpy, window, delay, True); break;
994 case 1: windows(dpy, window, delay, False); break;
995 case 2: amiga(dpy, window, delay); break;
996 case 3: mac(dpy, window, delay); break;
997 case 4: macsbug(dpy, window, delay); break;
998 case 5: openserver(dpy, window, delay); break;
999 case 6: sparc_linux(dpy, window, delay); break;
1000 case 7: atari(dpy, window, delay); break;
1001 default: abort(); break;