+ return True;
+}
+
+static Bool
+macsbug (Display *dpy, Window window, int delay)
+{
+ XGCValues gcv;
+ XWindowAttributes xgwa;
+ char *fontname;
+ const char *def_font = "fixed";
+ XFontStruct *font;
+ GC gc, gc2;
+
+ int char_width, line_height;
+ int col_right, row_top, row_bottom, page_right, page_bottom, body_top;
+ int xoff, yoff;
+
+ const char *left = (" SP \n"
+ " 04EB0A58 \n"
+ "58 00010000\n"
+ "5C 00010000\n"
+ " ........\n"
+ "60 00000000\n"
+ "64 000004EB\n"
+ " ........\n"
+ "68 0000027F\n"
+ "6C 2D980035\n"
+ " ....-..5\n"
+ "70 00000054\n"
+ "74 0173003E\n"
+ " ...T.s.>\n"
+ "78 04EBDA76\n"
+ "7C 04EBDA8E\n"
+ " .S.L.a.U\n"
+ "80 00000000\n"
+ "84 000004EB\n"
+ " ........\n"
+ "88 00010000\n"
+ "8C 00010000\n"
+ " ...{3..S\n"
+ "\n"
+ "\n"
+ " CurApName \n"
+ " Finder \n"
+ "\n"
+ " 32-bit VM \n"
+ "SR Smxnzvc0\n"
+ "D0 04EC0062\n"
+ "D1 00000053\n"
+ "D2 FFFF0100\n"
+ "D3 00010000\n"
+ "D4 00010000\n"
+ "D5 04EBDA76\n"
+ "D6 04EBDA8E\n"
+ "D7 00000001\n"
+ "\n"
+ "A0 04EBDA76\n"
+ "A1 04EBDA8E\n"
+ "A2 A0A00060\n"
+ "A3 027F2D98\n"
+ "A4 027F2E58\n"
+ "A5 04EC04F0\n"
+ "A6 04EB0A86\n"
+ "A7 04EB0A58");
+ const char *bottom = (" _A09D\n"
+ " +00884 40843714 #$0700,SR "
+ " ; A973 | A973\n"
+ " +00886 40843765 *+$0400 "
+ " | 4A1F\n"
+ " +00888 40843718 $0004(A7),([0,A7[)"
+ " ; 04E8D0AE | 66B8");
+
+#if 0
+ const char *body = ("Bus Error at 4BF6D6CC\n"
+ "while reading word from 4BF6D6CC in User data space\n"
+ " Unable to access that address\n"
+ " PC: 2A0DE3E6\n"
+ " Frame Type: B008");
+#else
+ const char * body = ("PowerPC unmapped memory exception at 003AFDAC "
+ "BowelsOfTheMemoryMgr+04F9C\n"
+ " Calling chain using A6/R1 links\n"
+ " Back chain ISA Caller\n"
+ " 00000000 PPC 28C5353C __start+00054\n"
+ " 24DB03C0 PPC 28B9258C main+0039C\n"
+ " 24DB0350 PPC 28B9210C MainEvent+00494\n"
+ " 24DB02B0 PPC 28B91B40 HandleEvent+00278\n"
+ " 24DB0250 PPC 28B83DAC DoAppleEvent+00020\n"
+ " 24DB0210 PPC FFD3E5D0 "
+ "AEProcessAppleEvent+00020\n"
+ " 24DB0132 68K 00589468\n"
+ " 24DAFF8C 68K 00589582\n"
+ " 24DAFF26 68K 00588F70\n"
+ " 24DAFEB3 PPC 00307098 "
+ "EmToNatEndMoveParams+00014\n"
+ " 24DAFE40 PPC 28B9D0B0 DoScript+001C4\n"
+ " 24DAFDD0 PPC 28B9C35C RunScript+00390\n"
+ " 24DAFC60 PPC 28BA36D4 run_perl+000E0\n"
+ " 24DAFC10 PPC 28BC2904 perl_run+002CC\n"
+ " 24DAFA80 PPC 28C18490 Perl_runops+00068\n"
+ " 24DAFA30 PPC 28BE6CC0 Perl_pp_backtick+000FC\n"
+ " 24DAF9D0 PPC 28BA48B8 Perl_my_popen+00158\n"
+ " 24DAF980 PPC 28C5395C sfclose+00378\n"
+ " 24DAF930 PPC 28BA568C free+0000C\n"
+ " 24DAF8F0 PPC 28BA6254 pool_free+001D0\n"
+ " 24DAF8A0 PPC FFD48F14 DisposePtr+00028\n"
+ " 24DAF7C9 PPC 00307098 "
+ "EmToNatEndMoveParams+00014\n"
+ " 24DAF780 PPC 003AA180 __DisposePtr+00010");
+#endif
+
+ const char *s;
+ int body_lines = 1;
+
+ if (!get_boolean_resource("doMacsBug", "DoMacsBug"))
+ return False;
+
+ for (s = body; *s; s++) if (*s == '\n') body_lines++;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+
+ fontname = get_string_resource ((xgwa.height > 850
+ ? "macsbug.font3"
+ : (xgwa.height > 700
+ ? "macsbug.font2"
+ : "macsbug.font")),
+ "MacsBug.Font");
+ if (!fontname || !*fontname) fontname = (char *)def_font;
+ font = XLoadQueryFont (dpy, fontname);
+ if (!font) font = XLoadQueryFont (dpy, def_font);
+ if (!font) exit(-1);
+ if (fontname && fontname != def_font)
+ free (fontname);
+
+ gcv.font = font->fid;
+ gcv.foreground = get_pixel_resource("macsbug.foreground",
+ "MacsBug.Foreground",
+ dpy, xgwa.colormap);
+ gcv.background = get_pixel_resource("macsbug.background",
+ "MacsBug.Background",
+ dpy, xgwa.colormap);
+
+ gc = XCreateGC(dpy, window, GCFont|GCForeground|GCBackground, &gcv);
+
+ gcv.foreground = gcv.background;
+ gc2 = XCreateGC(dpy, window, GCForeground, &gcv);
+
+ XSetWindowBackground(dpy, window,
+ get_pixel_resource("macsbug.borderColor",
+ "MacsBug.BorderColor",
+ dpy, xgwa.colormap));
+ XClearWindow(dpy, window);
+
+ char_width = (font->per_char
+ ? font->per_char['n'-font->min_char_or_byte2].width
+ : font->min_bounds.width);
+ line_height = font->ascent + font->descent + 1;
+
+ col_right = char_width * 12;
+ page_bottom = line_height * 47;
+
+ if (page_bottom > xgwa.height) page_bottom = xgwa.height;
+
+ row_bottom = page_bottom - line_height;
+ row_top = row_bottom - (line_height * 4);
+ page_right = col_right + (char_width * 88);
+ body_top = row_top - (line_height * body_lines);
+
+ page_bottom += 2;
+ row_bottom += 2;
+ body_top -= 4;
+
+ xoff = (xgwa.width - page_right) / 2;
+ yoff = (xgwa.height - page_bottom) / 2;
+ if (xoff < 0) xoff = 0;
+ if (yoff < 0) yoff = 0;
+
+ XFillRectangle(dpy, window, gc2, xoff, yoff, page_right, page_bottom);
+
+ draw_string(dpy, window, gc, &gcv, font, xoff, yoff, 10, 10, left, 0);
+ draw_string(dpy, window, gc, &gcv, font, xoff+col_right, yoff+row_top,
+ 10, 10, bottom, 0);
+
+ XFillRectangle(dpy, window, gc, xoff + col_right, yoff, 2, page_bottom);
+ XDrawLine(dpy, window, gc,
+ xoff+col_right, yoff+row_top, xoff+page_right, yoff+row_top);
+ XDrawLine(dpy, window, gc,
+ xoff+col_right, yoff+row_bottom, xoff+page_right, yoff+row_bottom);
+ XDrawRectangle(dpy, window, gc, xoff, yoff, page_right, page_bottom);
+
+ if (body_top > 4)
+ body_top = 4;
+
+ draw_string(dpy, window, gc, &gcv, font,
+ xoff + col_right + char_width, yoff + body_top, 10, 10, body,
+ 500);
+
+ while (delay > 0)
+ {
+ XDrawLine(dpy, window, gc,
+ xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
+ xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
+ XSync(dpy, False);
+ usleep(666666L);
+ XDrawLine(dpy, window, gc2,
+ xoff+col_right+(char_width/2)+2, yoff+row_bottom+3,
+ xoff+col_right+(char_width/2)+2, yoff+page_bottom-3);
+ XSync(dpy, False);
+ usleep(333333L);
+ if (bsod_sleep(dpy, 0))
+ break;
+ delay--;
+ }
+
+ XFreeGC(dpy, gc);
+ XFreeGC(dpy, gc2);
+ XClearWindow(dpy, window);
+ XFreeFont(dpy, font);
+ return True;
+}
+
+\f
+/* blit damage
+ *
+ * by Martin Pool <mbp@samba.org>, Feb 2000.
+ *
+ * This is meant to look like the preferred failure mode of NCD
+ * Xterms. The parameters for choosing what to copy where might not
+ * be quite right, but it looks about ugly enough.
+ */
+static Bool
+blitdamage (Display *dpy, Window window, int delay)
+{
+ XGCValues gcv;
+ XWindowAttributes xwa;
+ GC gc0;
+ int i;
+ int delta_x = 0, delta_y = 0;
+ int w, h;
+ int chunk_h, chunk_w;
+ int steps;
+ long gc_mask = 0;
+ int src_x, src_y;
+ int x, y;
+
+ if (!get_boolean_resource("doBlitDamage", "DoBlitDamage"))
+ return False;
+
+ XGetWindowAttributes(dpy, window, &xwa);
+
+ grab_screen_image(xwa.screen, window);
+
+ w = xwa.width;
+ h = xwa.height;
+
+ gc_mask = GCForeground;
+
+ gcv.plane_mask = random();
+ gc_mask |= GCPlaneMask;
+
+ gc0 = XCreateGC(dpy, window, gc_mask, &gcv);
+
+ steps = 50;
+ chunk_w = w / (random() % 1 + 1);
+ chunk_h = h / (random() % 1 + 1);
+ if (random() & 0x1000)
+ delta_y = random() % 600;
+ if (!delta_y || (random() & 0x2000))
+ delta_x = random() % 600;
+ src_x = 0;
+ src_y = 0;
+ x = 0;
+ y = 0;
+
+ for (i = 0; i < steps; i++) {
+ if (x + chunk_w > w)
+ x -= w;
+ else
+ x += delta_x;
+
+ if (y + chunk_h > h)
+ y -= h;
+ else
+ y += delta_y;
+
+ XCopyArea(dpy, window, window, gc0,
+ src_x, src_y,
+ chunk_w, chunk_h,
+ x, y);
+
+ bsod_sleep(dpy, 0);
+ }
+
+ bsod_sleep(dpy, delay);
+
+ XFreeGC(dpy, gc0);
+
+ return True;
+}
+
+\f
+/*
+ * SPARC Solaris panic. Should look pretty authentic on Solaris boxes.
+ * Anton Solovyev <solovam@earthlink.net>
+ */
+
+static int solaris_max_scroll = 10;
+
+typedef struct
+{
+ Display *dpy;
+ Window window;
+ GC gc;
+ Pixmap subwindow; /* The text subwindow */
+ XFontStruct *xfs;
+ int width; /* Window width in pixels */
+ int height; /* Window height in pixels */
+ int sub_width; /* Text subwindow width in pixels */
+ int sub_height; /* Text subwindow height in pixels */
+ int sub_x; /* upper left corner of the text subwindow */
+ int sub_y; /* upper left corner of the text subwindow */
+ int char_width; /* Char width in pixels */
+ int line_height; /* Line height in pixels */
+ int columns; /* Number of columns in the text screen */
+ int lines; /* Number of lines in the text screen */
+ int x; /* position of the cursor */
+ int y; /* position of the cursor */
+} solaris_console;
+
+
+static solaris_console *
+make_solaris_console (Display *dpy, Window window)
+{
+ const char *def_font = "fixed";
+ solaris_console* ts;
+
+ XWindowAttributes xgwa;
+ XGCValues gcv;
+ char* fontname;
+
+ ts = malloc(sizeof(solaris_console));
+
+ ts->window = window;
+ ts->dpy = dpy;
+
+ ts->x = 0;
+ ts->y = 0;
+
+ XGetWindowAttributes (dpy, window, &xgwa);
+ ts->width = xgwa.width;
+ ts->height = xgwa.height;
+ ts->sub_width = ts->width * 0.8;
+ ts->sub_height = ts->height * 0.8;
+
+ fontname = get_string_resource ("solaris.font", "Solaris.Font");
+ ts->xfs = XLoadQueryFont (dpy, fontname);
+ if (!ts->xfs)
+ {
+ fontname = get_string_resource("solaris.font2", "Solaris.Font");
+ ts->xfs = XLoadQueryFont(dpy, fontname);
+ }
+ if (!ts->xfs)
+ ts->xfs = XLoadQueryFont(dpy, def_font);
+ if (!ts->xfs)
+ {
+ fprintf (stderr, "Can't load font\n");
+ XFreeFont (dpy, ts->xfs);
+ free (ts);
+ exit (1);
+ }
+ gcv.font = ts->xfs->fid;
+ ts->char_width = (ts->xfs->per_char
+ ? ts->xfs->per_char[ts->xfs->min_char_or_byte2 +
+ ts->xfs->default_char].width
+ : ts->xfs->max_bounds.width);
+ ts->line_height = ts->xfs->ascent + ts->xfs->descent + 1;
+
+ ts->columns = ts->sub_width / ts->char_width;
+ ts->lines = ts->sub_height / ts->line_height;
+
+ ts->sub_x = (ts->width - ts->sub_width) / 2;
+ ts->sub_y = (ts->height - ts->sub_height) / 2;
+
+ ts->subwindow = XCreatePixmap (dpy, window, ts->sub_width,
+ ts->sub_height * (solaris_max_scroll + 1),
+ xgwa.depth);
+ grab_screen_image (xgwa.screen, window);
+ gcv.function = GXcopy;
+ gcv.background = XBlackPixel (dpy, XDefaultScreen(dpy));
+ gcv.foreground = XWhitePixel (dpy, XDefaultScreen(dpy));
+ ts->gc = XCreateGC (dpy, window,
+ GCFunction | GCBackground | GCForeground | GCFont,
+ &gcv);
+ XCopyArea (dpy, window, ts->subwindow, ts->gc,
+ ts->sub_x, ts->sub_y, ts->sub_width, ts->sub_height,
+ 0, 0);
+ XFillRectangle (dpy, ts->subwindow, ts->gc, 0, ts->sub_height,
+ ts->sub_width, ts->sub_height * solaris_max_scroll);
+
+ gcv.background = XWhitePixel (dpy, XDefaultScreen (dpy));
+ gcv.foreground = XBlackPixel (dpy, XDefaultScreen (dpy));
+ XChangeGC (dpy, ts->gc, GCBackground | GCForeground, &gcv);
+
+ return(ts);
+}
+
+static void
+free_solaris_console (solaris_console* ts)
+{
+ XFreePixmap (ts->dpy, ts->subwindow);
+ XFreeGC (ts->dpy, ts->gc);
+ XFreeFont (ts->dpy, ts->xfs);
+ free (ts);
+}
+
+static void
+solaris_draw (solaris_console* ts)
+{
+ XCopyArea (ts->dpy, ts->subwindow, ts->window, ts->gc, 0,
+ (ts->y + 1) * ts->line_height, ts->sub_width,
+ ts->sub_height, ts->sub_x, ts->sub_y);
+}
+
+static void
+solaris_putc (solaris_console* ts, const char aChar)
+{
+ if (ts->y >= solaris_max_scroll * ts->lines)
+ return;
+
+ if (!ts->y && !ts->x)
+ solaris_draw (ts);
+
+ switch (aChar)
+ {
+ case '\n':
+ ts->y++;
+ ts->x = 0;
+ solaris_draw (ts);
+ break;
+ case '\b':
+ if(ts->x > 0)
+ ts->x--;
+ break;
+ default:
+ XDrawImageString (ts->dpy, ts->subwindow, ts->gc,
+ (ts->x * ts->char_width -
+ ts->xfs->min_bounds.lbearing),
+ (ts->sub_height + (ts->y + 1) *
+ ts->line_height - ts->xfs->descent),
+ &aChar, 1);
+ XCopyArea (ts->dpy, ts->subwindow, ts->window, ts->gc,
+ ts->x * ts->char_width,
+ ts->y * ts->line_height + ts->sub_height,
+ ts->xfs->max_bounds.rbearing - ts->xfs->min_bounds.lbearing,
+ ts->line_height, ts->sub_x + ts->x * ts->char_width,
+ ts->sub_y + ts->sub_height - ts->line_height);
+ ts->x++;
+ if (ts->x >= ts->columns)
+ {
+ ts->x = 0;
+ solaris_putc(ts, '\n');
+ }
+ break;
+ }
+}
+
+static void
+solaris_puts (solaris_console* ts, const char* aString, int delay)
+{
+ const char *c;
+ for (c = aString; *c; ++c)
+ {
+ solaris_putc (ts, *c);
+ if (delay)
+ {
+ XSync(ts->dpy, 0);
+ usleep(delay);
+ }
+ }
+ XSync (ts->dpy, 0);
+}
+
+static Bool
+sparc_solaris (Display* dpy, Window window, int delay)
+{
+ const char *msg1 =
+ "BAD TRAP: cpu=0 type=0x31 rp=0x2a10043b5e0 addr=0xf3880 mmu_fsr=0x0\n"
+ "BAD TRAP occured in module \"unix\" due to an illegal access to a"
+ " user address.\n"
+ "adb: trap type = 0x31\n"
+ "addr=0xf3880\n"
+ "pid=307, pc=0x100306e4, sp=0x2a10043ae81, tstate=0x4480001602,"
+ " context=0x87f\n"
+ "g1-g7: 1045b000, 32f, 10079440, 180, 300000ebde8, 0, 30000953a20\n"
+ "Begin traceback... sp = 2a10043ae81\n"
+ "Called from 100bd060, fp=2a10043af31, args=f3700 300008cc988 f3880 0"
+ " 1 300000ebde0.\n"
+ "Called from 101fe1bc, fp=2a10043b011, args=3000045a240 104465a0"
+ " 300008e47d0 300008e48fa 300008ae350 300008ae410\n"
+ "Called from 1007c520, fp=2a10043b0c1, args=300008e4878 300003596e8 0"
+ " 3000045a320 0 3000045a220\n"
+ "Called from 1007c498, fp=2a10043b171, args=1045a000 300007847f0 20"
+ " 3000045a240 1 0\n"
+ "Called from 1007972c, fp=2a10043b221, args=1 300009517c0 30000951e58 1"
+ " 300007847f0 0\n"
+ "Called from 10031e10, fp=2a10043b2d1, args=3000095b0c8 0 300009396a8"
+ " 30000953a20 0 1\n"
+ "Called from 10000bdd8, fp=ffffffff7ffff1c1, args=0 57 100131480"
+ " 100131480 10012a6e0 0\n"
+ "End traceback...\n"
+ "panic[cpu0]/thread=30000953a20: trap\n"
+ "syncing file systems...";
+ const char *msg2 =
+ " 1 done\n"
+ "dumping to /dev/dsk/c0t0d0s3, offset 26935296\n";
+ const char *msg3 =
+ ": 2803 pages dumped, compression ratio 2.88, dump succeeded\n";
+ const char *msg4 =
+ "rebooting...\n"
+ "Resetting ...";
+
+ solaris_console* ts;
+ int i;
+ char buf[256];
+
+ if (!get_boolean_resource("doSolaris", "DoSolaris"))
+ return False;
+
+ ts = make_solaris_console (dpy, window);
+
+ solaris_puts (ts, msg1, 0);
+ bsod_sleep (dpy, 3);
+
+ solaris_puts (ts, msg2, 0);
+ bsod_sleep (dpy, 2);
+
+ for (i = 1; i <= 100; ++i)
+ {
+ sprintf(buf, "\b\b\b\b\b\b\b\b\b\b\b%3d%% done", i);
+ solaris_puts(ts, buf, 0);
+ usleep(100000);
+ }
+
+ solaris_puts (ts, msg3, 0);
+ bsod_sleep (dpy, 2);
+
+ solaris_puts (ts, msg4, 0);
+ bsod_sleep(dpy, 3);
+
+ XFillRectangle (ts->dpy, ts->window, ts->gc, 0, 0,
+ ts->width, ts->height);
+
+ bsod_sleep (dpy, 3);
+
+ free_solaris_console (ts);
+
+ return True;