New 9term using rio sources more directly.
This commit is contained in:
parent
a6c0ff35ee
commit
e830a90849
10 changed files with 2963 additions and 1842 deletions
File diff suppressed because it is too large
Load diff
243
src/cmd/9term/dat.h
Normal file
243
src/cmd/9term/dat.h
Normal file
|
|
@ -0,0 +1,243 @@
|
||||||
|
#define STACK 32768
|
||||||
|
#undef Borderwidth
|
||||||
|
#define Borderwidth 0
|
||||||
|
|
||||||
|
typedef struct Consreadmesg Consreadmesg;
|
||||||
|
typedef struct Conswritemesg Conswritemesg;
|
||||||
|
typedef struct Stringpair Stringpair;
|
||||||
|
typedef struct Dirtab Dirtab;
|
||||||
|
typedef struct Mouseinfo Mouseinfo;
|
||||||
|
typedef struct Mousereadmesg Mousereadmesg;
|
||||||
|
typedef struct Mousestate Mousestate;
|
||||||
|
typedef struct Timer Timer;
|
||||||
|
typedef struct Wctlmesg Wctlmesg;
|
||||||
|
typedef struct Window Window;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Selborder = 0, /* border of selected window */
|
||||||
|
Unselborder = 0, /* border of unselected window */
|
||||||
|
Scrollwid = 12, /* width of scroll bar */
|
||||||
|
Scrollgap = 4, /* gap right of scroll bar */
|
||||||
|
BIG = 3, /* factor by which window dimension can exceed screen */
|
||||||
|
TRUE = 1,
|
||||||
|
FALSE = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Kscrolloneup = KF|0x20,
|
||||||
|
Kscrollonedown = KF|0x21,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum /* control messages */
|
||||||
|
{
|
||||||
|
Wakeup,
|
||||||
|
Reshaped,
|
||||||
|
Moved,
|
||||||
|
Refresh,
|
||||||
|
Movemouse,
|
||||||
|
Rawon,
|
||||||
|
Rawoff,
|
||||||
|
Holdon,
|
||||||
|
Holdoff,
|
||||||
|
Deleted,
|
||||||
|
Exited,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Wctlmesg
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
Rectangle r;
|
||||||
|
Image *image;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Conswritemesg
|
||||||
|
{
|
||||||
|
Channel *cw; /* chan(Stringpair) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Consreadmesg
|
||||||
|
{
|
||||||
|
Channel *c1; /* chan(tuple(char*, int) == Stringpair) */
|
||||||
|
Channel *c2; /* chan(tuple(char*, int) == Stringpair) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mousereadmesg
|
||||||
|
{
|
||||||
|
Channel *cm; /* chan(Mouse) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stringpair /* rune and nrune or byte and nbyte */
|
||||||
|
{
|
||||||
|
void *s;
|
||||||
|
int ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mousestate
|
||||||
|
{
|
||||||
|
Mouse m;
|
||||||
|
ulong counter; /* serial no. of mouse event */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mouseinfo
|
||||||
|
{
|
||||||
|
Mousestate queue[16];
|
||||||
|
int ri; /* read index into queue */
|
||||||
|
int wi; /* write index */
|
||||||
|
ulong counter; /* serial no. of last mouse event we received */
|
||||||
|
ulong lastcounter; /* serial no. of last mouse event sent to client */
|
||||||
|
int lastb; /* last button state we received */
|
||||||
|
uchar qfull; /* filled the queue; no more recording until client comes back */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Window
|
||||||
|
{
|
||||||
|
Ref ref;
|
||||||
|
QLock lk;
|
||||||
|
Frame f;
|
||||||
|
Image *i;
|
||||||
|
Mousectl mc;
|
||||||
|
Mouseinfo mouse;
|
||||||
|
Channel *ck; /* chan(Rune[10]) */
|
||||||
|
Channel *cctl; /* chan(Wctlmesg)[20] */
|
||||||
|
Channel *conswrite; /* chan(Conswritemesg) */
|
||||||
|
Channel *consread; /* chan(Consreadmesg) */
|
||||||
|
Channel *mouseread; /* chan(Mousereadmesg) */
|
||||||
|
Channel *wctlread; /* chan(Consreadmesg) */
|
||||||
|
uint nr; /* number of runes in window */
|
||||||
|
uint maxr; /* number of runes allocated in r */
|
||||||
|
Rune *r;
|
||||||
|
uint nraw;
|
||||||
|
Rune *raw;
|
||||||
|
uint org;
|
||||||
|
uint q0;
|
||||||
|
uint q1;
|
||||||
|
uint qh;
|
||||||
|
int id;
|
||||||
|
char name[32];
|
||||||
|
uint namecount;
|
||||||
|
Rectangle scrollr;
|
||||||
|
/*
|
||||||
|
* Rio once used originwindow, so screenr could be different from i->r.
|
||||||
|
* Now they're always the same but the code doesn't assume so.
|
||||||
|
*/
|
||||||
|
Rectangle screenr; /* screen coordinates of window */
|
||||||
|
int resized;
|
||||||
|
int wctlready;
|
||||||
|
Rectangle lastsr;
|
||||||
|
int topped;
|
||||||
|
int notefd;
|
||||||
|
uchar scrolling;
|
||||||
|
Cursor cursor;
|
||||||
|
Cursor *cursorp;
|
||||||
|
uchar holding;
|
||||||
|
uchar rawing;
|
||||||
|
uchar ctlopen;
|
||||||
|
uchar wctlopen;
|
||||||
|
uchar deleted;
|
||||||
|
uchar mouseopen;
|
||||||
|
char *label;
|
||||||
|
int pid;
|
||||||
|
char *dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
int winborder(Window*, Point);
|
||||||
|
void winctl(void*);
|
||||||
|
void winshell(void*);
|
||||||
|
Window* wlookid(int);
|
||||||
|
Window* wmk(Image*, Mousectl*, Channel*, Channel*, int);
|
||||||
|
Window* wpointto(Point);
|
||||||
|
Window* wtop(Point);
|
||||||
|
void wtopme(Window*);
|
||||||
|
void wbottomme(Window*);
|
||||||
|
char* wcontents(Window*, int*);
|
||||||
|
int wbswidth(Window*, Rune);
|
||||||
|
int wclickmatch(Window*, int, int, int, uint*);
|
||||||
|
int wclose(Window*);
|
||||||
|
int wctlmesg(Window*, int, Rectangle, Image*);
|
||||||
|
int wctlmesg(Window*, int, Rectangle, Image*);
|
||||||
|
uint wbacknl(Window*, uint, uint);
|
||||||
|
uint winsert(Window*, Rune*, int, uint);
|
||||||
|
void waddraw(Window*, Rune*, int);
|
||||||
|
void wborder(Window*, int);
|
||||||
|
void wclosewin(Window*);
|
||||||
|
void wcurrent(Window*);
|
||||||
|
void wcut(Window*);
|
||||||
|
void wdelete(Window*, uint, uint);
|
||||||
|
void wdoubleclick(Window*, uint*, uint*);
|
||||||
|
void wfill(Window*);
|
||||||
|
void wframescroll(Window*, int);
|
||||||
|
void wkeyctl(Window*, Rune);
|
||||||
|
void wmousectl(Window*);
|
||||||
|
void wmovemouse(Window*, Point);
|
||||||
|
void wpaste(Window*);
|
||||||
|
void wplumb(Window*);
|
||||||
|
void wrefresh(Window*, Rectangle);
|
||||||
|
void wrepaint(Window*);
|
||||||
|
void wresize(Window*, Image*, int);
|
||||||
|
void wscrdraw(Window*);
|
||||||
|
void wscroll(Window*, int);
|
||||||
|
void wselect(Window*);
|
||||||
|
void wsendctlmesg(Window*, int, Rectangle, Image*);
|
||||||
|
void wsetcursor(Window*, int);
|
||||||
|
void wsetname(Window*);
|
||||||
|
void wsetorigin(Window*, uint, int);
|
||||||
|
void wsetpid(Window*, int, int);
|
||||||
|
void wsetselect(Window*, uint, uint);
|
||||||
|
void wshow(Window*, uint);
|
||||||
|
void wsnarf(Window*);
|
||||||
|
void wscrsleep(Window*, uint);
|
||||||
|
void wsetcols(Window*);
|
||||||
|
|
||||||
|
void deletetimeoutproc(void*);
|
||||||
|
|
||||||
|
struct Timer
|
||||||
|
{
|
||||||
|
int dt;
|
||||||
|
int cancel;
|
||||||
|
Channel *c; /* chan(int) */
|
||||||
|
Timer *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef Extern
|
||||||
|
#define Extern extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Extern Font *font;
|
||||||
|
Extern Mousectl *mousectl;
|
||||||
|
Extern Mouse *mouse;
|
||||||
|
Extern Keyboardctl *keyboardctl;
|
||||||
|
Extern Display *display;
|
||||||
|
Extern Image *view;
|
||||||
|
Extern Screen *wscreen;
|
||||||
|
Extern Cursor boxcursor;
|
||||||
|
Extern Cursor crosscursor;
|
||||||
|
Extern Cursor sightcursor;
|
||||||
|
Extern Cursor whitearrow;
|
||||||
|
Extern Cursor query;
|
||||||
|
Extern Cursor *corners[9];
|
||||||
|
Extern Image *background;
|
||||||
|
Extern Image *lightgrey;
|
||||||
|
Extern Image *red;
|
||||||
|
Extern Window **window;
|
||||||
|
Extern Window *wkeyboard; /* window of simulated keyboard */
|
||||||
|
Extern int nwindow;
|
||||||
|
Extern int snarffd;
|
||||||
|
Extern Window *input;
|
||||||
|
Extern QLock all; /* BUG */
|
||||||
|
Extern Window *hidden[100];
|
||||||
|
Extern int nhidden;
|
||||||
|
Extern int nsnarf;
|
||||||
|
Extern Rune* snarf;
|
||||||
|
Extern int scrolling;
|
||||||
|
Extern int maxtab;
|
||||||
|
Extern Channel* winclosechan;
|
||||||
|
Extern Channel* deletechan;
|
||||||
|
Extern char *startdir;
|
||||||
|
Extern int sweeping;
|
||||||
|
Extern int wctlfd;
|
||||||
|
Extern int errorshouldabort;
|
||||||
|
Extern int menuing; /* menu action is pending; waiting for window to be indicated */
|
||||||
|
Extern int snarfversion; /* updated each time it is written */
|
||||||
|
Extern int messagesize; /* negotiated in 9P version setup */
|
||||||
180
src/cmd/9term/data.c
Normal file
180
src/cmd/9term/data.c
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <frame.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
Cursor crosscursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
|
||||||
|
0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
|
||||||
|
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, },
|
||||||
|
{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||||
|
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
|
||||||
|
0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||||
|
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor boxcursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
|
||||||
|
0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||||||
|
{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
|
||||||
|
0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
|
||||||
|
0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
|
||||||
|
0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor sightcursor = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
|
||||||
|
0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
|
||||||
|
0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, },
|
||||||
|
{0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
|
||||||
|
0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
|
||||||
|
0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
|
||||||
|
0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor whitearrow = {
|
||||||
|
{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, },
|
||||||
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C,
|
||||||
|
0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C,
|
||||||
|
0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C,
|
||||||
|
0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor query = {
|
||||||
|
{-7,-7},
|
||||||
|
{0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe,
|
||||||
|
0x7c, 0x7e, 0x78, 0x7e, 0x00, 0xfc, 0x01, 0xf8,
|
||||||
|
0x03, 0xf0, 0x07, 0xe0, 0x07, 0xc0, 0x07, 0xc0,
|
||||||
|
0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, },
|
||||||
|
{0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xf8, 0x3c, 0x3c,
|
||||||
|
0x38, 0x1c, 0x00, 0x3c, 0x00, 0x78, 0x00, 0xf0,
|
||||||
|
0x01, 0xe0, 0x03, 0xc0, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor tl = {
|
||||||
|
{-4, -4},
|
||||||
|
{0xfe, 0x00, 0x82, 0x00, 0x8c, 0x00, 0x87, 0xff,
|
||||||
|
0xa0, 0x01, 0xb0, 0x01, 0xd0, 0x01, 0x11, 0xff,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1f, 0x00, },
|
||||||
|
{0x00, 0x00, 0x7c, 0x00, 0x70, 0x00, 0x78, 0x00,
|
||||||
|
0x5f, 0xfe, 0x4f, 0xfe, 0x0f, 0xfe, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor t = {
|
||||||
|
{-7, -8},
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x06, 0xc0,
|
||||||
|
0x1c, 0x70, 0x10, 0x10, 0x0c, 0x60, 0xfc, 0x7f,
|
||||||
|
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||||
|
0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor tr = {
|
||||||
|
{-11, -4},
|
||||||
|
{0x00, 0x7f, 0x00, 0x41, 0x00, 0x31, 0xff, 0xe1,
|
||||||
|
0x80, 0x05, 0x80, 0x0d, 0x80, 0x0b, 0xff, 0x88,
|
||||||
|
0x00, 0x88, 0x0, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xf8, },
|
||||||
|
{0x00, 0x00, 0x00, 0x3e, 0x00, 0x0e, 0x00, 0x1e,
|
||||||
|
0x7f, 0xfa, 0x7f, 0xf2, 0x7f, 0xf0, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor r = {
|
||||||
|
{-8, -7},
|
||||||
|
{0x07, 0xc0, 0x04, 0x40, 0x04, 0x40, 0x04, 0x58,
|
||||||
|
0x04, 0x68, 0x04, 0x6c, 0x04, 0x06, 0x04, 0x02,
|
||||||
|
0x04, 0x06, 0x04, 0x6c, 0x04, 0x68, 0x04, 0x58,
|
||||||
|
0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x07, 0xc0, },
|
||||||
|
{0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80,
|
||||||
|
0x03, 0x90, 0x03, 0x90, 0x03, 0xf8, 0x03, 0xfc,
|
||||||
|
0x03, 0xf8, 0x03, 0x90, 0x03, 0x90, 0x03, 0x80,
|
||||||
|
0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor br = {
|
||||||
|
{-11, -11},
|
||||||
|
{0x00, 0xf8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88,
|
||||||
|
0xff, 0x88, 0x80, 0x0b, 0x80, 0x0d, 0x80, 0x05,
|
||||||
|
0xff, 0xe1, 0x00, 0x31, 0x00, 0x41, 0x00, 0x7f, },
|
||||||
|
{0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70,
|
||||||
|
0x00, 0x70, 0x7f, 0xf0, 0x7f, 0xf2, 0x7f, 0xfa,
|
||||||
|
0x00, 0x1e, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor b = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||||
|
0xfc, 0x7f, 0x0c, 0x60, 0x10, 0x10, 0x1c, 0x70,
|
||||||
|
0x06, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, },
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe,
|
||||||
|
0x03, 0x80, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor bl = {
|
||||||
|
{-4, -11},
|
||||||
|
{0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00,
|
||||||
|
0x11, 0xff, 0xd0, 0x01, 0xb0, 0x01, 0xa0, 0x01,
|
||||||
|
0x87, 0xff, 0x8c, 0x00, 0x82, 0x00, 0xfe, 0x00, },
|
||||||
|
{0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00,
|
||||||
|
0x0e, 0x00, 0x0f, 0xfe, 0x4f, 0xfe, 0x5f, 0xfe,
|
||||||
|
0x78, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x00, 0x0, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor l = {
|
||||||
|
{-7, -7},
|
||||||
|
{0x03, 0xe0, 0x02, 0x20, 0x02, 0x20, 0x1a, 0x20,
|
||||||
|
0x16, 0x20, 0x36, 0x20, 0x60, 0x20, 0x40, 0x20,
|
||||||
|
0x60, 0x20, 0x36, 0x20, 0x16, 0x20, 0x1a, 0x20,
|
||||||
|
0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x03, 0xe0, },
|
||||||
|
{0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0,
|
||||||
|
0x09, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x3f, 0xc0,
|
||||||
|
0x1f, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x01, 0xc0,
|
||||||
|
0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, }
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor *corners[9] = {
|
||||||
|
&tl, &t, &tr,
|
||||||
|
&l, nil, &r,
|
||||||
|
&bl, &b, &br,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
iconinit(void)
|
||||||
|
{
|
||||||
|
background = allocimage(display, Rect(0,0,1,1), RGB24, 1, 0x777777FF);
|
||||||
|
red = allocimage(display, Rect(0,0,1,1), RGB24, 1, 0xDD0000FF);
|
||||||
|
}
|
||||||
36
src/cmd/9term/fns.h
Normal file
36
src/cmd/9term/fns.h
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#undef isalnum
|
||||||
|
#define isalnum runeisalnum
|
||||||
|
|
||||||
|
void keyboardsend(char*, int);
|
||||||
|
int whide(Window*);
|
||||||
|
int wunhide(int);
|
||||||
|
void freescrtemps(void);
|
||||||
|
int parsewctl(char**, Rectangle, Rectangle*, int*, int*, int*, int*, char**, char*, char*);
|
||||||
|
Window *new(Image*, int, int, int, char*, char*, char**);
|
||||||
|
void riosetcursor(Cursor*, int);
|
||||||
|
int min(int, int);
|
||||||
|
int max(int, int);
|
||||||
|
Rune* strrune(Rune*, Rune);
|
||||||
|
int isalnum(Rune);
|
||||||
|
void timerstop(Timer*);
|
||||||
|
void timercancel(Timer*);
|
||||||
|
Timer* timerstart(int);
|
||||||
|
void error(char*);
|
||||||
|
void killprocs(void);
|
||||||
|
int shutdown(void*, char*);
|
||||||
|
void iconinit(void);
|
||||||
|
void *erealloc(void*, uint);
|
||||||
|
void *emalloc(uint);
|
||||||
|
char *estrdup(char*);
|
||||||
|
void button3menu(void);
|
||||||
|
void button2menu(Window*);
|
||||||
|
void cvttorunes(char*, int, Rune*, int*, int*, int*);
|
||||||
|
/* was (byte*,int) runetobyte(Rune*, int); */
|
||||||
|
char* runetobyte(Rune*, int, int*);
|
||||||
|
void timerinit(void);
|
||||||
|
int goodrect(Rectangle);
|
||||||
|
int rawon(void);
|
||||||
|
|
||||||
|
#define runemalloc(n) malloc((n)*sizeof(Rune))
|
||||||
|
#define runerealloc(a, n) realloc(a, (n)*sizeof(Rune))
|
||||||
|
#define runemove(a, b, n) memmove(a, b, (n)*sizeof(Rune))
|
||||||
63
src/cmd/9term/malloc.c
Normal file
63
src/cmd/9term/malloc.c
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* These are here mainly so that I can link against
|
||||||
|
* debugmalloc.c instead and not recompile the world.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
static Lock malloclock;
|
||||||
|
|
||||||
|
void*
|
||||||
|
p9malloc(ulong n)
|
||||||
|
{
|
||||||
|
void *v;
|
||||||
|
|
||||||
|
if(n == 0)
|
||||||
|
n++;
|
||||||
|
lock(&malloclock);
|
||||||
|
v = malloc(n);
|
||||||
|
unlock(&malloclock);
|
||||||
|
print("p9malloc %lud => %p; pc %lux\n", n, v, getcallerpc(&n));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
p9free(void *v)
|
||||||
|
{
|
||||||
|
if(v == nil)
|
||||||
|
return;
|
||||||
|
lock(&malloclock);
|
||||||
|
print("p9free %p; pc %lux\n", v, getcallerpc(&v));
|
||||||
|
free(v);
|
||||||
|
unlock(&malloclock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
p9calloc(ulong a, ulong b)
|
||||||
|
{
|
||||||
|
void *v;
|
||||||
|
|
||||||
|
if(a*b == 0)
|
||||||
|
a = b = 1;
|
||||||
|
|
||||||
|
lock(&malloclock);
|
||||||
|
v = calloc(a*b, 1);
|
||||||
|
unlock(&malloclock);
|
||||||
|
print("p9calloc %lud %lud => %p; pc %lux\n", a, b, v, getcallerpc(&a));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
p9realloc(void *v, ulong n)
|
||||||
|
{
|
||||||
|
void *vv;
|
||||||
|
|
||||||
|
lock(&malloclock);
|
||||||
|
vv = realloc(v, n);
|
||||||
|
unlock(&malloclock);
|
||||||
|
print("p9realloc %p %lud => %p; pc %lux\n", v, n, vv, getcallerpc(&v));
|
||||||
|
return vv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -6,7 +6,11 @@ OFILES=\
|
||||||
rcstart.$O\
|
rcstart.$O\
|
||||||
$SYSNAME.$O\
|
$SYSNAME.$O\
|
||||||
|
|
||||||
|
HFILES=dat.h fns.h term.h
|
||||||
|
|
||||||
<$PLAN9/src/mkmany
|
<$PLAN9/src/mkmany
|
||||||
|
|
||||||
Darwin.$O Linux.$O FreeBSD.$O: bsdpty.c
|
Darwin.$O Linux.$O FreeBSD.$O: bsdpty.c
|
||||||
|
|
||||||
|
$O.9term: data.$O scrl.$O time.$O util.$O wind.$O
|
||||||
|
|
||||||
|
|
|
||||||
183
src/cmd/9term/scrl.c
Normal file
183
src/cmd/9term/scrl.c
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <frame.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
static Image *scrtmp;
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
scrtemps(void)
|
||||||
|
{
|
||||||
|
int h;
|
||||||
|
|
||||||
|
if(scrtmp)
|
||||||
|
return;
|
||||||
|
h = BIG*Dy(screen->r);
|
||||||
|
scrtmp = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, DWhite);
|
||||||
|
if(scrtmp == nil)
|
||||||
|
error("scrtemps");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freescrtemps(void)
|
||||||
|
{
|
||||||
|
freeimage(scrtmp);
|
||||||
|
scrtmp = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
Rectangle
|
||||||
|
scrpos(Rectangle r, uint p0, uint p1, uint tot)
|
||||||
|
{
|
||||||
|
Rectangle q;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
q = r;
|
||||||
|
h = q.max.y-q.min.y;
|
||||||
|
if(tot == 0)
|
||||||
|
return q;
|
||||||
|
if(tot > 1024*1024){
|
||||||
|
tot>>=10;
|
||||||
|
p0>>=10;
|
||||||
|
p1>>=10;
|
||||||
|
}
|
||||||
|
if(p0 > 0)
|
||||||
|
q.min.y += h*p0/tot;
|
||||||
|
if(p1 < tot)
|
||||||
|
q.max.y -= h*(tot-p1)/tot;
|
||||||
|
if(q.max.y < q.min.y+2){
|
||||||
|
if(q.min.y+2 <= r.max.y)
|
||||||
|
q.max.y = q.min.y+2;
|
||||||
|
else
|
||||||
|
q.min.y = q.max.y-2;
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wscrdraw(Window *w)
|
||||||
|
{
|
||||||
|
Rectangle r, r1, r2;
|
||||||
|
Image *b;
|
||||||
|
|
||||||
|
scrtemps();
|
||||||
|
if(w->i == nil)
|
||||||
|
error("scrdraw");
|
||||||
|
r = w->scrollr;
|
||||||
|
b = scrtmp;
|
||||||
|
r1 = r;
|
||||||
|
r1.min.x = 0;
|
||||||
|
r1.max.x = Dx(r);
|
||||||
|
r2 = scrpos(r1, w->org, w->org+w->f.nchars, w->nr);
|
||||||
|
if(!eqrect(r2, w->lastsr)){
|
||||||
|
w->lastsr = r2;
|
||||||
|
/* move r1, r2 to (0,0) to avoid clipping */
|
||||||
|
r2 = rectsubpt(r2, r1.min);
|
||||||
|
r1 = rectsubpt(r1, r1.min);
|
||||||
|
draw(b, r1, w->f.cols[BORD], nil, ZP);
|
||||||
|
draw(b, r2, w->f.cols[BACK], nil, ZP);
|
||||||
|
r2.min.x = r2.max.x-1;
|
||||||
|
draw(b, r2, w->f.cols[BORD], nil, ZP);
|
||||||
|
draw(w->i, r, b, nil, Pt(0, r1.min.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wscrsleep(Window *w, uint dt)
|
||||||
|
{
|
||||||
|
Timer *timer;
|
||||||
|
int y, b;
|
||||||
|
static Alt alts[3];
|
||||||
|
|
||||||
|
timer = timerstart(dt);
|
||||||
|
y = w->mc.m.xy.y;
|
||||||
|
b = w->mc.m.buttons;
|
||||||
|
alts[0].c = timer->c;
|
||||||
|
alts[0].v = nil;
|
||||||
|
alts[0].op = CHANRCV;
|
||||||
|
alts[1].c = w->mc.c;
|
||||||
|
alts[1].v = &w->mc.m;
|
||||||
|
alts[1].op = CHANRCV;
|
||||||
|
alts[2].op = CHANEND;
|
||||||
|
for(;;)
|
||||||
|
switch(alt(alts)){
|
||||||
|
case 0:
|
||||||
|
timerstop(timer);
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
if(abs(w->mc.m.xy.y-y)>2 || w->mc.m.buttons!=b){
|
||||||
|
timercancel(timer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wscroll(Window *w, int but)
|
||||||
|
{
|
||||||
|
uint p0, oldp0;
|
||||||
|
Rectangle s;
|
||||||
|
int x, y, my, h, first;
|
||||||
|
|
||||||
|
s = insetrect(w->scrollr, 1);
|
||||||
|
h = s.max.y-s.min.y;
|
||||||
|
x = (s.min.x+s.max.x)/2;
|
||||||
|
oldp0 = ~0;
|
||||||
|
first = TRUE;
|
||||||
|
do{
|
||||||
|
flushimage(display, 1);
|
||||||
|
if(w->mc.m.xy.x<s.min.x || s.max.x<=w->mc.m.xy.x){
|
||||||
|
readmouse(&w->mc);
|
||||||
|
}else{
|
||||||
|
my = w->mc.m.xy.y;
|
||||||
|
if(my < s.min.y)
|
||||||
|
my = s.min.y;
|
||||||
|
if(my >= s.max.y)
|
||||||
|
my = s.max.y;
|
||||||
|
if(!eqpt(w->mc.m.xy, Pt(x, my))){
|
||||||
|
wmovemouse(w, Pt(x, my));
|
||||||
|
readmouse(&w->mc); /* absorb event generated by moveto() */
|
||||||
|
}
|
||||||
|
if(but == 2){
|
||||||
|
y = my;
|
||||||
|
if(y > s.max.y-2)
|
||||||
|
y = s.max.y-2;
|
||||||
|
if(w->nr > 1024*1024)
|
||||||
|
p0 = ((w->nr>>10)*(y-s.min.y)/h)<<10;
|
||||||
|
else
|
||||||
|
p0 = w->nr*(y-s.min.y)/h;
|
||||||
|
if(oldp0 != p0)
|
||||||
|
wsetorigin(w, p0, FALSE);
|
||||||
|
oldp0 = p0;
|
||||||
|
readmouse(&w->mc);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(but == 1)
|
||||||
|
p0 = wbacknl(w, w->org, (my-s.min.y)/w->f.font->height);
|
||||||
|
else
|
||||||
|
p0 = w->org+frcharofpt(&w->f, Pt(s.max.x, my));
|
||||||
|
if(oldp0 != p0)
|
||||||
|
wsetorigin(w, p0, TRUE);
|
||||||
|
oldp0 = p0;
|
||||||
|
/* debounce */
|
||||||
|
if(first){
|
||||||
|
flushimage(display, 1);
|
||||||
|
sleep(200);
|
||||||
|
nbrecv(w->mc.c, &w->mc.m);
|
||||||
|
first = FALSE;
|
||||||
|
}
|
||||||
|
wscrsleep(w, 100);
|
||||||
|
}
|
||||||
|
}while(w->mc.m.buttons & (1<<(but-1)));
|
||||||
|
while(w->mc.m.buttons)
|
||||||
|
readmouse(&w->mc);
|
||||||
|
}
|
||||||
125
src/cmd/9term/time.c
Normal file
125
src/cmd/9term/time.c
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <frame.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
static Channel* ctimer; /* chan(Timer*)[100] */
|
||||||
|
static Timer *timer;
|
||||||
|
|
||||||
|
static
|
||||||
|
uint
|
||||||
|
msec(void)
|
||||||
|
{
|
||||||
|
return nsec()/1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timerstop(Timer *t)
|
||||||
|
{
|
||||||
|
t->next = timer;
|
||||||
|
timer = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timercancel(Timer *t)
|
||||||
|
{
|
||||||
|
t->cancel = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
timerproc(void *a)
|
||||||
|
{
|
||||||
|
int i, nt, na, dt, del;
|
||||||
|
Timer **t, *x;
|
||||||
|
uint old, new;
|
||||||
|
|
||||||
|
USED(a);
|
||||||
|
rfork(RFFDG);
|
||||||
|
threadsetname("TIMERPROC");
|
||||||
|
t = nil;
|
||||||
|
na = 0;
|
||||||
|
nt = 0;
|
||||||
|
old = msec();
|
||||||
|
for(;;){
|
||||||
|
sleep(1); /* will sleep minimum incr */
|
||||||
|
new = msec();
|
||||||
|
dt = new-old;
|
||||||
|
old = new;
|
||||||
|
if(dt < 0) /* timer wrapped; go around, losing a tick */
|
||||||
|
continue;
|
||||||
|
for(i=0; i<nt; i++){
|
||||||
|
x = t[i];
|
||||||
|
x->dt -= dt;
|
||||||
|
del = 0;
|
||||||
|
if(x->cancel){
|
||||||
|
timerstop(x);
|
||||||
|
del = 1;
|
||||||
|
}else if(x->dt <= 0){
|
||||||
|
/*
|
||||||
|
* avoid possible deadlock if client is
|
||||||
|
* now sending on ctimer
|
||||||
|
*/
|
||||||
|
if(nbsendul(x->c, 0) > 0)
|
||||||
|
del = 1;
|
||||||
|
}
|
||||||
|
if(del){
|
||||||
|
memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
|
||||||
|
--nt;
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nt == 0){
|
||||||
|
x = recvp(ctimer);
|
||||||
|
gotit:
|
||||||
|
if(nt == na){
|
||||||
|
na += 10;
|
||||||
|
t = realloc(t, na*sizeof(Timer*));
|
||||||
|
if(t == nil)
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
t[nt++] = x;
|
||||||
|
old = msec();
|
||||||
|
}
|
||||||
|
if(nbrecv(ctimer, &x) > 0)
|
||||||
|
goto gotit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timerinit(void)
|
||||||
|
{
|
||||||
|
ctimer = chancreate(sizeof(Timer*), 100);
|
||||||
|
proccreate(timerproc, nil, STACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* timeralloc() and timerfree() don't lock, so can only be
|
||||||
|
* called from the main proc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Timer*
|
||||||
|
timerstart(int dt)
|
||||||
|
{
|
||||||
|
Timer *t;
|
||||||
|
|
||||||
|
t = timer;
|
||||||
|
if(t)
|
||||||
|
timer = timer->next;
|
||||||
|
else{
|
||||||
|
t = emalloc(sizeof(Timer));
|
||||||
|
t->c = chancreate(sizeof(int), 0);
|
||||||
|
}
|
||||||
|
t->next = nil;
|
||||||
|
t->dt = dt;
|
||||||
|
t->cancel = FALSE;
|
||||||
|
sendp(ctimer, t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
149
src/cmd/9term/util.c
Normal file
149
src/cmd/9term/util.c
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <frame.h>
|
||||||
|
#include <fcall.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fns.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
|
||||||
|
{
|
||||||
|
uchar *q;
|
||||||
|
Rune *s;
|
||||||
|
int j, w;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always guaranteed that n bytes may be interpreted
|
||||||
|
* without worrying about partial runes. This may mean
|
||||||
|
* reading up to UTFmax-1 more bytes than n; the caller
|
||||||
|
* knows this. If n is a firm limit, the caller should
|
||||||
|
* set p[n] = 0.
|
||||||
|
*/
|
||||||
|
q = (uchar*)p;
|
||||||
|
s = r;
|
||||||
|
for(j=0; j<n; j+=w){
|
||||||
|
if(*q < Runeself){
|
||||||
|
w = 1;
|
||||||
|
*s = *q++;
|
||||||
|
}else{
|
||||||
|
w = chartorune(s, (char*)q);
|
||||||
|
q += w;
|
||||||
|
}
|
||||||
|
if(*s)
|
||||||
|
s++;
|
||||||
|
else if(nulls)
|
||||||
|
*nulls = TRUE;
|
||||||
|
}
|
||||||
|
*nb = (char*)q-p;
|
||||||
|
*nr = s-r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
error(char *s)
|
||||||
|
{
|
||||||
|
fprint(2, "rio: %s: %r\n", s);
|
||||||
|
if(errorshouldabort)
|
||||||
|
abort();
|
||||||
|
threadexitsall("error");
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
erealloc(void *p, uint n)
|
||||||
|
{
|
||||||
|
p = realloc(p, n);
|
||||||
|
if(p == nil)
|
||||||
|
error("realloc failed");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
emalloc(uint n)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = malloc(n);
|
||||||
|
if(p == nil)
|
||||||
|
error("malloc failed");
|
||||||
|
memset(p, 0, n);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
estrdup(char *s)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = malloc(strlen(s)+1);
|
||||||
|
if(p == nil)
|
||||||
|
error("strdup failed");
|
||||||
|
strcpy(p, s);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
isalnum(Rune c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Hard to get absolutely right. Use what we know about ASCII
|
||||||
|
* and assume anything above the Latin control characters is
|
||||||
|
* potentially an alphanumeric.
|
||||||
|
*/
|
||||||
|
if(c <= ' ')
|
||||||
|
return FALSE;
|
||||||
|
if(0x7F<=c && c<=0xA0)
|
||||||
|
return FALSE;
|
||||||
|
if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rune*
|
||||||
|
strrune(Rune *s, Rune c)
|
||||||
|
{
|
||||||
|
Rune c1;
|
||||||
|
|
||||||
|
if(c == 0) {
|
||||||
|
while(*s++)
|
||||||
|
;
|
||||||
|
return s-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(c1 = *s++)
|
||||||
|
if(c1 == c)
|
||||||
|
return s-1;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
min(int a, int b)
|
||||||
|
{
|
||||||
|
if(a < b)
|
||||||
|
return a;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
max(int a, int b)
|
||||||
|
{
|
||||||
|
if(a > b)
|
||||||
|
return a;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
runetobyte(Rune *r, int n, int *ip)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
int m;
|
||||||
|
|
||||||
|
s = emalloc(n*UTFmax+1);
|
||||||
|
m = snprint(s, n*UTFmax+1, "%.*S", n, r);
|
||||||
|
*ip = m;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
1628
src/cmd/9term/wind.c
Normal file
1628
src/cmd/9term/wind.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue