📄 yabasic.c
字号:
break;
}
#elif WINDOWS
GetConsoleMode(ConsoleInput,&oflags);
flags=oflags&~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT);
SetConsoleMode(ConsoleInput,flags);
skey="";
if (ms==0) {
PeekConsoleInput(ConsoleInput,&inrec,1,&num);
if (num==0) goto keydone;
ReadConsoleInput(ConsoleInput,&inrec,1,&num);
if (!is_valid_key(&inrec)) goto keydone;
}
else if (ms>0) {
end=GetTickCount()+ms;
do {
now=GetTickCount();
left=end-now;
if (left>0) {
ret=WaitForSingleObject(ConsoleInput,left);
if (ret==WAIT_OBJECT_0) ReadConsoleInput(ConsoleInput,&inrec,1,&num);
}
} while(left>0 && ret==WAIT_OBJECT_0 && !is_valid_key(&inrec));
if (left<=0 || ret!=WAIT_OBJECT_0) goto keydone;
}
else { /* if (ms<0) */
do {
ReadConsoleInput(ConsoleInput,&inrec,1,&num);
} while(!is_valid_key(&inrec));
}
skey=keybuff;
if (isprint(inrec.Event.KeyEvent.uChar.AsciiChar)) {
keybuff[0]=inrec.Event.KeyEvent.uChar.AsciiChar;
keybuff[1]='\0';
}
else {
key=inrec.Event.KeyEvent.wVirtualKeyCode;
switch(key) {
case 0x1b: skey="esc";break;
case 0x0d: skey="enter";break;
case 0x09: skey="tab";break;
case 0x21: skey="scrnup";break;
case 0x22: skey="scrndown";break;
case 0x70: skey="f1";break;
case 0x71: skey="f2";break;
case 0x72: skey="f3";break;
case 0x73: skey="f4";break;
case 0x74: skey="f5";break;
case 0x75: skey="f6";break;
case 0x76: skey="f7";break;
case 0x77: skey="f8";break;
case 0x78: skey="f9";break;
case 0x79: skey="f10";break;
case 0x7a: skey="f11";break;
case 0x7b: skey="f12";break;
case 0x24: skey="home";break;
case 0x23: skey="end";break;
case 0x2d: skey="ins";break;
case 0x2e: skey="del";break;
case 0x08: skey="backspace";break;
case 0x27: skey="right";break;
case 0x25: skey="left";break;
case 0x28: skey="down";break;
case 0x26: skey="up";break;
default:
sprintf(keybuff,"key%02x",key);
}
}
keydone:
SetConsoleMode(ConsoleInput,oflags);
#endif
return my_strdup(skey);
}
#ifdef WINDOWS
int is_valid_key(INPUT_RECORD *rec) /* check if input rec contains valid key */
{
if (rec->EventType!=KEY_EVENT ||
!rec->Event.KeyEvent.bKeyDown ||
rec->Event.KeyEvent.wVirtualKeyCode==VK_SHIFT ||
rec->Event.KeyEvent.wVirtualKeyCode==VK_CONTROL) {
return FALSE;
}
return TRUE;
}
#endif
void create_openwin(int fnt) /* create Command 'openwin' */
{
struct command *cmd;
cmd=add_command(cOPENWIN);
cmd->args=fnt;
}
void openwin(struct command *cmd) /* open a Window */
{
int fnt;
static int first=TRUE; /* flag to decide if initialization is necessary */
#ifdef UNIX
static XEvent event; /* what has happened ? */
XSetWindowAttributes attrib; /* properties of window */
#endif
if (winopened) {
error(WARNING,"Window already open");
return;
}
fnt=cmd->args;
if (fnt) font=my_strdup(pop()->pointer);
winheight=(int)pop()->value;
if (winheight<1) {
error(ERROR,"winheight less than 1 pixel");
return;
}
winwidth=(int)pop()->value;
if (winwidth<1) {
error(ERROR,"winwidth less than 1 pixel");
return;
}
/* initialize grafics */
if (first && !grafinit()) return;
#ifdef UNIX
/* create the window */
/* window=XCreateSimpleWindow(display,root,winx,winy,winwidth,winheight,
0,0,b_colour); */
attrib.backing_store=Always;
attrib.save_under=TRUE;
attrib.background_pixel=b_colour;
window=XCreateWindow(display,root,winx,winy,winwidth,winheight,0,
CopyFromParent,CopyFromParent,CopyFromParent,
CWBackingStore|CWSaveUnder|CWBackPixel,
&attrib);
if (window==None) {
error(ERROR,"Could not create window");
return;
}
/* put in name for the window */
XStoreName(display,window,progname);
/* set size hints */
XSetWMNormalHints(display,window,&sizehints);
/* display it */
XMapWindow(display,window);
/* wait for exposure */
XSelectInput(display,window,0xffffff);
XFlush(display);
do {
XNextEvent(display,&event);
} while(event.type!=VisibilityNotify);
XSelectInput(display,window,0);
#else /* WINDOWS */
if (wtevent==INVALID_HANDLE_VALUE) wtevent=CreateEvent(NULL,FALSE,FALSE,"winevent");
ResetEvent(wtevent);
/* create thread to care for window */
wthandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)winthread,
0,0,(LPDWORD)&wtid);
if (wthandle==NULL) {
error(ERROR,"can't create thread for window");
return;
}
WaitForSingleObject(wtevent,INFINITE);
#endif
first=FALSE;
winopened=TRUE;
calc_psscale();
}
int grafinit(void) /* initialize grafics (either X or WIN95) */
{
#ifdef UNIX
static int screen; /* Number of Screen on Display */
static XColor asked,got; /* color is complex ... */
static Colormap map; /* my color map */
static XGCValues xgcvalues; /* Values for Graphics Context */
static unsigned int w,h; /* width and height of window */
#elif WINDOWS
int n;
int f; /* int-value of font */
char *family; /* font family */
#endif
#ifdef UNIX
/* get display */
display=XOpenDisplay(displayname);
if (display==NULL) {
error(ERROR,"Can't open Display");
return FALSE;
}
/* get screen */
screen=DefaultScreen(display);
root=RootWindow(display,screen);
/* care for colors */
if (DefaultDepth(display,screen)==1) { /* BW-Screen ? */
f_colour=BlackPixel(display,screen);
b_colour=WhitePixel(display,screen); }
else {
map=DefaultColormap(display,screen);
if (foreground==NULL)
foreground=XGetDefault(display,"yabasic","foreground");
if (foreground==NULL) foreground="black";
if (!XAllocNamedColor(display,map,foreground,&got,&asked)) {
sprintf(string,"could not get fg-color '%s', trying 'black' instead",
foreground);
error(WARNING,string);
if (!XAllocNamedColor(display,map,"black",&got,&asked)) {
error(ERROR,"could not get it");
return FALSE;
}
}
f_colour=got.pixel;
if (background==NULL)
background=XGetDefault(display,"yabasic","background");
if (background==NULL) background="white";
if (!XAllocNamedColor(display,map,background,&got,&asked)) {
sprintf(string,"could not get bg-color '%s', trying 'white' instead",
background);
error(WARNING,string);
if (!XAllocNamedColor(display,map,"white", &got,&asked)) {
error(ERROR,"could not get it");
return FALSE;
}
}
b_colour=got.pixel;
}
/* get size hints */
if (geometry==NULL) geometry=XGetDefault(display,"yabasic","geometry");
XParseGeometry(geometry,&winx,&winy,&w,&h);
sizehints.x=winx;
sizehints.y=winy;
sizehints.flags=USPosition;
/* get font height */
if (!font) font=XGetDefault(display,"yabasic","font");
if (!font) font="6x10";
myfont=XLoadQueryFont(display,font);
if (!myfont) {
sprintf(string,"could not load font '%s', trying 'fixed' instead",font);
error(WARNING,string);
myfont=XLoadQueryFont(display,"fixed");
if (!myfont) {
error(ERROR,"could not get it");
return FALSE;
}
}
xgcvalues.font=myfont->fid;
fontheight=myfont->ascent;
/* create graphics context, accept defaults ... */
xgcvalues.foreground=f_colour;
xgcvalues.background=b_colour;
gc=XCreateGC(display,root,GCForeground|GCBackground|GCFont,&xgcvalues);
/* create graphics context for reverse drawing */
xgcvalues.foreground=b_colour;
xgcvalues.background=f_colour;
rgc=XCreateGC(display,root,GCForeground|GCBackground,&xgcvalues);
#elif WINDOWS
/* choose font */
if (!font) font=getreg("font");
if (!font) font="swiss13";
f=FF_SWISS;
fontheight=13;
family=my_strdup(font);
for(n=0;*(family+n)!='\0' && !isdigit(*(family+n));n++)
*(family+n)=tolower((int)*(family+n));
if (isdigit(*(family+n))) sscanf(family+n,"%d",&fontheight);
*(family+n)='\0';
if (!strcmp("decorative",family)) f=FF_DECORATIVE;
else if (!strcmp("dontcare",family)) f=FF_DONTCARE;
else if (!strcmp("modern",family)) f=FF_MODERN;
else if (!strcmp("roman",family)) f=FF_ROMAN;
else if (!strcmp("script",family)) f=FF_SCRIPT;
else if (!strcmp("swiss",family)) f=FF_SWISS;
else {
sprintf(string,"Don't know font '%s' using 'swiss' instead",font);
error(WARNING,string);
f=FF_SWISS;
}
logfont.lfHeight=-fontheight;
logfont.lfWidth=0;
logfont.lfEscapement=0;
logfont.lfOrientation=0;
logfont.lfWeight=FW_DONTCARE;
logfont.lfItalic=FALSE;
logfont.lfUnderline=FALSE;
logfont.lfStrikeOut=FALSE;
logfont.lfCharSet=DEFAULT_CHARSET;
logfont.lfOutPrecision=OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
logfont.lfQuality=DEFAULT_QUALITY;
logfont.lfPitchAndFamily=DEFAULT_PITCH | f;
logfont.lfFaceName[0]='\0';
myfont=CreateFontIndirect(&logfont);
if (myfont==NULL) {
sprintf(string,"Could not create font '%s' for screen",font);
error(ERROR,string);
return FALSE;
}
#endif
return TRUE;
}
void calc_psscale() /* calculate scale-factor for postscript */
{
if ((float)winwidth/winheight>(float)18/25)
psscale=18*0.39*72/winwidth;
else
psscale=25*0.39*72/winheight;
}
void dot() /* draw a dot */
{
double x,y;
y=pop()->value;
x=pop()->value;
transform(&x,&y);
if (!winopened) {
error(ERROR,"Got no window to draw");
return;
}
#ifdef UNIX
XDrawPoint(display,window,gc,x,y);
XFlush(display);
if (printerfile) {
fprintf(printerfile,"%g %g D\n",
(x-0.5)*psscale,(winheight-y+0.5)*psscale);
}
#elif WINDOWS
startdraw();
SetPixelV(devcon,(int)x,(int)y,RGB(0,0,0));
SetPixelV(bitcon,(int)x,(int)y,RGB(0,0,0));
if (printer) {
MoveToEx(printer,(int)(x*prnscale+prnoff),(int)(y*prnscale+prnoff),NULL);
LineTo(printer,(int)(x*prnscale+prnoff),(int)(y*prnscale+prnoff));
}
ReleaseDC(window,devcon);
#endif
}
void create_line(char flag) /* create Command 'line' */
{
struct command *cmd;
cmd=add_command(cLINE);
cmd->tag=flag;
}
void line(struct command *cmd) /* draw a line */
{
double x1,y1,x2,y2;
double nx,ny,px,py,norm;
int arrow;
static double lastx,lasty;
static int lastvalid=FALSE;
if (!winopened) {
error(ERROR,"Got no window to draw");
return;
}
if (cmd->tag=='n') {
lastvalid=FALSE;
return;
}
arrow=(cmd->tag=='a');
y2=pop()->value;
x2=pop()->value;
if (cmd->tag=='t') {
if (!lastvalid) {
lastx=x2;
lasty=y2;
lastvalid=TRUE;
return;
}
y1=lasty;
x1=lastx;
}
else {
y1=pop()->value;
x1=pop()->value;
}
lastx=x2;
lasty=y2;
transform(&x1,&y1);
transform(&x2,&y2);
if (arrow) {
px=x2-x1;
py=y2-y1;
nx=py;
ny=-px;
norm=sqrt(nx*nx+ny*ny);
nx*=0.4*fontheight/norm;
ny*=0.4*fontheight/norm;
px*=0.8*fontheight/norm;
py*=0.8*fontheight/norm;
}
do_line(x1,y1,x2,y2);
if (arrow) {
do_line(x2,y2,x2-px+nx,y2-py+ny);
do_line(x2,y2,x2-px-nx,y2-py-ny);
}
}
void do_line(double x1,double y1,double x2,double y2) /* draw a line */
{
#ifdef UNIX
XDrawLine(display,window,gc,x1,y1,x2,y2);
XFlush(display);
if(printerfile) {
fprintf(printerfile,"N\n");
fprintf(printerfile,"%g %g M\n",
x1*psscale,(winheight-y1)*psscale);
fprintf(printerfile,"%g %g L S\n",
x2*psscale,(winheight-y2)*psscale);
}
fflush(printerfile);
#elif WINDOWS
startdraw();
MoveToEx(devcon,(int)x1,(int)y1,NULL);
LineTo(devcon,(int)x2,(int)y2);
MoveToEx(bitcon,(int)x1,(int)y1,NULL);
LineTo(bitcon,(int)x2,(int)y2);
if (printer) {
MoveToEx(printer,(int)(x1*prnscale+prnoff),(int)(y1*prnscale+prnoff),NULL);
LineTo(printer,(int)(x2*prnscale+prnoff),(int)(y2*prnscale+prnoff));
}
ReleaseDC(window,devcon);
#endif
}
void circle() /* draw a circle */
{
double x,y,r;
r=pop()->value;
y=pop()->value;
x=pop()->value;
transform(&x,&y);
if (!winopened) {
error(ERROR,"Got no window to draw");
return;
}
do_circle(x,y,r);
}
void do_circle(double x,double y,double r) /* actually draw the circle */
{
#ifdef UNIX
XDrawArc(display,window,gc,x-r,y-r,2*r,2*r,0*64,360*64);
XFlush(display);
if(printerfile) {
fprintf(printerfile,"N\n");
fprintf(printerfile,"%g %g %g C S\n",
x*psscale,(winheight-y)*psscale,r*psscale);
fflush(printerfile);
}
#else /* WINDOWS */
startdraw();
Arc(devcon,(int)(x-r),(int)(y-r),(int)(x+r),(int)(y+r),0,0,0,0);
Arc(bitcon,(int)(x-r),(int)(y-r),(int)(x+r),(int)(y+r),0,0,0,0);
if (printer) {
Arc(printer,(int)((x-r)*prnscale+prnoff),(int)((y-r)*prnscale+prnoff),
(int)((x+r)*prnscale+prnoff),(int)((y+r)*prnscale+prnoff),0,0,0,0);
}
ReleaseDC(window,devcon);
#endif
}
void create_text(int has_alignement) /* create Command 'text' */
{
struct command *cmd;
cmd=add_command(cTEXT);
cmd->args=has_alignement;
}
void text(struct command *cmd) /* write a text */
{
double x,y;
char *text,*alignement;
if (cmd->args) {
alignement=pop()->pointer;
if (!check_alignement(alignement)) return;
}
else {
alignement=text_align;
}
text=pop()->pointer;
y=pop()->value;
x=pop()->value;
transform(&x,&y);
if (!winopened) {
error(ERROR,"Got no window to draw");
return;
}
do_text((int)x,(int)y,text,alignement);
}
int check_alignement(char *al) /* checks, if text-alignement is valid */
{
al[0]=tolower((int)al[0]);
al[1]=tolower((int)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -