aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xINSTALL45
-rwxr-xr-xbin/9l2
-rwxr-xr-xbin/web2
-rw-r--r--dist/isum.awk2
-rw-r--r--include/cursor.h10
-rw-r--r--include/draw.h7
-rw-r--r--include/drawfcall.h6
-rw-r--r--include/event.h2
-rw-r--r--include/memdraw.h1
-rw-r--r--include/mouse.h2
-rw-r--r--lib/keyboard4
-rwxr-xr-xmac/9term.app/Contents/MacOS/9term6
-rw-r--r--man/man1/paint.185
-rw-r--r--man/man3/graphics.311
-rw-r--r--man/man3/memdraw.33
-rw-r--r--plumb/basic22
-rw-r--r--src/cmd/9term/FreeBSD.c16
-rw-r--r--src/cmd/9term/rcstart.c7
-rw-r--r--src/cmd/acme/acme.c68
-rw-r--r--src/cmd/acme/cols.c10
-rw-r--r--src/cmd/acme/dat.h1
-rw-r--r--src/cmd/acme/rows.c2
-rw-r--r--src/cmd/devdraw/bigarrow.h92
-rw-r--r--src/cmd/devdraw/cocoa-screen-metal.m1250
-rw-r--r--src/cmd/devdraw/cocoa-screen.h8
-rw-r--r--src/cmd/devdraw/cocoa-screen.m10
-rw-r--r--src/cmd/devdraw/cocoa-srv.c24
-rw-r--r--src/cmd/devdraw/cocoa-thread.c7
-rw-r--r--src/cmd/devdraw/cocoa-thread.h1
-rw-r--r--src/cmd/devdraw/mkfile5
-rw-r--r--src/cmd/devdraw/mkwsysrules.sh17
-rw-r--r--src/cmd/devdraw/osx-screen-carbon.m1302
-rw-r--r--src/cmd/devdraw/osx-screen.h18
-rw-r--r--src/cmd/devdraw/osx-srv.c462
-rw-r--r--src/cmd/devdraw/x11-init.c9
-rw-r--r--src/cmd/draw/tweak.c108
-rw-r--r--src/cmd/file.c9
-rw-r--r--src/cmd/fontsrv/a.h1
-rw-r--r--src/cmd/fontsrv/main.c3
-rw-r--r--src/cmd/fontsrv/mkfile1
-rw-r--r--src/cmd/fontsrv/osx.c3
-rw-r--r--src/cmd/fontsrv/x11.c85
-rw-r--r--src/cmd/paint/eenter.c258
-rw-r--r--src/cmd/paint/mkfile11
-rw-r--r--src/cmd/paint/paint.c859
-rw-r--r--src/cmd/rio/mkriorules.sh6
-rw-r--r--src/cmd/upas/nfs/imap.c2
-rw-r--r--src/cmd/upas/smtp/mxdial.c48
-rw-r--r--src/cmd/upas/smtp/smtp.c1
-rw-r--r--src/libdraw/buildfont.c2
-rw-r--r--src/libdraw/cursor.c32
-rw-r--r--src/libdraw/defont.c402
-rw-r--r--src/libdraw/defont.h303
-rw-r--r--src/libdraw/drawclient.c7
-rw-r--r--src/libdraw/drawfcall.c14
-rw-r--r--src/libdraw/event.c8
-rw-r--r--src/libdraw/font.c3
-rw-r--r--src/libdraw/getdefont.c60
-rw-r--r--src/libdraw/getsubfont.c31
-rw-r--r--src/libdraw/init.c32
-rw-r--r--src/libdraw/mkfile5
-rw-r--r--src/libdraw/mouse.c8
-rw-r--r--src/libdraw/openfont.c7
-rw-r--r--src/libdraw/readsubfont.c16
-rw-r--r--src/libdraw/subfontcache.c2
-rw-r--r--src/libdraw/subfontname.c7
-rw-r--r--src/libmemdraw/defont.c68
-rw-r--r--src/libmemdraw/mkfile1
-rw-r--r--unix/mkfile8
69 files changed, 3401 insertions, 2529 deletions
diff --git a/INSTALL b/INSTALL
index 4673056b..cb0df570 100755
--- a/INSTALL
+++ b/INSTALL
@@ -15,9 +15,9 @@ x-c)
doinstall=true
;;
x-r)
- shift
- PLAN9_TARGET=$1 export PLAN9_TARGET
- ;;
+ shift
+ PLAN9_TARGET=$1 export PLAN9_TARGET
+ ;;
*)
echo 'usage: INSTALL [-b | -c] [-r path]' 1>&2
exit 1
@@ -42,23 +42,27 @@ echo "* Resetting $PLAN9/config"
rm -f config
(
-echo "* Compiler version:"
-9c -v 2>&1 | grep -v 'Configured with:' | grep -i version | sed 's/^/ /'
-
if [ `uname` = FreeBSD ]; then
- echo "* Running on FreeBSD, adjusting linker flags"
- echo "LDFLAGS='-L/usr/local/lib'" >> $PLAN9/config
+ case `cc -v 2>&1` in
+ *clang*)
+ echo "CC9=clang" >> $PLAN9/config
+ ;;
+ *)
+ ;;
+ esac
+ echo "* Running on FreeBSD, adjusting linker flags"
+ echo "LDFLAGS='-L/usr/local/lib'" >> $PLAN9/config
fi
if [ `uname` = DragonFly ]; then
- echo "* Running on DragonFly BSD, adjusting linker flags"
- echo "LDFLAGS='-L/usr/local/lib -pthread'" >> $PLAN9/config
- echo "CFLAGS='-pthread'" >> $PLAN9/config
+ echo "* Running on DragonFly BSD, adjusting linker flags"
+ echo "LDFLAGS='-L/usr/local/lib -pthread'" >> $PLAN9/config
+ echo "CFLAGS='-pthread'" >> $PLAN9/config
fi
if [ `uname` = OpenBSD ]; then
- echo "* Running on OpenBSD, adjusting linker flags"
- echo "LDFLAGS='-L/usr/X11R6/lib -pthread'" >> $PLAN9/config
+ echo "* Running on OpenBSD, adjusting linker flags"
+ echo "LDFLAGS='-L/usr/X11R6/lib -pthread'" >> $PLAN9/config
fi
if [ `uname` = Linux ]; then
@@ -80,8 +84,8 @@ fi
if [ `uname` = SunOS ]; then
# On Solaris x86, uname -p cannot be trusted.
- echo "* Running on Solaris: checking architecture..."
- case "$(isainfo -n)" in
+ echo "* Running on Solaris: checking architecture..."
+ case "$(isainfo -n)" in
*amd64*)
echo " x86-64 found."
echo "OBJTYPE=x86_64" >>$PLAN9/config
@@ -92,7 +96,7 @@ if [ `uname` = SunOS ]; then
echo "OBJTYPE=386" >>$PLAN9/config
echo "CC9=gcc" >>$PLAN9/config # defaults to gcc on Solaris/i386
;;
- *sparc*)
+ *sparc*)
echo " Sparc found."
echo "OBJTYPE=sparc" >>$PLAN9/config
;;
@@ -100,6 +104,7 @@ if [ `uname` = SunOS ]; then
fi
if [ `uname` = Darwin ]; then
+ export NPROC=$(sysctl hw.ncpu | sed 's/hw.ncpu: //')
# On Darwin, uname -m -p cannot be trusted.
echo "* Running on Darwin: checking architecture..."
rm -f ./a.out
@@ -112,13 +117,14 @@ if [ `uname` = Darwin ]; then
*x86_64*)
echo " x86-64 found."
echo "OBJTYPE=x86_64" >>$PLAN9/config
+ echo "CC9='xcrun --sdk macosx clang'" >>$PLAN9/config
;;
*i386*)
echo " i386 found."
echo "OBJTYPE=386" >>$PLAN9/config
;;
*ppc*)
- echo " power found."
+ echo " power found."
echo "OBJTYPE=power" >>$PLAN9/config
;;
esac
@@ -128,7 +134,7 @@ fi
if [ `uname` != Darwin ]; then
# Determine whether fontsrv X11 files are available.
rm -f a.out
- gcc -o a.out -c -Iinclude -I/usr/include -I/usr/local/include -I/usr/include/freetype2 -I/usr/local/include/freetype2 \
+ cc -o a.out -c -Iinclude -I/usr/include -I/usr/local/include -I/usr/include/freetype2 -I/usr/local/include/freetype2 \
-I/usr/X11R6/include -I/usr/X11R6/include/freetype2 src/cmd/fontsrv/x11.c >/dev/null 2>&1
if [ -f a.out ]; then
echo " fontsrv dependencies found."
@@ -147,6 +153,9 @@ if [ -f LOCAL.config ]; then
cat LOCAL.config >>config
fi
+echo "* Compiler version:"
+9c -v 2>&1 | grep -v 'Configured with:' | grep -i version | sed 's/^/ /'
+
cd src
if $dobuild; then
if [ ! -x ../bin/mk ]; then
diff --git a/bin/9l b/bin/9l
index 2409e641..6195815f 100755
--- a/bin/9l
+++ b/bin/9l
@@ -349,7 +349,7 @@ fi
xtmp=/tmp/9l.$$.$USER.out
xxout() {
sed 's/.*: In function `[^:]*: *//' $xtmp | egrep . |
- egrep -v 'is (often|almost always) misused|is dangerous, better use'
+ egrep -v 'is (often|almost always) misused|is dangerous, better use|text-based stub'
rm -f $xtmp
}
diff --git a/bin/web b/bin/web
index 7829229f..5de67398 100755
--- a/bin/web
+++ b/bin/web
@@ -34,7 +34,7 @@ plumbunix()
$BROWSER -remote 'openURL('"$@"',new-tab)' ||
$BROWSER "$@"
;;
- *chrome*|*chromium*)
+ ?*)
$BROWSER "$@"
;;
esac
diff --git a/dist/isum.awk b/dist/isum.awk
index 0d2f8721..081ba0ef 100644
--- a/dist/isum.awk
+++ b/dist/isum.awk
@@ -132,7 +132,7 @@ errors != 0 {
next
}
-/(up to date|nothing to see|assuming it will be|loop not entered)/ {
+/(up to date|nothing to see|assuming it will be|loop not entered|# WSYSTYPE)/ {
next
}
diff --git a/include/cursor.h b/include/cursor.h
index d53baf81..e39d2ea5 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -12,6 +12,16 @@ struct Cursor
uchar set[2*16];
};
+typedef struct Cursor2 Cursor2;
+struct Cursor2
+{
+ Point offset;
+ uchar clr[4*32];
+ uchar set[4*32];
+};
+
+void scalecursor(Cursor2*, Cursor*);
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/draw.h b/include/draw.h
index 3a012959..926cc748 100644
--- a/include/draw.h
+++ b/include/draw.h
@@ -199,7 +199,6 @@ struct Display
int obufsize;
uchar *obufp;
Font *defaultfont;
- Subfont *defaultsubfont;
Image *windows;
Image *screenimage;
int _isnewdisplay;
@@ -498,7 +497,6 @@ extern Point strsubfontwidth(Subfont*, char*);
extern int loadchar(Font*, Rune, Cacheinfo*, int, int, char**);
extern char* subfontname(char*, char*, int);
extern Subfont* _getsubfont(Display*, char*);
-extern Subfont* getdefont(Display*);
extern void lockdisplay(Display*);
extern void unlockdisplay(Display*);
extern int drawlsetrefresh(u32int, int, void*, void*);
@@ -508,8 +506,6 @@ extern void swapfont(Font*, Font**, Font**);
/*
* Predefined
*/
-extern uchar defontdata[];
-extern int sizeofdefont;
extern Point ZP;
extern Rectangle ZR;
@@ -568,9 +564,10 @@ int mousescrollsize(int);
*/
struct Mouse;
struct Cursor;
+struct Cursor2;
int _displaybouncemouse(Display *d, struct Mouse *m);
int _displayconnect(Display *d);
-int _displaycursor(Display *d, struct Cursor *c);
+int _displaycursor(Display *d, struct Cursor *c, struct Cursor2 *c2);
int _displayinit(Display *d, char *label, char *winsize);
int _displaylabel(Display *d, char *label);
int _displaymoveto(Display *d, Point p);
diff --git a/include/drawfcall.h b/include/drawfcall.h
index fb339919..acab98c5 100644
--- a/include/drawfcall.h
+++ b/include/drawfcall.h
@@ -13,6 +13,9 @@ tag[1] Rmoveto
tag[1] Tcursor cursor[]
tag[1] Rcursor
+tag[1] Tcursor2 cursor[]
+tag[1] Rcursor2
+
tag[1] Tbouncemouse x[4] y[4] button[4]
tag[1] Rbouncemouse
@@ -89,6 +92,8 @@ enum {
Rtop,
Tresize = 26,
Rresize,
+ Tcursor2 = 28,
+ Rcursor2,
Tmax,
};
@@ -104,6 +109,7 @@ struct Wsysmsg
Mouse mouse;
int resized;
Cursor cursor;
+ Cursor2 cursor2;
int arrowcursor;
Rune rune;
char *winsize;
diff --git a/include/event.h b/include/event.h
index 09cb5c78..e66bf117 100644
--- a/include/event.h
+++ b/include/event.h
@@ -61,7 +61,9 @@ extern int emenuhit(int, Mouse*, Menu*);
extern int eatomouse(Mouse*, char*, int);
extern Rectangle getrect(int, Mouse*);
struct Cursor;
+struct Cursor2;
extern void esetcursor(struct Cursor*);
+extern void esetcursor2(struct Cursor*, struct Cursor2*);
extern void emoveto(Point);
extern Rectangle egetrect(int, Mouse*);
extern void edrawgetrect(Rectangle, int);
diff --git a/include/memdraw.h b/include/memdraw.h
index b1495ed8..a22dbe2b 100644
--- a/include/memdraw.h
+++ b/include/memdraw.h
@@ -178,7 +178,6 @@ extern Memsubfont* allocmemsubfont(char*, int, int, int, Fontchar*, Memimage*);
extern Memsubfont* openmemsubfont(char*);
extern void freememsubfont(Memsubfont*);
extern Point memsubfontwidth(Memsubfont*, char*);
-extern Memsubfont* getmemdefont(void);
/*
* Predefined
diff --git a/include/mouse.h b/include/mouse.h
index 3d5c975f..c46d51e9 100644
--- a/include/mouse.h
+++ b/include/mouse.h
@@ -38,7 +38,9 @@ extern void moveto(Mousectl*, Point);
extern int readmouse(Mousectl*);
extern void closemouse(Mousectl*);
struct Cursor;
+struct Cursor2;
extern void setcursor(Mousectl*, struct Cursor*);
+extern void setcursor2(Mousectl*, struct Cursor*, struct Cursor2*);
extern void drawgetrect(Rectangle, int);
extern Rectangle getrect(int, Mousectl*);
extern int menuhit(int, Mousectl*, Menu*, Screen*);
diff --git a/lib/keyboard b/lib/keyboard
index ec16fa30..a1574a36 100644
--- a/lib/keyboard
+++ b/lib/keyboard
@@ -475,6 +475,8 @@
2194 ab ↔ left right arrow
21D0 V= ⇐ left double arrow
21D2 =V ⇒ right double arrow
+21E4 |< ⇤ left arrow to bar
+21E5 >| ⇥ right arrow to bar
2200 fa ∀ for all
2202 pd ∂ partial differential
2203 te ∃ there exists
@@ -551,6 +553,8 @@
22E6 <!~ ⋦ less than but not equivalent to
22E7 >!~ ⋧ greater than but not equivalent to
22EF el ⋯ midline horizontal ellipsis
+2308 lc ⌈ left ceiling
+2309 rc ⌉ right ceiling
230A lf ⌊ left floor
230B rf ⌋ right floor
2329 </ 〈 left angle bracket
diff --git a/mac/9term.app/Contents/MacOS/9term b/mac/9term.app/Contents/MacOS/9term
index ef6692c3..e5ef2735 100755
--- a/mac/9term.app/Contents/MacOS/9term
+++ b/mac/9term.app/Contents/MacOS/9term
@@ -2,4 +2,8 @@
cd $HOME
. ~/.bashrc
PLAN9=${PLAN9:-/usr/local/plan9}
-$PLAN9/bin/9term -W600x800 &
+if ! [[ :$PATH: =~ :$PLAN9/bin: ]]
+then
+ PATH=$PATH:$PLAN9/bin
+fi
+$PLAN9/bin/9term -l -W600x800 &
diff --git a/man/man1/paint.1 b/man/man1/paint.1
new file mode 100644
index 00000000..2bcbf245
--- /dev/null
+++ b/man/man1/paint.1
@@ -0,0 +1,85 @@
+.TH PAINT 1
+.CT 1 graphics
+.SH NAME
+paint \- create image files by drawing with a mouse or other pointing device
+.SH SYNOPSIS
+.B paint
+[
+.I file
+]
+.SH DESCRIPTION
+.I Paint
+displays a canvas upon which can be drawn lines using the mouse holding
+down buttons 1 or 2 for foreground or background color. The canvas
+may be moved with button 3. Colors and brush sizes may be selected by
+clicking on the palette at the bottom of the screen with buttons 1 or 2.
+.PP
+If the optional
+.I file
+argument is specified, then it is read and used as the canvas.
+.I Paint
+only recognizes Plan 9 bitmap format (see
+.IR image (6)).
+.PP
+A number of immediate keyboard commands are recognized:
+.TP
+.B u
+Undos the previous action.
+.TP
+.B c
+Clears the canvas with the background color.
+.TP
+.B 1-9
+Select brush size.
+.TP
+.B f
+Select flood fill brush.
+.TP
+.B +
+Doubles magnification.
+.TP
+.B -
+Halves magnification.
+.TP
+.B esc
+Centers the canvas and resets magnification.
+.PP
+Hitting any other key on the keyboard shows a command prompt
+where the following commands may be entered:
+.TP
+.BI r file
+Reads the canvas from
+.I file.
+.TP
+.BI w file
+Writes the canvas to
+.I file.
+.TP
+.BI < command
+Executes
+.I command
+and reads the canvas from its standard output.
+.TP
+.BI > command
+Executes
+.I command
+and writes the canvas to its standard input.
+.TP
+.BI | command
+Transforms the canvas by piping it thru
+.I command.
+.TP
+.B q
+Quits the program.
+.SH SOURCE
+.B /sys/src/cmd/paint.c
+.SH "SEE ALSO"
+.IR resample (1),
+.IR rotate (1),
+.IR crop (1),
+.IR jpg (1),
+.IR page (1),
+.IR image (6)
+.SH HISTORY
+.I Paint
+first appeared in 9front (October, 2011).
diff --git a/man/man3/graphics.3 b/man/man3/graphics.3
index a2b2d848..4f58451a 100644
--- a/man/man3/graphics.3
+++ b/man/man3/graphics.3
@@ -1,6 +1,6 @@
.TH GRAPHICS 3
.SH NAME
-Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getdefont, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, cursorswitch, cursorset, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth \- interactive graphics
+Display, Point, Rectangle, Cursor, initdraw, geninitdraw, drawerror, initdisplay, closedisplay, getwindow, gengetwindow, flushimage, bufimage, lockdisplay, unlockdisplay, cursorswitch, cursorset, openfont, buildfont, freefont, Pfmt, Rfmt, strtochan, chantostr, chantodepth \- interactive graphics
.SH SYNOPSIS
.nf
.PP
@@ -38,9 +38,6 @@ Display* initdisplay(char *devdir, char *win, void(*errfun)(Display*, char*))
void closedisplay(Display *d)
.PP
.B
-Font* getdefont(Display *d)
-.PP
-.B
int flushimage(Display *d, int vis)
.PP
.B
@@ -398,11 +395,7 @@ names the directory, default
in which the files associated with the window reside.
.I Closedisplay
disconnects the display and frees the associated data structures.
-.I Getdefont
-builds a
-.B Font
-structure from in-core data describing a default font.
-None of these routines is needed by most programs, since
+Neither of these routines is needed by most programs, since
.I initdraw
calls them as needed.
.PP
diff --git a/man/man3/memdraw.3 b/man/man3/memdraw.3
index 3f6c483e..16a5cd79 100644
--- a/man/man3/memdraw.3
+++ b/man/man3/memdraw.3
@@ -152,7 +152,6 @@ Memsubfont* allocmemsubfont(char *name, int n, int height,
Memsubfont* openmemsubfont(char *name)
void freememsubfont(Memsubfont *f)
Point memsubfontwidth(Memsubfont *f, char *s)
-Memsubfont* getmemdefont(void)
Point memimagestring(Memimage *dst, Point p, Memimage *color,
Point cp, Memsubfont *f, char *cs, Drawop op)
.PP
@@ -354,7 +353,6 @@ Similarly,
.IR openmemsubfont ,
.IR freememsubfont ,
.IR memsubfontwidth ,
-.IR getmemdefont ,
and
.I memimagestring
are the
@@ -364,7 +362,6 @@ analogues of
.IR openfont ,
.IR freesubfont ,
.IR strsubfontwidth ,
-.IR getdefont ,
and
.B string
(see
diff --git a/plumb/basic b/plumb/basic
index f728132f..b59b7948 100644
--- a/plumb/basic
+++ b/plumb/basic
@@ -37,8 +37,8 @@ plumb start wdoc2txt $file
# image files go to page
type is text
-data matches '[a-zA-Z¡-￿0-9_\-./]+'
-data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|bit|png|PNG)'
+data matches '[a-zA-Z¡-￿0-9_\-./@]+'
+data matches '([a-zA-Z¡-￿0-9_\-./@]+)\.(jpe?g|JPE?G|gif|GIF|tiff?|TIFF?|ppm|bit|png|PNG)'
arg isfile $0
plumb to image
plumb start 9 page $file
@@ -46,40 +46,40 @@ plumb start 9 page $file
# postscript/pdf/dvi go to page but not over the a plumb port
# the port is here for reference but is unused
type is text
-data matches '[a-zA-Z¡-￿0-9_\-./]+'
-data matches '([a-zA-Z¡-￿0-9_\-./]+)\.(ps|PS|eps|EPS|pdf|PDF|dvi|DVI)'
+data matches '[a-zA-Z¡-￿0-9_\-./@]+'
+data matches '([a-zA-Z¡-￿0-9_\-./@]+)\.(ps|PS|eps|EPS|pdf|PDF|dvi|DVI)'
arg isfile $0
plumb to postscript
plumb start 9 page $file
# open office - s[xt][cdigmw], doc, xls, ppt
-data matches '[a-zA-Z¡-￿0-9_\-./]+'
-data matches '([a-zA-Z¡-￿0-9_\-./]+)\.([Ss][XxTt][CcDdIiGgMmWw]|[Dd][Oo][Cc]|[Xx][Ll][Ss]|[Pp][Pp][Tt])'
+data matches '[a-zA-Z¡-￿0-9_\-./@]+'
+data matches '([a-zA-Z¡-￿0-9_\-./@]+)\.([Ss][XxTt][CcDdIiGgMmWw]|[Dd][Oo][Cc]|[Xx][Ll][Ss]|[Pp][Pp][Tt])'
arg isfile $0
plumb to openoffice
plumb start openoffice $file
# existing files tagged by line number:columnumber or linenumber.columnumber, twice, go to editor
type is text
-data matches '([.a-zA-Z¡-￿0-9_/\-]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr,$twocolonaddr
+data matches '([.a-zA-Z¡-￿0-9_/\-@]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr,$twocolonaddr
arg isfile $1
data set $file
-attr add addr=$2-#1+#$3,$4-#1+#$5
+attr add addr=$2-#0+#$3-#1,$4-#0+#$5-#1
plumb to edit
plumb client $editor
# existing files tagged by line number:columnumber or linenumber.columnumber, twice, go to editor
type is text
-data matches '([.a-zA-Z¡-￿0-9_/\-]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr
+data matches '([.a-zA-Z¡-￿0-9_/\-@]*[a-zA-Z¡-￿0-9_/\-])':$twocolonaddr
arg isfile $1
data set $file
-attr add addr=$2-#1+#$3
+attr add addr=$2-#0+#$3-#1
plumb to edit
plumb client $editor
# existing files, possibly tagged by line number, go to editor
type is text
-data matches '([.a-zA-Z¡-￿0-9_/\-]*[a-zA-Z¡-￿0-9_/\-])('$addr')?'
+data matches '([.a-zA-Z¡-￿0-9_/\-@]*[a-zA-Z¡-￿0-9_/\-])('$addr')?'
arg isfile $1
data set $file
attr add addr=$3
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 <libutil.h>
+
+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;
+}
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){
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 10e014ee..6215e044 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;
@@ -473,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 451ba392..3a3d2e78 100644
--- a/src/cmd/acme/dat.h
+++ b/src/cmd/acme/dat.h
@@ -526,6 +526,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)
diff --git a/src/cmd/devdraw/bigarrow.h b/src/cmd/devdraw/bigarrow.h
index a46f19a0..1221ec8c 100644
--- a/src/cmd/devdraw/bigarrow.h
+++ b/src/cmd/devdraw/bigarrow.h
@@ -1,11 +1,83 @@
-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,
+ },
+};
+
+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
new file mode 100644
index 00000000..049d1c5c
--- /dev/null
+++ b/src/cmd/devdraw/cocoa-screen-metal.m
@@ -0,0 +1,1250 @@
+#define Cursor OSXCursor
+#define Point OSXPoint
+#define Rect OSXRect
+
+#import <Cocoa/Cocoa.h>
+#import <Metal/Metal.h>
+#import <QuartzCore/CAMetalLayer.h>
+
+#undef Cursor
+#undef Point
+#undef Rect
+
+#include <u.h>
+#include <libc.h>
+#include "cocoa-thread.h"
+#include <draw.h>
+#include <memdraw.h>
+#include <keyboard.h>
+#include <cursor.h>
+#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<NSApplicationDelegate,NSWindowDelegate>
++ (void)callservep9p:(id)arg;
++ (void)makewin:(NSValue *)v;
++ (void)callkicklabel:(NSString *)v;
++ (void)callsetNeedsDisplayInRect:(NSValue *)v;
++ (void)callsetcursor:(NSValue *)v;
+@end
+@interface DevDrawView : NSView<NSTextInputClient>
+- (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<MTLDevice> device;
+static id<MTLRenderPipelineState> pipelineState;
+static id<MTLCommandQueue> commandQueue;
+static id<MTLTexture> texture;
+
+static Memimage *img = NULL;
+
+static QLock snarfl;
+
+static NSString *const metal =
+@"#include<metal_stdlib>\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<half> 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<MTLLibrary> 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];
+}
+
+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;
+ uchar *plane[5], *plane2[5];
+ int b;
+
+ cs = [v pointerValue];
+ c = cs->c;
+ if(!c)
+ c = &bigarrow;
+ c2 = cs->c2;
+ if(!c2)
+ c2 = &bigarrow2;
+
+ 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<nelem(c->set); 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];
+ for(b=0; b<nelem(c2->set); 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
+/*
+ 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<NSAttributedStringKey> *)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<MTLCommandBuffer> cbuf;
+ id<MTLRenderCommandEncoder> cmd;
+
+ LOG(@"display");
+
+ cbuf = [commandQueue commandBuffer];
+
+ LOG(@"display query drawable");
+
+@autoreleasepool{
+ id<CAMetalDrawable> 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<MTLCommandBuffer> 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, 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, Cursor2 *c2)
+{
+ Cursors cs;
+
+ cs.c = c;
+ cs.c2 = c2;
+
+ [AppDelegate
+ performSelectorOnMainThread:@selector(callsetcursor:)
+ withObject:[NSValue valueWithPointer:&cs]
+ 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..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*);
@@ -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-screen.m b/src/cmd/devdraw/cocoa-screen.m
index 8e141904..2b804c2f 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 197fd512..329dd71f 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);
}
}
@@ -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;
@@ -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,7 @@ runmsg(Wsysmsg *m)
break;
case Tresize:
- // _xresizewindow(m->rect);
+ resizewindow(m->rect);
replymsg(m);
break;
}
@@ -238,7 +242,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 +297,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 +371,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..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\
@@ -35,6 +37,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..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,15 +53,13 @@ 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
- 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'
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 <Carbon/Carbon.h>
-#import <Foundation/Foundation.h>
-#ifdef MULTITOUCH
-#include <IOKit/IOKitLib.h>
-#include <IOKit/hidsystem/IOHIDShared.h>
-#endif
-#undef Rect
-#undef Point
-#undef Cursor
-#undef offsetof
-#undef nil
-
-#include "u.h"
-#include "libc.h"
-#include <thread.h>
-#include <draw.h>
-#include <memdraw.h>
-#include <keyboard.h>
-#include "mouse.h"
-#include <cursor.h>
-#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; i<kNTracks; ++i) {
- tracks[i].id = -1;
- }
- }
-#endif
- osx.active = active;
-}
-
-void
-fullscreen(int wascmd)
-{
- static OSXRect oldrect;
- GDHandle device;
- OSXRect dr;
-
- if(!wascmd)
- return;
-
- if(!osx.isfullscreen){
- GetWindowGreatestAreaDevice(osx.window,
- kWindowTitleBarRgn, &device, nil);
- dr = (*device)->gdRect;
- 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<nflavor; j++){
- type = (CFStringRef)CFArrayGetValueAtIndex(flavors, j);
- if(!UTTypeConformsTo(type, CFSTR("public.utf16-plain-text")))
- continue;
- if(PasteboardCopyItemFlavorData(clip.apple, id, type, &data) != noErr)
- continue;
- qunlock(&clip.lk);
- ndata = CFDataGetLength(data)/2;
- u = (u16int*)CFDataGetBytePtr(data);
- fmtstrinit(&fmt);
- // decode utf-16. what was apple thinking?
- for(i=0; i<ndata; i++) {
- r = u[i];
- if(0xd800 <= r && r < 0xdc00 && i+1 < ndata && 0xdc00 <= u[i+1] && u[i+1] < 0xe000) {
- r = (((r - 0xd800)<<10) | (u[i+1] - 0xdc00)) + 0x10000;
- i++;
- }
- else if(0xd800 <= r && r < 0xe000)
- r = Runeerror;
- if(r == '\r')
- r = '\n';
- fmtrune(&fmt, r);
- }
- CFRelease(flavors);
- CFRelease(data);
- return fmtstrflush(&fmt);
- }
- CFRelease(flavors);
- }
- qunlock(&clip.lk);
- return nil;
-}
-
-void
-putsnarf(char *s)
-{
- CFDataRef cfdata;
- PasteboardSyncFlags flags;
- u16int *u, *p;
- Rune r;
- int i;
-
-/* fprint(2, "appleputsnarf\n"); */
-
- if(strlen(s) >= 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 f50d8dfe..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*);
-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 6cbb5235..00000000
--- a/src/cmd/devdraw/osx-srv.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Window system protocol server.
- */
-
-#include <u.h>
-#include <errno.h>
-#include <sys/select.h>
-#include <libc.h>
-#include <thread.h>
-#include <draw.h>
-#include <memdraw.h>
-#include <memlayer.h>
-#include <keyboard.h>
-#include <mouse.h>
-#include <cursor.h>
-#include <drawfcall.h>
-#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);
- else
- setcursor(&m->cursor);
- 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<nk; i++)
- kputc(k[i]);
- nk = 0;
- return;
- }
- // need more input
- return;
-}
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);
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(; i<argc; i++){
file = argv[i];
- t = tget(argv[i]);
- if(t)
+ t = tget(argv[i], 1);
+ if(t) {
+ nt = t->next;
+ 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);
}
diff --git a/src/cmd/file.c b/src/cmd/file.c
index 0afb9ba3..32d580cd 100644
--- a/src/cmd/file.c
+++ b/src/cmd/file.c
@@ -519,10 +519,13 @@ 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",
+ 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
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/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++) {
diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c
index a097ca4d..4137f9ca 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;
@@ -66,21 +66,18 @@ 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->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;
@@ -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
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 <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <keyboard.h>
+
+/* 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 <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <keyboard.h>
+
+/* 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; i<NBRUSH; i++){
+ r.max.x = penr.min.x + (i+1)*Dx(penr) / NBRUSH;
+ rr = r;
+ if(i == brush)
+ rr.min.y += Dy(r)/3;
+ if(i == NBRUSH-1){
+ /* last is special brush for fill draw */
+ draw(screen, rr, ink, nil, ZP);
+ } else {
+ rr.min = addpt(rr.min, divpt(subpt(rr.max, rr.min), 2));
+ rr.max = rr.min;
+ strokedraw(screen, rr, ink, i);
+ }
+ r.min.x = r.max.x;
+ }
+
+ r = palr;
+ for(i=1; i<=nelem(pal); i++){
+ r.max.x = palr.min.x + i*Dx(palr) / nelem(pal);
+ rr = r;
+ if(ink == pal[i-1])
+ rr.min.y += Dy(r)/3;
+ draw(screen, rr, pal[i-1], nil, ZP);
+ gendrawdiff(screen, r, rr, back, ZP, nil, ZP, SoverD);
+ r.min.x = r.max.x;
+ }
+
+ r = screen->r;
+ 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; i<nelem(pal); i++){
+ pal[i] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1,
+ c64[i % nelem(c64)]<<8 | 0xFF);
+ if(pal[i] == nil)
+ sysfatal("allocimage: %r");
+ }
+ ink = pal[0];
+ back = pal[1];
+ drawpal();
+ center();
+
+ einit(Emouse | Ekeyboard);
+
+ notify(catch);
+ for(;;) {
+ switch(event(&e)){
+ case Emouse:
+ if(hitpal(e.mouse))
+ continue;
+
+ img = ink;
+ switch(e.mouse.buttons & 7){
+ case 2:
+ img = back;
+ /* no break */
+ case 1:
+ p = s2c(e.mouse.xy);
+ if(brush == NBRUSH-1){
+ /* flood fill brush */
+ if(canvas == nil || !ptinrect(p, canvas->r)){
+ 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);
+}
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
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;
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 <ndb.h>
#include "smtp.h" /* to publish dial_string_parse */
#include <ip.h>
+#include <thread.h>
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);
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; i<f->nsubf; i++){
s = f->subf[i].f;
- if(s && (!display || s!=display->defaultsubfont))
+ if(s)
freesubfont(s);
}
freeimage(f->cacheimage);
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 <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <cursor.h>
+
+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/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 <u.h>
-#include <libc.h>
-#include <draw.h>
-
-/*
- * 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/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/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->age<SUBFAGE && s->cf->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 <u.h>
-#include <libc.h>
-#include <draw.h>
-
-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 <u.h>
#include <libc.h>
#include <draw.h>
+#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<<f->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 ddb0e833..fab6295b 100644
--- a/src/libdraw/mkfile
+++ b/src/libdraw/mkfile
@@ -14,8 +14,8 @@ OFILES=\
cloadimage.$O\
computil.$O\
creadimage.$O\
+ cursor.$O\
debug.$O\
- defont.$O\
draw.$O\
drawclient.$O\
drawfcall.$O\
@@ -26,7 +26,6 @@ OFILES=\
event.$O\
font.$O\
freesubfont.$O\
- getdefont.$O\
getrect.$O\
getsubfont.$O\
icossin.$O\
@@ -71,5 +70,7 @@ HFILES=\
$PLAN9/include/mouse.h\
$PLAN9/include/keyboard.h\
+getsubfont.$O: defont.h
+
<$PLAN9/src/mksyslib
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);
}
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 <u.h>
-#include <libc.h>
-#include <draw.h>
-#include <memdraw.h>
-
-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\
diff --git a/unix/mkfile b/unix/mkfile
index 245ea2ed..1c4319c6 100644
--- a/unix/mkfile
+++ b/unix/mkfile
@@ -38,15 +38,15 @@ test-%:V:
lib%.tgz:V:
mk new-$stem
- tar cf - lib$stem | gzip > $target
+ tar cf /dev/stdout lib$stem | gzip > $target
libregexp9.tgz:V:
mk new-regexp
- tar cf - libregexp | gzip >$target
+ tar cf /dev/stdout libregexp | gzip >$target
mk.tgz:V:
mk new-mk
- tar cf - mk | gzip > $target
+ tar cf /dev/stdout mk | gzip > $target
mk-with-libs.tgz:V:
mk new-utf
@@ -59,7 +59,7 @@ mk-with-libs.tgz:V:
mv libutf libfmt libbio libregexp mk zot
mv zot mk
cp make/Makefile.all mk/Makefile
- tar cf - mk | gzip > $target
+ tar cf /dev/stdout mk | gzip > $target
rm -r mk
tgz:V: libutf.tgz libfmt.tgz libregexp9.tgz libbio.tgz mk.tgz mk-with-libs.tgz