X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fapple2-main.c;h=3063b58d787f720324f9d700d7948586d0f420b0;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=facde4c0dbdf2bbadb2160030694256b7f62f460;hpb=f8cf5ac7b2f53510f80a0eaf286a25298be17bfe;p=xscreensaver diff --git a/hacks/apple2-main.c b/hacks/apple2-main.c index facde4c0..3063b58d 100644 --- a/hacks/apple2-main.c +++ b/hacks/apple2-main.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1998-2012 Jamie Zawinski +/* xscreensaver, Copyright (c) 1998-2014 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ #include "screenhack.h" #include "apple2.h" #include "textclient.h" +#include "utf8wc.h" #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -34,8 +35,6 @@ #define SCREEN_COLS 40 #define SCREEN_ROWS 24 -#define DEBUG - /* Given a bitmask, returns the position and width of the field. */ @@ -88,7 +87,7 @@ scale_image (Display *dpy, Window window, XImage *in, int x, y, i; unsigned int rpos=0, gpos=0, bpos=0; /* bitfield positions */ unsigned int rsiz=0, gsiz=0, bsiz=0; - unsigned int rmsk=0, gmsk=0, bmsk=0; + unsigned long rmsk=0, gmsk=0, bmsk=0; unsigned char spread_map[3][256]; XWindowAttributes xgwa; XColor *colors = 0; @@ -113,9 +112,7 @@ scale_image (Display *dpy, Window window, XImage *in, } else { - rmsk = xgwa.visual->red_mask; - gmsk = xgwa.visual->green_mask; - bmsk = xgwa.visual->blue_mask; + visual_rgb_masks (xgwa.screen, xgwa.visual, &rmsk, &gmsk, &bmsk); decode_mask (rmsk, &rpos, &rsiz); decode_mask (gmsk, &gpos, &gsiz); decode_mask (bmsk, &bpos, &bsiz); @@ -762,7 +759,21 @@ static void slideshow_controller(apple2_sim_t *sim, int *stepno, *stepno=10; break; + case 80: + /* Do nothing, just wait */ + *next_actiontime += 2.0; + *stepno = A2CONTROLLER_FREE; + break; + case A2CONTROLLER_FREE: + /* It is possible that still image is being loaded, + in that case mine cannot be freed, because + callback function tries to use it, so wait. + */ + if (mine->image_loading_p) { + *stepno = 80; + break; + } free(mine->render_img); free(mine->img_filename); free(mine); @@ -786,6 +797,7 @@ struct terminal_controller_data { int curparam; int cursor_x, cursor_y; int saved_x, saved_y; + int unicruds; char unicrud[7]; union { struct { unsigned int bold : 1; @@ -887,6 +899,8 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, int i; int start, end; + /* Mostly duplicated in phosphor.c */ + switch (state->escstate) { case 0: @@ -915,6 +929,9 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, } break; case 10: /* LF */ +# ifndef HAVE_FORKPTY + state->cursor_x = 0; /* No ptys on iPhone; assume CRLF. */ +# endif case 11: /* VT */ case 12: /* FF */ if (state->cursor_y < rows - 1) @@ -947,6 +964,38 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, state->curparam = 0; break; default: + + /* states 102-106 are for UTF-8 decoding */ + + if ((c & 0xE0) == 0xC0) { /* 110xxxxx - 11 bits, 2 bytes */ + state->unicruds = 1; + state->unicrud[0] = c; + state->escstate = 102; + break; + } else if ((c & 0xF0) == 0xE0) { /* 1110xxxx - 16 bits, 3 bytes */ + state->unicruds = 1; + state->unicrud[0] = c; + state->escstate = 103; + break; + } else if ((c & 0xF8) == 0xF0) { /* 11110xxx - 21 bits, 4 bytes */ + state->unicruds = 1; + state->unicrud[0] = c; + state->escstate = 104; + break; + } else if ((c & 0xFC) == 0xF8) { /* 111110xx - 26 bits, 5 bytes */ + state->unicruds = 1; + state->unicrud[0] = c; + state->escstate = 105; + break; + } else if ((c & 0xFE) == 0xFC) { /* 1111110x - 31 bits, 6 bytes */ + state->unicruds = 1; + state->unicrud[0] = c; + state->escstate = 106; + break; + } + + PRINT: + /* If the cursor is in column 39 and we print a character, then that character shows up in column 39, and the cursor is no longer visible on the screen (it's in "column 40".) If another character @@ -1021,9 +1070,13 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, state->curparam = 0; break; case '%': /* Select charset */ - /* No, I don't support UTF-8, since the apple2 font - isn't even Unicode anyway. We must still catch the - last byte, though. */ + /* @: Select default (ISO 646 / ISO 8859-1) + G: Select UTF-8 + 8: Select UTF-8 (obsolete) + + We can just ignore this and always process UTF-8, I think? + We must still catch the last byte, though. + */ case '(': case ')': /* I don't support different fonts either - see above @@ -1233,6 +1286,39 @@ a2_vt100_printc (apple2_sim_t *sim, struct terminal_controller_data *state, case 3: state->escstate = 0; break; + + case 102: + case 103: + case 104: + case 105: + case 106: + { + int total = state->escstate - 100; /* see what I did there */ + if (state->unicruds < total) { + /* Buffer more bytes of the UTF-8 sequence */ + state->unicrud[state->unicruds++] = c; + } + + if (state->unicruds >= total) { + /* Done! Convert it to ASCII and print that. */ + char *s; + state->unicrud[state->unicruds] = 0; + s = utf8_to_latin1 ((const char *) state->unicrud, True); + state->unicruds = 0; + state->escstate = 0; + if (s) { + c = s[0]; + free (s); + goto PRINT; + } else { + /* c = 0; */ + } + } + } + break; + + default: + abort(); } a2_goto(st, state->cursor_y, state->cursor_x); } @@ -1275,30 +1361,43 @@ terminal_controller(apple2_sim_t *sim, int *stepno, double *next_actiontime) mine->tc = textclient_open (mine->dpy); textclient_reshape (mine->tc, SCREEN_COLS, SCREEN_ROWS, - SCREEN_COLS, SCREEN_ROWS); + SCREEN_COLS, SCREEN_ROWS, + 0); } if (! mine->fast_p) *next_actiontime += 4.0; *stepno = 10; + + mine->last_emit_time = sim->curtime; break; case 10: + case 11: { + Bool first_line_p = (*stepno == 10); unsigned char buf[1024]; int nr,nwant; double elapsed; elapsed=sim->curtime - mine->last_emit_time; - mine->last_emit_time=sim->curtime; - nwant=elapsed*25.0; - if (elapsed>1.0) nwant=1; - if (nwant<1) nwant=1; - if (nwant>4) nwant=4; + + nwant = elapsed * 25.0; /* characters per second */ + + if (first_line_p) { + *stepno = 11; + nwant = 1; + } + + if (nwant > 40) nwant = 40; if (mine->fast_p) nwant = sizeof(buf)-1; + if (nwant <= 0) break; + + mine->last_emit_time = sim->curtime; + nr=terminal_read(mine, buf, nwant); for (i=0; isim = 0; } - return 10000; +#ifdef HAVE_MOBILE + return 0; +#else + return 5000; +#endif } static void @@ -1775,7 +1878,8 @@ apple2_reshape (Display *dpy, Window window, void *closure, unsigned int w, unsigned int h) { struct state *st = (struct state *) closure; - analogtv_reconfigure (st->sim->dec); + if (st->sim) + analogtv_reconfigure (st->sim->dec); } static Bool @@ -1783,7 +1887,8 @@ apple2_event (Display *dpy, Window window, void *closure, XEvent *event) { struct state *st = (struct state *) closure; - if (st->controller == terminal_controller && + if (st->sim && + st->controller == terminal_controller && event->xany.type == KeyPress) { terminal_keypress_handler (dpy, event, st->sim->controller_data); return True;