X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fbsod.c;h=46225e5dd13cb975c21d56ef057f739f39604f3a;hp=553eb5e0cfa7eabfbe695303e4d93f6f1b566b2a;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hpb=39809ded547bdbb08207d3e514950425215b4410 diff --git a/hacks/bsod.c b/hacks/bsod.c index 553eb5e0..46225e5d 100644 --- a/hacks/bsod.c +++ b/hacks/bsod.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1998-2017 Jamie Zawinski +/* xscreensaver, Copyright (c) 1998-2018 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -36,7 +36,7 @@ #include "screenhack.h" -#include "xpm-pixmap.h" +#include "ximage-loader.h" #include "apple2.h" #include @@ -50,23 +50,17 @@ # include #endif /* HAVE_UNAME */ -#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) || defined(HAVE_JWXYZ) -# define DO_XPM -#endif - -#ifdef DO_XPM -# include "images/amiga.xpm" -# include "images/hmac.xpm" -# include "images/osx_10_2.xpm" -# include "images/osx_10_3.xpm" -# include "images/android.xpm" -# include "images/ransomware.xpm" -#endif -#include "images/atari.xbm" -#include "images/mac.xbm" -#include "images/macbomb.xbm" -#include "images/apple.xbm" -#include "images/atm.xbm" +#include "images/gen/amiga_png.h" +#include "images/gen/hmac_png.h" +#include "images/gen/osx_10_2_png.h" +#include "images/gen/osx_10_3_png.h" +#include "images/gen/android_png.h" +#include "images/gen/ransomware_png.h" +#include "images/gen/atari_png.h" +#include "images/gen/mac_png.h" +#include "images/gen/macbomb_png.h" +#include "images/gen/apple_png.h" +#include "images/gen/atm_png.h" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -83,7 +77,8 @@ typedef enum { EOF=0, COLOR, INVERT, MOVETO, MARGINS, CURSOR_BLOCK, CURSOR_LINE, RECT, LINE, COPY, PIXMAP, IMG, FONT, PAUSE, CHAR_DELAY, LINE_DELAY, - LOOP, RESET, VERT_MARGINS, CROP + LOOP, RESET, VERT_MARGINS, CROP, + WRAP, WORD_WRAP, TRUNCATE } bsod_event_type; struct bsod_event { @@ -101,14 +96,16 @@ struct bsod_state { int left_margin, right_margin; /* for text wrapping */ int top_margin, bottom_margin; /* for text scrolling and cropping */ int xoff, yoff; - Bool wrap_p; + Bool wrap_p, word_wrap_p; + char word_buf[80]; Bool scroll_p; Bool crop_p; /* If True, chops off extra text vertically */ - Pixmap pixmap; /* Source image used by BSOD_PIXMAP */ + Pixmap pixmap, mask; /* Source image used by BSOD_PIXMAP */ int x, y; /* current text-drawing position */ int current_left; /* don't use this */ + int last_nonwhite; int pos; /* position in queue */ int queue_size; @@ -326,6 +323,23 @@ struct bsod_state { (bst)->pos++; \ } while (0) +#define BSOD_WRAP(bst) do { \ + ensure_queue (bst); \ + (bst)->queue[(bst)->pos].type = WRAP; \ + (bst)->pos++; \ + } while (0) + +#define BSOD_WORD_WRAP(bst) do { \ + ensure_queue (bst); \ + (bst)->queue[(bst)->pos].type = WORD_WRAP; \ + (bst)->pos++; \ + } while (0) + +#define BSOD_TRUNCATE(bst) do { \ + ensure_queue (bst); \ + (bst)->queue[(bst)->pos].type = TRUNCATE; \ + (bst)->pos++; \ + } while (0) static void @@ -438,6 +452,7 @@ draw_char (struct bsod_state *bst, char c) else if (c == '\r') { bst->x = bst->current_left; + bst->last_nonwhite = bst->x; } else if (c == '\n') { @@ -468,13 +483,60 @@ draw_char (struct bsod_state *bst, char c) XCharStruct ov; XTextExtents (bst->font, &c, 1, &dir, &ascent, &descent, &ov); - if (bst->wrap_p && + if ((bst->wrap_p || bst->word_wrap_p) && bst->x + ov.width > bst->xgwa.width - bst->right_margin - bst->xoff) - bst_crlf (bst); + { + XCharStruct ov2; + int L = 0; + + if (bst->word_wrap_p && *bst->word_buf) + { + L = strlen(bst->word_buf); + XTextExtents (bst->font, bst->word_buf, L, + &dir, &ascent, &descent, &ov2); + } + + if (L) /* Erase the truncated wrapped word */ + { + XSetForeground (bst->dpy, bst->gc, bst->bg); + XFillRectangle (bst->dpy, bst->window, bst->gc, + bst->last_nonwhite, + bst->y - bst->font->ascent, + ov2.width, + bst->font->ascent + bst->font->descent); + XSetForeground (bst->dpy, bst->gc, bst->fg); + } + + bst_crlf (bst); + + if (L) /* Draw wrapped partial word on the next line, no delay */ + { + XDrawImageString (bst->dpy, bst->window, bst->gc, + bst->x, bst->y, bst->word_buf, L); + bst->x += ov2.width; + bst->last_nonwhite = bst->x; + } + } XDrawImageString (bst->dpy, bst->window, bst->gc, bst->x, bst->y, &c, 1); bst->x += ov.width; + + if (bst->word_wrap_p) + { + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') + { + bst->word_buf[0] = 0; + bst->last_nonwhite = bst->x; + } + else + { + int L = strlen (bst->word_buf); + if (L >= sizeof(bst->word_buf)-1) abort(); + bst->word_buf[L] = c; + bst->word_buf[L+1] = 0; + } + } } } @@ -502,6 +564,11 @@ bsod_pop (struct bsod_state *bst) if (! *s) { long delay = bst->line_delay; + /* Reset the string back to the beginning, in case we loop. */ + bst->queue[bst->pos].arg2 = bst->queue[bst->pos].arg1; + bst->queue[bst->pos].arg3 = 0; + bst->queue[bst->pos].type = (bsod_event_type) + bst->queue[bst->pos].arg4; bst->pos++; bst->current_left = bst->left_margin + bst->xoff; return delay; @@ -512,6 +579,8 @@ bsod_pop (struct bsod_state *bst) position_for_text (bst, s); bst->queue[bst->pos].arg4 = (void *) bst->queue[bst->pos].type; bst->queue[bst->pos].type = LEFT; + bst->word_buf[0] = 0; + bst->last_nonwhite = bst->x; if (type == CENTER_FULL || type == LEFT_FULL || @@ -559,6 +628,8 @@ bsod_pop (struct bsod_state *bst) { bst->x = (long) bst->queue[bst->pos].arg1; bst->y = (long) bst->queue[bst->pos].arg2; + bst->word_buf[0] = 0; + bst->last_nonwhite = bst->x; bst->pos++; return 0; } @@ -599,10 +670,17 @@ bsod_pop (struct bsod_state *bst) int h = (long) bst->queue[bst->pos].arg4; int tox = (long) bst->queue[bst->pos].arg5; int toy = (long) bst->queue[bst->pos].arg6; + if (type == PIXMAP && bst->mask) + { + XSetClipMask (bst->dpy, bst->gc, bst->mask); + XSetClipOrigin (bst->dpy, bst->gc, tox, toy); + } XCopyArea (bst->dpy, (type == PIXMAP ? bst->pixmap : bst->window), bst->window, bst->gc, srcx, srcy, w, h, tox, toy); + if (type == PIXMAP && bst->mask) + XSetClipMask (bst->dpy, bst->gc, None); bst->pos++; return 0; } @@ -690,6 +768,24 @@ bsod_pop (struct bsod_state *bst) return delay; } + case WRAP: + bst->wrap_p = 1; + bst->word_wrap_p = 0; + bst->pos++; + return 0; + + case WORD_WRAP: + bst->wrap_p = 0; + bst->word_wrap_p = 1; + bst->pos++; + return 0; + + case TRUNCATE: + bst->wrap_p = 0; + bst->word_wrap_p = 0; + bst->pos++; + return 0; + case LOOP: { long off = (long) bst->queue[bst->pos].arg1; @@ -740,10 +836,9 @@ make_bsod_state (Display *dpy, Window window, XGCValues gcv; struct bsod_state *bst; char buf1[1024], buf2[1024]; - char buf3[1024], buf4[1024]; char buf5[1024], buf6[1024]; char buf7[1024], buf8[1024]; - const char *font1, *font2, *font3, *font4; + const char *font1, *font3, *font4; bst = (struct bsod_state *) calloc (1, sizeof (*bst)); bst->queue_size = 10; @@ -753,12 +848,7 @@ make_bsod_state (Display *dpy, Window window, bst->window = window; XGetWindowAttributes (dpy, window, &bst->xgwa); - /* If the window is small: - use ".font" if it is loadable, else use ".font2". - - If the window is big: - use ".bigFont" if it is loadable, else use ".bigFont2". - */ + /* If the window is small, use ".font"; if big, ".bigFont". */ if ( # ifdef HAVE_MOBILE 1 @@ -769,15 +859,11 @@ make_bsod_state (Display *dpy, Window window, { sprintf (buf1, "%.100s.font", name); sprintf (buf2, "%.100s.font", class); - sprintf (buf3, "%.100s.font2", name); - sprintf (buf4, "%.100s.font2", class); } else { sprintf (buf1, "%.100s.bigFont", name); sprintf (buf2, "%.100s.bigFont", class); - sprintf (buf3, "%.100s.bigFont2", name); - sprintf (buf4, "%.100s.bigFont2", class); } sprintf (buf5, "%.100s.fontB", name); sprintf (buf6, "%.100s.fontB", class); @@ -785,11 +871,10 @@ make_bsod_state (Display *dpy, Window window, sprintf (buf8, "%.100s.fontC", class); font1 = get_string_resource (dpy, buf1, buf2); - font2 = get_string_resource (dpy, buf3, buf4); font3 = get_string_resource (dpy, buf5, buf6); font4 = get_string_resource (dpy, buf7, buf8); - /* If there was no ".mode.font2" resource also look for ".font2". + /* If there was no ".mode.font" resource also look for ".font". Under real X11, the wildcard does this, so this is redundant, but jwxyz needs it because it doesn't implement wildcards. */ @@ -800,29 +885,20 @@ make_bsod_state (Display *dpy, Window window, strchr (BUF2, '.') + 1); \ }} while(0) RES2 (font1, buf1, buf2); - RES2 (font2, buf3, buf4); RES2 (font3, buf5, buf6); RES2 (font4, buf7, buf8); #undef RES2 - if (font1) - bst->font = XLoadQueryFont (dpy, font1); - if (! bst->font && font2) - bst->font = XLoadQueryFont (dpy, font2); - - /* If neither of those worked, try some defaults. */ + if (font1 && *font1) + bst->font = load_font_retry (dpy, font1); - if (! bst->font) - bst->font = XLoadQueryFont (dpy,"-*-courier-bold-r-*-*-*-120-*-*-m-*-*-*"); - if (! bst->font) - bst->font = XLoadQueryFont (dpy, "fixed"); if (! bst->font) abort(); - if (font3) - bst->fontB = XLoadQueryFont (dpy, font3); - if (font4) - bst->fontC = XLoadQueryFont (dpy, font4); + if (font3 && *font3) + bst->fontB = load_font_retry (dpy, font3); + if (font4 && *font4) + bst->fontC = load_font_retry (dpy, font4); if (! bst->fontB) bst->fontB = bst->font; if (! bst->fontC) bst->fontC = bst->font; @@ -876,6 +952,8 @@ free_bsod_state (struct bsod_state *bst) bst->free_cb (bst); if (bst->pixmap) XFreePixmap(bst->dpy, bst->pixmap); + if (bst->mask) + XFreePixmap(bst->dpy, bst->mask); XFreeFont (bst->dpy, bst->font); XFreeGC (bst->dpy, bst->gc); @@ -897,14 +975,18 @@ free_bsod_state (struct bsod_state *bst) static Pixmap -double_pixmap (Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap, +double_pixmap (Display *dpy, Visual *visual, int depth, Pixmap pixmap, int pix_w, int pix_h) { int x, y; Pixmap p2 = XCreatePixmap(dpy, pixmap, pix_w*2, pix_h*2, depth); - XImage *i1 = XGetImage(dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, ZPixmap); - XImage *i2 = XCreateImage(dpy, visual, depth, ZPixmap, 0, 0, - pix_w*2, pix_h*2, 8, 0); + XImage *i1 = XGetImage (dpy, pixmap, 0, 0, pix_w, pix_h, ~0L, + (depth == 1 ? XYPixmap : ZPixmap)); + XImage *i2 = XCreateImage (dpy, visual, depth, + (depth == 1 ? XYPixmap : ZPixmap), 0, 0, + pix_w*2, pix_h*2, 8, 0); + XGCValues gcv; + GC gc = XCreateGC (dpy, p2, 0, &gcv); i2->data = (char *) calloc(i2->height, i2->bytes_per_line); for (y = 0; y < pix_h; y++) for (x = 0; x < pix_w; x++) @@ -918,6 +1000,7 @@ double_pixmap (Display *dpy, GC gc, Visual *visual, int depth, Pixmap pixmap, free(i1->data); i1->data = 0; XDestroyImage(i1); XPutImage(dpy, p2, gc, i2, 0, 0, 0, 0, i2->width, i2->height); + XFreeGC (dpy, gc); free(i2->data); i2->data = 0; XDestroyImage(i2); XFreePixmap(dpy, pixmap); @@ -1331,13 +1414,17 @@ windows_10 (Display *dpy, Window window) pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) qr_bits, qr_width, qr_height, bst->fg, bst->bg, bst->xgwa.depth); - for (i = 0; i < 2; i++) - { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, - pixmap, qr_width, qr_height); - qr_width *= 2; - qr_height *= 2; - } + { + int n = 2; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, + pixmap, qr_width, qr_height); + qr_width *= 2; + qr_height *= 2; + } + } bst->pixmap = pixmap; y = top; @@ -1411,9 +1498,11 @@ windows_ransomware (Display *dpy, Window window) char buf[1024]; int pix_w = 0, pix_h = 0; - Pixmap pixmap = xpm_data_to_pixmap (dpy, window, - (char **) (ransomware_xpm), - &pix_w, &pix_h, 0); + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + ransomware_png, sizeof(ransomware_png), + &pix_w, &pix_h, &mask); + int i, n = 0; /* Don't start the countdown from the start, advance the deadline by 3 - 30 hours */ @@ -1424,14 +1513,17 @@ windows_ransomware (Display *dpy, Window window) const time_t stage2_deadline = now + 604800 - advance_deadline; /* 7 days */ char stage1_deadline_str[25], stage2_deadline_str[25]; char countdown_str[16]; - int stage1_countdown_y, stage2_countdown_y; int countdown_d, countdown_h, countdown_m, countdown_s, countdown_r; - const int line_height = bst->font->ascent + bst->font->descent; - int i; + int line_height = bst->font->ascent + bst->font->descent; + int line_height1 = bst->fontA->ascent + bst->fontA->descent; const char *currencies[] = { "Blitcoin", + "Bitcorn", + "Buttcorn", "clicks", + "clicks", + "Ass Pennies", "Ass Pennies", "Dollary-doos", "Dunning-Krugerrands", @@ -1439,6 +1531,7 @@ windows_ransomware (Display *dpy, Window window) "Dunning-Krugerrands", "Dunning-Krugerrands", "Dunning-Krugerrands", + "Dunning-Krugerrands", "gift certificates", "secret sauce", "Tribbles", @@ -1505,81 +1598,6 @@ windows_ransomware (Display *dpy, Window window) const char *screensaver_quip = screensaver_quips[random() % countof(screensaver_quips)]; - /* Positions of UI elements. Layout: - - +---------+-+---------------------------------------+ - | LOGO | | HEADER | - | | |---------------------------------------| - | | | NOTE TEXT | - | DEAD | | | - | LINE | | | - | TIMERS | | | - | | | | - | | | | - | | | | - | | | | - | | | | - +---------+ | | - | LINKS | +---------------------------------------+ - | LINKS | | FOOTER | - +---------+-+---------------------------------------+ - - The right side of the UI maximises to available width. - The note text maximises to available height. - The logo, header and timers are anchored to the top left of the window. - The links and footer are anchored to the bottom left of the window. - The entire window is a fixed 4:3 scale, with a minimum margin around it. - */ - - /* Minimum margin around the window */ - int margin_size = 50; - - /* Right side of window (header, ransom note, BTC address, buttons) */ - const int right_pane_x = 270; - /* "oops" header */ - const int header_y = 5; - /* Ransom note */ - const int ransom_y = 40; - /* Footer area */ - const int footer_height = 100; - - /* Left pane (deadlines, countdown, links) */ - const int left_pane_width = right_pane_x - 5; - /* Logo (shown at top left corner) */ - int logo_x = (left_pane_width - pix_w) / 2; - int logo_y = 10; - /* Deadline position */ - const int deadline_y = 130; - /* Links height */ - const int links_height = 100; - const int links_x = 20; - - /* main window text */ - unsigned long fg = bst->fg; - unsigned long bg = bst->bg; - /* ransom note */ - unsigned long fg2 = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.foreground2", - "Ransomware.Foreground"); - unsigned long bg2 = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.background2", - "Ransomware.Background"); - /* buttons */ - unsigned long fg3 = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.foreground3", - "Ransomware.Foreground"); - unsigned long bg3 = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.background3", - "Ransomware.Background"); - /* links */ - unsigned long link = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.link", - "Ransomware.Foreground"); - /* headers */ - unsigned long theader = get_pixel_resource (dpy, bst->xgwa.colormap, - "ransomware.timerheader", - "Ransomware.Foreground"); - const char *lines[] = { "*What Happened To My Computer?\n", "Your important pixels are paintcrypted. All of your documents, photos, ", @@ -1623,63 +1641,141 @@ windows_ransomware (Display *dpy, Window window) "*GREETZ TO CRASH OVERRIDE AND ALSO JOEY\n", }; - /* Make a 4:3 ratio box inside of the workspace */ - int box_width = bst->xgwa.width - (margin_size * 2); - int box_height = bst->xgwa.height - bst->yoff - (margin_size * 2); - int box_x = margin_size; - int box_y = margin_size; - if ((bst->xgwa.width / 4) * 3 > bst->xgwa.height) { - /* Widescreen, make narrow bits */ - box_width = (bst->xgwa.height * 4 / 3) - (margin_size * 2); - box_x = (bst->xgwa.width - box_width) / 2; - } else { - /* Narrowscreen, make wide bits */ - box_height = (bst->xgwa.width * 3 / 4) - (margin_size * 2); - box_y = (bst->xgwa.height - bst->yoff - box_height) / 2; - } + /* Positions of UI elements. Layout: - if (box_width < 750 && box_x == margin_size) { - /* Not much width... */ - box_width = bst->xgwa.width; - box_x = 0; - } + +---------+-+---------------------------------------+ + | LOGO | | HEADER | + | | |---------------------------------------| + | | | NOTE TEXT | + | DEAD | | | + | LINE | | | + | TIMERS | | | + | | | | + | | | | + | | | | + | | | | + | | | | + +---------+ | | + | LINKS | +---------------------------------------+ + | LINKS | | FOOTER | + +---------+-+---------------------------------------+ + + The right side of the UI maximises to available width. + The note text maximises to available height. + The logo, header and timers are anchored to the top left of the window. + The links and footer are anchored to the bottom left of the window. + The entire window is a fixed 4:3 scale, with a minimum margin around it. + */ + + /* main window text */ + unsigned long fg = bst->fg; + unsigned long bg = bst->bg; + /* ransom note */ + unsigned long fg2 = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.foreground2", + "Ransomware.Foreground"); + unsigned long bg2 = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.background2", + "Ransomware.Background"); + /* buttons */ + unsigned long fg3 = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.foreground3", + "Ransomware.Foreground"); + unsigned long bg3 = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.background3", + "Ransomware.Background"); + /* links */ + unsigned long link = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.link", + "Ransomware.Foreground"); + /* headers */ + unsigned long theader = get_pixel_resource (dpy, bst->xgwa.colormap, + "ransomware.timerheader", + "Ransomware.Foreground"); + int left_column_width; + int right_column_width; + int right_column_height; + int stage1_countdown_y, stage2_countdown_y; + int margin; + int top_height, bottom_height; + int x, y; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, + pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, + mask, pix_w, pix_h); + pix_w *= 2; + pix_h *= 2; + } + + margin = line_height; + left_column_width = MAX (pix_w, line_height1 * 8); + right_column_width = MIN (line_height * 40, + MAX (line_height * 8, + bst->xgwa.width - left_column_width + - margin*2)); + top_height = line_height * 2.5; + bottom_height = line_height * 6; + right_column_height = MIN (line_height * 36, + bst->xgwa.height - bottom_height - top_height + - line_height); + + if ((bst->xgwa.width / 4) * 3 > bst->xgwa.height) + /* Wide screen: keep the big text box at 4:3, centered. */ + right_column_height = MIN (right_column_height, + right_column_width * 4 / 3); + else if (right_column_width < line_height * 30) + /* Tall but narrow screen: make the text box be full height. */ + right_column_height = (bst->xgwa.height - bottom_height - top_height + - line_height); + + x = (bst->xgwa.width - left_column_width - right_column_width - margin) / 2; + y = (bst->xgwa.height - right_column_height - bottom_height) / 2; bst->xoff = bst->left_margin = bst->right_margin = 0; if (!(random() % 8)) return apple2ransomware (dpy, window); - /* Grab the desktop image */ - /* BSOD_IMG (bst); */ - bst->wrap_p = True; - /* Draw the main red window */ BSOD_INVERT (bst); - BSOD_RECT (bst, True, box_x, box_y, box_width, box_height); + BSOD_RECT (bst, True, 0, 0, bst->xgwa.width, bst->xgwa.height); if (pixmap) { bst->pixmap = pixmap; - BSOD_PIXMAP (bst, 0, 0, pix_w, pix_h, box_x + logo_x, box_y + logo_y); + bst->mask = mask; + BSOD_PIXMAP (bst, 0, 0, pix_w, pix_h, + x + (left_column_width - pix_w) / 2, + y); } /* Setup deadlines */ strftime (stage1_deadline_str, sizeof(stage1_deadline_str), - "%m/%d/%Y %H:%M:%S\n\n", localtime(&stage1_deadline)); + "%m/%d/%Y %H:%M:%S", localtime(&stage1_deadline)); strftime (stage2_deadline_str, sizeof(stage1_deadline_str), - "%m/%d/%Y %H:%M:%S\n\n", localtime(&stage2_deadline)); + "%m/%d/%Y %H:%M:%S", localtime(&stage2_deadline)); BSOD_INVERT (bst); /* Draw header pane */ BSOD_FONT (bst, 0); - BSOD_MOVETO (bst, box_x + right_pane_x, box_y + header_y + bst->fontA->ascent); - BSOD_MARGINS (bst, box_x + right_pane_x, box_x); + + BSOD_MARGINS (bst, + x + left_column_width + margin, + bst->xgwa.width - + (x + left_column_width + margin + right_column_width)); + BSOD_MOVETO (bst, x + left_column_width + margin, + y + bst->fontA->ascent); BSOD_COLOR (bst, fg, bg); + BSOD_WORD_WRAP (bst); BSOD_TEXT (bst, CENTER, header_quip); + BSOD_TRUNCATE (bst); /* Draw left-side timers */ - BSOD_MOVETO (bst, box_x, box_y + deadline_y); - BSOD_MARGINS (bst, box_x, box_x + box_width - left_pane_width); + BSOD_MARGINS (bst, x, bst->xgwa.width - (x + left_column_width)); + BSOD_MOVETO (bst, x, y + pix_h + line_height); BSOD_FONT (bst, 1); BSOD_COLOR (bst, theader, bg); @@ -1687,28 +1783,29 @@ windows_ransomware (Display *dpy, Window window) BSOD_COLOR (bst, fg, bg); BSOD_TEXT (bst, CENTER, stage1_deadline_str); - BSOD_TEXT (bst, CENTER, "Time Left\n"); - stage1_countdown_y = (line_height * 4) + box_y + deadline_y; - BSOD_TEXT (bst, CENTER, "\n"); - BSOD_TEXT (bst, CENTER, "\n\n"); + stage1_countdown_y = y + pix_h + line_height + line_height1 * 3; + BSOD_MOVETO (bst, x, stage1_countdown_y - line_height); + BSOD_TEXT (bst, CENTER, "Time Left"); BSOD_COLOR (bst, theader, bg); - BSOD_TEXT (bst, CENTER, "Your pixels will be lost on\n"); + BSOD_WORD_WRAP (bst); + BSOD_TEXT (bst, CENTER, "\n\n\n\nYour pixels will be lost on\n"); + BSOD_TRUNCATE (bst); BSOD_COLOR (bst, fg, bg); BSOD_TEXT (bst, CENTER, stage2_deadline_str); - BSOD_TEXT (bst, CENTER, "Time Left\n"); - stage2_countdown_y = (line_height * 9) + box_y + deadline_y; - BSOD_TEXT (bst, CENTER, "\n"); + stage2_countdown_y = stage1_countdown_y + line_height1 * 5; + BSOD_MOVETO (bst, x, stage2_countdown_y - line_height); + BSOD_TEXT (bst, CENTER, "Time Left"); - /* Draw links */ BSOD_FONT (bst, 1); - BSOD_MOVETO (bst, box_x + links_x, box_y + box_height - links_height); - BSOD_MARGINS (bst, box_x + links_x, box_x + box_width - left_pane_width); - BSOD_COLOR (bst, link, bg); - if (box_height > 425) { - /* Don't show this on small screens */ + /* Draw links, but skip on small screens */ + if (right_column_height > 425) { + BSOD_MOVETO (bst, x, + y + right_column_height + top_height + bottom_height + - line_height1 * 5); + BSOD_COLOR (bst, link, bg); BSOD_TEXT (bst, LEFT, "\n"); BSOD_TEXT (bst, LEFT, "About "); BSOD_TEXT (bst, LEFT, currency); @@ -1721,20 +1818,26 @@ windows_ransomware (Display *dpy, Window window) /* Ransom note text area */ BSOD_COLOR (bst, bg2, fg2); - BSOD_RECT (bst, True, box_x + right_pane_x, box_y + ransom_y, - box_width - right_pane_x - 10, - box_height - ransom_y - footer_height); - BSOD_MOVETO (bst, box_x + right_pane_x + 5, - box_y + ransom_y + (line_height * 1.1)); - BSOD_MARGINS (bst, box_x + right_pane_x + 5, box_x + 15); - /* VERT_MARGINS are a bit high, to ensure we draw as much text as we can in - * the box, even if the line is partially cut. We'll draw over this later. - */ - BSOD_VERT_MARGINS (bst, box_y + ransom_y, box_y + (footer_height / 2)); + BSOD_RECT (bst, True, + x + left_column_width + margin, + y + top_height, + right_column_width, + right_column_height); + BSOD_MOVETO (bst, + x + left_column_width + margin + line_height / 2, + y + top_height + line_height + line_height / 2); + BSOD_MARGINS (bst, + x + left_column_width + margin + line_height / 2, + bst->xgwa.width - + (x + left_column_width + margin + right_column_width)); + BSOD_VERT_MARGINS (bst, + y + top_height + line_height / 2, + bottom_height - line_height); BSOD_INVERT (bst); /* Write out the ransom note itself */ BSOD_CROP (bst, True); + BSOD_WORD_WRAP (bst); for (i = 0; i < countof(lines); i++) { const char *s = lines[i]; @@ -1752,19 +1855,26 @@ windows_ransomware (Display *dpy, Window window) BSOD_TEXT (bst, LEFT, s); } + BSOD_TRUNCATE (bst); BSOD_CROP (bst, False); BSOD_FONT (bst, 0); /* Draw over any overflowing ransom text. */ BSOD_COLOR (bst, bg, fg); - BSOD_RECT (bst, True, box_x + right_pane_x, - box_y + box_height - footer_height, - box_width - right_pane_x, footer_height); + BSOD_RECT (bst, True, + x + left_column_width + margin, + y + top_height + right_column_height, + bst->xgwa.width, bst->xgwa.height); + BSOD_RECT (bst, True, + x + left_column_width + margin + right_column_width, + y + top_height, + bst->xgwa.width, bst->xgwa.height); /* Draw the footer */ BSOD_COLOR (bst, theader, bg); - BSOD_MOVETO (bst, box_x + right_pane_x, - box_y + box_height - footer_height + line_height); + BSOD_MOVETO (bst, + x + left_column_width + margin, + y + top_height + right_column_height + line_height * 2); sprintf(buf, "Send $%.2f of %s to this address:\n", 101+frand(888), currency); BSOD_TEXT (bst, LEFT, buf); @@ -1803,8 +1913,8 @@ windows_ransomware (Display *dpy, Window window) BSOD_FONT (bst, 0); do { /* First timer */ - BSOD_MOVETO (bst, box_x, stage1_countdown_y); - BSOD_MARGINS (bst, box_x, box_x + box_width - left_pane_width); + BSOD_MOVETO (bst, x, stage1_countdown_y); + BSOD_MARGINS (bst, x, bst->xgwa.width - (x + left_column_width)); countdown_r = stage1_deadline - now; countdown_s = countdown_r % 60; @@ -1818,7 +1928,7 @@ windows_ransomware (Display *dpy, Window window) BSOD_TEXT (bst, CENTER, countdown_str); /* Second timer */ - BSOD_MOVETO (bst, box_x, stage2_countdown_y); + BSOD_MOVETO (bst, x, stage2_countdown_y); countdown_r = stage2_deadline - now; countdown_s = countdown_r % 60; @@ -2044,10 +2154,15 @@ amiga (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "amiga", "Amiga"); + const char *guru1 ="Software failure. Press left mouse button to continue."; + const char *guru2 ="Guru Meditation #00000003.00C01570"; Pixmap pixmap = 0; + Pixmap mask = 0; int pix_w = 0, pix_h = 0; int height; - int lw = 10; + int lw = bst->font->ascent + bst->font->descent; + unsigned long fg = bst->fg; + unsigned long bg = bst->bg; unsigned long bg2 = get_pixel_resource (dpy, bst->xgwa.colormap, "amiga.background2", @@ -2056,40 +2171,55 @@ amiga (Display *dpy, Window window) bst->yoff = 0; bst->top_margin = bst->bottom_margin = 0; -# ifdef DO_XPM - pixmap = xpm_data_to_pixmap (dpy, window, (char **) amiga_hand, - &pix_w, &pix_h, 0); -# endif /* DO_XPM */ + pixmap = image_data_to_pixmap (dpy, window, + amiga_png, sizeof(amiga_png), + &pix_w, &pix_h, &mask); - if (pixmap && - MIN (bst->xgwa.width, bst->xgwa.height) > 600) /* scale up the bitmap */ + if (pixmap) { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, - pixmap, pix_w, pix_h); - pix_w *= 2; - pix_h *= 2; - lw *= 2; + int i, n = 0; + if (MIN (bst->xgwa.width, bst->xgwa.height) > 600) n++; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, + pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); + pix_w *= 2; + pix_h *= 2; + } } XSetLineAttributes (dpy, bst->gc, lw, LineSolid, CapButt, JoinMiter); - height = (bst->font->ascent + bst->font->descent) * 6; + height = lw * 5; + + bst->char_delay = bst->line_delay = 0; BSOD_PAUSE (bst, 2000000); BSOD_COPY (bst, 0, 0, bst->xgwa.width, bst->xgwa.height - height, 0, height); - BSOD_INVERT (bst); - BSOD_RECT (bst, True, 0, 0, bst->xgwa.width, height); - BSOD_INVERT (bst); - BSOD_TEXT (bst, CENTER, - "\n" - "Software failure. Press left mouse button to continue.\n" - "Guru Meditation #00000003.00C01570" - ); - BSOD_RECT (bst, False, lw/2, lw/2, bst->xgwa.width - lw, height); + BSOD_COLOR (bst, fg, bg); + BSOD_RECT (bst, True, 0, 0, bst->xgwa.width, height); /* red */ + BSOD_COLOR (bst, bg, fg); + BSOD_RECT (bst, True, lw/2, lw/2, bst->xgwa.width-lw, height-lw); /* black */ + BSOD_COLOR (bst, fg, bg); + BSOD_MOVETO (bst, 0, lw*2); + BSOD_TEXT (bst, CENTER, guru1); + BSOD_MOVETO (bst, 0, lw*3.5); + BSOD_TEXT (bst, CENTER, guru2); BSOD_PAUSE (bst, 1000000); - BSOD_INVERT (bst); - BSOD_LOOP (bst, -3); + + BSOD_COLOR (bst, bg, fg); + BSOD_RECT (bst, True, 0, 0, bst->xgwa.width, height); /* black */ + BSOD_COLOR (bst, fg, bg); + BSOD_MOVETO (bst, 0, lw*2); + BSOD_TEXT (bst, CENTER, guru1); + BSOD_MOVETO (bst, 0, lw*3.5); + BSOD_TEXT (bst, CENTER, guru2); + BSOD_PAUSE (bst, 1000000); + + BSOD_LOOP (bst, -17); XSetWindowBackground (dpy, window, bg2); XClearWindow (dpy, window); @@ -2099,7 +2229,12 @@ amiga (Display *dpy, Window window) { int x = (bst->xgwa.width - pix_w) / 2; int y = ((bst->xgwa.height - pix_h) / 2); + XSetClipMask (dpy, bst->gc, mask); + XSetClipOrigin (dpy, bst->gc, x, y); XCopyArea (dpy, pixmap, bst->window, bst->gc, 0, 0, pix_w, pix_h, x, y); + XSetClipMask (dpy, bst->gc, None); + XFreePixmap (dpy, pixmap); + XFreePixmap (dpy, mask); } bst->y += lw; @@ -2124,17 +2259,17 @@ atari (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "atari", "Atari"); - Pixmap pixmap = 0; - int pix_w = atari_width; - int pix_h = atari_height; + int pix_w, pix_h; int offset; int i, x, y; + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + atari_png, sizeof(atari_png), + &pix_w, &pix_h, &mask); - pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) atari_bits, - pix_w, pix_h, - bst->fg, bst->bg, bst->xgwa.depth); - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); pix_w *= 2; pix_h *= 2; @@ -2153,8 +2288,12 @@ atari (Display *dpy, Window window) } XClearWindow (dpy, window); + XSetClipMask (dpy, bst->gc, mask); + XSetClipOrigin (dpy, bst->gc, x, y); XCopyArea (dpy, pixmap, window, bst->gc, 0, 0, pix_w, pix_h, x, y); + XSetClipMask (dpy, bst->gc, None); XFreePixmap (dpy, pixmap); + XFreePixmap (dpy, mask); return bst; } @@ -2165,25 +2304,25 @@ mac (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "mac", "Mac"); - Pixmap pixmap = 0; - int pix_w = mac_width; - int pix_h = mac_height; - int offset = mac_height * 4; + int pix_w, pix_h; int i; const char *string = ("0 0 0 0 0 0 0 F\n" "0 0 0 0 0 0 0 3"); - bst->xoff = bst->left_margin = bst->right_margin = 0; + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + mac_png, sizeof(mac_png), + &pix_w, &pix_h, &mask); + int offset = pix_h * 4; - pixmap = XCreatePixmapFromBitmapData(dpy, window, (char *) mac_bits, - mac_width, mac_height, - bst->fg, bst->bg, bst->xgwa.depth); + bst->xoff = bst->left_margin = bst->right_margin = 0; for (i = 0; i < 2; i++) { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); pix_w *= 2; pix_h *= 2; } @@ -2194,8 +2333,12 @@ mac (Display *dpy, Window window) if (bst->y < 0) bst->y = 0; XClearWindow (dpy, window); + XSetClipMask (dpy, bst->gc, mask); + XSetClipOrigin (dpy, bst->gc, bst->x, bst->y); XCopyArea (dpy, pixmap, window, bst->gc, 0, 0, pix_w, pix_h, bst->x, bst->y); + XSetClipMask (dpy, bst->gc, None); XFreePixmap (dpy, pixmap); + XFreePixmap (dpy, mask); bst->y += offset + bst->font->ascent + bst->font->descent; BSOD_TEXT (bst, CENTER, string); @@ -2391,23 +2534,27 @@ mac1 (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "mac1", "Mac1"); - Pixmap pixmap = 0; - int pix_w = macbomb_width; - int pix_h = macbomb_height; + int pix_w, pix_h; int x, y; - - pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) macbomb_bits, - macbomb_width, macbomb_height, - bst->fg, bst->bg, bst->xgwa.depth); + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + macbomb_png, sizeof(macbomb_png), + &pix_w, &pix_h, &mask); if (pixmap && pix_w < bst->xgwa.width / 2 && pix_h < bst->xgwa.height / 2) { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, - bst->xgwa.depth, pixmap, pix_w, pix_h); - pix_w *= 2; - pix_h *= 2; + int i, n = 1; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, + bst->xgwa.depth, pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); + pix_w *= 2; + pix_h *= 2; + } } x = (bst->xgwa.width - pix_w) / 2; @@ -2415,7 +2562,11 @@ mac1 (Display *dpy, Window window) if (y < 0) y = 0; XClearWindow (dpy, window); + XSetClipMask (dpy, bst->gc, mask); + XSetClipOrigin (dpy, bst->gc, x, y); XCopyArea (dpy, pixmap, window, bst->gc, 0, 0, pix_w, pix_h, x, y); + XSetClipMask (dpy, bst->gc, None); + XFreePixmap (dpy, mask); return bst; } @@ -2440,20 +2591,20 @@ macx_10_0 (Display *dpy, Window window) "macx.textBackground", "MacX.TextBackground")); -# ifdef DO_XPM { Pixmap pixmap = 0; Pixmap mask = 0; int x, y, pix_w, pix_h; - pixmap = xpm_data_to_pixmap (dpy, window, (char **) happy_mac, - &pix_w, &pix_h, &mask); + pixmap = image_data_to_pixmap (dpy, window, + hmac_png, sizeof(hmac_png), + &pix_w, &pix_h, &mask); # ifdef HAVE_MOBILE if (pixmap) { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, pixmap, pix_w, pix_h); - mask = double_pixmap (dpy, bst->gc, bst->xgwa.visual, + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); pix_w *= 2; pix_h *= 2; @@ -2468,8 +2619,8 @@ macx_10_0 (Display *dpy, Window window) XCopyArea (dpy, pixmap, window, bst->gc, 0, 0, pix_w, pix_h, x, y); XSetClipMask (dpy, bst->gc, None); XFreePixmap (dpy, pixmap); + XFreePixmap (dpy, mask); } -#endif /* DO_XPM */ bst->left_margin = 0; bst->right_margin = 0; @@ -2509,27 +2660,35 @@ macx_10_0 (Display *dpy, Window window) } -# ifdef DO_XPM static struct bsod_state * macx_10_2 (Display *dpy, Window window, Bool v10_3_p) { struct bsod_state *bst = make_bsod_state (dpy, window, "macx", "MacX"); + Pixmap mask = 0; Pixmap pixmap = 0; int pix_w = 0, pix_h = 0; int x, y; - pixmap = xpm_data_to_pixmap (dpy, window, - (char **) (v10_3_p ? osx_10_3 : osx_10_2), - &pix_w, &pix_h, 0); + if (v10_3_p) + pixmap = image_data_to_pixmap (dpy, window, + osx_10_3_png, sizeof(osx_10_3_png), + &pix_w, &pix_h, &mask); + else + pixmap = image_data_to_pixmap (dpy, window, + osx_10_2_png, sizeof(osx_10_2_png), + &pix_w, &pix_h, &mask); if (! pixmap) abort(); + if (! mask) abort(); #if 0 if (bst->xgwa.height > 600) /* scale up the bitmap */ { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); if (! pixmap) abort(); + if (! mask) abort(); pix_w *= 2; pix_h *= 2; } @@ -2539,6 +2698,7 @@ macx_10_2 (Display *dpy, Window window, Bool v10_3_p) BSOD_PAUSE (bst, 2000000); bst->pixmap = pixmap; + bst->mask = mask; x = (bst->xgwa.width - pix_w) / 2; y = ((bst->xgwa.height - pix_h) / 2); @@ -2546,7 +2706,6 @@ macx_10_2 (Display *dpy, Window window, Bool v10_3_p) return bst; } -# endif /* DO_XPM */ /* 2006 Mac Mini with MacOS 10.6 failing with a bad boot drive. By jwz. @@ -2726,9 +2885,7 @@ macx_install (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "macinstall", "MacX"); - Pixmap pixmap = 0; - int pix_w = apple_width; - int pix_h = apple_height; + int pix_w, pix_h; int x, y; int bw1, bh1; int bw2, bh2; @@ -2750,12 +2907,29 @@ macx_install (Display *dpy, Window window) int i, min; double pct; + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + apple_png, sizeof(apple_png), + &pix_w, &pix_h, &mask); + bst->xoff = bst->left_margin = bst->right_margin = 0; - pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) apple_bits, - apple_width, apple_height, - fg, bg, bst->xgwa.depth); + if (pixmap) + { + int i, n = 0; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, + pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); + pix_w *= 2; + pix_h *= 2; + } + } + bst->pixmap = pixmap; + bst->mask = mask; x = (bst->xgwa.width - pix_w) / 2; y = (bst->xgwa.height) / 2 - pix_h; @@ -2809,7 +2983,6 @@ macx_install (Display *dpy, Window window) static struct bsod_state * macx (Display *dpy, Window window) { -# ifdef DO_XPM switch (1?4:random() % 5) { case 0: return macx_10_0 (dpy, window); break; case 1: return macx_10_2 (dpy, window, False); break; @@ -2818,13 +2991,6 @@ macx (Display *dpy, Window window) case 4: return macx_install (dpy, window); break; default: abort(); } -# else /* !DO_XPM */ - switch (random() % 3) { - case 0: return macx_10_0 (dpy, window); break; - case 1: return macx_install (dpy, window); break; - default: return mac_diskfail (dpy, window); break; - } -# endif /* !DO_XPM */ } @@ -4864,23 +5030,22 @@ atm (Display *dpy, Window window) { struct bsod_state *bst = make_bsod_state (dpy, window, "atm", "ATM"); - Pixmap pixmap = 0; - int pix_w = atm_width; - int pix_h = atm_height; + int pix_w, pix_h; int x, y, i = 0; float scale = 0.48; + Pixmap mask = 0; + Pixmap pixmap = image_data_to_pixmap (dpy, window, + atm_png, sizeof(atm_png), + &pix_w, &pix_h, &mask); XClearWindow (dpy, window); - pixmap = XCreatePixmapFromBitmapData (dpy, window, (char *) atm_bits, - atm_width, atm_height, - bst->fg, bst->bg, bst->xgwa.depth); - while (pix_w <= bst->xgwa.width * scale && pix_h <= bst->xgwa.height * scale) { - pixmap = double_pixmap (dpy, bst->gc, bst->xgwa.visual, bst->xgwa.depth, + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, mask, pix_w, pix_h); pix_w *= 2; pix_h *= 2; i++; @@ -4903,9 +5068,12 @@ atm (Display *dpy, Window window) XDrawLine (bst->dpy, pixmap, bst->gc, 0, j, pix_w, j); } + XSetClipMask (dpy, bst->gc, mask); + XSetClipOrigin (dpy, bst->gc, x, y); XCopyArea (dpy, pixmap, window, bst->gc, 0, 0, pix_w, pix_h, x, y); XFreePixmap (dpy, pixmap); + XFreePixmap (dpy, mask); return bst; } @@ -4996,15 +5164,28 @@ android (Display *dpy, Window window) int state = 0; - Pixmap pixmap = 0; + Pixmap pixmap = 0, mask = 0; int pix_w = 0, pix_h = 0; -# ifdef DO_XPM - pixmap = xpm_data_to_pixmap (dpy, window, (char **) android_skate, - &pix_w, &pix_h, 0); + pixmap = image_data_to_pixmap (dpy, window, + android_png, sizeof(android_png), + &pix_w, &pix_h, &mask); if (! pixmap) abort(); + { + int i, n = 0; + if (bst->xgwa.width > 2560) n++; /* Retina displays */ + for (i = 0; i < n; i++) + { + pixmap = double_pixmap (dpy, bst->xgwa.visual, bst->xgwa.depth, + pixmap, pix_w, pix_h); + mask = double_pixmap (dpy, bst->xgwa.visual, 1, + mask, pix_w, pix_h); + pix_w *= 2; + pix_h *= 2; + } + } bst->pixmap = pixmap; -# endif /* DO_XPM */ + bst->mask = mask; bst->left_margin = (bst->xgwa.width - (cw * 40)) / 2; if (bst->left_margin < 0) bst->left_margin = 0; @@ -5322,32 +5503,35 @@ bsod_draw (Display *dpy, Window window, void *closure) else { int count = countof(all_modes); + int *enabled = (int *) calloc (sizeof(*enabled), count + 1); + int nenabled = 0; int i; - for (i = 0; i < 200; i++) + for (i = 0; i < count; i++) { char name[100], class[100]; - int new_mode = (random() & 0xFF) % count; - - if (i < 100 && new_mode == dst->which) - continue; - - sprintf (name, "do%s", all_modes[new_mode].name); - sprintf (class, "Do%s", all_modes[new_mode].name); - + sprintf (name, "do%s", all_modes[i].name); + sprintf (class, "Do%s", all_modes[i].name); if (get_boolean_resource (dpy, name, class)) - { - dst->which = new_mode; - break; - } + enabled[nenabled++] = i; } - if (i >= 200) + if (nenabled == 0) { fprintf (stderr, "%s: no display modes enabled?\n", progname); /* exit (-1); */ dst->which = dst->only = 0; } + else if (nenabled == 1) + dst->which = enabled[0]; + else + { + i = dst->which; + while (i == dst->which) + i = enabled[random() % nenabled]; + dst->which = i; + } + free (enabled); } if (dst->debug_p) @@ -5522,7 +5706,7 @@ static const char *bsod_defaults [] = { ".amiga.background: Black", ".amiga.background2: White", - ".mac.foreground: #BBFFFF", + ".mac.foreground: #FFFFFF", ".mac.background: Black", ".atari.foreground: Black", @@ -5614,8 +5798,6 @@ static const char *bsod_defaults [] = { "*font: PxPlus IBM VGA8 16, Courier-Bold 14", "*bigFont: ", - "*font2: ", - "*bigFont2: ", ".mac.font: Courier-Bold 18", ".macsbug.font: Courier-Bold 8", @@ -5629,18 +5811,20 @@ static const char *bsod_defaults [] = { ".win10.bigFont: Arial 12, Helvetica 12", ".win10.fontB: Arial 50, Helvetica 50", ".win10.fontC: Arial 9, Helvetica 9", - ".win10.bigFont2: ", - ".ransomware.font: Arial 10, Helvetica 10", - ".ransomware.fontB: Arial 8, Helvetica 8", - ".ransomware.fontC: Arial 10, Helvetica Bold 10", + /* The real Solaris font is ../OSX/Gallant19.bdf but I don't know how + to convert that to a TTF, so let's use Luxi Mono instead. */ + ".solaris.font: Luxi Mono 12, PxPlus IBM VGA8 12, Courier Bold 12", + + /* "Arial" loads "ArialMT" but "Arial Bold" does not load "Arial-BoldMT"? */ + ".ransomware.font: Arial 11, Helvetica 11", + ".ransomware.fontB: Arial 9, Helvetica 9", + ".ransomware.fontC: Arial Bold 11, Arial-BoldMT 11, Helvetica Bold 11", # elif defined(HAVE_ANDROID) "*font: PxPlus IBM VGA8 16", "*bigFont: ", - "*font2: ", - "*bigFont2: ", ".mac.font: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*", ".macsbug.font: -*-courier-bold-r-*-*-*-80-*-*-m-*-*-*", @@ -5650,12 +5834,12 @@ static const char *bsod_defaults [] = { ".macinstall.bigFont: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*", ".msdos.font: PxPlus IBM VGA8 32", ".nt.font: PxPlus IBM VGA8 12", + ".solaris.font: Luxi Mono 12, PxPlus IBM VGA8 12, Courier Bold 12", ".win10.font: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*", ".win10.bigFont: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*", ".win10.fontB: -*-helvetica-medium-r-*-*-*-500-*-*-*-*-*-*", ".win10.fontC: -*-helvetica-medium-r-*-*-*-90-*-*-*-*-*-*", - ".win10.bigFont2: ", ".ransomware.font: -*-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*", ".ransomware.fontB: -*-helvetica-medium-r-*-*-*-80-*-*-*-*-*-*", @@ -5665,8 +5849,6 @@ static const char *bsod_defaults [] = { "*font: PxPlus IBM VGA8 8, Courier Bold 9", "*bigFont: PxPlus IBM VGA8 32, Courier Bold 24", - "*font2: ", - "*bigFont2: ", ".mac.font: Monaco 10, Courier Bold 9", ".mac.bigFont: Monaco 18, Courier Bold 18", @@ -5683,16 +5865,16 @@ static const char *bsod_defaults [] = { ".hvx.bigFont: PxPlus IBM VGA8 16, Courier Bold 14", ".hppalinux.bigFont: PxPlus IBM VGA8 16, Courier Bold 14", - ".solaris.bigFont: PxPlus IBM VGA8 16, Courier Bold 14", ".linux.bigFont: PxPlus IBM VGA8 16, Courier Bold 14", ".hpux.bigFont: PxPlus IBM VGA8 16, Courier Bold 14", ".msdos.font: PxPlus IBM VGA8 16, Courier Bold 14", + ".solaris.font: Luxi Mono 12, PxPlus IBM VGA8 12, Courier Bold 12", + ".solaris.bigFont: Luxi Mono 16, PxPlus IBM VGA8 16, Courier Bold 14", ".win10.font: Arial 24, Helvetica 24", ".win10.bigFont: Arial 24, Helvetica 24", ".win10.fontB: Arial 100, Helvetica 100", ".win10.fontC: Arial 16, Helvetica 16", - ".win10.bigFont2: ", ".ransomware.font: Arial 24, Helvetica 24", ".ransomware.bigFont: Arial 24, Helvetica 24", @@ -5702,9 +5884,7 @@ static const char *bsod_defaults [] = { # else /* X11 */ "*font: 9x15bold", - "*font2: -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*", "*bigFont: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*", - "*bigFont2: -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*", ".macsbug.font: -*-courier-medium-r-*-*-*-80-*-*-m-*-*-*", ".macsbug.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", @@ -5719,11 +5899,18 @@ static const char *bsod_defaults [] = { ".hppalinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", ".sparclinux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", + /* Some systems might have this, but I'm not sure where it comes from: */ + /* ".bsd.font: -*-vga-normal-r-*-*-*-120-*-*-c-*-*-*", */ + /* The fonts/misc/vga.pcf that comes with xdosemu has no XLFD name: */ ".bsd.font: vga", - ".bsd.bigFont: -sun-console-medium-r-*-*-22-*-*-*-m-*-*-*", - ".bsd.bigFont2: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", + ".bsd.bigFont: -*-vga-normal-r-*-*-*-220-*-*-c-*-*-*", + + /* The original Solaris console font was: + -sun-gallant-demi-r-normal-*-*-140-*-*-c-*-*-* + Red Hat introduced Luxi Mono as its console font, which is similar + to Gallant. X.Org includes it but Debian and Fedora do not. */ + ".solaris.font: -*-luxi mono-medium-r-normal--*-140-*-*-m-*-*-*", - ".solaris.font: -sun-gallant-*-*-*-*-19-*-*-*-*-120-*-*", ".hpux.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", ".os390.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", ".tru64.bigFont: -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*", @@ -5734,8 +5921,6 @@ static const char *bsod_defaults [] = { ".win10.bigFont: -*-helvetica-medium-r-*-*-*-180-*-*-*-*-*-*", ".win10.fontB: -*-helvetica-medium-r-*-*-*-240-*-*-*-*-*-*", ".win10.fontC: -*-helvetica-medium-r-*-*-*-140-*-*-*-*-*-*", - ".win10.font2: ", - ".win10.bigFont2: ", ".ransomware.font: -*-helvetica-medium-r-*-*-*-180-*-*-*-*-*-*", ".ransomware.bigFont: -*-helvetica-medium-r-*-*-*-180-*-*-*-*-*-*",