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