/* * File: fwindow.r - Icon graphics interface * * Contents: Active, Bg, Color, CopyArea, Couple, * DrawArc, DrawCircle, DrawCurve, DrawImage, DrawLine, * DrawSegment, DrawPoint, DrawPolygon, DrawString, * DrawRectangle, EraseArea, Event, Fg, FillArc, FillCircle, * FillRectangle, FillPolygon, Font, FreeColor, GotoRC, GotoXY, * NewColor, Pattern, PaletteChars, PaletteColor, PaletteKey, * Pending, QueryPointer, ReadImage, TextWidth, Uncouple, * WAttrib, WDefault, WFlush, WSync, WriteImage */ #ifdef Graphics /* * Global variables. * A poll counter for use in interp.c, * the binding for the console window - FILE * for simplicity, * &col, &row, &x, &y, &interval, timestamp, and modifier keys. */ int pollctr; FILE *ConsoleBinding = NULL; /* * the global buffer used as work space for printing string, etc */ char ConsoleStringBuf[MaxReadStr * 48]; char *ConsoleStringBufPtr = ConsoleStringBuf; unsigned long ConsoleFlags = 0; /* Console flags */ "Active() - produce the next active window" function{0,1} Active() abstract { return file } body { wsp ws; if (!wstates || !(ws = getactivewindow())) fail; return ws->filep; } end "Alert(w,volume) - Alert the user" function{1} Alert(argv[argc]) abstract { return file } body { wbp w; int warg = 0; C_integer volume; OptWindow(w); if (argc == warg) volume = 0; else if (!def:C_integer(argv[warg], 0, volume)) runerr(101, argv[warg]); walert(w, volume); ReturnWindow; } end "Bg(w,s) - background color" function{0,1} Bg(argv[argc]) abstract { return string } body { wbp w; char sbuf1[MaxCvtLen]; int len; tended char *tmp; int warg = 0; OptWindow(w); /* * If there is a (non-window) argument we are setting by * either a mutable color (negative int) or a string name. */ if (argc - warg > 0) { if (is:integer(argv[warg])) { /* mutable color or packed RGB */ if (isetbg(w, IntVal(argv[warg])) == Failed) fail; } else { if (!cnv:C_string(argv[warg], tmp)) runerr(103,argv[warg]); if(setbg(w, tmp) == Failed) fail; } } /* * In any event, this function returns the current background color. */ getbg(w, sbuf1); len = strlen(sbuf1); Protect(tmp = alcstr(sbuf1, len), runerr(0)); return string(len, tmp); } end "Clip(w, x, y, w, h) - set context clip rectangle" function{1} Clip(argv[argc]) abstract { return file } body { wbp w; int warg = 0, r; C_integer x, y, width, height; wcp wc; OptWindow(w); wc = w->context; if (argc <= warg) { wc->clipx = wc->clipy = 0; wc->clipw = wc->cliph = -1; unsetclip(w); } else { r = rectargs(w, argc, argv, warg, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); wc->clipx = x; wc->clipy = y; wc->clipw = width; wc->cliph = height; setclip(w); } ReturnWindow; } end "Clone(w, attribs...) - create a new context bound to w's canvas" function{1} Clone(argv[argc]) abstract { return file } body { wbp w, w2; int warg = 0, n; tended struct descrip sbuf, sbuf2; char answer[128]; OptWindow(w); Protect(w2 = alc_wbinding(), runerr(0)); w2->window = w->window; w2->window->refcount++; if (argc>warg && is:file(argv[warg])) { if ((BlkLoc(argv[warg])->file.status & Fs_Window) == 0) runerr(140,argv[warg]); if ((BlkLoc(argv[warg])->file.status & (Fs_Read|Fs_Write)) == 0) runerr(142,argv[warg]); if (ISCLOSED((wbp)BlkLoc(argv[warg])->file.fd)) runerr(142,argv[warg]); Protect(w2->context = clone_context((wbp)BlkLoc(argv[warg])->file.fd), runerr(0)); warg++; } else { Protect(w2->context = clone_context(w), runerr(0)); } for (n = warg; n < argc; n++) { if (!is:null(argv[n])) { if (!cnv:tmp_string(argv[n], sbuf)) runerr(109, argv[n]); switch (wattrib(w2, StrLoc(argv[n]), StrLen(argv[n]), &sbuf2, answer)) { case Failed: fail; case Error: runerr(0, argv[n]); } } } Protect(BlkLoc(result) = (union block *)alcfile((FILE *)w2, Fs_Window|Fs_Read|Fs_Write, &emptystr),runerr(0)); result.dword = D_File; return result; } end "Color(argv[]) - return or set color map entries" function{0,1} Color(argv[argc]) abstract { return file ++ string } body { wbp w; int warg = 0; int i, len; C_integer n; char *colorname, *srcname; tended char *tmp; OptWindow(w); if (argc - warg == 0) runerr(101); if (argc - warg == 1) { /* if this is a query */ CnvCInteger(argv[warg], n) if ((colorname = get_mutable_name(w, n)) == NULL) fail; len = strlen(colorname); Protect(tmp = alcstr(colorname, len), runerr(0)); return string(len, tmp); } CheckArgMultiple(2); for (i = warg; i < argc; i += 2) { CnvCInteger(argv[i], n) if ((colorname = get_mutable_name(w, n)) == NULL) fail; if (is:integer(argv[i+1])) { /* copy another mutable */ if (IntVal(argv[i+1]) >= 0) runerr(205, argv[i+1]); /* must be negative */ if ((srcname = get_mutable_name(w, IntVal(argv[i+1]))) == NULL) fail; if (set_mutable(w, n, srcname) == Failed) fail; strcpy(colorname, srcname); } else { /* specified by name */ tended char *tmp; if (!cnv:C_string(argv[i+1],tmp)) runerr(103,argv[i+1]); if (set_mutable(w, n, tmp) == Failed) fail; strcpy(colorname, tmp); } } ReturnWindow; } end "ColorValue(w,s) - produce RGB components from string color name" function{0,1} ColorValue(argv[argc]) abstract { return string } body { wbp w; C_integer n; int warg = 0, len; long r, g, b; tended char *s; char tmp[24], *t; if (is:file(argv[0]) && (BlkLoc(argv[0])->file.status & Fs_Window)) { w = (wbp)BlkLoc(argv[0])->file.fd; /* explicit window */ warg = 1; } else if (is:file(kywd_xwin[XKey_Window]) && (BlkLoc(kywd_xwin[XKey_Window])->file.status & Fs_Window)) w = (wbp)BlkLoc(kywd_xwin[XKey_Window])->file.fd; /* &window */ else w = NULL; /* no window (but proceed anyway) */ if (!(warg < argc)) runerr(103); if (cnv:C_integer(argv[warg], n)) { if (w != NULL && (t = get_mutable_name(w, n))) Protect(s = alcstr(t, (word)strlen(t)+1), runerr(306)); else fail; } else if (!cnv:C_string(argv[warg], s)) runerr(103,argv[warg]); if (parsecolor(w, s, &r, &g, &b) == Succeeded) { sprintf(tmp,"%ld,%ld,%ld", r, g, b); len = strlen(tmp); Protect(s = alcstr(tmp,len), runerr(306)); return string(len, s); } fail; } end "CopyArea(w,w2,x,y,width,height,x2,y2) - copy area" function{0,1} CopyArea(argv[argc]) /* w,w2,x,y,width,height,x2,y2 */ abstract { return file } body { int warg = 0, n, r; C_integer x, y, width, height, x2, y2, width2, height2; wbp w, w2; OptWindow(w); /* * 2nd window defaults to value of first window */ if (argc>warg && is:file(argv[warg])) { if ((BlkLoc(argv[warg])->file.status & Fs_Window) == 0) runerr(140,argv[warg]); if ((BlkLoc(argv[warg])->file.status & (Fs_Read|Fs_Write)) == 0) runerr(142,argv[warg]); w2 = (wbp)BlkLoc(argv[warg])->file.fd; if (ISCLOSED(w2)) runerr(142,argv[warg]); warg++; } else { w2 = w; } /* * x1, y1, width, and height follow standard conventions. */ r = rectargs(w, argc, argv, warg, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); /* * get x2 and y2, ignoring width and height. */ n = argc; if (n > warg + 6) n = warg + 6; r = rectargs(w2, n, argv, warg + 4, &x2, &y2, &width2, &height2); if (r >= 0) runerr(101, argv[r]); if (copyArea(w, w2, x, y, width, height, x2, y2) == Failed) fail; ReturnWindow; } end /* * Bind the canvas associated with w to the context * associated with w2. If w2 is omitted, create a new context. * Produces a new window variable. */ "Couple(w,w2) - couple canvas to context" function{0,1} Couple(w,w2) abstract { return file } body { tended struct descrip sbuf, sbuf2; wbp wb, wb_new; wsp ws; /* * make the new binding */ Protect(wb_new = alc_wbinding(), runerr(0)); /* * if w is a file, then we bind to an existing window */ if (is:file(w) && (BlkLoc(w)->file.status & Fs_Window)) { wb = (wbp)(BlkLoc(w)->file.fd); wb_new->window = ws = wb->window; if (is:file(w2) && (BlkLoc(w2)->file.status & Fs_Window)) { /* * Bind an existing window to an existing context, * and up the context's reference count. */ if (rebind(wb_new, (wbp)(BlkLoc(w2)->file.fd)) == Failed) fail; wb_new->context->refcount++; } else runerr(140, w2); /* bump up refcount to ws */ ws->refcount++; } else runerr(140, w); Protect(BlkLoc(result) = (union block *)alcfile((FILE *)wb_new, Fs_Window|Fs_Read|Fs_Write, &emptystr),runerr(0)); result.dword = D_File; return result; } end /* * DrawArc(w, x1, y1, width1, height1, angle11, angle21,...) */ "DrawArc(argv[]){1} - draw arc" function{1} DrawArc(argv[argc]) abstract { return file } body { wbp w; int i, j, r, warg = 0; XArc arcs[MAXXOBJS]; C_integer x, y, width, height; double a1, a2; OptWindow(w); j = 0; for (i = warg; i < argc || i == warg; i += 6) { if (j == MAXXOBJS) { drawarcs(w, arcs, MAXXOBJS); j = 0; } r = rectargs(w, argc, argv, i, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); arcs[j].x = x; arcs[j].y = y; ARCWIDTH(arcs[j]) = width; ARCHEIGHT(arcs[j]) = height; /* * Angle 1 processing. Computes in radians and 64'ths of a degree, * bounds checks, and handles wraparound. */ if (i + 4 >= argc || is:null(argv[i + 4])) a1 = 0.0; else { if (!cnv:C_double(argv[i + 4], a1)) runerr(102, argv[i + 4]); if (a1 >= 0.0) a1 = fmod(a1, 2 * Pi); else a1 = -fmod(-a1, 2 * Pi); } /* * Angle 2 processing */ if (i + 5 >= argc || is:null(argv[i + 5])) a2 = 2 * Pi; else { if (!cnv:C_double(argv[i + 5], a2)) runerr(102, argv[i + 5]); if (fabs(a2) > 3 * Pi) runerr(101, argv[i + 5]); } if (fabs(a2) >= 2 * Pi) { a2 = 2 * Pi; } else { if (a2 < 0.0) { a1 += a2; a2 = fabs(a2); } } if (a1 < 0.0) a1 = 2 * Pi - fmod(fabs(a1), 2 * Pi); else a1 = fmod(a1, 2 * Pi); arcs[j].angle1 = ANGLE(a1); arcs[j].angle2 = EXTENT(a2); j++; } drawarcs(w, arcs, j); ReturnWindow; } end /* * DrawCircle(w, x1, y1, r1, angle11, angle21, ...) */ "DrawCircle(argv[]){1} - draw circle" function{1} DrawCircle(argv[argc]) abstract { return file } body { wbp w; int warg = 0, r; OptWindow(w); r = docircles(w, argc - warg, argv + warg, 0); if (r < 0) ReturnWindow; else if (r >= argc - warg) runerr(146); else runerr(102, argv[warg + r]); } end /* * DrawCurve(w,x1,y1,...xN,yN) * Draw a smooth curve through the given points. */ "DrawCurve(argv[]){1} - draw curve" function{1} DrawCurve(argv[argc]) abstract { return file } body { wbp w; int i, n, closed = 0, warg = 0; C_integer dx, dy, x0, y0, xN, yN; XPoint *points; OptWindow(w); CheckArgMultiple(2); dx = w->context->dx; dy = w->context->dy; Protect(points = (XPoint *)malloc(sizeof(XPoint) * (n+2)), runerr(305)); if (n > 1) { CnvCInteger(argv[warg], x0) CnvCInteger(argv[warg + 1], y0) CnvCInteger(argv[argc - 2], xN) CnvCInteger(argv[argc - 1], yN) if ((x0 == xN) && (y0 == yN)) { closed = 1; /* duplicate the next to last point */ CnvCShort(argv[argc-4], points[0].x); CnvCShort(argv[argc-3], points[0].y); points[0].x += w->context->dx; points[0].y += w->context->dy; } else { /* duplicate the first point */ CnvCShort(argv[warg], points[0].x); CnvCShort(argv[warg + 1], points[0].y); points[0].x += w->context->dx; points[0].y += w->context->dy; } for (i = 1; i <= n; i++) { int base = warg + (i-1) * 2; CnvCShort(argv[base], points[i].x); CnvCShort(argv[base + 1], points[i].y); points[i].x += dx; points[i].y += dy; } if (closed) { /* duplicate the second point */ points[i] = points[2]; } else { /* duplicate the last point */ points[i] = points[i-1]; } if (n < 3) { drawlines(w, points+1, n); } else { drawCurve(w, points, n+2); } } free(points); ReturnWindow; } end "DrawImage(w,x,y,s) - draw bitmapped figure" function{0,1} DrawImage(argv[argc]) abstract { return null++integer } body { wbp w; int warg = 0; int c, i, width, height, row, p; C_integer x, y; word nchars; unsigned char *s, *t, *z; struct descrip d; struct palentry *e; OptWindow(w); /* * X or y can be defaulted but s is required. * Validate x/y first so that the error message makes more sense. */ if (argc - warg >= 1 && !def:C_integer(argv[warg], -w->context->dx, x)) runerr(101, argv[warg]); if (argc - warg >= 2 && !def:C_integer(argv[warg + 1], -w->context->dy, y)) runerr(101, argv[warg + 1]); if (argc - warg < 3) runerr(103); /* missing s */ if (!cnv:tmp_string(argv[warg+2], d)) runerr(103, argv[warg + 2]); x += w->context->dx; y += w->context->dy; /* * Extract the Width and skip the following comma. */ s = (unsigned char *)StrLoc(d); z = s + StrLen(d); /* end+1 of string */ width = 0; while (s < z && *s == ' ') /* skip blanks */ s++; while (s < z && isdigit(*s)) /* scan number */ width = 10 * width + *s++ - '0'; while (s < z && *s == ' ') /* skip blanks */ s++; if (width == 0 || *s++ != ',') /* skip comma */ fail; while (s < z && *s == ' ') /* skip blanks */ s++; if (s >= z) /* if end of string */ fail; /* * Check for a bilevel format. */ if ((c = *s) == '#' || c == '~') { s++; nchars = 0; for (t = s; t < z; t++) if (isxdigit(*t)) nchars++; /* count hex digits */ else if (*t != PCH1 && *t != PCH2) fail; /* illegal punctuation */ if (nchars == 0) fail; row = (width + 3) / 4; /* digits per row */ if (nchars % row != 0) fail; height = nchars / row; if (blimage(w, x, y, width, height, c, s, (word)(z - s)) == Error) runerr(305); else return nulldesc; } /* * Extract the palette name and skip its comma. */ c = *s++; /* save initial character */ p = 0; while (s < z && isdigit(*s)) /* scan digits */ p = 10 * p + *s++ - '0'; while (s < z && *s == ' ') /* skip blanks */ s++; if (s >= z || p == 0 || *s++ != ',') /* skip comma */ fail; if (c == 'g' && p >= 2 && p <= 256) /* validate grayscale number */ p = -p; else if (c != 'c' || p < 1 || p > 6) /* validate color number */ fail; /* * Scan the image to see which colors are needed. */ e = palsetup(p); if (e == NULL) runerr(305); for (i = 0; i < 256; i++) e[i].used = 0; nchars = 0; for (t = s; t < z; t++) { c = *t; e[c].used = 1; if (e[c].valid || e[c].transpt) nchars++; /* valid color, or transparent */ else if (c != PCH1 && c != PCH2) fail; } if (nchars == 0) fail; /* empty image */ if (nchars % width != 0) fail; /* not rectangular */ /* * Call platform-dependent code to draw the image. */ height = nchars / width; i = strimage(w, x, y, width, height, e, s, (word)(z - s), 0); if (i == 0) return nulldesc; else if (i < 0) runerr(305); else return C_integer i; } end /* * DrawLine(w,x1,y1,...xN,yN) */ "DrawLine(argv[]){1} - draw line" function{1} DrawLine(argv[argc]) abstract { return file } body { wbp w; int i, j, n, warg = 0; XPoint points[MAXXOBJS]; int dx, dy; OptWindow(w); CheckArgMultiple(2); dx = w->context->dx; dy = w->context->dy; for(i=0, j=0;icontext->dx; dy = w->context->dy; for(i=0, j=0; i < n; i++, j++) { int base = warg + i * 2; if (j == MAXXOBJS) { drawpoints(w, points, MAXXOBJS); j = 0; } CnvCShort(argv[base], points[j].x); CnvCShort(argv[base + 1], points[j].y); points[j].x += dx; points[j].y += dy; } drawpoints(w, points, j); ReturnWindow; } end /* * DrawPolygon(w,x1,y1,...xN,yN) */ "DrawPolygon(argv[]){1} - draw polygon" function{1} DrawPolygon(argv[argc]) abstract { return file } body { wbp w; int i, j, n, base, dx, dy, warg = 0; XPoint points[MAXXOBJS]; OptWindow(w); CheckArgMultiple(2); dx = w->context->dx; dy = w->context->dy; /* * To make a closed polygon, start with the *last* point. */ CnvCShort(argv[argc - 2], points[0].x); CnvCShort(argv[argc - 1], points[0].y); points[0].x += dx; points[0].y += dy; /* * Now add all points from beginning to end, including last point again. */ for(i = 0, j = 1; i < n; i++, j++) { base = warg + i * 2; if (j == MAXXOBJS) { drawlines(w, points, MAXXOBJS); points[0] = points[MAXXOBJS-1]; j = 1; } CnvCShort(argv[base], points[j].x); CnvCShort(argv[base + 1], points[j].y); points[j].x += dx; points[j].y += dy; } drawlines(w, points, j); ReturnWindow; } end /* * DrawRectangle(w, x1, y1, width1, height1, ..., xN, yN, widthN,heightN) */ "DrawRectangle(argv[]){1} - draw rectangle" function{1} DrawRectangle(argv[argc]) abstract { return file } body { wbp w; int i, j, r, warg = 0; XRectangle recs[MAXXOBJS]; C_integer x, y, width, height; OptWindow(w); j = 0; for (i = warg; i < argc || i == warg; i += 4) { r = rectargs(w, argc, argv, i, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); if (j == MAXXOBJS) { drawrectangles(w,recs,MAXXOBJS); j = 0; } RECX(recs[j]) = x; RECY(recs[j]) = y; RECWIDTH(recs[j]) = width; RECHEIGHT(recs[j]) = height; j++; } drawrectangles(w, recs, j); ReturnWindow; } end /* * DrawSegment(x11,y11,x12,y12,...,xN1,yN1,xN2,yN2) */ "DrawSegment(argv[]){1} - draw line segment" function{1} DrawSegment(argv[argc]) abstract { return file } body { wbp w; int i, j, n, warg = 0, dx, dy; XSegment segs[MAXXOBJS]; OptWindow(w); CheckArgMultiple(4); dx = w->context->dx; dy = w->context->dy; for(i=0, j=0; i < n; i++, j++) { int base = warg + i * 4; if (j == MAXXOBJS) { drawsegments(w, segs, MAXXOBJS); j = 0; } CnvCShort(argv[base], segs[j].x1); CnvCShort(argv[base + 1], segs[j].y1); CnvCShort(argv[base + 2], segs[j].x2); CnvCShort(argv[base + 3], segs[j].y2); segs[j].x1 += dx; segs[j].x2 += dx; segs[j].y1 += dy; segs[j].y2 += dy; } drawsegments(w, segs, j); ReturnWindow; } end /* * DrawString(w, x1, y1, s1, ..., xN, yN, sN) */ "DrawString(argv[]){1} - draw text" function{1} DrawString(argv[argc]) abstract { return file } body { wbp w; int i, n, len, warg = 0; char *s; OptWindow(w); CheckArgMultiple(3); for(i=0; i < n; i++) { C_integer x, y; int base = warg + i * 3; CnvCInteger(argv[base], x); CnvCInteger(argv[base + 1], y); x += w->context->dx; y += w->context->dy; CnvTmpString(argv[base + 2], argv[base + 2]); s = StrLoc(argv[base + 2]); len = StrLen(argv[base + 2]); drawstrng(w, x, y, s, len); } ReturnWindow; } end "EraseArea(w,x,y,width,height) - clear an area of the window" function{1} EraseArea(argv[argc]) abstract { return file } body { wbp w; int warg = 0, i, r; C_integer x, y, width, height; OptWindow(w); for (i = warg; i < argc || i == warg; i += 4) { r = rectargs(w, argc, argv, i, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); eraseArea(w, x, y, width, height); } ReturnWindow; } end "Event(w) - return an event from a window" function{1} Event(argv[argc]) abstract { return string ++ integer } body { wbp w; C_integer i; tended struct descrip d; int warg = 0; OptWindow(w); d = nulldesc; i = wgetevent(w, &d); if (i == 0) { if (is:file(kywd_xwin[XKey_Window]) && w == (wbp)BlkLoc(kywd_xwin[XKey_Window])->file.fd) lastEventWin = kywd_xwin[XKey_Window]; else lastEventWin = argv[warg-1]; lastEvFWidth = FWIDTH((wbp)BlkLoc(lastEventWin)->file.fd); lastEvLeading = LEADING((wbp)BlkLoc(lastEventWin)->file.fd); lastEvAscent = ASCENT((wbp)BlkLoc(lastEventWin)->file.fd); return d; } else if (i == -1) runerr(141); else runerr(143); } end "Fg(w,s) - foreground color" function{0,1} Fg(argv[argc]) abstract { return string } body { wbp w; char sbuf1[MaxCvtLen]; int len; tended char *tmp; int warg = 0; OptWindow(w); /* * If there is a (non-window) argument we are setting by * either a mutable color (negative int) or a string name. */ if (argc - warg > 0) { if (is:integer(argv[warg])) { /* mutable color or packed RGB */ if (isetfg(w, IntVal(argv[warg])) == Failed) fail; } else { if (!cnv:C_string(argv[warg], tmp)) runerr(103,argv[warg]); if(setfg(w, tmp) == Failed) fail; } } /* * In any case, this function returns the current foreground color. */ getfg(w, sbuf1); len = strlen(sbuf1); Protect(tmp = alcstr(sbuf1, len), runerr(0)); return string(len, tmp); } end /* * FillArc(w, x1, y1, width1, height1, angle11, angle21,...) */ "FillArc(argv[]){1} - fill arc" function{1} FillArc(argv[argc]) abstract { return file } body { wbp w; int i, j, r, warg = 0; XArc arcs[MAXXOBJS]; C_integer x, y, width, height; double a1, a2; OptWindow(w); j = 0; for (i = warg; i < argc || i == warg; i += 6) { if (j == MAXXOBJS) { fillarcs(w, arcs, MAXXOBJS); j = 0; } r = rectargs(w, argc, argv, i, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); arcs[j].x = x; arcs[j].y = y; ARCWIDTH(arcs[j]) = width; ARCHEIGHT(arcs[j]) = height; if (i + 4 >= argc || is:null(argv[i + 4])) { a1 = 0.0; } else { if (!cnv:C_double(argv[i + 4], a1)) runerr(102, argv[i + 4]); if (a1 >= 0.0) a1 = fmod(a1, 2 * Pi); else a1 = -fmod(-a1, 2 * Pi); } if (i + 5 >= argc || is:null(argv[i + 5])) a2 = 2 * Pi; else { if (!cnv:C_double(argv[i + 5], a2)) runerr(102, argv[i + 5]); if (fabs(a2) > 3 * Pi) runerr(101, argv[i + 5]); } if (fabs(a2) >= 2 * Pi) { a2 = 2 * Pi; } else { if (a2 < 0.0) { a1 += a2; a2 = fabs(a2); } } arcs[j].angle2 = EXTENT(a2); if (a1 < 0.0) a1 = 2 * Pi - fmod(fabs(a1), 2 * Pi); else a1 = fmod(a1, 2 * Pi); arcs[j].angle1 = ANGLE(a1); j++; } fillarcs(w, arcs, j); ReturnWindow; } end /* * FillCircle(w, x1, y1, r1, angle11, angle21, ...) */ "FillCircle(argv[]){1} - draw filled circle" function{1} FillCircle(argv[argc]) abstract { return file } body { wbp w; int warg = 0, r; OptWindow(w); r = docircles(w, argc - warg, argv + warg, 1); if (r < 0) ReturnWindow; else if (r >= argc - warg) runerr(146); else runerr(102, argv[warg + r]); } end /* * FillPolygon(w, x1, y1, ...xN, yN) */ "FillPolygon(argv[]){1} - fill polygon" function{1} FillPolygon(argv[argc]) abstract { return file } body { wbp w; int i, n, warg = 0; XPoint *points; int dx, dy; OptWindow(w); CheckArgMultiple(2) /* * Allocate space for all the points in a contiguous array, * because a FillPolygon must be performed in a single call. */ n = argc>>1; Protect(points = (XPoint *)malloc(sizeof(XPoint) * n), runerr(305)); dx = w->context->dx; dy = w->context->dy; for(i=0; i < n; i++) { int base = warg + i * 2; CnvCShort(argv[base], points[i].x); CnvCShort(argv[base + 1], points[i].y); points[i].x += dx; points[i].y += dy; } fillpolygon(w, points, n); free(points); ReturnWindow; } end /* * FillRectangle(w, x1, y1, width1, height1,...,xN, yN, widthN, heightN) */ "FillRectangle(argv[]){1} - draw filled rectangle" function{1} FillRectangle(argv[argc]) abstract { return file } body { wbp w; int i, j, r, warg = 0; XRectangle recs[MAXXOBJS]; C_integer x, y, width, height; OptWindow(w); j = 0; for (i = warg; i < argc || i == warg; i += 4) { r = rectargs(w, argc, argv, i, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); if (j == MAXXOBJS) { fillrectangles(w,recs,MAXXOBJS); j = 0; } RECX(recs[j]) = x; RECY(recs[j]) = y; RECWIDTH(recs[j]) = width; RECHEIGHT(recs[j]) = height; j++; } fillrectangles(w, recs, j); ReturnWindow; } end "Font(w,s) - get/set font" function{0,1} Font(argv[argc]) abstract { return string } body { tended char *tmp; int len; wbp w; int warg = 0; char buf[MaxCvtLen]; OptWindow(w); if (warg < argc) { if (!cnv:C_string(argv[warg],tmp)) runerr(103,argv[warg]); if (setfont(w,&tmp) == Failed) fail; } getfntnam(w, buf); len = strlen(buf); Protect(tmp = alcstr(buf, len), runerr(0)); return string(len,tmp); } end "FreeColor(argv[]) - free colors" function{1} FreeColor(argv[argc]) abstract { return file } body { wbp w; int warg = 0; int i; C_integer n; tended char *s; OptWindow(w); if (argc - warg == 0) runerr(103); for (i = warg; i < argc; i++) { if (is:integer(argv[i])) { CnvCInteger(argv[i], n) if (n < 0) free_mutable(w, n); } else { if (!cnv:C_string(argv[i], s)) runerr(103,argv[i]); freecolor(w, s); } } ReturnWindow; } end "GotoRC(w,r,c) - move cursor to a particular text row and column" function{1} GotoRC(argv[argc]) abstract { return file } body { C_integer r, c; wbp w; int warg = 0; OptWindow(w); if (argc - warg < 1) r = 1; else CnvCInteger(argv[warg], r) if (argc - warg < 2) c = 1; else CnvCInteger(argv[warg + 1], c) /* * turn the cursor off */ hidecrsr(w->window); w->window->y = ROWTOY(w, r); w->window->x = COLTOX(w, c); w->window->x += w->context->dx; w->window->y += w->context->dy; /* * turn it back on at new location */ UpdateCursorPos(w->window, w->context); showcrsr(w->window); ReturnWindow; } end "GotoXY(w,x,y) - move cursor to a particular pixel location" function{1} GotoXY(argv[argc]) abstract { return file } body { wbp w; C_integer x, y; int warg = 0; OptWindow(w); if (argc - warg < 1) x = 0; else CnvCInteger(argv[warg], x) if (argc - warg < 2) y = 0; else CnvCInteger(argv[warg + 1], y) x += w->context->dx; y += w->context->dy; hidecrsr(w->window); w->window->x = x; w->window->y = y; UpdateCursorPos(w->window, w->context); showcrsr(w->window); ReturnWindow; } end "Lower(w) - lower w to the bottom of the window stack" function{1} Lower(argv[argc]) abstract { return file } body { wbp w; int warg = 0; OptWindow(w); lowerWindow(w); ReturnWindow; } end "NewColor(w,s) - allocate an entry in the color map" function{0,1} NewColor(argv[argc]) abstract { return integer } body { wbp w; int rv; int warg = 0; OptWindow(w); if (mutable_color(w, argv+warg, argc-warg, &rv) == Failed) fail; return C_integer rv; } end "PaletteChars(w,p) - return the characters forming keys to palette p" function{0,1} PaletteChars(argv[argc]) abstract { return string } body { int n, warg; extern char c1list[], c2list[], c3list[], c4list[]; if (is:file(argv[0]) && (BlkLoc(argv[0])->file.status & Fs_Window)) warg = 1; else warg = 0; /* window not required */ if (argc - warg < 1) n = 1; else n = palnum(&argv[warg]); switch (n) { case -1: runerr(103, argv[warg]); /* not a string */ case 0: fail; /* unrecognized */ case 1: return string(90, c1list); /* c1 */ case 2: return string(9, c2list); /* c2 */ case 3: return string(31, c3list); /* c3 */ case 4: return string(73, c4list); /* c4 */ case 5: return string(141, (char *)allchars); /* c5 */ case 6: return string(241, (char *)allchars); /* c6 */ default: /* gn */ if (n >= -64) return string(-n, c4list); else return string(-n, (char *)allchars); } } end "PaletteColor(w,p,s) - return color of key s in palette p" function{0,1} PaletteColor(argv[argc]) abstract { return string } body { int p, warg, len; char tmp[24], *s; struct palentry *e; tended struct descrip d; if (is:file(argv[0]) && (BlkLoc(argv[0])->file.status & Fs_Window)) warg = 1; else warg = 0; /* window not required */ if (argc - warg < 2) runerr(103); p = palnum(&argv[warg]); if (p == -1) runerr(103, argv[warg]); if (p == 0) fail; if (!cnv:tmp_string(argv[warg + 1], d)) runerr(103, argv[warg + 1]); if (StrLen(d) != 1) runerr(205, d); e = palsetup(p); if (e == NULL) runerr(305); e += *StrLoc(d) & 0xFF; if (!e->valid) fail; sprintf(tmp, "%ld,%ld,%ld", e->clr.red, e->clr.green, e->clr.blue); len = strlen(tmp); Protect(s = alcstr(tmp, len), runerr(306)); return string(len, s); } end "PaletteKey(w,p,s) - return key of closest color to s in palette p" function{0,1} PaletteKey(argv[argc]) abstract { return string } body { wbp w; int warg = 0, p; C_integer n; tended char *s; long r, g, b; if (is:file(argv[0]) && (BlkLoc(argv[0])->file.status & Fs_Window)) { w = (wbp)BlkLoc(argv[0])->file.fd; /* explicit window */ warg = 1; } else if (is:file(kywd_xwin[XKey_Window]) && (BlkLoc(kywd_xwin[XKey_Window])->file.status & Fs_Window)) w = (wbp)BlkLoc(kywd_xwin[XKey_Window])->file.fd; /* &window */ else w = NULL; /* no window (but proceed anyway) */ if (argc - warg < 2) runerr(103); p = palnum(&argv[warg]); if (p == -1) runerr(103, argv[warg]); if (p == 0) fail; if (cnv:C_integer(argv[warg + 1], n)) { if (w == NULL || (s = get_mutable_name(w, n)) == NULL) fail; } else if (!cnv:C_string(argv[warg + 1], s)) runerr(103, argv[warg + 1]); if (parsecolor(w, s, &r, &g, &b) == Succeeded) return string(1, rgbkey(p, r / 65535.0, g / 65535.0, b / 65535.0)); else fail; } end "Pattern(w,s) - sets the context fill pattern by string name" function{1} Pattern(argv[argc]) abstract { return file } body { int warg = 0; wbp w; OptWindow(w); if (argc - warg == 0) runerr(103, nulldesc); if (! cnv:string(argv[warg], argv[warg])) runerr(103, nulldesc); switch (SetPattern(w, StrLoc(argv[warg]), StrLen(argv[warg]))) { case Error: runerr(0, argv[warg]); case Failed: fail; } ReturnWindow; } end "Pending(w,x[]) - produce a list of events pending on window" function{0,1} Pending(argv[argc]) abstract { return list } body { wbp w; int warg = 0; wsp ws; int i; OptWindow(w); ws = w->window; wsync(w); /* * put additional arguments to Pending on the pending list in * guaranteed consecutive order. */ for (i = warg; i < argc; i++) { c_put(&(ws->listp), &argv[i]); } /* * retrieve any events that might be relevant before returning the * pending queue. */ switch (pollevent()) { case -1: runerr(141); case 0: fail; } return ws->listp; } end "Pixel(w,x,y,width,height) - produce the contents of some pixels" function{3} Pixel(argv[argc]) abstract { return integer ++ string } body { struct imgmem imem; C_integer x, y, width, height; wbp w; int warg = 0, slen, r; tended struct descrip lastval; char strout[50]; OptWindow(w); r = rectargs(w, argc, argv, warg, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); { int i, j; long rv; wsp ws = w->window; #ifndef max #define max(x,y) (((x)<(y))?(y):(x)) #define min(x,y) (((x)>(y))?(y):(x)) #endif imem.x = max(x,0); imem.y = max(y,0); imem.width = min(width, (int)ws->width - imem.x); imem.height = min(height, (int)ws->height - imem.y); if (getpixel_init(w, &imem) == Failed) fail; lastval = emptystr; for (j=y; j < y + height; j++) { for (i=x; i < x + width; i++) { getpixel(w, i, j, &rv, strout, &imem); slen = strlen(strout); if (rv >= 0) { int signal; if (slen != StrLen(lastval) || strncmp(strout, StrLoc(lastval), slen)) { Protect((StrLoc(lastval) = alcstr(strout, slen)), runerr(0)); StrLen(lastval) = slen; } /* * suspend, but free up imem if vanquished; RTL workaround * Needs implementing under the compiler. */ r_args[0] = lastval; if ((signal = interp(G_Csusp, r_args)) != A_Resume) { tend = r_tend.previous; getpixel_term(w, &imem); VanquishReturn(signal); } } else { int signal; /* * suspend, but free up imem if vanquished; RTL workaround * Needs implementing under the compiler. */ r_args[0].dword = D_Integer; r_args[0].vword.integr = rv; if ((signal = interp(G_Csusp, r_args)) != A_Resume) { tend = r_tend.previous; getpixel_term(w, &imem); VanquishReturn(signal); } } } } getpixel_term(w, &imem); fail; } } end "QueryPointer(w) - produce mouse position" function{0,2} QueryPointer(w) declare { XPoint xp; } abstract { return integer } body { pollevent(); if (is:null(w)) { query_rootpointer(&xp); } else { if (!is:file(w) || !(BlkLoc(w)->file.status & Fs_Window)) runerr(140, w); query_pointer((wbp)BlkLoc(w)->file.fd, &xp); } suspend C_integer xp.x; suspend C_integer xp.y; fail; } end "Raise(w) - raise w to the top of the window stack" function{1} Raise(argv[argc]) abstract { return file } body { wbp w; int warg = 0; OptWindow(w); raiseWindow(w); ReturnWindow; } end "ReadImage(w, s, x, y, p) - load image file" function{0,1} ReadImage(argv[argc]) abstract { return integer } body { wbp w; char filename[MaxPath + 1]; tended char *tmp; int status, warg = 0; C_integer x, y; int p, r; struct imgdata imd; OptWindow(w); if (argc - warg == 0) runerr(103,nulldesc); if (!cnv:C_string(argv[warg], tmp)) runerr(103,argv[warg]); /* * x and y must be integers; they default to the upper left pixel. */ if (argc - warg < 2) x = -w->context->dx; else if (!def:C_integer(argv[warg+1], -w->context->dx, x)) runerr(101, argv[warg+1]); if (argc - warg < 3) y = -w->context->dy; else if (!def:C_integer(argv[warg+2], -w->context->dy, y)) runerr(101, argv[warg+2]); /* * p is an optional palette name. */ if (argc - warg < 4 || is:null(argv[warg+3])) p = 0; else { p = palnum(&argv[warg+3]); if (p == -1) runerr(103, argv[warg+3]); if (p == 0) fail; } x += w->context->dx; y += w->context->dy; strncpy(filename, tmp, MaxPath); /* copy to loc that won't move */ filename[MaxPath] = '\0'; /* * First try to read as a GIF file. * If that doesn't work, try platform-dependent image reading code. */ r = readGIF(filename, p, &imd); if (r == Succeeded) { status = strimage(w, x, y, imd.width, imd.height, imd.paltbl, imd.data, (word)imd.width * (word)imd.height, 0); if (status < 0) r = Error; free((pointer)imd.paltbl); free((pointer)imd.data); } else if (r == Failed) r = readimage(w, filename, x, y, &status); if (r == Error) runerr(305); if (r == Failed) fail; if (status == 0) return nulldesc; else return C_integer (word)status; } end "WSync(w) - synchronize with server" function{1} WSync(w) abstract { return file++null } body { wbp _w_; if (is:null(w)) { _w_ = NULL; } else if (!is:file(w)) runerr(140,w); else { if (!(BlkLoc(w)->file.status & Fs_Window)) runerr(140,w); _w_ = (wbp)BlkLoc(w)->file.fd; } wsync(_w_); pollevent(); return w; } end "TextWidth(w,s) - compute text pixel width" function{1} TextWidth(argv[argc]) abstract { return integer } body { wbp w; int warg=0; C_integer i; OptWindow(w); if (warg == argc) runerr(103,nulldesc); else if (!cnv:tmp_string(argv[warg],argv[warg])) runerr(103,argv[warg]); i = TEXTWIDTH(w, StrLoc(argv[warg]), StrLen(argv[warg])); return C_integer i; } end "Uncouple(w) - uncouple window" function{1} Uncouple(w) abstract { return file } body { wbp _w_; if (!is:file(w)) runerr(140,w); if ((BlkLoc(w)->file.status & Fs_Window) == 0) runerr(140,w); if ((BlkLoc(w)->file.status & (Fs_Read|Fs_Write)) == 0) runerr(142,w); _w_ = (wbp)BlkLoc(w)->file.fd; BlkLoc(w)->file.status = Fs_Window; /* no longer open for read/write */ free_binding(_w_); return w; } end "WAttrib(argv[]) - read/write window attributes" function{*} WAttrib(argv[argc]) abstract { return file++string++integer } body { wbp w, wsave; word n; tended struct descrip sbuf, sbuf2; char answer[128]; int pass, config = 0; int warg = 0; OptWindow(w); wsave = w; /* * Loop through the arguments. */ for (pass = 1; pass <= 2; pass++) { w = wsave; if (config && pass == 2) { if (do_config(w, config) == Failed) fail; } for (n = warg; n < argc; n++) { if (is:file(argv[n])) {/* Current argument is a file */ /* * Switch the current file to the file named by the * current argument providing it is a file. argv[n] * is made to be a empty string to avoid a special case. */ if (!(BlkLoc(argv[n])->file.status & Fs_Window)) runerr(140,argv[n]); w = (wbp)BlkLoc(argv[n])->file.fd; if (config && pass == 2) { if (do_config(w, config) == Failed) fail; } } else { /* Current argument should be a string */ /* * In pass 1, a null argument is an error; failed attribute * assignments are turned into null descriptors for pass 2 * and are ignored. */ if (is:null(argv[n])) { if (pass == 2) continue; else runerr(109, argv[n]); } /* * If its an integer or real, it can't be a valid attribute. */ if (is:integer(argv[n]) || is:real(argv[n])) { runerr(145, argv[n]); } /* * Convert the argument to a string */ if (!cnv:tmp_string(argv[n], sbuf)) runerr(109, argv[n]); /* * Various parts of the code can't handle long attributes. * (ugh.) */ if (StrLen(sbuf) > 127) runerr(145, argv[n]); /* * Read/write the attribute */ if (pass == 1) { char *tmp_s = StrLoc(sbuf); char *tmp_s2 = StrLoc(sbuf) + StrLen(sbuf); for ( ; tmp_s < tmp_s2; tmp_s++) if (*tmp_s == '=') break; if (tmp_s < tmp_s2) { /* * pass 1: perform attribute assignments */ switch (wattrib(w, StrLoc(sbuf), StrLen(sbuf), &sbuf2, answer)) { case Failed: /* * Mark the attribute so we don't produce a result */ argv[n] = nulldesc; continue; case Error: runerr(0, argv[n]); } if (StrLen(sbuf) > 4) { if (!strncmp(StrLoc(sbuf), "pos=", 4)) config |= 1; if (StrLen(sbuf) > 5) { if (!strncmp(StrLoc(sbuf), "posx=", 5)) config |= 1; if (!strncmp(StrLoc(sbuf), "posy=", 5)) config |= 1; if (!strncmp(StrLoc(sbuf), "rows=", 5)) config |= 2; if (!strncmp(StrLoc(sbuf), "size=", 5)) config |= 2; if (StrLen(sbuf) > 6) { if (!strncmp(StrLoc(sbuf), "width=", 6)) config |= 2; if (!strncmp(StrLoc(sbuf), "lines=", 6)) config |= 2; if (StrLen(sbuf) > 7) { if (!strncmp(StrLoc(sbuf), "height=", 7)) config |= 2; if (!strncmp(StrLoc(sbuf), "resize=", 7)) config |= 2; if (StrLen(sbuf) > 8) { if (!strncmp(StrLoc(sbuf), "columns=", 8)) config |= 2; if (StrLen(sbuf) > 9) { if (!strncmp(StrLoc(sbuf), "geometry=", 9)) config |= 3; } } } } } } } } /* * pass 2: perform attribute queries, suspend result(s) */ else if (pass==2) { char *stmp, *stmp2; /* * Turn assignments into queries. */ for( stmp = StrLoc(sbuf), stmp2 = stmp + StrLen(sbuf); stmp < stmp2; stmp++) if (*stmp == '=') break; if (stmp < stmp2) StrLen(sbuf) = stmp - StrLoc(sbuf); switch (wattrib(w, StrLoc(sbuf), StrLen(sbuf), &sbuf2, answer)) { case Failed: continue; case Error: runerr(0, argv[n]); } if (is:string(sbuf2)) Protect(StrLoc(sbuf2) = alcstr(StrLoc(sbuf2),StrLen(sbuf2)), runerr(0)); suspend sbuf2; } } } } fail; } end "WDefault(w,program,option) - get a default value from the environment" function{0,1} WDefault(argv[argc]) abstract { return string } body { wbp w; int warg = 0; long l; tended char *prog, *opt; char sbuf1[MaxCvtLen]; OptWindow(w); if (argc-warg < 2) runerr(103); if (!cnv:C_string(argv[warg],prog)) runerr(103,argv[warg]); if (!cnv:C_string(argv[warg+1],opt)) runerr(103,argv[warg+1]); if (getdefault(w, prog, opt, sbuf1) == Failed) fail; l = strlen(sbuf1); Protect(prog = alcstr(sbuf1,l),runerr(0)); return string(l,prog); } end "WFlush(w) - flush all output to window w" function{1} WFlush(argv[argc]) abstract { return file } body { wbp w; int warg = 0; OptWindow(w); wflush(w); ReturnWindow; } end "WriteImage(w,filename,x,y,width,height) - write an image to a file" function{0,1} WriteImage(argv[argc]) abstract { return file } body { wbp w; int r; C_integer x, y, width, height, warg = 0; tended char *s; OptWindow(w); if (argc - warg == 0) runerr(103, nulldesc); else if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); r = rectargs(w, argc, argv, warg + 1, &x, &y, &width, &height); if (r >= 0) runerr(101, argv[r]); /* * clip image to window, and fail if zero-sized. * (the casts to long are necessary to avoid unsigned comparison.) */ if (x < 0) { width += x; x = 0; } if (y < 0) { height += y; y = 0; } if (x + width > (long) w->window->width) width = w->window->width - x; if (y + height > (long) w->window->height) height = w->window->height - y; if (width <= 0 || height <= 0) fail; /* * try platform-dependent code first; it will reject the call * if the file name s does not specify a platform-dependent format. */ r = dumpimage(w, s, x, y, width, height); if (r == NoCvt) r = writeGIF(w, s, x, y, width, height); if (r != Succeeded) fail; ReturnWindow; } end #ifdef WinExtns "WinPlayMedia(w,x[]) - play a multimedia resource" function{0,1} WinPlayMedia(argv[argc]) abstract { return null } body { wbp w; tended char *tmp; int warg = 0; int i; wsp ws; word n; OptWindow(w); ws = w->window; for (n = warg; n < argc; n++) { if (!cnv:C_string(argv[n], tmp)) runerr(103,argv[warg]); if (playmedia(w, tmp) == Failed) fail; } return nulldesc; } end /* * Simple Windows-native pushbutton */ "WinButton(w, s, x, y, wd, ht) - install a pushbutton with label s on window w" function{0,1} WinButton(argv[argc]) abstract { return file } body { wbp w; wsp ws; int i, ii, i2, r, total = 0; C_integer x, y, width, height, warg = 0; tended char *s, *s2; tended struct descrip d; tended struct b_list *hp; OptWindow(w); ws = w->window; if (warg == argc) fail; if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); warg++; /* * look for an existing button with this id. */ for(i = 0; i < ws->nChildren; i++) { if (!strcmp(s, ws->child[i].id) && ws->child[i].type==CHILD_BUTTON) break; } /* * create a new button if none is found */ if (i == ws->nChildren) { ws->nChildren++; ws->child = realloc(ws->child, ws->nChildren * sizeof(childcontrol)); makebutton(ws, ws->child + i, s); } if (warg >= argc) x = 0; else if (!def:C_integer(argv[warg], 0, x)) runerr(101, argv[warg]); warg++; if (warg >= argc) y = 0; else if (!def:C_integer(argv[warg], 0, y)) runerr(101, argv[warg]); warg++; /* * default width is width of text in system font + 2 chars */ ii = sysTextWidth(w, s, strlen(s)) + 10; if (warg >= argc) width = i2; else if (!def:C_integer(argv[warg], i2, width)) runerr(101, argv[warg]); warg++; /* * default height is height of text in system font * 7/4 */ i2 = sysFontHeight(w) * 7 / 4; if (warg >= argc) height = i2; else if (!def:C_integer(argv[warg], i2, height)) runerr(101, argv[warg]); movechild(ws->child + i, x, y, width, height); ReturnWindow; } end "WinScrollBar(w, s, i1, i2, i3, x, y, wd, ht) - install a scrollbar" function{0,1} WinScrollBar(argv[argc]) abstract { return file } body { wbp w; wsp ws; C_integer x, y, width, height, warg = 0, i1, i2, i3, i, ii; tended char *s, *s2; tended struct descrip d; tended struct b_list *hp; OptWindow(w); ws = w->window; if (warg == argc) fail; if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); warg++; /* * look for an existing scrollbar with this id. */ for(i = 0; i < ws->nChildren; i++) { if (!strcmp(s, ws->child[i].id) && ws->child[i].type==CHILD_EDIT) break; } /* * i1, the min of the scrollbar range, defaults to 0 */ if (warg >= argc) i1 = 0; else if (!def:C_integer(argv[warg], 0, i1)) runerr(101, argv[warg]); warg++; /* * i2, the max of the scrollbar range, defaults to 100 */ if (warg >= argc) i2 = 100; else if (!def:C_integer(argv[warg], 100, i2)) runerr(101, argv[warg]); warg++; /* * create a new scrollbar at end of array if none was found */ if (i == ws->nChildren) { ws->nChildren++; ws->child = realloc(ws->child, ws->nChildren * sizeof(childcontrol)); makescrollbar(ws, ws->child + i, s, i1, i2); } /* * i3, the interval, defaults to 10 */ if (warg >= argc) i3 = 10; else if (!def:C_integer(argv[warg], 10, i3)) runerr(101, argv[warg]); warg++; /* * x defaults to the right edge of the window - system scrollbar width */ ii = ws->width - sysScrollWidth(); if (warg >= argc) x = ii; else if (!def:C_integer(argv[warg], ii, x)) runerr(101, argv[warg]); warg++; /* * y defaults to 0 */ if (warg >= argc) y = 0; else if (!def:C_integer(argv[warg], 0, y)) runerr(101, argv[warg]); warg++; /* * width defaults to system scrollbar width */ ii = sysScrollWidth(); if (warg >= argc) width = ii; else if (!def:C_integer(argv[warg], ii, width)) runerr(101, argv[warg]); warg++; /* * height defaults to height of the client window */ if (warg >= argc) height = ws->height; else if (!def:C_integer(argv[warg], ws->height, height)) runerr(101, argv[warg]); movechild(ws->child + i, x, y, width, height); ReturnWindow; } end /* * Simple Windows-native menu bar */ "WinMenuBar(w,L1,L2,...) - install a set of top-level menus" function{0,1} WinMenuBar(argv[argc]) abstract { return file } body { wbp w; wsp ws; int i, total = 0; C_integer x, y, warg = 0; tended char *s; tended struct descrip d; OptWindow(w); ws = w->window; if (warg == argc) fail; for (i = warg; i < argc; i++) { if (!is:list(argv[i])) runerr(108, argv[i]); total += BlkLoc(argv[i])->list.size; } /* * free up memory for the old menu map */ if (ws->nmMapElems) { for (i=0; inmMapElems; i++) free(ws->menuMap[i]); free(ws->menuMap); } ws->menuMap = (char **)calloc(total, sizeof(char *)); if (nativemenubar(w, total, argc, argv, warg, &d) == Error) runerr(103, d); ReturnWindow; } end /* * Windows-native editor */ "WinEditRegion(w, s, s2, x, y, wd, ht) = install an edit box with label s" function{0, 1} WinEditRegion(argv[argc]) abstract { return file ++ string } body { wbp w; wsp ws; tended char *s, *s2; C_integer i, x, y, width, height, warg = 0; OptWindow(w); ws = w->window; if (warg == argc) fail; if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); warg++; /* * look for an existing edit region with this id. */ for(i = 0; i < ws->nChildren; i++) { if (!strcmp(s, ws->child[i].id) && ws->child[i].type==CHILD_EDIT) break; } /* * create a new edit region if none is found */ if (i == ws->nChildren) { ws->nChildren++; ws->child = realloc(ws->child, ws->nChildren * sizeof(childcontrol)); makeeditregion(w, ws->child + i, s); } /* * Invoked with no value, return the current value of an existing * edit region (entire buffer is one gigantic string). */ else if (warg == argc) { geteditregion(ws->child + i, &result); return result; } /* * Assign a value (s2 string contents) or perform editing command */ if (is:null(argv[warg])) s2 = NULL; else if (!cnv:C_string(argv[warg], s2)) runerr(103, argv[warg]); warg++; if (warg >= argc) x = 0; else if (!def:C_integer(argv[warg], 0, x)) runerr(101, argv[warg]); warg++; if (warg >= argc) y = 0; else if (!def:C_integer(argv[warg], 0, y)) runerr(101, argv[warg]); warg++; if (warg >= argc) width = ws->width - x; else if (!def:C_integer(argv[warg], ws->width -x, width)) runerr(101, argv[warg]); warg++; if (warg >= argc) height = ws->height - y; else if (!def:C_integer(argv[warg], ws->height - y, height)) runerr(101, argv[warg]); if (s2 && !strcmp("!clear", s2)) { cleareditregion(ws->child + i); s2 = NULL; } else if (s2 && !strcmp("!copy", s2)) { copyeditregion(ws->child + i); s2 = NULL; } else if (s2 && !strcmp("!cut", s2)) { cuteditregion(ws->child + i); s2 = NULL; } else if (s2 && !strcmp("!paste", s2)) { pasteeditregion(ws->child + i); s2 = NULL; } else if (s2 && !strcmp("!undo", s2)) { if (undoeditregion(ws->child + i) == Failed) fail; s2 = NULL; } else if (s2 && !strncmp("!modified=", s2, 10)) { setmodifiededitregion(ws->child + i, atoi(s2+10)); s2 = NULL; } else if (s2 && !strcmp("!modified", s2)) { if (modifiededitregion(ws->child + i) == Failed) fail; s2 = NULL; } else if (s2 && !strncmp("!font=", s2, 6)) { if (setchildfont(ws->child + i, s2 + 6) == Succeeded) { ReturnWindow; } else fail; } else if (s2 && !strcmp("!setsel", s2)) { setchildselection(ws, ws->child + i, x, y); ReturnWindow; } if (s2) { seteditregion(ws->child + i, s2); } movechild(ws->child + i, x, y, width, height); setfocusonchild(ws, ws->child + i, width, height); ReturnWindow; } end /* * common dialog functions */ "WinColorDialog(w,s) - choose a color for a window's context" function{0,1} WinColorDialog(argv[argc]) abstract { return string } body { wbp w; C_integer x, y, width, height, warg = 0; long r, g, b; tended char *s; char buf[64], *tmp = buf; OptWindow(w); if (warg < argc) { if (is:null(argv[warg])) s = "white"; else if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); } else s = "white"; if (parsecolor(w, s, &r, &g, &b) == Failed) fail; if (nativecolordialog(w, r, g, b, buf) == NULL) fail; StrLoc(result) = alcstr(buf, strlen(buf)); StrLen(result) = strlen(buf); return result; } end "WinFontDialog(w,s) - choose a font for a window's context" function{0,1} WinFontDialog(argv[argc]) abstract { return string } body { wbp w; int r; C_integer x, y, width, height, warg = 0, fheight; int flags; tended char *s; char buf[64], *tmp = buf; OptWindow(w); if (warg < argc) { if (is:null(argv[warg])) s = "fixed"; else if (!cnv:C_string(argv[warg], s)) runerr(103, argv[warg]); } else s = "fixed"; parsefont(s, buf, &flags, &fheight); if (nativefontdialog(w, buf, flags, fheight) == Failed) fail; StrLoc(result) = alcstr(buf, strlen(buf)); StrLen(result) = strlen(buf); return result; } end "WinOpenDialog(w,s1,s2,i,s3,j) - choose a file to open" function{0,1} WinOpenDialog(argv[argc]) abstract { return string } body { wbp w; int len, slen; C_integer i, j, x, y, width, height, warg = 0; char buf2[64], buf3[256], chReplace; char *tmpstr; tended char *s1, *s2, *s3; OptWindow(w); if (warg >= argc || is:null(argv[warg])) { s1 = "Open:"; } else if (!cnv:C_string(argv[warg], s1)) { runerr(103, argv[warg]); } warg++; if (warg >= argc || is:null(argv[warg])) { s2 = ""; } else if (!cnv:C_string(argv[warg], s2)) { runerr(103, argv[warg]); } warg++; if (warg >= argc) { i = 50; } else if (!def:C_integer(argv[warg], 50, i)) { runerr(101, argv[warg]); } warg++; if (warg >= argc || is:null(argv[warg])) { strcpy(buf3,"All Files(*.*)|*.*|"); s3 = buf3; } else if (!cnv:C_string(argv[warg], s3)) { runerr(103, argv[warg]); } else { strncpy(buf3, s3, 255); buf3[255] = '\0'; s3 = buf3; } chReplace = s3[strlen(s3)-1]; slen = strlen(s3); for(j=0; j < slen; j++) if(s3[j] == chReplace) s3[j] = '\0'; warg++; if (warg >= argc) { j = 1; } else if (!def:C_integer(argv[warg], 1, j)) { runerr(101, argv[warg]); } warg++; if ((tmpstr = nativeopendialog(w,s1,s2,s3,i,j)) == NULL) fail; len = strlen(tmpstr); StrLoc(result) = alcstr(tmpstr, len); StrLen(result) = len; return result; } end "WinSelectDialog(w, s1, buttons) - select from a set of choices" function{0,1} WinSelectDialog(argv[argc]) abstract { return string } body { wbp w; C_integer i, j, warg = 0, len; tended char *s1; char *s2 = NULL, *tmpstr; tended struct descrip d; tended struct b_list *hp; int lsize; OptWindow(w); /* * look for list of text for the message. concatenate text strings. */ if (warg == argc) fail; if (!is:list(argv[warg])) runerr(108, argv[warg]); hp = (struct b_list *)BlkLoc(argv[warg]); lsize = hp->size; for(i=0; i < lsize; i++) { c_get(hp, &d); if (!cnv:C_string(d, s1)) runerr(103, d); len += strlen(s1)+2; if (s2) { s2 = realloc(s2, len); if (!s2) fail; strcat(s2, "\r\n"); strcat(s2, s1); } else s2 = salloc(s1); c_put(&(argv[warg]), &d); } warg++; if (warg >= argc) { hp = NULL; } else { if (!is:list(argv[warg])) runerr(108, argv[warg]); hp = (struct b_list *)BlkLoc(argv[warg]); lsize = hp->size; for(i=0; i < lsize; i++) { c_get(hp, &d); if (!cnv:C_string(d, s1)) runerr(103, d); c_put(&(argv[warg]), &d); } } tmpstr = nativeselectdialog(w, hp, s2); if (tmpstr == NULL) fail; free(s2); len = strlen(tmpstr); StrLoc(result) = alcstr(tmpstr, len); StrLen(result) = len; return result; } end "WinSaveDialog(w,s1,s2,i,s3,j) - choose a file to save" function{0,1} WinSaveDialog(argv[argc]) abstract { return string } body { wbp w; int len; C_integer i, j, warg = 0, slen; char buf3[128], chReplace; tended char *tmpstr; tended char *s1, *s2, *s3; OptWindow(w); if (warg >= argc || is:null(argv[warg])) { s1 = "Save:"; } else if (!cnv:C_string(argv[warg], s1)) { runerr(103, argv[warg]); } warg++; if (warg >= argc || is:null(argv[warg])) { s2 = ""; } else if (!cnv:C_string(argv[warg], s2)) { runerr(103, argv[warg]); } warg++; if (warg >= argc) { i = 50; } else if (!def:C_integer(argv[warg], 50, i)) { runerr(101, argv[warg]); } warg++; if (warg >= argc || is:null(argv[warg])) { strcpy(buf3,"All Files(*.*)|*.*|"); s3 = buf3; } else if (!cnv:C_string(argv[warg], s3)) { runerr(103, argv[warg]); } else { strcpy(buf3, s3); s3 = buf3; } chReplace = s3[strlen(s3)-1]; slen = strlen(s3); for(j=0; j < slen; j++) if(s3[j] == chReplace) s3[j] = '\0'; warg++; if (warg >= argc) { j = 1; } else if (!def:C_integer(argv[warg], 1, j)) { runerr(101, argv[warg]); } warg++; if ((tmpstr = nativesavedialog(w, s1, s2, s3, i, j)) == NULL) fail; len = strlen(tmpstr); StrLoc(result) = alcstr(tmpstr, len); StrLen(result) = len; return result; } end #endif /* WinExtns */ #endif /* Graphics */