char *pschar(char *s, char *hex, int *wid, int *ht) { Point chpt, spt; Image *b; uchar rowdata[100]; char *hp = hex; int y, i; chpt = stringsize(font, s); /* bounding box of char */ *wid = ((chpt.x+7) / 8) * 8; *ht = chpt.y; /* postscript is backwards to video, so draw white (ones) on black (zeros) */ b = allocimage(display, Rpt(ZP, chpt), GREY1, 0, DBlack); /* place to put it */ spt = string(b, Pt(0,0), display->white, ZP, font, s); /* put it there */ /* Bprint(&bout, "chpt %P, spt %P, wid,ht %d,%d\n", chpt, spt, *wid, *ht); /* Bflush(&bout); */ for (y = 0; y < chpt.y; y++) { /* read bits a row at a time */ memset(rowdata, 0, sizeof rowdata); unloadimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata); for (i = 0; i < spt.x; i += 8) { /* 8 == byte */ sprint(hp, "%2.2x", rowdata[i/8]); hp += 2; } } *hp = 0; freeimage(b); return hex; }
boolean newheapstring (const bigstring bs, hdlstring *hstring) { /* 3/28/97 dmb: rewrote x-plat; don't use NewString toolbox */ return (newfilledhandle ((void *) bs, stringsize (bs), (Handle *)hstring)); } /*newheapstring*/
boolean debugnewheapstring (char * filename, unsigned long linenumber, unsigned long threadid, const bigstring bs, hdlstring *hstring) { /* 3/28/97 dmb: rewrote x-plat; don't use NewString toolbox */ return (debugnewfilledhandle (filename, linenumber, threadid, (void *) bs, stringsize (bs), (Handle *)hstring)); } /*newheapstring*/
/* * Draw text between pointers p and q with first character centered at x, y. * Use color c. Centered if cen is non-zero, right-justified if right is non-zero. * Returns the y coordinate for any following line of text. */ int m_text(int x, int y, char *p, char *q, int c, int cen, int right){ Point tsize; USED(c); tsize=stringsize(font, p); if(cen) x -= tsize.x/2; else if(right) x -= tsize.x; stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p); return y+tsize.y; }
boolean pushstringhandle (const bigstring bs, Handle htext) { /* htext is a handle created with newtexthandle. increase the size of the handle so we can push the pascal string bs at the end of the handle (including length byte). */ return (enlargehandle (htext, (long) stringsize (bs), (ptrvoid) bs)); } /*pushstringhandle*/
void mousethread(void *v) { Point p; Mouse m; int i, n, prev; char buf[100]; ulong rgb; prev = -1; while(readmouse(mousectl) >= 0){ m = mousectl->m; switch(m.buttons){ case 1: while(m.buttons){ if(screen->depth > 8) n = 256; else n = 1<<screen->depth; for(i=0; i!=n; i++) if(i!=prev && ptinrect(m.xy, crect[i])){ if(ramp) rgb = grey(i); else rgb = cmap2rgb(i); sprint(buf, fmt, i, (rgb>>16)&0xFF, (rgb>>8)&0xFF, rgb&0xFF, (rgb<<8) | 0xFF); p = addpt(screen->r.min, Pt(2,2)); draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p); string(screen, p, display->black, ZP, font, buf); prev=i; break; } readmouse(mousectl); m = mousectl->m; } break; case 4: switch(menuhit(3, mousectl, &menu, nil)){ case 0: threadexitsall(0); } } } }
int eenter(char *ask, char *buf, int len, Mouse *m) { int done, down, tick, n, h, w, l, i; Image *b, *save, *backcol, *bordcol; Point p, o, t; Rectangle r, sc; Event ev; Rune k; o = screen->r.min; backcol = allocimagemix(display, DPurpleblue, DWhite); bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue); if(backcol == nil || bordcol == nil) return -1; while(ecankbd()) ekbd(); if(m) o = m->xy; if(buf && len > 0) n = strlen(buf); else { buf = nil; len = 0; n = 0; } k = -1; tick = n; save = nil; done = down = 0; p = stringsize(font, " "); h = p.y; w = p.x; b = screen; sc = b->clipr; replclipr(b, 0, b->r); while(!done){ p = stringsize(font, buf ? buf : ""); if(ask && ask[0]){ if(buf) p.x += w; p.x += stringwidth(font, ask); } r = rectaddpt(insetrect(Rpt(ZP, p), -4), o); p.x = 0; r = rectsubpt(r, p); p = ZP; if(r.min.x < screen->r.min.x) p.x = screen->r.min.x - r.min.x; if(r.min.y < screen->r.min.y) p.y = screen->r.min.y - r.min.y; r = rectaddpt(r, p); p = ZP; if(r.max.x > screen->r.max.x) p.x = r.max.x - screen->r.max.x; if(r.max.y > screen->r.max.y) p.y = r.max.y - screen->r.max.y; r = rectsubpt(r, p); r = insetrect(r, -2); if(save == nil){ save = allocimage(display, r, b->chan, 0, DNofill); if(save == nil){ n = -1; break; } draw(save, r, b, nil, r.min); } draw(b, r, backcol, nil, ZP); border(b, r, 2, bordcol, ZP); p = addpt(r.min, Pt(6, 6)); if(ask && ask[0]){ p = string(b, p, bordcol, ZP, font, ask); if(buf) p.x += w; } if(buf){ t = p; p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, tick)); draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP); draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP); draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP); p = string(b, p, display->black, ZP, font, buf+tick); } flushimage(display, 1); nodraw: i = Ekeyboard; if(m != nil) i |= Emouse; replclipr(b, 0, sc); i = eread(i, &ev); /* screen might have been resized */ if(b != screen || !eqrect(screen->clipr, sc)){ freeimage(save); save = nil; } b = screen; sc = b->clipr; replclipr(b, 0, b->r); switch(i){ default: done = 1; n = -1; break; case Ekeyboard: k = ev.kbdc; if(buf == nil || k == Keof || k == '\n'){ done = 1; break; } if(k == Knack || k == Kesc){ done = !n; buf[n = tick = 0] = 0; break; } if(k == Ksoh || k == Khome){ tick = 0; continue; } if(k == Kenq || k == Kend){ tick = n; continue; } if(k == Kright){ if(tick < n) tick += chartorune(&k, buf+tick); continue; } if(k == Kleft){ for(i = 0; i < n; i += l){ l = chartorune(&k, buf+tick); if(i+l >= tick){ tick = i; break; } } continue; } if(k == Ketb){ while(tick > 0){ tick--; if(tick == 0 || strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1])) break; } buf[n = tick] = 0; break; } if(k == Kbs){ if(tick <= 0) continue; for(i = 0; i < n; i += l){ l = chartorune(&k, buf+i); if(i+l >= tick){ memmove(buf+i, buf+i+l, n - (i+l)); buf[n -= l] = 0; tick -= l; break; } } break; } if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec) continue; if((len-n) <= (l = runelen(k))) continue; memmove(buf+tick+l, buf+tick, n - tick); runetochar(buf+tick, &k); buf[n += l] = 0; tick += l; break; case Emouse: *m = ev.mouse; if(!ptinrect(m->xy, r)){ down = 0; goto nodraw; } if(m->buttons & 7){ down = 1; if(buf && m->xy.x >= (t.x - w)){ down = 0; for(i = 0; i < n; i += l){ l = chartorune(&k, buf+i); t.x += stringnwidth(font, buf+i, 1); if(t.x > m->xy.x) break; } tick = i; } continue; } done = down; break; } if(save){ draw(b, save->r, save, nil, save->r.min); freeimage(save); save = nil; } } replclipr(b, 0, sc); freeimage(backcol); freeimage(bordcol); flushimage(display, 1); return n; }
static void tkscalevert(Tk *tk, Image *i) { TkEnv *e; TkScale *tks; char sv[32]; Image *d, *l; Rectangle r, r2, sr; Point p, q; int fh, v, sw, gw, w, h, len, sl; int fgnd; e = tk->env; tks = TKobj(TkScale, tk); fh = e->font->height; fgnd = TkCforegnd; if (tk->flag & Tkdisabled) fgnd = TkCdisablefgnd; r = Rect(0, 0, tk->act.width, tk->act.height); r = rectaddpt(r, Pt(tk->borderwidth, tk->borderwidth)); r = insetrect(r, tk->highlightwidth); r = insetrect(r, ScalePad); if (tks->sv) r.min.x += tks->digwidth + ScalePad; if(tks->label != nil) { p = stringsize(e->font, tks->label); r.max.x -= p.x; string(i, Pt(r.max.x, r.min.y), tkgc(e, fgnd), ZP, e->font, tks->label); r.max.x -= ScalePad; } sr = insetrect(r, ScaleBW); h = Dy(sr); w = Dx(sr); sl = tks->sl + 2*ScaleBW; l = tkgc(e, TkCbackgndlght); d = tkgc(e, TkCbackgnddark); tkbevel(i, r.min, w, h, ScaleBW, d, l); tks->pixmin = sr.min.y; tks->pixmax = sr.max.y; sw = w - 2*ScaleBW; tks->sw = sw/2; h -= sl; if (h <= 0) h = 1; p.x = sr.max.x; p.y = sr.min.y; if(tks->tick > 0){ int j, t, l; t = tks->tick; l = tks->to-tks->from; if (l < 0) l = -l; if (l == 0) l = 1; r2.min = p; r2.max.x = p.x + ScaleBW + ScalePad; for(j = 0; j <= l; j += t){ r2.min.y = p.y+((vlong)j*h)/l+sl/2; r2.max.y = r2.min.y+1; draw(i, r2, tkgc(e, fgnd), nil, ZP); } } v = tks->value-tks->from; len = tks->to-tks->from; if (len != 0) p.y += ((vlong)v*h)/len; p.x = sr.min.x; q = p; if(ScaleBW > 1) { q.x++; gw = sw; } else gw = sw-1; q.y += tks->sl/2 + 1; if(tk->flag & Tkactivated) { r2.min = p; r2.max.x = sr.max.x; r2.max.y = p.y+sl; draw(i, r2, tkgc(e, TkCactivebgnd), nil, ZP); } switch(tks->relief) { case TKsunken: tkbevel(i, p, sw, tks->sl, ScaleBW, d, l); tkbevel(i, q, gw, 0, 1, l, d); break; case TKraised: tkbevel(i, p, sw, tks->sl, ScaleBW, l, d); tkbevel(i, q, gw, 0, 1, d, l); break; } tks->pixpos = p.y; tks->center = p.x + sw/2 + ScaleBW; if(tks->sv != BoolT) return; tkfprint(sv, tks->value); if(tks->digits > 0 && tks->digits < strlen(sv)) sv[tks->digits] = '\0'; p.x = r.min.x - ScalePad - stringwidth(e->font, sv); p.y = q.y; p.y -= fh/2; if (p.y < tks->pixmin) p.y = tks->pixmin; if (p.y + fh > tks->pixmax) p.y = tks->pixmax - fh; string(i, p, tkgc(e, fgnd), ZP, e->font, sv); }
boolean notifyuser (bigstring bsmessage) { /* use the Notification Manager to ask the user to bring our app to the front. note that we must allocate the record in the heap because multi-threading makes stack addresses non-persistent. 1/18/93 dmb: langbackgroundtask now takes flresting parameter; don't set global 6/9/93 dmb: don't ignore the result of the background callbacks 2.1b5 dmb: if we're in the main thread, need to do same as if yield is disabled. 7.0d6 PBS: In Pike, the header of the dialog should not read UserLand Frontier, it should be UserLand [Whatever]. At this writing, [Whatever] is still undefined, so we'll go with Whatever for the moment. */ #ifdef MACVERSION NMRecPtr pb; tyiconfamily icons; OSErr errcode; boolean fl = true; #define systemevents (osMask | updateMask | activMask | highLevelEventMask) #if TARGET_API_MAC_CARBON == 1 { SInt16 itemhit = 0; OSErr err = noErr; err = StandardAlert (kAlertNoteAlert, bsmessage, nil, nil, &itemhit); return (err == noErr); } #endif pb = (NMRecPtr) NewPtrClear (longsizeof (NMRec)); if (pb == nil) return (false); /* clearbytes (&pb, longsizeof (pb)); */ (*pb).qType = nmType; (*pb).nmMark = 1; clearbytes (&icons, longsizeof (icons)); icons.hics1 = GetResource ('ics#', 128); icons.hics4 = GetResource ('ics4', 128); icons.hics8 = GetResource ('ics8', 128); newfilledhandle (&icons, longsizeof (tyiconfamily), &(*pb).nmIcon); (*pb).nmSound = (Handle) -1; if (isemptystring (bsmessage)) (*pb).nmStr = nil; else { (*pb).nmStr = (StringPtr) NewPtr (stringsize (bsmessage)); copystring (bsmessage, (*pb).nmStr); } (*pb).nmResp = nil; errcode = NMInstall (pb); if (errcode == noErr) { while (!shellisactive ()) { if (flscriptrunning) { if (fldisableyield || inmainthread ()) fl = langpartialeventloop (systemevents); else fl = langbackgroundtask (true); /*let main thread field events*/ } else fl = shellpartialeventloop (systemevents); if (!fl) break; } NMRemove (pb); } disposehandle ((*pb).nmIcon); if ((*pb).nmStr != nil) DisposePtr ((Ptr) (*pb).nmStr); DisposePtr ((Ptr) pb); return (fl && (errcode == noErr)); #endif #ifdef WIN95VERSION char s [256]; short itemnumber; copyptocstring (bsmessage, s); releasethreadglobals (); //#ifdef PIKE // // /*7.0d8 PBS: name change to Radio UserLand*/ // // itemnumber = MessageBox (hwndMDIClient, s, "Radio UserLand", MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); // //#else /* 9.1b3 JES: APPNAME macro is defined in versions.h for both Radio and Frontier -- use instead of hard-coded string */ itemnumber = MessageBox (hwndMDIClient, s, APPNAME, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); //#endif grabthreadglobals (); return (itemnumber == IDOK); #endif } /*notifyuser*/
static boolean validate (hdlhashtable htable, boolean flalert) { /* a bullshit detector for hash tables. written on 3/21/90 by DW. we call it invalid if: 1. the table handle is nil -- there's nothing we can do with such a table! 2. one of the hashbuckets has an item chained into it that shouldn't be in its list. this is a very strong test -- it seems improbable if the chain is somehow invalid that all the handles would work out to point to a key string that just happens to hash to the same bucket number. 3. the sorted list is out of order -- this seems like a little icing on the cake -- how could it pass test 2 and not pass this test? 11/13/90 DW: relaxed the rule about the sorted list being in order, since we're allowing it. 11/14/90 DW: added flonlyinmemory -- if false, not being in memory is not an obstacle. side-effect of doing a full traversal -- all the tables get loaded into memory. */ register hdlhashtable ht = htable; register short i; register hdlhashnode x; hdltablevariable hvariable; short errcode; if (ht == nil) { if (flalert) shellinternalerror (idnilhashtable, BIGSTRING ("\x17" "hashtable handle is nil")); return (false); } if (!(**ht).fllocaltable) { /*8/15/92 dmb*/ for (i = 0; i < (**ht).cttmpstack; i++) { if ((**ht).tmpstack [i].data.binaryvalue != nil) { if (flalert) shellinternalerror (idnilhashtable, BIGSTRING ("\x14" "non-empty temp stack")); return (false); } } } for (i = 0; i < ctbuckets; i++) { x = (**ht).hashbucket [i]; while (x != nil) { /*chain through the hash list*/ bigstring bs; if (!flonlyinmemory) rollbeachball (); gethashkey (x, bs); if (gethandlesize ((Handle) x) != (long) sizeof (tyhashnode) + stringsize (bs)) { if (flalert) shellinternalerror (idbadbucketliststring, BIGSTRING ("\x17" "bad string in hash node")); return (false); } if (hashfunction (bs) != i) { if (flalert) shellinternalerror (idbadbucketliststring, BIGSTRING ("\x1b" "bad string in a bucket list")); return (false); } if (!gettablevariable ((**x).val, &hvariable, &errcode)) goto nextx; if (!(**hvariable).flinmemory) { if (flonlyinmemory) goto nextx; if (!tableverbinmemory ((hdlexternalvariable) hvariable, x)) { if (flalert) shellinternalerror (iderrorloadingtable, BIGSTRING ("\x13" "error loading table")); return (false); } } assert (tablesetdebugglobals (ht, x)); if (!validate ((hdlhashtable) (**hvariable).variabledata, flalert)) /*recurse*/ return (false); nextx: x = (**x).hashlink; /*advance to next node in chain*/ } /*while*/ } /*for*/ /* x = (**ht).hfirstsort; setstringlength (bslast, 0); while (x != nil) { bigstring bs; gethashkey (x, bs); if (!stringlessthan (bslast, bs)) { if (flalert) shellinternalerror (idunsortedhashlist, "\psorted list out of order"); return (false); } x = (**x).sortedlink; copystring (bs, bslast); } /%while%/ */ return (true); } /*validate*/