Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 1 | /* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998 |
| 2 | * Jamie Zawinski <jwz@jwz.org> |
| 3 | * |
| 4 | * Permission to use, copy, modify, distribute, and sell this software and its |
| 5 | * documentation for any purpose is hereby granted without fee, provided that |
| 6 | * the above copyright notice appear in all copies and that both that |
| 7 | * copyright notice and this permission notice appear in supporting |
| 8 | * documentation. No representations are made about the suitability of this |
| 9 | * software for any purpose. It is provided "as is" without express or |
| 10 | * implied warranty. |
| 11 | * |
| 12 | * And remember: X Windows is to graphics hacking as roman numerals are to |
| 13 | * the square root of pi. |
| 14 | */ |
| 15 | |
| 16 | /* This file contains simple code to open a window or draw on the root. |
| 17 | The idea being that, when writing a graphics hack, you can just link |
| 18 | with this .o to get all of the uninteresting junk out of the way. |
| 19 | |
| 20 | - create a procedure `screenhack(dpy, window)' |
| 21 | |
| 22 | - create a variable `char *progclass' which names this program's |
| 23 | resource class. |
| 24 | |
| 25 | - create a variable `char defaults []' for the default resources, and |
| 26 | null-terminate it. |
| 27 | |
| 28 | - create a variable `XrmOptionDescRec options[]' for the command-line, |
| 29 | and null-terminate it. |
| 30 | |
| 31 | And that's it... |
| 32 | */ |
| 33 | |
| 34 | #include <stdio.h> |
| 35 | #include <X11/Intrinsic.h> |
| 36 | #include <X11/IntrinsicP.h> |
| 37 | #include <X11/CoreP.h> |
| 38 | #include <X11/Shell.h> |
| 39 | #include <X11/StringDefs.h> |
| 40 | #include <X11/Xutil.h> |
| 41 | #include <X11/keysym.h> |
| 42 | |
| 43 | #ifdef __sgi |
| 44 | # include <X11/SGIScheme.h> /* for SgiUseSchemes() */ |
| 45 | #endif /* __sgi */ |
| 46 | |
| 47 | #ifdef HAVE_XMU |
| 48 | # ifndef VMS |
| 49 | # include <X11/Xmu/Error.h> |
| 50 | # else /* VMS */ |
| 51 | # include <Xmu/Error.h> |
| 52 | # endif |
| 53 | #else |
| 54 | # include "xmu.h" |
| 55 | #endif |
| 56 | #include "screenhack.h" |
| 57 | #include "version.h" |
| 58 | #include "vroot.h" |
| 59 | |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 60 | #include "debug.h" |
Björn Stenberg | 8b69504 | 2004-09-16 14:36:08 +0000 | [diff] [blame] | 61 | #include "config.h" |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 62 | |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 63 | #ifndef isupper |
| 64 | # define isupper(c) ((c) >= 'A' && (c) <= 'Z') |
| 65 | #endif |
| 66 | #ifndef _tolower |
| 67 | # define _tolower(c) ((c) - 'A' + 'a') |
| 68 | #endif |
| 69 | |
Kjell Ericson | 4bea14d | 2003-01-21 08:46:14 +0000 | [diff] [blame] | 70 | #define KEYBOARD_GENERIC \ |
| 71 | "Keyboard Rockbox\n" \ |
| 72 | "-------- --------------\n" \ |
| 73 | "+ ON\n" \ |
| 74 | "8 UP\n" \ |
| 75 | "2 DOWN\n" \ |
| 76 | "4 LEFT\n" \ |
| 77 | |
| 78 | #ifdef HAVE_LCD_BITMAP |
| 79 | #define KEYBOARD_SPECIFIC \ |
| 80 | "6 RIGHT\n" \ |
| 81 | "Enter OFF\n" \ |
| 82 | "5 PLAY\n" \ |
| 83 | "/ F1\n" \ |
| 84 | "* F2\n" \ |
| 85 | "- F3\n" |
| 86 | #else |
| 87 | #define KEYBOARD_SPECIFIC \ |
| 88 | "6 RIGHT/PLAY (there's no separation between PLAY and RIGHT)\n" \ |
| 89 | "Enter MENU\n" |
| 90 | #endif |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
Kjell Ericson | dbab14d | 2002-10-28 20:02:30 +0000 | [diff] [blame] | 95 | char having_new_lcd=True; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 96 | |
| 97 | char *progname; |
| 98 | XrmDatabase db; |
| 99 | XtAppContext app; |
| 100 | Bool mono_p; |
| 101 | |
| 102 | static XrmOptionDescRec default_options [] = { |
| 103 | { "-root", ".root", XrmoptionNoArg, "True" }, |
| 104 | { "-window", ".root", XrmoptionNoArg, "False" }, |
| 105 | { "-mono", ".mono", XrmoptionNoArg, "True" }, |
| 106 | { "-install", ".installColormap", XrmoptionNoArg, "True" }, |
| 107 | { "-noinstall",".installColormap", XrmoptionNoArg, "False" }, |
| 108 | { "-visual", ".visualID", XrmoptionSepArg, 0 }, |
| 109 | { "-window-id", ".windowID", XrmoptionSepArg, 0 }, |
| 110 | { 0, 0, 0, 0 } |
| 111 | }; |
| 112 | |
| 113 | static char *default_defaults[] = { |
| 114 | ".root: false", |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 115 | #define GEOMETRY_POSITION 1 |
Daniel Stenberg | 2ed1052 | 2002-08-09 09:13:40 +0000 | [diff] [blame] | 116 | "*geometry: " |
| 117 | #ifdef HAVE_LCD_BITMAP |
| 118 | "120x68" |
| 119 | #else |
Kjell Ericson | dbab14d | 2002-10-28 20:02:30 +0000 | [diff] [blame] | 120 | "280x132" /* A bit larger that necessary */ |
Daniel Stenberg | 2ed1052 | 2002-08-09 09:13:40 +0000 | [diff] [blame] | 121 | #endif |
| 122 | , /* this should be .geometry, but nooooo... */ |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 123 | "*mono: false", |
| 124 | "*installColormap: false", |
| 125 | "*visualID: default", |
| 126 | "*windowID: ", |
| 127 | 0 |
| 128 | }; |
| 129 | |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 130 | extern Display* dpy; |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 131 | extern int display_zoom; |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 132 | |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 133 | static XrmOptionDescRec *merged_options; |
| 134 | static int merged_options_size; |
| 135 | static char **merged_defaults; |
| 136 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 137 | static void merge_options (void) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 138 | { |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 139 | int def_opts_size, opts_size; |
| 140 | int def_defaults_size, defaults_size; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 141 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 142 | for (def_opts_size = 0; default_options[def_opts_size].option; |
| 143 | def_opts_size++) |
| 144 | ; |
| 145 | for (opts_size = 0; options[opts_size].option; opts_size++) |
| 146 | ; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 147 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 148 | merged_options_size = def_opts_size + opts_size; |
| 149 | merged_options = (XrmOptionDescRec *) |
| 150 | malloc ((merged_options_size + 1) * sizeof(*default_options)); |
| 151 | memcpy (merged_options, default_options, |
| 152 | (def_opts_size * sizeof(*default_options))); |
| 153 | memcpy (merged_options + def_opts_size, options, |
| 154 | ((opts_size + 1) * sizeof(*default_options))); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 155 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 156 | for (def_defaults_size = 0; default_defaults[def_defaults_size]; |
| 157 | def_defaults_size++) |
| 158 | ; |
| 159 | for (defaults_size = 0; defaults[defaults_size]; defaults_size++) |
| 160 | ; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 161 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 162 | merged_defaults = (char **) |
| 163 | malloc ((def_defaults_size + defaults_size + 1) * sizeof (*defaults)); |
| 164 | |
| 165 | memcpy (merged_defaults, default_defaults, |
| 166 | def_defaults_size * sizeof(*defaults)); |
| 167 | memcpy (merged_defaults + def_defaults_size, defaults, |
| 168 | (defaults_size + 1) * sizeof(*defaults)); |
| 169 | |
| 170 | /* This totally sucks. Xt should behave like this by default. |
| 171 | If the string in `defaults' looks like ".foo", change that |
| 172 | to "Progclass.foo". |
| 173 | */ |
| 174 | { |
| 175 | char **s; |
| 176 | for (s = merged_defaults; *s; s++) |
| 177 | if (**s == '.') |
| 178 | { |
| 179 | const char *oldr = *s; |
| 180 | char *newr = (char *) malloc(strlen(oldr) |
| 181 | + strlen(progclass) + 3); |
| 182 | strcpy (newr, progclass); |
| 183 | strcat (newr, oldr); |
| 184 | *s = newr; |
| 185 | } |
| 186 | } |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 187 | } |
| 188 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 189 | |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 190 | /* Make the X errors print out the name of this program, so we have some |
| 191 | clue which one has a bug when they die under the screensaver. |
| 192 | */ |
| 193 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 194 | static int screenhack_ehandler (Display *dpy, XErrorEvent *error) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 195 | { |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 196 | fprintf (stderr, "\nX error in %s:\n", progname); |
| 197 | if (XmuPrintDefaultErrorMessage (dpy, error, stderr)) |
| 198 | exit (-1); |
| 199 | else |
| 200 | fprintf (stderr, " (nonfatal.)\n"); |
| 201 | return 0; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 202 | } |
| 203 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 204 | static Bool MapNotify_event_p (Display *dpy, XEvent *event, XPointer window) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 205 | { |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 206 | (void)dpy; |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 207 | return (event->xany.type == MapNotify && |
| 208 | event->xvisibility.window == (Window) window); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 209 | } |
| 210 | |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 211 | static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW; |
| 212 | |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 213 | static Bool checkrepeat(time_t prev, |
| 214 | time_t now) |
| 215 | { |
| 216 | if(now-prev < 50) { |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 217 | return true; |
| 218 | } |
| 219 | return false; |
| 220 | } |
| 221 | |
| 222 | /* Dead-trivial event handling. |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 223 | Exit if the WM_PROTOCOLS WM_DELETE_WINDOW ClientMessage is received. |
| 224 | */ |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 225 | int screenhack_handle_event(Display *dpy, XEvent *event, |
| 226 | bool *release, bool *repeat) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 227 | { |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 228 | int key=0; |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 229 | static time_t lasttime; |
| 230 | static unsigned int lastkeycode; |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 231 | |
| 232 | *release = FALSE; |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 233 | *repeat = false; |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 234 | |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 235 | switch (event->xany.type) { |
| 236 | case KeyPress: |
| 237 | { |
| 238 | KeySym keysym; |
| 239 | unsigned char c = 0; |
| 240 | XLookupString (&event->xkey, &c, 1, &keysym, 0); |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 241 | key = keysym; |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 242 | #if 0 |
| 243 | DEBUGF("Got keypress: %02x %x, time %lx\n", c, |
| 244 | event->xkey.keycode, |
| 245 | event->xkey.time); |
| 246 | #endif |
| 247 | if(lastkeycode == event->xkey.keycode) |
| 248 | *repeat = checkrepeat(lasttime, event->xkey.time); |
| 249 | lasttime = event->xkey.time; |
| 250 | lastkeycode = event->xkey.keycode; |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 251 | } |
| 252 | break; |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 253 | case KeyRelease: |
| 254 | { |
| 255 | KeySym keysym; |
| 256 | unsigned char c = 0; |
| 257 | XLookupString (&event->xkey, &c, 1, &keysym, 0); |
| 258 | key = keysym; |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 259 | #if 0 |
| 260 | DEBUGF("Got keyrelease: %c (%02x) %x\n", c, c, |
| 261 | event->xkey.keycode); |
| 262 | #endif |
| 263 | if(lastkeycode == event->xkey.keycode) |
| 264 | *repeat = checkrepeat(lasttime, event->xkey.time); |
| 265 | lasttime = event->xkey.time; |
| 266 | lastkeycode = event->xkey.keycode; |
| 267 | if(*repeat) |
| 268 | return 0; /* on repeats, return nothing on release */ |
| 269 | |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 270 | *release = TRUE; |
| 271 | } |
| 272 | break; |
Kjell Ericson | fae2120 | 2002-10-16 08:44:43 +0000 | [diff] [blame] | 273 | case Expose: |
| 274 | { |
Kjell Ericson | dbab14d | 2002-10-28 20:02:30 +0000 | [diff] [blame] | 275 | screen_redraw(); |
Kjell Ericson | fae2120 | 2002-10-16 08:44:43 +0000 | [diff] [blame] | 276 | } |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 277 | break; |
| 278 | default: |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 279 | break; |
Daniel Stenberg | ed6c7e4 | 2002-06-14 11:00:13 +0000 | [diff] [blame] | 280 | case ClientMessage: |
| 281 | { |
| 282 | if (event->xclient.message_type != XA_WM_PROTOCOLS) { |
| 283 | char *s = XGetAtomName(dpy, event->xclient.message_type); |
| 284 | if (!s) s = "(null)"; |
| 285 | fprintf (stderr, "%s: unknown ClientMessage %s received!\n", |
| 286 | progname, s); |
| 287 | } |
| 288 | else if (event->xclient.data.l[0] != (int)XA_WM_DELETE_WINDOW) { |
| 289 | char *s1 = XGetAtomName(dpy, event->xclient.message_type); |
| 290 | char *s2 = XGetAtomName(dpy, event->xclient.data.l[0]); |
| 291 | if (!s1) s1 = "(null)"; |
| 292 | if (!s2) s2 = "(null)"; |
| 293 | fprintf (stderr, "%s: unknown ClientMessage %s[%s] received!\n", |
| 294 | progname, s1, s2); |
| 295 | } |
| 296 | else { |
| 297 | exit (0); |
| 298 | } |
| 299 | } |
| 300 | break; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 301 | } |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 302 | return key; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 306 | int screenhack_handle_events(bool *release, bool *repeat) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 307 | { |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 308 | int key=0; |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 309 | if(XPending(dpy)) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 310 | { |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 311 | XEvent event; |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 312 | XNextEvent(dpy, &event); |
Daniel Stenberg | eae5110 | 2003-04-23 18:49:57 +0000 | [diff] [blame] | 313 | key=screenhack_handle_event(dpy, &event, release, repeat); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 314 | } |
Björn Stenberg | 5d4094f | 2002-04-19 14:02:23 +0000 | [diff] [blame] | 315 | return key; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 316 | } |
| 317 | |
| 318 | |
| 319 | static Visual * |
| 320 | pick_visual (Screen *screen) |
| 321 | { |
| 322 | #ifdef USE_GL |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 323 | /* If we're linking against GL (that is, this is the version of |
| 324 | screenhack.o that the GL hacks will use, which is different from the |
| 325 | one that the non-GL hacks will use) then try to pick the "best" visual |
| 326 | by interrogating the GL library instead of by asking Xlib. GL knows |
| 327 | better. |
| 328 | */ |
| 329 | Visual *v = 0; |
| 330 | char *string = get_string_resource ("visualID", "VisualID"); |
| 331 | char *s; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 332 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 333 | if (string) |
| 334 | for (s = string; *s; s++) |
| 335 | if (isupper (*s)) *s = _tolower (*s); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 336 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 337 | if (!string || !*string || |
| 338 | !strcmp (string, "gl") || |
| 339 | !strcmp (string, "best") || |
| 340 | !strcmp (string, "color") || |
| 341 | !strcmp (string, "default")) |
| 342 | v = get_gl_visual (screen); /* from ../utils/visual-gl.c */ |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 343 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 344 | if (string) |
| 345 | free (string); |
| 346 | if (v) |
| 347 | return v; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 348 | #endif /* USE_GL */ |
| 349 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 350 | return get_visual_resource (screen, "visualID", "VisualID", False); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 351 | } |
| 352 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 353 | int main (int argc, char **argv) |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 354 | { |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 355 | Widget toplevel; |
| 356 | Display *dpy; |
| 357 | Window window; |
| 358 | Screen *screen; |
| 359 | Visual *visual; |
| 360 | Colormap cmap; |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 361 | XEvent event; |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 362 | char version[255]; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 363 | |
Dave Chapman | f830e38 | 2002-05-06 16:10:22 +0000 | [diff] [blame] | 364 | sprintf(version,"rockboxui %s",ROCKBOXUI_VERSION); |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 365 | #ifdef HAVE_LCD_BITMAP |
| 366 | display_zoom=2; |
| 367 | { |
| 368 | char *env=getenv("RECORDER_ZOOM"); |
| 369 | if (env) { |
| 370 | display_zoom=atoi(env); |
| 371 | } |
| 372 | } |
| 373 | #else |
| 374 | display_zoom=1; |
| 375 | { |
| 376 | char *env=getenv("PLAYER_ZOOM"); |
| 377 | if (env) { |
| 378 | display_zoom=atoi(env); |
| 379 | } |
| 380 | } |
| 381 | #endif |
| 382 | |
| 383 | if (argc > 1) |
| 384 | { |
| 385 | int x; |
| 386 | for (x=1; x<argc; x++) { |
| 387 | if (!strcmp("--old_lcd", argv[x])) { |
| 388 | having_new_lcd=FALSE; |
| 389 | printf("Using old LCD layout.\n"); |
| 390 | } else if (!strcmp("--recorder_zoom", argv[x])) { |
| 391 | x++; |
| 392 | #ifdef HAVE_LCD_BITMAP |
| 393 | display_zoom=atoi(argv[x]); |
| 394 | printf("Window zoom is %d\n", display_zoom); |
| 395 | #endif |
| 396 | } else if (!strcmp("--player_zoom", argv[x])) { |
| 397 | x++; |
| 398 | #ifndef HAVE_LCD_BITMAP |
| 399 | display_zoom=atoi(argv[x]); |
| 400 | printf("Window zoom is %d\n", display_zoom); |
| 401 | #endif |
| 402 | } else { |
| 403 | printf("rockboxui\n"); |
| 404 | printf("Arguments:\n"); |
| 405 | printf(" --old_lcd \t [Player] simulate old playermodel (ROM version<4.51)\n"); |
| 406 | printf(" --player_zoom \t [Player] window zoom\n"); |
| 407 | printf(" --recorder_zoom \t [Recorder] window zoom\n"); |
Kjell Ericson | 4bea14d | 2003-01-21 08:46:14 +0000 | [diff] [blame] | 408 | printf(KEYBOARD_GENERIC KEYBOARD_SPECIFIC); |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 409 | exit(0); |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | { |
| 414 | static char geometry[40]; |
| 415 | #ifdef HAVE_LCD_BITMAP |
Björn Stenberg | 8b69504 | 2004-09-16 14:36:08 +0000 | [diff] [blame] | 416 | snprintf(geometry, 40, "*geometry: %dx%d", |
| 417 | LCD_WIDTH*display_zoom+14, LCD_HEIGHT*display_zoom+8); |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 418 | #else |
| 419 | snprintf(geometry, 40, "*geometry: %dx%d", 280*display_zoom, 132*display_zoom); |
| 420 | #endif |
| 421 | default_defaults[GEOMETRY_POSITION]=geometry; |
| 422 | } |
Kjell Ericson | 4bea14d | 2003-01-21 08:46:14 +0000 | [diff] [blame] | 423 | printf(KEYBOARD_GENERIC KEYBOARD_SPECIFIC); |
Kjell Ericson | 0ca9ccb | 2003-01-20 09:39:38 +0000 | [diff] [blame] | 424 | |
| 425 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 426 | merge_options (); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 427 | |
| 428 | #ifdef __sgi |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 429 | /* We have to do this on SGI to prevent the background color from being |
| 430 | overridden by the current desktop color scheme (we'd like our |
| 431 | backgrounds to be black, thanks.) This should be the same as setting |
| 432 | the "*useSchemes: none" resource, but it's not -- if that resource is |
| 433 | present in the `default_defaults' above, it doesn't work, though it |
| 434 | does work when passed as an -xrm arg on the command line. So screw it, |
| 435 | turn them off from C instead. |
| 436 | */ |
| 437 | SgiUseSchemes ("none"); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 438 | #endif /* __sgi */ |
| 439 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 440 | toplevel = XtAppInitialize (&app, progclass, merged_options, |
| 441 | merged_options_size, &argc, argv, |
| 442 | merged_defaults, 0, 0); |
| 443 | dpy = XtDisplay (toplevel); |
| 444 | screen = XtScreen (toplevel); |
| 445 | db = XtDatabase (dpy); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 446 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 447 | XtGetApplicationNameAndClass (dpy, &progname, &progclass); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 448 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 449 | /* half-assed way of avoiding buffer-overrun attacks. */ |
| 450 | if (strlen (progname) >= 100) progname[100] = 0; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 451 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 452 | XSetErrorHandler (screenhack_ehandler); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 453 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 454 | XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); |
| 455 | XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 456 | |
| 457 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 458 | if (CellsOfScreen (DefaultScreenOfDisplay (dpy)) <= 2) |
| 459 | mono_p = True; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 460 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 461 | { |
| 462 | Boolean def_visual_p; |
| 463 | visual = pick_visual (screen); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 464 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 465 | if (toplevel->core.width <= 0) |
| 466 | toplevel->core.width = 600; |
| 467 | if (toplevel->core.height <= 0) |
| 468 | toplevel->core.height = 480; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 469 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 470 | def_visual_p = (visual == DefaultVisualOfScreen (screen)); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 471 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 472 | if (!def_visual_p) |
| 473 | { |
| 474 | unsigned int bg, bd; |
| 475 | Widget new; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 476 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 477 | cmap = XCreateColormap (dpy, RootWindowOfScreen(screen), |
| 478 | visual, AllocNone); |
| 479 | bg = get_pixel_resource ("background", "Background", dpy, cmap); |
| 480 | bd = get_pixel_resource ("borderColor", "Foreground", dpy, cmap); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 481 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 482 | new = XtVaAppCreateShell (progname, progclass, |
| 483 | topLevelShellWidgetClass, dpy, |
| 484 | XtNmappedWhenManaged, False, |
| 485 | XtNvisual, visual, |
| 486 | XtNdepth, visual_depth (screen, visual), |
| 487 | XtNwidth, toplevel->core.width, |
| 488 | XtNheight, toplevel->core.height, |
| 489 | XtNcolormap, cmap, |
| 490 | XtNbackground, (Pixel) bg, |
| 491 | XtNborderColor, (Pixel) bd, |
| 492 | XtNinput, True, /* for WM_HINTS */ |
| 493 | 0); |
| 494 | XtDestroyWidget (toplevel); |
| 495 | toplevel = new; |
| 496 | XtRealizeWidget (toplevel); |
| 497 | window = XtWindow (toplevel); |
| 498 | } |
| 499 | else |
| 500 | { |
| 501 | XtVaSetValues (toplevel, |
| 502 | XtNmappedWhenManaged, False, |
| 503 | XtNinput, True, /* for WM_HINTS */ |
| 504 | 0); |
| 505 | XtRealizeWidget (toplevel); |
| 506 | window = XtWindow (toplevel); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 507 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 508 | if (get_boolean_resource ("installColormap", "InstallColormap")) |
| 509 | { |
| 510 | cmap = XCreateColormap (dpy, window, |
| 511 | DefaultVisualOfScreen (XtScreen |
| 512 | (toplevel)), |
| 513 | AllocNone); |
| 514 | XSetWindowColormap (dpy, window, cmap); |
| 515 | } |
| 516 | else |
| 517 | { |
| 518 | cmap = DefaultColormap (dpy, DefaultScreen (dpy)); |
| 519 | } |
| 520 | } |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 521 | |
Daniel Stenberg | 14b91cc | 2002-09-09 13:28:29 +0000 | [diff] [blame] | 522 | XtPopup (toplevel, XtGrabNone); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 523 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 524 | XtVaSetValues(toplevel, XtNtitle, version, 0); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 525 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 526 | /* For screenhack_handle_events(): select KeyPress, and |
| 527 | announce that we accept WM_DELETE_WINDOW. */ |
| 528 | { |
| 529 | XWindowAttributes xgwa; |
| 530 | XGetWindowAttributes (dpy, window, &xgwa); |
| 531 | XSelectInput (dpy, window, |
Daniel Stenberg | 5fcce4d | 2002-10-14 08:09:29 +0000 | [diff] [blame] | 532 | xgwa.your_event_mask | KeyPressMask | KeyRelease | |
Kjell Ericson | fae2120 | 2002-10-16 08:44:43 +0000 | [diff] [blame] | 533 | ButtonPressMask | ExposureMask); |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 534 | XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, |
| 535 | PropModeReplace, |
| 536 | (unsigned char *) &XA_WM_DELETE_WINDOW, 1); |
| 537 | } |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 538 | } |
| 539 | |
Daniel Stenberg | 14b91cc | 2002-09-09 13:28:29 +0000 | [diff] [blame] | 540 | XSetWindowBackground (dpy, window, |
| 541 | get_pixel_resource ("background", "Background", |
| 542 | dpy, cmap)); |
| 543 | XClearWindow (dpy, window); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 544 | |
Daniel Stenberg | 14b91cc | 2002-09-09 13:28:29 +0000 | [diff] [blame] | 545 | /* wait for it to be mapped */ |
| 546 | XIfEvent (dpy, &event, MapNotify_event_p, (XPointer) window); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 547 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 548 | XSync (dpy, False); |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 549 | |
Robert Hak | 0326934 | 2002-05-03 06:51:05 +0000 | [diff] [blame] | 550 | screenhack (dpy, window); /* doesn't return */ |
| 551 | return 0; |
Daniel Stenberg | 9f6733f | 2002-03-25 14:21:30 +0000 | [diff] [blame] | 552 | } |