comparison src/video/ipod/SDL_ipodvideo.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 8d9bb0cf2c2a
children e27bdcc80744 204be4fc2726
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
43 #include "SDL_sysevents.h" 43 #include "SDL_sysevents.h"
44 #include "SDL_ipodvideo.h" 44 #include "SDL_ipodvideo.h"
45 45
46 #define _THIS SDL_VideoDevice *this 46 #define _THIS SDL_VideoDevice *this
47 47
48 static int iPod_VideoInit (_THIS, SDL_PixelFormat *vformat); 48 static int iPod_VideoInit(_THIS, SDL_PixelFormat * vformat);
49 static SDL_Rect **iPod_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags); 49 static SDL_Rect **iPod_ListModes(_THIS, SDL_PixelFormat * format,
50 static SDL_Surface *iPod_SetVideoMode (_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 50 Uint32 flags);
51 static int iPod_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color *colors); 51 static SDL_Surface *iPod_SetVideoMode(_THIS, SDL_Surface * current,
52 static void iPod_UpdateRects (_THIS, int nrects, SDL_Rect *rects); 52 int width, int height, int bpp,
53 static void iPod_VideoQuit (_THIS); 53 Uint32 flags);
54 static void iPod_PumpEvents (_THIS); 54 static int iPod_SetColors(_THIS, int firstcolor, int ncolors,
55 SDL_Color * colors);
56 static void iPod_UpdateRects(_THIS, int nrects, SDL_Rect * rects);
57 static void iPod_VideoQuit(_THIS);
58 static void iPod_PumpEvents(_THIS);
55 59
56 static long iPod_GetGeneration(); 60 static long iPod_GetGeneration();
57 61
58 static int initd = 0; 62 static int initd = 0;
59 static int kbfd = -1; 63 static int kbfd = -1;
73 #define IPOD_NEW_LCD_BASE 0x70003000 77 #define IPOD_NEW_LCD_BASE 0x70003000
74 #define IPOD_NEW_LCD_RTC 0x60005010 78 #define IPOD_NEW_LCD_RTC 0x60005010
75 79
76 static unsigned long lcd_base, lcd_rtc, lcd_width, lcd_height; 80 static unsigned long lcd_base, lcd_rtc, lcd_width, lcd_height;
77 81
78 static long iPod_GetGeneration() 82 static long
83 iPod_GetGeneration()
79 { 84 {
80 int i; 85 int i;
81 char cpuinfo[256]; 86 char cpuinfo[256];
82 char *ptr; 87 char *ptr;
83 FILE *file; 88 FILE *file;
84 89
85 if ((file = fopen("/proc/cpuinfo", "r")) != NULL) { 90 if ((file = fopen("/proc/cpuinfo", "r")) != NULL) {
86 while (fgets(cpuinfo, sizeof(cpuinfo), file) != NULL) 91 while (fgets(cpuinfo, sizeof(cpuinfo), file) != NULL)
87 if (SDL_strncmp(cpuinfo, "Revision", 8) == 0) 92 if (SDL_strncmp(cpuinfo, "Revision", 8) == 0)
88 break; 93 break;
89 fclose(file); 94 fclose(file);
90 } 95 }
91 for (i = 0; !isspace(cpuinfo[i]); i++); 96 for (i = 0; !isspace(cpuinfo[i]); i++);
92 for (; isspace(cpuinfo[i]); i++); 97 for (; isspace(cpuinfo[i]); i++);
93 ptr = cpuinfo + i + 2; 98 ptr = cpuinfo + i + 2;
94 99
95 return SDL_strtol(ptr, NULL, 10); 100 return SDL_strtol(ptr, NULL, 10);
96 } 101 }
97 102
98 static int iPod_Available() 103 static int
104 iPod_Available()
99 { 105 {
100 return 1; 106 return 1;
101 } 107 }
102 108
103 static void iPod_DeleteDevice (SDL_VideoDevice *device) 109 static void
104 { 110 iPod_DeleteDevice(SDL_VideoDevice * device)
105 free (device->hidden); 111 {
106 free (device); 112 free(device->hidden);
107 } 113 free(device);
108 114 }
109 void iPod_InitOSKeymap (_THIS) {} 115
110 116 void
111 static SDL_VideoDevice *iPod_CreateDevice (int devindex) 117 iPod_InitOSKeymap(_THIS)
118 {
119 }
120
121 static SDL_VideoDevice *
122 iPod_CreateDevice(int devindex)
112 { 123 {
113 SDL_VideoDevice *this; 124 SDL_VideoDevice *this;
114 125
115 this = (SDL_VideoDevice *)SDL_malloc (sizeof(SDL_VideoDevice)); 126 this = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
116 if (this) { 127 if (this) {
117 memset (this, 0, sizeof *this); 128 memset(this, 0, sizeof *this);
118 this->hidden = (struct SDL_PrivateVideoData *) SDL_malloc (sizeof(struct SDL_PrivateVideoData)); 129 this->hidden = (struct SDL_PrivateVideoData *)
130 SDL_malloc(sizeof(struct SDL_PrivateVideoData));
119 } 131 }
120 if (!this || !this->hidden) { 132 if (!this || !this->hidden) {
121 SDL_OutOfMemory(); 133 SDL_OutOfMemory();
122 if (this) 134 if (this)
123 SDL_free (this); 135 SDL_free(this);
124 return 0; 136 return 0;
125 } 137 }
126 memset (this->hidden, 0, sizeof(struct SDL_PrivateVideoData)); 138 memset(this->hidden, 0, sizeof(struct SDL_PrivateVideoData));
127 139
128 generation = iPod_GetGeneration(); 140 generation = iPod_GetGeneration();
129 141
130 this->VideoInit = iPod_VideoInit; 142 this->VideoInit = iPod_VideoInit;
131 this->ListModes = iPod_ListModes; 143 this->ListModes = iPod_ListModes;
132 this->SetVideoMode = iPod_SetVideoMode; 144 this->SetVideoMode = iPod_SetVideoMode;
159 iPod_Available, iPod_CreateDevice 171 iPod_Available, iPod_CreateDevice
160 }; 172 };
161 173
162 //--// 174 //--//
163 175
164 static int iPod_VideoInit (_THIS, SDL_PixelFormat *vformat) 176 static int
177 iPod_VideoInit(_THIS, SDL_PixelFormat * vformat)
165 { 178 {
166 if (!initd) { 179 if (!initd) {
167 /*** Code adapted/copied from SDL fbcon driver. ***/ 180 /*** Code adapted/copied from SDL fbcon driver. ***/
168 181
169 static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", 0 }; 182 static const char *const tty0[] = { "/dev/tty0", "/dev/vc/0", 0 };
170 static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", 0 }; 183 static const char *const vcs[] = { "/dev/vc/%d", "/dev/tty%d", 0 };
171 int i, tty0_fd; 184 int i, tty0_fd;
172 185
173 dbgout = fdopen (open ("/etc/sdlpod.log", O_WRONLY | O_SYNC | O_APPEND), "a"); 186 dbgout =
174 if (dbgout) { 187 fdopen(open("/etc/sdlpod.log", O_WRONLY | O_SYNC | O_APPEND),
175 setbuf (dbgout, 0); 188 "a");
176 fprintf (dbgout, "--> Started SDL <--\n"); 189 if (dbgout) {
177 } 190 setbuf(dbgout, 0);
178 191 fprintf(dbgout, "--> Started SDL <--\n");
179 // Try to query for a free VT 192 }
180 tty0_fd = -1; 193 // Try to query for a free VT
181 for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { 194 tty0_fd = -1;
182 tty0_fd = open(tty0[i], O_WRONLY, 0); 195 for (i = 0; tty0[i] && (tty0_fd < 0); ++i) {
183 } 196 tty0_fd = open(tty0[i], O_WRONLY, 0);
184 if ( tty0_fd < 0 ) { 197 }
185 tty0_fd = dup(0); /* Maybe stdin is a VT? */ 198 if (tty0_fd < 0) {
186 } 199 tty0_fd = dup(0); /* Maybe stdin is a VT? */
187 ioctl(tty0_fd, VT_OPENQRY, &curvt); 200 }
188 close(tty0_fd); 201 ioctl(tty0_fd, VT_OPENQRY, &curvt);
189 202 close(tty0_fd);
190 tty0_fd = open("/dev/tty", O_RDWR, 0); 203
191 if ( tty0_fd >= 0 ) { 204 tty0_fd = open("/dev/tty", O_RDWR, 0);
192 ioctl(tty0_fd, TIOCNOTTY, 0); 205 if (tty0_fd >= 0) {
193 close(tty0_fd); 206 ioctl(tty0_fd, TIOCNOTTY, 0);
194 } 207 close(tty0_fd);
195 208 }
196 if ( (geteuid() == 0) && (curvt > 0) ) { 209
197 for ( i=0; vcs[i] && (kbfd < 0); ++i ) { 210 if ((geteuid() == 0) && (curvt > 0)) {
198 char vtpath[12]; 211 for (i = 0; vcs[i] && (kbfd < 0); ++i) {
199 212 char vtpath[12];
200 SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], curvt); 213
201 kbfd = open(vtpath, O_RDWR); 214 SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], curvt);
202 } 215 kbfd = open(vtpath, O_RDWR);
203 } 216 }
204 if ( kbfd < 0 ) { 217 }
205 if (dbgout) fprintf (dbgout, "Couldn't open any VC\n"); 218 if (kbfd < 0) {
206 return -1; 219 if (dbgout)
207 } 220 fprintf(dbgout, "Couldn't open any VC\n");
208 if (dbgout) fprintf (stderr, "Current VT: %d\n", curvt); 221 return -1;
209 222 }
210 if (kbfd >= 0) { 223 if (dbgout)
211 /* Switch to the correct virtual terminal */ 224 fprintf(stderr, "Current VT: %d\n", curvt);
212 if ( curvt > 0 ) { 225
213 struct vt_stat vtstate; 226 if (kbfd >= 0) {
214 227 /* Switch to the correct virtual terminal */
215 if ( ioctl(kbfd, VT_GETSTATE, &vtstate) == 0 ) { 228 if (curvt > 0) {
216 oldvt = vtstate.v_active; 229 struct vt_stat vtstate;
217 } 230
218 if ( ioctl(kbfd, VT_ACTIVATE, curvt) == 0 ) { 231 if (ioctl(kbfd, VT_GETSTATE, &vtstate) == 0) {
219 if (dbgout) fprintf (dbgout, "Waiting for switch to this VT... "); 232 oldvt = vtstate.v_active;
220 ioctl(kbfd, VT_WAITACTIVE, curvt); 233 }
221 if (dbgout) fprintf (dbgout, "done!\n"); 234 if (ioctl(kbfd, VT_ACTIVATE, curvt) == 0) {
222 } 235 if (dbgout)
223 } 236 fprintf(dbgout, "Waiting for switch to this VT... ");
224 237 ioctl(kbfd, VT_WAITACTIVE, curvt);
225 // Set terminal input mode 238 if (dbgout)
226 if (tcgetattr (kbfd, &old_termios) < 0) { 239 fprintf(dbgout, "done!\n");
227 if (dbgout) fprintf (dbgout, "Can't get termios\n"); 240 }
228 return -1; 241 }
229 } 242 // Set terminal input mode
230 cur_termios = old_termios; 243 if (tcgetattr(kbfd, &old_termios) < 0) {
231 // cur_termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); 244 if (dbgout)
232 // cur_termios.c_iflag |= (BRKINT); 245 fprintf(dbgout, "Can't get termios\n");
233 // cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN); 246 return -1;
234 // cur_termios.c_oflag &= ~(OPOST); 247 }
235 // cur_termios.c_oflag |= (ONOCR | ONLRET); 248 cur_termios = old_termios;
236 cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG); 249 // cur_termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
237 cur_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); 250 // cur_termios.c_iflag |= (BRKINT);
238 cur_termios.c_cc[VMIN] = 0; 251 // cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN);
239 cur_termios.c_cc[VTIME] = 0; 252 // cur_termios.c_oflag &= ~(OPOST);
240 253 // cur_termios.c_oflag |= (ONOCR | ONLRET);
241 if (tcsetattr (kbfd, TCSAFLUSH, &cur_termios) < 0) { 254 cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
242 if (dbgout) fprintf (dbgout, "Can't set termios\n"); 255 cur_termios.c_iflag &=
243 return -1; 256 ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
244 } 257 cur_termios.c_cc[VMIN] = 0;
245 if (ioctl (kbfd, KDSKBMODE, K_MEDIUMRAW) < 0) { 258 cur_termios.c_cc[VTIME] = 0;
246 if (dbgout) fprintf (dbgout, "Can't set medium-raw mode\n"); 259
247 return -1; 260 if (tcsetattr(kbfd, TCSAFLUSH, &cur_termios) < 0) {
248 } 261 if (dbgout)
249 if (ioctl (kbfd, KDSETMODE, KD_GRAPHICS) < 0) { 262 fprintf(dbgout, "Can't set termios\n");
250 if (dbgout) fprintf (dbgout, "Can't set graphics\n"); 263 return -1;
251 return -1; 264 }
252 } 265 if (ioctl(kbfd, KDSKBMODE, K_MEDIUMRAW) < 0) {
253 } 266 if (dbgout)
254 267 fprintf(dbgout, "Can't set medium-raw mode\n");
255 // Open the framebuffer 268 return -1;
256 if ((fbfd = open ("/dev/fb0", O_RDWR)) < 0) { 269 }
257 if (dbgout) fprintf (dbgout, "Can't open framebuffer\n"); 270 if (ioctl(kbfd, KDSETMODE, KD_GRAPHICS) < 0) {
258 return -1; 271 if (dbgout)
259 } else { 272 fprintf(dbgout, "Can't set graphics\n");
260 struct fb_var_screeninfo vinfo; 273 return -1;
261 274 }
262 if (dbgout) fprintf (dbgout, "Generation: %ld\n", generation); 275 }
263 276 // Open the framebuffer
264 if (generation >= 40000) { 277 if ((fbfd = open("/dev/fb0", O_RDWR)) < 0) {
265 lcd_base = IPOD_NEW_LCD_BASE; 278 if (dbgout)
266 } else { 279 fprintf(dbgout, "Can't open framebuffer\n");
267 lcd_base = IPOD_OLD_LCD_BASE; 280 return -1;
268 } 281 } else {
269 282 struct fb_var_screeninfo vinfo;
270 ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo); 283
271 close (fbfd); 284 if (dbgout)
272 285 fprintf(dbgout, "Generation: %ld\n", generation);
273 if (lcd_base == IPOD_OLD_LCD_BASE) 286
274 lcd_rtc = IPOD_OLD_LCD_RTC; 287 if (generation >= 40000) {
275 else if (lcd_base == IPOD_NEW_LCD_BASE) 288 lcd_base = IPOD_NEW_LCD_BASE;
276 lcd_rtc = IPOD_NEW_LCD_RTC; 289 } else {
277 else { 290 lcd_base = IPOD_OLD_LCD_BASE;
278 SDL_SetError ("Unknown iPod version"); 291 }
279 return -1; 292
280 } 293 ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);
281 294 close(fbfd);
282 lcd_width = vinfo.xres; 295
283 lcd_height = vinfo.yres; 296 if (lcd_base == IPOD_OLD_LCD_BASE)
284 297 lcd_rtc = IPOD_OLD_LCD_RTC;
285 if (dbgout) fprintf (dbgout, "LCD is %dx%d\n", lcd_width, lcd_height); 298 else if (lcd_base == IPOD_NEW_LCD_BASE)
286 } 299 lcd_rtc = IPOD_NEW_LCD_RTC;
287 300 else {
288 fcntl (kbfd, F_SETFL, O_RDWR | O_NONBLOCK); 301 SDL_SetError("Unknown iPod version");
289 302 return -1;
290 /* Determine the current screen size */ 303 }
291 this->info.current_w = lcd_width; 304
292 this->info.current_h = lcd_height; 305 lcd_width = vinfo.xres;
293 306 lcd_height = vinfo.yres;
294 if ((generation >= 60000) && (generation < 70000)) { 307
295 vformat->BitsPerPixel = 16; 308 if (dbgout)
296 vformat->Rmask = 0xF800; 309 fprintf(dbgout, "LCD is %dx%d\n", lcd_width, lcd_height);
297 vformat->Gmask = 0x07E0; 310 }
298 vformat->Bmask = 0x001F; 311
299 } else { 312 fcntl(kbfd, F_SETFL, O_RDWR | O_NONBLOCK);
300 vformat->BitsPerPixel = 8; 313
301 vformat->Rmask = vformat->Gmask = vformat->Bmask = 0; 314 /* Determine the current screen size */
302 } 315 this->info.current_w = lcd_width;
303 316 this->info.current_h = lcd_height;
304 initd = 1; 317
305 if (dbgout) fprintf (dbgout, "Initialized.\n\n"); 318 if ((generation >= 60000) && (generation < 70000)) {
319 vformat->BitsPerPixel = 16;
320 vformat->Rmask = 0xF800;
321 vformat->Gmask = 0x07E0;
322 vformat->Bmask = 0x001F;
323 } else {
324 vformat->BitsPerPixel = 8;
325 vformat->Rmask = vformat->Gmask = vformat->Bmask = 0;
326 }
327
328 initd = 1;
329 if (dbgout)
330 fprintf(dbgout, "Initialized.\n\n");
306 } 331 }
307 return 0; 332 return 0;
308 } 333 }
309 334
310 static SDL_Rect **iPod_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) 335 static SDL_Rect **
336 iPod_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
311 { 337 {
312 int width, height, fd; 338 int width, height, fd;
313 static SDL_Rect r; 339 static SDL_Rect r;
314 static SDL_Rect *rs[2] = { &r, 0 }; 340 static SDL_Rect *rs[2] = { &r, 0 };
315 341
316 if ((fd = open ("/dev/fb0", O_RDWR)) < 0) { 342 if ((fd = open("/dev/fb0", O_RDWR)) < 0) {
317 return 0; 343 return 0;
318 } else { 344 } else {
319 struct fb_var_screeninfo vinfo; 345 struct fb_var_screeninfo vinfo;
320 346
321 ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo); 347 ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);
322 close (fbfd); 348 close(fbfd);
323 349
324 width = vinfo.xres; 350 width = vinfo.xres;
325 height = vinfo.yres; 351 height = vinfo.yres;
326 } 352 }
327 r.x = r.y = 0; 353 r.x = r.y = 0;
328 r.w = width; 354 r.w = width;
329 r.h = height; 355 r.h = height;
330 return rs; 356 return rs;
331 } 357 }
332 358
333 359
334 static SDL_Surface *iPod_SetVideoMode (_THIS, SDL_Surface *current, int width, int height, int bpp, 360 static SDL_Surface *
335 Uint32 flags) 361 iPod_SetVideoMode(_THIS, SDL_Surface * current, int width, int height,
362 int bpp, Uint32 flags)
336 { 363 {
337 Uint32 Rmask, Gmask, Bmask; 364 Uint32 Rmask, Gmask, Bmask;
338 if (bpp > 8) { 365 if (bpp > 8) {
339 Rmask = 0xF800; 366 Rmask = 0xF800;
340 Gmask = 0x07E0; 367 Gmask = 0x07E0;
341 Bmask = 0x001F; 368 Bmask = 0x001F;
342 } else { 369 } else {
343 Rmask = Gmask = Bmask = 0; 370 Rmask = Gmask = Bmask = 0;
344 } 371 }
345 372
346 if (this->hidden->buffer) SDL_free (this->hidden->buffer); 373 if (this->hidden->buffer)
347 this->hidden->buffer = SDL_malloc (width * height * (bpp / 8)); 374 SDL_free(this->hidden->buffer);
375 this->hidden->buffer = SDL_malloc(width * height * (bpp / 8));
348 if (!this->hidden->buffer) { 376 if (!this->hidden->buffer) {
349 SDL_SetError ("Couldn't allocate buffer for requested mode"); 377 SDL_SetError("Couldn't allocate buffer for requested mode");
350 return 0; 378 return 0;
351 } 379 }
352 380
353 memset (this->hidden->buffer, 0, width * height * (bpp / 8)); 381 memset(this->hidden->buffer, 0, width * height * (bpp / 8));
354 382
355 if (!SDL_ReallocFormat (current, bpp, Rmask, Gmask, Bmask, 0)) { 383 if (!SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0)) {
356 SDL_SetError ("Couldn't allocate new pixel format"); 384 SDL_SetError("Couldn't allocate new pixel format");
357 SDL_free (this->hidden->buffer); 385 SDL_free(this->hidden->buffer);
358 this->hidden->buffer = 0; 386 this->hidden->buffer = 0;
359 return 0; 387 return 0;
360 } 388 }
361 389
362 if (bpp <= 8) { 390 if (bpp <= 8) {
363 int i, j; 391 int i, j;
364 for (i = 0; i < 256; i += 4) { 392 for (i = 0; i < 256; i += 4) {
365 for (j = 0; j < 4; j++) { 393 for (j = 0; j < 4; j++) {
366 current->format->palette->colors[i+j].r = 85 * j; 394 current->format->palette->colors[i + j].r = 85 * j;
367 current->format->palette->colors[i+j].g = 85 * j; 395 current->format->palette->colors[i + j].g = 85 * j;
368 current->format->palette->colors[i+j].b = 85 * j; 396 current->format->palette->colors[i + j].b = 85 * j;
369 } 397 }
370 } 398 }
371 } 399 }
372 400
373 current->flags = flags & SDL_FULLSCREEN; 401 current->flags = flags & SDL_FULLSCREEN;
374 this->hidden->w = current->w = width; 402 this->hidden->w = current->w = width;
375 this->hidden->h = current->h = height; 403 this->hidden->h = current->h = height;
377 current->pixels = this->hidden->buffer; 405 current->pixels = this->hidden->buffer;
378 406
379 return current; 407 return current;
380 } 408 }
381 409
382 static int iPod_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color *colors) 410 static int
383 { 411 iPod_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
384 if (SDL_VideoSurface && SDL_VideoSurface->format && SDL_VideoSurface->format->palette) { 412 {
385 int i, j; 413 if (SDL_VideoSurface && SDL_VideoSurface->format
386 for (i = 0; i < 256; i += 4) { 414 && SDL_VideoSurface->format->palette) {
387 for (j = 0; j < 4; j++) { 415 int i, j;
388 SDL_VideoSurface->format->palette->colors[i+j].r = 85 * j; 416 for (i = 0; i < 256; i += 4) {
389 SDL_VideoSurface->format->palette->colors[i+j].g = 85 * j; 417 for (j = 0; j < 4; j++) {
390 SDL_VideoSurface->format->palette->colors[i+j].b = 85 * j; 418 SDL_VideoSurface->format->palette->colors[i + j].r = 85 * j;
391 } 419 SDL_VideoSurface->format->palette->colors[i + j].g = 85 * j;
392 } 420 SDL_VideoSurface->format->palette->colors[i + j].b = 85 * j;
421 }
422 }
393 } 423 }
394 return 0; 424 return 0;
395 } 425 }
396 426
397 static void iPod_VideoQuit (_THIS) 427 static void
398 { 428 iPod_VideoQuit(_THIS)
399 ioctl (kbfd, KDSETMODE, KD_TEXT); 429 {
400 tcsetattr (kbfd, TCSAFLUSH, &old_termios); 430 ioctl(kbfd, KDSETMODE, KD_TEXT);
431 tcsetattr(kbfd, TCSAFLUSH, &old_termios);
401 old_kbmode = -1; 432 old_kbmode = -1;
402 433
403 if (oldvt > 0) 434 if (oldvt > 0)
404 ioctl (kbfd, VT_ACTIVATE, oldvt); 435 ioctl(kbfd, VT_ACTIVATE, oldvt);
405 436
406 if (kbfd > 0) 437 if (kbfd > 0)
407 close (kbfd); 438 close(kbfd);
408 439
409 if (dbgout) { 440 if (dbgout) {
410 fprintf (dbgout, "<-- Ended SDL -->\n"); 441 fprintf(dbgout, "<-- Ended SDL -->\n");
411 fclose (dbgout); 442 fclose(dbgout);
412 } 443 }
413 444
414 kbfd = -1; 445 kbfd = -1;
415 } 446 }
416 447
417 static char iPod_SC_keymap[] = { 448 static char iPod_SC_keymap[] = {
418 0, /* 0 - no key */ 449 0, /* 0 - no key */
419 '[' - 0x40, /* ESC (Ctrl+[) */ 450 '[' - 0x40, /* ESC (Ctrl+[) */
420 '1', '2', '3', '4', '5', '6', '7', '8', '9', 451 '1', '2', '3', '4', '5', '6', '7', '8', '9',
421 '-', '=', 452 '-', '=',
422 '\b', '\t', /* Backspace, Tab (Ctrl+H,Ctrl+I) */ 453 '\b', '\t', /* Backspace, Tab (Ctrl+H,Ctrl+I) */
423 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 454 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
424 '\n', 0, /* Enter, Left CTRL */ 455 '\n', 0, /* Enter, Left CTRL */
425 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 456 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
426 0, '\\', /* left shift, backslash */ 457 0, '\\', /* left shift, backslash */
427 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 458 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
428 0, '*', 0, ' ', 0, /* right shift, KP mul, left alt, space, capslock */ 459 0, '*', 0, ' ', 0, /* right shift, KP mul, left alt, space, capslock */
429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1-10 */ 460 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1-10 */
430 0, 0, /* numlock, scrollock */ 461 0, 0, /* numlock, scrollock */
431 '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', /* numeric keypad */ 462 '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', /* numeric keypad */
432 0, 0, /* padding */ 463 0, 0, /* padding */
433 0, 0, 0, /* "less" (?), F11, F12 */ 464 0, 0, 0, /* "less" (?), F11, F12 */
434 0, 0, 0, 0, 0, 0, 0, /* padding */ 465 0, 0, 0, 0, 0, 0, 0, /* padding */
435 '\n', 0, '/', 0, 0, /* KP enter, Rctrl, Ctrl, KP div, PrtSc, RAlt */ 466 '\n', 0, '/', 0, 0, /* KP enter, Rctrl, Ctrl, KP div, PrtSc, RAlt */
436 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Break, Home, Up, PgUp, Left, Right, End, Down, PgDn */ 467 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Break, Home, Up, PgUp, Left, Right, End, Down, PgDn */
437 0, 0, /* Ins, Del */ 468 0, 0, /* Ins, Del */
438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* padding */ 469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* padding */
439 0, 0, /* RWin, LWin */ 470 0, 0, /* RWin, LWin */
440 0 /* no key */ 471 0 /* no key */
441 }; 472 };
442 473
443 474
444 static void iPod_keyboard() 475 static void
476 iPod_keyboard()
445 { 477 {
446 unsigned char keybuf[128]; 478 unsigned char keybuf[128];
447 int i, nread; 479 int i, nread;
448 SDL_keysym keysym; 480 SDL_keysym keysym;
449 SDL_Event ev; 481 SDL_Event ev;
450 482
451 keysym.mod = 0; 483 keysym.mod = 0;
452 keysym.scancode = 0xff; 484 keysym.scancode = 0xff;
453 memset (&ev, 0, sizeof(SDL_Event)); 485 memset(&ev, 0, sizeof(SDL_Event));
454 486
455 nread = read (kbfd, keybuf, 128); 487 nread = read(kbfd, keybuf, 128);
456 for (i = 0; i < nread; i++) { 488 for (i = 0; i < nread; i++) {
457 char ascii = iPod_SC_keymap[keybuf[i] & 0x7f]; 489 char ascii = iPod_SC_keymap[keybuf[i] & 0x7f];
458 490
459 if (dbgout) fprintf (dbgout, "Key! %02x is %c %s", keybuf[i], ascii, (keybuf[i] & 0x80)? "up" : "down"); 491 if (dbgout)
460 492 fprintf(dbgout, "Key! %02x is %c %s", keybuf[i], ascii,
461 keysym.sym = keysym.unicode = ascii; 493 (keybuf[i] & 0x80) ? "up" : "down");
462 ev.type = (keybuf[i] & 0x80)? SDL_KEYUP : SDL_KEYDOWN; 494
463 ev.key.state = 0; 495 keysym.sym = keysym.unicode = ascii;
464 ev.key.keysym = keysym; 496 ev.type = (keybuf[i] & 0x80) ? SDL_KEYUP : SDL_KEYDOWN;
465 SDL_PushEvent (&ev); 497 ev.key.state = 0;
466 } 498 ev.key.keysym = keysym;
467 } 499 SDL_PushEvent(&ev);
468 500 }
469 static void iPod_PumpEvents (_THIS) 501 }
502
503 static void
504 iPod_PumpEvents(_THIS)
470 { 505 {
471 fd_set fdset; 506 fd_set fdset;
472 int max_fd = 0; 507 int max_fd = 0;
473 static struct timeval zero; 508 static struct timeval zero;
474 int posted; 509 int posted;
475 510
476 do { 511 do {
477 posted = 0; 512 posted = 0;
478 513
479 FD_ZERO (&fdset); 514 FD_ZERO(&fdset);
480 if (kbfd >= 0) { 515 if (kbfd >= 0) {
481 FD_SET (kbfd, &fdset); 516 FD_SET(kbfd, &fdset);
482 max_fd = kbfd; 517 max_fd = kbfd;
483 } 518 }
484 if (dbgout) fprintf (dbgout, "Selecting"); 519 if (dbgout)
485 if (select (max_fd + 1, &fdset, 0, 0, &zero) > 0) { 520 fprintf(dbgout, "Selecting");
486 if (dbgout) fprintf (dbgout, " -> match!\n"); 521 if (select(max_fd + 1, &fdset, 0, 0, &zero) > 0) {
487 iPod_keyboard(); 522 if (dbgout)
488 posted++; 523 fprintf(dbgout, " -> match!\n");
489 } 524 iPod_keyboard();
490 if (dbgout) fprintf (dbgout, "\n"); 525 posted++;
491 } while (posted); 526 }
527 if (dbgout)
528 fprintf(dbgout, "\n");
529 }
530 while (posted);
492 } 531 }
493 532
494 // enough space for 160x128x2 533 // enough space for 160x128x2
495 static char ipod_scr[160 * (128/4)]; 534 static char ipod_scr[160 * (128 / 4)];
496 535
497 #define outl(datum,addr) (*(volatile unsigned long *)(addr) = (datum)) 536 #define outl(datum,addr) (*(volatile unsigned long *)(addr) = (datum))
498 #define inl(addr) (*(volatile unsigned long *)(addr)) 537 #define inl(addr) (*(volatile unsigned long *)(addr))
499 538
500 /*** The following LCD code is taken from Linux kernel uclinux-2.4.24-uc0-ipod2, 539 /*** The following LCD code is taken from Linux kernel uclinux-2.4.24-uc0-ipod2,
501 file arch/armnommu/mach-ipod/fb.c. A few modifications have been made. ***/ 540 file arch/armnommu/mach-ipod/fb.c. A few modifications have been made. ***/
502 541
503 /* get current usec counter */ 542 /* get current usec counter */
504 static int M_timer_get_current(void) 543 static int
505 { 544 M_timer_get_current(void)
506 return inl(lcd_rtc); 545 {
546 return inl(lcd_rtc);
507 } 547 }
508 548
509 /* check if number of useconds has past */ 549 /* check if number of useconds has past */
510 static int M_timer_check(int clock_start, int usecs) 550 static int
511 { 551 M_timer_check(int clock_start, int usecs)
512 unsigned long clock; 552 {
513 clock = inl(lcd_rtc); 553 unsigned long clock;
514 554 clock = inl(lcd_rtc);
515 if ( (clock - clock_start) >= usecs ) { 555
516 return 1; 556 if ((clock - clock_start) >= usecs) {
517 } else { 557 return 1;
518 return 0; 558 } else {
519 } 559 return 0;
560 }
520 } 561 }
521 562
522 /* wait for LCD with timeout */ 563 /* wait for LCD with timeout */
523 static void M_lcd_wait_write(void) 564 static void
524 { 565 M_lcd_wait_write(void)
525 if ( (inl(lcd_base) & 0x8000) != 0 ) { 566 {
526 int start = M_timer_get_current(); 567 if ((inl(lcd_base) & 0x8000) != 0) {
527 568 int start = M_timer_get_current();
528 do { 569
529 if ( (inl(lcd_base) & (unsigned int)0x8000) == 0 ) 570 do {
530 break; 571 if ((inl(lcd_base) & (unsigned int) 0x8000) == 0)
531 } while ( M_timer_check(start, 1000) == 0 ); 572 break;
532 } 573 }
574 while (M_timer_check(start, 1000) == 0);
575 }
533 } 576 }
534 577
535 578
536 /* send LCD data */ 579 /* send LCD data */
537 static void M_lcd_send_data(int data_lo, int data_hi) 580 static void
538 { 581 M_lcd_send_data(int data_lo, int data_hi)
539 M_lcd_wait_write(); 582 {
540 583 M_lcd_wait_write();
541 outl(data_lo, lcd_base + LCD_DATA); 584
542 585 outl(data_lo, lcd_base + LCD_DATA);
543 M_lcd_wait_write(); 586
544 587 M_lcd_wait_write();
545 outl(data_hi, lcd_base + LCD_DATA); 588
589 outl(data_hi, lcd_base + LCD_DATA);
546 590
547 } 591 }
548 592
549 /* send LCD command */ 593 /* send LCD command */
550 static void 594 static void
551 M_lcd_prepare_cmd(int cmd) 595 M_lcd_prepare_cmd(int cmd)
552 { 596 {
553 M_lcd_wait_write(); 597 M_lcd_wait_write();
554 598
555 outl(0x0, lcd_base + LCD_CMD); 599 outl(0x0, lcd_base + LCD_CMD);
556 600
557 M_lcd_wait_write(); 601 M_lcd_wait_write();
558 602
559 outl(cmd, lcd_base + LCD_CMD); 603 outl(cmd, lcd_base + LCD_CMD);
560 604
561 } 605 }
562 606
563 /* send LCD command and data */ 607 /* send LCD command and data */
564 static void M_lcd_cmd_and_data(int cmd, int data_lo, int data_hi) 608 static void
565 { 609 M_lcd_cmd_and_data(int cmd, int data_lo, int data_hi)
566 M_lcd_prepare_cmd(cmd); 610 {
567 611 M_lcd_prepare_cmd(cmd);
568 M_lcd_send_data(data_lo, data_hi); 612
613 M_lcd_send_data(data_lo, data_hi);
569 } 614 }
570 615
571 // Copied from uW 616 // Copied from uW
572 static void M_update_display(int sx, int sy, int mx, int my) 617 static void
573 { 618 M_update_display(int sx, int sy, int mx, int my)
574 int y; 619 {
575 unsigned short cursor_pos; 620 int y;
576 621 unsigned short cursor_pos;
577 sx >>= 3; 622
578 mx >>= 3; 623 sx >>= 3;
579 624 mx >>= 3;
580 cursor_pos = sx + (sy << 5); 625
581 626 cursor_pos = sx + (sy << 5);
582 for ( y = sy; y <= my; y++ ) { 627
583 unsigned char *img_data; 628 for (y = sy; y <= my; y++) {
584 int x; 629 unsigned char *img_data;
585 630 int x;
586 /* move the cursor */ 631
587 M_lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff); 632 /* move the cursor */
588 633 M_lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff);
589 /* setup for printing */ 634
590 M_lcd_prepare_cmd(0x12); 635 /* setup for printing */
591 636 M_lcd_prepare_cmd(0x12);
592 img_data = ipod_scr + (sx << 1) + (y * (lcd_width/4)); 637
593 638 img_data = ipod_scr + (sx << 1) + (y * (lcd_width / 4));
594 /* loops up to 160 times */ 639
595 for ( x = sx; x <= mx; x++ ) { 640 /* loops up to 160 times */
596 /* display eight pixels */ 641 for (x = sx; x <= mx; x++) {
597 M_lcd_send_data(*(img_data + 1), *img_data); 642 /* display eight pixels */
598 643 M_lcd_send_data(*(img_data + 1), *img_data);
599 img_data += 2; 644
600 } 645 img_data += 2;
601 646 }
602 /* update cursor pos counter */ 647
603 cursor_pos += 0x20; 648 /* update cursor pos counter */
604 } 649 cursor_pos += 0x20;
650 }
605 } 651 }
606 652
607 /* get current usec counter */ 653 /* get current usec counter */
608 static int C_timer_get_current(void) 654 static int
609 { 655 C_timer_get_current(void)
610 return inl(0x60005010); 656 {
657 return inl(0x60005010);
611 } 658 }
612 659
613 /* check if number of useconds has past */ 660 /* check if number of useconds has past */
614 static int C_timer_check(int clock_start, int usecs) 661 static int
615 { 662 C_timer_check(int clock_start, int usecs)
616 unsigned long clock; 663 {
617 clock = inl(0x60005010); 664 unsigned long clock;
618 665 clock = inl(0x60005010);
619 if ( (clock - clock_start) >= usecs ) { 666
620 return 1; 667 if ((clock - clock_start) >= usecs) {
621 } else { 668 return 1;
622 return 0; 669 } else {
623 } 670 return 0;
671 }
624 } 672 }
625 673
626 /* wait for LCD with timeout */ 674 /* wait for LCD with timeout */
627 static void C_lcd_wait_write(void) 675 static void
628 { 676 C_lcd_wait_write(void)
629 if ((inl(0x70008A0C) & 0x80000000) != 0) { 677 {
630 int start = C_timer_get_current(); 678 if ((inl(0x70008A0C) & 0x80000000) != 0) {
631 679 int start = C_timer_get_current();
632 do { 680
633 if ((inl(0x70008A0C) & 0x80000000) == 0) 681 do {
634 break; 682 if ((inl(0x70008A0C) & 0x80000000) == 0)
635 } while (C_timer_check(start, 1000) == 0); 683 break;
636 } 684 }
637 } 685 while (C_timer_check(start, 1000) == 0);
638 static void C_lcd_cmd_data(int cmd, int data) 686 }
639 { 687 }
640 C_lcd_wait_write(); 688 static void
641 outl(cmd | 0x80000000, 0x70008A0C); 689 C_lcd_cmd_data(int cmd, int data)
642 690 {
643 C_lcd_wait_write(); 691 C_lcd_wait_write();
644 outl(data | 0x80000000, 0x70008A0C); 692 outl(cmd | 0x80000000, 0x70008A0C);
645 } 693
646 694 C_lcd_wait_write();
647 static void C_update_display(int sx, int sy, int mx, int my) 695 outl(data | 0x80000000, 0x70008A0C);
648 { 696 }
649 int height = (my - sy) + 1; 697
650 int width = (mx - sx) + 1; 698 static void
651 699 C_update_display(int sx, int sy, int mx, int my)
652 char *addr = SDL_VideoSurface->pixels; 700 {
653 701 int height = (my - sy) + 1;
654 if (width & 1) width++; 702 int width = (mx - sx) + 1;
655 703
656 /* start X and Y */ 704 char *addr = SDL_VideoSurface->pixels;
657 C_lcd_cmd_data(0x12, (sy & 0xff)); 705
658 C_lcd_cmd_data(0x13, (((SDL_VideoSurface->w - 1) - sx) & 0xff)); 706 if (width & 1)
659 707 width++;
660 /* max X and Y */ 708
661 C_lcd_cmd_data(0x15, (((sy + height) - 1) & 0xff)); 709 /* start X and Y */
662 C_lcd_cmd_data(0x16, (((((SDL_VideoSurface->w - 1) - sx) - width) + 1) & 0xff)); 710 C_lcd_cmd_data(0x12, (sy & 0xff));
663 711 C_lcd_cmd_data(0x13, (((SDL_VideoSurface->w - 1) - sx) & 0xff));
664 addr += sx + sy * SDL_VideoSurface->pitch; 712
665 713 /* max X and Y */
666 while (height > 0) { 714 C_lcd_cmd_data(0x15, (((sy + height) - 1) & 0xff));
667 int h, x, y, pixels_to_write; 715 C_lcd_cmd_data(0x16,
668 716 (((((SDL_VideoSurface->w - 1) - sx) - width) + 1) & 0xff));
669 pixels_to_write = (width * height) * 2; 717
670 718 addr += sx + sy * SDL_VideoSurface->pitch;
671 /* calculate how much we can do in one go */ 719
672 h = height; 720 while (height > 0) {
673 if (pixels_to_write > 64000) { 721 int h, x, y, pixels_to_write;
674 h = (64000/2) / width; 722
675 pixels_to_write = (width * h) * 2; 723 pixels_to_write = (width * height) * 2;
676 } 724
677 725 /* calculate how much we can do in one go */
678 outl(0x10000080, 0x70008A20); 726 h = height;
679 outl((pixels_to_write - 1) | 0xC0010000, 0x70008A24); 727 if (pixels_to_write > 64000) {
680 outl(0x34000000, 0x70008A20); 728 h = (64000 / 2) / width;
681 729 pixels_to_write = (width * h) * 2;
682 /* for each row */ 730 }
683 for (x = 0; x < h; x++) 731
684 { 732 outl(0x10000080, 0x70008A20);
685 /* for each column */ 733 outl((pixels_to_write - 1) | 0xC0010000, 0x70008A24);
686 for (y = 0; y < width; y += 2) { 734 outl(0x34000000, 0x70008A20);
687 unsigned two_pixels; 735
688 736 /* for each row */
689 two_pixels = addr[0] | (addr[1] << 16); 737 for (x = 0; x < h; x++) {
690 addr += 2; 738 /* for each column */
691 739 for (y = 0; y < width; y += 2) {
692 while ((inl(0x70008A20) & 0x1000000) == 0); 740 unsigned two_pixels;
693 741
694 /* output 2 pixels */ 742 two_pixels = addr[0] | (addr[1] << 16);
695 outl(two_pixels, 0x70008B00); 743 addr += 2;
696 } 744
697 745 while ((inl(0x70008A20) & 0x1000000) == 0);
698 addr += SDL_VideoSurface->w - width; 746
699 } 747 /* output 2 pixels */
700 748 outl(two_pixels, 0x70008B00);
701 while ((inl(0x70008A20) & 0x4000000) == 0); 749 }
702 750
703 outl(0x0, 0x70008A24); 751 addr += SDL_VideoSurface->w - width;
704 752 }
705 height = height - h; 753
706 } 754 while ((inl(0x70008A20) & 0x4000000) == 0);
755
756 outl(0x0, 0x70008A24);
757
758 height = height - h;
759 }
707 } 760 }
708 761
709 // Should work with photo. However, I don't have one, so I'm not sure. 762 // Should work with photo. However, I don't have one, so I'm not sure.
710 static void iPod_UpdateRects (_THIS, int nrects, SDL_Rect *rects) 763 static void
764 iPod_UpdateRects(_THIS, int nrects, SDL_Rect * rects)
711 { 765 {
712 if (SDL_VideoSurface->format->BitsPerPixel == 16) { 766 if (SDL_VideoSurface->format->BitsPerPixel == 16) {
713 C_update_display (0, 0, lcd_width, lcd_height); 767 C_update_display(0, 0, lcd_width, lcd_height);
714 } else { 768 } else {
715 int i, y, x; 769 int i, y, x;
716 for (i = 0; i < nrects; i++) { 770 for (i = 0; i < nrects; i++) {
717 SDL_Rect *r = rects + i; 771 SDL_Rect *r = rects + i;
718 if (!r) { 772 if (!r) {
719 continue; 773 continue;
720 } 774 }
721 775
722 for (y = r->y; (y < r->y + r->h) && y < lcd_height; y++) { 776 for (y = r->y; (y < r->y + r->h) && y < lcd_height; y++) {
723 for (x = r->x; (x < r->x + r->w) && x < lcd_width; x++) { 777 for (x = r->x; (x < r->x + r->w) && x < lcd_width; x++) {
724 ipod_scr[y*(lcd_width/4) + x/4] &= ~(3 << (2 * (x%4))); 778 ipod_scr[y * (lcd_width / 4) + x / 4] &=
725 ipod_scr[y*(lcd_width/4) + x/4] |= 779 ~(3 << (2 * (x % 4)));
726 (((Uint8*)(SDL_VideoSurface->pixels))[ y*SDL_VideoSurface->pitch + x ] & 3) << (2 * (x%4)); 780 ipod_scr[y * (lcd_width / 4) + x / 4] |=
727 } 781 (((Uint8 *) (SDL_VideoSurface->pixels))[y *
728 } 782 SDL_VideoSurface->
729 } 783 pitch
730 784 +
731 M_update_display (0, 0, lcd_width, lcd_height); 785 x] &
732 } 786 3) << (2 * (x % 4));
733 } 787 }
788 }
789 }
790
791 M_update_display(0, 0, lcd_width, lcd_height);
792 }
793 }
794
795 /* vi: set ts=4 sw=4 expandtab: */