123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185 |
- /* Built with libmng-1.0.9
- * Compiled on linux with gcc-3.3.4
- * [email protected] suggested the single step mode and wrote:
- * "xmngview works on Solaris both Sparc and Intel and compiles with Sun's cc"
- *
- * <[email protected]>
- * This program my be redistributed under the terms of the
- * GNU General Public Licence, version 2, or at your preference,
- * any later version.
- *
- * For more information about libmng please visit:
- *
- * The official libmng web-site:
- * http://www.libmng.com
- *
- * Libmng on SourceForge:
- * http://libmng.sourceforge.net
- *
- * The official MNG homepage:
- * http://www.libpng.org/pub/mng
- *
- * The official PNG homepage:
- * http://www.libpng.org/pub/png
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/time.h>
- #include <ctype.h>
- #include <libmng.h>
- #include <X11/StringDefs.h>
- #include <X11/Intrinsic.h>
- #include <Xm/Xm.h>
- #include <X11/Xutil.h>
- #include <Xm/DrawingA.h>
- #include <Xm/Form.h>
- #include <Xm/PushB.h>
- #include <Xm/Frame.h>
- #include <Xm/RowColumn.h>
- #include <Xm/FileSB.h>
- #include <Xm/Label.h>
- #include <X11/extensions/XShm.h>
- #include "xmng.h"
- #define DEFAULT_BACKGROUND "grey77"
- static char version[]={"0.6"};
- static void run_viewer(FILE *reader, char *read_idf);
- static mng_handle user_handle;
- static ImageInfo img;
- static struct timeval start_tv, now_tv;
- static XtIntervalId timeout_ID;
- static char *prg_idf;
- static XtAppContext app_context;
- static Widget toplevel, main_form, canvas, file_label;
- static XmFontList file_font;
- static Dimension start_width;
- #define SLASH '/'
- /*
- * Cnf: XQueryColor(3X11)
- */
- static char *parse_rgb_color(char *val)
- {
- char *s, *d;
- int ch;
- char status, rgb_type;
- char r[6], g[6], b[6], rgb[24];
- rgb_type = 0;
- status = 1;
- s = val;
- memset(r, 0, 6);
- memset(g, 0, 6);
- memset(b, 0, 6);
- if(strncasecmp(s, "rgb:", 4) == 0)
- {
- rgb_type = 1;
- s += 4;
- if((d = strchr(s, SLASH)))
- {
- *d = 0;
- if(d - s > 4)
- s[4] = 0;
- strcpy(r, s);
- s = ++d;
- if((d = strchr(s, SLASH)))
- {
- *d = 0;
- if(d - s > 4)
- s[4] = 0;
- strcpy(g, s);
- s = d + 1;
- while((ch = *++d) && isxdigit(ch));
- *d = 0;
- if(d - s > 4)
- s[4] = 0;
- strcpy(b, s);
- }
- if(*r == 0 || *g == 0 || *b == 0)
- return NULL;
- s = r - 1;
- while((ch = *++s))
- {
- if(isxdigit(ch)) continue;
- status = rgb_type = 0;
- break;
- }
- s = g - 1;
- while((ch = *++s))
- {
- if(isxdigit(ch)) continue;
- status = rgb_type = 0;
- break;
- }
- s = b - 1;
- while((ch = *++s))
- {
- if(isxdigit(ch)) continue;
- status = rgb_type = 0;
- break;
- }
- if(status)
- {
- strcpy(rgb, "rgb:");
- d = rgb + 4;
- s = r;
- while(*s) *d++ = *s++;
- *d++ = SLASH;
- s = g;
- while(*s) *d++ = *s++;
- *d++ = SLASH;
- s = b;
- while(*s) *d++ = *s++;
- *d = 0;
- return strdup(rgb);
- }
- } /* if((slash = strchr(s, SLASH))) */
- return NULL;
- }
- s = val;
- if(*s == '#' || isdigit(*s))
- {
- if(*s != '#')
- --s;
- while((ch = *++s))
- {
- if(isxdigit(ch)) continue;
- status = 0;
- break;
- }
- if(status)
- {
- d = rgb;
- s = val;
- if(*s == '#')
- ++s;
- /*
- * #RGB (4 bits each)
- * #RRGGBB (8 bits each)
- * #RRRGGGBBB (12 bits each)
- * #RRRRGGGGBBBB (16 bits each)
- */
- if(strlen(s) > 12)
- s[12] = 0;
- *d++ = '#';
- strcpy(d, s);
- return strdup(rgb);
- }
- return NULL;
- }
- /*
- * 'white', 'LavenderBlush', 'dark slate gray', 'grey12'
- */
- s = val - 1;
- while((ch = *++s))
- {
- if(isalnum(ch) || isspace(ch)) continue;
- status = 0;
- break;
- }
- if(!status)
- return NULL;
- return strdup(val);
- }/* parse_rgb_color() */
- static void set_bg_pixel(ImageInfo *img)
- {
- XColor xcolor;
- Widget w;
- char *s, *d;
- int found;
- w = img->canvas;
- if(!img->has_bg_pixel)
- {
- if(img->has_bg_color)
- {
- s = strdup(img->bg_color);
- d = parse_rgb_color(s);
- free(s);
- if(d)
- {
- strcpy(img->bg_color, d);
- free(d);
- }
- else
- img->has_bg_color = 0;
- }
- if(!img->has_bg_color)
- {
- strcpy(img->bg_color, DEFAULT_BACKGROUND);
- img->has_bg_color = 1;
- }
- found = XParseColor(img->dpy,
- DefaultColormap(img->dpy, DefaultScreen(img->dpy)),
- img->bg_color, &xcolor);
- if(!found)
- {
- strcpy(img->bg_color, DEFAULT_BACKGROUND);
- found = XParseColor(img->dpy,
- DefaultColormap(img->dpy, DefaultScreen(img->dpy)),
- img->bg_color, &xcolor);
- }
- xcolor.flags = DoRed | DoGreen | DoBlue;
- XAllocColor(img->dpy,
- DefaultColormap(img->dpy, DefaultScreen(img->dpy)),
- &xcolor);
- }
- else
- {
- xcolor.pixel = img->bg_pixel;
- xcolor.flags = DoRed|DoGreen|DoBlue;
- found = XQueryColor(img->dpy,
- DefaultColormap(img->dpy, DefaultScreen(img->dpy)),
- &xcolor);
- }
- img->bg_pixel = xcolor.pixel;
- img->xbg_red = xcolor.red;
- img->xbg_green = xcolor.green;
- img->xbg_blue = xcolor.blue;
- img->bg_red = (unsigned char)xcolor.red&0xff;
- img->bg_green = (unsigned char)xcolor.green&0xff;
- img->bg_blue = (unsigned char)xcolor.blue&0xff;
- img->has_bg_pixel = 1;
- }/* set_bg_pixel() */
- static void fsb_cancel_cb(Widget w, XtPointer client, XtPointer call)
- {
- XtUnmanageChild(w);
- }
- void create_file_dialog(Widget w, char *button_text, char *title_text,
- void(*fsb_select_cb)(Widget,XtPointer,XtPointer))
- {
- Arg args[4];
- int cnt;
- Widget dialog;
- XmString button_str, title_str, filter;
- Widget child;
- cnt = 0;
- dialog = XmCreateFileSelectionDialog(w, "Files", args, cnt);
- XtUnmanageChild(XmFileSelectionBoxGetChild(dialog,XmDIALOG_HELP_BUTTON));
- XtAddCallback(dialog, XmNcancelCallback, fsb_cancel_cb, NULL);
- XtAddCallback(dialog, XmNokCallback, fsb_select_cb, NULL);
- button_str = XmStringCreateLocalized(button_text);
- title_str = XmStringCreateLocalized(title_text);
- filter = XmStringCreateLocalized("*.[jmp]ng");
- XtVaSetValues(dialog,
- XmNokLabelString, button_str,
- XmNdialogTitle, title_str,
- XmNpattern, filter,
- XmNfileFilterStyle, XmFILTER_NONE,
- NULL);
- XmStringFree(button_str);
- XmStringFree(title_str);
- XmStringFree(filter);
- child = XmFileSelectionBoxGetChild(dialog, XmDIALOG_FILTER_TEXT);
- XtVaSetValues(child, XmNfontList, file_font, NULL);
- child = XmFileSelectionBoxGetChild(dialog, XmDIALOG_DIR_LIST);
- XtVaSetValues(child, XmNfontList, file_font, NULL);
- child = XmFileSelectionBoxGetChild(dialog, XmDIALOG_LIST);
- XtVaSetValues(child, XmNfontList, file_font, NULL);
- child = XmFileSelectionBoxGetChild(dialog, XmDIALOG_TEXT);
- XtVaSetValues(child, XmNfontList, file_font, NULL);
- XtManageChild(dialog);
- XMapRaised(XtDisplay (dialog), XtWindow (XtParent (dialog)));
- }
- void run_mng_file_cb(Widget w, XtPointer client, XtPointer call)
- {
- XmFileSelectionBoxCallbackStruct *fsb;
- char *read_idf;
- FILE *reader;
- XtUnmanageChild(w);
- fsb = (XmFileSelectionBoxCallbackStruct *)call;
- XmStringGetLtoR(fsb->value, XmSTRING_DEFAULT_CHARSET, &read_idf);
- if(read_idf == NULL || *read_idf == 0) return;
- reader = fopen(read_idf, "r");
- if(reader == NULL)
- {
- perror(read_idf);
- fprintf(stderr, "\n\n%s: cannot open file '%s'\n\n", prg_idf, read_idf);
- return;
- }
- run_viewer(reader, read_idf);
- free(read_idf);
- }
- static void user_reset_data(void)
- {
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- timeout_ID = 0;
- mng_cleanup(&img.user_handle);
- img.read_pos = 0;
- free(img.read_buf);
- img.read_buf = NULL;
- img.read_len = 0;
- img.img_width = 0;
- img.img_height = 0;
- img.mng_bytes_per_line = 0;
- img.read_idf = NULL;
- img.frozen = 0;
- img.restarted = 0;
- img.single_step_wanted = 0;
- img.single_step_served = 0;
- XClearWindow(img.dpy, img.win);
- }
- void browse_file_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.user_handle)
- user_reset_data();
- img.stopped = 0;
- img.frozen = 0;
- img.restarted = 0;
- create_file_dialog(w, "Select", "Select MNG file", run_mng_file_cb);
- }
- void Viewer_postlude(void)
- {
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- mng_cleanup(&img.user_handle);
- if(img.reader) fclose(img.reader);
- if(img.ximage) XDestroyImage(img.ximage);
- if(img.read_buf) free(img.read_buf);
- if(img.mng_buf) free(img.mng_buf);
- if(img.dither_line) free(img.dither_line);
- if(!img.external_win && img.dpy) XtCloseDisplay(img.dpy);
- fputc('\n', stderr);
- }
- static void user_init_data(ImageInfo *img)
- {
- unsigned int depth;
- int screen;
- Display *dpy;
- dpy = img->dpy;
- screen = DefaultScreen(dpy);
- depth = DefaultDepth(dpy, screen);
- img->depth = depth;
- if(!img->visual)
- {
- img->visual = DefaultVisual(dpy, screen);
- img->gc = DefaultGC(dpy, DefaultScreen(dpy));
- }
- else
- {
- if(img->mng_buf) free(img->mng_buf);
- if(img->dither_line) free(img->dither_line);
- x11_destroy_ximage(img);
- }
- set_bg_pixel(img);
- mng_set_bgcolor(img->user_handle,
- img->xbg_red, img->xbg_green, img->xbg_blue);
- img->mng_bytes_per_line = img->img_width * img->mng_rgb_size;
- img->mng_buf = (unsigned char*)
- calloc(1, img->mng_bytes_per_line * img->img_height);
- img->dither_line = (unsigned char*)
- calloc(1, img->mng_bytes_per_line);
- if(!img->x11_init)
- {
- x11_init_color(img);
- img->x11_init = 1;
- }
- img->ximage = x11_create_ximage(img);
-
- if(img->ximage == NULL)
- {
- Viewer_postlude();
- exit(0);
- }
- }
- static void player_exit_cb(Widget w, XtPointer client, XtPointer call)
- {
- Viewer_postlude();
- exit(0);
- }
- static void player_stop_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.type != MNG_TYPE) return;
- if(!img.user_handle) return;
- if(img.stopped) return;
- user_reset_data();
- img.stopped = 1;
- }
- static void player_single_step_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.type != MNG_TYPE) return;
- if(!img.user_handle) return;
- if(img.stopped) return;
- if(img.single_step_served)
- {
- img.single_step_served = 0;
- img.frozen = 0;
- img.single_step_wanted = 1;
- return;
- }
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- timeout_ID = 0;
- img.single_step_wanted = 1;
- mng_display_resume(img.user_handle);
- }
- static void player_pause_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.type != MNG_TYPE) return;
- if(!img.user_handle) return;
- if(img.stopped) return;
- if(img.frozen) return;
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- timeout_ID = 0;
- img.frozen = 1;
- img.single_step_served = 0;
- img.single_step_wanted = 0;
- }
- static void player_resume_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.type != MNG_TYPE) return;
- if(!img.user_handle) return;
- if(img.stopped) return;
- if(!img.frozen
- && !img.single_step_served)
- return;
- img.frozen = 0;
- if(img.single_step_served
- || img.single_step_wanted)
- {
- img.single_step_served = 0;
- img.single_step_wanted = 0;
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- timeout_ID = 0;
- }
- mng_display_resume(img.user_handle);
- }
- static void player_restart_cb(Widget w, XtPointer client, XtPointer call)
- {
- if(img.type != MNG_TYPE) return;
- if(!img.user_handle) return;
- if(img.stopped) return;
- img.frozen = 1;
- if(timeout_ID) XtRemoveTimeOut(timeout_ID);
- timeout_ID = 0;
- img.frozen = 0;
- img.single_step_served = 0;
- img.single_step_wanted = 0;
- img.read_pos = 0;
- mng_reset(img.user_handle);
- img.restarted = 1;
- gettimeofday(&start_tv, NULL);
- mng_read(img.user_handle);
- mng_display(img.user_handle);
- }
- static void release_event_cb(Widget w, XtPointer client, XEvent *event,
- Boolean *cont)
- {
- Viewer_postlude();
- exit(0);
- }
- static void redraw(int type)
- {
- if((type == Expose || type == GraphicsExpose)
- && img.ximage)
- {
- XPutImage(img.dpy, img.win, img.gc, img.ximage,
- 0, 0, 0, 0, img.img_width, img.img_height);
- }
- }
- static void exposures_cb(Widget w, XtPointer client,
- XmDrawingAreaCallbackStruct *cbs)
- {
- redraw(cbs->event->xany.type);
- }
- static mng_ptr user_alloc(mng_size_t len)
- {
- return calloc(1, len + 2);
- }
- static void user_free(mng_ptr buf, mng_size_t len)
- {
- free(buf);
- }
- static mng_bool user_read(mng_handle user_handle, mng_ptr out_buf,
- mng_uint32 req_len, mng_uint32 *out_len)
- {
- mng_uint32 more;
- ImageInfo *img;
- img = (ImageInfo *)mng_get_userdata(user_handle);
- more = img->read_len - img->read_pos;
- if(more > 0
- && img->read_buf != NULL)
- {
- if(req_len < more)
- more = req_len;
- memcpy(out_buf, img->read_buf + img->read_pos, more);
- img->read_pos += more;
- *out_len = more;
- return MNG_TRUE;
- }
- return MNG_FALSE;
- }
- static mng_bool user_open_stream(mng_handle user_handle)
- {
- return MNG_TRUE;
- }
- static mng_bool user_close_stream(mng_handle user_handle)
- {
- return MNG_TRUE;
- }
- static void create_widgets(mng_uint32 width, mng_uint32 height)
- {
- Widget but_rc, but_frame, canvas_frame;
- Widget but1, but2, but3, but4, but5, but6, but7;
- toplevel = XtAppInitialize(&app_context, "xmngview", NULL, 0,
- img.argc_ptr, img.argv,
- 0, 0, 0);
- main_form = XtVaCreateManagedWidget("main_form",
- xmFormWidgetClass, toplevel,
- XmNhorizontalSpacing, SPACE_X,
- XmNverticalSpacing, SPACE_Y,
- XmNresizable, True,
- NULL);
- but_frame = XtVaCreateManagedWidget("but_frame",
- xmFrameWidgetClass, main_form,
- XmNshadowType, XmSHADOW_ETCHED_OUT,
- XmNtopAttachment, XmATTACH_FORM,
- XmNleftAttachment, XmATTACH_FORM,
- XmNrightAttachment, XmATTACH_FORM,
- XmNshadowThickness, FRAME_SHADOW_WIDTH,
- NULL);
- but_rc = XtVaCreateManagedWidget("but_rc",
- xmRowColumnWidgetClass, but_frame,
- XmNentryAlignment, XmALIGNMENT_CENTER,
- XmNorientation, XmHORIZONTAL,
- XmNpacking, XmPACK_COLUMN,
- XmNnumColumns, 1,
- XmNresizeWidth, True,
- XmNentryBorder, BUT_ENTRY_BORDER,
- NULL);
- but1 = XtVaCreateManagedWidget("Exit",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but1, XmNactivateCallback,
- player_exit_cb, (XtPointer)toplevel);
- but2 = XtVaCreateManagedWidget("Pause",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but2, XmNactivateCallback,
- player_pause_cb, (XtPointer)toplevel);
- but3 = XtVaCreateManagedWidget("GoOn",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but3, XmNactivateCallback,
- player_resume_cb, NULL);
- but4 = XtVaCreateManagedWidget("Restart",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but4, XmNactivateCallback,
- player_restart_cb, NULL);
- but5 = XtVaCreateManagedWidget("Step",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but5, XmNactivateCallback,
- player_single_step_cb, NULL);
- but6 = XtVaCreateManagedWidget("Finish",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but6, XmNactivateCallback,
- player_stop_cb, NULL);
- but7 = XtVaCreateManagedWidget("Browse",
- xmPushButtonWidgetClass, but_rc,
- NULL);
- XtAddCallback(but7, XmNactivateCallback,
- browse_file_cb, NULL);
- file_label = XtVaCreateManagedWidget("FILE: ",
- xmLabelWidgetClass, main_form,
- XmNalignment, XmALIGNMENT_BEGINNING,
- XmNtopAttachment, XmATTACH_WIDGET,
- XmNtopWidget, but_frame,
- XmNleftAttachment, XmATTACH_FORM,
- XmNrightAttachment, XmATTACH_FORM,
- NULL);
- canvas_frame = XtVaCreateManagedWidget("canvas_frame",
- xmFrameWidgetClass, main_form,
- XmNshadowType, XmSHADOW_ETCHED_OUT,
- XmNtopAttachment, XmATTACH_WIDGET,
- XmNtopWidget, file_label,
- XmNbottomAttachment, XmATTACH_FORM,
- XmNleftAttachment, XmATTACH_FORM,
- XmNrightAttachment, XmATTACH_FORM,
- NULL);
- canvas = XtVaCreateManagedWidget("canvas",
- xmDrawingAreaWidgetClass, canvas_frame,
- XmNheight, height,
- XmNwidth, width,
- NULL);
- XtAddEventHandler(canvas,
- ButtonReleaseMask|ButtonPressMask,
- False, release_event_cb, (XtPointer)toplevel);
- XtAddCallback(canvas,
- XmNexposeCallback, (XtCallbackProc)exposures_cb, (XtPointer)&img);
-
- XtRealizeWidget(toplevel);
- if(start_width == 0)
- {
- width = height = 0;
- start_width = (FRAME_SHADOW_WIDTH<<1);
- XtVaGetValues(but1, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1) + ANY_WIDTH;
- XtVaGetValues(but2, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1) + ANY_WIDTH;
- XtVaGetValues(but3, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1) + ANY_WIDTH;
- XtVaGetValues(but4, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1) + ANY_WIDTH;
- XtVaGetValues(but5, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1) + ANY_WIDTH;
- XtVaGetValues(but6, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1);
- XtVaGetValues(but7, XmNwidth, &width, NULL);
- start_width += width + (BUT_ENTRY_BORDER<<1);
- }
- img.canvas = canvas;
- img.dpy = XtDisplay(img.canvas);
- img.win = XtWindow(img.canvas);
- file_font = XmFontListAppendEntry(NULL,
- XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG,
- XmFONT_IS_FONT,
- XLoadQueryFont(img.dpy,
- "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1")));
- }
- static mng_bool user_process_header(mng_handle user_handle,
- mng_uint32 width, mng_uint32 height)
- {
- ImageInfo *img;
- Dimension cw, ch, tw, th, dh, dw, fw, fh;
- XmString xmstr;
- char *s, buf[128];
- img = (ImageInfo*)mng_get_userdata(user_handle);
- if(img->restarted)
- {
- img->restarted = 0;
- return MNG_TRUE;
- }
- img->img_width = width;
- img->img_height = height;
- if(!img->external_win)
- {
- if(!img->canvas)
- create_widgets(width, height);
- else
- {
- tw = th = fw = fh = cw = ch = 0;
- XtVaGetValues(toplevel, XmNwidth, &tw, XmNheight, &th, NULL);
- XtVaGetValues(main_form, XmNwidth, &fw, XmNheight, &fh, NULL);
- XtVaGetValues(img->canvas, XmNwidth, &cw, XmNheight, &ch, NULL);
- if(height > ch)
- {
- dh = height - ch;
- th += dh;
- fh += dh;
- } else
- if(ch > height)
- {
- dh = ch - height;
- th -= dh;
- fh -= dh;
- }
- if(width > cw)
- {
- dw = width - cw;
- tw += dw;
- fw += dw;
- } else
- if(cw > width)
- {
- if(width > start_width)
- dw = cw - width;
- else
- dw = cw - start_width;
- tw -= dw;
- fw -= dw;
- }
- if(fw < start_width)
- {
- tw = start_width + (SPACE_X<<1);
- fw = start_width;
- }
- XtVaSetValues(toplevel, XmNwidth,tw , XmNheight,th , NULL);
- XtVaSetValues(main_form, XmNwidth,fw , XmNheight,fh , NULL);
- XtVaSetValues(img->canvas, XmNwidth,width , XmNheight,height , NULL);
- }
- }
- else
- if(img->external_win)
- {
- Display *dpy;
- XtToolkitInitialize();
- app_context = XtCreateApplicationContext();
- dpy = XtOpenDisplay(app_context, NULL,NULL,"xmngview",
- NULL, 0, img->argc_ptr, img->argv);
- img->dpy = dpy;
- img->win = img->external_win;
-
- XSelectInput(dpy, img->win, ExposureMask);
- }
- user_init_data(img);
- if(img->canvas)
- {
- s = strrchr(img->read_idf, '/');
- if(s == NULL) s = img->read_idf; else ++s;
- s = strdup(s);
- if(strlen(s) > 64) s[64] = 0;
- sprintf(buf, "%s (%d x %d)", s, img->img_width, img->img_height);
- xmstr = XmStringCreateLtoR((char*)buf, XmSTRING_DEFAULT_CHARSET);
- XtVaSetValues(file_label, XmNlabelString, xmstr, NULL);
- XmStringFree(xmstr);
- free(s);
- }
- gettimeofday(&start_tv, NULL);
- return MNG_TRUE;
- }
- static void wait_cb(XtPointer client, XtIntervalId * id)
- {
- timeout_ID = 0;
- if(img.frozen
- || img.single_step_served)
- {
- // gettimeofday(&start_tv, NULL);
- timeout_ID = XtAppAddTimeOut(app_context,
- img.delay, wait_cb, NULL);
- }
- else
- {
- mng_display_resume(img.user_handle);
- }
- }
- static mng_bool user_set_timer(mng_handle user_handle, mng_uint32 delay)
- {
- ImageInfo *img;
- img = (ImageInfo*)mng_get_userdata(user_handle);
- img->delay = delay;
- timeout_ID = XtAppAddTimeOut(app_context,
- delay, wait_cb, NULL);
- return MNG_TRUE;
- }
- static mng_uint32 user_get_tick_count(mng_handle user_handle)
- {
- double sec, usec;
- mng_uint32 ticks;
- gettimeofday(&now_tv, NULL);
- sec = (double)(now_tv.tv_sec - start_tv.tv_sec);
- usec = (double)now_tv.tv_usec - (double)start_tv.tv_usec;
- ticks = (mng_uint32)(sec * 1000.0 + usec/1000.0);
- //fprintf(stderr,"TICKS %u (%f:%f)\n", ticks, sec, usec);
- return ticks;
- }
- static mng_ptr user_get_canvas_line(mng_handle user_handle, mng_uint32 line)
- {
- ImageInfo *img;
- img = (ImageInfo*)mng_get_userdata(user_handle);
- return img->mng_buf + img->mng_bytes_per_line * line;
- }
- static mng_bool user_refresh(mng_handle user_handle, mng_uint32 x,
- mng_uint32 y, mng_uint32 width, mng_uint32 height)
- {
- ImageInfo *img;
- mng_uint32 src_len;
- unsigned char *src_start, *src_buf;
- int row, max_row;
- Display *dpy;
- GC gc;
- Window win;
- XImage *ximage;
- Visual *visual;
- int have_shmem;
- img = (ImageInfo*)mng_get_userdata(user_handle);
- if(img->single_step_wanted)
- img->single_step_served = 1;
- win = img->win;
- gc = img->gc;
- dpy = img->dpy;
- ximage = img->ximage;
- visual = img->visual;
- have_shmem = img->have_shmem;
- max_row = y + height;
- row = y;
- src_len = img->mng_bytes_per_line;
- src_buf = src_start = img->mng_buf + img->mng_rgb_size * x + y * src_len;
- while(row < max_row)
- {
- viewer_renderline(img, src_start, row, x, width);
- ++row;
- src_start += src_len;
- }
- XPUTIMAGE(dpy, win, gc, ximage, x, y, x, y, width, height);
- XSync(dpy, False);
- return MNG_TRUE;
- }
- static mng_bool user_error(mng_handle user_handle, mng_int32 code,
- mng_int8 severity,
- mng_chunkid chunktype, mng_uint32 chunkseq,
- mng_int32 extra1, mng_int32 extra2, mng_pchar text)
- {
- ImageInfo *img;
- unsigned char chunk[5];
- img = (ImageInfo*)mng_get_userdata(user_handle);
- chunk[0] = (char)((chunktype >> 24) & 0xFF);
- chunk[1] = (char)((chunktype >> 16) & 0xFF);
- chunk[2] = (char)((chunktype >> 8) & 0xFF);
- chunk[3] = (char)((chunktype ) & 0xFF);
- chunk[4] = '\0';
- fprintf(stderr, "\n\n%s: error playing(%s) chunk[%d]'%s':\n",
- prg_idf, img->read_idf, chunkseq, chunk);
- fprintf(stderr, "code(%d) severity(%d) extra1(%d) extra2(%d)"
- "\ntext:'%s'\n\n", code, severity, extra1, extra2, text);
- return 0;
- }
- static mng_bool prelude(void)
- {
- #define MAXBUF 8
- unsigned char buf[MAXBUF];
-
- if(fread(buf, 1, MAXBUF, img.reader) != MAXBUF)
- {
- fprintf(stderr,"\n%s:prelude\n\tcannot read signature \n",
- prg_idf);
- return MNG_FALSE;
- }
-
- if(memcmp(buf, MNG_MAGIC, 8) == 0)
- img.type = MNG_TYPE;
- else
- if(memcmp(buf, JNG_MAGIC, 8) == 0)
- img.type = JNG_TYPE;
- else
- if(memcmp(buf, PNG_MAGIC, 8) == 0)
- img.type = PNG_TYPE;
- if(!img.type)
- {
- fprintf(stderr,"\n%s:'%s' is no MNG / JNG / PNG file\n",
- prg_idf, img.read_idf);
- return MNG_FALSE;
- }
- fseek(img.reader, 0, SEEK_SET);
- fseek(img.reader, 0, SEEK_END);
- img.read_len = ftell(img.reader);
- fseek(img.reader, 0, SEEK_SET);
- if(!img.user_handle)
- {
- user_handle = mng_initialize(&img, user_alloc, user_free, MNG_NULL);
- if(user_handle == MNG_NULL)
- {
- fprintf(stderr, "\n%s: cannot initialize libmng.\n", prg_idf);
- return MNG_FALSE;
- }
- img.user_handle = user_handle;
- mng_set_canvasstyle(user_handle, MNG_CANVAS_RGB8);
- img.mng_rgb_size = CANVAS_RGB8_SIZE;
- if(mng_setcb_openstream(user_handle, user_open_stream) != OK
- || mng_setcb_closestream(user_handle, user_close_stream) != OK
- || mng_setcb_readdata(user_handle, user_read) != OK
- || mng_setcb_settimer(user_handle, user_set_timer) != OK
- || mng_setcb_gettickcount(user_handle, user_get_tick_count) != OK
- || mng_setcb_processheader(user_handle, user_process_header) != OK
- || mng_setcb_getcanvasline(user_handle, user_get_canvas_line) != OK
- || mng_setcb_refresh(user_handle, user_refresh) != OK
- || mng_setcb_errorproc(user_handle, user_error) != OK
- )
- {
- fprintf(stderr,"\n%s: cannot set callbacks for libmng.\n",
- prg_idf);
- return MNG_FALSE;
- }
- }
- img.read_buf = (unsigned char*)calloc(1, img.read_len + 2);
- fread(img.read_buf, 1, img.read_len, img.reader);
- fclose(img.reader);
- img.reader = NULL;
- return MNG_TRUE;
- }
- static void run_viewer(FILE *reader, char *read_idf)
- {
- XEvent event;
- img.read_idf = read_idf;
- img.reader = reader;
- if(read_idf != NULL)
- {
- if(prelude() == MNG_FALSE)
- return ;
- gettimeofday(&start_tv, NULL);
- mng_read(img.user_handle);
- mng_display(img.user_handle);
- }
- if(!img.external_win)
- {
- XtAppMainLoop(app_context);
- }
- else
- while(1)
- {
- XtAppNextEvent(app_context, &event);
- redraw(event.type);
- }
- }
- static void usage(const char *prg)
- {
- const char *bar=
- "\n------------------------------------------------------------------------\n";
- fputs(bar, stderr);
- fprintf(stderr,"%s version %s\n"
- "USAGE: %s [--w WINDOW] [--bg BACKGROUND_COLOR] [FILE]\n",
- prg, version, prg);
- fputs("\twith BACKGROUND_COLOR = "
- "(\"TEXT\" | \"#RGB\" | \"rgb:R/G/B\" | \"PIXEL\")\n"
- "\te.g.\n\t(--bg \"red\" | --bg \"#ff0000\" "
- "| --bg \"rgb:ff/00/00\" | --bg \"0xf800\")\n"
- "\twith FILE=(idf.mng | idf.jng | idf.png)",stderr);
- fputs(bar, stderr);
- }
- static void shrink_name(char *buf)
- {
- char *s, *d;
- int ch;
- s = d = buf;
- while((ch = *s++))
- {
- if(isspace(ch)) continue;
- *d++ = tolower(ch);
- }
- *d = 0;
- }
- int main(int argc, char **argv)
- {
- FILE *reader;
- char *read_idf, *s;
- char *ok;
- int i;
- unsigned char has_bg_color, has_bg_pixel;
- Window external_win;
- Pixel bg_pixel;
- if((prg_idf = strrchr(argv[0], '/')) == NULL)
- prg_idf = argv[0];
- else
- ++prg_idf;
- memset(&img, 0, sizeof(ImageInfo));
- external_win = 0; read_idf = NULL; reader = NULL;
- has_bg_color = has_bg_pixel = 0;
- bg_pixel = 0;
- i = 0;
- while(++i < argc)
- {
- s = argv[i];
- if(strcmp(s, "--help") == 0
- || strcmp(s, "-help") == 0
- || *s == '?')
- {
- usage(prg_idf);
- return 0;
- }
- if(strcasecmp(s, "--w") == 0)
- {
- ++i;
- s = argv[i];
- external_win = strtoul(s, &ok, 10);
- if(*ok)
- return 0;
- continue;
- }
- if(strcasecmp(s, "--bg") == 0)
- {
- ++i;
- s = argv[i];
- if(*s == '#' || strncasecmp(s, "rgb:", 4) == 0 || isalpha(*s))
- {
- strncpy(img.bg_color, s, MAX_COLORBUF);
- img.bg_color[MAX_COLORBUF] = 0;
- has_bg_color = 1;
- if(*s != '#')
- shrink_name(img.bg_color);
- continue;
- }
- bg_pixel = strtoul(s, &ok, 16);
- if(*ok == 0)
- has_bg_pixel = 1;
- continue;
- }
- if(*s != '-')
- {
- read_idf = s; continue;
- }
- }
- if(read_idf != NULL)
- {
- reader = fopen(read_idf, "rb");
- if(reader == NULL)
- {
- perror(read_idf);
- fprintf(stderr, "\n\n%s: cannot open file '%s'\n\n", prg_idf, read_idf);
- return 0;
- }
- }
- img.argv = argv;
- img.argc_ptr = &argc;
- img.external_win = external_win;
- img.has_bg_pixel = has_bg_pixel;
- img.bg_pixel = bg_pixel;
- img.has_bg_color = has_bg_color;
- if(!has_bg_pixel && !has_bg_color)
- {
- strcpy(img.bg_color, DEFAULT_BACKGROUND);
- img.has_bg_color = 1;
- }
- if(read_idf == NULL && external_win == 0)
- create_widgets(5,5);
- run_viewer(reader, read_idf);
- Viewer_postlude();
- return 0;
- }
|