/* * UTF-8 stores wide characters in UTF-32 form. */ int towide_utf8(wchar_t *wc, const char *mb, unsigned n) { wchar_t c; int nb; int lv; /* lowest legal value */ int i; const uint8_t *s = (const uint8_t *)mb; c = *s; if ((c & 0x80) == 0) { /* 7-bit ASCII */ *wc = c; return (1); } else if ((c & 0xe0) == 0xc0) { /* u80-u7ff - two bytes encoded */ nb = 2; lv = 0x80; c &= ~0xe0; } else if ((c & 0xf0) == 0xe0) { /* u800-uffff - three bytes encoded */ nb = 3; lv = 0x800; c &= ~0xf0; } else if ((c & 0xf8) == 0xf0) { /* u1000-u1fffff - four bytes encoded */ nb = 4; lv = 0x1000; c &= ~0xf8; } else { /* 5 and 6 byte encodings are not legal unicode */ werr("utf8 encoding too large (%s)", show_mb(mb)); return (-1); } if (nb > n) { werr("incomplete utf8 sequence (%s)", show_mb(mb)); return (-1); } for (i = 1; i < nb; i++) { if (((s[i]) & 0xc0) != 0x80) { werr("illegal utf8 byte (%x)", s[i]); return (-1); } c <<= 6; c |= (s[i] & 0x3f); } if (c < lv) { werr("illegal redundant utf8 encoding (%s)", show_mb(mb)); return (-1); } *wc = c; return (nb); }
/* * GB18030. This encodes as 8, 16, or 32-bits. * 7-bit values are in 1 byte, 4 byte sequences are used when * the second byte encodes 0x30-39 and all other sequences are 2 bytes. */ int towide_gb18030(wchar_t *wc, const char *mb, unsigned n) { wchar_t c; c = *(uint8_t *)mb; if ((c & 0x80) == 0) { /* 7-bit */ *wc = c; return (1); } if (n < 2) { werr("incomplete character sequence (%s)", show_mb(mb)); return (-1); } /* pull in the second byte */ c <<= 8; c |= (uint8_t)(mb[1]); if (((c & 0xff) >= 0x30) && ((c & 0xff) <= 0x39)) { if (n < 4) { werr("incomplete 4-byte character sequence (%s)", show_mb(mb)); return (-1); } c <<= 8; c |= (uint8_t)(mb[2]); c <<= 8; c |= (uint8_t)(mb[3]); *wc = c; return (4); } *wc = c; return (2); }
/* * EUC forms. EUC encodings are "variable". FreeBSD carries some additional * variable data to encode these, but we're going to treat each as independent * instead. Its the only way we can sensibly move forward. * * Note that the way in which the different EUC forms vary is how wide * CS2 and CS3 are and what the first byte of them is. */ static int towide_euc_impl(wchar_t *wc, const char *mb, unsigned n, uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width) { int i; int width = 2; wchar_t c; c = *(uint8_t *)mb; /* * All variations of EUC encode 7-bit ASCII as one byte, and use * additional bytes for more than that. */ if ((c & 0x80) == 0) { /* 7-bit */ *wc = c; return (1); } /* * All EUC variants reserve 0xa1-0xff to identify CS1, which * is always two bytes wide. Note that unused CS will be zero, * and that cannot be true because we know that the high order * bit must be set. */ if (c >= 0xa1) { width = 2; } else if (c == cs2) { width = cs2width; } else if (c == cs3) { width = cs3width; } if (n < width) { werr("incomplete character sequence (%s)", show_mb(mb)); return (-1); } for (i = 1; i < width; i++) { /* pull in the next byte */ c <<= 8; c |= (uint8_t)(mb[i]); } *wc = c; return (width); }
/* * Several encodings share a simplistic dual byte encoding. In these * forms, they all indicate that a two byte sequence is to be used if * the first byte has its high bit set. They all store this simple * encoding as a 16-bit value, although a great many of the possible * code points are not used in most character sets. This gives a possible * set of just over 32,000 valid code points. * * 0x00 - 0x7f - 1 byte encoding * 0x80 - 0x7fff - illegal * 0x8000 - 0xffff - 2 byte encoding */ static int towide_dbcs(wchar_t *wc, const char *mb, unsigned n) { wchar_t c; c = *(uint8_t *)mb; if ((c & 0x80) == 0) { /* 7-bit */ *wc = c; return (1); } if (n < 2) { werr("incomplete character sequence (%s)", show_mb(mb)); return (-1); } /* Store both bytes as a single 16-bit wide. */ c <<= 8; c |= (uint8_t)(mb[1]); *wc = c; return (2); }
/* loop inspired by yay * http://freecode.com/projects/yay */ Uint32 event_loop(void) { char caption[256]; Uint16 quit = 0; Uint32 frame = 0; int play_yuv = 0; unsigned int start_ticks = 0; while (!quit) { set_caption(caption, frame, 256); SDL_WM_SetCaption(caption, NULL); /* wait for SDL event */ if (P.mode == NONE || P.mode == MASTER) { SDL_WaitEvent(&event); } else if (P.mode == SLAVE) { if (!event_dispatcher()) { SDL_WaitEvent(&event); } } switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_SPACE: play_yuv = 1; /* play it, sam! */ while (play_yuv) { start_ticks = SDL_GetTicks(); set_caption(caption, frame, 256); SDL_WM_SetCaption( caption, NULL ); /* check for next frame existing */ if (read_frame()) { draw_frame(); /* insert delay for real time viewing */ if (SDL_GetTicks() - start_ticks < 40) SDL_Delay(40 - (SDL_GetTicks() - start_ticks)); frame++; send_message(NEXT); } else { play_yuv = 0; } /* check for any key event */ if (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) { /* stop playing */ play_yuv = 0; } } } break; case SDLK_RIGHT: /* next frame */ /* check for next frame existing */ if (read_frame()) { draw_frame(); frame++; send_message(NEXT); } break; case SDLK_LEFT: /* previous frame */ if (frame > 1) { frame--; fseek(fd, ((frame-1) * P.frame_size), SEEK_SET); if (P.diff) { fseek(P.fd2, ((frame-1) * P.frame_size), SEEK_SET); } read_frame(); draw_frame(); send_message(PREV); } break; case SDLK_UP: /* zoom in */ P.zoom++; set_zoom_rect(); screen = SDL_SetVideoMode(P.zoom_width, P.zoom_height, P.bpp, P.vflags); video_rect.w = P.zoom_width; video_rect.h = P.zoom_height; SDL_DisplayYUVOverlay(my_overlay, &video_rect); send_message(ZOOM_IN); break; case SDLK_DOWN: /* zoom out */ P.zoom--; set_zoom_rect(); screen = SDL_SetVideoMode(P.zoom_width, P.zoom_height, P.bpp, P.vflags); video_rect.w = P.zoom_width; video_rect.h = P.zoom_height; SDL_DisplayYUVOverlay(my_overlay, &video_rect); send_message(ZOOM_OUT); break; case SDLK_r: /* rewind */ if (frame > 1) { frame = 1; fseek(fd, 0, SEEK_SET); if (P.diff) { fseek(P.fd2, 0, SEEK_SET); } read_frame(); draw_frame(); send_message(REW); } break; case SDLK_g: /* display grid */ P.grid = ~P.grid; if (P.zoom < 1) P.grid = 0; draw_frame(); break; case SDLK_m: /* show mb-data on stdout */ P.mb = ~P.mb; if (P.zoom < 1) P.mb = 0; draw_frame(); break; case SDLK_F5: /* Luma data only */ P.y_only = ~P.y_only; P.cb_only = 0; P.cr_only = 0; draw_frame(); send_message(Y_ONLY); break; case SDLK_F6: /* Cb data only */ P.cb_only = ~P.cb_only; P.y_only = 0; P.cr_only = 0; draw_frame(); send_message(CB_ONLY); break; case SDLK_F7: /* Cr data only */ P.cr_only = ~P.cr_only; P.y_only = 0; P.cb_only = 0; send_message(CR_ONLY); draw_frame(); break; case SDLK_F8: /* display all color planes */ P.y_only = 0; P.cb_only = 0; P.cr_only = 0; draw_frame(); send_message(ALL_PLANES); break; case SDLK_h: /* histogram */ P.hist = ~P.hist; draw_frame(); break; case SDLK_F1: /* MASTER-mode */ if (create_message_queue()) { P.mode = MASTER; } break; case SDLK_F2: /* SLAVE-mode */ if (P.mode == MASTER) { destroy_message_queue(); } if (connect_message_queue()) { P.mode = SLAVE; } break; case SDLK_F3: /* NONE-mode */ destroy_message_queue(); P.mode = NONE; break; case SDLK_q: /* quit */ quit = 1; send_message(QUIT); break; default: break; } /* switch key */ break; case SDL_QUIT: quit = 1; break; case SDL_VIDEOEXPOSE: SDL_DisplayYUVOverlay(my_overlay, &video_rect); break; case SDL_MOUSEBUTTONDOWN: /* If the left mouse button was pressed */ if (event.button.button == SDL_BUTTON_LEFT ) { show_mb(event.button.x, event.button.y); } break; default: break; } /* switch event type */ } /* while */ return quit; }
static bool HandleClient(t_x11 *x11, int ID, t_gmx *gmx) { t_pulldown *pd; pd = gmx->pd; switch (ID) { /* File Menu */ case IDDUMPWIN: write_gmx(x11, gmx, IDDODUMP); break; case IDDODUMP: if (gmx->man->bAnimate) { hide_but(x11, gmx->man->vbox); } dump_it(gmx->man); if (gmx->man->bAnimate) { show_but(x11, gmx->man->vbox); } break; case IDCLOSE: case IDIMPORT: case IDEXPORT: ShowDlg(gmx->dlgs[edExport]); break; case IDDOEXPORT: write_sto_conf(gmx->confout, *gmx->man->top.name, &(gmx->man->top.atoms), gmx->man->x, NULL, gmx->man->molw->ePBC, gmx->man->box); break; case IDQUIT: show_mb(gmx, emQuit); break; case IDTERM: done_gmx(x11, gmx); return true; /* Edit Menu */ case IDEDITTOP: edit_file("topol.gmx"); break; case IDEDITCOORDS: edit_file("confin.gmx"); break; case IDEDITPARAMS: edit_file("mdparin.gmx"); break; /* Display Menu */ case IDFILTER: if (gmx->filter) { ShowDlg(gmx->dlgs[edFilter]); } break; case IDDOFILTER: do_filter(x11, gmx->man, gmx->filter); break; case IDANIMATE: check_pd_item(pd, IDANIMATE, toggle_animate(x11, gmx->man)); break; case IDLABELSOFF: no_labels(x11, gmx->man); break; case IDRESETVIEW: reset_view(gmx->man->view); ExposeWin(x11->disp, gmx->man->molw->wd.self); break; case IDPHOTO: show_mb(gmx, emNotImplemented); break; case IDBONDOPTS: ShowDlg(gmx->dlgs[edBonds]); break; case IDTHIN: set_bond_type(x11, gmx->man->molw, eBThin); break; case IDFAT: set_bond_type(x11, gmx->man->molw, eBFat); break; case IDVERYFAT: set_bond_type(x11, gmx->man->molw, eBVeryFat); break; case IDBALLS: set_bond_type(x11, gmx->man->molw, eBSpheres); break; case IDNOBOX: set_box_type(x11, gmx->man->molw, esbNone); break; case IDRECTBOX: set_box_type(x11, gmx->man->molw, esbRect); break; case IDTRIBOX: set_box_type(x11, gmx->man->molw, esbTri); break; case IDTOBOX: set_box_type(x11, gmx->man->molw, esbTrunc); break; /* Analysis Menu */ case IDBOND: case IDANGLE: case IDDIH: case IDRMS: case IDRDF: case IDENERGIES: case IDCORR: show_mb(gmx, emNotImplemented); break; /* Help Menu */ case IDHELP: show_mb(gmx, emHelp); break; case IDABOUT: show_logo(x11, gmx->logo); break; default: break; } return false; }