1 /* xscreensaver, Copyright (c) 1997 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 * Wendy, let me explain something to you. Whenever you come in here and
12 * interrupt me, you're BREAKING my CONCENTRATION. You're DISTRACTING me!
13 * And it will then take me time to get back to where I was. You understand?
14 * Now, we're going to make a new rule. When you come in here and you hear
15 * me typing, or whether you DON'T hear me typing, or whatever the FUCK you
16 * hear me doing; when I'm in here, it means that I am working, THAT means
17 * don't come in! Now, do you think you can handle that?
21 #include "screenhack.h"
23 char *progclass = "XJack";
27 ".foreground: #00EE00",
28 "XJack.font: -*-courier-medium-r-*-*-*-240-*-*-m-*-*-*",
33 XrmOptionDescRec options [] = {
34 { "-delay", ".delay", XrmoptionSepArg, 0 },
35 { "-font", ".font", XrmoptionSepArg, 0 },
40 screenhack (Display *dpy, Window window)
42 static const char *source = "All work and no play makes Jack a dull boy. ";
43 const char *s = source;
44 int columns, rows; /* characters */
45 int left, right; /* characters */
46 int char_width, line_height; /* pixels */
47 int x, y; /* characters */
49 int hspace = 15; /* pixels */
50 int vspace = 15; /* pixels */
51 Bool break_para = True;
56 XWindowAttributes xgwa;
59 int delay = get_integer_resource ("delay", "Integer");
60 char *fontname = get_string_resource ("font", "Font");
61 XFontStruct *font = XLoadQueryFont (dpy, fontname);
64 font = XLoadQueryFont (dpy, "-*-*-medium-r-*-*-*-240-*-*-m-*-*-*");
66 font = XLoadQueryFont (dpy, "-*-courier-medium-r-*-*-*-180-*-*-m-*-*-*");
68 font = XLoadQueryFont (dpy, "-*-*-*-r-*-*-*-240-*-*-m-*-*-*");
71 fprintf(stderr, "no big fixed-width font like \"%s\"\n", fontname);
75 XGetWindowAttributes (dpy, window, &xgwa);
78 gcv.foreground = get_pixel_resource ("foreground", "Foreground", dpy,
80 gcv.background = get_pixel_resource ("background", "Background", dpy,
82 gc = XCreateGC (dpy, window, (GCFont | GCForeground | GCBackground), &gcv);
84 char_width = (font->per_char
85 ? font->per_char['n'-font->min_char_or_byte2].rbearing
86 : font->min_bounds.rbearing);
87 line_height = font->ascent + font->descent + 1;
89 columns = (xgwa.width - hspace - hspace) / char_width;
90 rows = (xgwa.height - vspace - vspace) / line_height;
92 left = 0xFF & (random() % ((columns / 2)+1));
93 right = left + (0xFF & (random() % (columns - left - 10)+10));
101 for (s2 = s; *s2 && *s2 != ' '; s2++)
106 (x + word_length) >= right))
114 if (mode == 1 || mode == 2)
116 /* 1 = left margin goes southwest; 2 = southeast */
117 left += (mode == 1 ? 1 : -1);
118 if (left >= right - 10)
120 if ((right < (columns - 10)) && (random() & 1))
121 right += (0xFF & (random() % (columns - right)));
131 else if (mode == 3 || mode == 4)
133 /* 3 = right margin goes southeast; 4 = southwest */
134 right += (mode == 3 ? 1 : -1);
135 if (right >= columns)
140 else if (right <= left + 10)
144 if (y >= rows) /* bottom of page */
146 /* scroll by 1-5 lines */
147 int lines = (random() % 5 ? 0 : (0xFF & (random() % 5))) + 1;
151 /* but sometimes scroll by a whole page */
152 if (0 == (random() % 100))
157 XCopyArea (dpy, window, window, gc,
158 0, hspace + line_height,
160 xgwa.height - vspace - vspace - line_height,
162 XClearArea (dpy, window,
163 0, xgwa.height - vspace - line_height,
165 line_height + vspace + vspace,
167 XClearArea (dpy, window, 0, 0, xgwa.width, vspace, False);
168 /* See? It's OK. He saw it on the television. */
169 XClearArea (dpy, window, 0, 0, hspace, xgwa.height, False);
170 XClearArea (dpy, window, xgwa.width - vspace, 0,
171 hspace, xgwa.height, False);
175 if (delay) usleep (delay * 10);
186 int xshift = 0, yshift = 0;
187 if (0 == random() % 50)
189 xshift = random() % ((char_width / 3) + 1); /* mis-strike */
190 yshift = random() % ((line_height / 6) + 1);
191 if (0 == (random() % 3))
199 if (0 == (random() % 250)) /* introduce adjascent-key typo */
201 static const char * const typo[] = {
202 "asqw", "ASQW", "bgvhn", "cxdfv", "dserfcx", "ewsdrf",
203 "Jhuikmn", "kjiol,m", "lkop;.,", "mnjk,", "nbhjm", "oiklp09",
204 "pol;(-0", "redft54", "sawedxz", "uyhji87", "wqase32",
205 "yuhgt67", ".,l;/", 0 };
207 while (typo[i] && typo[i][0] != c)
210 c = typo[i][0xFF & (random() % strlen(typo[i]+1))];
214 if (c >= 'a' && c <= 'z' && (caps || 0 == (random() % 350)))
217 if (c == 'O' && random() & 1)
222 XDrawString (dpy, window, gc,
223 (x * char_width) + hspace + xshift,
224 (y * line_height) + vspace + font->ascent + yshift,
226 if (xshift == 0 && yshift == 0 && (0 == (random() & 3000)))
235 if ((tolower(c) != tolower(*s))
236 ? (0 == (random() % 10)) /* backup to correct */
237 : (0 == (random() % 400))) /* fail to advance */
242 if (delay) usleep (0xFFFF & (delay + (random() % (delay * 10))));
249 if (0 == random() % 200)
251 if (random() & 1 && s != source)
252 s--; /* duplicate character */
254 s++; /* skip character */
260 caps = (0 == random() % 40); /* capitalize sentence */
262 if (0 == (random() % 10) || /* randomly break paragraph */
264 ((0 == (random() % 10)) || sentences > 20)))
270 if (random() & 1) /* mode=0 50% of the time */
273 mode = (0xFF & (random() % 5));
275 if (0 == (random() % 2)) /* re-pick margins */
277 left = 0xFF & (random() % (columns / 3));
278 right = columns - (0xFF & (random() % (columns / 3)));
280 if (0 == random() % 3) /* sometimes be wide */
281 right = left + ((right - left) / 2);
284 if (right - left <= 10) /* introduce sanity */
290 if (right - left > 50) /* if wide, shrink and move */
292 left += (0xFF & (random() % ((columns - 50) + 1)));
293 right = left + (0xFF & ((random() % 40) + 10));
303 left -= (right - columns);
313 if (0 == random() % 3)
314 usleep(0xFFFFFF & ((random() % (delay * 5)) + 1));
317 usleep(0xFFFFFF & ((random() % (delay * 15)) + 1));
321 (0 == (random() % 1000)) &&
325 int n = random() & 3;
327 for (i = 0; i < n; i++)
329 /* See also http://catalog.com/hopkins/unix-haters/login.html */
331 "NFS server overlook not responding, still trying...";
332 const char *n2 = "NFS server overlook ok.";
335 XDrawString (dpy, window, gc,
336 (x * char_width) + hspace,
337 (y * line_height) + vspace + font->ascent,
340 if (x >= columns) x = 0, y++;
347 XDrawString (dpy, window, gc,
348 (x * char_width) + hspace,
349 (y * line_height) + vspace + font->ascent,
352 if (x >= columns) x = 0, y++;