http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / bsod.c
index a65684615ccdf12f69d8d4682fbefe5567a75fee..8178dd4656328398c9eeb7e5dcdb0f053bfcab51 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1998, 2000 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1998-2001 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  *   TODO:
  *      -  Should simulate a Unix kernel panic and reboot.
  *      -  Making various boot noises would be fun, too.
- *      -  Maybe scatter some random bits across the screen,
- *         to simulate corruption of video ram?
  *      -  Should randomize the various hex numbers printed.
  */
 
 #include "screenhack.h"
+#include "xpm-pixmap.h"
 #include <stdio.h>
 #include <X11/Xutil.h>
 
-#ifdef HAVE_XPM
-# include <X11/xpm.h>
-# include "images/amiga.xpm"
-#endif
 
+#include "images/amiga.xpm"
 #include "images/atari.xbm"
 #include "images/mac.xbm"
 
 
-static void
+static int
 draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
             XFontStruct *font,
             int xoff, int yoff,
@@ -119,6 +115,8 @@ draw_string (Display *dpy, Window window, GC gc, XGCValues *gcv,
        }
       s++;
     }
+
+  return width * char_width;
 }
 
 
@@ -609,7 +607,7 @@ bsd (Display *dpy, Window window, int delay)
 
   for (bp = syncing; *bp;)
     {
-      char *bsd_bufs, oc;
+      char *bsd_bufs, oc = 0;
       for (;*bp && (*bp != ' '); bp++)
         ;
       if (*bp == ' ')
@@ -667,6 +665,8 @@ amiga (Display *dpy, Window window, int delay)
   unsigned long fg, bg, bg2;
   Pixmap pixmap = 0;
   int pix_w = 0, pix_h = 0;
+  int string_width;
+  int margin;
 
   const char *string =
     ("_Software failure.  Press left mouse button to continue.\n"
@@ -705,37 +705,10 @@ amiga (Display *dpy, Window window, int delay)
 
   height = (font->ascent + font->descent) * 6;
 
-#ifdef HAVE_XPM
-  {
-    XpmAttributes xpmattrs;
-    int result;
-    xpmattrs.valuemask = 0;
-
-# ifdef XpmCloseness
-    xpmattrs.valuemask |= XpmCloseness;
-    xpmattrs.closeness = 40000;
-# endif
-# ifdef XpmVisual
-    xpmattrs.valuemask |= XpmVisual;
-    xpmattrs.visual = xgwa.visual;
-# endif
-# ifdef XpmDepth
-    xpmattrs.valuemask |= XpmDepth;
-    xpmattrs.depth = xgwa.depth;
-# endif
-# ifdef XpmColormap
-    xpmattrs.valuemask |= XpmColormap;
-    xpmattrs.colormap = xgwa.colormap;
-# endif
-
-    result = XpmCreatePixmapFromData(dpy, window, amiga_hand,
-                                    &pixmap, 0 /* mask */, &xpmattrs);
-    if (!pixmap || (result != XpmSuccess && result != XpmColorError))
-      pixmap = 0;
-    pix_w = xpmattrs.width;
-    pix_h = xpmattrs.height;
-  }
-#endif /* HAVE_XPM */
+#if defined(HAVE_GDK_PIXBUF) || defined (HAVE_XPM)
+  pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand,
+                               &pix_w, &pix_h, 0);
+#endif /* HAVE_GDK_PIXBUF || HAVE_XPM */
 
   if (pixmap && xgwa.height > 600)     /* scale up the bitmap */
     {
@@ -760,18 +733,24 @@ amiga (Display *dpy, Window window, int delay)
     }
 
   XFillRectangle(dpy, window, gc2, 0, 0, xgwa.width, height);
-  draw_string(dpy, window, gc, &gcv, font, 0, 0, xgwa.width, height, string,0);
-
+  margin = font->ascent;
+  string_width = draw_string(dpy, window, gc, &gcv, font,
+                             margin, 0,
+                             xgwa.width - (margin * 2), height,
+                             string, 0);
   {
     GC gca = gc;
     while (delay > 0)
       {
-       XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, font->ascent);
-       XFillRectangle(dpy, window, gca, 0, 0, font->ascent, height);
-       XFillRectangle(dpy, window, gca, xgwa.width-font->ascent, 0,
-                      font->ascent, height);
-       XFillRectangle(dpy, window, gca, 0, height-font->ascent, xgwa.width,
-                      font->ascent);
+        int x2;
+       XFillRectangle(dpy, window, gca, 0, 0, xgwa.width, margin);
+       XFillRectangle(dpy, window, gca, 0, 0, margin, height);
+        XFillRectangle(dpy, window, gca,
+                       0, height - margin, xgwa.width, margin);
+        x2 = margin + string_width;
+        if (x2 < xgwa.width - margin) x2 = xgwa.width - margin;
+        XFillRectangle(dpy, window, gca, x2, 0, margin, height);
+
        gca = (gca == gc ? gc2 : gc);
        XSync(dpy, False);
        if (bsod_sleep(dpy, 1))
@@ -1242,6 +1221,264 @@ blitdamage (Display *dpy, Window window, int delay)
   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;
+}
 
 \f
 char *progclass = "BSOD";
@@ -1259,6 +1496,7 @@ char *defaults [] = {
   "*doBSD:                False",      /* boring */
   "*doSparcLinux:         False",      /* boring */
   "*doBlitDamage:          True",
+  "*doSolaris:             True",
 
   ".Windows.font:         -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
   ".Windows.font2:        -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
@@ -1284,12 +1522,12 @@ char *defaults [] = {
   ".MacsBug.foreground:           Black",
   ".MacsBug.background:           White",
   ".MacsBug.borderColor:   #AAAAAA",
-  
+
   ".SCO.font:             -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
   ".SCO.font2:            -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
   ".SCO.foreground:       White",
   ".SCO.background:       Black",
-  
+
   ".SparcLinux.font:      -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
   ".SparcLinux.font2:     -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
   ".SparcLinux.foreground: White",
@@ -1301,11 +1539,37 @@ char *defaults [] = {
 /* ".BSD.font2:                    -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", */
   ".BSD.foreground:        #c0c0c0",
   ".BSD.background:        Black",
+
+  ".Solaris.font:           -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*",
+  ".Solaris.font2:          -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+  "*dontClearRoot:          True",
   0
 };
 
 XrmOptionDescRec options [] = {
   { "-delay",          ".delay",               XrmoptionSepArg, 0 },
+  { "-windows",                ".doWindows",           XrmoptionNoArg,  "True"  },
+  { "-no-windows",     ".doWindows",           XrmoptionNoArg,  "False" },
+  { "-nt",             ".doNT",                XrmoptionNoArg,  "True"  },
+  { "-no-nt",          ".doNT",                XrmoptionNoArg,  "False" },
+  { "-amiga",          ".doAmiga",             XrmoptionNoArg,  "True"  },
+  { "-no-amiga",       ".doAmiga",             XrmoptionNoArg,  "False" },
+  { "-mac",            ".doMac",               XrmoptionNoArg,  "True"  },
+  { "-no-mac",         ".doMac",               XrmoptionNoArg,  "False" },
+  { "-atari",          ".doAtari",             XrmoptionNoArg,  "True"  },
+  { "-no-atari",       ".doAtari",             XrmoptionNoArg,  "False" },
+  { "-macsbug",                ".doMacsBug",           XrmoptionNoArg,  "True"  },
+  { "-no-macsbug",     ".doMacsBug",           XrmoptionNoArg,  "False" },
+  { "-sco",            ".doSCO",               XrmoptionNoArg,  "True"  },
+  { "-no-sco",         ".doSCO",               XrmoptionNoArg,  "False" },
+  { "-bsd",            ".doBSD",               XrmoptionNoArg,  "True"  },
+  { "-no-bsd",         ".doBSD",               XrmoptionNoArg,  "False" },
+  { "-sparclinux",     ".doSparcLinux",        XrmoptionNoArg,  "True"  },
+  { "-no-sparclinux",  ".doSparcLinux",        XrmoptionNoArg,  "False" },
+  { "-blitdamage",     ".doBlitDamage",        XrmoptionNoArg,  "True"  },
+  { "-no-blitdamage",  ".doBlitDamage",        XrmoptionNoArg,  "False" },
+  { "-solaris",                ".doSolaris",           XrmoptionNoArg,  "True"  },
+  { "-no-solaris",     ".doSolaris",           XrmoptionNoArg,  "False" },
   { 0, 0, 0, 0 }
 };
 
@@ -1330,7 +1594,7 @@ screenhack (Display *dpy, Window window)
   while (1)
     {
       Bool did;
-      do {  i = (random() & 0xFF) % 10; } while (i == j);
+      do {  i = (random() & 0xFF) % 11; } while (i == j);
       switch (i)
        {
        case 0: did = windows(dpy, window, delay, True); break;
@@ -1343,11 +1607,16 @@ screenhack (Display *dpy, Window window)
        case 7: did = bsd(dpy, window, delay); break;
        case 8: did = atari(dpy, window, delay); break;
        case 9: did = blitdamage(dpy, window, delay); break;
+       case 10: did = sparc_solaris(dpy, window, delay); break;
        default: abort(); break;
        }
       loop++;
       if (loop > 100) j = -1;
-      if (loop > 200) exit(-1);
+      if (loop > 200)
+        {
+          fprintf (stderr, "%s: no display modes enabled?\n", progname);
+          exit(-1);
+        }
       if (!did) continue;
       XSync (dpy, False);
       j = i;