From db27122d3942ebec4471c260403d87cdd6541add Mon Sep 17 00:00:00 2001 From: Charles Collicutt Date: Thu, 17 May 2018 22:56:12 +0100 Subject: upas/nfs: correctly quote IMAP LOGIN arguments According to RFC 3501 the arguments to the LOGIN command should be quoted strings (or length prefixed string literals). Without quoting, authentication to some IMAP servers (e.g. Dovecot) will fail. --- src/cmd/upas/nfs/imap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cmd/upas/nfs/imap.c b/src/cmd/upas/nfs/imap.c index 2cbe99e1..8d43fe79 100644 --- a/src/cmd/upas/nfs/imap.c +++ b/src/cmd/upas/nfs/imap.c @@ -214,7 +214,7 @@ imaplogin(Imap *z) return -1; } - sx = imapcmdsx(z, nil, "LOGIN %Z %Z", up->user, up->passwd); + sx = imapcmdsx(z, nil, "LOGIN %#Z %#Z", up->user, up->passwd); freeup(up); if(sx == nil) return -1; -- cgit v1.2.3 From 48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23 Mon Sep 17 00:00:00 2001 From: Fazlul Shahriar Date: Fri, 22 Jun 2018 16:43:17 -0400 Subject: fontsrv: copy some fixes from OS X to X11 * Avoid allocating empty images by adding 1 to width/height. This was crashing fontsrv. The total width of the subfont image can be zero even if the characters are present in the font. For example, all the characters in x0300.bit (part of "Combining Diacritical Marks" Unicode block) have zero width. * Make sure U+0000 is always present in the font, otherwise libdraw complains with: "stringwidth: bad character set for rune 0x0000 in ..." * Use the same fallback glyph (pjw face) as OS X. This also fixes a bug where advance was set to the total width of subfont instead of the character. Update #125 (most likely fixes the crash if in X11) Change-Id: Icdc2b641b8b0c08644569006e91cf613b4d5477f --- src/cmd/fontsrv/x11.c | 81 +++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index a097ca4d..455e8126 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -66,19 +66,16 @@ load(XFont *f) return; e = FT_New_Face(lib, f->fontfile, f->index, &face); - if(e){ fprint(2, "load failed for %s (%s) index:%d\n", f->name, f->fontfile, f->index); return; } - if(!FT_IS_SCALABLE(face)) { fprint(2, "%s is a non scalable font, skipping\n", f->name); FT_Done_Face(face); - f->loaded = 1; + f->loaded = 1; return; } - f->unit = face->units_per_EM; f->height = (int)((face->ascender - face->descender) * 1.2); f->originy = face->descender; // bbox.yMin (or descender) is negative, becase the baseline is y-coord 0 @@ -96,7 +93,11 @@ load(XFont *f) f->nrange++; } } - + // libdraw expects U+0000 to be present + if(!f->range[0]) { + f->range[0] = 1; + f->nrange++; + } FT_Done_Face(face); f->loaded = 1; } @@ -108,14 +109,13 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) FT_Error e; Memimage *m, *mc, *m1; double pixel_size; - int x, y, y0; + int w, x, y, y0; int i; Fontchar *fc, *fc0; Memsubfont *sf; //Point rect_points[4]; e = FT_New_Face(lib, xf->fontfile, xf->index, &face); - if(e){ fprint(2, "load failed for %s (%s) index:%d\n", xf->name, xf->fontfile, xf->index); return nil; @@ -129,16 +129,16 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) } pixel_size = (dpi*size)/72.0; - x = (int)((face->max_advance_width) * pixel_size/xf->unit + 0.99999999); + w = x = (int)((face->max_advance_width) * pixel_size/xf->unit + 0.99999999); y = (int)((face->ascender - face->descender) * pixel_size/xf->unit + 0.99999999); y0 = (int)(-face->descender * pixel_size/xf->unit + 0.99999999); - m = allocmemimage(Rect(0, 0, x*(hi+1-lo), y), antialias ? GREY8 : GREY1); + m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), antialias ? GREY8 : GREY1); if(m == nil) { FT_Done_Face(face); return nil; } - mc = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1); + mc = allocmemimage(Rect(0, 0, x+1, y+1), antialias ? GREY8 : GREY1); if(mc == nil) { freememimage(m); FT_Done_Face(face); @@ -165,41 +165,42 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) x = 0; for(i=lo; i<=hi; i++, fc++) { - int r; + int k, r; int advance; memfillcolor(mc, DBlack); - e = FT_Load_Char(face, i, FT_LOAD_RENDER|FT_LOAD_NO_HINTING|(antialias ? 0:FT_LOAD_TARGET_MONO)); - if(e){ - fprint(2, "FT_Load_Char failed for %d\n", i); - //mempoly(mc, rect_points, 4, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, Pt(m->r.max.x, m->r.min.y), Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, Pt(m->r.min.x, m->r.max.y), Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, Pt(m->r.max.x, m->r.min.y), m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, Pt(m->r.min.x, m->r.max.y), m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - advance = Dx(m->r); - - memimagedraw(m, Rect(x, 0, x + advance, y), mc, ZP, memopaque, ZP, S); - } else { - FT_Bitmap *bitmap = &face->glyph->bitmap; - uchar *base = byteaddr(mc, mc->r.min); - advance = (face->glyph->advance.x+32) >> 6; - - for(r=0; r < bitmap->rows; r++) - memmove(base + r*mc->width*sizeof(u32int), bitmap->buffer + r*bitmap->pitch, bitmap->pitch); - - memimagedraw(m, Rect(x, 0, x + advance, y), mc, - Pt(-face->glyph->bitmap_left, -(y - y0 - face->glyph->bitmap_top)), - memopaque, ZP, S); - } - fc->x = x; fc->top = 0; - fc->bottom = y; - fc->left = 0; + fc->bottom = Dy(m->r); + e = 1; + k = FT_Get_Char_Index(face, i); + if(k != 0) { + e = FT_Load_Glyph(face, k, FT_LOAD_RENDER|FT_LOAD_NO_HINTING|(antialias ? 0:FT_LOAD_TARGET_MONO)); + } + if(e || face->glyph->advance.x <= 0) { + fc->width = 0; + fc->left = 0; + if(i == 0) { + drawpjw(m, fc, x, w, y, y - y0); + x += fc->width; + } + continue; + } + + FT_Bitmap *bitmap = &face->glyph->bitmap; + uchar *base = byteaddr(mc, mc->r.min); + advance = (face->glyph->advance.x+32) >> 6; + + for(r=0; r < bitmap->rows; r++) + memmove(base + r*mc->width*sizeof(u32int), bitmap->buffer + r*bitmap->pitch, bitmap->pitch); + + memimagedraw(m, Rect(x, 0, x + advance, y), mc, + Pt(-face->glyph->bitmap_left, -(y - y0 - face->glyph->bitmap_top)), + memopaque, ZP, S); + fc->width = advance; + fc->left = 0; x += advance; #ifdef DEBUG_FT_BITMAP @@ -229,6 +230,10 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) // round up to 32-bit boundary // so that in-memory data is same // layout as in-file data. + if(x == 0) + x = 1; + if(y == 0) + y = 1; if(antialias) x += -x & 3; else -- cgit v1.2.3 From 014fd65a5ca780823c0e75787f193d3c6597de8f Mon Sep 17 00:00:00 2001 From: Xiao-Yong Date: Tue, 13 Nov 2018 22:09:10 -0600 Subject: 9term: fix getpts on FreeBSD 11.2 (#199) Opening /dev/ptyXX files fails on recent FreeBSD versions. Following the same fix being applied to Linux, OpenBSD, and Darwin, we use openpty to open a pseudoterminal in openpts. --- src/cmd/9term/FreeBSD.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/cmd/9term/FreeBSD.c b/src/cmd/9term/FreeBSD.c index eec79c28..e91f6ace 100644 --- a/src/cmd/9term/FreeBSD.c +++ b/src/cmd/9term/FreeBSD.c @@ -1 +1,17 @@ +#define getpts not_using_this_getpts #include "bsdpty.c" +#undef getpts + +#include + +int +getpts(int fd[], char *slave) +{ + if(openpty(&fd[1], &fd[0], NULL, NULL, NULL) >= 0){ + fchmod(fd[1], 0620); + strcpy(slave, ttyname(fd[0])); + return 0; + } + sysfatal("no ptys"); + return 0; +} -- cgit v1.2.3 From 2419c9343827a679353a8c0a44fd6e0e3e631a3c Mon Sep 17 00:00:00 2001 From: Xiao-Yong Date: Tue, 13 Nov 2018 22:09:59 -0600 Subject: fontsrv: disable font smoothing on osx (#196) macOS Mojave version 10.14 starts to disable font smoothing. We disable font smoothing for OSX_VERSION >= 101400 to match the system default font rendering. It also makes the font rendering on macOS similar to that on X11. --- src/cmd/fontsrv/mkfile | 1 + src/cmd/fontsrv/osx.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/cmd/fontsrv/mkfile b/src/cmd/fontsrv/mkfile index eed0355a..8ad99dbc 100644 --- a/src/cmd/fontsrv/mkfile +++ b/src/cmd/fontsrv/mkfile @@ -1,4 +1,5 @@ <$PLAN9/src/mkhdr +<|osxvers <|sh ../devdraw/mkwsysrules.sh <|sh freetyperules.sh $WSYSTYPE $X11H diff --git a/src/cmd/fontsrv/osx.c b/src/cmd/fontsrv/osx.c index b28ee252..c01ae6ce 100644 --- a/src/cmd/fontsrv/osx.c +++ b/src/cmd/fontsrv/osx.c @@ -277,6 +277,9 @@ mksubfont(XFont *f, char *name, int lo, int hi, int size, int antialias) CGContextSetAllowsAntialiasing(ctxt, antialias); CGContextSetTextPosition(ctxt, 0, 0); // XXX +#if OSX_VERSION >= 101400 + CGContextSetAllowsFontSmoothing(ctxt, false); +#endif x = 0; for(i=lo; i<=hi; i++, fc++) { -- cgit v1.2.3 From 76b9347a5fa3a0970527c6ee1b97ef1c714f636b Mon Sep 17 00:00:00 2001 From: Fazlul Shahriar Date: Tue, 13 Nov 2018 23:11:31 -0500 Subject: acme: avoid division by zero when resizing col (#189) To reproduce, create a column with at least two windows and resize acme to have almost zero height. --- src/cmd/acme/cols.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c index 10e014ee..b1fe23ba 100644 --- a/src/cmd/acme/cols.c +++ b/src/cmd/acme/cols.c @@ -250,8 +250,12 @@ colresize(Column *c, Rectangle r) w->maxlines = 0; if(i == c->nw-1) r1.max.y = r.max.y; - else - r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r); + else{ + r1.max.y = r1.min.y; + if(Dy(c->r) != 0){ + r1.max.y += (Dy(w->r)+Border)*Dy(r)/Dy(c->r); + } + } r1.max.y = max(r1.max.y, r1.min.y + Border+font->height); r2 = r1; r2.max.y = r2.min.y+Border; -- cgit v1.2.3 From c82e11b24e7a6aa03473111367cb792ce0537f61 Mon Sep 17 00:00:00 2001 From: Xiao-Yong Date: Tue, 13 Nov 2018 22:13:15 -0600 Subject: fontsrv: x11 uses FC_POSTSCRIPT_NAME (#174) This makes fontsrv use the PostScript font names on X11. The PostScript font names contains only alphanumeric and hyphens. This allows us to use the Font command in acme. It also matches the font names used by fontsrv on macOS, which has been using PostScript font names. --- src/cmd/fontsrv/x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index 455e8126..f93c031e 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -40,7 +40,7 @@ loadfonts(void) int index; FcPattern *pat = sysfonts->fonts[i]; - if(FcPatternGetString(pat, FC_FULLNAME, 0, &fullname) != FcResultMatch || + if(FcPatternGetString(pat, FC_POSTSCRIPT_NAME, 0, &fullname) != FcResultMatch || FcPatternGetString(pat, FC_FILE, 0, &fontfile) != FcResultMatch || FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch) continue; -- cgit v1.2.3 From a9e66ffa4eb61a4728d536d20f916a5a02ab5626 Mon Sep 17 00:00:00 2001 From: Xiao-Yong Date: Tue, 13 Nov 2018 22:57:56 -0600 Subject: devdraw: make ctrl generate 1-click while mouse down (#119) This makes 2-1 chords possible with touchpad on a mac laptop. --- src/cmd/devdraw/cocoa-screen.m | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/cmd/devdraw/cocoa-screen.m b/src/cmd/devdraw/cocoa-screen.m index e7296e44..16053eaa 100644 --- a/src/cmd/devdraw/cocoa-screen.m +++ b/src/cmd/devdraw/cocoa-screen.m @@ -927,6 +927,8 @@ getkeyboard(NSEvent *e) case NSFlagsChanged: if(in.mbuttons || in.kbuttons){ in.kbuttons = 0; + if(m & NSControlKeyMask) + in.kbuttons |= 1; if(m & NSAlternateKeyMask) in.kbuttons |= 2; if(m & NSCommandKeyMask) -- cgit v1.2.3 From ed959cfba326356a5cdea1a12c8ac17b5365486c Mon Sep 17 00:00:00 2001 From: iru- Date: Tue, 13 Nov 2018 21:01:04 -0800 Subject: fontsrv: increase x11 font height scale (#111) --- src/cmd/fontsrv/x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index f93c031e..4137f9ca 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -77,7 +77,7 @@ load(XFont *f) return; } f->unit = face->units_per_EM; - f->height = (int)((face->ascender - face->descender) * 1.2); + f->height = (int)((face->ascender - face->descender) * 1.35); f->originy = face->descender; // bbox.yMin (or descender) is negative, becase the baseline is y-coord 0 for(charcode=FT_Get_First_Char(face, &glyph_index); glyph_index != 0; -- cgit v1.2.3 From d3f21b709efc5e1ca4c4f0ef58bf9ac5db8e921c Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 14 Nov 2018 00:11:48 -0500 Subject: 9term: make 9term -l invoke $SHELL with -l --- src/cmd/9term/rcstart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cmd/9term/rcstart.c b/src/cmd/9term/rcstart.c index 141b9b00..fddabc6d 100644 --- a/src/cmd/9term/rcstart.c +++ b/src/cmd/9term/rcstart.c @@ -34,7 +34,7 @@ int rcstart(int argc, char **argv, int *pfd, int *tfd) { int fd[2], i, pid; - char *cmd, *xargv[3]; + char *cmd, *xargv[4]; char slave[256]; int sfd; @@ -46,6 +46,11 @@ rcstart(int argc, char **argv, int *pfd, int *tfd) argv[0] = "rc"; argv[1] = "-i"; argv[2] = 0; + if(loginshell){ + argv[2] = "-l"; + argv[3] = 0; + argc = 3; + } } cmd = argv[0]; if(loginshell){ -- cgit v1.2.3 From 000c1a3b19a8d3f8bbaefba84131995cb62c889f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20D=C3=ADaz?= Date: Wed, 14 Nov 2018 06:19:29 +0100 Subject: devdraw: set displaydpi on devdraw x11 attach (#178) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://plan9port-review.googlesource.com/c/plan9/+/1470 for discussion of the approach, especially Michael Stapleberg's comment: Note that chromium, firefox and others have tried this and then switched to using the Xft.dpi X resource, see e.g. https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/ui/libgtk2ui/gtk2_ui.cc and especially http://sources.debian.net/src/gnome-settings-daemon/3.18.2-1/plugins/xsettings/gsd-xsettings-manager.c/?hl=824#L80 for some anecdata about why this approach doesn’t work out. The Xft.dpi resource is being set accurately by desktop environments (GNOME, KDE, …) and can easily be changed by users of niche window managers by editing ~/.Xresources. I suggest we check only Xft.dpi, without considering the DPI environment variable or the monitor width/height. --- src/cmd/devdraw/x11-init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cmd/devdraw/x11-init.c b/src/cmd/devdraw/x11-init.c index 5363fb74..f09963dc 100644 --- a/src/cmd/devdraw/x11-init.c +++ b/src/cmd/devdraw/x11-init.c @@ -208,9 +208,9 @@ _xattach(char *label, char *winsize) * Parse the various X resources. Thanks to Peter Canning. */ char *screen_resources, *display_resources, *geom, - *geomrestype, *home, *file; + *geomrestype, *home, *file, *dpitype; XrmDatabase database; - XrmValue geomres; + XrmValue geomres, dpires; database = XrmGetDatabase(_x.display); screen_resources = XScreenResourceString(xscreen); @@ -230,6 +230,11 @@ _xattach(char *label, char *winsize) }else XrmCombineDatabase(XrmGetStringDatabase(display_resources), &database, False); + if (XrmGetResource(database, "Xft.dpi", "String", &dpitype, &dpires) == True) { + if (dpires.addr) { + displaydpi=atoi(dpires.addr); + } + } geom = smprint("%s.geometry", label); if(geom && XrmGetResource(database, geom, nil, &geomrestype, &geomres)) mask = XParseGeometry(geomres.addr, &x, &y, (uint*)&width, (uint*)&height); -- cgit v1.2.3 From de43b1629d008aa6cdf4f6beb2b06e3859616a3e Mon Sep 17 00:00:00 2001 From: Zach Scott Date: Wed, 14 Nov 2018 05:24:07 +0000 Subject: upas/smtp: fix TLS connections (#163) Both `upas/nfs` and `upas/smtp` call the currently broken `tlsClient()` from libsec. This commit copies a fix from upas/nfs into upas/smtp. In `imapdial()`, upas/nfs replaces a process call for tlsClient with `stunnel3` when not on Plan 9. upas/smtp calls tlsClient directly as a function, so imapdial was copied into mxdial.c as `smtpdial()`, and tlsClient+dial replaced with a call to smtpdial. --- src/cmd/upas/smtp/mxdial.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/cmd/upas/smtp/smtp.c | 1 + 2 files changed, 49 insertions(+) (limited to 'src') diff --git a/src/cmd/upas/smtp/mxdial.c b/src/cmd/upas/smtp/mxdial.c index f3a2a209..56962dcd 100644 --- a/src/cmd/upas/smtp/mxdial.c +++ b/src/cmd/upas/smtp/mxdial.c @@ -2,6 +2,7 @@ #include #include "smtp.h" /* to publish dial_string_parse */ #include +#include enum { @@ -27,6 +28,45 @@ static int callmx(DS*, char*, char*); static void expand_meta(DS *ds); extern int cistrcmp(char*, char*); +/* Taken from imapdial, replaces tlsclient call with stunnel */ +static int +smtpdial(char *server) +{ + int p[2]; + int fd[3]; + char *tmp; + char *fpath; + + if(pipe(p) < 0) + return -1; + fd[0] = dup(p[0], -1); + fd[1] = dup(p[0], -1); + fd[2] = dup(2, -1); +#ifdef PLAN9PORT + tmp = smprint("%s:587", server); + fpath = searchpath("stunnel3"); + if (!fpath) { + werrstr("stunnel not found. it is required for tls support."); + return -1; + } + if(threadspawnl(fd, fpath, "stunnel", "-n", "smtp" , "-c", "-r", tmp, nil) < 0) { +#else + tmp = smprint("tcp!%s!587", server); + if(threadspawnl(fd, "/bin/tlsclient", "tlsclient", tmp, nil) < 0){ +#endif + free(tmp); + close(p[0]); + close(p[1]); + close(fd[0]); + close(fd[1]); + close(fd[2]); + return -1; + } + free(tmp); + close(p[0]); + return p[1]; +} + int mxdial(char *addr, char *ddomain, char *gdomain) { @@ -100,13 +140,21 @@ callmx(DS *ds, char *dest, char *domain) } /* dial each one in turn */ for(i = 0; i < nmx; i++){ +#ifdef PLAN9PORT + snprint(addr, sizeof(addr), "%s", mx[i].host); +#else snprint(addr, sizeof(addr), "%s!%s!%s", ds->proto, mx[i].host, ds->service); +#endif if(debug) fprint(2, "mxdial trying %s (%d)\n", addr, i); atnotify(timeout, 1); alarm(10*1000); +#ifdef PLAN9PORT + fd = smtpdial(addr); +#else fd = dial(addr, 0, 0, 0); +#endif alarm(0); atnotify(timeout, 0); if(fd >= 0) diff --git a/src/cmd/upas/smtp/smtp.c b/src/cmd/upas/smtp/smtp.c index 9dd05596..92873723 100644 --- a/src/cmd/upas/smtp/smtp.c +++ b/src/cmd/upas/smtp/smtp.c @@ -467,6 +467,7 @@ hello(char *me, int encrypted) } ehlo = 1; + encrypted = 1; Again: if(ehlo) dBprint("EHLO %s\r\n", me); -- cgit v1.2.3 From 9af9ceca26596d562a3ae89fda70bad9f8822ab0 Mon Sep 17 00:00:00 2001 From: Xiao-Yong Jin Date: Sun, 21 Oct 2018 20:59:21 -0500 Subject: devdraw: rewrite the Cocoa screen using Metal Add a new macOS cocoa screen, cocoa-screen-metal.m. Rewrite the macOS cocoa drawing code to use the builtin runloop, and use Metal to push pixels with CAMetalLayer. Remove all of the deprecated code, and simplify some of the logic. Modify mkwsysrules.sh such that the new code is used only when the system version is equal or higher than 10.14. Allow touch events to simulate mouse clicks: three finger tap for the middle mouse button; four finger tap for the 2-1 chord. Support Tresize. Scale 16x16 Cursor up to 32x32 with an EPX algorithm. Support macOS input sources including the basic dead keys and the advanced CJK input methods. Increase the communication buffers in cocoa-srv.c to allow more input, especially for long sentences prepared by the macOS input souces. --- src/cmd/devdraw/bigarrow.h | 22 +- src/cmd/devdraw/cocoa-screen-metal.m | 1260 ++++++++++++++++++++++++++++++++++ src/cmd/devdraw/cocoa-screen.h | 6 +- src/cmd/devdraw/cocoa-srv.c | 22 +- src/cmd/devdraw/cocoa-thread.c | 7 + src/cmd/devdraw/cocoa-thread.h | 1 + src/cmd/devdraw/mkfile | 3 + src/cmd/devdraw/mkwsysrules.sh | 7 +- 8 files changed, 1307 insertions(+), 21 deletions(-) create mode 100644 src/cmd/devdraw/cocoa-screen-metal.m (limited to 'src') diff --git a/src/cmd/devdraw/bigarrow.h b/src/cmd/devdraw/bigarrow.h index a46f19a0..3b66c954 100644 --- a/src/cmd/devdraw/bigarrow.h +++ b/src/cmd/devdraw/bigarrow.h @@ -1,11 +1,13 @@ -Cursor bigarrow = { - {0, 0}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, - 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC, - 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC, - 0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40}, - {0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, - 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, - 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, - 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00}, +Cursor bigarrow = { + { -1, -1 }, + { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, + 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, + 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, + 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, + }, + { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, + 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, + 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, + 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, + }, }; diff --git a/src/cmd/devdraw/cocoa-screen-metal.m b/src/cmd/devdraw/cocoa-screen-metal.m new file mode 100644 index 00000000..c82ce0bc --- /dev/null +++ b/src/cmd/devdraw/cocoa-screen-metal.m @@ -0,0 +1,1260 @@ +#define Cursor OSXCursor +#define Point OSXPoint +#define Rect OSXRect + +#import +#import +#import + +#undef Cursor +#undef Point +#undef Rect + +#include +#include +#include "cocoa-thread.h" +#include +#include +#include +#include +#include "cocoa-screen.h" +#include "osx-keycodes.h" +#include "devdraw.h" +#include "bigarrow.h" +#include "glendapng.h" + +AUTOFRAMEWORK(Cocoa) +AUTOFRAMEWORK(Metal) +AUTOFRAMEWORK(QuartzCore) + +#define LOG if(0)NSLog + +static void setprocname(const char*); +static uint keycvt(uint); +static uint msec(void); +static Memimage* initimg(void); + +void +usage(void) +{ + fprint(2, "usage: devdraw (don't run directly)\n"); + threadexitsall("usage"); +} + +@interface AppDelegate : NSObject ++ (void)callservep9p:(id)arg; ++ (void)makewin:(NSValue *)v; ++ (void)callkicklabel:(NSString *)v; ++ (void)callsetNeedsDisplayInRect:(NSValue *)v; ++ (void)callsetcursor:(NSValue *)v; +@end +@interface DevDrawView : NSView +- (void)clearInput; +- (void)getmouse:(NSEvent *)e; +- (void)sendmouse:(NSUInteger)b; +- (void)resetLastInputRect; +- (void)enlargeLastInputRect:(NSRect)r; +@end +@interface DrawLayer : CAMetalLayer +@end + +static AppDelegate *myApp = NULL; +static DevDrawView *myContent = NULL; +static NSWindow *win = NULL; +static NSCursor *currentCursor = NULL; + +static DrawLayer *layer; +static MTLRenderPassDescriptor *renderPass; +static id device; +static id pipelineState; +static id commandQueue; +static id texture; + +static Memimage *img = NULL; + +static QLock snarfl; + +static NSString *const metal = +@"#include\n" +"using namespace metal;\n" +"typedef struct {\n" +" float4 rCoord [[position]];\n" +" float2 tCoord;\n" +"} VertexOut;\n" +"vertex VertexOut\n" +"renderVertex(unsigned int vid [[ vertex_id ]])\n" +"{\n" +" const VertexOut fixedV[] = {\n" +" {{ -1.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f }},\n" +" {{ 1.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f }},\n" +" {{ -1.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f }},\n" +" {{ 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f }},\n" +" };\n" +" return fixedV[vid];\n" +"}\n" +"fragment half4\n" +"renderFragment(VertexOut in [[ stage_in ]],\n" +" texture2d texture [[ texture(0) ]]) {\n" +" constexpr sampler s;\n" +" return texture.sample(s, in.tCoord);\n" +"}"; + + +void +threadmain(int argc, char **argv) +{ + /* + * Move the protocol off stdin/stdout so that + * any inadvertent prints don't screw things up. + */ + dup(0,3); + dup(1,4); + close(0); + close(1); + open("/dev/null", OREAD); + open("/dev/null", OWRITE); + + ARGBEGIN{ + case 'D': /* for good ps -a listings */ + break; + case 'f': /* fall through for backward compatibility */ + case 'g': + case 'b': + break; + default: + usage(); + }ARGEND + + setprocname(argv0); + + @autoreleasepool{ + [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + myApp = [AppDelegate new]; + [NSApp setDelegate:myApp]; + [NSApp run]; + } +} + +@implementation AppDelegate + ++ (void)callservep9p:(id)arg +{ + servep9p(); + [NSApp terminate:self]; +} + ++ (void)makewin:(NSValue *)v +{ + NSRect r, sr; + Rectangle wr; + int set; + char *s; + id library; + MTLRenderPipelineDescriptor *pipelineDesc; + NSError *error; + + const NSWindowStyleMask Winstyle = NSWindowStyleMaskTitled + | NSWindowStyleMaskClosable + | NSWindowStyleMaskMiniaturizable + | NSWindowStyleMaskResizable; + + sr = [[NSScreen mainScreen] frame]; + r = [[NSScreen mainScreen] visibleFrame]; + + s = [v pointerValue]; + LOG(@"makewin(%s)", s); + if(s && *s){ + if(parsewinsize(s, &wr, &set) < 0) + sysfatal("%r"); + }else{ + wr = Rect(0, 0, sr.size.width*2/3, sr.size.height*2/3); + set = 0; + } + + r.origin.x = wr.min.x; + r.origin.y = sr.size.height-wr.max.y; /* winsize is top-left-based */ + r.size.width = fmin(Dx(wr), r.size.width); + r.size.height = fmin(Dy(wr), r.size.height); + r = [NSWindow contentRectForFrameRect:r styleMask:Winstyle]; + + win = [[NSWindow alloc] + initWithContentRect:r + styleMask:Winstyle + backing:NSBackingStoreBuffered defer:NO]; + [win setTitle:@"devdraw"]; + + if(!set) + [win center]; + [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + [win setContentMinSize:NSMakeSize(64,64)]; + + [win setRestorable:NO]; + [win setAcceptsMouseMovedEvents:YES]; + [win setDelegate:myApp]; + + myContent = [DevDrawView new]; + [win setContentView:myContent]; + [myContent setWantsLayer:YES]; + [myContent setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay]; + + device = MTLCreateSystemDefaultDevice(); + commandQueue = [device newCommandQueue]; + + layer = (DrawLayer *)[myContent layer]; + layer.device = device; + layer.pixelFormat = MTLPixelFormatBGRA8Unorm; + layer.framebufferOnly = YES; + layer.opaque = YES; + + renderPass = [MTLRenderPassDescriptor renderPassDescriptor]; + renderPass.colorAttachments[0].loadAction = MTLLoadActionDontCare; + renderPass.colorAttachments[0].storeAction = MTLStoreActionDontCare; + + library = [device newLibraryWithSource:metal options:nil error:&error]; + if(!library) + sysfatal((char *)[[error localizedDescription] UTF8String]); + + pipelineDesc = [MTLRenderPipelineDescriptor new]; + pipelineDesc.alphaToOneEnabled = YES; + pipelineDesc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle; + pipelineDesc.rasterSampleCount = 1; + pipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; + [pipelineDesc setVertexFunction: [library newFunctionWithName: @"renderVertex"]]; + [pipelineDesc setFragmentFunction: [library newFunctionWithName: @"renderFragment"]]; + + pipelineState = [device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error]; + if(!pipelineState) + sysfatal((char *)[[error localizedDescription] UTF8String]); + + [NSEvent setMouseCoalescingEnabled:NO]; + + topwin(); +} + ++ (void)callkicklabel:(NSString *)s +{ + LOG(@"callkicklabel(%@)", s); + [win setTitle:s]; + [[NSApp dockTile] setBadgeLabel:s]; +} + + ++ (void)callsetNeedsDisplayInRect:(NSValue *)v +{ + NSRect r; + + r = [v rectValue]; + LOG(@"callsetNeedsDisplayInRect(%g, %g, %g, %g)", r.origin.x, r.origin.y, r.size.width, r.size.height); + r = [win convertRectFromBacking:r]; + LOG(@"setNeedsDisplayInRect(%g, %g, %g, %g)", r.origin.x, r.origin.y, r.size.width, r.size.height); + [layer setNeedsDisplayInRect:r]; + [myContent enlargeLastInputRect:r]; +} + ++ (void)callsetcursor:(NSValue *)v +{ + Cursor *c; + NSBitmapImageRep *r, *r2; + NSImage *i; + NSPoint p; + uint b, x, y, a; + uchar *plane[5], *plane2[5]; + uchar pu, pb, pl, pr, pc; // upper, bottom, left, right, center + uchar pul, pur, pbl, pbr; + uchar ful, fur, fbl, fbr; + + c = [v pointerValue]; + if(!c) + c = &bigarrow; + + r = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:nil + pixelsWide:16 + pixelsHigh:16 + bitsPerSample:1 + samplesPerPixel:2 + hasAlpha:YES + isPlanar:YES + colorSpaceName:NSDeviceWhiteColorSpace + bytesPerRow:2 + bitsPerPixel:0]; + [r getBitmapDataPlanes:plane]; + for(b=0; b<2*16; b++){ + plane[0][b] = ~c->set[b] & c->clr[b]; + plane[1][b] = c->set[b] | c->clr[b]; + } + + r2 = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:nil + pixelsWide:32 + pixelsHigh:32 + bitsPerSample:1 + samplesPerPixel:2 + hasAlpha:YES + isPlanar:YES + colorSpaceName:NSDeviceWhiteColorSpace + bytesPerRow:4 + bitsPerPixel:0]; + [r2 getBitmapDataPlanes:plane2]; + // https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms#EPX/Scale2×/AdvMAME2× + for(a=0; a<2; a++){ + for(y=0; y<16; y++){ + for(x=0; x<2; x++){ + pc = plane[a][x+2*y]; + pu = y==0 ? pc : plane[a][x+2*(y-1)]; + pb = y==15 ? pc : plane[a][x+2*(y+1)]; + pl = (pc>>1) | (x==0 ? pc&0x80 : (plane[a][x-1+2*y]&1)<<7); + pr = (pc<<1) | (x==1 ? pc&1 : (plane[a][x+1+2*y]&0x80)>>7); + ful = ~(pl^pu) & (pl^pb) & (pu^pr); + pul = (ful & pu) | (~ful & pc); + fur = ~(pu^pr) & (pu^pl) & (pr^pb); + pur = (fur & pr) | (~fur & pc); + fbl = ~(pb^pl) & (pb^pr) & (pl^pu); + pbl = (fbl & pl) | (~fbl & pc); + fbr = ~(pr^pb) & (pr^pu) & (pb^pl); + pbr = (fbr & pb) | (~fbr & pc); + plane2[a][2*x+4*2*y] = (pul&0x80) | ((pul&0x40)>>1) | ((pul&0x20)>>2) | ((pul&0x10)>>3) + | ((pur&0x80)>>1) | ((pur&0x40)>>2) | ((pur&0x20)>>3) | ((pur&0x10)>>4); + plane2[a][2*x+1+4*2*y] = ((pul&0x8)<<4) | ((pul&0x4)<<3) | ((pul&0x2)<<2) | ((pul&0x1)<<1) + | ((pur&0x8)<<3) | ((pur&0x4)<<2) | ((pur&0x2)<<1) | (pur&0x1); + plane2[a][2*x+4*(2*y+1)] = (pbl&0x80) | ((pbl&0x40)>>1) | ((pbl&0x20)>>2) | ((pbl&0x10)>>3) + | ((pbr&0x80)>>1) | ((pbr&0x40)>>2) | ((pbr&0x20)>>3) | ((pbr&0x10)>>4); + plane2[a][2*x+1+4*(2*y+1)] = ((pbl&0x8)<<4) | ((pbl&0x4)<<3) | ((pbl&0x2)<<2) | ((pbl&0x1)<<1) + | ((pbr&0x8)<<3) | ((pbr&0x4)<<2) | ((pbr&0x2)<<1) | (pbr&0x1); + } + } + } + + // For checking out the cursor bitmap image +/* + static BOOL saveimg = YES; + if(saveimg){ + NSData *data = [r representationUsingType: NSBitmapImageFileTypeBMP properties: @{}]; + [data writeToFile: @"/tmp/r.bmp" atomically: NO]; + data = [r2 representationUsingType: NSBitmapImageFileTypeBMP properties: @{}]; + [data writeToFile: @"/tmp/r2.bmp" atomically: NO]; + saveimg = NO; + } +*/ + + i = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)]; + [i addRepresentation:r2]; + [i addRepresentation:r]; + + p = NSMakePoint(-c->offset.x, -c->offset.y); + currentCursor = [[NSCursor alloc] initWithImage:i hotSpot:p]; + + [win invalidateCursorRectsForView:myContent]; +} + +- (void)applicationDidFinishLaunching:(id)arg +{ + NSMenu *m, *sm; + NSData *d; + NSImage *i; + + LOG(@"applicationDidFinishLaunching"); + + sm = [NSMenu new]; + [sm addItemWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"]; + [sm addItemWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@"h"]; + [sm addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"]; + m = [NSMenu new]; + [m addItemWithTitle:@"DEVDRAW" action:NULL keyEquivalent:@""]; + [m setSubmenu:sm forItem:[m itemWithTitle:@"DEVDRAW"]]; + [NSApp setMainMenu:m]; + + d = [[NSData alloc] initWithBytes:glenda_png length:(sizeof glenda_png)]; + i = [[NSImage alloc] initWithData:d]; + [NSApp setApplicationIconImage:i]; + [[NSApp dockTile] display]; + + [NSThread + detachNewThreadSelector:@selector(callservep9p:) + toTarget:[self class] withObject:nil]; +} + +- (NSApplicationPresentationOptions)window:(id)arg + willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { + NSApplicationPresentationOptions o; + o = proposedOptions; + o &= ~(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar); + o |= NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; + return o; +} + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { + return YES; +} + +@end + +@implementation DevDrawView +{ + NSMutableString *_tmpText; + NSRange _markedRange; + NSRange _selectedRange; + NSRect _lastInputRect; // The view is flipped, this is not. + BOOL _tapping; + NSUInteger _tapFingers; + NSUInteger _tapTime; +} + +- (id)init +{ + LOG(@"View init"); + self = [super init]; + [self setAllowedTouchTypes:NSTouchTypeMaskDirect|NSTouchTypeMaskIndirect]; + _tmpText = [[NSMutableString alloc] initWithCapacity:2]; + _markedRange = NSMakeRange(NSNotFound, 0); + _selectedRange = NSMakeRange(0, 0); + return self; +} + +- (CALayer *)makeBackingLayer +{ + LOG(@"makeBackingLayer"); + return [DrawLayer layer]; +} + +- (BOOL)wantsUpdateLayer +{ + return YES; +} + +- (BOOL)isOpaque +{ + return YES; +} + +- (BOOL)isFlipped +{ + return YES; +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (void)mouseMoved:(NSEvent*)e{ [self getmouse:e];} +- (void)mouseDown:(NSEvent*)e{ [self getmouse:e];} +- (void)mouseDragged:(NSEvent*)e{ [self getmouse:e];} +- (void)mouseUp:(NSEvent*)e{ [self getmouse:e];} +- (void)otherMouseDown:(NSEvent*)e{ [self getmouse:e];} +- (void)otherMouseDragged:(NSEvent*)e{ [self getmouse:e];} +- (void)otherMouseUp:(NSEvent*)e{ [self getmouse:e];} +- (void)rightMouseDown:(NSEvent*)e{ [self getmouse:e];} +- (void)rightMouseDragged:(NSEvent*)e{ [self getmouse:e];} +- (void)rightMouseUp:(NSEvent*)e{ [self getmouse:e];} + +- (void)scrollWheel:(NSEvent*)e +{ + NSInteger s; + + s = [e scrollingDeltaY]; + if(s > 0) + [self sendmouse:8]; + else if (s < 0) + [self sendmouse:16]; +} + +- (void)keyDown:(NSEvent*)e +{ + LOG(@"keyDown to interpret"); + + [self interpretKeyEvents:[NSArray arrayWithObject:e]]; + + [self resetLastInputRect]; +} + +- (void)flagsChanged:(NSEvent*)e +{ + static NSEventModifierFlags omod; + NSEventModifierFlags m; + uint b; + + LOG(@"flagsChanged"); + m = [e modifierFlags]; + + b = [NSEvent pressedMouseButtons]; + b = (b&~6) | (b&4)>>1 | (b&2)<<1; + if(b){ + if(m & ~omod & NSEventModifierFlagControl) + b |= 1; + if(m & ~omod & NSEventModifierFlagOption) + b |= 2; + if(m & ~omod & NSEventModifierFlagCommand) + b |= 4; + [self sendmouse:b]; + }else if(m & ~omod & NSEventModifierFlagOption) + keystroke(Kalt); + + omod = m; +} + +- (void)magnifyWithEvent:(NSEvent*)e +{ + if(fabs([e magnification]) > 0.02) + [[self window] toggleFullScreen:nil]; +} + +- (void)touchesBeganWithEvent:(NSEvent*)e +{ + _tapping = YES; + _tapFingers = [e touchesMatchingPhase:NSTouchPhaseTouching inView:nil].count; + _tapTime = msec(); +} +- (void)touchesMovedWithEvent:(NSEvent*)e +{ + _tapping = NO; +} +- (void)touchesEndedWithEvent:(NSEvent*)e +{ + if(_tapping + && [e touchesMatchingPhase:NSTouchPhaseTouching inView:nil].count == 0 + && msec() - _tapTime < 250){ + switch(_tapFingers){ + case 3: + [self sendmouse:2]; + [self sendmouse:0]; + break; + case 4: + [self sendmouse:2]; + [self sendmouse:1]; + [self sendmouse:0]; + break; + } + _tapping = NO; + } +} +- (void)touchesCancelledWithEvent:(NSEvent*)e +{ + _tapping = NO; +} + +- (void)getmouse:(NSEvent *)e +{ + NSUInteger b; + NSEventModifierFlags m; + + b = [NSEvent pressedMouseButtons]; + b = b&~6 | (b&4)>>1 | (b&2)<<1; + b = mouseswap(b); + + if(b == 1){ + m = [e modifierFlags]; + if(m & NSEventModifierFlagOption){ + abortcompose(); + b = 2; + }else + if(m & NSEventModifierFlagCommand) + b = 4; + } + [self sendmouse:b]; +} + +- (void)sendmouse:(NSUInteger)b +{ + NSPoint p; + + p = [self.window convertPointToBacking: + [self.window mouseLocationOutsideOfEventStream]]; + p.y = Dy(mouserect) - p.y; + // LOG(@"(%g, %g) <- sendmouse(%d)", p.x, p.y, (uint)b); + mousetrack(p.x, p.y, b, msec()); + if(b && _lastInputRect.size.width && _lastInputRect.size.height) + [self resetLastInputRect]; +} + +- (void)resetCursorRects { + [super resetCursorRects]; + [self addCursorRect:self.bounds cursor:currentCursor]; +} + +- (void)viewDidEndLiveResize +{ + [super viewDidEndLiveResize]; + resizeimg(); +} + +- (void)viewDidChangeBackingProperties +{ + [super viewDidChangeBackingProperties]; + resizeimg(); +} + +// conforms to protocol NSTextInputClient +- (BOOL)hasMarkedText +{ + LOG(@"hasMarkedText"); + return _markedRange.location != NSNotFound; +} +- (NSRange)markedRange +{ + LOG(@"markedRange"); + return _markedRange; +} +- (NSRange)selectedRange +{ + LOG(@"selectedRange"); + return _selectedRange; +} +- (void)setMarkedText:(id)string + selectedRange:(NSRange)sRange + replacementRange:(NSRange)rRange +{ + NSString *str; + + LOG(@"setMarkedText: %@ (%ld, %ld) (%ld, %ld)", string, + sRange.location, sRange.length, + rRange.location, rRange.length); + + [self clearInput]; + + if([string isKindOfClass:[NSAttributedString class]]) + str = [string string]; + else + str = string; + + if(rRange.location == NSNotFound){ + if(_markedRange.location != NSNotFound){ + rRange = _markedRange; + }else{ + rRange = _selectedRange; + } + } + + if(str.length == 0){ + [_tmpText deleteCharactersInRange:rRange]; + [self unmarkText]; + }else{ + _markedRange = NSMakeRange(rRange.location, str.length); + [_tmpText replaceCharactersInRange:rRange withString:str]; + } + _selectedRange.location = rRange.location + sRange.location; + _selectedRange.length = sRange.length; + + if(_tmpText.length){ + uint i; + LOG(@"text length %ld", _tmpText.length); + for(i = 0; i <= _tmpText.length; ++i){ + if(i == _markedRange.location) + keystroke('['); + if(_selectedRange.length){ + if(i == _selectedRange.location) + keystroke('{'); + if(i == NSMaxRange(_selectedRange)) + keystroke('}'); + } + if(i == NSMaxRange(_markedRange)) + keystroke(']'); + if(i < _tmpText.length) + keystroke([_tmpText characterAtIndex:i]); + } + int l; + l = 1 + _tmpText.length - NSMaxRange(_selectedRange) + + (_selectedRange.length > 0); + LOG(@"move left %d", l); + for(i = 0; i < l; ++i) + keystroke(Kleft); + } + + LOG(@"text: \"%@\" (%ld,%ld) (%ld,%ld)", _tmpText, + _markedRange.location, _markedRange.length, + _selectedRange.location, _selectedRange.length); +} +- (void)unmarkText +{ + //NSUInteger i; + NSUInteger len; + + LOG(@"unmarkText"); + len = [_tmpText length]; + //for(i = 0; i < len; ++i) + // keystroke([_tmpText characterAtIndex:i]); + [_tmpText deleteCharactersInRange:NSMakeRange(0, len)]; + _markedRange = NSMakeRange(NSNotFound, 0); + _selectedRange = NSMakeRange(0, 0); +} +- (NSArray *)validAttributesForMarkedText +{ + LOG(@"validAttributesForMarkedText"); + return @[]; +} +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)r + actualRange:(NSRangePointer)actualRange +{ + NSRange sr; + NSAttributedString *s; + + LOG(@"attributedSubstringForProposedRange: (%ld, %ld) (%ld, %ld)", + r.location, r.length, actualRange->location, actualRange->length); + sr = NSMakeRange(0, [_tmpText length]); + sr = NSIntersectionRange(sr, r); + if(actualRange) + *actualRange = sr; + LOG(@"use range: %ld, %ld", sr.location, sr.length); + if(sr.length) + s = [[NSAttributedString alloc] + initWithString:[_tmpText substringWithRange:sr]]; + LOG(@" return %@", s); + return s; +} +- (void)insertText:(id)s + replacementRange:(NSRange)r +{ + NSUInteger i; + NSUInteger len; + + LOG(@"insertText: %@ replacementRange: %ld, %ld", s, r.location, r.length); + + [self clearInput]; + + len = [s length]; + for(i = 0; i < len; ++i) + keystroke([s characterAtIndex:i]); + [_tmpText deleteCharactersInRange:NSMakeRange(0, _tmpText.length)]; + _markedRange = NSMakeRange(NSNotFound, 0); + _selectedRange = NSMakeRange(0, 0); +} +- (NSUInteger)characterIndexForPoint:(NSPoint)point +{ + LOG(@"characterIndexForPoint: %g, %g", point.x, point.y); + return 0; +} +- (NSRect)firstRectForCharacterRange:(NSRange)r + actualRange:(NSRangePointer)actualRange +{ + LOG(@"firstRectForCharacterRange: (%ld, %ld) (%ld, %ld)", + r.location, r.length, actualRange->location, actualRange->length); + if(actualRange) + *actualRange = r; + return [[self window] convertRectToScreen:_lastInputRect]; +} +- (void)doCommandBySelector:(SEL)s +{ + NSEvent *e; + NSEventModifierFlags m; + uint c, k; + + LOG(@"doCommandBySelector (%@)", NSStringFromSelector(s)); + + e = [NSApp currentEvent]; + c = [[e characters] characterAtIndex:0]; + k = keycvt(c); + LOG(@"keyDown: character0: 0x%x -> 0x%x", c, k); + m = [e modifierFlags]; + + if(m & NSEventModifierFlagCommand){ + if((m & NSEventModifierFlagShift) && 'a' <= k && k <= 'z') + k += 'A' - 'a'; + if(' '<=k && k<='~') + k += Kcmd; + } + if(k>0) + keystroke(k); +} + +// Helper for managing input rect approximately +- (void)resetLastInputRect +{ + LOG(@"resetLastInputRect"); + _lastInputRect.origin.x = 0.0; + _lastInputRect.origin.y = 0.0; + _lastInputRect.size.width = 0.0; + _lastInputRect.size.height = 0.0; +} + +- (void)enlargeLastInputRect:(NSRect)r +{ + r.origin.y = [self bounds].size.height - r.origin.y - r.size.height; + _lastInputRect = NSUnionRect(_lastInputRect, r); + LOG(@"update last input rect (%g, %g, %g, %g)", + _lastInputRect.origin.x, _lastInputRect.origin.y, + _lastInputRect.size.width, _lastInputRect.size.height); +} + +- (void)clearInput +{ + if(_tmpText.length){ + uint i; + int l; + l = 1 + _tmpText.length - NSMaxRange(_selectedRange) + + (_selectedRange.length > 0); + LOG(@"move right %d", l); + for(i = 0; i < l; ++i) + keystroke(Kright); + l = _tmpText.length+2+2*(_selectedRange.length > 0); + LOG(@"backspace %d", l); + for(uint i = 0; i < l; ++i) + keystroke(Kbs); + } +} + +@end + +@implementation DrawLayer + +- (void)display +{ + id cbuf; + id cmd; + + LOG(@"display"); + + cbuf = [commandQueue commandBuffer]; + + LOG(@"display query drawable"); + +@autoreleasepool{ + id drawable; + + drawable = [layer nextDrawable]; + if(!drawable){ + LOG(@"display couldn't get drawable"); + [self setNeedsDisplay]; + return; + } + + LOG(@"display got drawable"); + + renderPass.colorAttachments[0].texture = drawable.texture; + + cmd = [cbuf renderCommandEncoderWithDescriptor:renderPass]; + [cmd setRenderPipelineState:pipelineState]; + [cmd setFragmentTexture:texture atIndex:0]; + [cmd drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + [cmd endEncoding]; + + [cbuf presentDrawable:drawable]; + drawable = nil; +} + [cbuf addCompletedHandler:^(id cmdBuff){ + if(cmdBuff.error){ + NSLog(@"command buffer finished with error: %@", + cmdBuff.error.localizedDescription); + }else + LOG(@"command buffer finishes present drawable"); + }]; + [cbuf commit]; + + LOG(@"display commit"); +} + +@end + +static uint +msec(void) +{ + return nsec()/1000000; +} + +static uint +keycvt(uint code) +{ + switch(code){ + case '\r': return '\n'; + case '\b': return 127; + case 127: return '\b'; + case NSUpArrowFunctionKey: return Kup; + case NSDownArrowFunctionKey: return Kdown; + case NSLeftArrowFunctionKey: return Kleft; + case NSRightArrowFunctionKey: return Kright; + case NSInsertFunctionKey: return Kins; + case NSDeleteFunctionKey: return Kdel; + case NSHomeFunctionKey: return Khome; + case NSEndFunctionKey: return Kend; + case NSPageUpFunctionKey: return Kpgup; + case NSPageDownFunctionKey: return Kpgdown; + case NSF1FunctionKey: return KF|1; + case NSF2FunctionKey: return KF|2; + case NSF3FunctionKey: return KF|3; + case NSF4FunctionKey: return KF|4; + case NSF5FunctionKey: return KF|5; + case NSF6FunctionKey: return KF|6; + case NSF7FunctionKey: return KF|7; + case NSF8FunctionKey: return KF|8; + case NSF9FunctionKey: return KF|9; + case NSF10FunctionKey: return KF|10; + case NSF11FunctionKey: return KF|11; + case NSF12FunctionKey: return KF|12; + case NSBeginFunctionKey: + case NSPrintScreenFunctionKey: + case NSScrollLockFunctionKey: + case NSF13FunctionKey: + case NSF14FunctionKey: + case NSF15FunctionKey: + case NSF16FunctionKey: + case NSF17FunctionKey: + case NSF18FunctionKey: + case NSF19FunctionKey: + case NSF20FunctionKey: + case NSF21FunctionKey: + case NSF22FunctionKey: + case NSF23FunctionKey: + case NSF24FunctionKey: + case NSF25FunctionKey: + case NSF26FunctionKey: + case NSF27FunctionKey: + case NSF28FunctionKey: + case NSF29FunctionKey: + case NSF30FunctionKey: + case NSF31FunctionKey: + case NSF32FunctionKey: + case NSF33FunctionKey: + case NSF34FunctionKey: + case NSF35FunctionKey: + case NSPauseFunctionKey: + case NSSysReqFunctionKey: + case NSBreakFunctionKey: + case NSResetFunctionKey: + case NSStopFunctionKey: + case NSMenuFunctionKey: + case NSUserFunctionKey: + case NSSystemFunctionKey: + case NSPrintFunctionKey: + case NSClearLineFunctionKey: + case NSClearDisplayFunctionKey: + case NSInsertLineFunctionKey: + case NSDeleteLineFunctionKey: + case NSInsertCharFunctionKey: + case NSDeleteCharFunctionKey: + case NSPrevFunctionKey: + case NSNextFunctionKey: + case NSSelectFunctionKey: + case NSExecuteFunctionKey: + case NSUndoFunctionKey: + case NSRedoFunctionKey: + case NSFindFunctionKey: + case NSHelpFunctionKey: + case NSModeSwitchFunctionKey: return 0; + default: return code; + } +} + +Memimage* +attachscreen(char *label, char *winsize) +{ + LOG(@"attachscreen(%s, %s)", label, winsize); + [AppDelegate + performSelectorOnMainThread:@selector(makewin:) + withObject:[NSValue valueWithPointer:winsize] + waitUntilDone:YES]; + kicklabel(label); + setcursor(nil); + mouseresized = 0; + return initimg(); +} + +static Memimage* +initimg(void) +{ +@autoreleasepool{ + CGFloat scale; + NSSize size; + MTLTextureDescriptor *textureDesc; + + size = [myContent convertSizeToBacking:[myContent bounds].size]; + mouserect = Rect(0, 0, size.width, size.height); + + LOG(@"initimg %.0f %.0f", size.width, size.height); + + img = allocmemimage(mouserect, XRGB32); + if(img == nil) + panic("allocmemimage: %r"); + if(img->data == nil) + panic("img->data == nil"); + + textureDesc = [MTLTextureDescriptor + texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm + width:size.width + height:size.height + mipmapped:NO]; + textureDesc.allowGPUOptimizedContents = YES; + textureDesc.usage = MTLTextureUsageShaderRead; + textureDesc.cpuCacheMode = MTLCPUCacheModeWriteCombined; + texture = [device newTextureWithDescriptor:textureDesc]; + + scale = [win backingScaleFactor]; + [layer setDrawableSize:size]; + [layer setContentsScale:scale]; + + // NOTE: This is not really the display DPI. + // On retina, scale is 2; otherwise it is 1. + // This formula gives us 220 for retina, 110 otherwise. + // That's not quite right but it's close to correct. + // https://en.wikipedia.org/wiki/Retina_display#Models + displaydpi = scale * 110; +} + LOG(@"initimg return"); + + return img; +} + +void +_flushmemscreen(Rectangle r) +{ + LOG(@"_flushmemscreen(%d,%d,%d,%d)", r.min.x, r.min.y, Dx(r), Dy(r)); + + @autoreleasepool{ + [texture + replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r)) + mipmapLevel:0 + withBytes:byteaddr(img, Pt(r.min.x, r.min.y)) + bytesPerRow:img->width*sizeof(u32int)]; + [AppDelegate + performSelectorOnMainThread:@selector(callsetNeedsDisplayInRect:) + withObject:[NSValue valueWithRect:NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r))] + waitUntilDone:NO]; + } +} + +void +setmouse(Point p) +{ + @autoreleasepool{ + NSPoint q; + + LOG(@"setmouse(%d,%d)", p.x, p.y); + q = [win convertPointFromBacking:NSMakePoint(p.x, p.y)]; + LOG(@"(%g, %g) <- fromBacking", q.x, q.y); + q = [myContent convertPoint:q toView:nil]; + LOG(@"(%g, %g) <- toWindow", q.x, q.y); + q = [win convertPointToScreen:q]; + LOG(@"(%g, %g) <- toScreen", q.x, q.y); + // Quartz has the origin of the "global display + // coordinate space" at the top left of the primary + // screen with y increasing downward, while Cocoa has + // the origin at the bottom left of the primary screen + // with y increasing upward. We flip the coordinate + // with a negative sign and shift upward by the height + // of the primary screen. + q.y = NSScreen.screens[0].frame.size.height - q.y; + LOG(@"(%g, %g) <- setmouse", q.x, q.y); + CGWarpMouseCursorPosition(NSPointToCGPoint(q)); + CGAssociateMouseAndMouseCursorPosition(true); + } +} + +char* +getsnarf(void) +{ + NSPasteboard *pb; + NSString *s; + + @autoreleasepool{ + pb = [NSPasteboard generalPasteboard]; + + qlock(&snarfl); + s = [pb stringForType:NSPasteboardTypeString]; + qunlock(&snarfl); + + if(s) + return strdup((char *)[s UTF8String]); + else + return nil; + } +} + +void +putsnarf(char *s) +{ + NSArray *t; + NSPasteboard *pb; + NSString *str; + + if(strlen(s) >= SnarfSize) + return; + + @autoreleasepool{ + t = [NSArray arrayWithObject:NSPasteboardTypeString]; + pb = [NSPasteboard generalPasteboard]; + str = [[NSString alloc] initWithUTF8String:s]; + + qlock(&snarfl); + [pb declareTypes:t owner:nil]; + [pb setString:str forType:NSPasteboardTypeString]; + qunlock(&snarfl); + } +} + +void +kicklabel(char *label) +{ + NSString *s; + + LOG(@"kicklabel(%s)", label); + if(label == nil) + return; + + @autoreleasepool{ + s = [[NSString alloc] initWithUTF8String:label]; + [AppDelegate + performSelectorOnMainThread:@selector(callkicklabel:) + withObject:s + waitUntilDone:NO]; + } +} + +void +setcursor(Cursor *c) +{ + [AppDelegate + performSelectorOnMainThread:@selector(callsetcursor:) + withObject:[NSValue valueWithPointer:c] + waitUntilDone:YES]; +} + +void +topwin(void) +{ + [win + performSelectorOnMainThread: + @selector(makeKeyAndOrderFront:) + withObject:nil + waitUntilDone:YES]; + + [NSApp activateIgnoringOtherApps:YES]; +} + +void +resizeimg(void) +{ + zlock(); + _drawreplacescreenimage(initimg()); + + mouseresized = 1; + zunlock(); + [myContent sendmouse:0]; +} + +void +resizewindow(Rectangle r) +{ + LOG(@"resizewindow %d %d %d %d", r.min.x, r.min.y, Dx(r), Dy(r)); + dispatch_async(dispatch_get_main_queue(), ^(void){ + NSSize s; + + s = [myContent convertSizeFromBacking:NSMakeSize(Dx(r), Dy(r))]; + [win setContentSize:s]; + resizeimg(); + }); +} + +static void +setprocname(const char *s) +{ + CFStringRef process_name; + + process_name = CFStringCreateWithBytes(nil, (uchar*)s, strlen(s), kCFStringEncodingUTF8, false); + + // Adapted from Chrome's mac_util.mm. + // http://src.chromium.org/viewvc/chrome/trunk/src/base/mac/mac_util.mm + // + // Copyright (c) 2012 The Chromium Authors. All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions are + // met: + // + // * Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // * Redistributions in binary form must reproduce the above + // copyright notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // * Neither the name of Google Inc. nor the names of its + // contributors may be used to endorse or promote products derived from + // this software without specific prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // Warning: here be dragons! This is SPI reverse-engineered from WebKit's + // plugin host, and could break at any time (although realistically it's only + // likely to break in a new major release). + // When 10.7 is available, check that this still works, and update this + // comment for 10.8. + + // Private CFType used in these LaunchServices calls. + typedef CFTypeRef PrivateLSASN; + typedef PrivateLSASN (*LSGetCurrentApplicationASNType)(); + typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN, + CFStringRef, + CFStringRef, + CFDictionaryRef*); + + static LSGetCurrentApplicationASNType ls_get_current_application_asn_func = + NULL; + static LSSetApplicationInformationItemType + ls_set_application_information_item_func = NULL; + static CFStringRef ls_display_name_key = NULL; + + static bool did_symbol_lookup = false; + if (!did_symbol_lookup) { + did_symbol_lookup = true; + CFBundleRef launch_services_bundle = + CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); + if (!launch_services_bundle) { + fprint(2, "Failed to look up LaunchServices bundle\n"); + return; + } + + ls_get_current_application_asn_func = + (LSGetCurrentApplicationASNType)( + CFBundleGetFunctionPointerForName( + launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN"))); + if (!ls_get_current_application_asn_func) + fprint(2, "Could not find _LSGetCurrentApplicationASN\n"); + + ls_set_application_information_item_func = + (LSSetApplicationInformationItemType)( + CFBundleGetFunctionPointerForName( + launch_services_bundle, + CFSTR("_LSSetApplicationInformationItem"))); + if (!ls_set_application_information_item_func) + fprint(2, "Could not find _LSSetApplicationInformationItem\n"); + + CFStringRef* key_pointer = (CFStringRef*)( + CFBundleGetDataPointerForName(launch_services_bundle, + CFSTR("_kLSDisplayNameKey"))); + ls_display_name_key = key_pointer ? *key_pointer : NULL; + if (!ls_display_name_key) + fprint(2, "Could not find _kLSDisplayNameKey\n"); + + // Internally, this call relies on the Mach ports that are started up by the + // Carbon Process Manager. In debug builds this usually happens due to how + // the logging layers are started up; but in release, it isn't started in as + // much of a defined order. So if the symbols had to be loaded, go ahead + // and force a call to make sure the manager has been initialized and hence + // the ports are opened. + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + } + if (!ls_get_current_application_asn_func || + !ls_set_application_information_item_func || + !ls_display_name_key) { + return; + } + + PrivateLSASN asn = ls_get_current_application_asn_func(); + // Constant used by WebKit; what exactly it means is unknown. + const int magic_session_constant = -2; + OSErr err = + ls_set_application_information_item_func(magic_session_constant, asn, + ls_display_name_key, + process_name, + NULL /* optional out param */); + if(err != noErr) + fprint(2, "Call to set process name failed\n"); +} diff --git a/src/cmd/devdraw/cocoa-screen.h b/src/cmd/devdraw/cocoa-screen.h index 3c4c94c5..7b41c34b 100644 --- a/src/cmd/devdraw/cocoa-screen.h +++ b/src/cmd/devdraw/cocoa-screen.h @@ -16,5 +16,9 @@ void servep9p(void); void zlock(void); void zunlock(void); +void resizeimg(void); + Rectangle mouserect; -int mouseresized; + +int mouseresized; +void resizewindow(Rectangle); diff --git a/src/cmd/devdraw/cocoa-srv.c b/src/cmd/devdraw/cocoa-srv.c index 197fd512..6f9449ad 100644 --- a/src/cmd/devdraw/cocoa-srv.c +++ b/src/cmd/devdraw/cocoa-srv.c @@ -21,7 +21,7 @@ typedef struct Tagbuf Tagbuf; struct Kbdbuf { - Rune r[32]; + Rune r[256]; int ri; int wi; int stall; @@ -29,7 +29,7 @@ struct Kbdbuf struct Mousebuf { - Mouse m[32]; + Mouse m[256]; Mouse last; int ri; int wi; @@ -38,7 +38,7 @@ struct Mousebuf struct Tagbuf { - int t[32]; + int t[256]; int ri; int wi; }; @@ -97,7 +97,7 @@ servep9p(void) /* pick off messages one by one */ if(convM2W(mbuf, nn+4, &m) <= 0) sysfatal("cannot convert message"); - if(trace) fprint(2, "<- %W\n", &m); + if(trace) fprint(2, "%ud [%d] <- %W\n", nsec()/1000000, threadid(), &m); runmsg(&m); } } @@ -191,6 +191,7 @@ runmsg(Wsysmsg *m) break; case Trddraw: + zlock(); n = m->count; if(n > sizeof buf) n = sizeof buf; @@ -202,13 +203,16 @@ runmsg(Wsysmsg *m) m->data = buf; replymsg(m); } + zunlock(); break; case Twrdraw: + zlock(); if(_drawmsgwrite(m->data, m->count) < 0) replyerror(m); else replymsg(m); + zunlock(); break; case Ttop: @@ -217,7 +221,9 @@ runmsg(Wsysmsg *m) break; case Tresize: - // _xresizewindow(m->rect); +#if OSX_VERSION >= 101400 + resizewindow(m->rect); +#endif replymsg(m); break; } @@ -238,7 +244,7 @@ replymsg(Wsysmsg *m) if(m->type%2 == 0) m->type++; - if(trace) fprint(2, "-> %W\n", m); + if(trace) fprint(2, "%ud [%d] -> %W\n", nsec()/1000000, threadid(), m); /* copy to output buffer */ n = sizeW2M(m); @@ -293,11 +299,11 @@ matchmouse(void) mousetags.ri = 0; m.mouse = mouse.m[mouse.ri]; m.resized = mouseresized; + mouseresized = 0; /* if(m.resized) fprint(2, "sending resize\n"); */ - mouseresized = 0; mouse.ri++; if(mouse.ri == nelem(mouse.m)) mouse.ri = 0; @@ -367,8 +373,6 @@ abortcompose(void) keystroke(Kalt); } -void resizeimg(void); - void keystroke(int c) { diff --git a/src/cmd/devdraw/cocoa-thread.c b/src/cmd/devdraw/cocoa-thread.c index c9b280f7..92b92d2c 100644 --- a/src/cmd/devdraw/cocoa-thread.c +++ b/src/cmd/devdraw/cocoa-thread.c @@ -25,4 +25,11 @@ qunlock(QLock *q) { pthread_mutex_unlock(&q->m); } + +int +threadid(void) +{ + return pthread_mach_thread_np(pthread_self()); +} + #endif diff --git a/src/cmd/devdraw/cocoa-thread.h b/src/cmd/devdraw/cocoa-thread.h index c2f3e982..d5793f0a 100644 --- a/src/cmd/devdraw/cocoa-thread.h +++ b/src/cmd/devdraw/cocoa-thread.h @@ -30,4 +30,5 @@ void qlock(QLock*); void qunlock(QLock*); + int threadid(void); #endif diff --git a/src/cmd/devdraw/mkfile b/src/cmd/devdraw/mkfile index cad244ac..2e40087e 100644 --- a/src/cmd/devdraw/mkfile +++ b/src/cmd/devdraw/mkfile @@ -35,6 +35,9 @@ latin1.h: $PLAN9/lib/keyboard $O.mklatinkbd $O.macargv: $MACARGV $LD -o $target $prereq +cocoa-screen-metal-objc.$O: cocoa-screen-metal.m + $CC $CFLAGS $OBJCFLAGS -o $target cocoa-screen-metal.m + %-objc.$O: %.m $CC $CFLAGS -o $target $stem.m diff --git a/src/cmd/devdraw/mkwsysrules.sh b/src/cmd/devdraw/mkwsysrules.sh index 9c422261..98d6799d 100644 --- a/src/cmd/devdraw/mkwsysrules.sh +++ b/src/cmd/devdraw/mkwsysrules.sh @@ -60,7 +60,12 @@ elif [ $WSYSTYPE = osx ]; then echo 'WSYSOFILES=$WSYSOFILES osx-screen-carbon-objc.o osx-draw.o osx-srv.o' echo 'MACARGV=macargv.o' elif [ $WSYSTYPE = osx-cocoa ]; then - echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-objc.o cocoa-srv.o cocoa-thread.o' + if sw_vers|awk '/ProductVersion/{split($2,a,".");exit(a[2]<14)}' >/dev/null; then # 0 is true in sh. + echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc' + echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-metal-objc.o cocoa-srv.o cocoa-thread.o' + else + echo 'WSYSOFILES=$WSYSOFILES osx-draw.o cocoa-screen-objc.o cocoa-srv.o cocoa-thread.o' + fi echo 'MACARGV=macargv-objc.o' elif [ $WSYSTYPE = nowsys ]; then echo 'WSYSOFILES=nowsys.o' -- cgit v1.2.3 From 8581c2b56763d7787604c8c833d2bd78bdc6a466 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Nov 2018 20:22:59 -0500 Subject: libdraw: add Cursor2, a 32x32 high-res cursor Also add setcursor2, esetcursor2, and draw protocol encoding. Calls to the old setcursor, esetcursor create a 32x32 by pixel doubling when needed. --- src/libdraw/cursor.c | 32 ++++++++++++++++++++++++++++++++ src/libdraw/drawclient.c | 7 ++++++- src/libdraw/drawfcall.c | 14 +++++++++++--- src/libdraw/event.c | 8 +++++++- src/libdraw/mkfile | 1 + src/libdraw/mouse.c | 8 +++++++- 6 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/libdraw/cursor.c (limited to 'src') diff --git a/src/libdraw/cursor.c b/src/libdraw/cursor.c new file mode 100644 index 00000000..58f447b1 --- /dev/null +++ b/src/libdraw/cursor.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +static uint8 expand[16] = { + 0x00, 0x03, 0x0c, 0x0f, + 0x30, 0x33, 0x3c, 0x3f, + 0xc0, 0xc3, 0xcc, 0xcf, + 0xf0, 0xf3, 0xfc, 0xff, +}; + +void +scalecursor(Cursor2 *c2, Cursor *c) +{ + int y; + + c2->offset.x = 2*c->offset.x; + c2->offset.y = 2*c->offset.y; + memset(c2->clr, 0, sizeof c2->clr); + memset(c2->set, 0, sizeof c2->set); + for(y = 0; y < 16; y++) { + c2->clr[8*y] = c2->clr[8*y+4] = expand[c->clr[2*y]>>4]; + c2->set[8*y] = c2->set[8*y+4] = expand[c->set[2*y]>>4]; + c2->clr[8*y+1] = c2->clr[8*y+5] = expand[c->clr[2*y]&15]; + c2->set[8*y+1] = c2->set[8*y+5] = expand[c->set[2*y]&15]; + c2->clr[8*y+2] = c2->clr[8*y+6] = expand[c->clr[2*y+1]>>4]; + c2->set[8*y+2] = c2->set[8*y+6] = expand[c->set[2*y+1]>>4]; + c2->clr[8*y+3] = c2->clr[8*y+7] = expand[c->clr[2*y+1]&15]; + c2->set[8*y+3] = c2->set[8*y+7] = expand[c->set[2*y+1]&15]; + } +} diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c index f0c09430..de20d3a3 100644 --- a/src/libdraw/drawclient.c +++ b/src/libdraw/drawclient.c @@ -292,17 +292,22 @@ _displaymoveto(Display *d, Point p) } int -_displaycursor(Display *d, Cursor *c) +_displaycursor(Display *d, Cursor *c, Cursor2 *c2) { Wsysmsg tx, rx; tx.type = Tcursor; if(c == nil){ memset(&tx.cursor, 0, sizeof tx.cursor); + memset(&tx.cursor2, 0, sizeof tx.cursor2); tx.arrowcursor = 1; }else{ tx.arrowcursor = 0; tx.cursor = *c; + if(c2 != nil) + tx.cursor2 = *c2; + else + scalecursor(&tx.cursor2, c); } return displayrpc(d, &tx, &rx, nil); } diff --git a/src/libdraw/drawfcall.c b/src/libdraw/drawfcall.c index e2d3c642..e36413b6 100644 --- a/src/libdraw/drawfcall.c +++ b/src/libdraw/drawfcall.c @@ -64,7 +64,7 @@ sizeW2M(Wsysmsg *m) case Tmoveto: return 4+1+1+4+4; case Tcursor: - return 4+1+1+4+4+2*16+2*16+1; + return 4+1+1+4+4+2*16+2*16+4+4+4*32+4*32+1; case Rerror: return 4+1+1+_stringsize(m->error); case Rrdkbd: @@ -141,7 +141,11 @@ convW2M(Wsysmsg *m, uchar *p, uint n) PUT(p+10, m->cursor.offset.y); memmove(p+14, m->cursor.clr, sizeof m->cursor.clr); memmove(p+46, m->cursor.set, sizeof m->cursor.set); - p[78] = m->arrowcursor; + PUT(p+78, m->cursor2.offset.x); + PUT(p+82, m->cursor2.offset.y); + memmove(p+86, m->cursor2.clr, sizeof m->cursor2.clr); + memmove(p+214, m->cursor2.set, sizeof m->cursor2.set); + p[342] = m->arrowcursor; break; case Rrdkbd: PUT2(p+6, m->rune); @@ -229,7 +233,11 @@ convM2W(uchar *p, uint n, Wsysmsg *m) GET(p+10, m->cursor.offset.y); memmove(m->cursor.clr, p+14, sizeof m->cursor.clr); memmove(m->cursor.set, p+46, sizeof m->cursor.set); - m->arrowcursor = p[78]; + GET(p+78, m->cursor2.offset.x); + GET(p+82, m->cursor2.offset.y); + memmove(m->cursor2.clr, p+86, sizeof m->cursor2.clr); + memmove(m->cursor2.set, p+214, sizeof m->cursor2.set); + m->arrowcursor = p[342]; break; case Rrdkbd: GET2(p+6, m->rune); diff --git a/src/libdraw/event.c b/src/libdraw/event.c index f113d1f0..b369c020 100644 --- a/src/libdraw/event.c +++ b/src/libdraw/event.c @@ -416,7 +416,13 @@ emoveto(Point pt) void esetcursor(Cursor *c) { - _displaycursor(display, c); + _displaycursor(display, c, nil); +} + +void +esetcursor2(Cursor *c, Cursor2 *c2) +{ + _displaycursor(display, c, c2); } int diff --git a/src/libdraw/mkfile b/src/libdraw/mkfile index ddb0e833..003bf3ce 100644 --- a/src/libdraw/mkfile +++ b/src/libdraw/mkfile @@ -14,6 +14,7 @@ OFILES=\ cloadimage.$O\ computil.$O\ creadimage.$O\ + cursor.$O\ debug.$O\ defont.$O\ draw.$O\ diff --git a/src/libdraw/mouse.c b/src/libdraw/mouse.c index ad1a069b..fc486be4 100644 --- a/src/libdraw/mouse.c +++ b/src/libdraw/mouse.c @@ -85,6 +85,12 @@ initmouse(char *file, Image *i) void setcursor(Mousectl *mc, Cursor *c) { - _displaycursor(mc->display, c); + _displaycursor(mc->display, c, nil); +} + +void +setcursor2(Mousectl *mc, Cursor *c, Cursor2 *c2) +{ + _displaycursor(mc->display, c, c2); } -- cgit v1.2.3 From be0a15c47b75dc73a5c389cca125692f0cfdf726 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Nov 2018 20:24:38 -0500 Subject: tweak: add support for Cursor2 --- src/cmd/draw/tweak.c | 108 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/cmd/draw/tweak.c b/src/cmd/draw/tweak.c index 9d7cd601..89fdef32 100644 --- a/src/cmd/draw/tweak.c +++ b/src/cmd/draw/tweak.c @@ -30,7 +30,7 @@ enum Up = 1, Down = 0, Mag = 4, - Maxmag = 10 + Maxmag = 20 }; enum @@ -161,7 +161,7 @@ Image *values[256]; Image *greyvalues[256]; uchar data[8192]; -Thing* tget(char*); +Thing* tget(char*, int); void mesg(char*, ...); void drawthing(Thing*, int); void xselect(void); @@ -184,6 +184,7 @@ main(volatile int argc, char **volatile argv) volatile int i; Event e; Thing *t; + Thing *nt; ARGBEGIN{ case 'W': @@ -209,9 +210,14 @@ main(volatile int argc, char **volatile argv) setjmp(err); for(; inext; + t->next = 0; drawthing(t, 1); + if(nt) + drawthing(nt, 1); + } flushimage(display, 1); } file = 0; @@ -382,6 +388,8 @@ stext(Thing *t, char *l0, char *l1) }else if(t->s) sprint(l1, "offset(hex): %ux n:%d height:%d ascent:%d", t->off, t->s->n, t->s->height, t->s->ascent); + else if(t->face == CURSOR) + sprint(l0+strlen(l0), " cursor:%d", Dx(t->b->r)); } void @@ -569,7 +577,7 @@ tohex(int c) } Thing* -tget(char *file) +tget(char *file, int extra) { int i, j, fd, face, x, y, c, chan; Image *b; @@ -577,8 +585,9 @@ tget(char *file) Thing *t; Dir *volatile d; jmp_buf oerr; - uchar buf[256]; + uchar buf[300]; char *data; + Rectangle r; buf[0] = '\0'; errstr((char*)buf, sizeof buf); /* flush pending error message */ @@ -628,17 +637,15 @@ tget(char *file) close(fd); goto Err; } - b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill); - if(b == 0){ - mesg("image alloc failed file %s: %r", file); - free(data); - close(fd); - goto Err; - } i = 0; - for(x=0;x<64; ){ - if((c=data[i]) == '\0') - goto ill; + for(x=0;; ){ + if((c=data[i]) == '\0' || x > 256) { + if(x == 64 || x == 256) + goto HaveCursor; + mesg("ill-formed cursor file %s", file); + close(fd); + goto Err; + } if(c=='0' && data[i+1] == 'x'){ i += 2; continue; @@ -650,7 +657,19 @@ tget(char *file) } i++; } - loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf); + HaveCursor: + if(x == 64) + r = Rect(0, 0, 16, 32); + else + r = Rect(0, 0, 32, 64); + b = allocimage(display, r, GREY1, 0, DNofill); + if(b == 0){ + mesg("image alloc failed file %s: %r", file); + free(data); + close(fd); + goto Err; + } + loadimage(b, r, buf, sizeof buf); free(data); }else if(memcmp(buf, "0x", 2)==0){ /* @@ -752,7 +771,7 @@ tget(char *file) s = readsubfonti(display, file, fd, b, 0); } close(fd); - t = malloc(sizeof(Thing)); + t = mallocz(sizeof(Thing), 1); if(t == 0){ nomem: mesg("malloc failed: %r"); @@ -775,6 +794,40 @@ tget(char *file) t->c = -1; t->mag = 1; t->off = 0; + if(face == CURSOR && extra && Dx(t->b->r) == 16) { + // Make 32x32 cursor as second image. + Thing *nt; + Cursor c; + Cursor2 c2; + + nt = mallocz(sizeof(Thing), 1); + if(nt == 0) + goto nomem; + nt->name = strdup(""); + if(nt->name == 0) { + free(nt); + goto nomem; + } + b = allocimage(display, Rect(0, 0, 32, 64), GREY1, 0, DNofill); + if(b == nil) { + free(nt->name); + free(nt); + goto nomem; + } + memmove(c.clr, buf, 64); + scalecursor(&c2, &c); + memmove(buf, c2.clr, 256); + loadimage(b, b->r, buf, sizeof buf); + t->next = nt; + nt->b = b; + nt->s = 0; + nt->face = CURSOR; + nt->mod = 0; + nt->parent = 0; + nt->c = -1; + nt->mag = 1; + nt->off = 0; + } memmove(err, oerr, sizeof err); return t; } @@ -1637,18 +1690,13 @@ twrite(Thing *t) Bprint(&buf, "%.2x", data[i+j]); Bprint(&buf, ", "); } - if(t->face == CURSOR){ - switch(y){ - case 3: case 7: case 11: case 19: case 23: case 27: - Bprint(&buf, "\n "); - break; - case 15: + if(t->face == CURSOR) { + if(y == Dy(r)/2-1) Bprint(&buf, "},\n{"); - break; - case 31: + else if(y == Dy(r)-1) Bprint(&buf, "}\n"); - break; - } + else + Bprint(&buf, "\n\t"); }else Bprint(&buf, "\n"); } @@ -1759,7 +1807,7 @@ tread(Thing *t) if(t->parent) t = t->parent; - new = tget(t->name); + new = tget(t->name, 0); if(new == 0) return; nclosed = 0; @@ -2025,7 +2073,7 @@ menu(void) switch(sel){ case Mopen: if(type(buf, "file")){ - t = tget(buf); + t = tget(buf, 0); if(t) drawthing(t, 1); } -- cgit v1.2.3 From 7d43dde539378fb5730df6ce961f7916f495746e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Nov 2018 20:28:56 -0500 Subject: devdraw: add Cursor2 support on macOS 10.14 Mojave This replaces the pixel-art scaling algorithm used for upscaling before. The results were not crisp enough to serve as everyday cursors. --- src/cmd/devdraw/bigarrow.h | 70 ++++++++++++++++++++++++++++++++++++ src/cmd/devdraw/cocoa-screen-metal.m | 62 ++++++++++++++------------------ src/cmd/devdraw/cocoa-screen.h | 2 +- src/cmd/devdraw/cocoa-screen.m | 10 +++++- src/cmd/devdraw/cocoa-srv.c | 6 ++-- src/cmd/devdraw/mkfile | 2 ++ src/cmd/devdraw/osx-screen.h | 2 +- src/cmd/devdraw/osx-srv.c | 4 +-- 8 files changed, 113 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/cmd/devdraw/bigarrow.h b/src/cmd/devdraw/bigarrow.h index 3b66c954..1221ec8c 100644 --- a/src/cmd/devdraw/bigarrow.h +++ b/src/cmd/devdraw/bigarrow.h @@ -11,3 +11,73 @@ Cursor bigarrow = { 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, }, }; + +Cursor2 bigarrow2 = { + { -2, -2 }, + { 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x03, + 0xC0, 0x00, 0x00, 0x07, + 0xC0, 0x00, 0x00, 0x1E, + 0xC0, 0x00, 0x00, 0x3C, + 0xC0, 0x00, 0x00, 0xF0, + 0xC0, 0x00, 0x03, 0xE0, + 0xC0, 0x00, 0x0F, 0x80, + 0xC0, 0x00, 0x0E, 0x00, + 0xC0, 0x00, 0x07, 0x00, + 0xC0, 0x00, 0x03, 0x80, + 0xC0, 0x00, 0x01, 0xC0, + 0xC0, 0x00, 0x00, 0xE0, + 0xC0, 0x00, 0x00, 0x70, + 0xC0, 0x00, 0x00, 0x38, + 0xC0, 0x00, 0x00, 0x1C, + 0xC0, 0x00, 0x00, 0x0E, + 0xC0, 0x00, 0x00, 0x07, + 0xC0, 0x00, 0x00, 0x03, + 0xC0, 0xC0, 0x00, 0x07, + 0xC0, 0xE0, 0x00, 0x0E, + 0xC1, 0xF0, 0x00, 0x1C, + 0xC1, 0xB8, 0x00, 0x38, + 0xC3, 0x9C, 0x00, 0x70, + 0xC3, 0x0E, 0x00, 0xE0, + 0xC7, 0x07, 0x01, 0xC0, + 0xCE, 0x03, 0x83, 0x80, + 0xCC, 0x01, 0xC7, 0x00, + 0xDC, 0x00, 0xEE, 0x00, + 0xF8, 0x00, 0x7C, 0x00, + 0xF0, 0x00, 0x38, 0x00, + }, + { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xF8, + 0x3F, 0xFF, 0xFF, 0xE0, + 0x3F, 0xFF, 0xFF, 0xC0, + 0x3F, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xFF, 0x80, + 0x3F, 0xFF, 0xFF, 0xC0, + 0x3F, 0xFF, 0xFF, 0xE0, + 0x3F, 0xFF, 0xFF, 0xF0, + 0x3F, 0xFF, 0xFF, 0xF8, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0x3F, 0xFF, 0xF8, + 0x3F, 0x1F, 0xFF, 0xF0, + 0x3E, 0x0F, 0xFF, 0xE0, + 0x3E, 0x07, 0xFF, 0xC0, + 0x3C, 0x03, 0xFF, 0x80, + 0x3C, 0x01, 0xFF, 0x00, + 0x38, 0x00, 0xFE, 0x00, + 0x30, 0x00, 0x7C, 0x00, + 0x30, 0x00, 0x38, 0x00, + 0x20, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + } +}; diff --git a/src/cmd/devdraw/cocoa-screen-metal.m b/src/cmd/devdraw/cocoa-screen-metal.m index c82ce0bc..049d1c5c 100644 --- a/src/cmd/devdraw/cocoa-screen-metal.m +++ b/src/cmd/devdraw/cocoa-screen-metal.m @@ -252,21 +252,30 @@ threadmain(int argc, char **argv) [myContent enlargeLastInputRect:r]; } +typedef struct Cursors Cursors; +struct Cursors { + Cursor *c; + Cursor2 *c2; +}; + + (void)callsetcursor:(NSValue *)v { + Cursors *cs; Cursor *c; + Cursor2 *c2; NSBitmapImageRep *r, *r2; NSImage *i; NSPoint p; - uint b, x, y, a; uchar *plane[5], *plane2[5]; - uchar pu, pb, pl, pr, pc; // upper, bottom, left, right, center - uchar pul, pur, pbl, pbr; - uchar ful, fur, fbl, fbr; + int b; - c = [v pointerValue]; + cs = [v pointerValue]; + c = cs->c; if(!c) c = &bigarrow; + c2 = cs->c2; + if(!c2) + c2 = &bigarrow2; r = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil @@ -280,7 +289,7 @@ threadmain(int argc, char **argv) bytesPerRow:2 bitsPerPixel:0]; [r getBitmapDataPlanes:plane]; - for(b=0; b<2*16; b++){ + for(b=0; bset); b++){ plane[0][b] = ~c->set[b] & c->clr[b]; plane[1][b] = c->set[b] | c->clr[b]; } @@ -297,33 +306,9 @@ threadmain(int argc, char **argv) bytesPerRow:4 bitsPerPixel:0]; [r2 getBitmapDataPlanes:plane2]; - // https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms#EPX/Scale2×/AdvMAME2× - for(a=0; a<2; a++){ - for(y=0; y<16; y++){ - for(x=0; x<2; x++){ - pc = plane[a][x+2*y]; - pu = y==0 ? pc : plane[a][x+2*(y-1)]; - pb = y==15 ? pc : plane[a][x+2*(y+1)]; - pl = (pc>>1) | (x==0 ? pc&0x80 : (plane[a][x-1+2*y]&1)<<7); - pr = (pc<<1) | (x==1 ? pc&1 : (plane[a][x+1+2*y]&0x80)>>7); - ful = ~(pl^pu) & (pl^pb) & (pu^pr); - pul = (ful & pu) | (~ful & pc); - fur = ~(pu^pr) & (pu^pl) & (pr^pb); - pur = (fur & pr) | (~fur & pc); - fbl = ~(pb^pl) & (pb^pr) & (pl^pu); - pbl = (fbl & pl) | (~fbl & pc); - fbr = ~(pr^pb) & (pr^pu) & (pb^pl); - pbr = (fbr & pb) | (~fbr & pc); - plane2[a][2*x+4*2*y] = (pul&0x80) | ((pul&0x40)>>1) | ((pul&0x20)>>2) | ((pul&0x10)>>3) - | ((pur&0x80)>>1) | ((pur&0x40)>>2) | ((pur&0x20)>>3) | ((pur&0x10)>>4); - plane2[a][2*x+1+4*2*y] = ((pul&0x8)<<4) | ((pul&0x4)<<3) | ((pul&0x2)<<2) | ((pul&0x1)<<1) - | ((pur&0x8)<<3) | ((pur&0x4)<<2) | ((pur&0x2)<<1) | (pur&0x1); - plane2[a][2*x+4*(2*y+1)] = (pbl&0x80) | ((pbl&0x40)>>1) | ((pbl&0x20)>>2) | ((pbl&0x10)>>3) - | ((pbr&0x80)>>1) | ((pbr&0x40)>>2) | ((pbr&0x20)>>3) | ((pbr&0x10)>>4); - plane2[a][2*x+1+4*(2*y+1)] = ((pbl&0x8)<<4) | ((pbl&0x4)<<3) | ((pbl&0x2)<<2) | ((pbl&0x1)<<1) - | ((pbr&0x8)<<3) | ((pbr&0x4)<<2) | ((pbr&0x2)<<1) | (pbr&0x1); - } - } + for(b=0; bset); b++){ + plane2[0][b] = ~c2->set[b] & c2->clr[b]; + plane2[1][b] = c2->set[b] | c2->clr[b]; } // For checking out the cursor bitmap image @@ -943,7 +928,7 @@ attachscreen(char *label, char *winsize) withObject:[NSValue valueWithPointer:winsize] waitUntilDone:YES]; kicklabel(label); - setcursor(nil); + setcursor(nil, nil); mouseresized = 0; return initimg(); } @@ -1099,11 +1084,16 @@ kicklabel(char *label) } void -setcursor(Cursor *c) +setcursor(Cursor *c, Cursor2 *c2) { + Cursors cs; + + cs.c = c; + cs.c2 = c2; + [AppDelegate performSelectorOnMainThread:@selector(callsetcursor:) - withObject:[NSValue valueWithPointer:c] + withObject:[NSValue valueWithPointer:&cs] waitUntilDone:YES]; } diff --git a/src/cmd/devdraw/cocoa-screen.h b/src/cmd/devdraw/cocoa-screen.h index 7b41c34b..b5e3c701 100644 --- a/src/cmd/devdraw/cocoa-screen.h +++ b/src/cmd/devdraw/cocoa-screen.h @@ -2,7 +2,7 @@ Memimage *attachscreen(char*, char*); void setmouse(Point); -void setcursor(Cursor*); +void setcursor(Cursor*, Cursor2*); void setlabel(char*); char* getsnarf(void); void putsnarf(char*); diff --git a/src/cmd/devdraw/cocoa-screen.m b/src/cmd/devdraw/cocoa-screen.m index 16053eaa..c2489a6c 100644 --- a/src/cmd/devdraw/cocoa-screen.m +++ b/src/cmd/devdraw/cocoa-screen.m @@ -1410,8 +1410,10 @@ kicklabel0(char *label) { } void -setcursor(Cursor *c) +setcursor(Cursor *c, Cursor2 *c2) { + USED(c2); + /* * No cursor change unless in main thread. */ @@ -1658,3 +1660,9 @@ setprocname(const char *s) if(err != noErr) fprint(2, "Call to set process name failed\n"); } + +void +resizewindow(Rectangle r) +{ + USED(r); +} diff --git a/src/cmd/devdraw/cocoa-srv.c b/src/cmd/devdraw/cocoa-srv.c index 6f9449ad..329dd71f 100644 --- a/src/cmd/devdraw/cocoa-srv.c +++ b/src/cmd/devdraw/cocoa-srv.c @@ -163,9 +163,9 @@ runmsg(Wsysmsg *m) case Tcursor: if(m->arrowcursor) - setcursor(nil); + setcursor(nil, nil); else - setcursor(&m->cursor); + setcursor(&m->cursor, &m->cursor2); replymsg(m); break; @@ -221,9 +221,7 @@ runmsg(Wsysmsg *m) break; case Tresize: -#if OSX_VERSION >= 101400 resizewindow(m->rect); -#endif replymsg(m); break; } diff --git a/src/cmd/devdraw/mkfile b/src/cmd/devdraw/mkfile index 2e40087e..7f0c2a20 100644 --- a/src/cmd/devdraw/mkfile +++ b/src/cmd/devdraw/mkfile @@ -3,6 +3,8 @@ TARG=devdraw +SHORTLIB=draw memdraw + WSYSOFILES=\ devdraw.$O\ latin1.$O\ diff --git a/src/cmd/devdraw/osx-screen.h b/src/cmd/devdraw/osx-screen.h index f50d8dfe..d5ba3dd2 100644 --- a/src/cmd/devdraw/osx-screen.h +++ b/src/cmd/devdraw/osx-screen.h @@ -5,7 +5,7 @@ void zunlock(void); Memimage *attachscreen(char*, char*); void setmouse(Point); -void setcursor(Cursor*); +void setcursor(Cursor*, Cursor2*); void setlabel(char*); char* getsnarf(void); void putsnarf(char*); diff --git a/src/cmd/devdraw/osx-srv.c b/src/cmd/devdraw/osx-srv.c index 6cbb5235..d0a1c2d3 100644 --- a/src/cmd/devdraw/osx-srv.c +++ b/src/cmd/devdraw/osx-srv.c @@ -230,9 +230,9 @@ runmsg(Wsysmsg *m) case Tcursor: if(m->arrowcursor) - setcursor(nil); + setcursor(nil, nil); else - setcursor(&m->cursor); + setcursor(&m->cursor, &m->cursor2); replymsg(m); break; -- cgit v1.2.3 From 43b0d532bd3c1e4fbd4385c6470db12dbf7a5ad8 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Nov 2018 20:52:18 -0500 Subject: acme: add 32x32 boxcursor The only difference from the upscaled 16x16 is a one-pixel adjustment in the offset position, but this at least exercises setcursor2. --- src/cmd/acme/acme.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cmd/acme/cols.c | 2 +- src/cmd/acme/dat.h | 1 + src/cmd/acme/rows.c | 2 +- 4 files changed, 71 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c index 742aabdf..12701f23 100644 --- a/src/cmd/acme/acme.c +++ b/src/cmd/acme/acme.c @@ -966,6 +966,74 @@ Cursor boxcursor = { 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00} }; +Cursor2 boxcursor2 = { + {-15, -15}, + {0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0x00, 0x00, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + void iconinit(void) { diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c index b1fe23ba..6215e044 100644 --- a/src/cmd/acme/cols.c +++ b/src/cmd/acme/cols.c @@ -477,7 +477,7 @@ coldragwin(Column *c, Window *w, int but) Column *nc; clearmouse(); - setcursor(mousectl, &boxcursor); + setcursor2(mousectl, &boxcursor, &boxcursor2); b = mouse->buttons; op = mouse->xy; while(mouse->buttons == b) diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h index 8c4b14ee..8a81c97d 100644 --- a/src/cmd/acme/dat.h +++ b/src/cmd/acme/dat.h @@ -525,6 +525,7 @@ Image *button; Image *but2col; Image *but3col; Cursor boxcursor; +Cursor2 boxcursor2; Row row; int timerpid; Disk *disk; diff --git a/src/cmd/acme/rows.c b/src/cmd/acme/rows.c index 8cff0855..83c64594 100644 --- a/src/cmd/acme/rows.c +++ b/src/cmd/acme/rows.c @@ -148,7 +148,7 @@ rowdragcol(Row *row, Column *c, int _0) USED(_0); clearmouse(); - setcursor(mousectl, &boxcursor); + setcursor2(mousectl, &boxcursor, &boxcursor2); b = mouse->buttons; op = mouse->xy; while(mouse->buttons == b) -- cgit v1.2.3 From 3d6fc088f028e0267ecbc64e21eadbe9ca1bcb83 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Sat, 6 Oct 2018 00:13:04 +0200 Subject: devdraw: remove os x 10.5 compatibility code --- src/cmd/devdraw/mkwsysrules.sh | 10 +- src/cmd/devdraw/osx-screen-carbon.m | 1302 ----------------------------------- src/cmd/devdraw/osx-screen.h | 18 - src/cmd/devdraw/osx-srv.c | 462 ------------- 4 files changed, 2 insertions(+), 1790 deletions(-) delete mode 100644 src/cmd/devdraw/osx-screen-carbon.m delete mode 100644 src/cmd/devdraw/osx-screen.h delete mode 100644 src/cmd/devdraw/osx-srv.c (limited to 'src') diff --git a/src/cmd/devdraw/mkwsysrules.sh b/src/cmd/devdraw/mkwsysrules.sh index 98d6799d..e94afbd3 100644 --- a/src/cmd/devdraw/mkwsysrules.sh +++ b/src/cmd/devdraw/mkwsysrules.sh @@ -23,7 +23,8 @@ fi if [ "x$WSYSTYPE" = "x" ]; then if [ "x`uname`" = "xDarwin" ]; then if sw_vers | grep 'ProductVersion: 10\.[0-5]\.' >/dev/null; then - WSYSTYPE=osx + echo 1>&2 'OS X 10.5 and older are not supported' + exit 1 else #echo 1>&2 'WARNING: OS X Lion is not working. Copy binaries from a Snow Leopard system.' WSYSTYPE=osx-cocoa @@ -52,13 +53,6 @@ if [ $WSYSTYPE = x11 ]; then echo 'HFILES=$HFILES $XHFILES' XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'` echo 'WSYSOFILES=$WSYSOFILES '$XO -elif [ $WSYSTYPE = osx ]; then - if [ -d /System/Library/PrivateFrameworks/MultitouchSupport.framework ]; then - echo 'CFLAGS=$CFLAGS -DMULTITOUCH' - echo 'LDFLAGS=$LDFLAGS -F/System/Library/PrivateFrameworks' - fi - echo 'WSYSOFILES=$WSYSOFILES osx-screen-carbon-objc.o osx-draw.o osx-srv.o' - echo 'MACARGV=macargv.o' elif [ $WSYSTYPE = osx-cocoa ]; then if sw_vers|awk '/ProductVersion/{split($2,a,".");exit(a[2]<14)}' >/dev/null; then # 0 is true in sh. echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc' diff --git a/src/cmd/devdraw/osx-screen-carbon.m b/src/cmd/devdraw/osx-screen-carbon.m deleted file mode 100644 index d41e9d10..00000000 --- a/src/cmd/devdraw/osx-screen-carbon.m +++ /dev/null @@ -1,1302 +0,0 @@ -#define Point OSXPoint -#define Rect OSXRect -#define Cursor OSXCursor -#include -#import -#ifdef MULTITOUCH -#include -#include -#endif -#undef Rect -#undef Point -#undef Cursor -#undef offsetof -#undef nil - -#include "u.h" -#include "libc.h" -#include -#include -#include -#include -#include "mouse.h" -#include -#include "osx-screen.h" -#include "osx-keycodes.h" -#include "devdraw.h" -#include "glendapng.h" - -AUTOFRAMEWORK(Carbon) -AUTOFRAMEWORK(Cocoa) - -#ifdef MULTITOUCH -AUTOFRAMEWORK(MultitouchSupport) -AUTOFRAMEWORK(IOKit) -#endif - -#define panic sysfatal - -extern Rectangle mouserect; - -struct { - char *label; - char *winsize; - QLock labellock; - - Rectangle fullscreenr; - Rectangle screenr; - Memimage *screenimage; - int isfullscreen; - ulong fullscreentime; - - Point xy; - int buttons; - int kbuttons; - - CGDataProviderRef provider; - MenuRef wmenu; - MenuRef vmenu; - WindowRef window; - CGImageRef image; - CGContextRef windowctx; - PasteboardRef snarf; - int needflush; - QLock flushlock; - int active; - int infullscreen; - int kalting; // last keystroke was Kalt - int touched; // last mouse event was touchCallback - int collapsed; // parked in dock - int flushing; // flushproc has started - NSMutableArray* devicelist; -} osx; - -/* - These structs are required, in order to handle some parameters returned from the - Support.framework - */ -typedef struct { - float x; - float y; -}mtPoint; - -typedef struct { - mtPoint position; - mtPoint velocity; -}mtReadout; - -/* - Some reversed engineered informations from MultiTouchSupport.framework - */ -typedef struct -{ - int frame; //the current frame - double timestamp; //event timestamp - int identifier; //identifier guaranteed unique for life of touch per device - int state; //the current state (not sure what the values mean) - int unknown1; //no idea what this does - int unknown2; //no idea what this does either - mtReadout normalized; //the normalized position and vector of the touch (0,0 to 1,1) - float size; //the size of the touch (the area of your finger being tracked) - int unknown3; //no idea what this does - float angle; //the angle of the touch -| - float majorAxis; //the major axis of the touch -|-- an ellipsoid. you can track the angle of each finger! - float minorAxis; //the minor axis of the touch -| - mtReadout unknown4; //not sure what this is for - int unknown5[2]; //no clue - float unknown6; //no clue -}Touch; - -//a reference pointer for the multitouch device -typedef void *MTDeviceRef; - -//the prototype for the callback function -typedef int (*MTContactCallbackFunction)(int,Touch*,int,double,int); - -//returns a pointer to the default device (the trackpad?) -MTDeviceRef MTDeviceCreateDefault(void); - -//returns a CFMutableArrayRef array of all multitouch devices -CFMutableArrayRef MTDeviceCreateList(void); - -//registers a device's frame callback to your callback function -void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); -void MTUnregisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction); - -//start sending events -void MTDeviceStart(MTDeviceRef, int); -void MTDeviceStop(MTDeviceRef); - -MTDeviceRef MTDeviceCreateFromService(io_service_t); -io_service_t MTDeviceGetService(MTDeviceRef); - -#define kNTracks 10 -struct TouchTrack { - int id; - float firstThreshTime; - mtPoint pos; -} tracks[kNTracks]; - -#define kSizeSensitivity 1.25f -#define kTimeSensitivity 0.03f /* seconds */ -#define kButtonLimit 0.6f /* percentage from base of pad */ - -int -findTrack(int id) -{ - int i; - for(i = 0; i < kNTracks; ++i) - if(tracks[i].id == id) - return i; - return -1; -} - -#define kMoveSensitivity 0.05f - -int -moved(mtPoint a, mtPoint b) -{ - if(fabs(a.x - b.x) > kMoveSensitivity) - return 1; - if(fabs(a.y - b.y) > kMoveSensitivity) - return 1; - return 0; -} - -int -classifyTouch(Touch *t) -{ - mtPoint p; - int i; - - p = t->normalized.position; - - i = findTrack(t->identifier); - if(i == -1) { - i = findTrack(-1); - if(i == -1) - return 0; // No empty tracks. - tracks[i].id = t->identifier; - tracks[i].firstThreshTime = t->timestamp; - tracks[i].pos = p; - // we don't have a touch yet - we wait kTimeSensitivity before reporting it. - return 0; - } - - if(t->size == 0) { // lost touch - tracks[i].id = -1; - return 0; - } - if(t->size < kSizeSensitivity) { - tracks[i].firstThreshTime = t->timestamp; - } - if((t->timestamp - tracks[i].firstThreshTime) < kTimeSensitivity) { - return 0; - } - if(p.y > kButtonLimit && t->size > kSizeSensitivity) { - if(p.x < 0.35) - return 1; - if(p.x > 0.65) - return 4; - if(p.x > 0.35 && p.x < 0.65) - return 2; - } - return 0; -} - -static ulong msec(void); - -int -touchCallback(int device, Touch *data, int nFingers, double timestamp, int frame) -{ -#ifdef MULTITOUCH - int buttons, delta, i; - static int obuttons; - CGPoint p; - CGEventRef e; - - p.x = osx.xy.x+osx.screenr.min.x; - p.y = osx.xy.y+osx.screenr.min.y; - if(!ptinrect(Pt(p.x, p.y), osx.screenr)) - return 0; - osx.touched = 1; - buttons = 0; - for(i = 0; i < nFingers; ++i) - buttons |= classifyTouch(data+i); - delta = buttons ^ obuttons; - obuttons = buttons; - if(delta & 1) { - e = CGEventCreateMouseEvent(NULL, - (buttons & 1) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp, - p, - 29); - CGEventPost(kCGSessionEventTap, e); - CFRelease(e); - } - if(delta & 2) { - e = CGEventCreateMouseEvent(NULL, - (buttons & 2) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp, - p, - 30); - CGEventPost(kCGSessionEventTap, e); - CFRelease(e); - } - if(delta & 4){ - e = CGEventCreateMouseEvent(NULL, - (buttons & 4) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp, - p, - 31); - CGEventPost(kCGSessionEventTap, e); - CFRelease(e); - } - return delta != 0; -#else - return 0; -#endif -} - -extern int multitouch; - -enum -{ - WindowAttrs = - kWindowCloseBoxAttribute | - kWindowCollapseBoxAttribute | - kWindowResizableAttribute | - kWindowStandardHandlerAttribute | - kWindowFullZoomAttribute -}; - -enum -{ - P9PEventLabelUpdate = 1 -}; - -static void screenproc(void*); -static void eresized(int); -static void fullscreen(int); -static void seticon(void); -static void activated(int); - -static OSStatus quithandler(EventHandlerCallRef, EventRef, void*); -static OSStatus eventhandler(EventHandlerCallRef, EventRef, void*); -static OSStatus cmdhandler(EventHandlerCallRef, EventRef, void*); - -enum -{ - CmdFullScreen = 1, -}; - -void screeninit(void); -void _flushmemscreen(Rectangle r); - -#ifdef MULTITOUCH -static void -RegisterMultitouch(void *ctx, io_iterator_t iter) -{ - io_object_t io; - MTDeviceRef dev; - - while((io = IOIteratorNext(iter)) != 0){ - dev = MTDeviceCreateFromService(io); - if (dev != nil){ - MTRegisterContactFrameCallback(dev, touchCallback); - [osx.devicelist addObject:dev]; - if(osx.active) - MTDeviceStart(dev, 0); - } - - IOObjectRelease(io); - } -} - -static void -UnregisterMultitouch(void *ctx, io_iterator_t iter) -{ - io_object_t io; - MTDeviceRef dev; - int i; - - while((io = IOIteratorNext(iter)) != 0){ - for(i = 0; i < [osx.devicelist count]; i++){ - dev = [osx.devicelist objectAtIndex:i]; - if(IOObjectIsEqualTo(MTDeviceGetService(dev), io)){ - if(osx.active) - MTDeviceStop(dev); - MTUnregisterContactFrameCallback(dev, touchCallback); - [osx.devicelist removeObjectAtIndex:i]; - break; - } - } - - IOObjectRelease(io); - } -} - -#endif /*MULTITOUCH*/ - -static void -InitMultiTouch() -{ -#ifdef MULTITOUCH - IONotificationPortRef port; - CFRunLoopSourceRef source; - io_iterator_t iter; - kern_return_t kr; - io_object_t obj; - int i; - - if(!multitouch) - return; - - osx.devicelist = [[NSMutableArray alloc] init]; - - for(i = 0; i < kNTracks; ++i) - tracks[i].id = -1; - - port = IONotificationPortCreate(kIOMasterPortDefault); - if(port == nil){ - fprint(2, "failed to get an IO notification port\n"); - return; - } - - source = IONotificationPortGetRunLoopSource(port); - if(source == nil){ - fprint(2, "failed to get loop source for port"); - return; - } - - CFRunLoopAddSource( - (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()), - source, - kCFRunLoopDefaultMode); - - kr = IOServiceAddMatchingNotification( - port, kIOTerminatedNotification, - IOServiceMatching("AppleMultitouchDevice"), - &UnregisterMultitouch, - nil, &iter); - - if(kr != KERN_SUCCESS){ - fprint(2, "failed to add termination notification\n"); - return; - } - - /* Arm the notification */ - while((obj = IOIteratorNext(iter)) != 0) - IOObjectRelease(obj); - - kr = IOServiceAddMatchingNotification( - port, kIOMatchedNotification, - IOServiceMatching("AppleMultitouchDevice"), - &RegisterMultitouch, - nil, &iter); - - if(kr != KERN_SUCCESS){ - fprint(2, "failed to add matching notification\n"); - return; - } - - RegisterMultitouch(nil, iter); -#endif -} - -Memimage* -attachscreen(char *label, char *winsize) -{ - if(label == nil) - label = "gnot a label"; - osx.label = strdup(label); - osx.winsize = winsize; - if(osx.screenimage == nil){ - screeninit(); - if(osx.screenimage == nil) - panic("cannot create OS X screen"); - } - return osx.screenimage; -} - -extern int multitouch; - -void -_screeninit(void) -{ - CGRect cgr; - OSXRect or; - Rectangle r; - int havemin; - - memimageinit(); - - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - SetFrontProcess(&psn); - - cgr = CGDisplayBounds(CGMainDisplayID()); - osx.fullscreenr = Rect(0, 0, cgr.size.width, cgr.size.height); - - InitCursor(); - - // Create minimal menu with full-screen option. - ClearMenuBar(); - CreateStandardWindowMenu(0, &osx.wmenu); - InsertMenu(osx.wmenu, 0); - MenuItemIndex ix; - CreateNewMenu(1004, 0, &osx.vmenu); // XXX 1004? - SetMenuTitleWithCFString(osx.vmenu, CFSTR("View")); - AppendMenuItemTextWithCFString(osx.vmenu, - CFSTR("Full Screen"), 0, CmdFullScreen, &ix); - SetMenuItemCommandKey(osx.vmenu, ix, 0, 'F'); - AppendMenuItemTextWithCFString(osx.vmenu, - CFSTR("Cmd-F exits full screen"), - kMenuItemAttrDisabled, CmdFullScreen, &ix); - InsertMenu(osx.vmenu, GetMenuID(osx.wmenu)); - DrawMenuBar(); - - // Create the window. - r = Rect(0, 0, Dx(osx.fullscreenr)*2/3, Dy(osx.fullscreenr)*2/3); - havemin = 0; - if(osx.winsize && osx.winsize[0]){ - if(parsewinsize(osx.winsize, &r, &havemin) < 0) - sysfatal("%r"); - } - if(!havemin) - r = rectaddpt(r, Pt((Dx(osx.fullscreenr)-Dx(r))/2, (Dy(osx.fullscreenr)-Dy(r))/2)); - or.left = r.min.x; - or.top = r.min.y; - or.right = r.max.x; - or.bottom = r.max.y; - CreateNewWindow(kDocumentWindowClass, WindowAttrs, &or, &osx.window); - setlabel(osx.label); - seticon(); - - // Set up the clip board. - if(PasteboardCreate(kPasteboardClipboard, &osx.snarf) != noErr) - panic("pasteboard create"); - - // Explain in great detail which events we want to handle. - // Why can't we just have one handler? - const EventTypeSpec quits[] = { - { kEventClassApplication, kEventAppQuit } - }; - const EventTypeSpec cmds[] = { - { kEventClassWindow, kEventWindowClosed }, - { kEventClassWindow, kEventWindowBoundsChanged }, - { kEventClassWindow, kEventWindowDrawContent }, - { kEventClassCommand, kEventCommandProcess }, - { kEventClassWindow, kEventWindowActivated }, - { kEventClassWindow, kEventWindowDeactivated }, - { kEventClassWindow, kEventWindowCollapsed }, - { kEventClassWindow, kEventWindowExpanded }, - }; - const EventTypeSpec events[] = { - { kEventClassApplication, kEventAppShown }, - { kEventClassKeyboard, kEventRawKeyDown }, - { kEventClassKeyboard, kEventRawKeyModifiersChanged }, - { kEventClassKeyboard, kEventRawKeyRepeat }, - { kEventClassMouse, kEventMouseDown }, - { kEventClassMouse, kEventMouseUp }, - { kEventClassMouse, kEventMouseMoved }, - { kEventClassMouse, kEventMouseDragged }, - { kEventClassMouse, kEventMouseWheelMoved }, - { 'P9PE', P9PEventLabelUpdate} - }; - - InstallApplicationEventHandler( - NewEventHandlerUPP(quithandler), - nelem(quits), quits, nil, nil); - - InstallApplicationEventHandler( - NewEventHandlerUPP(eventhandler), - nelem(events), events, nil, nil); - - InstallWindowEventHandler(osx.window, - NewEventHandlerUPP(cmdhandler), - nelem(cmds), cmds, osx.window, nil); - - // Finally, put the window on the screen. - ShowWindow(osx.window); - ShowMenuBar(); - eresized(0); - SelectWindow(osx.window); - - if(multitouch) - InitMultiTouch(); - - // CoreGraphics pins mouse events to the destination point of a - // CGWarpMouseCursorPosition (see setmouse) for an interval of time - // following the move. Disable this by setting the interval to zero - // seconds. - CGSetLocalEventsSuppressionInterval(0.0); - - InitCursor(); -} - -static Rendez scr; -static QLock slock; - -void -screeninit(void) -{ - scr.l = &slock; - qlock(scr.l); - proccreate(screenproc, nil, 256*1024); - while(osx.window == nil) - rsleep(&scr); - qunlock(scr.l); -} - -static void -screenproc(void *v) -{ - qlock(scr.l); - _screeninit(); - rwakeup(&scr); - qunlock(scr.l); - RunApplicationEventLoop(); -} - -static OSStatus kbdevent(EventRef); -static OSStatus mouseevent(EventRef); - -static OSStatus -cmdhandler(EventHandlerCallRef next, EventRef event, void *arg) -{ - return eventhandler(next, event, arg); -} - -static OSStatus -quithandler(EventHandlerCallRef next, EventRef event, void *arg) -{ - exit(0); - return 0; -} - -static OSStatus -eventhandler(EventHandlerCallRef next, EventRef event, void *arg) -{ - OSStatus result; - - result = CallNextEventHandler(next, event); - - switch(GetEventClass(event)){ - - case 'P9PE': - if(GetEventKind(event) == P9PEventLabelUpdate) { - qlock(&osx.labellock); - setlabel(osx.label); - qunlock(&osx.labellock); - return noErr; - } else - return eventNotHandledErr; - - case kEventClassApplication:; - Rectangle r = Rect(0, 0, Dx(osx.screenr), Dy(osx.screenr)); - _flushmemscreen(r); - return eventNotHandledErr; - - case kEventClassKeyboard: - return kbdevent(event); - - case kEventClassMouse: - return mouseevent(event); - - case kEventClassCommand:; - HICommand cmd; - GetEventParameter(event, kEventParamDirectObject, - typeHICommand, nil, sizeof cmd, nil, &cmd); - switch(cmd.commandID){ - case kHICommandQuit: - exit(0); - - case CmdFullScreen: - fullscreen(1); - break; - - default: - return eventNotHandledErr; - } - break; - - case kEventClassWindow: - switch(GetEventKind(event)){ - case kEventWindowClosed: - exit(0); - - case kEventWindowBoundsChanged:; - // We see kEventWindowDrawContent - // if we grow a window but not if we shrink it. - UInt32 flags; - GetEventParameter(event, kEventParamAttributes, - typeUInt32, 0, sizeof flags, 0, &flags); - int new = (flags & kWindowBoundsChangeSizeChanged) != 0; - eresized(new); - break; - - case kEventWindowDrawContent: - // Tried using just flushmemimage here, but - // it causes an odd artifact in which making a window - // bigger in both width and height can then only draw - // on the new border: it's like the old window is stuck - // floating on top. Doing a full "get a new window" - // seems to solve the problem. - eresized(1); - break; - - case kEventWindowActivated: - if(!osx.collapsed) - activated(1); - return eventNotHandledErr; - - case kEventWindowDeactivated: - activated(0); - return eventNotHandledErr; - - case kEventWindowCollapsed: - osx.collapsed = 1; - activated(0); - return eventNotHandledErr; - - case kEventWindowExpanded: - osx.collapsed = 0; - activated(1); - return eventNotHandledErr; - - default: - return eventNotHandledErr; - } - break; - } - - return result; -} - -static ulong -msec(void) -{ - return nsec()/1000000; -} - -static OSStatus -mouseevent(EventRef event) -{ - int wheel; - OSXPoint op; - - GetEventParameter(event, kEventParamMouseLocation, - typeQDPoint, 0, sizeof op, 0, &op); - - osx.xy = subpt(Pt(op.h, op.v), osx.screenr.min); - wheel = 0; - - switch(GetEventKind(event)){ - case kEventMouseWheelMoved:; - SInt32 delta; - GetEventParameter(event, kEventParamMouseWheelDelta, - typeSInt32, 0, sizeof delta, 0, &delta); - - // if I have any active touches in my region, I need to ignore the wheel motion. - //int i; - //for(i = 0; i < kNTracks; ++i) { - // if(tracks[i].id != -1 && tracks[i].pos.y > kButtonLimit) break; - //} - //if(i == kNTracks) { // No active touches, go ahead and scroll. - if(delta > 0) - wheel = 8; - else - wheel = 16; - //} - break; - - case kEventMouseDown: - case kEventMouseUp:; - UInt32 but, mod; - GetEventParameter(event, kEventParamMouseChord, - typeUInt32, 0, sizeof but, 0, &but); - GetEventParameter(event, kEventParamKeyModifiers, - typeUInt32, 0, sizeof mod, 0, &mod); - - // OS X swaps button 2 and 3 - but = (but & ~6) | ((but & 4)>>1) | ((but&2)<<1); - but = (but & ~((1<<10)-1)) | mouseswap(but & ((1<<10)-1)); - if(osx.touched) { - // in multitouch we use the clicks down to enable our - // virtual buttons. - if(but & 0x7) { - if(but>>29) - but = but >> 29; - } else - but = 0; - osx.touched = 0; - } - - // Apply keyboard modifiers and pretend it was a real mouse button. - // (Modifiers typed while holding the button go into kbuttons, - // but this one does not.) - if(but == 1){ - if(mod & optionKey) { - // Take the ALT away from the keyboard handler. - if(osx.kalting) { - osx.kalting = 0; - keystroke(Kalt); - } - but = 2; - } - else if(mod & cmdKey) - but = 4; - } - osx.buttons = but; - break; - - case kEventMouseMoved: - case kEventMouseDragged: - break; - - default: - return eventNotHandledErr; - } - - mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons|wheel, msec()); - return noErr; -} - -static int keycvt[] = -{ - [QZ_IBOOK_ENTER] '\n', - [QZ_RETURN] '\n', - [QZ_ESCAPE] 27, - [QZ_BACKSPACE] '\b', - [QZ_LALT] Kalt, - [QZ_LCTRL] Kctl, - [QZ_LSHIFT] Kshift, - [QZ_F1] KF+1, - [QZ_F2] KF+2, - [QZ_F3] KF+3, - [QZ_F4] KF+4, - [QZ_F5] KF+5, - [QZ_F6] KF+6, - [QZ_F7] KF+7, - [QZ_F8] KF+8, - [QZ_F9] KF+9, - [QZ_F10] KF+10, - [QZ_F11] KF+11, - [QZ_F12] KF+12, - [QZ_INSERT] Kins, - [QZ_DELETE] 0x7F, - [QZ_HOME] Khome, - [QZ_END] Kend, - [QZ_KP_PLUS] '+', - [QZ_KP_MINUS] '-', - [QZ_TAB] '\t', - [QZ_PAGEUP] Kpgup, - [QZ_PAGEDOWN] Kpgdown, - [QZ_UP] Kup, - [QZ_DOWN] Kdown, - [QZ_LEFT] Kleft, - [QZ_RIGHT] Kright, - [QZ_KP_MULTIPLY] '*', - [QZ_KP_DIVIDE] '/', - [QZ_KP_ENTER] '\n', - [QZ_KP_PERIOD] '.', - [QZ_KP0] '0', - [QZ_KP1] '1', - [QZ_KP2] '2', - [QZ_KP3] '3', - [QZ_KP4] '4', - [QZ_KP5] '5', - [QZ_KP6] '6', - [QZ_KP7] '7', - [QZ_KP8] '8', - [QZ_KP9] '9', -}; - -static OSStatus -kbdevent(EventRef event) -{ - char ch; - UInt32 code; - UInt32 mod; - int k; - - GetEventParameter(event, kEventParamKeyMacCharCodes, - typeChar, nil, sizeof ch, nil, &ch); - GetEventParameter(event, kEventParamKeyCode, - typeUInt32, nil, sizeof code, nil, &code); - GetEventParameter(event, kEventParamKeyModifiers, - typeUInt32, nil, sizeof mod, nil, &mod); - - switch(GetEventKind(event)){ - case kEventRawKeyDown: - case kEventRawKeyRepeat: - osx.kalting = 0; - if(mod == cmdKey){ - if(ch == 'F' || ch == 'f'){ - if(osx.isfullscreen && msec() - osx.fullscreentime > 500) - fullscreen(0); - return noErr; - } - - // Pass most Cmd keys through as Kcmd + ch. - // OS X interprets a few no matter what we do, - // so it is useless to pass them through as keystrokes too. - switch(ch) { - case 'm': // minimize window - case 'h': // hide window - case 'H': // hide others - case 'q': // quit - return eventNotHandledErr; - } - if(' ' <= ch && ch <= '~') { - keystroke(Kcmd + ch); - return noErr; - } - return eventNotHandledErr; - } - k = ch; - if(code < nelem(keycvt) && keycvt[code]) - k = keycvt[code]; - if(k == 0) - return noErr; - if(k > 0) - keystroke(k); - else{ - UniChar uc; - OSStatus s; - - s = GetEventParameter(event, kEventParamKeyUnicodes, - typeUnicodeText, nil, sizeof uc, nil, &uc); - if(s == noErr) - keystroke(uc); - } - break; - - case kEventRawKeyModifiersChanged: - if(!osx.buttons && !osx.kbuttons){ - if(mod == optionKey) { - osx.kalting = 1; - keystroke(Kalt); - } - break; - } - - // If the mouse button is being held down, treat - // changes in the keyboard modifiers as changes - // in the mouse buttons. - osx.kbuttons = 0; - if(mod & optionKey) - osx.kbuttons |= 2; - if(mod & cmdKey) - osx.kbuttons |= 4; - mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons, msec()); - break; - } - return noErr; -} - -static void -eresized(int new) -{ - Memimage *m; - OSXRect or; - ulong chan; - Rectangle r; - int bpl; - CGDataProviderRef provider; - CGImageRef image; - CGColorSpaceRef cspace; - - GetWindowBounds(osx.window, kWindowContentRgn, &or); - r = Rect(or.left, or.top, or.right, or.bottom); - if(Dx(r) == Dx(osx.screenr) && Dy(r) == Dy(osx.screenr) && !new){ - // No need to make new image. - osx.screenr = r; - return; - } - - chan = XBGR32; - m = allocmemimage(Rect(0, 0, Dx(r), Dy(r)), chan); - if(m == nil) - panic("allocmemimage: %r"); - if(m->data == nil) - panic("m->data == nil"); - bpl = bytesperline(r, 32); - provider = CGDataProviderCreateWithData(0, - m->data->bdata, Dy(r)*bpl, 0); - //cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - cspace = CGColorSpaceCreateDeviceRGB(); - image = CGImageCreate(Dx(r), Dy(r), 8, 32, bpl, - cspace, - kCGImageAlphaNoneSkipLast, - provider, 0, 0, kCGRenderingIntentDefault); - CGColorSpaceRelease(cspace); - CGDataProviderRelease(provider); // CGImageCreate did incref - - mouserect = m->r; - if(new){ - mouseresized = 1; - mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons, msec()); - } -// termreplacescreenimage(m); - _drawreplacescreenimage(m); // frees old osx.screenimage if any - if(osx.image) - CGImageRelease(osx.image); - osx.image = image; - osx.screenimage = m; - osx.screenr = r; - - if(new){ - qlock(&osx.flushlock); - QDEndCGContext(GetWindowPort(osx.window), &osx.windowctx); - osx.windowctx = nil; - qunlock(&osx.flushlock); - } -} - -void -flushproc(void *v) -{ - for(;;){ - if(osx.needflush && osx.windowctx && canqlock(&osx.flushlock)){ - if(osx.windowctx){ - CGContextFlush(osx.windowctx); - osx.needflush = 0; - } - qunlock(&osx.flushlock); - } - usleep(33333); - } -} - -void -_flushmemscreen(Rectangle r) -{ - CGRect cgr; - CGImageRef subimg; - - qlock(&osx.flushlock); - if(osx.windowctx == nil){ - QDBeginCGContext(GetWindowPort(osx.window), &osx.windowctx); - if(!osx.flushing) { - proccreate(flushproc, nil, 256*1024); - osx.flushing = 1; - } - } - - cgr.origin.x = r.min.x; - cgr.origin.y = r.min.y; - cgr.size.width = Dx(r); - cgr.size.height = Dy(r); - subimg = CGImageCreateWithImageInRect(osx.image, cgr); - cgr.origin.y = Dy(osx.screenr) - r.max.y; // XXX how does this make any sense? - CGContextDrawImage(osx.windowctx, cgr, subimg); - osx.needflush = 1; - qunlock(&osx.flushlock); - CGImageRelease(subimg); -} - -void -activated(int active) -{ -#ifdef MULTITOUCH - int i; - if(active) { - for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices - MTDeviceStart([osx.devicelist objectAtIndex:i], 0); //start sending events - } - } else { - osx.xy.x = -10000; - for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices - MTDeviceStop([osx.devicelist objectAtIndex:i]); //stop sending events - } - for(i = 0; igdRect; - if(dr.top == 0 && dr.left == 0) - HideMenuBar(); - GetWindowBounds(osx.window, kWindowContentRgn, &oldrect); - ChangeWindowAttributes(osx.window, - kWindowNoTitleBarAttribute, - kWindowResizableAttribute); - MoveWindow(osx.window, 0, 0, 1); - MoveWindow(osx.window, dr.left, dr.top, 0); - SizeWindow(osx.window, - dr.right - dr.left, - dr.bottom - dr.top, 0); - osx.isfullscreen = 1; - }else{ - ShowMenuBar(); - ChangeWindowAttributes(osx.window, - kWindowResizableAttribute, - kWindowNoTitleBarAttribute); - SizeWindow(osx.window, - oldrect.right - oldrect.left, - oldrect.bottom - oldrect.top, 0); - MoveWindow(osx.window, oldrect.left, oldrect.top, 0); - osx.isfullscreen = 0; - } - eresized(1); -} - -void -setmouse(Point p) -{ - CGPoint cgp; - - cgp.x = p.x + osx.screenr.min.x; - cgp.y = p.y + osx.screenr.min.y; - CGWarpMouseCursorPosition(cgp); - osx.xy = p; -} - -void -setcursor(Cursor *c) -{ - OSXCursor oc; - int i; - - if(c == nil){ - InitCursor(); - return; - } - - // SetCursor is deprecated, but what replaces it? - for(i=0; i<16; i++){ - oc.data[i] = ((ushort*)c->set)[i]; - oc.mask[i] = oc.data[i] | ((ushort*)c->clr)[i]; - } - oc.hotSpot.h = - c->offset.x; - oc.hotSpot.v = - c->offset.y; - SetCursor(&oc); -} - -void -getcolor(ulong i, ulong *r, ulong *g, ulong *b) -{ - ulong v; - - v = 0; - *r = (v>>16)&0xFF; - *g = (v>>8)&0xFF; - *b = v&0xFF; -} - -int -setcolor(ulong i, ulong r, ulong g, ulong b) -{ - /* no-op */ - return 0; -} - - -int -hwdraw(Memdrawparam *p) -{ - return 0; -} - -struct { - QLock lk; - char buf[SnarfSize]; - Rune rbuf[SnarfSize]; - PasteboardRef apple; -} clip; - -char* -getsnarf(void) -{ - char *s; - CFArrayRef flavors; - CFDataRef data; - CFIndex nflavor, ndata, j; - CFStringRef type; - ItemCount nitem; - PasteboardItemID id; - PasteboardSyncFlags flags; - UInt32 i; - u16int *u; - Fmt fmt; - Rune r; - -/* fprint(2, "applegetsnarf\n"); */ - qlock(&clip.lk); - clip.apple = osx.snarf; - if(clip.apple == nil){ - if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){ - fprint(2, "apple pasteboard create failed\n"); - qunlock(&clip.lk); - return nil; - } - } - flags = PasteboardSynchronize(clip.apple); - if(flags&kPasteboardClientIsOwner){ - s = strdup(clip.buf); - qunlock(&clip.lk); - return s; - } - if(PasteboardGetItemCount(clip.apple, &nitem) != noErr){ - fprint(2, "apple pasteboard get item count failed\n"); - qunlock(&clip.lk); - return nil; - } - for(i=1; i<=nitem; i++){ - if(PasteboardGetItemIdentifier(clip.apple, i, &id) != noErr) - continue; - if(PasteboardCopyItemFlavors(clip.apple, id, &flavors) != noErr) - continue; - nflavor = CFArrayGetCount(flavors); - for(j=0; j= SnarfSize) - return; - qlock(&clip.lk); - strcpy(clip.buf, s); - runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s); - clip.apple = osx.snarf; - if(PasteboardClear(clip.apple) != noErr){ - fprint(2, "apple pasteboard clear failed\n"); - qunlock(&clip.lk); - return; - } - flags = PasteboardSynchronize(clip.apple); - if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){ - fprint(2, "apple pasteboard cannot assert ownership\n"); - qunlock(&clip.lk); - return; - } - u = malloc(runestrlen(clip.rbuf)*4); - p = u; - for(i=0; clip.rbuf[i]; i++) { - r = clip.rbuf[i]; - // convert to utf-16 - if(0xd800 <= r && r < 0xe000) - r = Runeerror; - if(r >= 0x10000) { - r -= 0x10000; - *p++ = 0xd800 + (r>>10); - *p++ = 0xdc00 + (r & ((1<<10)-1)); - } else - *p++ = r; - } - cfdata = CFDataCreate(kCFAllocatorDefault, - (uchar*)u, (p-u)*2); - free(u); - if(cfdata == nil){ - fprint(2, "apple pasteboard cfdatacreate failed\n"); - qunlock(&clip.lk); - return; - } - if(PasteboardPutItemFlavor(clip.apple, (PasteboardItemID)1, - CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){ - fprint(2, "apple pasteboard putitem failed\n"); - CFRelease(cfdata); - qunlock(&clip.lk); - return; - } - CFRelease(cfdata); - qunlock(&clip.lk); -} - -void -setlabel(char *label) -{ - CFStringRef cs; - - cs = CFStringCreateWithBytes(nil, (uchar*)label, strlen(label), kCFStringEncodingUTF8, false); - SetWindowTitleWithCFString(osx.window, cs); - CFRelease(cs); -} - -void -kicklabel(char *label) -{ - char *p; - EventRef e; - - p = strdup(label); - if(p == nil) - return; - qlock(&osx.labellock); - free(osx.label); - osx.label = p; - qunlock(&osx.labellock); - - CreateEvent(nil, 'P9PE', P9PEventLabelUpdate, 0, kEventAttributeUserEvent, &e); - PostEventToQueue(GetMainEventQueue(), e, kEventPriorityStandard); - -} - -static void -seticon(void) -{ - CGImageRef im; - CGDataProviderRef d; - - d = CGDataProviderCreateWithData(nil, glenda_png, sizeof glenda_png, nil); - im = CGImageCreateWithPNGDataProvider(d, nil, true, kCGRenderingIntentDefault); - if(im) - SetApplicationDockTileImage(im); - CGImageRelease(im); - CGDataProviderRelease(d); -} - diff --git a/src/cmd/devdraw/osx-screen.h b/src/cmd/devdraw/osx-screen.h deleted file mode 100644 index d5ba3dd2..00000000 --- a/src/cmd/devdraw/osx-screen.h +++ /dev/null @@ -1,18 +0,0 @@ -void zlock(void); -void zunlock(void); - -#define setcursor dsetcursor - -Memimage *attachscreen(char*, char*); -void setmouse(Point); -void setcursor(Cursor*, Cursor2*); -void setlabel(char*); -char* getsnarf(void); -void putsnarf(char*); - -void mousetrack(int, int, int, int); -void keystroke(int); -void kicklabel(char*); - -extern Rectangle mouserect; -extern int mouseresized; diff --git a/src/cmd/devdraw/osx-srv.c b/src/cmd/devdraw/osx-srv.c deleted file mode 100644 index d0a1c2d3..00000000 --- a/src/cmd/devdraw/osx-srv.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Window system protocol server. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "osx-screen.h" -#include "devdraw.h" - -#undef time - -#define MouseMask (\ - ButtonPressMask|\ - ButtonReleaseMask|\ - PointerMotionMask|\ - Button1MotionMask|\ - Button2MotionMask|\ - Button3MotionMask) - -#define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|EnterWindowMask|LeaveWindowMask - -typedef struct Kbdbuf Kbdbuf; -typedef struct Mousebuf Mousebuf; -typedef struct Fdbuf Fdbuf; -typedef struct Tagbuf Tagbuf; - -struct Kbdbuf -{ - Rune r[32]; - int ri; - int wi; - int stall; -}; - -struct Mousebuf -{ - Mouse m[32]; - Mouse last; - int ri; - int wi; - int stall; -}; - -struct Tagbuf -{ - int t[32]; - int ri; - int wi; -}; - -Kbdbuf kbd; -Mousebuf mouse; -Tagbuf kbdtags; -Tagbuf mousetags; - -void fdslide(Fdbuf*); -void runmsg(Wsysmsg*); -void replymsg(Wsysmsg*); -void matchkbd(void); -void matchmouse(void); -int fdnoblock(int); -Rectangle mouserect; -int mouseresized; - - -QLock lk; -void -zlock(void) -{ - qlock(&lk); -} - -void -zunlock(void) -{ - qunlock(&lk); -} - -int chatty; -int drawsleep; -int trace; -int multitouch = 1; - -void -usage(void) -{ - fprint(2, "usage: devdraw (don't run directly)\n"); - threadexitsall("usage"); -} - -void -bell(void *v, char *msg) -{ - if(strcmp(msg, "alarm") == 0) - drawsleep = drawsleep ? 0 : 1000; - noted(NCONT); -} - -void -threadmain(int argc, char **argv) -{ - uchar buf[4], *mbuf; - int nmbuf, n, nn; - Wsysmsg m; - - /* - * Move the protocol off stdin/stdout so that - * any inadvertent prints don't screw things up. - */ - dup(0, 3); - dup(1, 4); - close(0); - close(1); - open("/dev/null", OREAD); - open("/dev/null", OWRITE); - -//trace = 1; - fmtinstall('W', drawfcallfmt); - - ARGBEGIN{ - case 'D': - chatty++; - break; - case 'M': - multitouch = 0; - break; - default: - usage(); - }ARGEND - - /* - * Ignore arguments. They're only for good ps -a listings. - */ - - notify(bell); - - mbuf = nil; - nmbuf = 0; - while((n = read(3, buf, 4)) == 4){ - GET(buf, n); - if(n > nmbuf){ - free(mbuf); - mbuf = malloc(4+n); - if(mbuf == nil) - sysfatal("malloc: %r"); - nmbuf = n; - } - memmove(mbuf, buf, 4); - nn = readn(3, mbuf+4, n-4); - if(nn != n-4) - sysfatal("eof during message"); - - /* pick off messages one by one */ - if(convM2W(mbuf, nn+4, &m) <= 0) - sysfatal("cannot convert message"); - if(trace) fprint(2, "<- %W\n", &m); - runmsg(&m); - } - threadexitsall(0); -} - -void -replyerror(Wsysmsg *m) -{ - char err[256]; - - rerrstr(err, sizeof err); - m->type = Rerror; - m->error = err; - replymsg(m); -} - -/* - * Handle a single wsysmsg. - * Might queue for later (kbd, mouse read) - */ -void -runmsg(Wsysmsg *m) -{ - static uchar buf[65536]; - int n; - Memimage *i; - - switch(m->type){ - case Tinit: - memimageinit(); - i = attachscreen(m->label, m->winsize); - _initdisplaymemimage(i); - replymsg(m); - break; - - case Trdmouse: - zlock(); - mousetags.t[mousetags.wi++] = m->tag; - if(mousetags.wi == nelem(mousetags.t)) - mousetags.wi = 0; - if(mousetags.wi == mousetags.ri) - sysfatal("too many queued mouse reads"); - mouse.stall = 0; - matchmouse(); - zunlock(); - break; - - case Trdkbd: - zlock(); - kbdtags.t[kbdtags.wi++] = m->tag; - if(kbdtags.wi == nelem(kbdtags.t)) - kbdtags.wi = 0; - if(kbdtags.wi == kbdtags.ri) - sysfatal("too many queued keyboard reads"); - kbd.stall = 0; - matchkbd(); - zunlock(); - break; - - case Tmoveto: - setmouse(m->mouse.xy); - replymsg(m); - break; - - case Tcursor: - if(m->arrowcursor) - setcursor(nil, nil); - else - setcursor(&m->cursor, &m->cursor2); - replymsg(m); - break; - - case Tbouncemouse: - // _xbouncemouse(&m->mouse); - replymsg(m); - break; - - case Tlabel: - kicklabel(m->label); - replymsg(m); - break; - - case Trdsnarf: - m->snarf = getsnarf(); - replymsg(m); - free(m->snarf); - break; - - case Twrsnarf: - putsnarf(m->snarf); - replymsg(m); - break; - - case Trddraw: - n = m->count; - if(n > sizeof buf) - n = sizeof buf; - n = _drawmsgread(buf, n); - if(n < 0) - replyerror(m); - else{ - m->count = n; - m->data = buf; - replymsg(m); - } - break; - - case Twrdraw: - if(_drawmsgwrite(m->data, m->count) < 0) - replyerror(m); - else - replymsg(m); - break; - - case Ttop: - // _xtopwindow(); - replymsg(m); - break; - - case Tresize: - // _xresizewindow(m->rect); - replymsg(m); - break; - } -} - -/* - * Reply to m. - */ -QLock replylock; -void -replymsg(Wsysmsg *m) -{ - int n; - static uchar *mbuf; - static int nmbuf; - - /* T -> R msg */ - if(m->type%2 == 0) - m->type++; - - if(trace) fprint(2, "-> %W\n", m); - /* copy to output buffer */ - n = sizeW2M(m); - - qlock(&replylock); - if(n > nmbuf){ - free(mbuf); - mbuf = malloc(n); - if(mbuf == nil) - sysfatal("out of memory"); - nmbuf = n; - } - convW2M(m, mbuf, n); - if(write(4, mbuf, n) != n) - sysfatal("write: %r"); - qunlock(&replylock); -} - -/* - * Match queued kbd reads with queued kbd characters. - */ -void -matchkbd(void) -{ - Wsysmsg m; - - if(kbd.stall) - return; - while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){ - m.type = Rrdkbd; - m.tag = kbdtags.t[kbdtags.ri++]; - if(kbdtags.ri == nelem(kbdtags.t)) - kbdtags.ri = 0; - m.rune = kbd.r[kbd.ri++]; - if(kbd.ri == nelem(kbd.r)) - kbd.ri = 0; - replymsg(&m); - } -} - -/* - * Match queued mouse reads with queued mouse events. - */ -void -matchmouse(void) -{ - Wsysmsg m; - - while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){ - m.type = Rrdmouse; - m.tag = mousetags.t[mousetags.ri++]; - if(mousetags.ri == nelem(mousetags.t)) - mousetags.ri = 0; - m.mouse = mouse.m[mouse.ri]; - m.resized = mouseresized; - /* - if(m.resized) - fprint(2, "sending resize\n"); - */ - mouseresized = 0; - mouse.ri++; - if(mouse.ri == nelem(mouse.m)) - mouse.ri = 0; - replymsg(&m); - } -} - -void -mousetrack(int x, int y, int b, int ms) -{ - Mouse *m; - - if(x < mouserect.min.x) - x = mouserect.min.x; - if(x > mouserect.max.x) - x = mouserect.max.x; - if(y < mouserect.min.y) - y = mouserect.min.y; - if(y > mouserect.max.y) - y = mouserect.max.y; - - zlock(); - // If reader has stopped reading, don't bother. - // If reader is completely caught up, definitely queue. - // Otherwise, queue only button change events. - if(!mouse.stall) - if(mouse.wi == mouse.ri || mouse.last.buttons != b){ - m = &mouse.last; - m->xy.x = x; - m->xy.y = y; - m->buttons = b; - m->msec = ms; - - mouse.m[mouse.wi] = *m; - if(++mouse.wi == nelem(mouse.m)) - mouse.wi = 0; - if(mouse.wi == mouse.ri){ - mouse.stall = 1; - mouse.ri = 0; - mouse.wi = 1; - mouse.m[0] = *m; - } - matchmouse(); - } - zunlock(); -} - -void -kputc(int c) -{ - zlock(); - kbd.r[kbd.wi++] = c; - if(kbd.wi == nelem(kbd.r)) - kbd.wi = 0; - if(kbd.ri == kbd.wi) - kbd.stall = 1; - matchkbd(); - zunlock(); -} - -void -keystroke(int c) -{ - static Rune k[10]; - static int alting, nk; - int i; - - if(c == Kalt){ - alting = !alting; - return; - } - if(!alting){ - kputc(c); - return; - } - if(nk >= nelem(k)) // should not happen - nk = 0; - k[nk++] = c; - c = _latin1(k, nk); - if(c > 0){ - alting = 0; - kputc(c); - nk = 0; - return; - } - if(c == -1){ - alting = 0; - for(i=0; i Date: Thu, 15 Nov 2018 22:05:39 -0500 Subject: rio: make 'mk all' explain why it does nothing on non-x11 systems Fixes #98. --- src/cmd/rio/mkriorules.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cmd/rio/mkriorules.sh b/src/cmd/rio/mkriorules.sh index 76dda36b..25cacc79 100644 --- a/src/cmd/rio/mkriorules.sh +++ b/src/cmd/rio/mkriorules.sh @@ -1,6 +1,8 @@ if [ "x$WSYSTYPE" != xx11 ]; then - echo 'all install clean nuke:Q:' - echo ' #' + echo 'default:V: all' + echo + echo 'all install clean nuke:' + echo ' # WSYSTYPE is not x11, and rio is only for x11' exit 0 fi cat $PLAN9/src/mkmany -- cgit v1.2.3 From a309537fdc8d86131522d43f9a9b2a0f58d9bda9 Mon Sep 17 00:00:00 2001 From: Tobias Heinicke Date: Wed, 6 Sep 2017 14:30:17 +0200 Subject: paint: add drawing program from 9front (#112) Paint first appeared in 9front. The 9front license is reproduced in the related source files - the original repository is located at https://code.9front.org/hg/plan9front. --- src/cmd/paint/eenter.c | 258 +++++++++++++++ src/cmd/paint/mkfile | 11 + src/cmd/paint/paint.c | 859 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1128 insertions(+) create mode 100644 src/cmd/paint/eenter.c create mode 100644 src/cmd/paint/mkfile create mode 100644 src/cmd/paint/paint.c (limited to 'src') diff --git a/src/cmd/paint/eenter.c b/src/cmd/paint/eenter.c new file mode 100644 index 00000000..6645820c --- /dev/null +++ b/src/cmd/paint/eenter.c @@ -0,0 +1,258 @@ +/* +This code was taken from 9front repository (https://code.9front.org/hg/plan9front). +It is subject to license from 9front, below is a reproduction of the license. + +Copyright (c) 20XX 9front + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#include +#include +#include +#include +#include + +/* additional keyboard codes needed - defined here to avoid API change */ +enum { + Spec= 0xF800, + Knack= 0x15, + Ksoh= 0x01, + Kenq= 0x05, + Ketb= 0x17 +}; + +int +eenter(char *ask, char *buf, int len, Mouse *m) +{ + int done, down, tick, n, h, w, l, i; + Image *b, *save, *backcol, *bordcol; + Point p, o, t; + Rectangle r, sc; + Event ev; + Rune k; + + o = screen->r.min; + backcol = allocimagemix(display, DPurpleblue, DWhite); + bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue); + if(backcol == nil || bordcol == nil) + return -1; + + while(ecankbd()) + ekbd(); + + if(m) o = m->xy; + + if(buf && len > 0) + n = strlen(buf); + else { + buf = nil; + len = 0; + n = 0; + } + + k = -1; + tick = n; + save = nil; + done = down = 0; + + p = stringsize(font, " "); + h = p.y; + w = p.x; + + b = screen; + sc = b->clipr; + replclipr(b, 0, b->r); + + while(!done){ + p = stringsize(font, buf ? buf : ""); + if(ask && ask[0]){ + if(buf) p.x += w; + p.x += stringwidth(font, ask); + } + r = rectaddpt(insetrect(Rpt(ZP, p), -4), o); + p.x = 0; + r = rectsubpt(r, p); + + p = ZP; + if(r.min.x < screen->r.min.x) + p.x = screen->r.min.x - r.min.x; + if(r.min.y < screen->r.min.y) + p.y = screen->r.min.y - r.min.y; + r = rectaddpt(r, p); + p = ZP; + if(r.max.x > screen->r.max.x) + p.x = r.max.x - screen->r.max.x; + if(r.max.y > screen->r.max.y) + p.y = r.max.y - screen->r.max.y; + r = rectsubpt(r, p); + + r = insetrect(r, -2); + if(save == nil){ + save = allocimage(display, r, b->chan, 0, DNofill); + if(save == nil){ + n = -1; + break; + } + draw(save, r, b, nil, r.min); + } + draw(b, r, backcol, nil, ZP); + border(b, r, 2, bordcol, ZP); + p = addpt(r.min, Pt(6, 6)); + if(ask && ask[0]){ + p = string(b, p, bordcol, ZP, font, ask); + if(buf) p.x += w; + } + if(buf){ + t = p; + p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick)); + draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP); + draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP); + draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP); + p = string(b, p, display->black, ZP, font, buf+tick); + } + flushimage(display, 1); + +nodraw: + i = Ekeyboard; + if(m != nil) + i |= Emouse; + + replclipr(b, 0, sc); + i = eread(i, &ev); + + /* screen might have been resized */ + if(b != screen || !eqrect(screen->clipr, sc)){ + freeimage(save); + save = nil; + } + b = screen; + sc = b->clipr; + replclipr(b, 0, b->r); + + switch(i){ + default: + done = 1; + n = -1; + break; + case Ekeyboard: + k = ev.kbdc; + if(buf == nil || k == Keof || k == '\n'){ + done = 1; + break; + } + if(k == Knack || k == Kesc){ + done = !n; + buf[n = tick = 0] = 0; + break; + } + if(k == Ksoh || k == Khome){ + tick = 0; + continue; + } + if(k == Kenq || k == Kend){ + tick = n; + continue; + } + if(k == Kright){ + if(tick < n) + tick += chartorune(&k, buf+tick); + continue; + } + if(k == Kleft){ + for(i = 0; i < n; i += l){ + l = chartorune(&k, buf+tick); + if(i+l >= tick){ + tick = i; + break; + } + } + continue; + } + if(k == Ketb){ + while(tick > 0){ + tick--; + if(tick == 0 || + strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1])) + break; + } + buf[n = tick] = 0; + break; + } + if(k == Kbs){ + if(tick <= 0) + continue; + for(i = 0; i < n; i += l){ + l = chartorune(&k, buf+i); + if(i+l >= tick){ + memmove(buf+i, buf+i+l, n - (i+l)); + buf[n -= l] = 0; + tick -= l; + break; + } + } + break; + } + if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec) + continue; + if((len-n) <= (l = runelen(k))) + continue; + memmove(buf+tick+l, buf+tick, n - tick); + runetochar(buf+tick, &k); + buf[n += l] = 0; + tick += l; + break; + case Emouse: + *m = ev.mouse; + if(!ptinrect(m->xy, r)){ + down = 0; + goto nodraw; + } + if(m->buttons & 7){ + down = 1; + if(buf && m->xy.x >= (t.x - w)){ + down = 0; + for(i = 0; i < n; i += l){ + l = chartorune(&k, buf+i); + t.x += stringnwidth(font, buf+i, 1); + if(t.x > m->xy.x) + break; + } + tick = i; + } + continue; + } + done = down; + break; + } + if(save){ + draw(b, save->r, save, nil, save->r.min); + freeimage(save); + save = nil; + } + } + + replclipr(b, 0, sc); + + freeimage(backcol); + freeimage(bordcol); + flushimage(display, 1); + + return n; +} + diff --git a/src/cmd/paint/mkfile b/src/cmd/paint/mkfile new file mode 100644 index 00000000..272db4b4 --- /dev/null +++ b/src/cmd/paint/mkfile @@ -0,0 +1,11 @@ +<$PLAN9/src/mkhdr + +TARG=paint + +OFILES=\ + eenter.$O\ + paint.$O\ + +HFILES=paint.h\ + +<$PLAN9/src/mkone diff --git a/src/cmd/paint/paint.c b/src/cmd/paint/paint.c new file mode 100644 index 00000000..7dce3710 --- /dev/null +++ b/src/cmd/paint/paint.c @@ -0,0 +1,859 @@ +/* +This code was taken from 9front repository (https://code.9front.org/hg/plan9front). +It is subject to license from 9front, below is a reproduction of the license. + +Copyright (c) 20XX 9front + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#include +#include +#include +#include +#include + +/* additional libdraw function needed - defined here to avoid API change */ +extern int eenter(char*, char*, int, Mouse*); + +char *filename; +int zoom = 1; +int brush = 1; +Point spos; /* position on screen */ +Point cpos; /* position on canvas */ +Image *canvas; +Image *ink; +Image *back; +Image *pal[16]; /* palette */ +Rectangle palr; /* palette rect on screen */ +Rectangle penr; /* pen size rect on screen */ + +enum { + NBRUSH = 10+1, +}; + +int nundo = 0; +Image *undo[1024]; + +int c64[] = { /* c64 color palette */ + 0x000000, + 0xFFFFFF, + 0x68372B, + 0x70A4B2, + 0x6F3D86, + 0x588D43, + 0x352879, + 0xB8C76F, + 0x6F4F25, + 0x433900, + 0x9A6759, + 0x444444, + 0x6C6C6C, + 0x9AD284, + 0x6C5EB5, + 0x959595, +}; + +/* + * get bounding rectnagle for stroke from r.min to r.max with + * specified brush (size). + */ +static Rectangle +strokerect(Rectangle r, int brush) +{ + r = canonrect(r); + return Rect(r.min.x-brush, r.min.y-brush, r.max.x+brush+1, r.max.y+brush+1); +} + +/* + * draw stroke from r.min to r.max to dst with color ink and + * brush (size). + */ +static void +strokedraw(Image *dst, Rectangle r, Image *ink, int brush) +{ + if(!eqpt(r.min, r.max)) + line(dst, r.min, r.max, Enddisc, Enddisc, brush, ink, ZP); + fillellipse(dst, r.max, brush, brush, ink, ZP); +} + +/* + * A draw operation that touches only the area contained in bot but not in top. + * mp and sp get aligned with bot.min. + */ +static void +gendrawdiff(Image *dst, Rectangle bot, Rectangle top, + Image *src, Point sp, Image *mask, Point mp, int op) +{ + Rectangle r; + Point origin; + Point delta; + + if(Dx(bot)*Dy(bot) == 0) + return; + + /* no points in bot - top */ + if(rectinrect(bot, top)) + return; + + /* bot - top ≡ bot */ + if(Dx(top)*Dy(top)==0 || rectXrect(bot, top)==0){ + gendrawop(dst, bot, src, sp, mask, mp, op); + return; + } + + origin = bot.min; + /* split bot into rectangles that don't intersect top */ + /* left side */ + if(bot.min.x < top.min.x){ + r = Rect(bot.min.x, bot.min.y, top.min.x, bot.max.y); + delta = subpt(r.min, origin); + gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); + bot.min.x = top.min.x; + } + + /* right side */ + if(bot.max.x > top.max.x){ + r = Rect(top.max.x, bot.min.y, bot.max.x, bot.max.y); + delta = subpt(r.min, origin); + gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); + bot.max.x = top.max.x; + } + + /* top */ + if(bot.min.y < top.min.y){ + r = Rect(bot.min.x, bot.min.y, bot.max.x, top.min.y); + delta = subpt(r.min, origin); + gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); + bot.min.y = top.min.y; + } + + /* bottom */ + if(bot.max.y > top.max.y){ + r = Rect(bot.min.x, top.max.y, bot.max.x, bot.max.y); + delta = subpt(r.min, origin); + gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); + bot.max.y = top.max.y; + } +} + +int +alphachan(ulong chan) +{ + for(; chan; chan >>= 8) + if(TYPE(chan) == CAlpha) + return 1; + return 0; +} + +void +zoomdraw(Image *d, Rectangle r, Rectangle top, Image *b, Image *s, Point sp, int f) +{ + Rectangle dr; + Image *t; + Point a; + int w; + + a = ZP; + if(r.min.x < d->r.min.x){ + sp.x += (d->r.min.x - r.min.x)/f; + a.x = (d->r.min.x - r.min.x)%f; + r.min.x = d->r.min.x; + } + if(r.min.y < d->r.min.y){ + sp.y += (d->r.min.y - r.min.y)/f; + a.y = (d->r.min.y - r.min.y)%f; + r.min.y = d->r.min.y; + } + rectclip(&r, d->r); + w = s->r.max.x - sp.x; + if(w > Dx(r)) + w = Dx(r); + dr = r; + dr.max.x = dr.min.x+w; + if(!alphachan(s->chan)) + b = nil; + if(f <= 1){ + if(b) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD); + gendrawdiff(d, dr, top, s, sp, nil, ZP, SoverD); + return; + } + if((t = allocimage(display, dr, s->chan, 0, 0)) == nil) + return; + for(; dr.min.y < r.max.y; dr.min.y++){ + dr.max.y = dr.min.y+1; + draw(t, dr, s, nil, sp); + if(++a.y == f){ + a.y = 0; + sp.y++; + } + } + dr = r; + for(sp=dr.min; dr.min.x < r.max.x; sp.x++){ + dr.max.x = dr.min.x+1; + if(b) gendrawdiff(d, dr, top, b, sp, nil, ZP, SoverD); + gendrawdiff(d, dr, top, t, sp, nil, ZP, SoverD); + for(dr.min.x++; ++a.x < f && dr.min.x < r.max.x; dr.min.x++){ + dr.max.x = dr.min.x+1; + gendrawdiff(d, dr, top, d, Pt(dr.min.x-1, dr.min.y), nil, ZP, SoverD); + } + a.x = 0; + } + freeimage(t); +} + +Point +s2c(Point p){ + p = subpt(p, spos); + if(p.x < 0) p.x -= zoom-1; + if(p.y < 0) p.y -= zoom-1; + return addpt(divpt(p, zoom), cpos); +} + +Point +c2s(Point p){ + return addpt(mulpt(subpt(p, cpos), zoom), spos); +} + +Rectangle +c2sr(Rectangle r){ + return Rpt(c2s(r.min), c2s(r.max)); +} + +void +update(Rectangle *rp){ + if(canvas==nil) + draw(screen, screen->r, back, nil, ZP); + else { + if(rp == nil) + rp = &canvas->r; + gendrawdiff(screen, screen->r, c2sr(canvas->r), back, ZP, nil, ZP, SoverD); + zoomdraw(screen, c2sr(*rp), ZR, back, canvas, rp->min, zoom); + } + flushimage(display, 1); +} + +void +expand(Rectangle r) +{ + Rectangle nr; + Image *tmp; + + if(canvas==nil){ + if((canvas = allocimage(display, r, screen->chan, 0, DNofill)) == nil) + sysfatal("allocimage: %r"); + draw(canvas, canvas->r, back, nil, ZP); + return; + } + nr = canvas->r; + combinerect(&nr, r); + if(eqrect(nr, canvas->r)) + return; + if((tmp = allocimage(display, nr, canvas->chan, 0, DNofill)) == nil) + return; + draw(tmp, canvas->r, canvas, nil, canvas->r.min); + gendrawdiff(tmp, tmp->r, canvas->r, back, ZP, nil, ZP, SoverD); + freeimage(canvas); + canvas = tmp; +} + +void +save(Rectangle r, int mark) +{ + Image *tmp; + int x; + + if(mark){ + x = nundo++ % nelem(undo); + if(undo[x]) + freeimage(undo[x]); + undo[x] = nil; + } + if(canvas==nil || nundo<0) + return; + if(!rectclip(&r, canvas->r)) + return; + if((tmp = allocimage(display, r, canvas->chan, 0, DNofill)) == nil) + return; + draw(tmp, r, canvas, nil, r.min); + x = nundo++ % nelem(undo); + if(undo[x]) + freeimage(undo[x]); + undo[x] = tmp; +} + +void +restore(int n) +{ + Image *tmp; + int x; + + while(nundo > 0){ + if(n-- == 0) + return; + x = --nundo % nelem(undo); + if((tmp = undo[x]) == nil) + return; + undo[x] = nil; + if(canvas == nil || canvas->chan != tmp->chan){ + freeimage(canvas); + canvas = tmp; + update(nil); + } else { + expand(tmp->r); + draw(canvas, tmp->r, tmp, nil, tmp->r.min); + update(&tmp->r); + freeimage(tmp); + } + } +} + +typedef struct { + Rectangle r; + Rectangle r0; + Image* dst; + + int yscan; /* current scanline */ + int wscan; /* bscan width in bytes */ + Image* iscan; /* scanline image */ + uchar* bscan; /* scanline buffer */ + + int nmask; /* size of bmask in bytes */ + int wmask; /* width of bmask in bytes */ + Image* imask; /* mask image */ + uchar* bmask; /* mask buffer */ + + int ncmp; + uchar bcmp[4]; +} Filldata; + +void +fillscan(Filldata *f, Point p0) +{ + int x, y; + uchar *b; + + x = p0.x; + y = p0.y; + b = f->bmask + y*f->wmask; + if(b[x/8] & 0x80>>(x%8)) + return; + + if(f->yscan != y){ + draw(f->iscan, f->iscan->r, f->dst, nil, Pt(f->r.min.x, f->r.min.y+y)); + if(unloadimage(f->iscan, f->iscan->r, f->bscan, f->wscan) < 0) + return; + f->yscan = y; + } + + for(x = p0.x; x >= 0; x--){ + if(memcmp(f->bscan + x*f->ncmp, f->bcmp, f->ncmp)) + break; + b[x/8] |= 0x80>>(x%8); + } + for(x = p0.x+1; x < f->r0.max.x; x++){ + if(memcmp(f->bscan + x*f->ncmp, f->bcmp, f->ncmp)) + break; + b[x/8] |= 0x80>>(x%8); + } + + y = p0.y-1; + if(y >= 0){ + for(x = p0.x; x >= 0; x--){ + if((b[x/8] & 0x80>>(x%8)) == 0) + break; + fillscan(f, Pt(x, y)); + } + for(x = p0.x+1; x < f->r0.max.x; x++){ + if((b[x/8] & 0x80>>(x%8)) == 0) + break; + fillscan(f, Pt(x, y)); + } + } + + y = p0.y+1; + if(y < f->r0.max.y){ + for(x = p0.x; x >= 0; x--){ + if((b[x/8] & 0x80>>(x%8)) == 0) + break; + fillscan(f, Pt(x, y)); + } + for(x = p0.x+1; x < f->r0.max.x; x++){ + if((b[x/8] & 0x80>>(x%8)) == 0) + break; + fillscan(f, Pt(x, y)); + } + } +} + +void +floodfill(Image *dst, Rectangle r, Point p, Image *src) +{ + Filldata f; + + if(!rectclip(&r, dst->r)) + return; + if(!ptinrect(p, r)) + return; + memset(&f, 0, sizeof(f)); + f.dst = dst; + f.r = r; + f.r0 = rectsubpt(r, r.min); + f.wmask = bytesperline(f.r0, 1); + f.nmask = f.wmask*f.r0.max.y; + if((f.bmask = mallocz(f.nmask, 1)) == nil) + goto out; + if((f.imask = allocimage(display, f.r0, GREY1, 0, DNofill)) == nil) + goto out; + + r = f.r0; + r.max.y = 1; + if((f.iscan = allocimage(display, r, RGB24, 0, DNofill)) == nil) + goto out; + f.yscan = -1; + f.wscan = bytesperline(f.iscan->r, f.iscan->depth); + if((f.bscan = mallocz(f.wscan, 0)) == nil) + goto out; + + r = Rect(0,0,1,1); + f.ncmp = (f.iscan->depth+7) / 8; + draw(f.iscan, r, dst, nil, p); + if(unloadimage(f.iscan, r, f.bcmp, sizeof(f.bcmp)) < 0) + goto out; + + fillscan(&f, subpt(p, f.r.min)); + + loadimage(f.imask, f.imask->r, f.bmask, f.nmask); + draw(f.dst, f.r, src, f.imask, f.imask->r.min); +out: + free(f.bmask); + free(f.bscan); + if(f.iscan) + freeimage(f.iscan); + if(f.imask) + freeimage(f.imask); +} + +void +translate(Point d) +{ + Rectangle r, nr; + + if(canvas==nil || d.x==0 && d.y==0) + return; + r = c2sr(canvas->r); + nr = rectaddpt(r, d); + rectclip(&r, screen->clipr); + draw(screen, rectaddpt(r, d), screen, nil, r.min); + zoomdraw(screen, nr, rectaddpt(r, d), back, canvas, canvas->r.min, zoom); + gendrawdiff(screen, screen->r, nr, back, ZP, nil, ZP, SoverD); + spos = addpt(spos, d); + flushimage(display, 1); +} + +void +setzoom(Point o, int z) +{ + if(z < 1) + return; + cpos = s2c(o); + spos = o; + zoom = z; + update(nil); +} + +void +center(void) +{ + cpos = ZP; + if(canvas) + cpos = addpt(canvas->r.min, + divpt(subpt(canvas->r.max, canvas->r.min), 2)); + spos = addpt(screen->r.min, + divpt(subpt(screen->r.max, screen->r.min), 2)); + update(nil); +} + +void +drawpal(void) +{ + Rectangle r, rr; + int i; + + r = screen->r; + r.min.y = r.max.y - 20; + replclipr(screen, 0, r); + + penr = r; + penr.min.x = r.max.x - NBRUSH*Dy(r); + + palr = r; + palr.max.x = penr.min.x; + + r = penr; + draw(screen, r, back, nil, ZP); + for(i=0; ir; + r.max.y -= Dy(palr); + replclipr(screen, 0, r); +} + +int +hitpal(Mouse m) +{ + if(ptinrect(m.xy, penr)){ + if(m.buttons & 7){ + brush = ((m.xy.x - penr.min.x) * NBRUSH) / Dx(penr); + drawpal(); + } + return 1; + } + if(ptinrect(m.xy, palr)){ + Image *col; + + col = pal[(m.xy.x - palr.min.x) * nelem(pal) / Dx(palr)]; + switch(m.buttons & 7){ + case 1: + ink = col; + drawpal(); + break; + case 2: + back = col; + drawpal(); + update(nil); + break; + } + return 1; + } + return 0; +} + +void +catch(void * _, char *msg) +{ + USED(_); + if(strstr(msg, "closed pipe")) + noted(NCONT); + noted(NDFLT); +} + +int +pipeline(char *fmt, ...) +{ + char buf[1024]; + va_list a; + int p[2]; + + va_start(a, fmt); + vsnprint(buf, sizeof(buf), fmt, a); + va_end(a); + if(pipe(p) < 0) + return -1; + switch(rfork(RFPROC|RFMEM|RFFDG|RFNOTEG)){ // RFEND not available in libc port + case -1: + close(p[0]); + close(p[1]); + return -1; + case 0: + close(p[1]); + dup(p[0], 0); + dup(p[0], 1); + close(p[0]); + execl("/bin/rc", "rc", "-c", buf, nil); + exits("exec"); + } + close(p[0]); + return p[1]; +} + +void +usage(void) +{ + fprint(2, "usage: %s [ file ]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + char *s, buf[1024]; + Rectangle r; + Image *img; + int i, fd; + Event e; + Mouse m; + Point p, d; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if(argc == 1) + filename = strdup(argv[0]); + else if(argc != 0) + usage(); + + if(initdraw(0, 0, "paint") < 0) + sysfatal("initdraw: %r"); + + if(filename){ + if((fd = open(filename, OREAD)) < 0) + sysfatal("open: %r"); + if((canvas = readimage(display, fd, 0)) == nil) + sysfatal("readimage: %r"); + close(fd); + } + + /* palette initialization */ + for(i=0; ir)){ + back = img; + drawpal(); + update(nil); + break; + } + r = canvas->r; + save(r, 1); + floodfill(canvas, r, p, img); + update(&r); + + /* wait for mouse release */ + while(event(&e) == Emouse && (e.mouse.buttons & 7) != 0) + ; + break; + } + r = strokerect(Rpt(p, p), brush); + expand(r); + save(r, 1); + strokedraw(canvas, Rpt(p, p), img, brush); + update(&r); + for(;;){ + m = e.mouse; + if(event(&e) != Emouse) + break; + if((e.mouse.buttons ^ m.buttons) & 7) + break; + d = s2c(e.mouse.xy); + if(eqpt(d, p)) + continue; + r = strokerect(Rpt(p, d), brush); + expand(r); + save(r, 0); + strokedraw(canvas, Rpt(p, d), img, brush); + update(&r); + p = d; + } + break; + case 4: + for(;;){ + m = e.mouse; + if(event(&e) != Emouse) + break; + if((e.mouse.buttons & 7) != 4) + break; + translate(subpt(e.mouse.xy, m.xy)); + } + break; + } + break; + case Ekeyboard: + switch(e.kbdc){ + case Kesc: + zoom = 1; + center(); + break; + case '+': + if(zoom < 0x1000) + setzoom(e.mouse.xy, zoom*2); + break; + case '-': + if(zoom > 1) + setzoom(e.mouse.xy, zoom/2); + break; + case 'c': + if(canvas == nil) + break; + save(canvas->r, 1); + freeimage(canvas); + canvas = nil; + update(nil); + break; + case 'u': + restore(16); + break; + case 'f': + brush = NBRUSH-1; + drawpal(); + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + brush = e.kbdc - '0'; + drawpal(); + break; + default: + if(e.kbdc == Kdel) + e.kbdc = 'q'; + buf[0] = 0; + if(filename && (e.kbdc == 'r' || e.kbdc == 'w')) + snprint(buf, sizeof(buf), "%C %s", e.kbdc, filename); + else if(e.kbdc > 0x20 && e.kbdc < 0x7f) + snprint(buf, sizeof(buf), "%C", e.kbdc); + if(eenter("Cmd", buf, sizeof(buf), &e.mouse) <= 0) + break; + if(strcmp(buf, "q") == 0) + exits(nil); + s = buf+1; + while(*s == ' ' || *s == '\t') + s++; + if(*s == 0) + break; + switch(buf[0]){ + case 'r': + if((fd = open(s, OREAD)) < 0){ + Error: + snprint(buf, sizeof(buf), "%r"); + eenter(buf, nil, 0, &e.mouse); + break; + } + free(filename); + filename = strdup(s); + Readimage: + unlockdisplay(display); + img = readimage(display, fd, 1); + close(fd); + lockdisplay(display); + if(img == nil){ + werrstr("readimage: %r"); + goto Error; + } + if(canvas){ + save(canvas->r, 1); + freeimage(canvas); + } + canvas = img; + center(); + break; + case 'w': + if((fd = create(s, OWRITE, 0660)) < 0) + goto Error; + free(filename); + filename = strdup(s); + Writeimage: + if(canvas) + if(writeimage(fd, canvas, 0) < 0){ + close(fd); + werrstr("writeimage: %r"); + goto Error; + } + close(fd); + break; + case '<': + if((fd = pipeline("%s", s)) < 0) + goto Error; + goto Readimage; + case '>': + if((fd = pipeline("%s", s)) < 0) + goto Error; + goto Writeimage; + case '|': + if(canvas == nil) + break; + if((fd = pipeline("%s", s)) < 0) + goto Error; + switch(rfork(RFMEM|RFPROC|RFFDG)){ + case -1: + close(fd); + werrstr("rfork: %r"); + goto Error; + case 0: + writeimage(fd, canvas, 1); + exits(nil); + } + goto Readimage; + } + break; + } + break; + } + } +} + +void +eresized(int _) +{ + USED(_); + if(getwindow(display, Refnone) < 0) + sysfatal("resize failed"); + drawpal(); + update(nil); +} -- cgit v1.2.3 From 3ae09bee86485f1aaa517f68ed2823ae9b960524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 8 Feb 2018 13:59:31 +0100 Subject: file: add missing newlines to file types --- src/cmd/file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cmd/file.c b/src/cmd/file.c index 0afb9ba3..232c1b30 100644 --- a/src/cmd/file.c +++ b/src/cmd/file.c @@ -519,10 +519,10 @@ Filemagic long0tab[] = { 0x32636170, 0xFFFF00FF, "pac4 audio file\n", OCTET, 0xBA010000, 0xFFFFFFFF, "mpeg system stream\n", OCTET, 0x30800CC0, 0xFFFFFFFF, "inferno .dis executable\n", OCTET, - 0x04034B50, 0xFFFFFFFF, "zip archive\n", "application/zip", + 0x04034B50, 0xFFFFFFFF, "zip archive\n", "application/zip\n", 070707, 0xFFFF, "cpio archive\n", OCTET, - 0x2F7, 0xFFFF, "tex dvi\n", "application/dvi", - 0xfffa0000, 0xfffe0000, "mp3 audio", "audio/mpeg", + 0x2F7, 0xFFFF, "tex dvi\n", "application/dvi\n", + 0xfffa0000, 0xfffe0000, "mp3 audio\n", "audio/mpeg\n", }; int -- cgit v1.2.3 From 3ebbb99ce3b13357f4dfb0156877c6e5892de5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BChl?= Date: Thu, 8 Feb 2018 14:00:46 +0100 Subject: file: recognize Mach-O binaries and Java class files --- src/cmd/file.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cmd/file.c b/src/cmd/file.c index 232c1b30..32d580cd 100644 --- a/src/cmd/file.c +++ b/src/cmd/file.c @@ -523,6 +523,9 @@ Filemagic long0tab[] = { 070707, 0xFFFF, "cpio archive\n", OCTET, 0x2F7, 0xFFFF, "tex dvi\n", "application/dvi\n", 0xfffa0000, 0xfffe0000, "mp3 audio\n", "audio/mpeg\n", + 0xcafebabe, 0xFFFFFFFF, "Mach-O fat executable\n", "application/x-mach-binary\n", + 0xfeedface, 0xFFFFFFFE, "Mach-O executable\n", "application/x-mach-binary\n", + 0xbebafeca, 0xFFFFFFFF, "Java class\n", "application/x-java-applet\n", }; int -- cgit v1.2.3 From 16d00819899260085ee10949012b07bf1c203db6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 15 Nov 2018 23:52:05 -0500 Subject: libdraw: redo default font construction to be hidpi-safe If $font is not set, the default font is constructed from font data linked into every libdraw binary. That process was different from the usual openfont code, and so it was not hidpi-aware, resulting in very tiny fonts out of the box on hidpi systems, until users set $font. Fix this by using openfont to construct the default font, by recognizing the name *default* when looking for font and subfont file contents. Then all the hidpi scaling applies automatically. As a side effect, the concept of a 'default subfont' is gone, as are display->defaultsubfont, getdefont, and memgetdefont. --- src/cmd/fontsrv/a.h | 1 - src/cmd/fontsrv/main.c | 3 - src/libdraw/buildfont.c | 2 +- src/libdraw/defont.c | 402 --------------------------------------------- src/libdraw/defont.h | 303 ++++++++++++++++++++++++++++++++++ src/libdraw/font.c | 3 +- src/libdraw/getdefont.c | 60 ------- src/libdraw/getsubfont.c | 31 +++- src/libdraw/init.c | 32 ++-- src/libdraw/mkfile | 4 +- src/libdraw/openfont.c | 7 + src/libdraw/readsubfont.c | 16 ++ src/libdraw/subfontcache.c | 2 - src/libdraw/subfontname.c | 7 +- src/libmemdraw/defont.c | 68 -------- src/libmemdraw/mkfile | 1 - 16 files changed, 372 insertions(+), 570 deletions(-) delete mode 100644 src/libdraw/defont.c create mode 100644 src/libdraw/defont.h delete mode 100644 src/libdraw/getdefont.c delete mode 100644 src/libmemdraw/defont.c (limited to 'src') diff --git a/src/cmd/fontsrv/a.h b/src/cmd/fontsrv/a.h index 3344d28e..164b1bd6 100644 --- a/src/cmd/fontsrv/a.h +++ b/src/cmd/fontsrv/a.h @@ -30,6 +30,5 @@ Memsubfont* mksubfont(XFont*, char*, int, int, int, int); extern XFont *xfont; extern int nxfont; void *emalloc9p(ulong); -extern Memsubfont *defont; void drawpjw(Memimage*, Fontchar*, int, int, int, int); diff --git a/src/cmd/fontsrv/main.c b/src/cmd/fontsrv/main.c index b00802d8..37f0da32 100644 --- a/src/cmd/fontsrv/main.c +++ b/src/cmd/fontsrv/main.c @@ -13,8 +13,6 @@ #include "a.h" -Memsubfont *defont; - void usage(void) { @@ -526,7 +524,6 @@ main(int argc, char **argv) fmtinstall('R', Rfmt); fmtinstall('P', Pfmt); memimageinit(); - defont = getmemdefont(); loadfonts(); qsort(xfont, nxfont, sizeof xfont[0], fontcmp); diff --git a/src/libdraw/buildfont.c b/src/libdraw/buildfont.c index ed533b14..02d976e1 100644 --- a/src/libdraw/buildfont.c +++ b/src/libdraw/buildfont.c @@ -132,7 +132,7 @@ freefont(Font *f) } for(i=0; insubf; i++){ s = f->subf[i].f; - if(s && (!display || s!=display->defaultsubfont)) + if(s) freesubfont(s); } freeimage(f->cacheimage); diff --git a/src/libdraw/defont.c b/src/libdraw/defont.c deleted file mode 100644 index b0c85e1d..00000000 --- a/src/libdraw/defont.c +++ /dev/null @@ -1,402 +0,0 @@ -#include -#include -#include - -/* - * lucm/latin1.9, in uncompressed form - */ -uchar -defontdata[] = -{ -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x32,0x33,0x30,0x34,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x35,0x20,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x06,0x06,0x03,0x42,0x40,0x00,0x00,0x00,0x18,0x03,0x03, -0x02,0x43,0x00,0x60,0x60,0x48,0x00,0x0d,0x0c,0x01,0x81,0x80,0xd0,0x90,0x00,0x00, -0x18,0x01,0x81,0x81,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x7f,0x9c,0x1c, -0x0e,0x07,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x70, -0x38,0x1c,0x0e,0x04,0x81,0xc1,0xc0,0x70,0x00,0x1c,0x1c,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x80,0xc0,0x63,0xe3, -0xf1,0xf8,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x7f,0xff,0xff,0x1f,0x8f, -0xc7,0xe3,0xf1,0xfb,0x7e,0x3e,0x3f,0x8f,0xff,0xe3,0xe3,0xff,0xff,0xff,0xff,0xff, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x0c,0x18,0x09,0x05,0x82,0x40,0xc0,0x00,0x00,0x06,0x0c,0x04, -0x82,0x40,0xc1,0x80,0x90,0x48,0x00,0x16,0x03,0x06,0x02,0x41,0x60,0x90,0x00,0x00, -0x06,0x06,0x02,0x41,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x7f,0xa0,0x10, -0x08,0x04,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x48, -0x24,0x12,0x09,0x06,0x82,0x01,0x00,0x90,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x04,0x80,0x00,0x40,0x00,0x00,0x38,0x06,0x18,0x00,0x00,0x00,0x00,0x00, -0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0xc6,0x01,0xf0,0x00,0x00,0x0c,0x00,0x18,0x00,0x00,0x30,0x00,0x3c, -0x00,0x60,0x06,0x01,0x8c,0x07,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0xc3,0xc0,0x01,0x54,0x9c,0xc0,0x5f,0xef, -0xf7,0xfb,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0x7f,0xff,0xff,0x6f,0xb7, -0xdb,0xed,0xf6,0xf9,0x7d,0xfe,0xff,0x6f,0xff,0xdf,0xef,0xff,0xff,0xff,0xff,0xff, -0xff,0x00,0x01,0x00,0x00,0x00,0x00,0x30,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x30,0x06,0x06,0x06,0x82,0x80,0xc0,0x00, -0x00,0x18,0x03,0x03,0x02,0x41,0x80,0x30,0x30,0x24,0x76,0x0d,0x0c,0x00,0xc0,0xc0, -0xd0,0x50,0x00,0x00,0x18,0x01,0x81,0x81,0x40,0x30,0x00,0x28,0x0f,0x7f,0xbc,0x1c, -0x0e,0x07,0x03,0xc0,0x10,0x70,0x24,0x10,0x09,0x07,0x03,0x80,0xe0,0x70,0x90,0x48, -0x24,0x12,0x09,0x05,0x81,0x81,0xc0,0x80,0x70,0x18,0x1c,0x07,0x01,0xc1,0xc0,0x90, -0x00,0x0c,0x04,0x84,0x83,0xe1,0xc0,0xe0,0x38,0x0c,0x0c,0x02,0x00,0x00,0x00,0x00, -0x00,0x06,0x1c,0x06,0x0f,0x87,0xc0,0x63,0xf8,0x78,0xfe,0x3e,0x0e,0x00,0x00,0x00, -0x00,0x00,0x00,0x7c,0x1c,0x0c,0x1f,0x03,0xc7,0xc3,0xf1,0xf8,0x3c,0x63,0x3f,0x0f, -0x8c,0x66,0x06,0x19,0x84,0x78,0x7e,0x1e,0x1f,0x07,0xcf,0xf3,0x1b,0x0d,0x86,0x63, -0x61,0x9f,0xc6,0x06,0x00,0x30,0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x30,0x00,0x60, -0x00,0x60,0x06,0x01,0x8c,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xc0,0x60,0x00,0xaa,0xb6,0xc0,0x43,0xe3, -0xf1,0xf8,0xfc,0x3f,0xef,0x8f,0xdb,0xef,0xf6,0xf8,0xfb,0xff,0x1f,0x8f,0x6f,0xb7, -0xdb,0xed,0xf6,0xfa,0x7e,0x7e,0x3f,0x7f,0x8f,0xe7,0xe3,0xf8,0xfe,0x3e,0x3f,0x6f, -0x00,0x00,0x01,0x01,0xc8,0x0b,0x0c,0x30,0x7c,0x14,0x0f,0x0f,0x00,0x00,0x00,0x00, -0x78,0x00,0x1c,0x00,0x0f,0x07,0x81,0x80,0x00,0x7c,0x00,0x00,0x1c,0x0f,0x80,0x04, -0x42,0x23,0x90,0x00,0x18,0x0c,0x06,0x03,0x01,0x80,0xc0,0x3c,0x3c,0x3f,0x1f,0x8f, -0xc7,0xe7,0xe3,0xf1,0xf8,0xfc,0x7c,0x30,0x8f,0x07,0x83,0xc1,0xe0,0xf0,0x00,0x3d, -0x31,0x98,0xcc,0x66,0x36,0x19,0x80,0xcc,0x0c,0x18,0x09,0x0b,0x02,0x81,0x20,0x00, -0x00,0x06,0x0c,0x04,0x82,0x40,0x60,0xc0,0x48,0x24,0x18,0x16,0x03,0x03,0x01,0x21, -0x60,0x50,0x00,0x00,0x06,0x06,0x02,0x41,0x40,0xc1,0x80,0x28,0x87,0x7f,0x84,0x10, -0x08,0x04,0x02,0x40,0x38,0x48,0x24,0x10,0x09,0x04,0x04,0x81,0x00,0x80,0x90,0x48, -0x24,0x12,0x09,0x04,0x80,0x41,0x00,0x80,0x40,0x04,0x10,0x04,0x02,0x01,0x20,0x90, -0x00,0x0c,0x04,0x84,0x86,0x53,0x65,0xb0,0x08,0x18,0x06,0x0a,0x80,0x00,0x00,0x00, -0x00,0x0c,0x36,0x0e,0x19,0xcc,0xe0,0xe3,0xf8,0xcc,0xfe,0x63,0x1b,0x00,0x00,0x00, -0x00,0x00,0x00,0xc6,0x62,0x0c,0x19,0x86,0x66,0x63,0x01,0x80,0x66,0x63,0x0c,0x01, -0x8c,0xc6,0x06,0x19,0xc4,0xcc,0x63,0x33,0x19,0x8c,0x61,0x83,0x1b,0x0d,0x86,0x63, -0x61,0x80,0xc6,0x03,0x00,0x30,0x30,0x00,0x1c,0x00,0x18,0x00,0x00,0x30,0x00,0x60, -0x00,0x60,0x00,0x00,0x0c,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xc0,0x60,0x01,0x54,0x86,0xc0,0x7b,0xef, -0xf7,0xfb,0xfd,0xbf,0xc7,0xb7,0xdb,0xef,0xf6,0xfb,0xfb,0x7e,0xff,0x7f,0x6f,0xb7, -0xdb,0xed,0xf6,0xfb,0x7f,0xbe,0xff,0x7f,0xbf,0xfb,0xef,0xfb,0xfd,0xfe,0xdf,0x6f, -0xff,0x00,0x07,0x83,0x24,0x13,0x0c,0x30,0xc6,0x00,0x10,0x81,0x80,0x00,0x00,0x00, -0x84,0x00,0x22,0x00,0x01,0x80,0xc0,0x00,0x00,0xf4,0x00,0x00,0x2c,0x18,0xc0,0x0c, -0x46,0x20,0x90,0x00,0x18,0x0c,0x06,0x03,0x01,0x80,0xc0,0x70,0x66,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x66,0x38,0x99,0x8c,0xc6,0x63,0x31,0x98,0x00,0x66, -0x31,0x98,0xcc,0x66,0x36,0x19,0x80,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0xff,0x7f,0xb8,0x1c, -0x0e,0x07,0x02,0x40,0x7c,0x70,0x3c,0x10,0x09,0x07,0x04,0x00,0xc0,0x60,0xe0,0x70, -0x38,0x1c,0x0e,0x04,0x83,0x81,0xc0,0x70,0x70,0x38,0x1c,0x07,0x02,0xc1,0xc0,0x90, -0x00,0x0c,0x00,0x04,0x86,0x43,0x69,0xb0,0x30,0x18,0x06,0x07,0x01,0x00,0x00,0x00, -0x00,0x0c,0x63,0x16,0x00,0xc0,0x61,0x62,0x01,0x80,0x06,0x63,0x31,0x80,0x00,0x00, -0x60,0x00,0xc0,0x06,0x43,0x16,0x19,0x8c,0x06,0x33,0x01,0x80,0xc0,0x63,0x0c,0x01, -0x8c,0x86,0x07,0x39,0xc5,0x86,0x63,0x61,0x99,0x8c,0x01,0x83,0x1b,0x0d,0xb6,0x63, -0x31,0x01,0x86,0x03,0x00,0x30,0x30,0x00,0x1c,0x3e,0x1b,0x03,0xc1,0xf0,0xf0,0x60, -0x3e,0x6e,0x3e,0x0f,0x8c,0x60,0xc5,0xb1,0xb8,0x38,0x6c,0x0f,0x8c,0xc7,0xc1,0x83, -0x19,0x8d,0x82,0x63,0x31,0x9f,0xc1,0x80,0xc0,0xc0,0x00,0xaa,0x86,0xc0,0x47,0xe3, -0xf1,0xf8,0xfd,0xbf,0x83,0x8f,0xc3,0xef,0xf6,0xf8,0xfc,0xff,0x3f,0x9f,0x1f,0x8f, -0xc7,0xe3,0xf1,0xfb,0x7c,0x7e,0x3f,0x8f,0x8f,0xc7,0xe3,0xf8,0xfd,0x3e,0x3f,0x6f, -0x00,0x0c,0x0d,0x43,0x03,0xe1,0x88,0x30,0xc0,0x00,0x27,0x41,0x80,0x00,0x00,0x01, -0x72,0x00,0x22,0x04,0x01,0x80,0xc0,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xc0,0x04, -0x82,0x43,0x20,0x18,0x2c,0x16,0x0b,0x05,0x82,0xc1,0x60,0xb0,0xc0,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x38,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x00,0xc7, -0x31,0x98,0xcc,0x66,0x33,0x11,0xf8,0xc8,0x7c,0x3e,0x1f,0x0f,0x87,0xc3,0xe1,0xd8, -0x3c,0x1e,0x0f,0x07,0x83,0xc7,0xc3,0xe1,0xf0,0xf8,0x06,0x37,0x07,0x03,0x81,0xc0, -0xe0,0x70,0x10,0x1d,0x31,0x98,0xcc,0x66,0x33,0x19,0xb0,0xc6,0x8f,0x7f,0x87,0x03, -0x81,0x80,0x90,0x30,0x6c,0x48,0x24,0x10,0x06,0x04,0x04,0x80,0x20,0x10,0x10,0x0e, -0x07,0x03,0x81,0xc0,0x60,0x88,0x38,0x0c,0x40,0x09,0x03,0x84,0x02,0x41,0x40,0x90, -0x00,0x0c,0x00,0x1f,0xe7,0x41,0xd1,0xa0,0x00,0x30,0x03,0x0a,0x81,0x00,0x00,0x00, -0x00,0x18,0x63,0x06,0x00,0xc0,0xc2,0x62,0x01,0xb0,0x0c,0x72,0x31,0x86,0x03,0x00, -0xc0,0x00,0x60,0x06,0x8f,0x16,0x19,0x0c,0x06,0x33,0x01,0x80,0xc0,0x63,0x0c,0x01, -0x8d,0x06,0x07,0x39,0x65,0x86,0x63,0x61,0x99,0x0e,0x01,0x83,0x19,0x89,0xb6,0x32, -0x33,0x03,0x06,0x01,0x80,0x30,0x78,0x00,0x00,0x03,0x1d,0x86,0x23,0x31,0x99,0xfc, -0x66,0x77,0x06,0x01,0x8c,0x40,0xc6,0xd9,0xdc,0x6c,0x76,0x19,0x8d,0xcc,0x27,0xf3, -0x19,0x8d,0x82,0x63,0x31,0x80,0xc0,0x80,0xc0,0x80,0x01,0x54,0x8c,0xc0,0x78,0xfc, -0x7e,0x7f,0x6f,0xcf,0x93,0xb7,0xdb,0xef,0xf9,0xfb,0xff,0xff,0xdf,0xef,0xef,0xf1, -0xf8,0xfc,0x7e,0x3f,0x9f,0x77,0xc7,0xf3,0xbf,0xf6,0xfc,0x7b,0xfd,0xbe,0xbf,0x6f, -0xff,0x0c,0x19,0x03,0x03,0x61,0x98,0x30,0x78,0x00,0x28,0x4f,0x83,0x30,0x00,0x01, -0x4a,0x00,0x1c,0x04,0x03,0x03,0x80,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xd9,0x84, -0x82,0x40,0xa0,0x18,0x2c,0x16,0x0b,0x05,0x82,0xc1,0x60,0xb0,0xc0,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x2c,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x64,0xcb, -0x31,0x98,0xcc,0x66,0x33,0x31,0x8c,0xd8,0x06,0x03,0x01,0x80,0xc0,0x60,0x30,0x6c, -0x62,0x33,0x19,0x8c,0xc6,0x60,0xc0,0x60,0x30,0x18,0x1e,0x3b,0x8d,0x86,0xc3,0x61, -0xb0,0xd8,0x10,0x36,0x31,0x98,0xcc,0x66,0x33,0x19,0xd8,0xc6,0x0f,0x7f,0x82,0x01, -0x02,0x40,0xd0,0x40,0x6c,0x70,0x24,0x1c,0x06,0x04,0x03,0x01,0xc0,0xe0,0x10,0x12, -0x09,0x04,0x82,0x40,0x90,0x50,0x10,0x12,0x70,0x09,0x04,0x04,0x01,0xc1,0x20,0x60, -0x00,0x0c,0x00,0x04,0x83,0xc0,0x20,0xcc,0x00,0x30,0x03,0x02,0x01,0x00,0x00,0x00, -0x00,0x18,0x63,0x06,0x01,0x83,0x84,0x63,0xf1,0xd8,0x18,0x3c,0x31,0x86,0x03,0x01, -0x83,0xf8,0x30,0x1c,0x9b,0x33,0x1e,0x0c,0x06,0x33,0xe1,0x80,0xc0,0x7f,0x0c,0x01, -0x8f,0x06,0x07,0x79,0x65,0x86,0x66,0x61,0x9e,0x07,0x81,0x83,0x19,0x89,0xb6,0x1c, -0x1a,0x03,0x06,0x01,0x80,0x30,0x48,0x00,0x00,0x03,0x18,0xcc,0x06,0x33,0x18,0x60, -0xc6,0x63,0x06,0x01,0x8c,0x80,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8e,0x4c,0x01,0x83, -0x19,0x8d,0x92,0x32,0x31,0x81,0x87,0x00,0xc0,0x70,0xe4,0xaa,0x98,0xc0,0x7d,0xfe, -0xfd,0xbf,0x2f,0xbf,0x93,0x8f,0xdb,0xe3,0xf9,0xfb,0xff,0x1e,0x3f,0x1f,0xef,0xed, -0xf6,0xfb,0x7d,0xbf,0x6f,0xaf,0xef,0xed,0x8f,0xf6,0xfb,0xfb,0xfe,0x3e,0xdf,0x9f, -0x00,0x00,0x19,0x0f,0xc6,0x30,0xd0,0x00,0xcc,0x00,0x28,0x59,0x86,0x67,0xf0,0x01, -0x72,0x00,0x00,0x3f,0x86,0x00,0xc0,0x03,0x18,0xf4,0x00,0x00,0x0c,0x18,0xcc,0xc5, -0x32,0x83,0x4c,0x00,0x66,0x33,0x19,0x8c,0xc6,0x63,0x31,0xbc,0xc0,0x3e,0x1f,0x0f, -0x87,0xc1,0x80,0xc0,0x60,0x30,0xfb,0x2c,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x38,0xcb, -0x31,0x98,0xcc,0x66,0x31,0xa1,0x8c,0xcc,0x06,0x03,0x01,0x80,0xc0,0x60,0x30,0x6c, -0xc0,0x63,0x31,0x98,0xcc,0x60,0xc0,0x60,0x30,0x18,0x37,0x31,0x98,0xcc,0x66,0x33, -0x19,0x8c,0x00,0x67,0x31,0x98,0xcc,0x66,0x33,0x19,0x8c,0xc6,0x1f,0x7f,0x82,0x01, -0x02,0x40,0xb0,0x40,0x6c,0x07,0x03,0x83,0x80,0xe0,0xe0,0x00,0x18,0x0e,0x10,0x10, -0x08,0x04,0x02,0x00,0xf0,0x20,0x10,0x1e,0x08,0x89,0x03,0x00,0xe0,0x38,0x1c,0x0e, -0x00,0x0c,0x00,0x04,0x81,0xe0,0x41,0x6c,0x00,0x30,0x03,0x00,0x0f,0xe0,0x03,0xf8, -0x00,0x30,0x63,0x06,0x03,0x00,0xc7,0xf0,0x39,0x8c,0x30,0x3e,0x1b,0x80,0x00,0x03, -0x00,0x00,0x18,0x30,0x9b,0x23,0x19,0x0c,0x06,0x33,0x01,0xf8,0xc6,0x63,0x0c,0x01, -0x8d,0x86,0x05,0xd9,0x35,0x86,0x7c,0x61,0x9b,0x01,0xc1,0x83,0x19,0x99,0xb4,0x1c, -0x0c,0x06,0x06,0x00,0xc0,0x30,0xcc,0x00,0x00,0x3f,0x18,0xcc,0x06,0x33,0xf8,0x60, -0xc6,0x63,0x06,0x01,0x8f,0x00,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x0f,0x81,0x83, -0x18,0xd9,0xba,0x1c,0x1b,0x03,0x00,0x80,0xc0,0x81,0x75,0x54,0x98,0xc0,0x7d,0xfe, -0xfd,0xbf,0x4f,0xbf,0x93,0xf8,0xfc,0x7c,0x7f,0x1f,0x1f,0x6f,0xe7,0xf1,0xef,0xef, -0xf7,0xfb,0xfd,0xff,0x0f,0xdf,0xef,0xe1,0xf7,0x76,0xfc,0xff,0x1f,0xc7,0xe3,0xf1, -0xff,0x08,0x19,0x03,0x06,0x31,0xf8,0x00,0xc6,0x00,0x28,0x5b,0x8c,0xc0,0x11,0xf1, -0x4a,0x00,0x00,0x04,0x0c,0x00,0xc0,0x03,0x18,0x74,0x38,0x00,0x0c,0x18,0xc6,0x65, -0x52,0xb8,0x54,0x18,0x46,0x23,0x11,0x88,0xc4,0x62,0x31,0x30,0xc0,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x26,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x10,0xd3, -0x31,0x98,0xcc,0x66,0x30,0xc1,0x8c,0xc6,0x7e,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xfc, -0xc0,0x7f,0x3f,0x9f,0xcf,0xe0,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33, -0x19,0x8c,0xfe,0x6b,0x31,0x98,0xcc,0x66,0x31,0xb1,0x8c,0x6c,0x0e,0x7f,0x82,0x01, -0x01,0x80,0x90,0x30,0xc6,0x08,0x01,0x02,0x00,0x40,0x80,0xe0,0x24,0x04,0x1c,0x10, -0x08,0x04,0x02,0x00,0x90,0x20,0x10,0x12,0x0d,0x86,0x00,0x81,0x00,0x40,0x20,0x10, -0x00,0x04,0x00,0x1f,0xe1,0x70,0xbb,0x28,0x00,0x30,0x03,0x00,0x01,0x00,0x00,0x00, -0x00,0x30,0x63,0x06,0x06,0x00,0x67,0xf0,0x19,0x8c,0x30,0x67,0x0d,0x80,0x00,0x01, -0x83,0xf8,0x30,0x30,0x9b,0x7f,0x19,0x8c,0x06,0x33,0x01,0x80,0xc6,0x63,0x0c,0x01, -0x8c,0xc6,0x05,0xd9,0x35,0x86,0x60,0x61,0x99,0x80,0xe1,0x83,0x18,0xd0,0xdc,0x26, -0x0c,0x0c,0x06,0x00,0xc0,0x30,0x84,0x00,0x00,0x63,0x18,0xcc,0x06,0x33,0x00,0x60, -0xc6,0x63,0x06,0x01,0x8d,0x80,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x03,0xe1,0x83, -0x18,0xd9,0xba,0x1c,0x1b,0x06,0x01,0x80,0xc0,0xc1,0x38,0xaa,0x80,0xc0,0x7d,0xfe, -0xfe,0x7f,0x6f,0xcf,0x39,0xf7,0xfe,0xfd,0xff,0xbf,0x7f,0x0f,0xdb,0xfb,0xe3,0xef, -0xf7,0xfb,0xfd,0xff,0x6f,0xdf,0xef,0xed,0xf2,0x79,0xff,0x7e,0xff,0xbf,0xdf,0xef, -0x00,0x0c,0x19,0x03,0x03,0x60,0x60,0x30,0x66,0x00,0x28,0x4d,0xc6,0x60,0x10,0x00, -0x84,0x00,0x00,0x04,0x0f,0x87,0x80,0x03,0x18,0x14,0x38,0x00,0x3f,0x0f,0x8c,0xc2, -0x90,0x84,0xa4,0x18,0xfe,0x7f,0x3f,0x9f,0xcf,0xe7,0xf1,0xf0,0xc0,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x26,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x38,0xd3, -0x31,0x98,0xcc,0x66,0x30,0xc1,0x98,0xc6,0xc6,0x63,0x31,0x98,0xcc,0x66,0x33,0x60, -0xc0,0x60,0x30,0x18,0x0c,0x00,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33, -0x19,0x8c,0x00,0x6b,0x31,0x98,0xcc,0x66,0x31,0xb1,0x8c,0x6c,0x1c,0x7f,0x81,0x20, -0x90,0x38,0x18,0x0b,0x83,0x06,0x01,0x03,0x80,0x40,0xe0,0x90,0x24,0x04,0x03,0x8e, -0x86,0xc3,0x61,0x90,0x24,0x12,0x0e,0x04,0x8a,0x81,0xc7,0x70,0xc0,0x30,0x18,0x0c, -0x00,0x00,0x00,0x04,0x81,0x31,0x6f,0x30,0x00,0x18,0x06,0x00,0x01,0x00,0x00,0x00, -0x00,0x60,0x63,0x06,0x0c,0x00,0x60,0x60,0x19,0x8c,0x60,0x63,0x01,0x80,0x00,0x00, -0xc0,0x00,0x60,0x00,0x4d,0xe1,0x99,0x8c,0x06,0x33,0x01,0x80,0xc6,0x63,0x0c,0x01, -0x8c,0xc6,0x04,0x99,0x1d,0x86,0x60,0x61,0x99,0x80,0x61,0x83,0x18,0xd0,0xdc,0x63, -0x0c,0x0c,0x06,0x00,0x60,0x30,0x84,0x00,0x00,0x63,0x18,0xcc,0x06,0x33,0x00,0x60, -0x6e,0x63,0x06,0x01,0x8c,0xc0,0xc6,0xd9,0x8c,0xc6,0x63,0x31,0x8c,0x00,0x61,0x83, -0x18,0xd0,0xcc,0x26,0x0e,0x0c,0x03,0x00,0xc0,0x60,0x01,0x54,0x98,0xc0,0x7e,0xdf, -0x6f,0xc7,0xe7,0xf4,0x7c,0xf9,0xfe,0xfc,0x7f,0xbf,0x1f,0x5f,0xdb,0xfb,0xfc,0x71, -0x79,0x3c,0x9e,0x6f,0xdb,0xed,0xf1,0xfb,0x75,0x7e,0x38,0x8f,0x3f,0xcf,0xe7,0xf3, -0xff,0x0c,0x0d,0x03,0x03,0xe1,0xf8,0x30,0x3c,0x00,0x27,0x40,0x03,0x30,0x00,0x00, -0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x14,0x00,0x00,0x00,0x00,0x19,0x82, -0xf8,0x98,0xbe,0x70,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x30,0xc0,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x63,0x23,0xb0,0xd8,0x6c,0x36,0x1b,0x0c,0x4c,0xe3, -0x31,0x98,0xcc,0x66,0x30,0xc1,0xf0,0xc6,0xc6,0x63,0x31,0x98,0xcc,0x66,0x33,0x60, -0xc0,0x60,0x30,0x18,0x0c,0x00,0xc0,0x60,0x30,0x18,0x63,0x31,0x98,0xcc,0x66,0x33, -0x19,0x8c,0x10,0x73,0x31,0x98,0xcc,0x66,0x30,0xe1,0x8c,0x38,0x1c,0x7f,0x80,0xa0, -0x50,0x10,0x24,0x0d,0xff,0x01,0x01,0x02,0x00,0x40,0x80,0xf0,0x24,0x04,0x02,0x01, -0x81,0x20,0x10,0x30,0x28,0x1a,0x09,0x06,0x8a,0x81,0x20,0x90,0x20,0x08,0x04,0x02, -0x00,0x0c,0x00,0x04,0x85,0x32,0x6f,0xb8,0x00,0x18,0x06,0x00,0x01,0x01,0xc0,0x00, -0x70,0x60,0x36,0x06,0x1f,0xcc,0xe0,0x63,0x30,0xd8,0x60,0x63,0x33,0x06,0x03,0x00, -0x60,0x00,0xc0,0x30,0x60,0x61,0x99,0x86,0x66,0x63,0x01,0x80,0x66,0x63,0x0c,0x03, -0x0c,0x66,0x04,0x19,0x1c,0xcc,0x60,0x33,0x18,0xcc,0x61,0x81,0xb0,0x60,0xcc,0x63, -0x0c,0x18,0x06,0x00,0x60,0x30,0x00,0x00,0x00,0x67,0x19,0x86,0x23,0x71,0x88,0x60, -0x36,0x63,0x06,0x01,0x8c,0x60,0xc6,0xd9,0x8c,0x6c,0x66,0x1b,0x8c,0x08,0x61,0x83, -0xb8,0x70,0xcc,0x63,0x0c,0x18,0x03,0x00,0xc0,0x60,0x00,0xaa,0x98,0xc0,0x7f,0x5f, -0xaf,0xef,0xdb,0xf2,0x00,0xfe,0xfe,0xfd,0xff,0xbf,0x7f,0x6f,0xdb,0xfb,0xfd,0xfe, -0x7e,0xdf,0xef,0xcf,0xd7,0xe5,0xf6,0xf9,0x75,0x7e,0xdf,0x6f,0xdf,0xf7,0xfb,0xfd, -0x00,0x0c,0x07,0xc6,0x04,0x10,0x60,0x30,0x06,0x00,0x10,0x80,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x3f,0x80,0x00,0x00,0x03,0xb8,0x14,0x00,0x00,0x00,0x00,0x00,0x04, -0x11,0x21,0x04,0xc0,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x30,0x66,0x30,0x18,0x0c, -0x06,0x01,0x80,0xc0,0x60,0x30,0x66,0x23,0x99,0x8c,0xc6,0x63,0x31,0x98,0x00,0x66, -0x1b,0x0d,0x86,0xc3,0x60,0xc1,0x80,0xc6,0xce,0x67,0x33,0x99,0xcc,0xe6,0x73,0x74, -0x62,0x31,0x18,0x8c,0x46,0x20,0xc0,0x60,0x30,0x18,0x36,0x31,0x8d,0x86,0xc3,0x61, -0xb0,0xd8,0x10,0x36,0x3b,0x9d,0xce,0xe7,0x70,0xc1,0x98,0x30,0x00,0x7f,0x80,0xc0, -0x60,0x10,0x24,0x0c,0x38,0x0e,0x01,0x02,0x00,0x40,0x80,0xa0,0x18,0x0e,0x03,0x00, -0x80,0x40,0x60,0x50,0x30,0x16,0x0e,0x05,0x88,0x81,0xc0,0x81,0xc0,0x70,0x38,0x1c, -0x00,0x0c,0x00,0x04,0x83,0xe0,0x39,0xcc,0x00,0x0c,0x0c,0x00,0x00,0x01,0xc0,0x00, -0x70,0xc0,0x1c,0x06,0x1f,0xc7,0xc0,0x61,0xe0,0x70,0x60,0x3e,0x1e,0x06,0x03,0x00, -0x00,0x00,0x00,0x30,0x1e,0x61,0x9f,0x03,0xc7,0xc3,0xf1,0x80,0x3e,0x63,0x3f,0x1e, -0x0c,0x67,0xe4,0x19,0x0c,0x78,0x60,0x1e,0x18,0xc7,0xc1,0x80,0xe0,0x60,0xcc,0x63, -0x0c,0x1f,0xc6,0x00,0x30,0x30,0x00,0x00,0x00,0x3b,0x9f,0x03,0xc1,0xb0,0xf0,0x60, -0x06,0x63,0x06,0x01,0x8c,0x70,0xc6,0xd9,0x8c,0x38,0x7c,0x0d,0x8c,0x07,0xc0,0xf1, -0xd8,0x60,0xcc,0x63,0x0c,0x1f,0xc3,0x00,0xc0,0x60,0x01,0x54,0x80,0xc0,0x7f,0x3f, -0x9f,0xef,0xdb,0xf3,0xc7,0xf1,0xfe,0xfd,0xff,0xbf,0x7f,0xff,0xe7,0xf1,0xfc,0xff, -0x7f,0xbf,0x9f,0xaf,0xcf,0xe9,0xf1,0xfa,0x77,0x7e,0x3f,0x7e,0x3f,0x8f,0xc7,0xe3, -0xff,0x0c,0x01,0x0f,0xe8,0x08,0x60,0x30,0xc6,0x00,0x0f,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xd8,0x14,0x00,0x00,0x00,0x00,0x00,0x04, -0x11,0x3d,0x04,0xc0,0xc3,0x61,0xb0,0xd8,0x6c,0x36,0x1b,0x3c,0x3c,0x3f,0x1f,0x8f, -0xc7,0xe7,0xe3,0xf1,0xf8,0xfc,0x7c,0x21,0x8f,0x07,0x83,0xc1,0xe0,0xf0,0x00,0xbc, -0x0e,0x07,0x03,0x81,0xc0,0xc1,0x80,0xcc,0x77,0x3b,0x9d,0xce,0xe7,0x73,0xb9,0x98, -0x3c,0x1e,0x0f,0x07,0x83,0xc0,0xc0,0x60,0x30,0x18,0x1c,0x31,0x87,0x03,0x81,0xc0, -0xe0,0x70,0x00,0x5c,0x1d,0x8e,0xc7,0x63,0xb0,0xc1,0xf0,0x30,0x00,0x7f,0x81,0x40, -0xa0,0x10,0x28,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x02,0x00, -0x80,0x80,0x10,0xf8,0x28,0x12,0x09,0x04,0x80,0x01,0x20,0x80,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x06,0x18,0x00,0x00,0x00,0x40,0x00, -0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0xc0,0x31,0xf0,0x01,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0xcc,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x80,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x18,0x00,0x01,0xe0,0xc3,0xc0,0x00,0x00,0xff,0xc0,0x7e,0xbf, -0x5f,0xef,0xd7,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff, -0x7f,0x7f,0xef,0x07,0xd7,0xed,0xf6,0xfb,0x7f,0xfe,0xdf,0x7f,0xff,0xff,0xff,0xff, -0x00,0x0c,0x01,0x00,0x00,0x00,0x00,0x30,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x80,0x60,0x00,0x7f,0x81,0x20, -0x90,0x10,0x1c,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80, -0x81,0xe0,0x60,0x10,0x24,0x12,0x0e,0x04,0x80,0x01,0xc0,0x70,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x78,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x80,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0xdf, -0x6f,0xef,0xe3,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x7f, -0x7e,0x1f,0x9f,0xef,0xdb,0xed,0xf1,0xfb,0x7f,0xfe,0x3f,0x8f,0xff,0xff,0xff,0xff, -0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x81,0x80,0x60,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x32,0x35,0x36,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x31,0x35,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x33,0x20, -0x00,0x00,0x01,0x0c,0x00,0x09,0x09,0x00,0x01,0x0f,0x00,0x09,0x12,0x00,0x01,0x0f, -0x00,0x09,0x1b,0x00,0x01,0x0f,0x00,0x09,0x24,0x00,0x01,0x0f,0x00,0x09,0x2d,0x00, -0x01,0x0f,0x00,0x09,0x36,0x00,0x01,0x0f,0x00,0x09,0x3f,0x00,0x03,0x0d,0x00,0x09, -0x48,0x00,0x03,0x0d,0x00,0x09,0x51,0x00,0x03,0x0d,0x00,0x09,0x5a,0x00,0x03,0x0d, -0x00,0x09,0x63,0x00,0x03,0x0d,0x00,0x09,0x6c,0x00,0x03,0x0d,0x00,0x09,0x75,0x00, -0x03,0x0e,0x00,0x09,0x7e,0x00,0x03,0x0d,0x00,0x09,0x87,0x00,0x03,0x0d,0x00,0x09, -0x90,0x00,0x01,0x0f,0x00,0x09,0x99,0x00,0x01,0x0f,0x00,0x09,0xa2,0x00,0x01,0x0f, -0x00,0x09,0xab,0x00,0x01,0x0f,0x00,0x09,0xb4,0x00,0x01,0x0f,0x00,0x09,0xbd,0x00, -0x01,0x0f,0x00,0x09,0xc6,0x00,0x01,0x0f,0x00,0x09,0xcf,0x00,0x01,0x0f,0x00,0x09, -0xd8,0x00,0x01,0x0f,0x00,0x09,0xe1,0x00,0x03,0x0d,0x00,0x09,0xea,0x00,0x01,0x0f, -0x00,0x09,0xf3,0x00,0x01,0x0f,0x00,0x09,0xfc,0x00,0x03,0x0d,0x00,0x09,0x05,0x01, -0x03,0x0d,0x00,0x09,0x0e,0x01,0x03,0x0d,0x00,0x09,0x17,0x01,0x03,0x0d,0x00,0x09, -0x20,0x01,0x00,0x00,0x00,0x09,0x29,0x01,0x03,0x0d,0x00,0x09,0x32,0x01,0x02,0x05, -0x00,0x09,0x3b,0x01,0x03,0x0d,0x00,0x09,0x44,0x01,0x02,0x0e,0x00,0x09,0x4d,0x01, -0x03,0x0d,0x00,0x09,0x56,0x01,0x03,0x0d,0x00,0x09,0x5f,0x01,0x02,0x06,0x00,0x09, -0x68,0x01,0x02,0x0e,0x00,0x09,0x71,0x01,0x02,0x0e,0x00,0x09,0x7a,0x01,0x03,0x08, -0x00,0x09,0x83,0x01,0x05,0x0c,0x00,0x09,0x8c,0x01,0x0b,0x0f,0x00,0x09,0x95,0x01, -0x08,0x09,0x00,0x09,0x9e,0x01,0x0b,0x0d,0x00,0x09,0xa7,0x01,0x02,0x0e,0x00,0x09, -0xb0,0x01,0x03,0x0d,0x00,0x09,0xb9,0x01,0x03,0x0d,0x00,0x09,0xc2,0x01,0x03,0x0d, -0x00,0x09,0xcb,0x01,0x03,0x0d,0x00,0x09,0xd4,0x01,0x03,0x0d,0x00,0x09,0xdd,0x01, -0x03,0x0d,0x00,0x09,0xe6,0x01,0x03,0x0d,0x00,0x09,0xef,0x01,0x03,0x0d,0x00,0x09, -0xf8,0x01,0x03,0x0d,0x00,0x09,0x01,0x02,0x03,0x0d,0x00,0x09,0x0a,0x02,0x06,0x0d, -0x00,0x09,0x13,0x02,0x06,0x0f,0x00,0x09,0x1c,0x02,0x05,0x0c,0x00,0x09,0x25,0x02, -0x07,0x0a,0x00,0x09,0x2e,0x02,0x05,0x0c,0x00,0x09,0x37,0x02,0x03,0x0d,0x00,0x09, -0x40,0x02,0x03,0x0d,0x00,0x09,0x49,0x02,0x03,0x0d,0x00,0x09,0x52,0x02,0x03,0x0d, -0x00,0x09,0x5b,0x02,0x03,0x0d,0x00,0x09,0x64,0x02,0x03,0x0d,0x00,0x09,0x6d,0x02, -0x03,0x0d,0x00,0x09,0x76,0x02,0x03,0x0d,0x00,0x09,0x7f,0x02,0x03,0x0d,0x00,0x09, -0x88,0x02,0x03,0x0d,0x00,0x09,0x91,0x02,0x03,0x0d,0x00,0x09,0x9a,0x02,0x03,0x0d, -0x00,0x09,0xa3,0x02,0x03,0x0d,0x00,0x09,0xac,0x02,0x03,0x0d,0x00,0x09,0xb5,0x02, -0x03,0x0d,0x00,0x09,0xbe,0x02,0x03,0x0d,0x00,0x09,0xc7,0x02,0x03,0x0d,0x00,0x09, -0xd0,0x02,0x03,0x0d,0x00,0x09,0xd9,0x02,0x03,0x0f,0x00,0x09,0xe2,0x02,0x03,0x0d, -0x00,0x09,0xeb,0x02,0x03,0x0d,0x00,0x09,0xf4,0x02,0x03,0x0d,0x00,0x09,0xfd,0x02, -0x03,0x0d,0x00,0x09,0x06,0x03,0x03,0x0d,0x00,0x09,0x0f,0x03,0x03,0x0d,0x00,0x09, -0x18,0x03,0x03,0x0d,0x00,0x09,0x21,0x03,0x03,0x0d,0x00,0x09,0x2a,0x03,0x03,0x0d, -0x00,0x09,0x33,0x03,0x02,0x0e,0x00,0x09,0x3c,0x03,0x02,0x0e,0x00,0x09,0x45,0x03, -0x02,0x0e,0x00,0x09,0x4e,0x03,0x04,0x0b,0x00,0x09,0x57,0x03,0x0d,0x0e,0x00,0x09, -0x60,0x03,0x02,0x06,0x00,0x09,0x69,0x03,0x05,0x0d,0x00,0x09,0x72,0x03,0x02,0x0d, -0x00,0x09,0x7b,0x03,0x05,0x0d,0x00,0x09,0x84,0x03,0x02,0x0d,0x00,0x09,0x8d,0x03, -0x05,0x0d,0x00,0x09,0x96,0x03,0x02,0x0d,0x00,0x09,0x9f,0x03,0x05,0x0f,0x00,0x09, -0xa8,0x03,0x02,0x0d,0x00,0x09,0xb1,0x03,0x02,0x0d,0x00,0x09,0xba,0x03,0x02,0x0f, -0x00,0x09,0xc3,0x03,0x02,0x0d,0x00,0x09,0xcc,0x03,0x02,0x0d,0x00,0x09,0xd5,0x03, -0x05,0x0d,0x00,0x09,0xde,0x03,0x05,0x0d,0x00,0x09,0xe7,0x03,0x05,0x0d,0x00,0x09, -0xf0,0x03,0x05,0x0f,0x00,0x09,0xf9,0x03,0x05,0x0f,0x00,0x09,0x02,0x04,0x05,0x0d, -0x00,0x09,0x0b,0x04,0x05,0x0d,0x00,0x09,0x14,0x04,0x03,0x0d,0x00,0x09,0x1d,0x04, -0x05,0x0d,0x00,0x09,0x26,0x04,0x05,0x0d,0x00,0x09,0x2f,0x04,0x05,0x0d,0x00,0x09, -0x38,0x04,0x05,0x0d,0x00,0x09,0x41,0x04,0x05,0x0f,0x00,0x09,0x4a,0x04,0x05,0x0d, -0x00,0x09,0x53,0x04,0x02,0x0e,0x00,0x09,0x5c,0x04,0x02,0x0e,0x00,0x09,0x65,0x04, -0x02,0x0e,0x00,0x09,0x6e,0x04,0x07,0x0a,0x00,0x09,0x77,0x04,0x01,0x0d,0x00,0x09, -0x80,0x04,0x00,0x0e,0x00,0x09,0x89,0x04,0x00,0x0f,0x00,0x09,0x92,0x04,0x00,0x0f, -0x00,0x09,0x9b,0x04,0x00,0x0f,0x00,0x09,0xa4,0x04,0x00,0x0f,0x00,0x09,0xad,0x04, -0x00,0x0f,0x00,0x09,0xb6,0x04,0x00,0x0f,0x00,0x09,0xbf,0x04,0x00,0x0f,0x00,0x09, -0xc8,0x04,0x00,0x0f,0x00,0x09,0xd1,0x04,0x00,0x0f,0x00,0x09,0xda,0x04,0x00,0x0f, -0x00,0x09,0xe3,0x04,0x00,0x0f,0x00,0x09,0xec,0x04,0x00,0x0f,0x00,0x09,0xf5,0x04, -0x00,0x0f,0x00,0x09,0xfe,0x04,0x00,0x0f,0x00,0x09,0x07,0x05,0x00,0x0f,0x00,0x09, -0x10,0x05,0x00,0x0f,0x00,0x09,0x19,0x05,0x00,0x0f,0x00,0x09,0x22,0x05,0x00,0x0f, -0x00,0x09,0x2b,0x05,0x00,0x0f,0x00,0x09,0x34,0x05,0x00,0x0f,0x00,0x09,0x3d,0x05, -0x00,0x0f,0x00,0x09,0x46,0x05,0x00,0x0f,0x00,0x09,0x4f,0x05,0x00,0x0f,0x00,0x09, -0x58,0x05,0x00,0x0f,0x00,0x09,0x61,0x05,0x00,0x0f,0x00,0x09,0x6a,0x05,0x00,0x0f, -0x00,0x09,0x73,0x05,0x00,0x0f,0x00,0x09,0x7c,0x05,0x00,0x0f,0x00,0x09,0x85,0x05, -0x00,0x0f,0x00,0x09,0x8e,0x05,0x00,0x0f,0x00,0x09,0x97,0x05,0x00,0x0f,0x00,0x09, -0xa0,0x05,0x00,0x0d,0x00,0x09,0xa9,0x05,0x05,0x0f,0x00,0x09,0xb2,0x05,0x02,0x0e, -0x00,0x09,0xbb,0x05,0x03,0x0d,0x00,0x09,0xc4,0x05,0x03,0x0d,0x00,0x09,0xcd,0x05, -0x03,0x0d,0x00,0x09,0xd6,0x05,0x02,0x0e,0x00,0x09,0xdf,0x05,0x03,0x0e,0x00,0x09, -0xe8,0x05,0x02,0x04,0x00,0x09,0xf1,0x05,0x03,0x0d,0x00,0x09,0xfa,0x05,0x03,0x0a, -0x00,0x09,0x03,0x06,0x06,0x0b,0x00,0x09,0x0c,0x06,0x07,0x0a,0x00,0x09,0x15,0x06, -0x08,0x09,0x00,0x09,0x1e,0x06,0x03,0x0b,0x00,0x09,0x27,0x06,0x02,0x03,0x00,0x09, -0x30,0x06,0x03,0x07,0x00,0x09,0x39,0x06,0x05,0x0c,0x00,0x09,0x42,0x06,0x03,0x0a, -0x00,0x09,0x4b,0x06,0x03,0x0a,0x00,0x09,0x54,0x06,0x02,0x04,0x00,0x09,0x5d,0x06, -0x05,0x0f,0x00,0x09,0x66,0x06,0x03,0x0e,0x00,0x09,0x6f,0x06,0x08,0x0a,0x00,0x09, -0x78,0x06,0x0d,0x0f,0x00,0x09,0x81,0x06,0x03,0x0a,0x00,0x09,0x8a,0x06,0x03,0x0a, -0x00,0x09,0x93,0x06,0x06,0x0b,0x00,0x09,0x9c,0x06,0x03,0x0d,0x00,0x09,0xa5,0x06, -0x03,0x0d,0x00,0x09,0xae,0x06,0x03,0x0d,0x00,0x09,0xb7,0x06,0x05,0x0f,0x00,0x09, -0xc0,0x06,0x00,0x0d,0x00,0x09,0xc9,0x06,0x00,0x0d,0x00,0x09,0xd2,0x06,0x00,0x0d, -0x00,0x09,0xdb,0x06,0x00,0x0d,0x00,0x09,0xe4,0x06,0x00,0x0d,0x00,0x09,0xed,0x06, -0x01,0x0d,0x00,0x09,0xf6,0x06,0x03,0x0d,0x00,0x09,0xff,0x06,0x03,0x0f,0x00,0x09, -0x08,0x07,0x00,0x0d,0x00,0x09,0x11,0x07,0x00,0x0d,0x00,0x09,0x1a,0x07,0x00,0x0d, -0x00,0x09,0x23,0x07,0x00,0x0d,0x00,0x09,0x2c,0x07,0x00,0x0d,0x00,0x09,0x35,0x07, -0x00,0x0d,0x00,0x09,0x3e,0x07,0x00,0x0d,0x00,0x09,0x47,0x07,0x00,0x0d,0x00,0x09, -0x50,0x07,0x03,0x0d,0x00,0x09,0x59,0x07,0x00,0x0d,0x00,0x09,0x62,0x07,0x00,0x0d, -0x00,0x09,0x6b,0x07,0x00,0x0d,0x00,0x09,0x74,0x07,0x00,0x0d,0x00,0x09,0x7d,0x07, -0x00,0x0d,0x00,0x09,0x86,0x07,0x00,0x0d,0x00,0x09,0x8f,0x07,0x06,0x0b,0x00,0x09, -0x98,0x07,0x03,0x0d,0x00,0x09,0xa1,0x07,0x00,0x0d,0x00,0x09,0xaa,0x07,0x00,0x0d, -0x00,0x09,0xb3,0x07,0x00,0x0d,0x00,0x09,0xbc,0x07,0x00,0x0d,0x00,0x09,0xc5,0x07, -0x00,0x0d,0x00,0x09,0xce,0x07,0x03,0x0d,0x00,0x09,0xd7,0x07,0x02,0x0d,0x00,0x09, -0xe0,0x07,0x02,0x0d,0x00,0x09,0xe9,0x07,0x02,0x0d,0x00,0x09,0xf2,0x07,0x02,0x0d, -0x00,0x09,0xfb,0x07,0x02,0x0d,0x00,0x09,0x04,0x08,0x02,0x0d,0x00,0x09,0x0d,0x08, -0x02,0x0d,0x00,0x09,0x16,0x08,0x05,0x0d,0x00,0x09,0x1f,0x08,0x05,0x0f,0x00,0x09, -0x28,0x08,0x02,0x0d,0x00,0x09,0x31,0x08,0x02,0x0d,0x00,0x09,0x3a,0x08,0x02,0x0d, -0x00,0x09,0x43,0x08,0x02,0x0d,0x00,0x09,0x4c,0x08,0x02,0x0d,0x00,0x09,0x55,0x08, -0x02,0x0d,0x00,0x09,0x5e,0x08,0x02,0x0d,0x00,0x09,0x67,0x08,0x02,0x0d,0x00,0x09, -0x70,0x08,0x02,0x0d,0x00,0x09,0x79,0x08,0x02,0x0d,0x00,0x09,0x82,0x08,0x02,0x0d, -0x00,0x09,0x8b,0x08,0x02,0x0d,0x00,0x09,0x94,0x08,0x02,0x0d,0x00,0x09,0x9d,0x08, -0x02,0x0d,0x00,0x09,0xa6,0x08,0x02,0x0d,0x00,0x09,0xaf,0x08,0x05,0x0c,0x00,0x09, -0xb8,0x08,0x05,0x0d,0x00,0x09,0xc1,0x08,0x02,0x0d,0x00,0x09,0xca,0x08,0x02,0x0d, -0x00,0x09,0xd3,0x08,0x02,0x0d,0x00,0x09,0xdc,0x08,0x02,0x0d,0x00,0x09,0xe5,0x08, -0x02,0x0f,0x00,0x09,0xee,0x08,0x03,0x0f,0x00,0x09,0xf7,0x08,0x02,0x0f,0x00,0x09, -0x00,0x09,0x00,0x00,0x00,0x00, -}; - -int sizeofdefont = sizeof defontdata; - -void -_unpackinfo(Fontchar *fc, uchar *p, int n) -{ - int j; - - for(j=0; j<=n; j++){ - fc->x = p[0]|(p[1]<<8); - fc->top = p[2]; - fc->bottom = p[3]; - fc->left = p[4]; - fc->width = p[5]; - fc++; - p += 6; - } -} diff --git a/src/libdraw/defont.h b/src/libdraw/defont.h new file mode 100644 index 00000000..3d108cfc --- /dev/null +++ b/src/libdraw/defont.h @@ -0,0 +1,303 @@ + +/* + * lucm/latin1.9 + */ + +char _defontfile[] = "15 13\n0 255\t*default*\n"; + +static uchar +defontdata[] = +{ +// xd -b ../../font/lucm/latin1.9 | awk '{$1=""; for(i=2; i<=NF;i++) $i="0x"$i","; print}' + 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6b, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x33, 0x30, 0x34, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x31, 0x35, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x39, 0x37, 0x36, 0x20, 0x80, + 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x10, 0x00, 0x80, 0xff, 0x7c, 0x00, 0x80, + 0xff, 0x7c, 0x45, 0x87, 0x00, 0x00, 0x30, 0x06, 0x06, 0x03, 0x42, 0x40, 0x00, 0x08, 0x90, 0x18, + 0x03, 0x03, 0x02, 0x43, 0x00, 0x60, 0x60, 0x48, 0x00, 0x0d, 0x0c, 0x01, 0x81, 0x80, 0xd0, 0x90, + 0x00, 0x12, 0x84, 0x01, 0x81, 0x81, 0x40, 0x60, 0x7c, 0x43, 0x04, 0x00, 0x87, 0x18, 0x7f, 0x9c, + 0x1c, 0x0e, 0x07, 0x01, 0x80, 0x1c, 0x11, 0x8c, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x04, 0x81, 0xc1, + 0xc0, 0x70, 0x00, 0x1c, 0x1c, 0x7c, 0x40, 0x7c, 0x00, 0x7c, 0x00, 0x1c, 0x00, 0x88, 0xaa, 0x80, + 0xc0, 0x63, 0xe3, 0xf1, 0xf8, 0xfe, 0x7f, 0x0d, 0x09, 0x80, 0xfc, 0x00, 0x07, 0x8c, 0x1f, 0x8f, + 0xc7, 0xe3, 0xf1, 0xfb, 0x7e, 0x3e, 0x3f, 0x8f, 0xff, 0xe3, 0xe3, 0x7d, 0x1f, 0x10, 0x00, 0x98, + 0x0c, 0x18, 0x09, 0x05, 0x82, 0x40, 0xc0, 0x00, 0x00, 0x06, 0x0c, 0x04, 0x82, 0x40, 0xc1, 0x80, + 0x90, 0x48, 0x00, 0x16, 0x03, 0x06, 0x02, 0x41, 0x60, 0x01, 0x1f, 0x80, 0x06, 0x00, 0x07, 0x80, + 0x41, 0x20, 0xf1, 0x64, 0x00, 0x86, 0x3e, 0x7f, 0xa0, 0x10, 0x08, 0x04, 0x02, 0x05, 0x69, 0x10, + 0x00, 0x8c, 0x90, 0x48, 0x24, 0x12, 0x09, 0x06, 0x82, 0x01, 0x00, 0x90, 0x00, 0x20, 0x10, 0x10, + 0x13, 0x82, 0x04, 0x80, 0x00, 0x00, 0x21, 0x82, 0x38, 0x06, 0x18, 0x0c, 0x0e, 0x80, 0x06, 0x7c, + 0x57, 0x2c, 0x00, 0x83, 0x07, 0xc6, 0x01, 0xf0, 0x00, 0xb3, 0x80, 0x00, 0x00, 0x3f, 0x88, 0x30, + 0x00, 0x3c, 0x00, 0x60, 0x06, 0x01, 0x8c, 0x07, 0x00, 0xbb, 0x28, 0x00, 0x8d, 0x01, 0xe0, 0xc3, + 0xc0, 0x01, 0x54, 0x9c, 0xc0, 0x5f, 0xef, 0xf7, 0xfb, 0xfd, 0xbf, 0x0d, 0x1f, 0x80, 0xfb, 0x01, + 0x1f, 0x8c, 0x6f, 0xb7, 0xdb, 0xed, 0xf6, 0xf9, 0x7d, 0xfe, 0xff, 0x6f, 0xff, 0xdf, 0xef, 0x11, + 0x1f, 0x80, 0x01, 0x0a, 0x22, 0x81, 0x00, 0x14, 0x10, 0x3a, 0x80, 0x38, 0x08, 0x05, 0x3e, 0x11, + 0x81, 0x01, 0x20, 0x64, 0x94, 0x80, 0x78, 0x02, 0x63, 0x82, 0x06, 0x82, 0x80, 0x00, 0x87, 0x06, + 0x63, 0x8c, 0x41, 0x80, 0x30, 0x30, 0x24, 0x76, 0x0d, 0x0c, 0x00, 0xc0, 0xc0, 0xd0, 0x50, 0x12, + 0x63, 0x82, 0x30, 0x00, 0x28, 0x82, 0x0f, 0x7f, 0xbc, 0x02, 0x3f, 0x8b, 0x03, 0xc0, 0x10, 0x70, + 0x24, 0x10, 0x09, 0x07, 0x03, 0x80, 0xe0, 0x70, 0x09, 0x1f, 0x98, 0x05, 0x81, 0x81, 0xc0, 0x80, + 0x70, 0x18, 0x1c, 0x07, 0x01, 0xc1, 0xc0, 0x90, 0x00, 0x0c, 0x04, 0x84, 0x83, 0xe1, 0xc0, 0xe0, + 0x38, 0x0c, 0x0c, 0x02, 0x0d, 0x1f, 0x8a, 0x1c, 0x06, 0x0f, 0x87, 0xc0, 0x63, 0xf8, 0x78, 0xfe, + 0x3e, 0x0e, 0x0c, 0x6b, 0xa0, 0x7c, 0x1c, 0x0c, 0x1f, 0x03, 0xc7, 0xc3, 0xf1, 0xf8, 0x3c, 0x63, + 0x3f, 0x0f, 0x8c, 0x66, 0x06, 0x19, 0x84, 0x78, 0x7e, 0x1e, 0x1f, 0x07, 0xcf, 0xf3, 0x1b, 0x0d, + 0x86, 0x63, 0x61, 0x9f, 0xc6, 0x06, 0x00, 0xcd, 0x81, 0x00, 0x10, 0x0d, 0x1f, 0x80, 0x60, 0x09, + 0x1f, 0x80, 0x00, 0x15, 0x1f, 0x16, 0xbb, 0x88, 0x03, 0x00, 0xc0, 0x60, 0x00, 0xaa, 0xb6, 0xc0, + 0x43, 0x02, 0x3f, 0x88, 0xfc, 0x3f, 0xef, 0x8f, 0xdb, 0xef, 0xf6, 0xf8, 0xfb, 0x02, 0x3d, 0x09, + 0x1f, 0x8c, 0xfa, 0x7e, 0x7e, 0x3f, 0x7f, 0x8f, 0xe7, 0xe3, 0xf8, 0xfe, 0x3e, 0x3f, 0x6f, 0x00, + 0x33, 0x88, 0x01, 0xc8, 0x0b, 0x0c, 0x30, 0x7c, 0x14, 0x0f, 0x0f, 0x08, 0xe8, 0x9c, 0x00, 0x1c, + 0x00, 0x0f, 0x07, 0x81, 0x80, 0x00, 0x7c, 0x00, 0x00, 0x1c, 0x0f, 0x80, 0x04, 0x42, 0x23, 0x90, + 0x00, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x80, 0xc0, 0x3c, 0x3c, 0x3f, 0x02, 0x7f, 0x80, 0xe7, 0x04, + 0x52, 0x91, 0x7c, 0x30, 0x8f, 0x07, 0x83, 0xc1, 0xe0, 0xf0, 0x00, 0x3d, 0x31, 0x98, 0xcc, 0x66, + 0x36, 0x19, 0x80, 0xcc, 0x02, 0x63, 0x82, 0x0b, 0x02, 0x81, 0x01, 0x43, 0x0a, 0x63, 0x8a, 0x60, + 0xc0, 0x48, 0x24, 0x18, 0x16, 0x03, 0x03, 0x01, 0x21, 0x60, 0x01, 0x1f, 0x06, 0x63, 0x02, 0x76, + 0x80, 0x28, 0x82, 0x87, 0x7f, 0x84, 0x0a, 0x3f, 0x81, 0x38, 0x48, 0x01, 0x1f, 0x83, 0x04, 0x04, + 0x81, 0x00, 0x02, 0x89, 0x01, 0x1f, 0x8b, 0x04, 0x80, 0x41, 0x00, 0x80, 0x40, 0x04, 0x10, 0x04, + 0x02, 0x01, 0x20, 0x09, 0x1f, 0x87, 0x86, 0x53, 0x65, 0xb0, 0x08, 0x18, 0x06, 0x0a, 0x08, 0xcc, + 0x8b, 0x0c, 0x36, 0x0e, 0x19, 0xcc, 0xe0, 0xe3, 0xf8, 0xcc, 0xfe, 0x63, 0x1b, 0x0c, 0xdc, 0x98, + 0xc6, 0x62, 0x0c, 0x19, 0x86, 0x66, 0x63, 0x01, 0x80, 0x66, 0x63, 0x0c, 0x01, 0x8c, 0xc6, 0x06, + 0x19, 0xc4, 0xcc, 0x63, 0x33, 0x19, 0x8c, 0x61, 0x83, 0x09, 0x1f, 0x85, 0x80, 0xc6, 0x03, 0x00, + 0x30, 0x30, 0x00, 0xc5, 0x15, 0x1f, 0x06, 0x4b, 0x45, 0x1f, 0x84, 0x01, 0x54, 0x86, 0xc0, 0x7b, + 0x0a, 0x3f, 0x81, 0xc7, 0xb7, 0x01, 0x1f, 0x84, 0xfb, 0xfb, 0x7e, 0xff, 0x7f, 0x09, 0x1f, 0x8b, + 0xfb, 0x7f, 0xbe, 0xff, 0x7f, 0xbf, 0xfb, 0xef, 0xfb, 0xfd, 0xfe, 0xdf, 0x01, 0x1f, 0x88, 0x07, + 0x83, 0x24, 0x13, 0x0c, 0x30, 0xc6, 0x00, 0x10, 0x01, 0x14, 0x84, 0x00, 0x00, 0x84, 0x00, 0x22, + 0x00, 0x45, 0x00, 0x4f, 0x87, 0xf4, 0x00, 0x00, 0x2c, 0x18, 0xc0, 0x0c, 0x46, 0x00, 0xb2, 0x11, + 0x1f, 0x82, 0x70, 0x66, 0x30, 0x00, 0x09, 0x00, 0x08, 0x8b, 0x60, 0x30, 0x66, 0x38, 0x99, 0x8c, + 0xc6, 0x63, 0x31, 0x98, 0x00, 0x66, 0x15, 0x1f, 0x0c, 0x77, 0x26, 0xc7, 0x80, 0x6c, 0x32, 0x7f, + 0x81, 0x80, 0x00, 0x82, 0xff, 0x7f, 0xb8, 0x02, 0x3f, 0x84, 0x02, 0x40, 0x7c, 0x70, 0x3c, 0x02, + 0x3f, 0x80, 0x04, 0x00, 0xa3, 0x89, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x04, 0x83, 0x81, 0xc0, 0x70, + 0x00, 0x08, 0x81, 0x07, 0x02, 0x0a, 0x3f, 0x89, 0x00, 0x04, 0x86, 0x43, 0x69, 0xb0, 0x30, 0x18, + 0x06, 0x07, 0x0a, 0xd9, 0x8b, 0x0c, 0x63, 0x16, 0x00, 0xc0, 0x61, 0x62, 0x01, 0x80, 0x06, 0x63, + 0x31, 0x00, 0xa0, 0x89, 0x60, 0x00, 0xc0, 0x06, 0x43, 0x16, 0x19, 0x8c, 0x06, 0x33, 0x00, 0x88, + 0x05, 0x1f, 0x83, 0x86, 0x07, 0x39, 0xc5, 0x01, 0x16, 0x82, 0x99, 0x8c, 0x01, 0x01, 0x1f, 0x84, + 0xb6, 0x63, 0x31, 0x01, 0x86, 0x0d, 0x1f, 0xa5, 0x3e, 0x1b, 0x03, 0xc1, 0xf0, 0xf0, 0x60, 0x3e, + 0x6e, 0x3e, 0x0f, 0x8c, 0x60, 0xc5, 0xb1, 0xb8, 0x38, 0x6c, 0x0f, 0x8c, 0xc7, 0xc1, 0x83, 0x19, + 0x8d, 0x82, 0x63, 0x31, 0x9f, 0xc1, 0x80, 0xc0, 0xc0, 0x00, 0xaa, 0x86, 0xc0, 0x47, 0x01, 0xec, + 0x84, 0xfd, 0xbf, 0x83, 0x8f, 0xc3, 0x02, 0x3f, 0x83, 0xfc, 0xff, 0x3f, 0x9f, 0x01, 0xff, 0x86, + 0xe3, 0xf1, 0xfb, 0x7c, 0x7e, 0x3f, 0x8f, 0x00, 0x08, 0x81, 0xf8, 0xfd, 0x06, 0x3f, 0x8a, 0x0c, + 0x0d, 0x43, 0x03, 0xe1, 0x88, 0x30, 0xc0, 0x00, 0x27, 0x41, 0x00, 0x7e, 0x84, 0x01, 0x72, 0x00, + 0x22, 0x04, 0x00, 0x79, 0x81, 0x03, 0x18, 0x01, 0x1f, 0x90, 0x0c, 0x18, 0xc0, 0x04, 0x82, 0x43, + 0x20, 0x18, 0x2c, 0x16, 0x0b, 0x05, 0x82, 0xc1, 0x60, 0xb0, 0xc0, 0x19, 0x1f, 0x89, 0x63, 0x38, + 0xb0, 0xd8, 0x6c, 0x36, 0x1b, 0x0c, 0x00, 0xc7, 0x05, 0x1f, 0x9f, 0x33, 0x11, 0xf8, 0xc8, 0x7c, + 0x3e, 0x1f, 0x0f, 0x87, 0xc3, 0xe1, 0xd8, 0x3c, 0x1e, 0x0f, 0x07, 0x83, 0xc7, 0xc3, 0xe1, 0xf0, + 0xf8, 0x06, 0x37, 0x07, 0x03, 0x81, 0xc0, 0xe0, 0x70, 0x10, 0x1d, 0x08, 0x23, 0x82, 0x19, 0xb0, + 0xc6, 0x88, 0x8f, 0x7f, 0x87, 0x03, 0x81, 0x80, 0x90, 0x30, 0x6c, 0x02, 0x3f, 0x86, 0x06, 0x04, + 0x04, 0x80, 0x20, 0x10, 0x10, 0x03, 0x6e, 0x89, 0x81, 0xc0, 0x60, 0x88, 0x38, 0x0c, 0x40, 0x09, + 0x03, 0x84, 0x02, 0x65, 0x05, 0x1f, 0x89, 0x1f, 0xe7, 0x41, 0xd1, 0xa0, 0x00, 0x30, 0x03, 0x0a, + 0x81, 0x05, 0x1f, 0x8b, 0x18, 0x63, 0x06, 0x00, 0xc0, 0xc2, 0x62, 0x01, 0xb0, 0x0c, 0x72, 0x31, + 0x00, 0xfa, 0x80, 0xc0, 0x03, 0x30, 0x83, 0x8f, 0x16, 0x19, 0x0c, 0x15, 0x1f, 0x84, 0x8d, 0x06, + 0x07, 0x39, 0x65, 0x05, 0x1f, 0x88, 0x0e, 0x01, 0x83, 0x19, 0x89, 0xb6, 0x32, 0x33, 0x03, 0x00, + 0xa1, 0x81, 0x30, 0x78, 0x02, 0x22, 0x87, 0x1d, 0x86, 0x23, 0x31, 0x99, 0xfc, 0x66, 0x77, 0x03, + 0x5f, 0x8a, 0x40, 0xc6, 0xd9, 0xdc, 0x6c, 0x76, 0x19, 0x8d, 0xcc, 0x27, 0xf3, 0x09, 0x1f, 0x81, + 0x80, 0xc0, 0x00, 0x01, 0x8a, 0x01, 0x54, 0x8c, 0xc0, 0x78, 0xfc, 0x7e, 0x7f, 0x6f, 0xcf, 0x93, + 0x02, 0x3f, 0x86, 0xf9, 0xfb, 0xff, 0xff, 0xdf, 0xef, 0xef, 0x03, 0x1b, 0x8c, 0x7e, 0x3f, 0x9f, + 0x77, 0xc7, 0xf3, 0xbf, 0xf6, 0xfc, 0x7b, 0xfd, 0xbe, 0xbf, 0x01, 0x1f, 0x84, 0x19, 0x03, 0x03, + 0x61, 0x98, 0x00, 0x51, 0x8c, 0x28, 0x4f, 0x83, 0x30, 0x00, 0x01, 0x4a, 0x00, 0x1c, 0x04, 0x03, + 0x03, 0x80, 0x11, 0x1f, 0x84, 0xd9, 0x84, 0x82, 0x40, 0xa0, 0x45, 0x1f, 0x80, 0x2c, 0x0d, 0x1f, + 0x81, 0x64, 0xcb, 0x08, 0xfb, 0x82, 0x31, 0x8c, 0xd8, 0x0a, 0x61, 0x83, 0x60, 0x30, 0x6c, 0x62, + 0x02, 0xe9, 0x81, 0xc6, 0x60, 0x00, 0x09, 0x8a, 0x18, 0x1e, 0x3b, 0x8d, 0x86, 0xc3, 0x61, 0xb0, + 0xd8, 0x10, 0x36, 0x0d, 0x1f, 0x81, 0xd8, 0xc6, 0x92, 0x0f, 0x7f, 0x82, 0x01, 0x02, 0x40, 0xd0, + 0x40, 0x6c, 0x70, 0x24, 0x1c, 0x06, 0x04, 0x03, 0x01, 0xc0, 0xe0, 0x10, 0x03, 0x5d, 0x86, 0x82, + 0x40, 0x90, 0x50, 0x10, 0x12, 0x70, 0x03, 0x70, 0x83, 0x01, 0xc1, 0x20, 0x60, 0x06, 0x3f, 0x83, + 0x83, 0xc0, 0x20, 0xcc, 0x01, 0x1f, 0x80, 0x02, 0x0a, 0x3f, 0x01, 0x1f, 0x87, 0x01, 0x83, 0x84, + 0x63, 0xf1, 0xd8, 0x18, 0x3c, 0x01, 0x1f, 0x87, 0x01, 0x83, 0xf8, 0x30, 0x1c, 0x9b, 0x33, 0x1e, + 0x01, 0x1f, 0x90, 0xe1, 0x80, 0xc0, 0x7f, 0x0c, 0x01, 0x8f, 0x06, 0x07, 0x79, 0x65, 0x86, 0x66, + 0x61, 0x9e, 0x07, 0x81, 0x05, 0x1f, 0x81, 0x1c, 0x1a, 0x09, 0x1f, 0x80, 0x48, 0x01, 0x1f, 0x86, + 0x18, 0xcc, 0x06, 0x33, 0x18, 0x60, 0xc6, 0x00, 0x3e, 0x83, 0x8c, 0x80, 0xc6, 0xd9, 0x06, 0xee, + 0x81, 0x8e, 0x4c, 0x01, 0x43, 0x96, 0x8d, 0x92, 0x32, 0x31, 0x81, 0x87, 0x00, 0xc0, 0x70, 0xe4, + 0xaa, 0x98, 0xc0, 0x7d, 0xfe, 0xfd, 0xbf, 0x2f, 0xbf, 0x93, 0x8f, 0xdb, 0xe3, 0x01, 0x1f, 0x83, + 0x1e, 0x3f, 0x1f, 0xef, 0x03, 0x5d, 0x86, 0x7d, 0xbf, 0x6f, 0xaf, 0xef, 0xed, 0x8f, 0x03, 0x70, + 0x92, 0xfe, 0x3e, 0xdf, 0x9f, 0x00, 0x00, 0x19, 0x0f, 0xc6, 0x30, 0xd0, 0x00, 0xcc, 0x00, 0x28, + 0x59, 0x86, 0x67, 0xf0, 0x02, 0x3f, 0x83, 0x00, 0x3f, 0x86, 0x00, 0x16, 0x3f, 0x85, 0xcc, 0xc5, + 0x32, 0x83, 0x4c, 0x00, 0x00, 0xdc, 0x04, 0x5e, 0x81, 0xbc, 0xc0, 0x06, 0x23, 0x02, 0x9a, 0x82, + 0x60, 0x30, 0xfb, 0x11, 0x1f, 0x80, 0x38, 0x09, 0x1f, 0x83, 0x31, 0xa1, 0x8c, 0xcc, 0x15, 0x1f, + 0x80, 0xc0, 0x03, 0x75, 0x80, 0xcc, 0x09, 0x1f, 0x80, 0x37, 0x0d, 0x16, 0x82, 0x8c, 0x00, 0x67, + 0x10, 0x08, 0x80, 0xc6, 0x80, 0x1f, 0x09, 0x1f, 0x9a, 0xb0, 0x40, 0x6c, 0x07, 0x03, 0x83, 0x80, + 0xe0, 0xe0, 0x00, 0x18, 0x0e, 0x10, 0x10, 0x08, 0x04, 0x02, 0x00, 0xf0, 0x20, 0x10, 0x1e, 0x08, + 0x89, 0x03, 0x00, 0xe0, 0x03, 0x6c, 0x05, 0x1f, 0x83, 0x81, 0xe0, 0x41, 0x6c, 0x01, 0x1f, 0x94, + 0x00, 0x0f, 0xe0, 0x03, 0xf8, 0x00, 0x30, 0x63, 0x06, 0x03, 0x00, 0xc7, 0xf0, 0x39, 0x8c, 0x30, + 0x3e, 0x1b, 0x80, 0x00, 0x03, 0x01, 0x30, 0x82, 0x30, 0x9b, 0x23, 0x0a, 0x3f, 0x81, 0xf8, 0xc6, + 0x06, 0x3f, 0x88, 0x86, 0x05, 0xd9, 0x35, 0x86, 0x7c, 0x61, 0x9b, 0x01, 0x03, 0x3b, 0x84, 0x99, + 0xb4, 0x1c, 0x0c, 0x06, 0x02, 0x6e, 0x80, 0x30, 0x03, 0xee, 0x80, 0x3f, 0x05, 0x1f, 0x80, 0xf8, + 0x09, 0x1f, 0x81, 0x8f, 0x00, 0x0d, 0x1f, 0x8f, 0x8c, 0x0f, 0x81, 0x83, 0x18, 0xd9, 0xba, 0x1c, + 0x1b, 0x03, 0x00, 0x80, 0xc0, 0x81, 0x75, 0x54, 0x0d, 0x1f, 0x9a, 0x4f, 0xbf, 0x93, 0xf8, 0xfc, + 0x7c, 0x7f, 0x1f, 0x1f, 0x6f, 0xe7, 0xf1, 0xef, 0xef, 0xf7, 0xfb, 0xfd, 0xff, 0x0f, 0xdf, 0xef, + 0xe1, 0xf7, 0x76, 0xfc, 0xff, 0x1f, 0x03, 0x6c, 0x94, 0x00, 0x08, 0x19, 0x03, 0x06, 0x31, 0xf8, + 0x00, 0xc6, 0x00, 0x28, 0x5b, 0x8c, 0xc0, 0x11, 0xf1, 0x4a, 0x00, 0x00, 0x04, 0x0c, 0x05, 0x1f, + 0x81, 0x74, 0x38, 0x01, 0x1f, 0x8d, 0xc6, 0x65, 0x52, 0xb8, 0x54, 0x18, 0x46, 0x23, 0x11, 0x88, + 0xc4, 0x62, 0x31, 0x30, 0x22, 0x3f, 0x80, 0x26, 0x0d, 0x1f, 0x81, 0x10, 0xd3, 0x04, 0xfb, 0x85, + 0x30, 0xc1, 0x8c, 0xc6, 0x7e, 0x3f, 0x0b, 0xbb, 0x86, 0xfc, 0xc0, 0x7f, 0x3f, 0x9f, 0xcf, 0xe0, + 0x05, 0x1f, 0x05, 0x28, 0x05, 0x16, 0x81, 0xfe, 0x6b, 0x09, 0x43, 0x82, 0xb1, 0x8c, 0x6c, 0x80, + 0x0e, 0x01, 0x1f, 0x80, 0x01, 0x03, 0x5f, 0x8a, 0xc6, 0x08, 0x01, 0x02, 0x00, 0x40, 0x80, 0xe0, + 0x24, 0x04, 0x1c, 0x09, 0x1f, 0x93, 0x90, 0x20, 0x10, 0x12, 0x0d, 0x86, 0x00, 0x81, 0x00, 0x40, + 0x20, 0x10, 0x00, 0x04, 0x00, 0x1f, 0xe1, 0x70, 0xbb, 0x28, 0x05, 0x1f, 0x0a, 0x3f, 0x01, 0x1f, + 0x8a, 0x06, 0x00, 0x67, 0xf0, 0x19, 0x8c, 0x30, 0x67, 0x0d, 0x80, 0x00, 0x06, 0x3f, 0x84, 0x30, + 0x9b, 0x7f, 0x19, 0x8c, 0x07, 0x5f, 0x05, 0x1f, 0x81, 0x8c, 0xc6, 0x05, 0x1f, 0x8b, 0x60, 0x61, + 0x99, 0x80, 0xe1, 0x83, 0x18, 0xd0, 0xdc, 0x26, 0x0c, 0x0c, 0x05, 0x1f, 0x83, 0x84, 0x00, 0x00, + 0x63, 0x05, 0x1f, 0x80, 0x00, 0x09, 0x1f, 0x80, 0x8d, 0x12, 0x3f, 0x81, 0x8c, 0x03, 0x00, 0x23, + 0x05, 0x1f, 0x04, 0xc4, 0x83, 0xc1, 0x38, 0xaa, 0x80, 0x01, 0x1f, 0x80, 0xfe, 0x03, 0x5f, 0x8a, + 0x39, 0xf7, 0xfe, 0xfd, 0xff, 0xbf, 0x7f, 0x0f, 0xdb, 0xfb, 0xe3, 0x09, 0x1f, 0x8b, 0x6f, 0xdf, + 0xef, 0xed, 0xf2, 0x79, 0xff, 0x7e, 0xff, 0xbf, 0xdf, 0xef, 0x0b, 0x5f, 0x8a, 0x60, 0x60, 0x30, + 0x66, 0x00, 0x28, 0x4d, 0xc6, 0x60, 0x10, 0x00, 0x00, 0x59, 0x82, 0x04, 0x0f, 0x87, 0x03, 0x5f, + 0x8b, 0x14, 0x38, 0x00, 0x3f, 0x0f, 0x8c, 0xc2, 0x90, 0x84, 0xa4, 0x18, 0xfe, 0x04, 0xf3, 0x82, + 0xe7, 0xf1, 0xf0, 0x3d, 0x1f, 0x80, 0x38, 0x11, 0x1f, 0x81, 0x98, 0xc6, 0x00, 0x7e, 0x05, 0x0e, + 0x0a, 0x39, 0x01, 0x5f, 0x21, 0x1f, 0x80, 0x00, 0x19, 0x1f, 0x93, 0x1c, 0x7f, 0x81, 0x20, 0x90, + 0x38, 0x18, 0x0b, 0x83, 0x06, 0x01, 0x03, 0x80, 0x40, 0xe0, 0x90, 0x24, 0x04, 0x03, 0x8e, 0x03, + 0x82, 0x88, 0x90, 0x24, 0x12, 0x0e, 0x04, 0x8a, 0x81, 0xc7, 0x70, 0x04, 0x5f, 0x01, 0x11, 0x87, + 0x04, 0x81, 0x31, 0x6f, 0x30, 0x00, 0x18, 0x06, 0x0d, 0x1f, 0x95, 0x60, 0x63, 0x06, 0x0c, 0x00, + 0x60, 0x60, 0x19, 0x8c, 0x60, 0x63, 0x01, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x4d, 0xe1, + 0x99, 0x21, 0x1f, 0x82, 0x04, 0x99, 0x1d, 0x09, 0x1f, 0x80, 0x61, 0x05, 0x1f, 0x80, 0x63, 0x05, + 0x1f, 0x80, 0x60, 0x21, 0x1f, 0x80, 0x6e, 0x07, 0x5f, 0x80, 0xc0, 0x11, 0x1f, 0x80, 0x00, 0x04, + 0x23, 0x84, 0xcc, 0x26, 0x0e, 0x0c, 0x03, 0x00, 0xa1, 0x80, 0x01, 0x02, 0x3f, 0xb2, 0x7e, 0xdf, + 0x6f, 0xc7, 0xe7, 0xf4, 0x7c, 0xf9, 0xfe, 0xfc, 0x7f, 0xbf, 0x1f, 0x5f, 0xdb, 0xfb, 0xfc, 0x71, + 0x79, 0x3c, 0x9e, 0x6f, 0xdb, 0xed, 0xf1, 0xfb, 0x75, 0x7e, 0x38, 0x8f, 0x3f, 0xcf, 0xe7, 0xf3, + 0x00, 0x0c, 0x0d, 0x03, 0x03, 0xe1, 0xf8, 0x30, 0x3c, 0x00, 0x27, 0x40, 0x03, 0x30, 0x00, 0x00, + 0x78, 0x04, 0x93, 0x07, 0xbd, 0x80, 0x14, 0x04, 0x06, 0x87, 0x19, 0x82, 0xf8, 0x98, 0xbe, 0x70, + 0xc3, 0x61, 0x09, 0x0d, 0x26, 0x3f, 0x80, 0x23, 0x0d, 0x1f, 0x81, 0x4c, 0xe3, 0x0d, 0x1f, 0x80, + 0xf0, 0x61, 0x1f, 0x81, 0x10, 0x73, 0x08, 0x23, 0x82, 0xe1, 0x8c, 0x38, 0x89, 0x1c, 0x7f, 0x80, + 0xa0, 0x50, 0x10, 0x24, 0x0d, 0xff, 0x01, 0x0a, 0x3f, 0x8d, 0xf0, 0x24, 0x04, 0x02, 0x01, 0x81, + 0x20, 0x10, 0x30, 0x28, 0x1a, 0x09, 0x06, 0x8a, 0x01, 0x3a, 0x80, 0x20, 0x06, 0x4c, 0x03, 0x5f, + 0x83, 0x85, 0x32, 0x6f, 0xb8, 0x09, 0x1f, 0x8f, 0x01, 0xc0, 0x00, 0x70, 0x60, 0x36, 0x06, 0x1f, + 0xcc, 0xe0, 0x63, 0x30, 0xd8, 0x60, 0x63, 0x33, 0x03, 0x69, 0x80, 0x60, 0x02, 0x1d, 0x01, 0x0d, + 0x81, 0x86, 0x66, 0x01, 0x2d, 0x94, 0x66, 0x63, 0x0c, 0x03, 0x0c, 0x66, 0x04, 0x19, 0x1c, 0xcc, + 0x60, 0x33, 0x18, 0xcc, 0x61, 0x81, 0xb0, 0x60, 0xcc, 0x63, 0x0c, 0x00, 0x37, 0x80, 0x60, 0x00, + 0xc7, 0x88, 0x00, 0x67, 0x19, 0x86, 0x23, 0x71, 0x88, 0x60, 0x36, 0x05, 0x1f, 0x80, 0x60, 0x01, + 0x1f, 0x88, 0x6c, 0x66, 0x1b, 0x8c, 0x08, 0x61, 0x83, 0xb8, 0x70, 0x04, 0x23, 0x05, 0x1f, 0x8b, + 0x00, 0xaa, 0x98, 0xc0, 0x7f, 0x5f, 0xaf, 0xef, 0xdb, 0xf2, 0x00, 0xfe, 0x0a, 0x3f, 0x8d, 0x6f, + 0xdb, 0xfb, 0xfd, 0xfe, 0x7e, 0xdf, 0xef, 0xcf, 0xd7, 0xe5, 0xf6, 0xf9, 0x75, 0x01, 0x3a, 0x80, + 0xdf, 0x02, 0x4c, 0x8a, 0x00, 0x0c, 0x07, 0xc6, 0x04, 0x10, 0x60, 0x30, 0x06, 0x00, 0x10, 0x01, + 0x9d, 0x08, 0x00, 0x80, 0x3f, 0x00, 0x08, 0x81, 0x03, 0xb8, 0x09, 0x1f, 0x85, 0x00, 0x04, 0x11, + 0x21, 0x04, 0xc0, 0x15, 0x1f, 0x80, 0x66, 0x19, 0x1f, 0x82, 0x66, 0x23, 0x99, 0x05, 0x90, 0x98, + 0x98, 0x00, 0x66, 0x1b, 0x0d, 0x86, 0xc3, 0x60, 0xc1, 0x80, 0xc6, 0xce, 0x67, 0x33, 0x99, 0xcc, + 0xe6, 0x73, 0x74, 0x62, 0x31, 0x18, 0x8c, 0x46, 0x20, 0x05, 0x1f, 0x82, 0x36, 0x31, 0x8d, 0x02, + 0x1c, 0x8b, 0xb0, 0xd8, 0x10, 0x36, 0x3b, 0x9d, 0xce, 0xe7, 0x70, 0xc1, 0x98, 0x30, 0x81, 0x00, + 0x7f, 0x00, 0x3b, 0x84, 0x10, 0x24, 0x0c, 0x38, 0x0e, 0x09, 0x1f, 0x94, 0xa0, 0x18, 0x0e, 0x03, + 0x00, 0x80, 0x40, 0x60, 0x50, 0x30, 0x16, 0x0e, 0x05, 0x88, 0x81, 0xc0, 0x81, 0xc0, 0x70, 0x38, + 0x1c, 0x05, 0x1f, 0x85, 0x83, 0xe0, 0x39, 0xcc, 0x00, 0x0c, 0x02, 0x4a, 0x05, 0x1f, 0x8b, 0xc0, + 0x1c, 0x06, 0x1f, 0xc7, 0xc0, 0x61, 0xe0, 0x70, 0x60, 0x3e, 0x1e, 0x01, 0x1f, 0x07, 0x71, 0x98, + 0x1e, 0x61, 0x9f, 0x03, 0xc7, 0xc3, 0xf1, 0x80, 0x3e, 0x63, 0x3f, 0x1e, 0x0c, 0x67, 0xe4, 0x19, + 0x0c, 0x78, 0x60, 0x1e, 0x18, 0xc7, 0xc1, 0x80, 0xe0, 0x05, 0x1f, 0x83, 0x1f, 0xc6, 0x00, 0x30, + 0x05, 0x1f, 0x87, 0x3b, 0x9f, 0x03, 0xc1, 0xb0, 0xf0, 0x60, 0x06, 0x05, 0x1f, 0x80, 0x70, 0x01, + 0x1f, 0x87, 0x38, 0x7c, 0x0d, 0x8c, 0x07, 0xc0, 0xf1, 0xd8, 0x08, 0x23, 0x80, 0xc3, 0x0a, 0x3f, + 0x81, 0x80, 0xc0, 0x03, 0x18, 0x84, 0xef, 0xdb, 0xf3, 0xc7, 0xf1, 0x09, 0x1f, 0x9f, 0xff, 0xe7, + 0xf1, 0xfc, 0xff, 0x7f, 0xbf, 0x9f, 0xaf, 0xcf, 0xe9, 0xf1, 0xfa, 0x77, 0x7e, 0x3f, 0x7e, 0x3f, + 0x8f, 0xc7, 0xe3, 0x00, 0x0c, 0x01, 0x0f, 0xe8, 0x08, 0x60, 0x30, 0xc6, 0x00, 0x0f, 0x11, 0x1e, + 0x0e, 0x3f, 0x80, 0xd8, 0x15, 0x1f, 0x80, 0x3d, 0x19, 0x1f, 0x9d, 0x3c, 0x3c, 0x3f, 0x1f, 0x8f, + 0xc7, 0xe7, 0xe3, 0xf1, 0xf8, 0xfc, 0x7c, 0x21, 0x8f, 0x07, 0x83, 0xc1, 0xe0, 0xf0, 0x00, 0xbc, + 0x0e, 0x07, 0x03, 0x81, 0xc0, 0xc1, 0x80, 0xcc, 0x77, 0x05, 0x04, 0x88, 0x73, 0xb9, 0x98, 0x3c, + 0x1e, 0x0f, 0x07, 0x83, 0xc0, 0x05, 0x1f, 0x82, 0x1c, 0x31, 0x87, 0x00, 0x1a, 0x8b, 0xe0, 0x70, + 0x00, 0x5c, 0x1d, 0x8e, 0xc7, 0x63, 0xb0, 0xc1, 0xf0, 0x30, 0x87, 0x00, 0x7f, 0x81, 0x40, 0xa0, + 0x10, 0x28, 0x0a, 0x10, 0x63, 0x8f, 0x90, 0x00, 0x00, 0x02, 0x00, 0x80, 0x80, 0x10, 0xf8, 0x28, + 0x12, 0x09, 0x04, 0x80, 0x01, 0x20, 0x15, 0x9f, 0x0f, 0x57, 0x81, 0x06, 0x18, 0x00, 0x04, 0x80, + 0x40, 0x07, 0x50, 0x20, 0x00, 0x08, 0x19, 0x44, 0x00, 0x09, 0x38, 0x0c, 0x00, 0x85, 0x07, 0xc0, + 0x31, 0xf0, 0x01, 0xff, 0x14, 0x0d, 0x80, 0xcc, 0x00, 0x34, 0x0c, 0x58, 0x80, 0x60, 0x10, 0x07, + 0x86, 0x00, 0x00, 0x18, 0x00, 0x01, 0xe0, 0xc3, 0x00, 0x57, 0x88, 0xff, 0xc0, 0x7e, 0xbf, 0x5f, + 0xef, 0xd7, 0xf5, 0xff, 0x18, 0x00, 0x8d, 0xfd, 0xff, 0x7f, 0x7f, 0xef, 0x07, 0xd7, 0xed, 0xf6, + 0xfb, 0x7f, 0xfe, 0xdf, 0x7f, 0x04, 0x11, 0x01, 0x1f, 0x09, 0x93, 0x80, 0x7c, 0x34, 0x6f, 0x82, + 0x14, 0x00, 0x08, 0x10, 0x0b, 0x80, 0xc6, 0x14, 0x14, 0x14, 0x10, 0x64, 0x00, 0x54, 0x23, 0x83, + 0x01, 0x81, 0x80, 0x60, 0x01, 0x1f, 0x83, 0x20, 0x90, 0x10, 0x1c, 0x15, 0x1f, 0x04, 0x66, 0x82, + 0x80, 0x81, 0xe0, 0x02, 0x51, 0x81, 0x12, 0x0e, 0x01, 0x1f, 0x81, 0xc0, 0x70, 0x3c, 0x34, 0x19, + 0x32, 0x10, 0x00, 0x80, 0x02, 0x54, 0x76, 0x38, 0x29, 0x14, 0x00, 0x83, 0x78, 0x00, 0x00, 0x1f, + 0x0c, 0x09, 0x25, 0x1f, 0x10, 0x00, 0x01, 0x04, 0x82, 0x6f, 0xef, 0xe3, 0x21, 0x1f, 0x83, 0xfc, + 0x7f, 0x7e, 0x1f, 0x02, 0x51, 0x81, 0xed, 0xf1, 0x01, 0x1f, 0x81, 0x3f, 0x8f, 0x0d, 0x1f, 0x59, + 0x8f, 0x06, 0xa5, 0x04, 0x00, 0x19, 0x3a, 0x14, 0x10, 0x64, 0x00, 0x54, 0x23, 0x05, 0x1f, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x32, 0x35, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x31, 0x33, 0x20, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x09, 0x09, 0x00, 0x01, 0x0f, 0x00, 0x09, 0x12, + 0x00, 0x01, 0x0f, 0x00, 0x09, 0x1b, 0x00, 0x01, 0x0f, 0x00, 0x09, 0x24, 0x00, 0x01, 0x0f, 0x00, + 0x09, 0x2d, 0x00, 0x01, 0x0f, 0x00, 0x09, 0x36, 0x00, 0x01, 0x0f, 0x00, 0x09, 0x3f, 0x00, 0x03, + 0x0d, 0x00, 0x09, 0x48, 0x00, 0x03, 0x0d, 0x00, 0x09, 0x51, 0x00, 0x03, 0x0d, 0x00, 0x09, 0x5a, + 0x00, 0x03, 0x0d, 0x00, 0x09, 0x63, 0x00, 0x03, 0x0d, 0x00, 0x09, 0x6c, 0x00, 0x03, 0x0d, 0x00, + 0x09, 0x75, 0x00, 0x03, 0x0e, 0x00, 0x09, 0x7e, 0x00, 0x03, 0x0d, 0x00, 0x09, 0x87, 0x00, 0x03, + 0x0d, 0x00, 0x09, 0x90, 0x00, 0x01, 0x0f, 0x00, 0x09, 0x99, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xa2, + 0x00, 0x01, 0x0f, 0x00, 0x09, 0xab, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xb4, 0x00, 0x01, 0x0f, 0x00, + 0x09, 0xbd, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xc6, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xcf, 0x00, 0x01, + 0x0f, 0x00, 0x09, 0xd8, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xe1, 0x00, 0x03, 0x0d, 0x00, 0x09, 0xea, + 0x00, 0x01, 0x0f, 0x00, 0x09, 0xf3, 0x00, 0x01, 0x0f, 0x00, 0x09, 0xfc, 0x00, 0x03, 0x0d, 0x00, + 0x09, 0x05, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x0e, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x17, 0x01, 0x03, + 0x0d, 0x00, 0x09, 0x20, 0x01, 0x00, 0x00, 0x00, 0x09, 0x29, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x32, + 0x01, 0x02, 0x05, 0x00, 0x09, 0x3b, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x44, 0x01, 0x02, 0x0e, 0x00, + 0x09, 0x4d, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x56, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x5f, 0x01, 0x02, + 0x06, 0x00, 0x09, 0x68, 0x01, 0x02, 0x0e, 0x00, 0x09, 0x71, 0x01, 0x02, 0x0e, 0x00, 0x09, 0x7a, + 0x01, 0x03, 0x08, 0x00, 0x09, 0x83, 0x01, 0x05, 0x0c, 0x00, 0x09, 0x8c, 0x01, 0x0b, 0x0f, 0x00, + 0x09, 0x95, 0x01, 0x08, 0x09, 0x00, 0x09, 0x9e, 0x01, 0x0b, 0x0d, 0x00, 0x09, 0xa7, 0x01, 0x02, + 0x0e, 0x00, 0x09, 0xb0, 0x01, 0x03, 0x0d, 0x00, 0x09, 0xb9, 0x01, 0x03, 0x0d, 0x00, 0x09, 0xc2, + 0x01, 0x03, 0x0d, 0x00, 0x09, 0xcb, 0x01, 0x03, 0x0d, 0x00, 0x09, 0xd4, 0x01, 0x03, 0x0d, 0x00, + 0x09, 0xdd, 0x01, 0x03, 0x0d, 0x00, 0x09, 0xe6, 0x01, 0x03, 0x0d, 0x00, 0x09, 0xef, 0x01, 0x03, + 0x0d, 0x00, 0x09, 0xf8, 0x01, 0x03, 0x0d, 0x00, 0x09, 0x01, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x0a, + 0x02, 0x06, 0x0d, 0x00, 0x09, 0x13, 0x02, 0x06, 0x0f, 0x00, 0x09, 0x1c, 0x02, 0x05, 0x0c, 0x00, + 0x09, 0x25, 0x02, 0x07, 0x0a, 0x00, 0x09, 0x2e, 0x02, 0x05, 0x0c, 0x00, 0x09, 0x37, 0x02, 0x03, + 0x0d, 0x00, 0x09, 0x40, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x49, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x52, + 0x02, 0x03, 0x0d, 0x00, 0x09, 0x5b, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x64, 0x02, 0x03, 0x0d, 0x00, + 0x09, 0x6d, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x76, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x7f, 0x02, 0x03, + 0x0d, 0x00, 0x09, 0x88, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x91, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x9a, + 0x02, 0x03, 0x0d, 0x00, 0x09, 0xa3, 0x02, 0x03, 0x0d, 0x00, 0x09, 0xac, 0x02, 0x03, 0x0d, 0x00, + 0x09, 0xb5, 0x02, 0x03, 0x0d, 0x00, 0x09, 0xbe, 0x02, 0x03, 0x0d, 0x00, 0x09, 0xc7, 0x02, 0x03, + 0x0d, 0x00, 0x09, 0xd0, 0x02, 0x03, 0x0d, 0x00, 0x09, 0xd9, 0x02, 0x03, 0x0f, 0x00, 0x09, 0xe2, + 0x02, 0x03, 0x0d, 0x00, 0x09, 0xeb, 0x02, 0x03, 0x0d, 0x00, 0x09, 0xf4, 0x02, 0x03, 0x0d, 0x00, + 0x09, 0xfd, 0x02, 0x03, 0x0d, 0x00, 0x09, 0x06, 0x03, 0x03, 0x0d, 0x00, 0x09, 0x0f, 0x03, 0x03, + 0x0d, 0x00, 0x09, 0x18, 0x03, 0x03, 0x0d, 0x00, 0x09, 0x21, 0x03, 0x03, 0x0d, 0x00, 0x09, 0x2a, + 0x03, 0x03, 0x0d, 0x00, 0x09, 0x33, 0x03, 0x02, 0x0e, 0x00, 0x09, 0x3c, 0x03, 0x02, 0x0e, 0x00, + 0x09, 0x45, 0x03, 0x02, 0x0e, 0x00, 0x09, 0x4e, 0x03, 0x04, 0x0b, 0x00, 0x09, 0x57, 0x03, 0x0d, + 0x0e, 0x00, 0x09, 0x60, 0x03, 0x02, 0x06, 0x00, 0x09, 0x69, 0x03, 0x05, 0x0d, 0x00, 0x09, 0x72, + 0x03, 0x02, 0x0d, 0x00, 0x09, 0x7b, 0x03, 0x05, 0x0d, 0x00, 0x09, 0x84, 0x03, 0x02, 0x0d, 0x00, + 0x09, 0x8d, 0x03, 0x05, 0x0d, 0x00, 0x09, 0x96, 0x03, 0x02, 0x0d, 0x00, 0x09, 0x9f, 0x03, 0x05, + 0x0f, 0x00, 0x09, 0xa8, 0x03, 0x02, 0x0d, 0x00, 0x09, 0xb1, 0x03, 0x02, 0x0d, 0x00, 0x09, 0xba, + 0x03, 0x02, 0x0f, 0x00, 0x09, 0xc3, 0x03, 0x02, 0x0d, 0x00, 0x09, 0xcc, 0x03, 0x02, 0x0d, 0x00, + 0x09, 0xd5, 0x03, 0x05, 0x0d, 0x00, 0x09, 0xde, 0x03, 0x05, 0x0d, 0x00, 0x09, 0xe7, 0x03, 0x05, + 0x0d, 0x00, 0x09, 0xf0, 0x03, 0x05, 0x0f, 0x00, 0x09, 0xf9, 0x03, 0x05, 0x0f, 0x00, 0x09, 0x02, + 0x04, 0x05, 0x0d, 0x00, 0x09, 0x0b, 0x04, 0x05, 0x0d, 0x00, 0x09, 0x14, 0x04, 0x03, 0x0d, 0x00, + 0x09, 0x1d, 0x04, 0x05, 0x0d, 0x00, 0x09, 0x26, 0x04, 0x05, 0x0d, 0x00, 0x09, 0x2f, 0x04, 0x05, + 0x0d, 0x00, 0x09, 0x38, 0x04, 0x05, 0x0d, 0x00, 0x09, 0x41, 0x04, 0x05, 0x0f, 0x00, 0x09, 0x4a, + 0x04, 0x05, 0x0d, 0x00, 0x09, 0x53, 0x04, 0x02, 0x0e, 0x00, 0x09, 0x5c, 0x04, 0x02, 0x0e, 0x00, + 0x09, 0x65, 0x04, 0x02, 0x0e, 0x00, 0x09, 0x6e, 0x04, 0x07, 0x0a, 0x00, 0x09, 0x77, 0x04, 0x01, + 0x0d, 0x00, 0x09, 0x80, 0x04, 0x00, 0x0e, 0x00, 0x09, 0x89, 0x04, 0x00, 0x0f, 0x00, 0x09, 0x92, + 0x04, 0x00, 0x0f, 0x00, 0x09, 0x9b, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xa4, 0x04, 0x00, 0x0f, 0x00, + 0x09, 0xad, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xb6, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xbf, 0x04, 0x00, + 0x0f, 0x00, 0x09, 0xc8, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xd1, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xda, + 0x04, 0x00, 0x0f, 0x00, 0x09, 0xe3, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xec, 0x04, 0x00, 0x0f, 0x00, + 0x09, 0xf5, 0x04, 0x00, 0x0f, 0x00, 0x09, 0xfe, 0x04, 0x00, 0x0f, 0x00, 0x09, 0x07, 0x05, 0x00, + 0x0f, 0x00, 0x09, 0x10, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x19, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x22, + 0x05, 0x00, 0x0f, 0x00, 0x09, 0x2b, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x34, 0x05, 0x00, 0x0f, 0x00, + 0x09, 0x3d, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x46, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x4f, 0x05, 0x00, + 0x0f, 0x00, 0x09, 0x58, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x61, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x6a, + 0x05, 0x00, 0x0f, 0x00, 0x09, 0x73, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x7c, 0x05, 0x00, 0x0f, 0x00, + 0x09, 0x85, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x8e, 0x05, 0x00, 0x0f, 0x00, 0x09, 0x97, 0x05, 0x00, + 0x0f, 0x00, 0x09, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x09, 0xa9, 0x05, 0x05, 0x0f, 0x00, 0x09, 0xb2, + 0x05, 0x02, 0x0e, 0x00, 0x09, 0xbb, 0x05, 0x03, 0x0d, 0x00, 0x09, 0xc4, 0x05, 0x03, 0x0d, 0x00, + 0x09, 0xcd, 0x05, 0x03, 0x0d, 0x00, 0x09, 0xd6, 0x05, 0x02, 0x0e, 0x00, 0x09, 0xdf, 0x05, 0x03, + 0x0e, 0x00, 0x09, 0xe8, 0x05, 0x02, 0x04, 0x00, 0x09, 0xf1, 0x05, 0x03, 0x0d, 0x00, 0x09, 0xfa, + 0x05, 0x03, 0x0a, 0x00, 0x09, 0x03, 0x06, 0x06, 0x0b, 0x00, 0x09, 0x0c, 0x06, 0x07, 0x0a, 0x00, + 0x09, 0x15, 0x06, 0x08, 0x09, 0x00, 0x09, 0x1e, 0x06, 0x03, 0x0b, 0x00, 0x09, 0x27, 0x06, 0x02, + 0x03, 0x00, 0x09, 0x30, 0x06, 0x03, 0x07, 0x00, 0x09, 0x39, 0x06, 0x05, 0x0c, 0x00, 0x09, 0x42, + 0x06, 0x03, 0x0a, 0x00, 0x09, 0x4b, 0x06, 0x03, 0x0a, 0x00, 0x09, 0x54, 0x06, 0x02, 0x04, 0x00, + 0x09, 0x5d, 0x06, 0x05, 0x0f, 0x00, 0x09, 0x66, 0x06, 0x03, 0x0e, 0x00, 0x09, 0x6f, 0x06, 0x08, + 0x0a, 0x00, 0x09, 0x78, 0x06, 0x0d, 0x0f, 0x00, 0x09, 0x81, 0x06, 0x03, 0x0a, 0x00, 0x09, 0x8a, + 0x06, 0x03, 0x0a, 0x00, 0x09, 0x93, 0x06, 0x06, 0x0b, 0x00, 0x09, 0x9c, 0x06, 0x03, 0x0d, 0x00, + 0x09, 0xa5, 0x06, 0x03, 0x0d, 0x00, 0x09, 0xae, 0x06, 0x03, 0x0d, 0x00, 0x09, 0xb7, 0x06, 0x05, + 0x0f, 0x00, 0x09, 0xc0, 0x06, 0x00, 0x0d, 0x00, 0x09, 0xc9, 0x06, 0x00, 0x0d, 0x00, 0x09, 0xd2, + 0x06, 0x00, 0x0d, 0x00, 0x09, 0xdb, 0x06, 0x00, 0x0d, 0x00, 0x09, 0xe4, 0x06, 0x00, 0x0d, 0x00, + 0x09, 0xed, 0x06, 0x01, 0x0d, 0x00, 0x09, 0xf6, 0x06, 0x03, 0x0d, 0x00, 0x09, 0xff, 0x06, 0x03, + 0x0f, 0x00, 0x09, 0x08, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x11, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x1a, + 0x07, 0x00, 0x0d, 0x00, 0x09, 0x23, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x2c, 0x07, 0x00, 0x0d, 0x00, + 0x09, 0x35, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x3e, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x47, 0x07, 0x00, + 0x0d, 0x00, 0x09, 0x50, 0x07, 0x03, 0x0d, 0x00, 0x09, 0x59, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x62, + 0x07, 0x00, 0x0d, 0x00, 0x09, 0x6b, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x74, 0x07, 0x00, 0x0d, 0x00, + 0x09, 0x7d, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x86, 0x07, 0x00, 0x0d, 0x00, 0x09, 0x8f, 0x07, 0x06, + 0x0b, 0x00, 0x09, 0x98, 0x07, 0x03, 0x0d, 0x00, 0x09, 0xa1, 0x07, 0x00, 0x0d, 0x00, 0x09, 0xaa, + 0x07, 0x00, 0x0d, 0x00, 0x09, 0xb3, 0x07, 0x00, 0x0d, 0x00, 0x09, 0xbc, 0x07, 0x00, 0x0d, 0x00, + 0x09, 0xc5, 0x07, 0x00, 0x0d, 0x00, 0x09, 0xce, 0x07, 0x03, 0x0d, 0x00, 0x09, 0xd7, 0x07, 0x02, + 0x0d, 0x00, 0x09, 0xe0, 0x07, 0x02, 0x0d, 0x00, 0x09, 0xe9, 0x07, 0x02, 0x0d, 0x00, 0x09, 0xf2, + 0x07, 0x02, 0x0d, 0x00, 0x09, 0xfb, 0x07, 0x02, 0x0d, 0x00, 0x09, 0x04, 0x08, 0x02, 0x0d, 0x00, + 0x09, 0x0d, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x16, 0x08, 0x05, 0x0d, 0x00, 0x09, 0x1f, 0x08, 0x05, + 0x0f, 0x00, 0x09, 0x28, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x31, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x3a, + 0x08, 0x02, 0x0d, 0x00, 0x09, 0x43, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x4c, 0x08, 0x02, 0x0d, 0x00, + 0x09, 0x55, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x5e, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x67, 0x08, 0x02, + 0x0d, 0x00, 0x09, 0x70, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x79, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x82, + 0x08, 0x02, 0x0d, 0x00, 0x09, 0x8b, 0x08, 0x02, 0x0d, 0x00, 0x09, 0x94, 0x08, 0x02, 0x0d, 0x00, + 0x09, 0x9d, 0x08, 0x02, 0x0d, 0x00, 0x09, 0xa6, 0x08, 0x02, 0x0d, 0x00, 0x09, 0xaf, 0x08, 0x05, + 0x0c, 0x00, 0x09, 0xb8, 0x08, 0x05, 0x0d, 0x00, 0x09, 0xc1, 0x08, 0x02, 0x0d, 0x00, 0x09, 0xca, + 0x08, 0x02, 0x0d, 0x00, 0x09, 0xd3, 0x08, 0x02, 0x0d, 0x00, 0x09, 0xdc, 0x08, 0x02, 0x0d, 0x00, + 0x09, 0xe5, 0x08, 0x02, 0x0f, 0x00, 0x09, 0xee, 0x08, 0x03, 0x0f, 0x00, 0x09, 0xf7, 0x08, 0x02, + 0x0f, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/src/libdraw/font.c b/src/libdraw/font.c index 13bcd267..c0235c4b 100644 --- a/src/libdraw/font.c +++ b/src/libdraw/font.c @@ -132,8 +132,7 @@ agefont(Font *f) if(s->age){ if(s->agecf->name != nil){ /* clean up */ - if(display==nil || s->f != display->defaultsubfont) - freesubfont(s->f); + freesubfont(s->f); s->cf = nil; s->f = nil; s->age = 0; diff --git a/src/libdraw/getdefont.c b/src/libdraw/getdefont.c deleted file mode 100644 index 9279eec4..00000000 --- a/src/libdraw/getdefont.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include - -Subfont* -getdefont(Display *d) -{ - char *hdr, *p; - int n; - Fontchar *fc; - Subfont *f; - int ld; - Rectangle r; - Image *i; - - /* - * make sure data is word-aligned. this is true with Plan 9 compilers - * but not in general. the byte order is right because the data is - * declared as char*, not ulong*. - */ - p = (char*)defontdata; - n = (ulong)p & 3; - if(n != 0){ - memmove(p+(4-n), p, sizeofdefont-n); - p += 4-n; - } - ld = atoi(p+0*12); - r.min.x = atoi(p+1*12); - r.min.y = atoi(p+2*12); - r.max.x = atoi(p+3*12); - r.max.y = atoi(p+4*12); - - i = allocimage(d, r, drawld2chan[ld], 0, 0); - if(i == 0) - return 0; - - p += 5*12; - n = loadimage(i, r, (uchar*)p, (defontdata+sizeofdefont)-(uchar*)p); - if(n < 0){ - freeimage(i); - return 0; - } - - hdr = p+n; - n = atoi(hdr); - p = hdr+3*12; - fc = malloc(sizeof(Fontchar)*(n+1)); - if(fc == 0){ - freeimage(i); - return 0; - } - _unpackinfo(fc, (uchar*)p, n); - f = allocsubfont("*default*", n, atoi(hdr+12), atoi(hdr+24), fc, i); - if(f == 0){ - freeimage(i); - free(fc); - return 0; - } - return f; -} diff --git a/src/libdraw/getsubfont.c b/src/libdraw/getsubfont.c index 1a5006b4..ba675390 100644 --- a/src/libdraw/getsubfont.c +++ b/src/libdraw/getsubfont.c @@ -1,12 +1,14 @@ #include #include #include +#include "defont.h" /* * Default version: treat as file name */ int _fontpipe(char*); +static int defaultpipe(void); static void scalesubfont(Subfont*, int); @@ -17,12 +19,14 @@ _getsubfont(Display *d, char *name) Subfont *f; int scale; char *fname; - + scale = parsefontscale(name, &fname); - fd = open(fname, OREAD); + if(strcmp(fname, "*default*") == 0) + fd = defaultpipe(); + else + fd = open(fname, OREAD); if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0) fd = _fontpipe(fname+10); - if(fd < 0){ fprint(2, "getsubfont: can't open %s: %r\n", fname); return 0; @@ -46,6 +50,21 @@ _getsubfont(Display *d, char *name) return f; } +static int +defaultpipe(void) +{ + int p[2]; + + // assuming defontdata (<5k) fits in pipe buffer. + // especially reasonable since p9pipe is actually + // a socket pair. + if(pipe(p) < 0) + return -1; + write(p[1], defontdata, sizeof defontdata); + close(p[1]); + return p[0]; +} + static void scalesubfont(Subfont *f, int scale) { @@ -69,8 +88,10 @@ scalesubfont(Subfont *f, int scale) i = allocimage(f->bits->display, r2, f->bits->chan, 0, DBlack); for(y=r.min.y; y < r.max.y; y++) { n = unloadimage(f->bits, Rect(r.min.x, y, r.max.x, y+1), src, srcn); - if(n != srcn) - sysfatal("scalesubfont: bad unload: %d < %d: %r", n, srcn); + if(n != srcn) { + abort(); + sysfatal("scalesubfont: bad unload %R %R: %d < %d: %r", f->bits->r, Rect(r.min.x, y, r.max.x, y+1), n, srcn); + } memset(dst, 0, dstn+1); pack = 8 / f->bits->depth; mask = (1<bits->depth) - 1; diff --git a/src/libdraw/init.c b/src/libdraw/init.c index e5a367f3..350365fe 100644 --- a/src/libdraw/init.c +++ b/src/libdraw/init.c @@ -8,7 +8,6 @@ Font *font; Image *screen; int _drawdebug; -static char deffontname[] = "*default*"; Screen *_screen; int debuglockdisplay = 1; @@ -41,8 +40,7 @@ drawshutdown(void) int geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref) { - Subfont *df; - char buf[128], *p; + char *p; if(label == nil) label = argv0; @@ -53,9 +51,7 @@ geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *l /* * Set up default font */ - df = getdefont(display); - display->defaultsubfont = df; - if(df == nil){ + if(openfont(display, "*default*") == 0) { fprint(2, "imageinit: can't open default subfont: %r\n"); Error: closedisplay(display); @@ -69,21 +65,13 @@ geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *l * Build fonts with caches==depth of screen, for speed. * If conversion were faster, we'd use 0 and save memory. */ - if(fontname == nil){ - snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent, - df->n-1, deffontname); -//BUG: Need something better for this installsubfont("*default*", df); - font = buildfont(display, buf, deffontname); - if(font == nil){ - fprint(2, "imageinit: can't open default font: %r\n"); - goto Error; - } - }else{ - font = openfont(display, fontname); /* BUG: grey fonts */ - if(font == nil){ - fprint(2, "imageinit: can't open font %s: %r\n", fontname); - goto Error; - } + if(fontname == nil) + fontname = strdup("*default*"); + + font = openfont(display, fontname); + if(font == nil){ + fprint(2, "imageinit: can't open font %s: %r\n", fontname); + goto Error; } display->defaultfont = font; @@ -306,7 +294,7 @@ _initdisplay(void (*error)(Display*, char*), char *label) /* * Call with d unlocked. - * Note that disp->defaultfont and defaultsubfont are not freed here. + * Note that disp->defaultfont is not freed here. */ void closedisplay(Display *disp) diff --git a/src/libdraw/mkfile b/src/libdraw/mkfile index 003bf3ce..fab6295b 100644 --- a/src/libdraw/mkfile +++ b/src/libdraw/mkfile @@ -16,7 +16,6 @@ OFILES=\ creadimage.$O\ cursor.$O\ debug.$O\ - defont.$O\ draw.$O\ drawclient.$O\ drawfcall.$O\ @@ -27,7 +26,6 @@ OFILES=\ event.$O\ font.$O\ freesubfont.$O\ - getdefont.$O\ getrect.$O\ getsubfont.$O\ icossin.$O\ @@ -72,5 +70,7 @@ HFILES=\ $PLAN9/include/mouse.h\ $PLAN9/include/keyboard.h\ +getsubfont.$O: defont.h + <$PLAN9/src/mksyslib diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c index 3fe9410a..366664ae 100644 --- a/src/libdraw/openfont.c +++ b/src/libdraw/openfont.c @@ -26,6 +26,8 @@ parsefontscale(char *name, char **base) return scale; } +extern char _defontfile[]; + Font* openfont1(Display *d, char *name) { @@ -37,6 +39,10 @@ openfont1(Display *d, char *name) freename = nil; scale = parsefontscale(name, &fname); + if(strcmp(fname, "*default*") == 0) { + buf = strdup(_defontfile); + goto build; + } fd = open(fname, OREAD); if(fd < 0 && strncmp(fname, "/lib/font/bit/", 14) == 0){ nambuf = smprint("#9/font/%s", fname+14); @@ -87,6 +93,7 @@ openfont1(Display *d, char *name) return 0; } buf[i] = 0; +build: fnt = buildfont(d, buf, name); free(buf); free(nambuf); diff --git a/src/libdraw/readsubfont.c b/src/libdraw/readsubfont.c index 05962640..e1024326 100644 --- a/src/libdraw/readsubfont.c +++ b/src/libdraw/readsubfont.c @@ -58,3 +58,19 @@ readsubfont(Display*d, char *name, int fd, int dolock) { return readsubfonti(d, name, fd, nil, dolock); } + +void +_unpackinfo(Fontchar *fc, uchar *p, int n) +{ + int j; + + for(j=0; j<=n; j++){ + fc->x = p[0]|(p[1]<<8); + fc->top = p[2]; + fc->bottom = p[3]; + fc->left = p[4]; + fc->width = p[5]; + fc++; + p += 6; + } +} diff --git a/src/libdraw/subfontcache.c b/src/libdraw/subfontcache.c index 91a6861a..6a51f435 100644 --- a/src/libdraw/subfontcache.c +++ b/src/libdraw/subfontcache.c @@ -12,8 +12,6 @@ Subfont *lastsubfont; Subfont* lookupsubfont(Display *d, char *name) { - if(d && strcmp(name, "*default*") == 0) - return d->defaultsubfont; if(lastname && strcmp(name, lastname)==0) if(d==lastsubfont->bits->display){ lastsubfont->ref++; diff --git a/src/libdraw/subfontname.c b/src/libdraw/subfontname.c index 9d68570d..e6059d0e 100644 --- a/src/libdraw/subfontname.c +++ b/src/libdraw/subfontname.c @@ -15,8 +15,13 @@ subfontname(char *cfname, char *fname, int maxdepth) scale = parsefontscale(fname, &base); t = strdup(cfname); /* t is the return string */ - if(strcmp(cfname, "*default*") == 0) + if(strcmp(cfname, "*default*") == 0) { + if(scale > 1) { + free(t); + return smprint("%d*%s", scale, cfname); + } return t; + } if(t[0] != '/'){ tmp2 = strdup(base); u = utfrrune(tmp2, '/'); diff --git a/src/libmemdraw/defont.c b/src/libmemdraw/defont.c deleted file mode 100644 index 21ea6cc0..00000000 --- a/src/libmemdraw/defont.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -Memsubfont* -getmemdefont(void) -{ - char *hdr, *p; - int n; - Fontchar *fc; - Memsubfont *f; - int ld; - Rectangle r; - Memdata *md; - Memimage *i; - - /* - * make sure data is word-aligned. this is true with Plan 9 compilers - * but not in general. the byte order is right because the data is - * declared as char*, not u32int*. - */ - p = (char*)defontdata; - n = (uintptr)p & 3; - if(n != 0){ - memmove(p+(4-n), p, sizeofdefont-n); - p += 4-n; - } - ld = atoi(p+0*12); - r.min.x = atoi(p+1*12); - r.min.y = atoi(p+2*12); - r.max.x = atoi(p+3*12); - r.max.y = atoi(p+4*12); - - md = mallocz(sizeof(Memdata), 1); - if(md == nil) - return nil; - - p += 5*12; - - md->base = nil; /* so freememimage doesn't free p */ - md->bdata = (uchar*)p; /* ick */ - md->ref = 1; - md->allocd = 1; /* so freememimage does free md */ - - i = allocmemimaged(r, drawld2chan[ld], md, nil); - if(i == nil){ - free(md); - return nil; - } - - hdr = p+Dy(r)*i->width*sizeof(u32int); - n = atoi(hdr); - p = hdr+3*12; - fc = malloc(sizeof(Fontchar)*(n+1)); - if(fc == 0){ - freememimage(i); - return 0; - } - _unpackinfo(fc, (uchar*)p, n); - f = allocmemsubfont("*default*", n, atoi(hdr+12), atoi(hdr+24), fc, i); - if(f == 0){ - freememimage(i); - free(fc); - return 0; - } - return f; -} diff --git a/src/libmemdraw/mkfile b/src/libmemdraw/mkfile index a8c32ff5..5668ea43 100644 --- a/src/libmemdraw/mkfile +++ b/src/libmemdraw/mkfile @@ -10,7 +10,6 @@ OFILES=\ cload-stub.$O\ cmap.$O\ cread.$O\ - defont.$O\ draw.$O\ draw-stub.$O\ ellipse.$O\ -- cgit v1.2.3