diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-03-02 18:34:17 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-03-02 18:34:17 +0100 |
commit | 73f77775f4919118e8403b9a33c6e29ae4a62774 (patch) | |
tree | e061f6707f57063b42e54f044aac942001f93bd2 /apps/unix | |
parent | f72e69fb6625f708845db643129273969b35383d (diff) | |
download | mupdf-73f77775f4919118e8403b9a33c6e29ae4a62774.tar.xz |
Flatten apps/ directories.
Diffstat (limited to 'apps/unix')
-rw-r--r-- | apps/unix/gs_l.xbm | 29 | ||||
-rw-r--r-- | apps/unix/x11pdf.c | 663 | ||||
-rw-r--r-- | apps/unix/ximage.c | 709 |
3 files changed, 0 insertions, 1401 deletions
diff --git a/apps/unix/gs_l.xbm b/apps/unix/gs_l.xbm deleted file mode 100644 index 85014e43..00000000 --- a/apps/unix/gs_l.xbm +++ /dev/null @@ -1,29 +0,0 @@ -#define gs_l_xbm_width 48 -#define gs_l_xbm_height 48 -#define gs_l_xbm_x_hot 0 -#define gs_l_xbm_y_hot 0 -static unsigned char gs_l_xbm_bits[] = { - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x07, 0x00, - 0x00, 0xe0, 0xff, 0x0f, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x81, 0x07, 0x00, - 0x00, 0xfc, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0xf0, 0x1f, 0x00, - 0x00, 0xff, 0x01, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0x41, 0xfc, 0x3f, 0x00, - 0x80, 0xff, 0xc8, 0xfc, 0x3f, 0x00, 0x80, 0xff, 0xd8, 0xf8, 0x3f, 0x00, - 0x80, 0xff, 0x98, 0xf0, 0x3f, 0x00, 0x80, 0xff, 0x10, 0xe0, 0x3f, 0x00, - 0x00, 0xff, 0x01, 0xc0, 0x3f, 0x00, 0x00, 0xff, 0x81, 0x81, 0x1f, 0x00, - 0x00, 0xfe, 0x83, 0x83, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x83, 0x0f, 0x00, - 0x00, 0xf8, 0x1f, 0xc3, 0x03, 0x00, 0x00, 0xe0, 0x1f, 0xe0, 0x01, 0x00, - 0x00, 0xf0, 0x1f, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xff, 0xff, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, - 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x03, - 0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x03, - 0xc0, 0x3f, 0x00, 0x00, 0xff, 0x03, 0xe0, 0x0f, 0x00, 0x00, 0xfe, 0x03, - 0xf0, 0x07, 0xfc, 0x00, 0xfc, 0x01, 0xf0, 0x07, 0x0e, 0x00, 0xff, 0x04, - 0xf0, 0x07, 0x7e, 0xe0, 0x7f, 0x02, 0xf0, 0x0f, 0xfc, 0xff, 0x1f, 0x01, - 0xe0, 0x1f, 0xf0, 0xff, 0xc3, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x78, 0x00, - 0x80, 0xff, 0x0f, 0xf8, 0x3f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00, - 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/apps/unix/x11pdf.c b/apps/unix/x11pdf.c deleted file mode 100644 index fc069e26..00000000 --- a/apps/unix/x11pdf.c +++ /dev/null @@ -1,663 +0,0 @@ -#include "fitz.h" -#include "mupdf.h" -#include "pdfapp.h" - -#include "gs_l.xbm" - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xatom.h> -#include <X11/cursorfont.h> - -#include <sys/select.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> - -#ifndef timeradd -#define timeradd(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ - if ((result)->tv_usec >= 1000000) \ - { \ - ++(result)->tv_sec; \ - (result)->tv_usec -= 1000000; \ - } \ - } while (0) -#endif - -#ifndef timersub -#define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif - -extern int ximage_init(Display *display, int screen, Visual *visual); -extern int ximage_get_depth(void); -extern Visual *ximage_get_visual(void); -extern Colormap ximage_get_colormap(void); -extern void ximage_blit(Drawable d, GC gc, int dstx, int dsty, - unsigned char *srcdata, - int srcx, int srcy, int srcw, int srch, int srcstride); - -static Display *xdpy; -static Atom XA_TARGETS; -static Atom XA_TIMESTAMP; -static Atom XA_UTF8_STRING; -static int x11fd; -static int xscr; -static Window xwin; -static GC xgc; -static XEvent xevt; -static int mapped = 0; -static Cursor xcarrow, xchand, xcwait; -static int justcopied = 0; -static int isshowingpage = 0; -static int dirty = 0; -static char *password = ""; -static XColor xbgcolor; -static XColor xshcolor; -static int reqw = 0; -static int reqh = 0; -static char copylatin1[1024 * 16] = ""; -static char copyutf8[1024 * 48] = ""; -static Time copytime; - -static pdfapp_t gapp; - -/* - * Dialog boxes - */ - -void winwarn(pdfapp_t *app, char *msg) -{ - fprintf(stderr, "mupdf: %s\n", msg); -} - -void winerror(pdfapp_t *app, fz_error error) -{ - fz_catch(error, "aborting"); - exit(1); -} - -char *winpassword(pdfapp_t *app, char *filename) -{ - char *r = password; - password = NULL; - return r; -} - -/* - * X11 magic - */ - -static void winopen(void) -{ - XWMHints *wmhints; - XClassHint *classhint; - - xdpy = XOpenDisplay(nil); - if (!xdpy) - winerror(&gapp, fz_throw("could not open display")); - - XA_TARGETS = XInternAtom(xdpy, "TARGETS", False); - XA_TIMESTAMP = XInternAtom(xdpy, "TIMESTAMP", False); - XA_UTF8_STRING = XInternAtom(xdpy, "UTF8_STRING", False); - - xscr = DefaultScreen(xdpy); - - ximage_init(xdpy, xscr, DefaultVisual(xdpy, xscr)); - - xcarrow = XCreateFontCursor(xdpy, XC_left_ptr); - xchand = XCreateFontCursor(xdpy, XC_hand2); - xcwait = XCreateFontCursor(xdpy, XC_watch); - - xbgcolor.red = 0x7000; - xbgcolor.green = 0x7000; - xbgcolor.blue = 0x7000; - - xshcolor.red = 0x4000; - xshcolor.green = 0x4000; - xshcolor.blue = 0x4000; - - XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xbgcolor); - XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xshcolor); - - xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy), - 10, 10, 200, 100, 1, - ximage_get_depth(), - InputOutput, - ximage_get_visual(), - 0, - nil); - - XSetWindowColormap(xdpy, xwin, ximage_get_colormap()); - XSelectInput(xdpy, xwin, - StructureNotifyMask | ExposureMask | KeyPressMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask); - - mapped = 0; - - xgc = XCreateGC(xdpy, xwin, 0, nil); - - XDefineCursor(xdpy, xwin, xcarrow); - - wmhints = XAllocWMHints(); - if (wmhints) - { - wmhints->flags = IconPixmapHint; - wmhints->icon_pixmap = XCreateBitmapFromData(xdpy, xwin, - (char *) gs_l_xbm_bits, gs_l_xbm_width, gs_l_xbm_height); - if (wmhints->icon_pixmap) - { - XSetWMHints(xdpy, xwin, wmhints); - } - XFree(wmhints); - } - - classhint = XAllocClassHint(); - if (classhint) - { - classhint->res_name = "mupdf"; - classhint->res_class = "MuPDF"; - XSetClassHint(xdpy, xwin, classhint); - XFree(classhint); - } - - x11fd = ConnectionNumber(xdpy); -} - -void wincursor(pdfapp_t *app, int curs) -{ - if (curs == ARROW) - XDefineCursor(xdpy, xwin, xcarrow); - if (curs == HAND) - XDefineCursor(xdpy, xwin, xchand); - if (curs == WAIT) - XDefineCursor(xdpy, xwin, xcwait); - XFlush(xdpy); -} - -void wintitle(pdfapp_t *app, char *s) -{ -#ifdef X_HAVE_UTF8_STRING - Xutf8SetWMProperties(xdpy, xwin, s, s, nil, 0, nil, nil, nil); -#else - XmbSetWMProperties(xdpy, xwin, s, s, nil, 0, nil, nil, nil); -#endif -} - -void winconvert(pdfapp_t *app, fz_pixmap *image) -{ - /* never mind */ -} - -void winresize(pdfapp_t *app, int w, int h) -{ - XWindowChanges values; - int mask; - - mask = CWWidth | CWHeight; - values.width = w; - values.height = h; - XConfigureWindow(xdpy, xwin, mask, &values); - - reqw = w; - reqh = h; - - if (!mapped) - { - gapp.winw = w; - gapp.winh = h; - - XMapWindow(xdpy, xwin); - XFlush(xdpy); - - while (1) - { - XNextEvent(xdpy, &xevt); - if (xevt.type == MapNotify) - break; - } - - XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr)); - XFillRectangle(xdpy, xwin, xgc, 0, 0, gapp.image->w, gapp.image->h); - XFlush(xdpy); - - mapped = 1; - } -} - -static void fillrect(int x, int y, int w, int h) -{ - if (w > 0 && h > 0) - XFillRectangle(xdpy, xwin, xgc, x, y, w, h); -} - -static void invertcopyrect() -{ - unsigned *p; - int x, y; - - int x0 = gapp.selr.x0 - gapp.panx; - int x1 = gapp.selr.x1 - gapp.panx; - int y0 = gapp.selr.y0 - gapp.pany; - int y1 = gapp.selr.y1 - gapp.pany; - - x0 = CLAMP(x0, 0, gapp.image->w - 1); - x1 = CLAMP(x1, 0, gapp.image->w - 1); - y0 = CLAMP(y0, 0, gapp.image->h - 1); - y1 = CLAMP(y1, 0, gapp.image->h - 1); - - for (y = y0; y < y1; y++) - { - p = (unsigned *)(gapp.image->samples + (y * gapp.image->w + x0) * 4); - for (x = x0; x < x1; x++) - { - *p = ~0 - *p; - p ++; - } - } - - justcopied = 1; -} - -static void winblit(pdfapp_t *app) -{ - int x0 = gapp.panx; - int y0 = gapp.pany; - int x1 = gapp.panx + gapp.image->w; - int y1 = gapp.pany + gapp.image->h; - - XSetForeground(xdpy, xgc, xbgcolor.pixel); - fillrect(0, 0, x0, gapp.winh); - fillrect(x1, 0, gapp.winw - x1, gapp.winh); - fillrect(0, 0, gapp.winw, y0); - fillrect(0, y1, gapp.winw, gapp.winh - y1); - - XSetForeground(xdpy, xgc, xshcolor.pixel); - fillrect(x0+2, y1, gapp.image->w, 2); - fillrect(x1, y0+2, 2, gapp.image->h); - - if (gapp.iscopying || justcopied) - invertcopyrect(); - - ximage_blit(xwin, xgc, - x0, y0, - gapp.image->samples, - 0, 0, - gapp.image->w, - gapp.image->h, - gapp.image->w * gapp.image->n); - - if (gapp.iscopying || justcopied) - invertcopyrect(); -} - -void winrepaint(pdfapp_t *app) -{ - dirty = 1; -} - -static void windrawstring(pdfapp_t *app, char *s, int x, int y) -{ - int prevfunction; - XGCValues xgcv; - - XGetGCValues(xdpy, xgc, GCFunction, &xgcv); - prevfunction = xgcv.function; - xgcv.function = GXxor; - XChangeGC(xdpy, xgc, GCFunction, &xgcv); - - XSetForeground(xdpy, xgc, WhitePixel(xdpy, DefaultScreen(xdpy))); - - XDrawString(xdpy, xwin, xgc, x, y, s, strlen(s)); - XFlush(xdpy); - - XGetGCValues(xdpy, xgc, GCFunction, &xgcv); - xgcv.function = prevfunction; - XChangeGC(xdpy, xgc, GCFunction, &xgcv); -} - -static void windrawpageno(pdfapp_t *app) -{ - char s[100]; - - int ret = snprintf(s, 100, "Page %d/%d", gapp.pageno, gapp.pagecount); - if (ret >= 0) - { - isshowingpage = 1; - windrawstring(&gapp, s, 10, 20); - } -} - -void windocopy(pdfapp_t *app) -{ - unsigned short copyucs2[16 * 1024]; - char *latin1 = copylatin1; - char *utf8 = copyutf8; - unsigned short *ucs2; - int ucs; - - pdfapp_oncopy(&gapp, copyucs2, 16 * 1024); - - for (ucs2 = copyucs2; ucs2[0] != 0; ucs2++) - { - ucs = ucs2[0]; - - utf8 += runetochar(utf8, &ucs); - - if (ucs < 256) - *latin1++ = ucs; - else - *latin1++ = '?'; - } - - *utf8 = 0; - *latin1 = 0; - - printf("oncopy utf8=%zd latin1=%zd\n", strlen(copyutf8), strlen(copylatin1)); - - XSetSelectionOwner(xdpy, XA_PRIMARY, xwin, copytime); - - justcopied = 1; -} - -void onselreq(Window requestor, Atom selection, Atom target, Atom property, Time time) -{ - XEvent nevt; - - printf("onselreq\n"); - - if (property == None) - property = target; - - nevt.xselection.type = SelectionNotify; - nevt.xselection.send_event = True; - nevt.xselection.display = xdpy; - nevt.xselection.requestor = requestor; - nevt.xselection.selection = selection; - nevt.xselection.target = target; - nevt.xselection.property = property; - nevt.xselection.time = time; - - if (target == XA_TARGETS) - { - Atom atomlist[4]; - atomlist[0] = XA_TARGETS; - atomlist[1] = XA_TIMESTAMP; - atomlist[2] = XA_STRING; - atomlist[3] = XA_UTF8_STRING; - printf(" -> targets\n"); - XChangeProperty(xdpy, requestor, property, target, - 32, PropModeReplace, - (unsigned char *)atomlist, sizeof(atomlist)/sizeof(Atom)); - } - - else if (target == XA_STRING) - { - printf(" -> string %zd\n", strlen(copylatin1)); - XChangeProperty(xdpy, requestor, property, target, - 8, PropModeReplace, - (unsigned char *)copylatin1, strlen(copylatin1)); - } - - else if (target == XA_UTF8_STRING) - { - printf(" -> utf8string\n"); - XChangeProperty(xdpy, requestor, property, target, - 8, PropModeReplace, - (unsigned char *)copyutf8, strlen(copyutf8)); - } - - else - { - printf(" -> unknown\n"); - nevt.xselection.property = None; - } - - XSendEvent(xdpy, requestor, False, SelectionNotify, &nevt); -} - -void winopenuri(pdfapp_t *app, char *buf) -{ - char *browser = getenv("BROWSER"); - if (!browser) - browser = "open"; - if (fork() == 0) - execlp(browser, browser, buf, (char*)0); -} - -static void onkey(int c) -{ - if (justcopied) - { - justcopied = 0; - winrepaint(&gapp); - } - - if (c == 'P') - windrawpageno(&gapp); - else if (c == 'q') - exit(0); - else - pdfapp_onkey(&gapp, c); -} - -static void onmouse(int x, int y, int btn, int modifiers, int state) -{ - if (state != 0 && justcopied) - { - justcopied = 0; - winrepaint(&gapp); - } - - pdfapp_onmouse(&gapp, x, y, btn, modifiers, state); -} - -static void usage(void) -{ - fprintf(stderr, "usage: mupdf [-d password] [-z zoom%%] [-p pagenumber] file.pdf\n"); - exit(1); -} - -static void winawaitevent(struct timeval *tmo, struct timeval *tmo_at) -{ - if (tmo_at->tv_sec == 0 && tmo_at->tv_usec == 0 && - tmo->tv_sec == 0 && tmo->tv_usec == 0) - XNextEvent(xdpy, &xevt); - else - { - fd_set fds; - struct timeval now; - - FD_ZERO(&fds); - FD_SET(x11fd, &fds); - - if (select(x11fd + 1, &fds, nil, nil, tmo)) - { - gettimeofday(&now, nil); - timersub(tmo_at, &now, tmo); - XNextEvent(xdpy, &xevt); - } - } -} - -static void winsettmo(struct timeval *tmo, struct timeval *tmo_at) -{ - struct timeval now; - - tmo->tv_sec = 2; - tmo->tv_usec = 0; - - gettimeofday(&now, nil); - timeradd(&now, tmo, tmo_at); -} - -static void winresettmo(struct timeval *tmo, struct timeval *tmo_at) -{ - tmo->tv_sec = 0; - tmo->tv_usec = 0; - - tmo_at->tv_sec = 0; - tmo_at->tv_usec = 0; -} - -int main(int argc, char **argv) -{ - char *filename; - int c; - int len; - char buf[128]; - KeySym keysym; - int oldx = 0; - int oldy = 0; - int zoom = 100; - int pageno = 1; - int wasshowingpage; - struct timeval tmo, tmo_at; - - while ((c = fz_getopt(argc, argv, "d:z:p:")) != -1) - { - switch (c) - { - case 'd': password = fz_optarg; break; - case 'z': zoom = atoi(fz_optarg); break; - case 'p': pageno = atoi(fz_optarg); break; - default: usage(); - } - } - - if (zoom < 100) - zoom = 100; - if (zoom > 300) - zoom = 300; - - if (argc - fz_optind == 0) - usage(); - - filename = argv[fz_optind++]; - - fz_cpudetect(); - fz_accelerate(); - - winopen(); - - pdfapp_init(&gapp); - gapp.scrw = DisplayWidth(xdpy, xscr); - gapp.scrh = DisplayHeight(xdpy, xscr); - gapp.zoom = zoom / 100.0; - gapp.pageno = pageno; - - pdfapp_open(&gapp, filename); - - winresettmo(&tmo, &tmo_at); - - while (1) - { - do - { - winawaitevent(&tmo, &tmo_at); - - if (tmo_at.tv_sec != 0 && tmo_at.tv_usec != 0 && - tmo.tv_sec == 0 && tmo.tv_usec == 0) - { - /* redraw page */ - winblit(&gapp); - isshowingpage = 0; - winresettmo(&tmo, &tmo_at); - continue; - } - - switch (xevt.type) - { - case Expose: - dirty = 1; - break; - - case ConfigureNotify: - if (gapp.image) - { - if (xevt.xconfigure.width != reqw || - xevt.xconfigure.height != reqh) - gapp.shrinkwrap = 0; - } - pdfapp_onresize(&gapp, - xevt.xconfigure.width, - xevt.xconfigure.height); - break; - - case KeyPress: - wasshowingpage = isshowingpage; - - len = XLookupString(&xevt.xkey, buf, sizeof buf, &keysym, nil); - if (len) - onkey(buf[0]); - onmouse(oldx, oldy, 0, 0, 0); - - if (dirty) - { - winblit(&gapp); - dirty = 0; - if (isshowingpage) - { - isshowingpage = 0; - winresettmo(&tmo, &tmo_at); - } - } - - if (!wasshowingpage && isshowingpage) - winsettmo(&tmo, &tmo_at); - - break; - - case MotionNotify: - oldx = xevt.xbutton.x; - oldy = xevt.xbutton.y; - onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 0); - break; - - case ButtonPress: - onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 1); - break; - - case ButtonRelease: - copytime = xevt.xbutton.time; - onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, -1); - break; - - case SelectionRequest: - onselreq(xevt.xselectionrequest.requestor, - xevt.xselectionrequest.selection, - xevt.xselectionrequest.target, - xevt.xselectionrequest.property, - xevt.xselectionrequest.time); - break; - } - } - while (XPending(xdpy)); - - if (dirty) - { - winblit(&gapp); - dirty = 0; - if (isshowingpage) - { - isshowingpage = 0; - winresettmo(&tmo, &tmo_at); - } - } - } - - pdfapp_close(&gapp); - - return 0; -} - diff --git a/apps/unix/ximage.c b/apps/unix/ximage.c deleted file mode 100644 index 90116026..00000000 --- a/apps/unix/ximage.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * Blit ARGB images to X with X(Shm)Images - */ - -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 1 -#endif - -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 1 -#endif - -#include <fitz.h> - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> - -extern int ffs(int); - -typedef void (*ximage_convert_func_t) -( - const unsigned char *src, - int srcstride, - unsigned char *dst, - int dststride, - int w, - int h - ); - -#define POOLSIZE 4 -#define WIDTH 256 -#define HEIGHT 256 - -enum { - ARGB8888, - BGRA8888, - RGBA8888, - ABGR8888, - RGB888, - BGR888, - RGB565, - RGB565_BR, - RGB555, - RGB555_BR, - BGR233, - UNKNOWN -}; - -static char *modename[] = { - "ARGB8888", - "BGRA8888", - "RGBA8888", - "ABGR8888", - "RGB888", - "BGR888", - "RGB565", - "RGB565_BR", - "RGB555", - "RGB555_BR", - "BGR233", - "UNKNOWN" -}; - -extern ximage_convert_func_t ximage_convert_funcs[]; - -static struct -{ - Display *display; - int screen; - XVisualInfo visual; - Colormap colormap; - - int bitsperpixel; - int mode; - - XColor rgbcube[256]; - - ximage_convert_func_t convert_func; - - int useshm; - int shmcode; - XImage *pool[POOLSIZE]; - /* MUST exist during the lifetime of the shared ximage according to the - xc/doc/hardcopy/Xext/mit-shm.PS.gz */ - XShmSegmentInfo shminfo[POOLSIZE]; - int lastused; -} info; - -static XImage * -createximage(Display *dpy, Visual *vis, XShmSegmentInfo *xsi, int depth, int w, int h) -{ - XImage *img; - Status status; - - if (!XShmQueryExtension(dpy)) goto fallback; - - img = XShmCreateImage(dpy, vis, depth, ZPixmap, nil, xsi, w, h); - if (!img) - { - fprintf(stderr, "warn: could not XShmCreateImage\n"); - goto fallback; - } - - xsi->shmid = shmget(IPC_PRIVATE, - img->bytes_per_line * img->height, - IPC_CREAT | 0777); - if (xsi->shmid < 0) - { - XDestroyImage(img); - fprintf(stderr, "warn: could not shmget\n"); - goto fallback; - } - - img->data = xsi->shmaddr = shmat(xsi->shmid, nil, 0); - if (img->data == (char*)-1) - { - XDestroyImage(img); - fprintf(stderr, "warn: could not shmat\n"); - goto fallback; - } - - xsi->readOnly = False; - status = XShmAttach(dpy, xsi); - if (!status) - { - shmdt(xsi->shmaddr); - XDestroyImage(img); - fprintf(stderr, "warn: could not XShmAttach\n"); - goto fallback; - } - - XSync(dpy, False); - - shmctl(xsi->shmid, IPC_RMID, nil); - - return img; - -fallback: - info.useshm = 0; - - img = XCreateImage(dpy, vis, depth, ZPixmap, 0, nil, w, h, 32, 0); - if (!img) - { - fprintf(stderr, "fail: could not XCreateImage"); - abort(); - } - - img->data = malloc(h * img->bytes_per_line); - if (!img->data) - { - fprintf(stderr, "fail: could not malloc"); - abort(); - } - - return img; -} - -static void -make_colormap(void) -{ - if (info.visual.class == PseudoColor && info.visual.depth == 8) - { - int i, r, g, b; - i = 0; - for (b = 0; b < 4; b++) { - for (g = 0; g < 8; g++) { - for (r = 0; r < 8; r++) { - info.rgbcube[i].pixel = i; - info.rgbcube[i].red = (r * 36) << 8; - info.rgbcube[i].green = (g * 36) << 8; - info.rgbcube[i].blue = (b * 85) << 8; - info.rgbcube[i].flags = - DoRed | DoGreen | DoBlue; - i++; - } - } - } - info.colormap = XCreateColormap(info.display, - RootWindow(info.display, info.screen), - info.visual.visual, - AllocAll); - XStoreColors(info.display, info.colormap, info.rgbcube, 256); - return; - } - else if (info.visual.class == TrueColor) - { - info.colormap = 0; - return; - } - fprintf(stderr, "Cannot handle visual class %d with depth: %d\n", - info.visual.class, info.visual.depth); - return; -} - -static void -select_mode(void) -{ - - int byteorder; - int byterev; - unsigned long rm, gm, bm; - unsigned long rs, gs, bs; - - byteorder = ImageByteOrder(info.display); -#if BYTE_ORDER == BIG_ENDIAN - byterev = byteorder != MSBFirst; -#else - byterev = byteorder != LSBFirst; -#endif - - rm = info.visual.red_mask; - gm = info.visual.green_mask; - bm = info.visual.blue_mask; - - rs = ffs(rm) - 1; - gs = ffs(gm) - 1; - bs = ffs(bm) - 1; - - printf("ximage: mode %d/%d %08lx %08lx %08lx (%ld,%ld,%ld) %s%s\n", - info.visual.depth, - info.bitsperpixel, - rm, gm, bm, rs, gs, bs, - byteorder == MSBFirst ? "msb" : "lsb", - byterev ? " <swap>":""); - - info.mode = UNKNOWN; - if (info.bitsperpixel == 8) { - /* Either PseudoColor with BGR233 colormap, or TrueColor */ - info.mode = BGR233; - } - else if (info.bitsperpixel == 16) { - if (rm == 0xF800 && gm == 0x07E0 && bm == 0x001F) - info.mode = !byterev ? RGB565 : RGB565_BR; - if (rm == 0x7C00 && gm == 0x03E0 && bm == 0x001F) - info.mode = !byterev ? RGB555 : RGB555_BR; - } - else if (info.bitsperpixel == 24) { - if (rs == 0 && gs == 8 && bs == 16) - info.mode = byteorder == MSBFirst ? RGB888 : BGR888; - if (rs == 16 && gs == 8 && bs == 0) - info.mode = byteorder == MSBFirst ? BGR888 : RGB888; - } - else if (info.bitsperpixel == 32) { - if (rs == 0 && gs == 8 && bs == 16) - info.mode = byteorder == MSBFirst ? ABGR8888 : RGBA8888; - if (rs == 8 && gs == 16 && bs == 24) - info.mode = byteorder == MSBFirst ? BGRA8888 : ARGB8888; - if (rs == 16 && gs == 8 && bs == 0) - info.mode = byteorder == MSBFirst ? ARGB8888 : BGRA8888; - if (rs == 24 && gs == 16 && bs == 8) - info.mode = byteorder == MSBFirst ? RGBA8888 : ABGR8888; - } - - printf("ximage: ARGB8888 to %s\n", modename[info.mode]); - - /* select conversion function */ - info.convert_func = ximage_convert_funcs[info.mode]; -} - -static int -create_pool(void) -{ - int i; - - info.lastused = 0; - - for (i = 0; i < POOLSIZE; i++) { - info.pool[i] = nil; - } - - for (i = 0; i < POOLSIZE; i++) { - info.pool[i] = createximage(info.display, - info.visual.visual, &info.shminfo[i], info.visual.depth, - WIDTH, HEIGHT); - if (info.pool[i] == nil) { - return 0; - } - } - - return 1; -} - -static XImage * -next_pool_image(void) -{ - if (info.lastused + 1 >= POOLSIZE) { - if (info.useshm) - XSync(info.display, False); - else - XFlush(info.display); - info.lastused = 0; - } - return info.pool[info.lastused ++]; -} - -static int -ximage_error_handler(Display *display, XErrorEvent *event) -{ - /* Turn off shared memory images if we get an error from the MIT-SHM extension */ - if (event->request_code == info.shmcode) - { - char buf[80]; - XGetErrorText(display, event->error_code, buf, sizeof buf); - printf("ximage: disabling shared memory extension: %s\n", buf); - info.useshm = 0; - return 0; - } - - XSetErrorHandler(NULL); - return (XSetErrorHandler(ximage_error_handler))(display, event); -} - -int -ximage_init(Display *display, int screen, Visual *visual) -{ - XVisualInfo template; - XVisualInfo *visuals; - int nvisuals; - XPixmapFormatValues *formats; - int nformats; - int ok; - int i; - int major; - int event; - int error; - - info.display = display; - info.screen = screen; - info.colormap = 0; - - /* Get XVisualInfo for this visual */ - template.visualid = XVisualIDFromVisual(visual); - visuals = XGetVisualInfo(display, VisualIDMask, &template, &nvisuals); - if (nvisuals != 1) { - fprintf(stderr, "Visual not found!\n"); - XFree(visuals); - return 0; - } - memcpy(&info.visual, visuals, sizeof (XVisualInfo)); - XFree(visuals); - - /* Get appropriate PixmapFormat for this visual */ - formats = XListPixmapFormats(info.display, &nformats); - for (i = 0; i < nformats; i++) { - if (formats[i].depth == info.visual.depth) { - info.bitsperpixel = formats[i].bits_per_pixel; - break; - } - } - XFree(formats); - if (i == nformats) { - fprintf(stderr, "PixmapFormat not found!\n"); - return 0; - } - - /* extract mode */ - select_mode(); - - /* prepare colormap */ - make_colormap(); - - /* identify code for MIT-SHM extension */ - if (XQueryExtension(display, "MIT-SHM", &major, &event, &error) && - XShmQueryExtension(display)) - info.shmcode = major; - - /* intercept errors looking for SHM code */ - XSetErrorHandler(ximage_error_handler); - - /* prepare pool of XImages */ - info.useshm = 1; - ok = create_pool(); - if (!ok) - return 0; - - printf("ximage: %sPutImage\n", info.useshm ? "XShm" : "X"); - - return 1; -} - -int -ximage_get_depth(void) -{ - return info.visual.depth; -} - -Visual * -ximage_get_visual(void) -{ - return info.visual.visual; -} - -Colormap -ximage_get_colormap(void) -{ - return info.colormap; -} - -void -ximage_blit(Drawable d, GC gc, - int dstx, int dsty, - unsigned char *srcdata, - int srcx, int srcy, - int srcw, int srch, - int srcstride) -{ - XImage *image; - int ax, ay; - int w, h; - unsigned char *srcptr; - - for (ay = 0; ay < srch; ay += HEIGHT) - { - h = MIN(srch - ay, HEIGHT); - for (ax = 0; ax < srcw; ax += WIDTH) - { - w = MIN(srcw - ax, WIDTH); - - image = next_pool_image(); - - srcptr = srcdata + - (ay + srcy) * srcstride + - (ax + srcx) * 4; - - info.convert_func(srcptr, srcstride, - (unsigned char *) image->data, - image->bytes_per_line, w, h); - - if (info.useshm) - { - XShmPutImage(info.display, d, gc, image, - 0, 0, dstx + ax, dsty + ay, - w, h, False); - } - else - { - XPutImage(info.display, d, gc, image, - 0, 0, - dstx + ax, - dsty + ay, - w, h); - } - } - } -} - -/* - * Primitive conversion functions - */ - -#ifndef restrict -#ifndef _C99 -#ifdef __GNUC__ -#define restrict __restrict__ -#else -#define restrict -#endif -#endif -#endif - -#define PARAMS \ - const unsigned char * restrict src, \ - int srcstride, \ - unsigned char * restrict dst, \ - int dststride, \ - int w, \ - int h - -/* - * Convert byte:ARGB8888 to various formats - */ - -static void -ximage_convert_argb8888(PARAMS) -{ - int x, y; - unsigned * restrict s = (unsigned *)src; - unsigned * restrict d = (unsigned *)dst; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - d[x] = s[x]; - } - d += dststride>>2; - s += srcstride>>2; - } -} - -static void -ximage_convert_bgra8888(PARAMS) -{ - int x, y; - unsigned * restrict s = (unsigned *)src; - unsigned * restrict d = (unsigned *)dst; - unsigned val; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - val = s[x]; - d[x] = - (val >> 24) | - ((val >> 8) & 0xff00) | - (val << 24) | - ((val << 8) & 0xff0000); - /* - d[x] = - (((val >> 24) & 0xff) << 0) | - (((val >> 16) & 0xff) << 8) | - (((val >> 8) & 0xff) << 16) | - (((val >> 0) & 0xff) << 24); - */ - } - d += dststride>>2; - s += srcstride>>2; - } -} - -/* following have yet to receive some MMX love ;-) */ - -static void -ximage_convert_abgr8888(PARAMS) -{ - int x, y; - unsigned * restrict s = (unsigned *)src; - unsigned * restrict d = (unsigned *)dst; - unsigned val; - - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - val = s[x]; -#if 1 /* FZ_MSB */ - d[x] = (val & 0xff00ff00) | - (((val << 16) | (val >> 16)) & 0x00ff00ff); -#else /* FZ_LSB */ - d[x] = (val << 24) | ((val >> 8) & 0xff); -#endif - } - d += dststride>>2; - s += srcstride>>2; - } -} - -static void -ximage_convert_rgba8888(PARAMS) -{ - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - dst[x * 4 + 0] = src[x * 4 + 1]; - dst[x * 4 + 1] = src[x * 4 + 2]; - dst[x * 4 + 2] = src[x * 4 + 3]; - dst[x * 4 + 3] = src[x * 4 + 0]; - } - dst += dststride; - src += srcstride; - } -} - -static void -ximage_convert_bgr888(PARAMS) -{ - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - dst[3*x + 0] = src[4*x + 3]; - dst[3*x + 1] = src[4*x + 2]; - dst[3*x + 2] = src[4*x + 1]; - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_rgb888(PARAMS) -{ - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - dst[3*x + 0] = src[4*x + 1]; - dst[3*x + 1] = src[4*x + 2]; - dst[3*x + 2] = src[4*x + 3]; - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_rgb565(PARAMS) -{ - unsigned char r, g, b; - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - r = src[4*x + 1]; - g = src[4*x + 2]; - b = src[4*x + 3]; - ((unsigned short *)dst)[x] = - ((r & 0xF8) << 8) | - ((g & 0xFC) << 3) | - (b >> 3); - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_rgb565_br(PARAMS) -{ - unsigned char r, g, b; - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - r = src[4*x + 1]; - g = src[4*x + 2]; - b = src[4*x + 3]; - /* final word is: - g4 g3 g2 b7 b6 b5 b4 b3 r7 r6 r5 r4 r3 g7 g6 g5 - */ - ((unsigned short *)dst)[x] = - (r & 0xF8) | - ((g & 0xE0) >> 5) | - ((g & 0x1C) << 11) | - ((b & 0xF8) << 5); - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_rgb555(PARAMS) -{ - unsigned char r, g, b; - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - r = src[4*x + 1]; - g = src[4*x + 2]; - b = src[4*x + 3]; - ((unsigned short *)dst)[x] = - ((r & 0xF8) << 7) | - ((g & 0xF8) << 2) | - (b >> 3); - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_rgb555_br(PARAMS) -{ - unsigned char r, g, b; - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - r = src[4*x + 1]; - g = src[4*x + 2]; - b = src[4*x + 3]; - /* final word is: - g5 g4 g3 b7 b6 b5 b4 b3 0 r7 r6 r5 r4 r3 g7 g6 - */ - ((unsigned short *)dst)[x] = - ((r & 0xF8) >> 1) | - ((g & 0xC0) >> 6) | - ((g & 0x38) << 10) | - ((b & 0xF8) << 5); - } - src += srcstride; - dst += dststride; - } -} - -static void -ximage_convert_bgr233(PARAMS) -{ - unsigned char r, g, b; - int x,y; - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) { - r = src[4*x + 1]; - g = src[4*x + 2]; - b = src[4*x + 3]; - /* format: b7 b6 g7 g6 g5 r7 r6 r5 */ - dst[x] = (b&0xC0) | ((g>>2)&0x38) | ((r>>5)&0x7); - } - src += srcstride; - dst += dststride; - } -} - -ximage_convert_func_t ximage_convert_funcs[] = { - ximage_convert_argb8888, - ximage_convert_bgra8888, - ximage_convert_rgba8888, - ximage_convert_abgr8888, - ximage_convert_rgb888, - ximage_convert_bgr888, - ximage_convert_rgb565, - ximage_convert_rgb565_br, - ximage_convert_rgb555, - ximage_convert_rgb555_br, - ximage_convert_bgr233, -}; - |