xcip/0000755000175300001440000000000011513632737010354 5ustar meusersxcip/commands.c0000644000175300001440000006777711513632544012345 0ustar meusers#ifndef X11 #ifndef BRAM #include "setup.h" #endif #endif #include "cip.h" #ifdef DMD5620 #include #endif extern char *Pgm_name; extern char *Jpic_pgm; struct macro *macroList; int nextMacroName; Rectangle macroBB(); char filename[MAXNAMESIZE+10]; extern int currentBrush, copyFlag, gridState, buttonState; extern int videoState; extern int editDepth; extern char c; extern char fontString[]; extern Rectangle brushes[]; extern Rectangle BBpic; extern struct thing *readPic(); extern void StringSize(); extern void undo_clear(); extern Point jString (); extern Point translate(); char tempString[MAXTEXT]; char fixedString[MAXTEXT]; /* Fixes string by placing backslashes in front of characters * that give problems in pic and troff (i.e., double quote * and backslash). Exceptions are "\(" and "\*" which are passed thru * untouched to allow users to get things like bullits ("\(bu") and * trademark ("\*(Tm"). */ char * addBackslashes( s ) register char * s; { register int i,j; for( j=i=0; s[i]!='\0'; i++ ) { if( s[i] == '"' ) { fixedString[j++] = '\\'; } else if( s[i] == '\\' ) { if( (s[i+1] == '\\') && ( (s[i+2] == '(') || (s[i+2] == '*') ) ) { /* Special cases of \\( turn to \\\\( * and \\* turn to \\\\* */ fixedString[j++] = '\\'; fixedString[j++] = '\\'; fixedString[j++] = '\\'; i++; } else if ( (s[i+1] != '(') && (s[i+1] != '*') ) { /* Normal case - add 3 extra backslashes */ fixedString[j++] = '\\'; fixedString[j++] = '\\'; fixedString[j++] = '\\'; } } fixedString[j++] = s[i]; } fixedString[j++] = '\0'; return( fixedString ); } int numLines(s) register char *s; { register int i; register int num = 1; if (s[0]=='\0') { return (0); } else { for(i=0; s[i]!='\0'; i++) if ( s[i] == '\r' ) num++; return (num); } } putText(fp,h) /* recursive */ FILE *fp; register struct thing *h; { register struct thing *t; register int q,v,start; int hi; char * s; short spacing; Point w; if ((t = h) != TNULL) { do { if (t->type == TEXT) { s = t->otherValues.text.s; if ( numLines(s) > 1 ) { s = addBackslashes(s); spacing = t->otherValues.text.spacing + fontheight(t->otherValues.text.f->f); w = sub(t->bb.corner, t->bb.origin); fprintf(fp, "define t%d |\n", t->otherValues.text.outName); fprintf(fp, "[ box invis ht %d wid %d with .sw at 0,0\n", w.y, w.x ); hi = w.y - (fontheight(t->otherValues.text.f->f)>>1) - (fontheight(t->otherValues.text.f->f)>>3); q = 0; v = 0; start = 0; while(s[q] != '\0') { for(q=start; (s[q]!='\r')&&(s[q]!='\0'); q++) tempString[v++] = s[q]; tempString[v] = '\0'; font2string(t->otherValues.text.f->num); if( strlen(fontString) == 2 ) fprintf(fp, "\"\\f(%s", fontString ); else fprintf(fp, "\"\\f%s", fontString ); switch (t->otherValues.text.just) { case CENTER: fprintf(fp,"\\s%d\\&%s\\fP\\s0\" at %d,%d\n", t->otherValues.text.f->ps, tempString, (w.x>>1), hi ); break; case LEFTJUST: fprintf(fp,"\\s%d\\&%s\\fP\\s0\" at %d,%d %s\n", t->otherValues.text.f->ps, tempString, 0, hi, "ljust" ); break; case RIGHTJUST: fprintf(fp,"\\s%d\\&%s\\fP\\s0\" at %d,%d %s\n", t->otherValues.text.f->ps, tempString, w.x, hi, "rjust" ); break; } start = q+1; hi = hi - spacing; v = 0; } fprintf(fp, "] |\n\n"); } } else if (t->type == MACRO) { putText(fp,t->otherValues.list->parts); } t = t->next; } while(t != h); } } doPut() { register struct thing * t; FILE * fp; struct macro * m; int saveB; int r; char cp2backup[300]; saveB = buttonState; initMessage(); if( firstThing == TNULL ) { moreMessage("Nothing to write out!"); return; } changeButtons(DObuttons); moreMessage("Put file: "); r = getMessage(filename); if( (r==1) || (r==2) || (strlen(filename) == 0) ) { newMessage("*** put file cancelled ***"); changeButtons(saveB); return; } cursswitch(&hourglass); changeButtons(BLANKbuttons); if( access(filename,4) == 0 ) { /* If file exists already, copy it to a backup file in user's home directory. */ sprintf(cp2backup, "/bin/cp %s $HOME/%s.backup", filename, Pgm_name); #ifdef DMDTERM /* Check for more than 60 characters - a limit imposed by the jx command. */ if( strlen(cp2backup) >= 60 ) { newMessage("Warning: file path name is too long!"); moreMessage("\nIt may cause xcip to abort on machines"); moreMessage("\nsuch as VAXes. Continue anyway?"); if( !RUsure() ) { newMessage("*** put file cancelled ***"); cursSwitch(); return; } } #endif if( (fp=popen(cp2backup,"r")) == (FILE *) NULL ) { fileError("Failed to backup the", filename ); } else { getc(fp); /* forces DMD to wait for cp completion. */ newMessage("Previous file copied to "); moreMessage( Pgm_name ); moreMessage( ".backup in\nyour home directory." ); pclose(fp); } } if ((fp = fopen(filename,"w")) == (FILE *) NULL) { fileError("open",filename); cursSwitch(); return; } fprintf(fp,".nf\n.PS\nscale=100\n"); findBBpic( firstThing ); putText( fp, firstThing ); /* Write out macro definitions */ for( m=macroList; m!=MNULL; m=m->next ) { if( m->useCount>0 ) { fprintf(fp,"define %s |\n",m->name); fprintf(fp,"[ box invis ht %d wid %d with .sw at 0,0\n", m->bb.corner.y, m->bb.corner.x); if( (t=m->parts) != TNULL ) { do { writePIC( t, fp, Rpt(Pt(0,0), m->bb.corner) ); t = t->next; } while( t != m->parts ); } fprintf(fp,"] |\n\n"); } } /* Write out bounding box. */ fprintf(fp,"box invis ht %d wid %d with .sw at 0,0\n", BBpic.corner.y - BBpic.origin.y, BBpic.corner.x - BBpic.origin.x); t = firstThing; do { writePIC(t,fp,BBpic); t = t->next; } while( t != firstThing ); fprintf(fp,".PE\n.fi\n"); fclose(fp); cursSwitch(); changeButtons(saveB); } fileError(s,fn) register char *s, *fn; { moreMessage("\nCannot "); moreMessage(s); moreMessage(" file "); moreMessage(fn); } struct thing * doGet(h) register struct thing * h; { register FILE * fp; int r; char hostCmd[MAXNAMESIZE+100]; initMessage(); if( editDepth != 0 ) { moreMessage("Warning: currently editing a macro.\r"); moreMessage("Continue get file operation?\r"); if( !RUsure() ) goto wrapup; } else if( h != TNULL ) { moreMessage("Warning: adding to existing picture.\r"); moreMessage("Clear screen first?\r"); if( RUsure() ) h = doClear(h); } changeButtons(DObuttons); moreMessage("Get file: "); r = getMessage(filename); if( (r==1) || (r==2) || (strlen(filename) == 0) ) { newMessage("*** get file cancelled ***"); goto wrapup; } if (access(filename,4)!=0) { fileError("access",filename); goto wrapup; } strcpy( hostCmd, Jpic_pgm ); strcat( hostCmd, " " ); strcat( hostCmd, filename ); strcat( hostCmd, " 2>&1" ); if ((fp = popen(hostCmd,"r")) == (FILE *) NULL) { fileError("open pipe for",filename); goto wrapup; } cursswitch(&hourglass); changeButtons(BLANKbuttons); getChar(fp); h = readPic(fp,h); if( firstThing == TNULL ) firstThing = h; pclose(fp); cursSwitch(); wrapup: changeBrush(-1); changeButtons(INITbuttons); return(h); } eraseAll() { cursinhibit(); clearRegion( brushes[PIC] ); cursallow(); if (gridState==GRIDon) { drawGrid(); } } struct thing * doClear(h) struct thing *h; { deleteAllThings(h); eraseAll(); copyFlag = 0; textOutName = INITtextOutName; changeBrush(-1); changeButtons(INITbuttons); undo_clear(); scrollOffset.x = 0; scrollOffset.y = 0; return(TNULL); } struct thing * defineMacro( h, offset ) register struct thing * h; Point offset; { Point p, q; register struct thing *s, *t, *l = TNULL; Rectangle r; struct thing dummy; char *z; /* Temporary alloc space */ changeBrush(-1); /* Test to see if there is enough memory to create this macro */ if ((z=getSpace(sizeof(struct macro)+sizeof(struct thing))) == NULL) { return (h); } free (z); changeButtons(MACRObuttons); while( !button12() ) { if (P->state & RESHAPED) redrawLayer(); nap(2); } if( button1() ) { /* abort defining macro */ while( button1() ) nap(2); changeButtons(INITbuttons); return( h ); } p = sub( MOUSE_XY, offset ); q = trackMacro( p, offset ); r = canon( p, q ); /* Go through entire list of things moving those which are inside the rectangle r to a new list l. Must use a dummy thing as an end marker. */ t = insert(&dummy,h); /* Note: t is &dummy->next. */ while( t != &dummy ) { if (inside(r,t->bb)) { s = Remove(t); l = insert(t,l); /* If firstThing happens to point to t, reset to TNULL. It will be reset to point to the new macro below. */ if( firstThing == t ) firstThing = TNULL; t = s; } else { t = t->next; } } h = Remove(&dummy); if( (t = l) != TNULL ) { r = macroBB(l); /* Get outline of macro */ do { makeRelative(t,r.origin); /* Make things relative to this box */ t = t->next; } while (t != l); p = r.origin; /* Macro is located at original orig */ r = rsubp (r, r.origin); /* but the bb is made relative. */ h = insert(newMacro(p,recordMacro(l,r,NULL)),h); if( firstThing == TNULL ) firstThing = h; /* To insure new macro is first thing selected, back up h list by two elements! */ h = h->last->last; } changeButtons(INITbuttons); return(h); } Rectangle macroBB(l) struct thing *l; { Point p, q, p1, p2; register struct thing *t; Rectangle r; p.x = Xmax; p.y=YBOT; q.x=0; q.y=0; if ((t=l) != TNULL) { do { if ( (t->type == TEXT) || (t->type == ARC) ){ /* Expand out the bounding box to nearest alignment points to insure alignment of new macro. */ p1 = alignDown( t->bb.origin ); p2 = alignUp( t->bb.corner ); } else { p1 = t->bb.origin; p2 = t->bb.corner; } p.x = min(p.x,p1.x); p.y = min(p.y,p1.y); q.x = max(q.x,p2.x); q.y = max(q.y,p2.y); t=t->next; } while (t != l); } /* Add 1 to prevent zero size bounding box. */ if (p.x == q.x) q.x += 1; if (p.y == q.y) q.y += 1; r.origin = p; r.corner = q; return(r); } /* Find macro definition given name. */ struct macro * findMacro(s) register char *s; { struct macro *m; for( m=macroList; ((m!=MNULL) && (strcmp(s,m->name)!=0)); m=m->next) ; return(m); } /* Returns TRUE if macro id is unique. */ int uniqMacroId(id) register short id; { register struct macro * m; for( m=macroList; m!=MNULL; m=m->next) { if( m->id == id ) return FALSE; } return TRUE; } /* Returns an available macro id to be used for a new macro. */ short newMacroId() { register short i; /* Start from 0 to find an id available. Prevents big holes. */ for( i=0 ; !uniqMacroId(i) ; i++ ) ; return i; } /* Compare things in macros. Returns TRUE if macros are the same. Will recurse to check out nested macros. */ BOOL cmpMacroParts( p1, p2 ) register struct thing * p1; register struct thing * p2; { /* Create 2 macro things temporarily, so can call cmpThings. */ struct thing t1; struct thing t2; struct macro m1; struct macro m2; t1.type = MACRO; t2.type = MACRO; t1.origin = t2.origin = Pt(0,0); t1.otherValues.list = &m1; t2.otherValues.list = &m2; m1.parts = p1; m2.parts = p2; return cmpThings( &t1 , &t2 ); } /* This routine places a new macro at the start of the macro list. The head of the list is pointed to by macroList. The bounding box for the macro always has a relative origin of (0,0). */ struct macro * recordMacro(list,r,s) struct thing * list; /* List of things making up macro */ Rectangle r; /* BB of macro with origin at (0,0) */ char * s; /* Name of macro */ { register struct macro *m, *l, *n; int i; if( (m = (struct macro *) getSpace(sizeof(struct macro))) !=MNULL) { if( s == NULL ) { /* Macro has no name, so make up one. */ m->id = newMacroId(); m->name = getSpace(8); /* 'm' + 6 digits + '\0' */ sprintf( m->name, "m%d", m->id ); } else { /* Macro has a name. */ m->name = s; m->id = 0; if( (s[0] == 'm') && isdigit(s[1]) ) { /* Macro name assumed to be generated name. Find and store its id. */ i = 1; while( isdigit(s[i]) ) { m->id = (10 * m->id) + (s[i] - '0'); i++; } } } m->bb = r; m->useCount = 0; m->parts = list; /* Append macro to the end of the macro list */ l = MNULL; for (n=macroList; n!=MNULL; n=n->next) { l=n; } if (l == MNULL) { macroList = m; } else { l->next = m; } } return(m); } int inside(r,s) Rectangle r,s; { return((r.origin.x <= s.origin.x) && (r.origin.y <= s.origin.y) && (r.corner.x >= s.corner.x) && (r.corner.y >= s.corner.y)); } struct thing * makeRelative(t,p) register struct thing *t; Point p; { register int i; t->origin = sub(t->origin,p); switch(t->type) { case CIRCLE: case ELLIPSE: case TEXT: { break; } case LINE: { t->otherValues.end = sub(t->otherValues.end,p); break; } case BOX: { t->otherValues.corner = sub(t->otherValues.corner,p); break; } case ARC: { t->otherValues.arc.start = sub(t->otherValues.arc.start,p); t->otherValues.arc.end = sub(t->otherValues.arc.end,p); break; } case SPLINE: { for (i=0; i<=t->otherValues.spline.used; i++) { t->otherValues.spline.plist[i] = sub(t->otherValues.spline.plist[i],p); } break; } } boundingBox(t); return(t); } int backspaceOneWord(s,i) register char *s; register int i; { s[(i>0)? --i : 0] = '\0'; for ( ; i>0 && (isdigit(s[i-1]) || isletter(s[i-1])); ) { s[--i]='\0'; } return(i); } #ifdef DMD630 Rectangle canon (p1, p2) Point p1, p2; { Rectangle r; r.origin.x = min (p1.x, p2.x); r.origin.y = min (p1.y, p2.y); r.corner.x = max (p1.x, p2.x); r.corner.y = max (p1.y, p2.y); return (r); } #endif cursSwitch () { if (own() & MOUSE) { cursswitch(ptinrect(MOUSE_XY,brushes[PIC]) ? &crossHairs : (Texture16 *)0); } } static int kbdcount = 1; static int metafg = 0; static int counting = 0; static char *oldText = 0; /* Get a character from keyboard and add to text string associated with thing unless character is a control or ESC character in which case the string is edited via a subset (and extension) of emacs operations. (The CNTL-U & CNTL-W are the extensions to keep compatibility with the original cip and xcip.) The charPos is the position where editing occurs in the character string. Function returns the new charPos after editing. */ int editText( t, offset, charPos ) register struct thing * t; Point offset; int charPos; /* position where edited */ { register char * s; register int i,j,k; register char c; s = t->otherValues.text.s; i = charPos; draw(t,offset); /* erases present string. */ /* copy part of string before edit cursor into temporary buffer. */ strncpy(tempString,s,charPos); c = kbdchar(); #ifdef DMD5620 if (c >= 0x82 && c <= 0x89) { /* DMD function keys - load in entire string. */ j = c - 0x82; k = 0; while ((c = BRAM->pfkeys[j][i].byte) && (++k <= PFKEYSIZE)) { if (i >= MAXTEXT) { ringbell (); break; } else { tempString[i++] = c; } } } else { #endif if (c == 27 /* ESC */ ) { metafg = 1; } else if (counting && (c >= '0') && (c <= '9')) { /* Build up number of times to repeat argument. */ kbdcount = 10*kbdcount+c-'0'; } else if (metafg && (c >= '0') && (c <= '9')) { /* Start to build up number of times to repeat argument. */ counting = 1; metafg = 0; kbdcount = c-'0'; } else { while (kbdcount--) { if (metafg) { /* META operations. Characters preceded by the ESC. */ switch (c) { case 'f': /* Forward word. */ case 'd': /* Delete next word. */ while (tempString[charPos] && !(isdigit(tempString[charPos]) || isletter(tempString[charPos]))) charPos++; while (isdigit(tempString[charPos]) || isletter(tempString[charPos]) ) charPos++; if (c == 'f') i = charPos; break; case 'b': /* Back word. */ case 127: /* DELETE: Delete next word. */ case 'H'-'@': /* ^H: Delete previous word. */ while (i && !(isdigit(tempString[i-1]) || isletter(tempString[i-1]) ) ) i--; while (i && (isdigit(tempString[i-1]) || isletter(tempString[i-1]) ) ) i--; if (c == 'b') charPos = i; break; } } else { switch (c) { case 'A'-'@': /* ^A: Start of line. */ while (i && tempString[i-1] != '\r') i--; charPos = i; break; case 'B'-'@': /* ^B: Back 1 character. */ if (i) i--; charPos = i; break; case 'C'-'@': /* ^C: Capitalize. */ if (tempString[i] >= 'a' && tempString[i] <= 'z') tempString[i] -= 32; case 'F'-'@': /* ^F: Forward one character. */ if (tempString[i]) { i++; charPos = i; } break; case 'D'-'@': /* ^D: Delete next character. */ if (tempString[charPos]) charPos++; break; case 'E'-'@': /* ^E: End of line. */ while (tempString[i] && tempString[i] != '\r') i++; charPos = i; break; case 'H'-'@': /* ^H: Delete one character. */ if (i>0) i--; break; case 'K'-'@': /* ^K: Kill text after the cursor. */ while (tempString[charPos]) charPos++; break; case 'U'-'@': /* ^U: Delete all preceding text. */ i=0; break; case 'W'-'@': /* ^W: Backspace one word. */ i = backspaceOneWord( tempString, i ); break; case 'Y'-'@': /* ^Y: Retrieve last deletion. */ if (oldText) { j = 0; while (oldText[j] && i= MAXTEXT) { ringbell (); } else { tempString[i++] = c; } break; } } } kbdcount = 1; metafg = 0; counting = 0; j = charPos-i; if (j>0) { /* Save old text string. */ if (oldText != NULL) free(oldText); oldText = getSpace(j+1); strncpy(oldText,s+i,j); oldText[j] = 0; } } #ifdef DMD5620 } #endif /* Copy any part of string that was after edit cursor and null char. */ for( j=charPos, charPos=i; (tempString[i++] = s[j++]) != '\0'; ) ; free(s); s = getSpace(i); strcpy(s,tempString); t->otherValues.text.s = s; draw( t, offset ); /* display new string. */ return( charPos ); } drawText(p,s,just,spacing,f) Point p; /* point at center of text */ register char *s; short just; /* justification */ short spacing; Font *f; { register int line; /* line number */ register int lx; /* line x position */ register int ly; /* line y position */ register int q; register int m; int num; /* number of lines */ num = numLines(s); if( num == 0 ) return; ly = -( ( (fontheight(f)+spacing) * (num-1) ) >> 1 ); q = 0; for(line = 1; line <= num; line++) { for(m = 0; (s[q] != '\r') && (s[q] != '\0'); q++ ) tempString[m++] = s[q]; tempString[m] = '\0'; q++; switch (just) { case CENTER: lx = p.x - ( strwidth(f, tempString)>>1 ); break; case LEFTJUST: lx = p.x; break; case RIGHTJUST: lx = p.x - strwidth(f, tempString); break; } string(f, tempString,&display, Pt(lx, (p.y + ly)), F_XOR); ly = ly + (fontheight(f)+spacing); } } void StringSize(f,spacing,s,h,w) register int *h, *w; Font *f; register char *s; short spacing; { register int num; register int m,q; register int line; num = numLines(s); *h = (num * fontheight(f)) + ( (num-1) * spacing ); *w = 0; q = 0; for(line = 1; line <= num; line++) { for(m = 0; (s[q] != '\r') && (s[q] != '\0'); q++) tempString[m++] = s[q]; tempString[m] = '\0'; *w = max( *w, strwidth(f,tempString) ); q++; } *w = *w + 5; } #ifdef DMD630 /* Word is 16 bits. */ Word textMarker[] = { /* marker icon */ 0x0000, 0x0000, 0x0000, 0x0080, 0x0080, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0FF8, 0x0FF8, 0x0FF8, 0x0FF8, 0x0000, }; Word markerMask[] = { /* one bit bigger marker icon */ 0x0000, 0x0000, 0x0080, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0FF8, 0x0FF8, 0x1FFC, 0x1FFC, 0x1FFC, 0x1FFC, 0x1FFC, }; #endif #ifdef DMD5620 /* Word is 32 bits on DMD 5620. */ Word textMarker[] = { /* marker icon */ 0x00000000, 0x00000000, 0x00000000, 0x00800000, 0x00800000, 0x01C00000, 0x01C00000, 0x03E00000, 0x03E00000, 0x07F00000, 0x07F00000, 0x0FF80000, 0x0FF80000, 0x0FF80000, 0x0FF80000, 0x00000000, }; Word markerMask[] = { /* one bit bigger marker icon */ 0x00000000, 0x00000000, 0x00800000, 0x01C00000, 0x01C00000, 0x03E00000, 0x03E00000, 0x07F00000, 0x07F00000, 0x0FF80000, 0x0FF80000, 0x1FFC0000, 0x1FFC0000, 0x1FFC0000, 0x1FFC0000, 0x1FFC0000, }; #endif #define MARKERWID 16 #define MARKERHT 16 #ifdef DMDTERM Word bgsave[MARKERHT]; /* Space to save background */ Bitmap markerbm = { textMarker, /* Will be changed to markerMask and back */ 1, 0, 0, MARKERWID, MARKERHT, 0 }; #endif /* DMDTERM */ int moveTextSpot(t,offset) struct thing * t; Point offset; { register char * s; register int i; /* position in text string */ int istart; /* saves start of line */ register int j; /* position in temp string */ register int line; /* line number */ register int x; /* line x position */ register int y; /* line y position */ Point m; /* mouse position */ Point pt; /* text marker point */ int spacing; int prevI; /* previous position in text string */ int w; /* string or character width */ int num; /* number of lines */ short just; /* justification */ Font * f; s = t->otherValues.text.s; f = t->otherValues.text.f->f; just = t->otherValues.text.just; spacing = fontheight(f) + t->otherValues.text.spacing; pt.x = offset.x+16; pt.y = offset.y+16; cursinhibit(); #ifdef X11 bitblt( &display, raddp(bgsave.rect,pt), &bgsave,bgsave.rect.origin, F_STORE ); #else markerbm.base = bgsave; /* save initial background */ bitblt( &display, raddp(markerbm.rect,pt), &markerbm,markerbm.rect.origin, F_STORE ); #endif /* X11 */ prevI = -1; do { m = sub(MOUSE_XY,offset); num = numLines(s); x = t->origin.x; y = t->origin.y - ( ( spacing * (num-1) ) >> 1 ); /* Skip over any text lines above mouse position, except * do not skip over last line even if mouse is below it. */ i = 0; line = 1; for (; (line < num) && (m.y >= (y + spacing)); line++) { while (s[i++] != '\r') ; y += spacing; } /* Form string from only this line's characters. */ istart = i; /* Save start of current line */ for (j=0; (s[i] != '\r') && (s[i] != '\0'); ) { tempString[j++] = s[i++]; } tempString[j] = '\0'; /* Adjust x for justification */ w = strwidth( f, tempString); switch (just) { case CENTER: x = t->origin.x - ( w >> 1 ); break; case LEFTJUST: x = t->origin.x; break; case RIGHTJUST: x = t->origin.x - w; break; } i = istart; /* Back to start of line */ /* Find character hit */ while (( x <= m.x) && (s[i] != '\0') && (s[i] != '\r')) { x += fontwidth(f,s[i]); /* Char width */ i++; } if( i != prevI ) { prevI = i; /* restore background */ #ifdef X11 bitblt(&bgsave, bgsave.rect, &display, pt, F_STORE); #else markerbm.base = bgsave; bitblt(&markerbm, markerbm.rect, &display, pt, F_STORE); #endif /* X11 */ pt.x = x - 9 + offset.x; pt.y = y + fontheight(f) - (fontheight(f)>>2) -4 + offset.y; /* save background */ #ifdef X11 bitblt( &display, raddp(bgsave.rect,pt), &bgsave,bgsave.rect.origin, F_STORE ); bitblt( &markermaskbm, markermaskbm.rect, &display, pt, F_CLR ); bitblt( &markerbm, markerbm.rect, &display, pt, F_OR ); #else bitblt( &display, raddp(markerbm.rect,pt), &markerbm,markerbm.rect.origin, F_STORE ); markerbm.base = markerMask; /* make dark edge */ bitblt( &markerbm, markerbm.rect, &display, pt, F_OR ); markerbm.base = textMarker; /* draw marker */ bitblt( &markerbm, markerbm.rect, &display, pt, F_XOR ); #endif /* X11 */ /* Note: F_OR & F_XOR used when marking on * highlighted area; F_CLR & F_OR otherwise. */ } nap(2); } while( button1() ); /* restore background */ #ifdef X11 bitblt( &bgsave, bgsave.rect, &display, pt, F_STORE ); #else markerbm.base = bgsave; bitblt( &markerbm, markerbm.rect, &display, pt, F_STORE ); #endif /* X11 */ cursallow(); return( i ); } /* Like strcmp in string(3C). Compares two character strings, returns less than, equal to, or greater than 0, according as s1 is lexicographically less than, equal to, or greater than s2. */ int strcmp(s1,s2) register char *s1, *s2; { while ( *s1!='\0' && *s2!='\0' && *s1==*s2) { s1++; s2++; } if( *s1=='\0' && *s2=='\0' ) return 0; if( *s1=='\0' ) return -1; if( *s2=='\0' ) return 1; if( *s1 < *s2 ) return -1; else return 1; } xcip/630/0000755000175300001440000000000011513632542010656 5ustar meusersxcip/README-20110000644000175300001440000000056311513632737011621 0ustar meusersThis is a lightly patched version of xcip that runs on X11 on modern (Ubuntu 10.10 / i386 tested) systems. Run 'make x11' in the root to build xcip.x11; make clobberx11 cleans. You will need to use the Plan9port version of lex to build this; the path to p9p's lex is coded as LEX_CMD in JPIC/makefile. Make sure to set this to the patch of your p9p lex. Cheers, -- vs xcip/JPIC/0000755000175300001440000000000011513632667011103 5ustar meusersxcip/JPIC/textgen.c0000644000175300001440000000163411513632543012722 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *textgen(s, garb) { int i, dx, dy, type; struct obj *p, *ppos; type = 'C'; dx = dy = 0; for (i = 0; i < nattr; i++) switch (attr[i].a_type) { case LEFT: dx -= attr[i].a_val; break; case RIGHT: dx += attr[i].a_val; break; case UP: dy += attr[i].a_val; break; case DOWN: dy -= attr[i].a_val; break; case AT: ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; break; case LJUST: type = 'L'; break; case RJUST: type = 'R'; break; case SPREAD: type = 'S'; break; case FILL: type = 'F'; break; case ABOVE: type = 'A'; break; case BELOW: type = 'B'; break; } dprintf("T %c %s\n", type, s); extreme(curx, cury); curx += dx; cury += dy; extreme(curx, cury); p = makenode(TEXT, 2); p->o_val[0] = s; p->o_val[1] = type; return(p); } xcip/JPIC/symtab.c0000644000175300001440000000256311513632543012545 0ustar meusers#include #include "pic.h" #include "y.tab.h" extern char *tostring(); getvar(s) /* return value of variable s */ char *s; { struct symtab *p; p = lookup(s); if (p == NULL) { if ((s[0] >= 'a') && (s[0] <= 'z')) yyerror("no such variable as %s", s); else yyerror("no such place as %s", s); return(0); } return(p->s_val); } struct symtab *makevar(s, t, v) /* make variable named s in table */ char *s; /* assumes s is static or from tostring */ int t; int v; { struct symtab *p; for (p = stack[nstack].p_symtab; p != NULL; p = p->s_next) if (strcmp(s, p->s_name) == 0) break; if (p == NULL) { /* it's a new one */ p = (struct symtab *) malloc(sizeof(struct symtab)); if (p == NULL) { yyerror("out of symtab space with %s", s); exit(1); } p->s_next = stack[nstack].p_symtab; stack[nstack].p_symtab = p; /* stick it at front */ } p->s_name = s; p->s_type = t; p->s_val = v; return(p); } struct symtab *lookup(s) /* find s in symtab */ char *s; { int i; struct symtab *p; for (i = nstack; i >= 0; i--) /* look in each active symtab */ for (p = stack[i].p_symtab; p != NULL; p = p->s_next) if (strcmp(s, p->s_name) == 0) return(p); return(NULL); } freesymtab(p) /* free space used by symtab at p */ struct symtab *p; { for ( ; p != NULL; p = p->s_next) { free(p->s_name); /* assumes done with tostring */ free(p); } } xcip/JPIC/misc.c0000644000175300001440000001474211513632543012203 0ustar meusers#include #include "pic.h" #include "y.tab.h" setdir(n) /* set direction from n */ int n; { switch (n) { case UP: hvmode = U_DIR; break; case DOWN: hvmode = D_DIR; break; case LEFT: hvmode = L_DIR; break; case RIGHT: hvmode = R_DIR; break; } return(hvmode); } coord getcomp(p, t) /* return component of a position */ struct obj *p; int t; { switch (t) { case DOTX: return(p->o_x); case DOTY: return(p->o_y); case DOTWID: switch (p->o_type) { case BOX: case BLOCK: return(p->o_val[0]); case CIRCLE: case ELLIPSE: return(2 * p->o_val[0]); case LINE: case ARROW: return(p->o_val[0] - p->o_x); } case DOTHT: switch (p->o_type) { case BOX: case BLOCK: return(p->o_val[1]); case CIRCLE: case ELLIPSE: return(2 * p->o_val[1]); case LINE: case ARROW: return(p->o_val[1] - p->o_y); } case DOTRAD: switch (p->o_type) { case CIRCLE: case ELLIPSE: return(p->o_val[0]); } } } makeattr(type, val) /* add attribute type and val */ int type; int val; /* typing probably wrong */ { if (type == 0 && val == 0) { /* clear table for next stat */ nattr = 0; return; } dprintf("attr %d: %d %d\n", nattr, type, val); attr[nattr].a_type = type; attr[nattr].a_val = val; nattr++; } printexpr(n) /* print expression for debugging */ int n; { dprintf("%d\n", n); } printpos(p) /* print position for debugging */ struct obj *p; { dprintf("%d, %d\n", p->o_x, p->o_y); } char *tostring(s) register char *s; { register char *p; p = malloc(strlen(s)+1); if (p == NULL) { yyerror("out of space in tostring on %s", s); exit(1); } strcpy(p, s); return(p); } struct obj *makepos(x, y) /* make a position cell */ coord x; coord y; { struct obj *p; p = makenode(PLACE, 0); p->o_x = x; p->o_y = y; return(p); } float between; /* stores fraction from lex analyzer */ float lastfloat; /* last float seen in lex */ struct obj *makebetween(fract, p1, p2) /* make position between p1 and p2 */ int fract; struct obj *p1, *p2; { struct obj *p; dprintf("fraction = %.2f\n", between); p = makenode(PLACE, 0); p->o_x = p1->o_x + between * (p2->o_x - p1->o_x) + 0.5; p->o_y = p1->o_y + between * (p2->o_y - p1->o_y) + 0.5; return(p); } struct obj *getpos(p, corner) /* find position of point */ struct obj *p; int corner; { coord x, y, x1, y1; dprintf("getpos %o %d\n", p, corner); x = p->o_x; y = p->o_y; x1 = p->o_val[0]; y1 = p->o_val[1]; switch (p->o_type) { case PLACE: break; case BOX: case BLOCK: switch (corner) { case NORTH: y += y1 / 2; break; case SOUTH: y -= y1 / 2; break; case EAST: x += x1 / 2; break; case WEST: x -= x1 / 2; break; case NE: x += x1 / 2; y += y1 / 2; break; case SW: x -= x1 / 2; y -= y1 / 2; break; case SE: x += x1 / 2; y -= y1 / 2; break; case NW: x -= x1 / 2; y += y1 / 2; break; case START: if (p->o_type == BLOCK) return getpos(objlist[p->o_val[2]], START); case END: if (p->o_type == BLOCK) return getpos(objlist[p->o_val[3]], END); } break; case CIRCLE: case ELLIPSE: switch (corner) { case NORTH: y += y1; break; case SOUTH: y -= y1; break; case EAST: x += x1; break; case WEST: x -= x1; break; case NE: x += 0.707 * x1; y += 0.707 * y1; break; case SE: x += 0.707 * x1; y -= 0.707 * y1; break; case NW: x -= 0.707 * x1; y += 0.707 * y1; break; case SW: x -= 0.707 * x1; y -= 0.707 * y1; break; } break; case LINE: case SPLINE: case ARROW: case MOVE: switch (corner) { case START: break; /* already in place */ case END: x = x1; y = y1; break; case CENTER: x = (x+x1)/2; y = (y+y1)/2; break; case NORTH: if (y1 > y) { x = x1; y = y1; } break; case SOUTH: if (y1 < y) { x = x1; y = y1; } break; case EAST: if (x1 > x) { x = x1; y = y1; } break; case WEST: if (x1 < x) { x = x1; y = y1; } break; } break; case ARC: switch (corner) { case START: if (p->o_attr & CW_ARC) { x = p->o_val[2]; y = p->o_val[3]; } else { x = x1; y = y1; } break; case END: if (p->o_attr & CW_ARC) { x = x1; y = y1; } else { x = p->o_val[2]; y = p->o_val[3]; } break; } break; } dprintf("getpos returns %d %d\n", x, y); return(makepos(x, y)); } struct obj *gethere(n) /* make a place for curx,cury */ { dprintf("gethere %d %d\n", curx, cury); return(makepos(curx, cury)); } struct obj *getlast(n, t) /* find n-th previous occurrence of type t */ int n, t; { int i, k; struct obj *p; k = n; for (i = nobj-1; i >= 0; i--) { p = objlist[i]; if (p->o_type == BLOCKEND) { i = p->o_val[4]; continue; } if (p->o_type != t) continue; if (--k > 0) continue; /* not there yet */ dprintf("got a last of x,y= %d,%d\n", p->o_x, p->o_y); return(p); } yyerror("there is no %dth last", n); return(NULL); } struct obj *getfirst(n, t) /* find n-th occurrence of type t */ int n, t; { int i, k; struct obj *p; k = n; for (i = 0; i < nobj; i++) { p = objlist[i]; if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */ i = p->o_val[5] + 1; continue; } if (p->o_type != t) continue; if (--k > 0) continue; /* not there yet */ dprintf("got a first of x,y= %d,%d\n", p->o_x, p->o_y); return(p); } yyerror("there is no %dth ", n); return(NULL); } struct obj *getblock(p, s) /* find variable s in block p */ struct obj *p; char *s; { struct symtab *stp; if (p->o_type != BLOCK) { yyerror(".%s is not in that block", s); return(NULL); } for (stp = (struct symtab *) p->o_val[6]; stp != NULL; stp = stp->s_next) if (strcmp(s, stp->s_name) == 0) { dprintf("getblock found s_type=%d, s_val=%d\n", stp->s_type, stp->s_val); return((struct obj *)stp->s_val); } yyerror("there is no .%s in that []", s); return(NULL); } struct obj *fixpos(p, x, y) struct obj *p; coord x, y; { dprintf("fixpos returns %d %d\n", p->o_x + x, p->o_y + y); return(makepos(p->o_x + x, p->o_y + y)); } struct obj *makenode(type, n) int type, n; { struct obj *p; p = (struct obj *) malloc(sizeof(struct obj) + (n-1)*sizeof(coord)); if (p == NULL) { yyerror("out of space in makenode\n"); exit(1); } p->o_type = type; p->o_count = n; p->o_nobj = nobj; p->o_mode = hvmode; p->o_x = curx; p->o_y = cury; p->o_nt1 = ntext1; p->o_nt2 = ntext; ntext1 = ntext; /* ready for next caller */ p->o_attr = p->o_dotdash = p->o_ddval = 0; if (nobj >= MAXOBJ) { yyerror("objlist overflow\n"); exit(1); } objlist[nobj++] = p; return(p); } extreme(x, y) /* record max and min x and y values */ { if (x > xmax) xmax = x; if (y > ymax) ymax = y; if (x < xmin) xmin = x; if (y < ymin) ymin = y; } xcip/JPIC/epic.c0000644000175300001440000000227011513632544012162 0ustar meusers#include int dbg; int jpflag; main(argc, argv) char *argv[]; { FILE *pfp, *f, *popen(); int c; char buf[100], fname[100], *whichjerq, cmd[100]; char *getenv(); whichjerq = getenv("JERQ"); while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { case 'd': dbg = 1; break; case 'j': jpflag = 1; break; } argc--; argv++; } if (argc > 1) strcpy(fname, argv[1]); if (jpflag == 0) system("run /usr/bwk/pic/jp"); sprintf(cmd, "/usr/bwk/pic/pic >/dev/%s", whichjerq); if ((pfp = popen(cmd, "w")) == NULL) { fprintf(stderr, "epic: can't open pic\n"); exit(2); } while (fgets(buf, sizeof buf, stdin) != NULL) { switch (buf[0]) { case 'q': exit(0); break; case '\n': case 'p': f = fopen(fname, "r"); while ((c = getc(f)) != EOF) putc(c, pfp); fflush(pfp); fclose(f); break; case 'e': if (sscanf(buf, "%*s %s", fname) > 0) printf("editing file %s\n", fname); else sprintf(buf, "e %s", fname); system(buf); break; case 'f': sscanf(buf, "%*s %s", fname); printf("%s\n", fname); break; case '!': system(buf+1); printf("!\n"); break; default: printf("eh?\n"); break; } } } xcip/JPIC/lex.yy.c0000644000175300001440000012342711513632543012501 0ustar meuserstypedef unsigned char Uchar; # include # define U(x) x # define NLSTATE yyprevious=YYNEWLINE # define BEGIN yybgin = yysvec + 1 + # define INITIAL 0 # define YYLERR yysvec # define YYSTATE (yyestate-yysvec-1) # define YYOPTIM 1 # define YYLMAX 200 # define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;} # define yymore() (yymorfg=1) # define ECHO fprintf(yyout, "%s",yytext) # define REJECT { nstr = yyreject(); goto yyfussy;} int yyleng; extern char yytext[]; int yymorfg; extern Uchar *yysptr, yysbuf[]; int yytchar; FILE *yyin, *yyout; extern int yylineno; struct yysvf { struct yywork *yystoff; struct yysvf *yyother; int *yystops;}; struct yysvf *yyestate; extern struct yysvf yysvec[], *yybgin; int yylook(void), yywrap(void), yyback(int *, int); # define output(c) putc(c,yyout) # define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) #define A 2 #define str 4 #define comment 6 #define def 8 #define sc 10 #define br 12 #undef input #undef unput #include "pic.h" #include "y.tab.h" extern double atof(); extern int dbg; #define dprintf if(dbg)printf extern int yylval; extern struct symtab symtab[]; extern char *filename; extern int synerr; extern float lastfloat; #define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;} #define CBUFLEN 150 char cbuf[CBUFLEN]; int clen, cflag; #define YYNEWLINE 10 int yylex(void){ int nstr; extern int yyprevious; if(yyprevious){} switch (yybgin-yysvec-1) { /* witchcraft */ case 0: BEGIN A; break; case sc: BEGIN A; return('}'); case br: BEGIN A; return(']'); } while((nstr = yylook()) >= 0){ goto yyfussy; yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: ; break; case 2: ; break; case 3: { return(ST); } break; case 4: { return(ST); } break; case 5: { BEGIN sc; return(ST); } break; case 6: { BEGIN br; return(ST); } break; case 7: { if (yytext[1] == 'P' && (yytext[2] == 'E' || yytext[2] == 'F')) { yylval = yytext[2]; return(EOF); } else { yylval = tostring(yytext); return(TROFF); } } break; case 8: return(yylval = PRINT); break; case 9: return(yylval = BOX); break; case 10: return(yylval = CIRCLE); break; case 11: return(yylval = ARC); break; case 12: return(yylval = ELLIPSE); break; case 13: return(yylval = ARROW); break; case 14: return(yylval = SPLINE); break; case 15: return(yylval = LINE); break; case 16: return(yylval = MOVE); break; case 17: return(yylval = BLOCK); break; case 18: return(SAME); break; case 19: return(BETWEEN); break; case 20: return(AND); break; case 21: ; break; case 22: ; break; case 23: ; break; case 24: { yylval = EAST; return(CORNER); } break; case 25: { yylval = EAST; return(CORNER); } break; case 26: { yylval = EAST; return(CORNER); } break; case 27: { yylval = EAST; return(CORNER); } break; case 28: { yylval = WEST; return(CORNER); } break; case 29: { yylval = WEST; return(CORNER); } break; case 30: { yylval = WEST; return(CORNER); } break; case 31: { yylval = WEST; return(CORNER); } break; case 32: { yylval = NORTH; return(CORNER); } break; case 33: { yylval = NORTH; return(CORNER); } break; case 34: { yylval = NORTH; return(CORNER); } break; case 35: { yylval = NORTH; return(CORNER); } break; case 36: { yylval = SOUTH; return(CORNER); } break; case 37: { yylval = SOUTH; return(CORNER); } break; case 38: { yylval = SOUTH; return(CORNER); } break; case 39: { yylval = SOUTH; return(CORNER); } break; case 40: { yylval = SOUTH; return(CORNER); } break; case 41: { yylval = CENTER; return(CORNER); } break; case 42: { yylval = CENTER; return(CORNER); } break; case 43: { yylval = START; return(CORNER); } break; case 44: { yylval = END; return(CORNER); } break; case 45: { yylval = NE; return(CORNER); } break; case 46: { yylval = NE; return(CORNER); } break; case 47: { yylval = SE; return(CORNER); } break; case 48: { yylval = SE; return(CORNER); } break; case 49: { yylval = NW; return(CORNER); } break; case 50: { yylval = NW; return(CORNER); } break; case 51: { yylval = SW; return(CORNER); } break; case 52: { yylval = SW; return(CORNER); } break; case 53: { yylval = NORTH; return(CORNER); } break; case 54: { yylval = NORTH; return(CORNER); } break; case 55: { yylval = SOUTH; return(CORNER); } break; case 56: { yylval = SOUTH; return(CORNER); } break; case 57: { yylval = WEST; return(CORNER); } break; case 58: { yylval = WEST; return(CORNER); } break; case 59: { yylval = EAST; return(CORNER); } break; case 60: { yylval = EAST; return(CORNER); } break; case 61: { yylval = CENTER; return(CORNER); } break; case 62: { yylval = START; return(CORNER); } break; case 63: { yylval = END; return(CORNER); } break; case 64: { yylval = NE; return(CORNER); } break; case 65: { yylval = NW; return(CORNER); } break; case 66: { yylval = SE; return(CORNER); } break; case 67: { yylval = SW; return(CORNER); } break; case 68: { yylval = HEIGHT; return(ATTR); } break; case 69: { yylval = HEIGHT; return(ATTR); } break; case 70: { yylval = WIDTH; return(ATTR); } break; case 71: { yylval = WIDTH; return(ATTR); } break; case 72: { yylval = RADIUS; return(ATTR); } break; case 73: { yylval = RADIUS; return(ATTR); } break; case 74: { yylval = DIAMETER; return(ATTR); } break; case 75: { yylval = DIAMETER; return(ATTR); } break; case 76: { yylval = SIZE; return(ATTR); } break; case 77: { yylval = LEFT; return(DIR); } break; case 78: { yylval = RIGHT; return(DIR); } break; case 79: { yylval = UP; return(DIR); } break; case 80: { yylval = DOWN; return(DIR); } break; case 81: { yylval = CW; return(ATTR); } break; case 82: { yylval = CCW; return(ATTR); } break; case 83: { yylval = THEN; return(ATTR); } break; case 84: { yylval = INVIS; return(ATTR); } break; case 85: { yylval = INVIS; return(ATTR); } break; case 86: return(yylval = DOT); break; case 87: return(yylval = DOT); break; case 88: return(yylval = DASH); break; case 89: return(yylval = DASH); break; case 90: return(yylval = CHOP); break; case 91: return(yylval = SPREAD); break; case 92: return(yylval = FILL); break; case 93: return(yylval = LJUST); break; case 94: return(yylval = RJUST); break; case 95: return(yylval = ABOVE); break; case 96: return(yylval = BELOW); break; case 97: { yylval = HEAD1; return(HEAD); } break; case 98: { yylval = HEAD2; return(HEAD); } break; case 99: { yylval = HEAD12; return(HEAD); } break; case 100: return(yylval = DOTX); break; case 101: return(yylval = DOTY); break; case 102: return(yylval = DOTHT); break; case 103: return(yylval = DOTHT); break; case 104: return(yylval = DOTWID); break; case 105: return(yylval = DOTWID); break; case 106: return(yylval = DOTRAD); break; case 107: return(yylval = DOTRAD); break; case 108: return(yylval = FROM); break; case 109: return(yylval = TO); break; case 110: return(yylval = AT); break; case 111: return(yylval = BY); break; case 112: return(yylval = WITH); break; case 113: return(yylval = LAST); break; case 114: return(yylval = HERE); break; case 115: { BEGIN def; } break; case 116: { yylval = definition(yytext); BEGIN A; return(TROFF); } break; case 117: { yylval = 1; return(NTH); } break; case 118: { yylval = atoi(yytext); return(NTH); } break; case 119: { int i, inch; inch = 0; for (i = 0; i < yyleng; i++) if (yytext[i] == '.' || yytext[i] == 'i') { inch++; break; } if (inch) yylval = atof(yytext) * getvar("scale") + 0.5; else yylval = atoi(yytext); lastfloat = atof(yytext); return(NUMBER); } break; case 120: { int c; char buf[100]; struct symtab *p; p = lookup(yytext); if (p != NULL && p->s_type == DEFNAME) { yylval = defuse(yytext, p); return(TROFF); } else if ((yytext[0] >= 'a') && (yytext[0] <= 'z')) { yylval = (int) tostring(yytext); return(VARNAME); } else { yylval = (int) tostring(yytext); return(PLACENAME); } } break; case 121: { BEGIN str; clen=0; } break; case 122: { BEGIN comment; } break; case 123: { BEGIN A; return(ST); } break; case 124: ; break; case 125: { yylval = yytext[0]; return(yytext[0]); } break; case 126: { BEGIN A; cbuf[clen]=0; yylval = tostring(cbuf); return(TEXT); } break; case 127: { yyerror("newline in string"); BEGIN A; return(ST); } break; case 128: { cbuf[clen++]='"'; } break; case 129: { cbuf[clen++]='\t'; } break; case 130: { cbuf[clen++]='\\'; } break; case 131: { CADD; } break; case -1: break; default: fprintf(yyout,"bad switch yylook %d",nstr); }} return(0); } /* end of yylex */ int yyvstop[] = { 0, 125, 0, 1, 125, 0, 3, 0, 121, 125, 0, 122, 125, 0, 125, 0, 125, 0, 119, 125, 0, 4, 125, 0, 125, 0, 120, 125, 0, 120, 125, 0, 125, 0, 125, 0, 6, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 120, 125, 0, 5, 125, 0, 7, 125, 0, 131, 0, 127, 0, 126, 131, 0, 131, 0, 124, 0, 123, 0, 116, 0, 98, 0, 119, 0, 38, 0, 41, 0, 24, 0, 30, 0, 32, 0, 26, 0, 36, 0, 34, 0, 28, 0, 100, 0, 101, 0, 119, 0, 119, 0, 119, 0, 97, 0, 120, 0, 120, 0, 17, 0, 2, 0, 120, 0, 120, 0, 120, 0, 110, 120, 0, 120, 0, 120, 0, 111, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 81, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 69, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 21, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 109, 120, 0, 79, 120, 0, 120, 0, 120, 0, 120, 0, 7, 0, 7, 119, 0, 7, 38, 0, 7, 41, 0, 7, 24, 0, 7, 0, 7, 30, 0, 7, 32, 0, 7, 26, 0, 7, 36, 0, 7, 34, 0, 7, 0, 7, 28, 0, 7, 100, 0, 7, 101, 0, 128, 0, 130, 0, 129, 0, 102, 0, 45, 0, 49, 0, 47, 0, 51, 0, 118, 0, 99, 0, 120, 0, 120, 0, 20, 120, 0, 11, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 9, 120, 0, 82, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 86, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 72, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 22, 120, 0, 120, 0, 120, 0, 23, 120, 0, 120, 0, 70, 120, 0, 120, 0, 7, 119, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 102, 0, 7, 0, 7, 0, 7, 45, 0, 7, 0, 7, 49, 0, 7, 0, 7, 0, 7, 47, 0, 7, 0, 7, 0, 7, 51, 0, 7, 0, 7, 0, 7, 0, 7, 0, 39, 0, 44, 0, 106, 0, 35, 0, 104, 0, 114, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 90, 120, 0, 120, 0, 88, 120, 0, 120, 0, 74, 120, 0, 120, 0, 80, 120, 0, 120, 0, 120, 0, 92, 120, 0, 120, 0, 108, 120, 0, 120, 0, 120, 0, 113, 120, 0, 77, 120, 0, 15, 120, 0, 120, 0, 120, 0, 16, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 18, 120, 0, 76, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 83, 120, 0, 120, 0, 120, 0, 120, 0, 112, 120, 0, 7, 39, 0, 7, 0, 7, 0, 7, 44, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 106, 0, 7, 0, 7, 0, 7, 0, 7, 35, 0, 7, 0, 7, 0, 7, 104, 0, 25, 0, 31, 0, 29, 0, 95, 120, 0, 13, 120, 0, 96, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 117, 120, 0, 120, 0, 84, 120, 0, 93, 120, 0, 120, 0, 120, 0, 8, 120, 0, 120, 0, 78, 120, 0, 94, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 120, 0, 71, 120, 0, 7, 0, 7, 0, 7, 25, 0, 7, 0, 7, 31, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 29, 0, 7, 0, 33, 0, 27, 0, 37, 0, 43, 0, 105, 0, 120, 0, 120, 0, 120, 0, 10, 120, 0, 89, 120, 0, 120, 0, 120, 0, 87, 120, 0, 120, 0, 63, 0, 68, 120, 0, 120, 0, 73, 120, 0, 14, 120, 0, 91, 120, 0, 53, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 33, 0, 7, 0, 7, 27, 0, 7, 37, 0, 7, 43, 0, 7, 0, 7, 105, 0, 40, 0, 42, 0, 103, 0, 107, 0, 19, 120, 0, 115, 0, 120, 0, 60, 0, 12, 120, 0, 120, 0, 57, 0, 58, 0, 7, 40, 0, 7, 42, 0, 7, 103, 0, 7, 0, 7, 0, 7, 107, 0, 7, 0, 7, 0, 75, 120, 0, 120, 0, 54, 0, 59, 0, 56, 0, 62, 0, 7, 0, 7, 0, 7, 0, 7, 0, 55, 0, 61, 0, 85, 120, 0, 7, 0, 7, 0, 7, 0, 7, 0, 52, 0, 50, 0, 7, 52, 0, 7, 0, 7, 50, 0, 7, 0, 48, 0, 46, 0, 7, 48, 0, 7, 46, 0, 67, 0, 65, 0, 66, 0, 64, 0, 0}; # define YYTYPE int struct yywork { YYTYPE verify, advance; } yycrank[] = { 0,0, 0,0, 3,15, 0,0, 7,54, 0,0, 0,0, 0,0, 0,0, 0,0, 3,16, 3,17, 7,54, 7,55, 28,83, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 3,18, 3,19, 0,0, 0,0, 6,52, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 3,20, 3,21, 24,79, 3,22, 0,0, 7,54, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 3,23, 3,24, 0,0, 20,57, 0,0, 79,171, 3,25, 0,0, 7,54, 0,0, 4,18, 4,19, 0,0, 3,26, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 4,20, 4,49, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 3,27, 3,28, 3,29, 4,23, 4,24, 6,53, 3,30, 3,31, 3,32, 3,33, 3,34, 3,35, 26,81, 3,36, 3,37, 27,82, 4,26, 3,38, 3,39, 3,40, 3,41, 3,42, 37,107, 3,43, 3,44, 3,45, 3,46, 39,113, 3,47, 35,103, 40,114, 5,50, 41,115, 42,116, 3,48, 4,27, 4,28, 4,29, 35,104, 5,50, 5,51, 4,30, 4,31, 4,32, 4,33, 4,34, 4,35, 31,88, 4,36, 4,37, 30,84, 46,127, 4,38, 4,39, 4,40, 4,41, 4,42, 31,89, 4,43, 4,44, 4,45, 4,46, 30,85, 4,47, 5,52, 36,105, 30,86, 31,90, 30,87, 4,48, 32,91, 34,100, 32,92, 33,96, 59,149, 32,93, 32,94, 33,97, 5,50, 45,125, 36,106, 33,98, 34,101, 43,117, 34,102, 47,128, 45,126, 33,99, 60,150, 47,129, 32,95, 43,118, 43,119, 47,130, 67,166, 5,50, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 5,53, 68,167, 53,146, 75,170, 9,56, 77,170, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 9,56, 21,58, 21,58, 21,58, 21,58, 21,58, 21,58, 21,58, 21,58, 21,58, 21,58, 78,170, 22,72, 81,172, 22,73, 22,73, 22,73, 22,73, 22,73, 22,73, 22,73, 22,73, 22,73, 22,73, 38,108, 63,155, 44,120, 62,153, 38,109, 53,147, 61,151, 65,160, 38,110, 38,111, 44,121, 63,156, 84,173, 64,157, 38,112, 65,161, 44,122, 44,123, 62,154, 61,152, 69,168, 44,124, 85,174, 64,158, 69,169, 86,175, 88,177, 21,59, 21,60, 53,148, 21,61, 64,159, 89,179, 21,62, 88,178, 91,181, 89,180, 21,63, 92,182, 21,64, 86,176, 93,183, 94,184, 21,65, 21,66, 21,67, 21,68, 22,74, 21,69, 21,70, 21,71, 96,185, 22,75, 97,186, 98,187, 100,190, 22,76, 22,77, 22,78, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 99,188, 101,191, 102,192, 99,189, 104,195, 105,196, 107,197, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 108,198, 109,199, 110,200, 111,201, 25,80, 112,202, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 25,80, 49,131, 103,193, 113,203, 114,204, 116,205, 117,206, 118,207, 103,194, 49,131, 49,0, 56,56, 56,56, 56,56, 56,56, 56,56, 56,56, 56,56, 56,56, 56,56, 56,56, 58,58, 58,58, 58,58, 58,58, 58,58, 58,58, 58,58, 58,58, 58,58, 58,58, 66,162, 119,208, 120,209, 121,210, 122,211, 123,212, 124,214, 125,215, 126,216, 127,217, 66,163, 123,213, 128,218, 129,219, 130,220, 66,164, 132,0, 49,132, 66,165, 72,72, 72,72, 72,72, 72,72, 72,72, 72,72, 72,72, 72,72, 72,72, 72,72, 131,131, 130,221, 133,0, 134,0, 135,0, 49,131, 136,0, 137,0, 131,131, 131,0, 138,0, 142,0, 139,0, 141,0, 143,0, 140,131, 144,0, 145,0, 58,74, 149,244, 150,245, 151,246, 152,247, 140,131, 140,0, 132,132, 153,248, 155,249, 156,250, 158,251, 160,252, 161,253, 163,254, 164,255, 166,256, 167,257, 168,258, 169,259, 49,133, 49,134, 172,260, 49,135, 173,261, 176,262, 49,136, 177,263, 178,264, 131,131, 49,137, 179,265, 49,138, 182,266, 183,267, 184,268, 49,139, 49,140, 49,141, 49,142, 185,269, 49,143, 49,144, 49,145, 140,131, 186,270, 131,131, 187,271, 188,272, 189,273, 190,274, 191,275, 192,276, 193,277, 194,278, 195,279, 196,280, 197,281, 198,282, 199,283, 200,284, 140,131, 201,285, 202,286, 132,222, 203,287, 204,288, 205,289, 206,290, 207,291, 208,292, 209,293, 210,294, 135,225, 211,295, 212,296, 134,224, 213,297, 214,298, 136,227, 137,229, 139,234, 215,299, 138,231, 216,300, 133,223, 135,226, 143,242, 217,301, 139,235, 137,230, 143,243, 219,302, 138,232, 136,228, 142,241, 141,240, 140,236, 220,303, 221,304, 222,0, 138,233, 223,0, 224,0, 225,0, 226,0, 227,0, 140,237, 228,0, 230,0, 229,0, 231,0, 140,238, 232,0, 233,0, 140,239, 234,0, 235,0, 236,0, 237,0, 238,0, 239,0, 240,0, 241,0, 242,0, 243,0, 244,321, 245,322, 246,323, 248,324, 249,325, 250,326, 251,327, 252,328, 253,329, 254,330, 255,331, 257,332, 258,333, 259,334, 261,335, 262,336, 263,337, 264,338, 265,339, 266,340, 268,341, 269,342, 270,343, 271,344, 272,345, 274,346, 275,347, 276,276, 278,349, 280,350, 281,351, 283,352, 285,353, 286,354, 288,355, 289,356, 290,357, 291,358, 292,359, 295,360, 296,361, 297,362, 298,363, 300,300, 301,365, 302,366, 303,367, 305,0, 306,0, 307,0, 308,0, 309,0, 310,0, 312,0, 311,0, 313,0, 315,0, 314,0, 317,0, 316,0, 319,0, 318,0, 320,0, 321,382, 322,383, 324,384, 326,385, 327,386, 328,387, 226,308, 329,388, 330,389, 331,390, 332,391, 334,392, 227,309, 229,310, 224,306, 338,393, 339,394, 234,313, 238,316, 223,305, 225,307, 235,314, 340,395, 341,396, 342,397, 343,398, 243,320, 344,399, 232,312, 230,311, 345,400, 346,346, 347,402, 348,403, 350,404, 240,317, 241,318, 237,315, 351,405, 352,352, 242,319, 354,407, 355,408, 276,348, 357,409, 358,410, 360,411, 361,412, 362,413, 363,414, 364,415, 365,416, 366,366, 368,0, 369,0, 370,0, 371,0, 372,0, 373,0, 300,364, 375,0, 374,0, 376,0, 377,0, 378,0, 379,0, 380,0, 381,0, 382,429, 383,430, 384,431, 385,385, 387,434, 393,437, 394,438, 395,439, 391,391, 399,441, 398,440, 401,442, 402,443, 309,371, 311,373, 405,444, 406,445, 408,408, 410,410, 313,375, 314,376, 318,379, 305,368, 306,369, 307,370, 411,411, 417,454, 310,372, 312,374, 407,407, 414,414, 315,377, 316,378, 398,440, 416,416, 319,380, 418,0, 320,381, 419,0, 420,0, 421,0, 422,0, 346,401, 423,0, 424,0, 425,0, 426,0, 428,0, 427,0, 432,463, 352,406, 433,464, 435,465, 436,466, 438,438, 439,439, 441,469, 440,440, 444,470, 446,471, 447,472, 448,473, 421,421, 366,417, 449,474, 450,475, 451,476, 452,477, 453,478, 455,0, 427,427, 456,0, 457,0, 458,0, 459,0, 460,0, 461,0, 369,419, 462,0, 385,432, 440,440, 463,483, 371,420, 464,484, 391,435, 385,433, 368,418, 374,422, 465,485, 377,425, 391,436, 466,486, 467,487, 381,428, 373,421, 468,488, 408,448, 410,449, 470,489, 375,423, 376,424, 379,427, 378,426, 471,490, 411,450, 407,446, 472,491, 477,492, 478,493, 414,451, 416,452, 407,447, 479,0, 480,0, 483,498, 481,0, 416,453, 482,0, 484,499, 485,500, 486,501, 490,502, 491,503, 492,504, 493,505, 494,0, 495,0, 496,0, 497,0, 499,510, 501,511, 502,512, 503,513, 438,467, 439,468, 418,455, 504,514, 505,515, 421,458, 506,0, 507,0, 508,0, 419,456, 509,0, 421,459, 420,457, 427,461, 512,512, 423,460, 513,519, 514,514, 515,521, 427,462, 516,0, 517,0, 518,522, 519,519, 520,524, 521,521, 523,526, 525,527, 0,0, 0,0, 0,0, 458,479, 0,0, 0,0, 461,481, 0,0, 459,480, 0,0, 0,0, 0,0, 462,482, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 479,494, 0,0, 480,495, 481,496, 0,0, 0,0, 482,497, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 495,507, 0,0, 497,509, 0,0, 0,0, 0,0, 512,518, 0,0, 0,0, 514,520, 0,0, 494,506, 0,0, 496,508, 0,0, 519,523, 0,0, 521,525, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 507,516, 0,0, 0,0, 509,517, 0,0, 0,0}; struct yysvf yysvec[] = { 0, 0, 0, yycrank+0, 0, 0, yycrank+0, 0, 0, yycrank+-1, 0, 0, yycrank+-36, yysvec+3, 0, yycrank+-122, 0, 0, yycrank+-5, yysvec+5, 0, yycrank+-3, 0, 0, yycrank+0, yysvec+7, 0, yycrank+123, 0, 0, yycrank+0, yysvec+9, 0, yycrank+0, 0, 0, yycrank+0, 0, 0, yycrank+0, 0, 0, yycrank+0, 0, 0, yycrank+0, 0, yyvstop+1, yycrank+0, 0, yyvstop+3, yycrank+0, 0, yyvstop+6, yycrank+0, 0, yyvstop+8, yycrank+0, 0, yyvstop+11, yycrank+1, 0, yyvstop+14, yycrank+198, 0, yyvstop+16, yycrank+211, 0, yyvstop+18, yycrank+0, 0, yyvstop+21, yycrank+3, 0, yyvstop+24, yycrank+280, 0, yyvstop+26, yycrank+3, yysvec+25, yyvstop+29, yycrank+14, 0, yyvstop+32, yycrank+4, 0, yyvstop+34, yycrank+0, 0, yyvstop+36, yycrank+44, yysvec+25, yyvstop+39, yycrank+38, yysvec+25, yyvstop+42, yycrank+63, yysvec+25, yyvstop+45, yycrank+68, yysvec+25, yyvstop+48, yycrank+66, yysvec+25, yyvstop+51, yycrank+16, yysvec+25, yyvstop+54, yycrank+56, yysvec+25, yyvstop+57, yycrank+4, yysvec+25, yyvstop+60, yycrank+172, yysvec+25, yyvstop+63, yycrank+8, yysvec+25, yyvstop+66, yycrank+11, yysvec+25, yyvstop+69, yycrank+22, yysvec+25, yyvstop+72, yycrank+11, yysvec+25, yyvstop+75, yycrank+78, yysvec+25, yyvstop+78, yycrank+174, yysvec+25, yyvstop+81, yycrank+67, yysvec+25, yyvstop+84, yycrank+31, yysvec+25, yyvstop+87, yycrank+80, yysvec+25, yyvstop+90, yycrank+0, 0, yyvstop+93, yycrank+-402, 0, yyvstop+96, yycrank+0, 0, yyvstop+99, yycrank+0, 0, yyvstop+101, yycrank+0, 0, yyvstop+103, yycrank+182, 0, yyvstop+106, yycrank+0, 0, yyvstop+108, yycrank+0, 0, yyvstop+110, yycrank+365, yysvec+9, yyvstop+112, yycrank+0, 0, yyvstop+114, yycrank+375, 0, yyvstop+116, yycrank+55, 0, yyvstop+118, yycrank+79, 0, yyvstop+120, yycrank+178, 0, yyvstop+122, yycrank+171, 0, 0, yycrank+169, 0, yyvstop+124, yycrank+181, 0, yyvstop+126, yycrank+179, 0, yyvstop+128, yycrank+332, 0, yyvstop+130, yycrank+75, 0, yyvstop+132, yycrank+103, 0, 0, yycrank+188, 0, yyvstop+134, yycrank+0, 0, yyvstop+136, yycrank+0, 0, yyvstop+138, yycrank+404, yysvec+58, yyvstop+140, yycrank+0, yysvec+22, yyvstop+142, yycrank+0, 0, yyvstop+144, yycrank+117, 0, 0, yycrank+0, yysvec+75, 0, yycrank+103, 0, 0, yycrank+152, 0, 0, yycrank+3, 0, yyvstop+146, yycrank+0, yysvec+25, yyvstop+148, yycrank+144, yysvec+25, yyvstop+150, yycrank+0, 0, yyvstop+152, yycrank+0, 0, yyvstop+154, yycrank+170, yysvec+25, yyvstop+156, yycrank+191, yysvec+25, yyvstop+158, yycrank+195, yysvec+25, yyvstop+160, yycrank+0, yysvec+25, yyvstop+162, yycrank+187, yysvec+25, yyvstop+165, yycrank+185, yysvec+25, yyvstop+167, yycrank+0, yysvec+25, yyvstop+169, yycrank+185, yysvec+25, yyvstop+172, yycrank+197, yysvec+25, yyvstop+174, yycrank+199, yysvec+25, yyvstop+176, yycrank+197, yysvec+25, yyvstop+178, yycrank+0, yysvec+25, yyvstop+180, yycrank+205, yysvec+25, yyvstop+183, yycrank+220, yysvec+25, yyvstop+185, yycrank+226, yysvec+25, yyvstop+187, yycrank+222, yysvec+25, yyvstop+189, yycrank+209, yysvec+25, yyvstop+191, yycrank+231, yysvec+25, yyvstop+193, yycrank+240, yysvec+25, yyvstop+195, yycrank+296, yysvec+25, yyvstop+197, yycrank+231, yysvec+25, yyvstop+199, yycrank+238, yysvec+25, yyvstop+201, yycrank+0, yysvec+25, yyvstop+203, yycrank+226, yysvec+25, yyvstop+206, yycrank+256, yysvec+25, yyvstop+208, yycrank+270, yysvec+25, yyvstop+210, yycrank+263, yysvec+25, yyvstop+212, yycrank+257, yysvec+25, yyvstop+214, yycrank+257, yysvec+25, yyvstop+216, yycrank+287, yysvec+25, yyvstop+218, yycrank+292, yysvec+25, yyvstop+220, yycrank+0, yysvec+25, yyvstop+222, yycrank+302, yysvec+25, yyvstop+225, yycrank+308, yysvec+25, yyvstop+227, yycrank+306, yysvec+25, yyvstop+229, yycrank+317, yysvec+25, yyvstop+231, yycrank+326, yysvec+25, yyvstop+233, yycrank+314, yysvec+25, yyvstop+235, yycrank+320, yysvec+25, yyvstop+237, yycrank+330, yysvec+25, yyvstop+239, yycrank+342, yysvec+25, yyvstop+241, yycrank+339, yysvec+25, yyvstop+243, yycrank+329, yysvec+25, yyvstop+245, yycrank+330, yysvec+25, yyvstop+248, yycrank+324, yysvec+25, yyvstop+251, yycrank+331, yysvec+25, yyvstop+253, yycrank+347, yysvec+25, yyvstop+255, yycrank+-461, 0, yyvstop+257, yycrank+-439, yysvec+131, yyvstop+259, yycrank+-454, yysvec+131, yyvstop+262, yycrank+-455, yysvec+131, yyvstop+265, yycrank+-456, yysvec+131, yyvstop+268, yycrank+-458, yysvec+131, yyvstop+271, yycrank+-459, yysvec+131, yyvstop+273, yycrank+-462, yysvec+131, yyvstop+276, yycrank+-464, yysvec+131, yyvstop+279, yycrank+-476, 0, yyvstop+282, yycrank+-465, yysvec+131, yyvstop+285, yycrank+-463, yysvec+131, yyvstop+288, yycrank+-466, yysvec+131, yyvstop+290, yycrank+-468, yysvec+131, yyvstop+293, yycrank+-469, yysvec+131, yyvstop+296, yycrank+0, 0, yyvstop+299, yycrank+0, 0, yyvstop+301, yycrank+0, 0, yyvstop+303, yycrank+365, 0, 0, yycrank+372, 0, 0, yycrank+368, 0, 0, yycrank+384, 0, 0, yycrank+383, 0, 0, yycrank+0, 0, yyvstop+305, yycrank+387, 0, 0, yycrank+371, 0, 0, yycrank+0, 0, yyvstop+307, yycrank+377, 0, 0, yycrank+0, 0, yyvstop+309, yycrank+392, 0, 0, yycrank+390, 0, 0, yycrank+0, 0, yyvstop+311, yycrank+377, 0, 0, yycrank+398, 0, 0, yycrank+0, 0, yyvstop+313, yycrank+384, 0, 0, yycrank+385, 0, 0, yycrank+383, 0, 0, yycrank+399, 0, 0, yycrank+0, 0, yyvstop+315, yycrank+0, 0, yyvstop+317, yycrank+401, yysvec+25, yyvstop+319, yycrank+386, yysvec+25, yyvstop+321, yycrank+0, yysvec+25, yyvstop+323, yycrank+0, yysvec+25, yyvstop+326, yycrank+394, yysvec+25, yyvstop+329, yycrank+396, yysvec+25, yyvstop+331, yycrank+389, yysvec+25, yyvstop+333, yycrank+395, yysvec+25, yyvstop+335, yycrank+0, yysvec+25, yyvstop+337, yycrank+0, yysvec+25, yyvstop+340, yycrank+397, yysvec+25, yyvstop+343, yycrank+402, yysvec+25, yyvstop+345, yycrank+416, yysvec+25, yyvstop+347, yycrank+416, yysvec+25, yyvstop+349, yycrank+420, yysvec+25, yyvstop+351, yycrank+418, yysvec+25, yyvstop+353, yycrank+412, yysvec+25, yyvstop+355, yycrank+419, yysvec+25, yyvstop+358, yycrank+414, yysvec+25, yyvstop+360, yycrank+426, yysvec+25, yyvstop+362, yycrank+500, yysvec+25, yyvstop+364, yycrank+425, yysvec+25, yyvstop+366, yycrank+419, yysvec+25, yyvstop+368, yycrank+426, yysvec+25, yyvstop+370, yycrank+433, yysvec+25, yyvstop+372, yycrank+432, yysvec+25, yyvstop+374, yycrank+422, yysvec+25, yyvstop+376, yycrank+423, yysvec+25, yyvstop+378, yycrank+439, yysvec+25, yyvstop+380, yycrank+427, yysvec+25, yyvstop+382, yycrank+442, yysvec+25, yyvstop+384, yycrank+444, yysvec+25, yyvstop+386, yycrank+430, yysvec+25, yyvstop+388, yycrank+437, yysvec+25, yyvstop+390, yycrank+443, yysvec+25, yyvstop+392, yycrank+445, yysvec+25, yyvstop+395, yycrank+435, yysvec+25, yyvstop+397, yycrank+450, yysvec+25, yyvstop+399, yycrank+451, yysvec+25, yyvstop+401, yycrank+438, yysvec+25, yyvstop+403, yycrank+450, yysvec+25, yyvstop+405, yycrank+456, yysvec+25, yyvstop+407, yycrank+444, yysvec+25, yyvstop+409, yycrank+452, yysvec+25, yyvstop+411, yycrank+532, yysvec+25, yyvstop+414, yycrank+467, yysvec+25, yyvstop+416, yycrank+0, yysvec+25, yyvstop+418, yycrank+456, yysvec+25, yyvstop+421, yycrank+462, yysvec+25, yyvstop+423, yycrank+475, yysvec+25, yyvstop+426, yycrank+-570, yysvec+131, yyvstop+428, yycrank+-572, yysvec+131, yyvstop+431, yycrank+-573, yysvec+131, yyvstop+433, yycrank+-574, yysvec+131, yyvstop+435, yycrank+-575, yysvec+131, yyvstop+437, yycrank+-576, yysvec+131, yyvstop+439, yycrank+-578, yysvec+131, yyvstop+441, yycrank+-580, yysvec+131, yyvstop+444, yycrank+-579, yysvec+131, yyvstop+446, yycrank+-581, yysvec+131, yyvstop+448, yycrank+-583, yysvec+131, yyvstop+451, yycrank+-584, yysvec+131, yyvstop+453, yycrank+-586, yysvec+131, yyvstop+456, yycrank+-587, yysvec+131, yyvstop+458, yycrank+-588, yysvec+131, yyvstop+460, yycrank+-589, yysvec+131, yyvstop+463, yycrank+-590, yysvec+131, yyvstop+465, yycrank+-591, yysvec+131, yyvstop+467, yycrank+-592, yysvec+131, yyvstop+470, yycrank+-593, yysvec+131, yyvstop+472, yycrank+-594, yysvec+131, yyvstop+474, yycrank+-595, yysvec+131, yyvstop+476, yycrank+490, 0, yyvstop+478, yycrank+491, 0, 0, yycrank+492, 0, 0, yycrank+0, 0, yyvstop+480, yycrank+506, 0, 0, yycrank+494, 0, 0, yycrank+510, 0, 0, yycrank+496, 0, 0, yycrank+508, 0, yyvstop+482, yycrank+510, 0, 0, yycrank+499, 0, 0, yycrank+502, 0, 0, yycrank+0, 0, yyvstop+484, yycrank+516, 0, 0, yycrank+502, 0, 0, yycrank+503, 0, yyvstop+486, yycrank+0, yysvec+25, yyvstop+488, yycrank+519, yysvec+25, yyvstop+491, yycrank+502, yysvec+25, yyvstop+493, yycrank+503, yysvec+25, yyvstop+495, yycrank+522, yysvec+25, yyvstop+497, yycrank+513, yysvec+25, yyvstop+499, yycrank+524, yysvec+25, yyvstop+501, yycrank+0, yysvec+25, yyvstop+503, yycrank+518, yysvec+25, yyvstop+506, yycrank+526, yysvec+25, yyvstop+508, yycrank+518, yysvec+25, yyvstop+511, yycrank+528, yysvec+25, yyvstop+513, yycrank+529, yysvec+25, yyvstop+516, yycrank+0, yysvec+25, yyvstop+518, yycrank+599, yysvec+25, yyvstop+521, yycrank+520, yysvec+25, yyvstop+523, yycrank+601, 0, 0, yycrank+0, yysvec+25, yyvstop+525, yycrank+518, yysvec+25, yyvstop+528, yycrank+0, yysvec+25, yyvstop+530, yycrank+531, yysvec+25, yyvstop+533, yycrank+521, yysvec+25, yyvstop+535, yycrank+0, yysvec+25, yyvstop+537, yycrank+605, yysvec+25, yyvstop+540, yycrank+0, yysvec+25, yyvstop+543, yycrank+522, yysvec+25, yyvstop+546, yycrank+525, yysvec+25, yyvstop+548, yycrank+0, yysvec+25, yyvstop+550, yycrank+536, yysvec+25, yyvstop+553, yycrank+525, yysvec+25, yyvstop+555, yycrank+525, yysvec+25, yyvstop+557, yycrank+527, yysvec+25, yyvstop+559, yycrank+528, yysvec+25, yyvstop+561, yycrank+0, yysvec+25, yyvstop+563, yycrank+0, yysvec+25, yyvstop+566, yycrank+541, yysvec+25, yyvstop+569, yycrank+536, yysvec+25, yyvstop+571, yycrank+550, yysvec+25, yyvstop+573, yycrank+532, yysvec+25, yyvstop+575, yycrank+0, yysvec+25, yyvstop+577, yycrank+617, 0, 0, yycrank+536, yysvec+25, yyvstop+580, yycrank+619, yysvec+25, yyvstop+582, yycrank+548, yysvec+25, yyvstop+584, yycrank+0, yysvec+25, yyvstop+586, yycrank+-643, yysvec+131, yyvstop+589, yycrank+-644, yysvec+131, yyvstop+592, yycrank+-645, yysvec+131, yyvstop+594, yycrank+-646, yysvec+131, yyvstop+596, yycrank+-647, yysvec+131, yyvstop+599, yycrank+-648, yysvec+131, yyvstop+601, yycrank+-650, yysvec+131, yyvstop+603, yycrank+-649, yysvec+131, yyvstop+605, yycrank+-651, yysvec+131, yyvstop+607, yycrank+-653, yysvec+131, yyvstop+610, yycrank+-652, yysvec+131, yyvstop+612, yycrank+-655, yysvec+131, yyvstop+614, yycrank+-654, yysvec+131, yyvstop+616, yycrank+-657, yysvec+131, yyvstop+619, yycrank+-656, yysvec+131, yyvstop+621, yycrank+-658, yysvec+131, yyvstop+623, yycrank+558, 0, 0, yycrank+569, 0, 0, yycrank+0, 0, yyvstop+626, yycrank+567, 0, 0, yycrank+0, 0, yyvstop+628, yycrank+558, 0, 0, yycrank+569, 0, 0, yycrank+557, 0, 0, yycrank+560, 0, 0, yycrank+573, 0, 0, yycrank+562, 0, 0, yycrank+565, 0, 0, yycrank+0, 0, yyvstop+630, yycrank+576, 0, 0, yycrank+0, yysvec+25, yyvstop+632, yycrank+0, yysvec+25, yyvstop+635, yycrank+0, yysvec+25, yyvstop+638, yycrank+583, yysvec+25, yyvstop+641, yycrank+576, yysvec+25, yyvstop+643, yycrank+577, yysvec+25, yyvstop+645, yycrank+591, yysvec+25, yyvstop+647, yycrank+593, yysvec+25, yyvstop+649, yycrank+593, yysvec+25, yyvstop+651, yycrank+580, yysvec+25, yyvstop+653, yycrank+599, yysvec+25, yyvstop+655, yycrank+668, 0, 0, yycrank+586, yysvec+25, yyvstop+657, yycrank+600, 0, 0, yycrank+0, yysvec+25, yyvstop+659, yycrank+587, yysvec+25, yyvstop+662, yycrank+602, yysvec+25, yyvstop+664, yycrank+676, 0, 0, yycrank+0, yysvec+25, yyvstop+667, yycrank+678, yysvec+25, yyvstop+670, yycrank+679, yysvec+25, yyvstop+672, yycrank+0, yysvec+25, yyvstop+674, yycrank+598, yysvec+25, yyvstop+677, yycrank+682, yysvec+25, yyvstop+679, yycrank+0, yysvec+25, yyvstop+682, yycrank+683, yysvec+25, yyvstop+685, yycrank+615, yysvec+25, yyvstop+687, yycrank+617, yysvec+25, yyvstop+689, yycrank+686, yysvec+25, yyvstop+691, yycrank+617, 0, 0, yycrank+688, yysvec+25, yyvstop+693, yycrank+689, 0, 0, yycrank+0, yysvec+25, yyvstop+695, yycrank+-712, yysvec+131, yyvstop+698, yycrank+-713, yysvec+131, yyvstop+700, yycrank+-714, yysvec+131, yyvstop+702, yycrank+-715, yysvec+131, yyvstop+705, yycrank+-716, yysvec+131, yyvstop+707, yycrank+-717, yysvec+131, yyvstop+710, yycrank+-720, yysvec+131, yyvstop+712, yycrank+-719, yysvec+131, yyvstop+714, yycrank+-721, yysvec+131, yyvstop+716, yycrank+-722, yysvec+131, yyvstop+718, yycrank+-723, yysvec+131, yyvstop+720, yycrank+-724, yysvec+131, yyvstop+722, yycrank+-725, yysvec+131, yyvstop+724, yycrank+-726, yysvec+131, yyvstop+727, yycrank+628, 0, 0, yycrank+624, 0, 0, yycrank+623, 0, 0, yycrank+708, 0, 0, yycrank+0, 0, yyvstop+729, yycrank+626, 0, 0, yycrank+0, 0, yyvstop+731, yycrank+0, 0, yyvstop+733, yycrank+0, 0, yyvstop+735, yycrank+713, 0, 0, yycrank+0, 0, yyvstop+737, yycrank+632, yysvec+25, yyvstop+739, yycrank+711, yysvec+25, yyvstop+741, yycrank+712, yysvec+25, yyvstop+743, yycrank+0, yysvec+25, yyvstop+745, yycrank+0, yysvec+25, yyvstop+748, yycrank+738, yysvec+25, yyvstop+751, yycrank+645, yysvec+25, yyvstop+753, yycrank+0, yysvec+25, yyvstop+755, yycrank+646, 0, 0, yycrank+648, yysvec+25, yyvstop+758, yycrank+0, 0, yyvstop+760, yycrank+0, yysvec+25, yyvstop+762, yycrank+654, yysvec+25, yyvstop+765, yycrank+651, 0, 0, yycrank+734, 0, 0, yycrank+722, 0, 0, yycrank+0, yysvec+25, yyvstop+767, yycrank+723, 0, 0, yycrank+730, 0, 0, yycrank+0, yysvec+25, yyvstop+770, yycrank+0, yysvec+25, yyvstop+773, yycrank+735, 0, 0, yycrank+0, 0, yyvstop+776, yycrank+739, 0, 0, yycrank+661, 0, 0, yycrank+-763, yysvec+131, yyvstop+778, yycrank+-765, yysvec+131, yyvstop+780, yycrank+-766, yysvec+131, yyvstop+782, yycrank+-767, yysvec+131, yyvstop+784, yycrank+-768, yysvec+131, yyvstop+786, yycrank+-770, yysvec+131, yyvstop+789, yycrank+-771, yysvec+131, yyvstop+791, yycrank+-772, yysvec+131, yyvstop+794, yycrank+-773, yysvec+131, yyvstop+797, yycrank+-775, yysvec+131, yyvstop+800, yycrank+-774, yysvec+131, yyvstop+802, yycrank+0, 0, yyvstop+805, yycrank+0, 0, yyvstop+807, yycrank+0, 0, yyvstop+809, yycrank+685, 0, 0, yycrank+683, 0, 0, yycrank+0, 0, yyvstop+811, yycrank+688, 0, 0, yycrank+685, 0, 0, yycrank+0, yysvec+25, yyvstop+813, yycrank+759, 0, 0, yycrank+760, 0, 0, yycrank+785, 0, yyvstop+816, yycrank+679, yysvec+25, yyvstop+818, yycrank+0, 0, yyvstop+820, yycrank+0, yysvec+25, yyvstop+822, yycrank+687, yysvec+25, yyvstop+825, yycrank+0, 0, yyvstop+827, yycrank+695, 0, 0, yycrank+692, 0, 0, yycrank+696, 0, 0, yycrank+699, 0, 0, yycrank+700, 0, 0, yycrank+701, 0, 0, yycrank+703, 0, 0, yycrank+700, 0, 0, yycrank+0, 0, yyvstop+829, yycrank+-796, yysvec+131, yyvstop+831, yycrank+-798, yysvec+131, yyvstop+834, yycrank+-799, yysvec+131, yyvstop+837, yycrank+-800, yysvec+131, yyvstop+840, yycrank+-801, yysvec+131, yyvstop+842, yycrank+-802, yysvec+131, yyvstop+844, yycrank+-803, yysvec+131, yyvstop+847, yycrank+-805, yysvec+131, yyvstop+849, yycrank+716, 0, 0, yycrank+717, 0, 0, yycrank+723, 0, 0, yycrank+725, 0, 0, yycrank+727, 0, 0, yycrank+730, 0, 0, yycrank+0, yysvec+25, yyvstop+851, yycrank+734, yysvec+25, yyvstop+854, yycrank+738, 0, 0, yycrank+740, 0, 0, yycrank+0, 0, yyvstop+856, yycrank+0, 0, yyvstop+858, yycrank+0, 0, yyvstop+860, yycrank+0, 0, yyvstop+862, yycrank+742, 0, 0, yycrank+742, 0, 0, yycrank+-839, yysvec+131, yyvstop+864, yycrank+-840, yysvec+131, yyvstop+866, yycrank+-842, yysvec+131, yyvstop+868, yycrank+-844, yysvec+131, yyvstop+870, yycrank+735, 0, 0, yycrank+751, 0, 0, yycrank+740, 0, 0, yycrank+753, 0, 0, yycrank+0, 0, yyvstop+872, yycrank+0, 0, yyvstop+874, yycrank+0, yysvec+25, yyvstop+876, yycrank+742, 0, 0, yycrank+755, 0, 0, yycrank+744, 0, 0, yycrank+757, 0, 0, yycrank+-852, yysvec+131, yyvstop+879, yycrank+-853, yysvec+131, yyvstop+881, yycrank+-854, yysvec+131, yyvstop+883, yycrank+-855, yysvec+131, yyvstop+885, yycrank+0, 0, yyvstop+887, yycrank+750, 0, 0, yycrank+0, 0, yyvstop+889, yycrank+751, 0, 0, yycrank+836, 0, 0, yycrank+753, 0, 0, yycrank+841, 0, 0, yycrank+758, 0, 0, yycrank+-866, yysvec+131, yyvstop+891, yycrank+-867, yysvec+131, yyvstop+894, yycrank+-868, yysvec+131, yyvstop+896, yycrank+-870, yysvec+131, yyvstop+899, yycrank+0, 0, yyvstop+901, yycrank+0, 0, yyvstop+903, yycrank+852, 0, 0, yycrank+854, 0, 0, yycrank+855, 0, 0, yycrank+856, 0, 0, yycrank+-880, yysvec+131, yyvstop+905, yycrank+-881, yysvec+131, yyvstop+908, yycrank+790, 0, 0, yycrank+861, 0, 0, yycrank+792, 0, 0, yycrank+863, 0, 0, yycrank+0, 0, yyvstop+911, yycrank+794, 0, 0, yycrank+0, 0, yyvstop+913, yycrank+795, 0, 0, yycrank+0, 0, yyvstop+915, yycrank+0, 0, yyvstop+917, 0, 0, 0}; struct yywork *yytop = yycrank+986; struct yysvf *yybgin = yysvec+1; Uchar yymatch[] = { 00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 011 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , '0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' , '0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,'A' , 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' , 'A' ,'A' ,'A' ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 0}; Uchar yyextra[] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0}; /* #pragma lib "libl.a" */ int yylineno =1; # define YYU(x) x char yytext[YYLMAX]; struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; Uchar yysbuf[YYLMAX]; Uchar *yysptr = yysbuf; int *yyfnd; extern struct yysvf *yyestate; int yyprevious = YYNEWLINE; # ifdef LEXDEBUG extern void allprint(char); # endif int yylook(void){ struct yysvf *yystate, **lsp; struct yywork *yyt; struct yysvf *yyz; int yych; struct yywork *yyr; # ifdef LEXDEBUG int debug; # endif Uchar *yylastch; /* start off machines */ # ifdef LEXDEBUG debug = 0; # endif if (!yymorfg) yylastch = (Uchar*)yytext; else { yymorfg=0; yylastch = (Uchar*)yytext+yyleng; } for(;;){ lsp = yylstate; yyestate = yystate = yybgin; if (yyprevious==YYNEWLINE) yystate++; for (;;){ # ifdef LEXDEBUG if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1); # endif yyt = yystate->yystoff; if(yyt == yycrank){ /* may not be any transitions */ yyz = yystate->yyother; if(yyz == 0)break; if(yyz->yystoff == yycrank)break; } *yylastch++ = yych = input(); tryagain: # ifdef LEXDEBUG if(debug){ fprintf(yyout,"char "); allprint(yych); putchar('\n'); } # endif yyr = yyt; if (yyt > yycrank){ yyt = yyr + yych; if (yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } } # ifdef YYOPTIM else if(yyt < yycrank) { /* r < yycrank */ yyt = yyr = yycrank+(yycrank-yyt); # ifdef LEXDEBUG if(debug)fprintf(yyout,"compressed state\n"); # endif yyt = yyt + yych; if(yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } yyt = yyr + YYU(yymatch[yych]); # ifdef LEXDEBUG if(debug){ fprintf(yyout,"try fall back character "); allprint(YYU(yymatch[yych])); putchar('\n'); } # endif if(yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transition */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } } if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){ # ifdef LEXDEBUG if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1); # endif goto tryagain; } # endif else {unput(*--yylastch);break;} contin: # ifdef LEXDEBUG if(debug){ fprintf(yyout,"state %d char ",yystate-yysvec-1); allprint(yych); putchar('\n'); } # endif ; } # ifdef LEXDEBUG if(debug){ fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1); allprint(yych); putchar('\n'); } # endif while (lsp-- > yylstate){ *yylastch-- = 0; if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){ yyolsp = lsp; if(yyextra[*yyfnd]){ /* must backup */ while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){ lsp--; unput(*yylastch--); } } yyprevious = YYU(*yylastch); yylsp = lsp; yyleng = yylastch-(Uchar*)yytext+1; yytext[yyleng] = 0; # ifdef LEXDEBUG if(debug){ fprintf(yyout,"\nmatch '%s'", yytext); fprintf(yyout," action %d\n",*yyfnd); } # endif return(*yyfnd++); } unput(*yylastch); } if (yytext[0] == 0 /* && feof(yyin) */) { yysptr=yysbuf; return(0); } yyprevious = input(); yytext[0] = yyprevious; if (yyprevious>0) output(yyprevious); yylastch = (Uchar*)yytext; # ifdef LEXDEBUG if(debug)putchar('\n'); # endif } return(0); /* shut up the compiler; i have no idea what should be returned */ } int yyback(int *p, int m) { if (p==0) return(0); while (*p) { if (*p++ == m) return(1); } return(0); } /* the following are only used in the lex library */ int yyinput(void){ if(yyin == ((void*)0)) yyin = stdin; return(input()); } void yyoutput(int c) { if(yyout == ((void*)0)) yyout = stdin; output(c); } void yyunput(int c) { unput(c); } xcip/JPIC/arcgen.c0000644000175300001440000000706511513632544012510 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ { static int prevw = HT/10; static int prevh = HT/5; static int prevrad = HT/2; static int dtox[2][4] ={ 1, -1, -1, 1, 1, 1, -1, -1 }; static int dtoy[2][4] ={ 1, 1, -1, -1, -1, 1, 1, -1 }; static int dctrx[2][4] ={ 0, -1, 0, 1, 0, 1, 0, -1 }; static int dctry[2][4] ={ 1, 0, -1, 0, -1, 0, 1, 0 }; static int nexthv[2][4] ={ U_DIR, L_DIR, D_DIR, R_DIR, D_DIR, R_DIR, U_DIR, L_DIR }; double sqrt(), atan2(), sin(), cos(); float dx2, dy2, ht, phi, r, d; int i, head, to, at, cw, invis; struct obj *p, *ppos; coord fromx, fromy, tox, toy; prevrad = getvar("arcrad"); prevh = getvar("arrowht"); prevw = getvar("arrowwid"); fromx = curx; fromy = cury; head = to = at = cw = invis = 0; for (i = 0; i < nattr; i++) { switch (attr[i].a_type) { case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; case HEAD: head += attr[i].a_val; break; case INVIS: invis = INVIS; break; case HEIGHT: /* length of arrowhead */ prevh = attr[i].a_val; break; case WIDTH: /* width of arrowhead */ prevw = attr[i].a_val; break; case RADIUS: prevrad = attr[i].a_val; break; case DIAMETER: prevrad = attr[i].a_val / 2; break; case CW: cw = 1; break; case FROM: /* start point of arc */ ppos = (struct obj *) attr[i].a_val; fromx = ppos->o_x; fromy = ppos->o_y; break; case TO: /* end point of arc */ ppos = (struct obj *) attr[i].a_val; tox = ppos->o_x; toy = ppos->o_y; to++; break; case AT: /* center of arc */ ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; at = 1; break; case UP: hvmode = U_DIR; break; case DOWN: hvmode = D_DIR; break; case RIGHT: hvmode = R_DIR; break; case LEFT: hvmode = L_DIR; break; } } if (!at && !to) { /* the defaults are mostly OK */ curx = fromx + prevrad * dctrx[cw][hvmode]; cury = fromy + prevrad * dctry[cw][hvmode]; tox = fromx + prevrad * dtox[cw][hvmode]; toy = fromy + prevrad * dtoy[cw][hvmode]; hvmode = nexthv[cw][hvmode]; } else if (!at) { dx2 = (float)(tox - fromx) / 2; dy2 = (float)(toy - fromy) / 2; phi = atan2(dy2, dx2) + (cw ? -PI2 : PI2); for (r=prevrad; (d = r*r - (dx2*dx2+dy2*dy2)) <= 0.0; r *= 2) ; /* this kludge gets around too-small radii */ ht = sqrt(d); curx = fromx + dx2 + ht * cos(phi) + 0.5; cury = fromy + dy2 + ht * sin(phi) + 0.5; dprintf("dx2,dy2=%g,%g, phi=%g, r,ht=%g,%g\n", dx2, dy2, phi, r, ht); } else if (at && !to) { /* do we have all the cases??? */ tox = fromx + prevrad * dtox[cw][hvmode]; toy = fromy + prevrad * dtoy[cw][hvmode]; hvmode = nexthv[cw][hvmode]; } if (cw) { /* interchange roles of from-to and heads */ coord temp; temp = fromx; fromx = tox; tox = temp; temp = fromy; fromy = toy; toy = temp; if (head == HEAD1) head = HEAD2; else if (head == HEAD2) head = HEAD1; } p = makenode(type, 6); /* these are wrong in general */ extreme(fromx, fromy); extreme(tox, toy); p->o_val[0] = fromx; p->o_val[1] = fromy; p->o_val[2] = tox; p->o_val[3] = toy; if (cw) { curx = fromx; cury = fromy; } else { curx = tox; cury = toy; } p->o_val[4] = prevw; p->o_val[5] = prevh; p->o_attr = head | (cw ? CW_ARC : 0) | invis; dprintf("arc at %d %d from %d %d to %d %d head %d %d\n", p->o_x, p->o_y, p->o_val[0], p->o_val[1], p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]); return(p); } xcip/JPIC/troffgen.c0000644000175300001440000000141311513632544013052 0ustar meusers#include #include "pic.h" #include "y.tab.h" troffgen(s) /* save away a string of troff commands */ char *s; { if (strncmp(s, ".PS", 3) == 0) yyerror(".PS found inside .PS/.PE"); savetext(CENTER, s); /* use the existing text mechanism */ makenode(TROFF, 0); } savetext(t, s) /* record text elements for current object */ int t; char *s; { switch (t) { case CENTER: t = 'C'; break; case LJUST: t = 'L'; break; case RJUST: t = 'R'; break; case SPREAD: t = 'S'; break; case FILL: t = 'F'; break; case ABOVE: t = 'A'; break; case BELOW: t = 'B'; break; } if (ntext >= MAXTEXT) { yyerror("too many text strings (%d)\n", ntext); exit(1); } text[ntext].t_type = t; text[ntext].t_val = s; dprintf("saving %c text %s at %d\n", t, s, ntext); ntext++; } xcip/JPIC/blockgen.c0000644000175300001440000001146411513632543013032 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct pushstack stack[20]; int nstack = 0; struct obj *leftthing(c) /* called for {... or [... */ int c; { struct obj *p; stack[nstack].p_x = curx; stack[nstack].p_y = cury; stack[nstack].p_hvmode = hvmode; if (c == '[') { curx = cury = 0; stack[nstack].p_xmin = xmin; stack[nstack].p_xmax = xmax; stack[nstack].p_ymin = ymin; stack[nstack].p_ymax = ymax; xmin = ymin = 30000; xmax = ymax = -30000; p = makenode(BLOCK, 7); p->o_val[4] = nobj; /* 1st item within [...] */ if (p->o_nobj != nobj-1) fprintf(stderr, "nobjs wrong%d %d\n", p->o_nobj, nobj); } else p = NULL; nstack++; return(p); } struct obj *rightthing(p, c) /* called for ... ] or ... } */ struct obj *p; { struct obj *q; nstack--; curx = stack[nstack].p_x; cury = stack[nstack].p_y; hvmode = stack[nstack].p_hvmode; if (c == '}') { q = makenode(MOVE, 0); dprintf("M %d %d\n", curx, cury); } else { q = makenode(BLOCKEND, 7); q->o_val[4] = p->o_nobj + 1; /* back pointer */ p->o_val[5] = q->o_nobj - 1; /* forward pointer */ p->o_val[0] = xmin; p->o_val[1] = ymin; p->o_val[2] = xmax; p->o_val[3] = ymax; p->o_val[6] = q->o_val[6] = (int) stack[nstack+1].p_symtab; xmin = stack[nstack].p_xmin; ymin = stack[nstack].p_ymin; xmax = stack[nstack].p_xmax; ymax = stack[nstack].p_ymax; } return(q); } struct obj *blockgen(p, type, q) /* handles [...] */ struct obj *p, *q; int type; { static int prevh = HT; static int prevw = WID; /* golden mean, sort of */ int i, invis, at, ddtype, ddval; int with, xwith, ywith; int h, w; coord x0, y0, x1, y1, cx, cy; struct obj *ppos; invis = at = 0; with = xwith = ywith = 0; ddtype = ddval = 0; w = p->o_val[2] - p->o_val[0]; h = p->o_val[3] - p->o_val[1]; cx = (p->o_val[2] + p->o_val[0]) / 2; /* geom ctr of [] wrt local orogin */ cy = (p->o_val[3] + p->o_val[1]) / 2; dprintf("cx,cy=%d,%d\n", cx, cy); for (i = 0; i < nattr; i++) { switch (attr[i].a_type) { case HEIGHT: h = attr[i].a_val; break; case WIDTH: w = attr[i].a_val; break; case SAME: h = prevh; w = prevw; break; case WITH: with = attr[i].a_val; /* corner */ break; case PLACE: /* actually with position ... */ ppos = (struct obj *) attr[i].a_val; xwith = cx - ppos->o_x; ywith = cy - ppos->o_y; with = PLACE; break; case AT: ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; at++; break; case INVIS: invis = INVIS; break; case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; } } if (with) { switch (with) { case NORTH: ywith = -((h+1) / 2); break; case SOUTH: ywith = h / 2; break; case EAST: xwith = -((w+1) / 2); break; case WEST: xwith = w / 2; break; case NE: xwith = -((w+1) / 2); ywith = -((h+1) / 2); break; case SE: xwith = -((w+1) / 2); ywith = h / 2; break; case NW: xwith = w / 2; ywith = -((h+1) / 2); break; case SW: xwith = w / 2; ywith = h / 2; break; } curx += xwith; cury += ywith; } if (!at) { if (isright(hvmode)) curx += (w+1) / 2; else if (isleft(hvmode)) curx -= w / 2; else if (isup(hvmode)) cury += (h+1) / 2; else cury -= h / 2; } x0 = curx - w / 2; y0 = cury - h / 2; x1 = curx + (w+1) / 2; y1 = cury + (h+1) / 2; extreme(x0, y0); extreme(x1, y1); p->o_x = curx; p->o_y = cury; p->o_nt1 = ntext1; p->o_nt2 = ntext; ntext1 = ntext; p->o_val[0] = w; p->o_val[1] = h; p->o_val[2] = cx; p->o_val[3] = cy; p->o_val[5] = q->o_nobj - 1; /* last item in [...] */ p->o_dotdash = ddtype; p->o_ddval = ddval; p->o_attr = invis; dprintf("[] %d %d %d %d at %d %d, h=%d, w=%d\n", x0, y0, x1, y1, curx, cury, h, w); if (isright(hvmode)) curx = x1; else if (isleft(hvmode)) curx = x0; else if (isup(hvmode)) cury = y1; else cury = y0; for (i = 0; i <= 5; i++) q->o_val[i] = p->o_val[i]; stack[nstack+1].p_symtab = NULL; /* so won't be found again */ blockadj(p); /* fix up coords for enclosed blocks */ prevh = h; prevw = w; return(p); } blockadj(p) /* adjust coords in block starting at p */ struct obj *p; { coord dx, dy; int n, lev; dx = p->o_x - p->o_val[2]; dy = p->o_y - p->o_val[3]; n = p->o_nobj + 1; dprintf("into blockadj: dx,dy=%d,%d\n", dx, dy); for (lev = 1; lev > 0; n++) { p = objlist[n]; if (p->o_type == BLOCK) lev++; else if (p->o_type == BLOCKEND) lev--; dprintf("blockadj: type=%d o_x,y=%d,%d;", p->o_type, p->o_x, p->o_y); p->o_x += dx; p->o_y += dy; dprintf(" becomes %d,%d\n", p->o_x, p->o_y); switch (p->o_type) { /* other absolute coords */ case LINE: case ARROW: case SPLINE: p->o_val[0] += dx; p->o_val[1] += dy; break; case ARC: p->o_val[0] += dx; p->o_val[1] += dy; p->o_val[2] += dx; p->o_val[3] += dy; break; } } } xcip/JPIC/circgen.c0000644000175300001440000000440511513632544012656 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *circgen(type) { static int rad[2] = { HT/2, WID/2 }; static int rad2[2] = { HT/2, HT/2 }; int i, at, t, invis; int with, xwith, ywith; int r, r2; struct obj *p, *ppos; at = invis = 0; with = xwith = ywith = 0; t = (type == CIRCLE) ? 0 : 1; if (type == CIRCLE) r = r2 = getvar("circlerad"); else if (type == ELLIPSE) { r = getvar("ellipsewid") / 2; r2 = getvar("ellipseht") / 2; } for (i = 0; i < nattr; i++) switch (attr[i].a_type) { case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; case RADIUS: r = attr[i].a_val; break; case DIAMETER: case WIDTH: r = (attr[i].a_val + 1) / 2; break; case HEIGHT: r2 = (attr[i].a_val + 1) / 2; break; case SAME: r = rad[t]; r2 = rad2[t]; break; case WITH: with = attr[i].a_val; break; case AT: ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; at++; break; case INVIS: invis = INVIS; break; } if (type == CIRCLE) r2 = r; /* probably superfluous */ if (with) { switch (with) { case NORTH: ywith = -r2; break; case SOUTH: ywith = r2; break; case EAST: xwith = -r; break; case WEST: xwith = r; break; case NE: xwith = -r * 0.707; ywith = -r2 * 0.707; break; case SE: xwith = -r * 0.707; ywith = r2 * 0.707; break; case NW: xwith = r * 0.707; ywith = -r2 * 0.707; break; case SW: xwith = r * 0.707; ywith = r2 * 0.707; break; } curx += xwith; cury += ywith; } if (!at) { if (isright(hvmode)) curx += r; else if (isleft(hvmode)) curx -= r; else if (isup(hvmode)) cury += r2; else cury -= r2; } p = makenode(type, 2); p->o_val[0] = rad[t] = r; p->o_val[1] = rad2[t] = r2; if (r <= 0 || r2 <= 0) { yyerror("%s has invalid radius %d\n", (type==CIRCLE) ? "circle" : "ellipse", ro_attr = invis; extreme(curx+r, cury+r2); extreme(curx-r, cury-r2); if (type == CIRCLE) dprintf("C %d %d %d\n", curx, cury, r); if (type == ELLIPSE) dprintf("E %d %d %d %d\n", curx, cury, r, r2); if (isright(hvmode)) curx += r; else if (isleft(hvmode)) curx -= r; else if (isup(hvmode)) cury += r2; else cury -= r2; return(p); } xcip/JPIC/picl.l0000644000175300001440000001500411513632544012201 0ustar meusers#include %Start A str comment def sc br %e 1300 %k 100 %a 1400 %o 1200 %p 3500 %n 600 %{ #undef input #undef unput #include "pic.h" #include "y.tab.h" extern double atof(); extern int dbg; #define dprintf if(dbg)printf extern int yylval; extern struct symtab symtab[]; extern char *filename; extern int synerr; extern float lastfloat; #define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;} #define CBUFLEN 150 char cbuf[CBUFLEN]; int clen, cflag; %} A [a-zA-Z_] B [a-zA-Z0-9_] D [0-9] WS [ \t] %% switch (yybgin-yysvec-1) { /* witchcraft */ case 0: BEGIN A; break; case sc: BEGIN A; return('}'); case br: BEGIN A; return(']'); } {WS} ; "\\"\n ; \n { return(ST); } ";" { return(ST); } "}" { BEGIN sc; return(ST); } "]" { BEGIN br; return(ST); } ^".".* { if (yytext[1] == 'P' && (yytext[2] == 'E' || yytext[2] == 'F')) { yylval = yytext[2]; return(EOF); } else { yylval = tostring(yytext); return(TROFF); } } print return(yylval = PRINT); box return(yylval = BOX); circle return(yylval = CIRCLE); arc return(yylval = ARC); ellipse return(yylval = ELLIPSE); arrow return(yylval = ARROW); spline return(yylval = SPLINE); line return(yylval = LINE); move return(yylval = MOVE); "[]" return(yylval = BLOCK); same return(SAME); between return(BETWEEN); and return(AND); of ; the ; way ; ".e" { yylval = EAST; return(CORNER); } ".east" { yylval = EAST; return(CORNER); } ".r" { yylval = EAST; return(CORNER); } ".right" { yylval = EAST; return(CORNER); } ".w" { yylval = WEST; return(CORNER); } ".west" { yylval = WEST; return(CORNER); } ".l" { yylval = WEST; return(CORNER); } ".left" { yylval = WEST; return(CORNER); } ".n" { yylval = NORTH; return(CORNER); } ".north" { yylval = NORTH; return(CORNER); } ".t" { yylval = NORTH; return(CORNER); } ".top" { yylval = NORTH; return(CORNER); } ".s" { yylval = SOUTH; return(CORNER); } ".south" { yylval = SOUTH; return(CORNER); } ".b" { yylval = SOUTH; return(CORNER); } ".bot" { yylval = SOUTH; return(CORNER); } ".bottom" { yylval = SOUTH; return(CORNER); } ".c" { yylval = CENTER; return(CORNER); } ".center" { yylval = CENTER; return(CORNER); } ".start" { yylval = START; return(CORNER); } ".end" { yylval = END; return(CORNER); } ".ne" { yylval = NE; return(CORNER); } "."upper" "*right { yylval = NE; return(CORNER); } ".se" { yylval = SE; return(CORNER); } "."lower" "*right { yylval = SE; return(CORNER); } ".nw" { yylval = NW; return(CORNER); } "."upper" "*left { yylval = NW; return(CORNER); } ".sw" { yylval = SW; return(CORNER); } "."lower" "*left { yylval = SW; return(CORNER); } top" "+of { yylval = NORTH; return(CORNER); } north" "+of { yylval = NORTH; return(CORNER); } bottom" "+of { yylval = SOUTH; return(CORNER); } south" "+of { yylval = SOUTH; return(CORNER); } left" "+of { yylval = WEST; return(CORNER); } west" "+of { yylval = WEST; return(CORNER); } right" "+of { yylval = EAST; return(CORNER); } east" "+of { yylval = EAST; return(CORNER); } center" "+of { yylval = CENTER; return(CORNER); } start" "+of { yylval = START; return(CORNER); } end" "+of { yylval = END; return(CORNER); } upper" "+right" "+of { yylval = NE; return(CORNER); } upper" "+left" "+of { yylval = NW; return(CORNER); } lower" "+right" "+of { yylval = SE; return(CORNER); } lower" "+left" "+of { yylval = SW; return(CORNER); } height { yylval = HEIGHT; return(ATTR); } ht { yylval = HEIGHT; return(ATTR); } wid { yylval = WIDTH; return(ATTR); } width { yylval = WIDTH; return(ATTR); } rad { yylval = RADIUS; return(ATTR); } radius { yylval = RADIUS; return(ATTR); } diam { yylval = DIAMETER; return(ATTR); } diameter { yylval = DIAMETER; return(ATTR); } size { yylval = SIZE; return(ATTR); } left { yylval = LEFT; return(DIR); } right { yylval = RIGHT; return(DIR); } up { yylval = UP; return(DIR); } down { yylval = DOWN; return(DIR); } cw { yylval = CW; return(ATTR); } ccw { yylval = CCW; return(ATTR); } then { yylval = THEN; return(ATTR); } invis { yylval = INVIS; return(ATTR); } invisible { yylval = INVIS; return(ATTR); } dot return(yylval = DOT); dotted return(yylval = DOT); dash return(yylval = DASH); dashed return(yylval = DASH); chop return(yylval = CHOP); spread return(yylval = SPREAD); fill return(yylval = FILL); ljust return(yylval = LJUST); rjust return(yylval = RJUST); above return(yylval = ABOVE); below return(yylval = BELOW); "<-" { yylval = HEAD1; return(HEAD); } "->" { yylval = HEAD2; return(HEAD); } "<->" { yylval = HEAD12; return(HEAD); } ".x" return(yylval = DOTX); ".y" return(yylval = DOTY); ".ht" return(yylval = DOTHT); ".height" return(yylval = DOTHT); ".wid" return(yylval = DOTWID); ".width" return(yylval = DOTWID); ".rad" return(yylval = DOTRAD); ".radius" return(yylval = DOTRAD); from return(yylval = FROM); to return(yylval = TO); at return(yylval = AT); by return(yylval = BY); with return(yylval = WITH); last return(yylval = LAST); Here return(yylval = HERE); define{WS}+ { BEGIN def; } {A}{B}* { yylval = definition(yytext); BEGIN A; return(TROFF); } first { yylval = 1; return(NTH); } {D}+(th|nd|rd|st) { yylval = atoi(yytext); return(NTH); } ({D}+("."?){D}*|"."{D}+)i? { int i, inch; inch = 0; for (i = 0; i < yyleng; i++) if (yytext[i] == '.' || yytext[i] == 'i') { inch++; break; } if (inch) yylval = atof(yytext) * getvar("scale") + 0.5; else yylval = atoi(yytext); lastfloat = atof(yytext); return(NUMBER); } {A}{B}* { int c; char buf[100]; struct symtab *p; p = lookup(yytext); if (p != NULL && p->s_type == DEFNAME) { yylval = defuse(yytext, p); return(TROFF); } else if ((yytext[0] >= 'a') && (yytext[0] <= 'z')) { yylval = (int) tostring(yytext); return(VARNAME); } else { yylval = (int) tostring(yytext); return(PLACENAME); } } \" { BEGIN str; clen=0; } # { BEGIN comment; } \n { BEGIN A; return(ST); } . ; . { yylval = yytext[0]; return(yytext[0]); } \" { BEGIN A; cbuf[clen]=0; yylval = tostring(cbuf); return(TEXT); } \n { yyerror("newline in string"); BEGIN A; return(ST); } "\\\"" { cbuf[clen++]='"'; } "\\"t { cbuf[clen++]='\t'; } "\\\\" { cbuf[clen++]='\\'; } . { CADD; } %% xcip/JPIC/xjpic0000755000175300001440000020576211513632543012153 0ustar meusersELF ‰4Œé4 (44€4€444€€<ž<ž Ÿ / /dIÌr Ÿ / /ÐÐHHHDDQåtdRåtd Ÿ / /ôô/lib/ld-linux.so.2GNUGNUW…§Øƾ¦CX¶WT`«béý›n€+")Œ¬KãÀ8ò‹gUaл@  Žmµ(:_.ëÝÖˆfäž3 !z9É xPÄù€x¯„xlibm.so.6__gmon_start___Jv_RegisterClassessqrtatan2sincossqrtflibc.so.6_IO_stdin_usedfflushstrcpy__printf_chkexit_IO_putcfopen__isoc99_sscanf__stack_chk_failstdinfgets__fprintf_chkstdoutfputsmemcpyfclosemalloc__ctype_b_locstderratofatoi__sprintf_chk_IO_getcstrcmp__libc_start_mainfreeGLIBC_2.1GLIBC_2.0GLIBC_2.4GLIBC_2.3GLIBC_2.7GLIBC_2.3.4 0ii ?ii IFii Sii ?ii ]ii gti qii Ið/€x„x  x000 00000 0 $0 (0 ,0 004080<0@0D0H0L0P0T0X0\0`0d0h0U‰åSƒìè[ÃĨ‹“üÿÿÿ…ÒtèNèeè yX[ÉÃÿ5ø/ÿ%ü/ÿ%0héàÿÿÿÿ%0héÐÿÿÿÿ%0héÀÿÿÿÿ% 0hé°ÿÿÿÿ%0h é ÿÿÿÿ%0h(éÿÿÿÿ%0h0é€ÿÿÿÿ%0h8épÿÿÿÿ% 0h@é`ÿÿÿÿ%$0hHéPÿÿÿÿ%(0hPé@ÿÿÿÿ%,0hXé0ÿÿÿÿ%00h`é ÿÿÿÿ%40hhéÿÿÿÿ%80hpéÿÿÿÿ%<0hxéðþÿÿÿ%@0h€éàþÿÿÿ%D0hˆéÐþÿÿÿ%H0héÀþÿÿÿ%L0h˜é°þÿÿÿ%P0h é þÿÿÿ%T0h¨éþÿÿÿ%X0h°é€þÿÿÿ%\0h¸épþÿÿÿ%`0hÀé`þÿÿÿ%d0hÈéPþÿÿÿ%h0hÐé@þÿÿ1í^‰áƒäðPTRhhQVh2Žè“þÿÿôU‰åSƒì€=¤xu?¡¨x»/ë/Áûƒë9Øs¶ƒÀ£¨xÿ…/¡¨x9ØrèƤxƒÄ[]Ãt&¼'U‰åƒì¡/…Àt¸…Àt Ç$/ÿÐÉÃU‰åWVSƒìƒ=¬x~5¾» ¹‰÷‹³ƒ8 u ‹@D‰$èO‹»‰$èØýÿÿƒÆ95¬xÕǬxÇ°xƒ=´x~ »¾Äy‹Þ‰$è›ýÿÿƒÃ9´xêǸxÇ´xÇØxÇÈxÇàxÇÀxǼxÇÄxÇ yǤyÇ°0Ǭ0Ǹ00uÇ´00uÇÀ0ЊÿÿǼ0ЊÿÿƒÄ[^_]ÃU‰åWVSì\‹}e¡‰Eä1ÀÇÔxÊûÿÿéh‹5ÔxƒÆ‰5Ôx€½Êûÿÿ.…;€½ËûÿÿP….€½ÌûÿÿS…!¶•Íûÿÿ…Íûÿÿ€ú u ƒÀ¶€ú tõ€ú<…ÖƒÀ‰…¼ûÿÿ‹@¸‰•´ûÿÿ¡0‰…¸ûÿÿU²‰T$ÇD$] ‹…¼ûÿÿ‰$èÐûÿÿÇD$ó U²‰$èmüÿÿ£@¸…Àu0E²‰D$ ÇD$ÈÇD$¡€x‰$è`ûÿÿÇ$èÔüÿÿÇÔx‹•¼ûÿÿ‰0‰$èÎþÿÿ¡@¸‰$èéûÿÿ‰5Ôx‹…´ûÿÿ£@¸‹•¸ûÿÿ‰0é6ènýÿÿè¾W€½Íûÿÿ u…Îûÿÿ‰$èæûÿÿkÀd£Œ0£ˆ0ë~‹5¼0+5´0u ‹5À0+5¸0Ç$Üè'‰µÄûÿÿÛ…Äûÿÿ‰…ÄûÿÿÛ…ÄûÿÿØ=ÈÞÉÙ½Âûÿÿ·…Âûÿÿ´ f‰…ÀûÿÿÙ­ÀûÿÿÛÄûÿÿÙ­Âûÿÿ‹…Äûÿÿ£Œ0£ˆ0ƒ=Ðxt-‹ ˆ0¸…ëQ÷éÁúÁù)ʉT$ÇD$âÇ$ècúÿÿƒ=Èxt)ƒ=Øxu •Íûÿÿ‰$è(Pèš¡0œ‰$èÑO¡ x‰$ètúÿÿë¡ x‰D$‰$èÁùÿÿ‰|$ÇD$è‰$è úÿÿ…À…|ýÿÿ‹Uäe3t t&èÏúÿÿÄ\[^_]ÃU‰åWVSƒì¡@…Àt8»¾D¿@‰$èî‹Þ‰T$ÇD$‰$è!ƒÃ‹ß…Àu׃Ä[^_]ÃU‰åƒäðWVSƒì$‹U ‹£¨yƒ}ŽË‰ÓƒÃ‹€8-…¶pV¬€ú#w ¶Òÿ$• ‹] éÞÇD$ î‹U ‹‰D$ÇD$óÇ$èùÿÿÇ$èCúÿÿƒÀ‰Æ¿¹ó¦—Á’Â8Ñu0Çœ0Ðǘ0Ǥ0Ç 0‹] éb‰Æ¿¹ó¦—Á’Â8Ñu0Çœ0°Ç˜0Ǥ0Ç 0‹] é‰Æ¿ ¹ó¦—Á’Â8ÑuÇœ0ðǘ0‹] éæ‰$èôøÿÿ£œ0‹] éÑÇ”0‹] 鿃À‰$èÊøÿÿkÀd£Œ0‹] 餃À€8u5ƒm‹C‰$è³øÿÿØ ÈÙ|$·D$´ f‰D$Ùl$Ûˆ0Ùl$ë/‰$è…øÿÿØ ÈÙ|$·D$´ f‰D$Ùl$Ûˆ0Ùl$‹] ‰ðé‹S,‰UÜ‹C0‰Eäø‰ÂÁêÑø‰D$‹EÜEà‰ÂÁêÑø‰$è—>‰$è…øÿÿ‹C ¨t‹Uä‰T$‹E܉$èv>éÁ‹ƒú u&‰D$C@‰D$ ‹C<‰D$‰|$‹Uà‰$èÏ@锃út ƒúf…„‹S(‰T$‹S$‰T$‰D$C@‰D$ ‹C<‰D$‰|$‹Eà‰$è#?ëS‰|$‹Uà‰$èô=‰$èâ÷ÿÿë:‹C,‰Eä‹[0‰|$‹Uà‰$èÒ=ÇD$‰\$‹Eä‰$è‰B‹Uä‰$èZîÿÿƒÆ95¬x‚ûÿÿƒÄL[^_]ÃU‰å‹E= tQ= = uMt&ë0= t=u6¶ë ÇÄxë"ÇÄxëÇÄxë ÇÄx¡Äx]ÃU‰å‹U‹E -3ƒø‡ÿ$…‹Bé~‹Bëyƒ: vw/‹ ¸Óà¨(u¨Du©t‹B,vëQ‹B,ÀëJ‹B,+BëBƒ: w,‹ ¸Óà¨(u¨Du©t‹B0ë ‹B0Àë‹B0+B닃øtƒøu‹B,ë]ÃU‰å‹U‹E 9¼0}‰¼09À0}£À0;´0}‰´0;¸0}£¸0]ÃU‰åSƒì‹] ,‰$èeíÿÿ…ÀuÇ$Àè4Ç$è©íÿÿ‹U‰‰X‹¬x‰P‹ Äx‰H ‹ ¼x‰H‹ Àx‰H‹ ¸x‰H‹ ´x‰H‰ ¸xÇ@(Ç@$Ç@ ú'~Ç$Úè4Ç$è0íÿÿ‰• ¹ƒÂ‰¬xƒÄ[]ÃU‰åƒìÇD$Ç$è"ÿÿÿ‹U‰P‹U ‰PÉÃU‰åƒì(‰]ô‰uø‰}ü‹]‹} ‹uƒ=Ðxt&‰ðC‰D$ ‰øC‰D$ÇD$ìÇ$èkëÿÿs‰t${‰<$èÿÿÿ‹]ô‹uø‹}ü‰ì]ÃU‰åWVSƒì,‹u ‹ ¬x…É~i‹E‰E丿 ¹‹‡‹ƒú u ƒþ t‹C@ƒÀë;9òu7ƒmäƒ}ä-ƒ=ÐxtC‹S‰T$ ‹C‰D$ÇD$Ç$èÖêÿÿëƒÀ9È|§‹E‰D$Ç$èÄ2»‰ØƒÄ,[^_]ÃU‰åWVSƒì‹u ¡¬xƒèxU‹}¹ ¹‹‹ƒú u‹C<ë99òu5ƒï…ÿ-ƒ=ÐxtA‹S‰T$ ‹C‰D$ÇD$/Ç$èGêÿÿëƒèy³‹E‰D$Ç$Iè72»‰ØƒÄ[^_]ÃU‰åƒìƒ=Ðxt&¡Àx‰D$ ¡¼x‰D$ÇD$_Ç$èééÿÿ¡Àx‰D$¡¼x‰$èùýÿÿÉÃU‰åƒì8‰]ô‰uø‰}ü‹]ƒ=Ðxt‹E ‰D$ ‰\$ÇD$nÇ$è—éÿÿ‹{‹s‹C,‰EÜ‹S0‹ƒø ‡^ÿ$…‹M é(ƒù ‡Eÿ$H‰ÐÁèÑúÖé-‰ÐÁèÑú)Öé‹EÜÁèEÜÑøÇé ‹EÜÁèEÜÑø)Çéø‹EÜÁèEÜÑøljÐÁèÑúÖéÚ‹EÜÁèEÜÑø)ljÐÁèÑú)Ö鼋EÜÁèEÜÑøljÐÁèÑú)Öéž‹EÜÁèEÜÑø)ljÐÁèÑúÖ逃ø …wÇD$1‹C4‹… ¹‰$è«þÿÿ鉃ø …OÇD$2‹C8‹… ¹‰$èƒþÿÿéa‹M é(ƒù‡ÿ$tÖé)Öé}Üé+}Üéø‰}äÛEäÛEÜÝ8ÜÉÙÉÞÂÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹}ä‰uäÛEä‰UäÛEäÞÊÞÁÙmàÛ]äÙmâ‹uä駉}äÛEäÛEÜÜ 8ÞÁÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹}ä‰uäÛEä‰UäÛEäÜ @ÞÁÙmàÛ]äÙmâ‹uäéX‰}äÛEäÛEÜÜ @ÞÁÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹}ä‰uäÛEä‰UäÛEäÜ 8ÞÁÙmàÛ]äÙmâ‹uäé ‰}äÛEäÛEÜÝ@ÜÉÙÉÞÂÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹}ä‰uäÛEä‰UäÛEäÞÊÞÁÙmàÛ]äÙmâ‹uä鸋M é(ƒù ‡¦ÿ$”}܉øÁè<8Ñÿò‰ÖÁîÖÑþé‚9Ö|yë|9Öt&n¶ëk;}Üv|^¶ë[;}ÜvN¶ëK} 1´&t} 2´&u+¶ëöC ft‹{4‹s8ëöC u‹{4‹s8ë‰Ö‹}܃=Ðxt‰t$ ‰|$ÇD$|Ç$èúåÿÿ‰t$‰<$èúÿÿ‹]ô‹uø‹}ü‰ì]ÃU‰åVSƒì ‹] ‹uƒ=ÐxtÙàUÝ\$ÇD$’Ç$è¬åÿÿÇD$Ç$èúøÿÿ‹S‰UôÛEô‹N)щMôÛEôØ àUÞÁÙüÜÁÙÉÙ}ò·Uò¶ f‰UðÙmðÛXÙmò‹S‰UôÛEô‹N)щMôÛEôØ àUÞÁÞÁÙmðÛXÙmòƒÄ [^]ÃU‰åƒì‹Eƒ=Ðxt"‹P‰T$ ‹@‰D$ÇD$£Ç$èúäÿÿÉÃU‰åƒìƒ=Ðxt‹E‰D$ÇD$§Ç$èÎäÿÿÉÃU‰åƒì(‰]ø‰uü‹u‹] …Ûu…öu Ç°xëIƒ=Ðxt%‰\$‰t$ ¡°x‰D$ÇD$«Ç$èxäÿÿ¡°x‰4Å`¸‰Åd¸ƒÀ£°x‹]ø‹uü‰ì]ÃU‰åVSƒì‹E‹u ƒ8 t‰t$Ç$¼è:,¸ëe‹XD…ÛtI‹‰D$‰4$èDåÿÿ…Àu0ƒ=Ðxt"‹C‰D$ ‹C‰D$ÇD$ðÇ$èåãÿÿ‹Cë‹[ …Ûu·‰t$Ç$ÕèÓ+¸ƒÄ[^]ÃU‰åƒì(‰]ô‰uø‰}ü‹u‰÷¸¹ÿÿÿÿò®÷щ $èsäÿÿ‰Ã…Àu‰t$Ç$è‡+Ç$è±äÿÿ‰t$‰$èäÿÿ‰Ø‹]ô‹uø‹}ü‰ì]ÃU‰åSƒì‹]…Ût‹‰$è|ãÿÿ‰$ètãÿÿ‹[ …ÛuçƒÄ[]ÃU‰åWVSƒì,‹u‹=àx…ÿx8‰øÁàV‰Eä‹Eä‹…Ût‹‰D$‰4$èäÿÿ…Àt‹[ …Ûuçƒmä ƒïyÕ»‰ØƒÄ,[^_]ÃU‰åSƒì‹]‰$è‘ÿÿÿ…Àu8¶ƒèa<w‰\$Ç$Hè¤*¸ë‰\$Ç$_è*¸ë‹@ƒÄ[]ÃU‰åVSƒì‹u¡àxÁà‹˜V…Ût$‹‰D$‰4$èxãÿÿ…Àt ‹[ …Ûuçë …Ût&uOÇ$´&èÿâÿÿ‰Ã…Àu‰t$Ç$sè*Ç$è=ãÿÿ¡àxT¸ VÁâ‹ ‰K ‰‰3‹E ‰C‹E‰C‰ØƒÄ[^]ÃU‰åWVSƒì<‹E‹P+P4‰Uà‹P+P8‰Uä‹Xƒ=Ðxt‰T$ ‹Eà‰D$ÇD$Ç$è{áÿÿ4¤¹¿‹‹ƒø uƒÇë ƒø ”¶Ò)׃=Ðxt&‹S‰T$‹S‰T$ ‰D$ÇD$äÇ$è'áÿÿ‹EàC‰C‹UäS‰Sƒ=Ðxt‰T$ ‰D$ÇD$«Ç$èðàÿÿ‹ƒøt-ƒø ƒøu;vëƒøvtƒø vu&‹EàC,‹EäC0ë‹EàC,‹EäC0‹EàC4‹EäC8ƒÆ…ÿ*ÿÿÿƒÄ<[^_]ÃU‰åWVSƒìl‹u‹V4‹N,‰Ð)ȉEä‹^8‹F0‰ß)lj}à‰ÑÁéÑú‰UÌ؉ÃÁëÑø‰EЃ=Ðxt‰D$ ‰T$ÇD$»Ç$è'àÿÿÇEÔƒ=°xŽfÇEÈÇEÄÇEÜÇEØ»¿`¸‰Ú‹ß=„Ü=<=„¨=fƒø¸EEÔ‰EÔéÞˆûþÿÿƒù‡Ïé·=tD==tS=…§vë=%t(=0…Žfëw‹Ýd¸‰Uàë~‹Ýd¸‰Uäër¡Ì0‰Eà‹È0‰Uäë_‹Ýd¸‰UÜëS‹Ýd¸‹MÌ+H‰MÄ‹UÐ+P‰UÈÇEÜë1‹Ýd¸‹P‰¼x‹@£ÀxƒEØë‹Õd¸‰T$‰$è,"ƒÃ9°xÔþÿÿ‹Uä‹Màƒ}Ü„þ‹EÜ-(ƒø‡Ûÿ$…,ƒÁ‰ÈÁè Ñù÷Ù‰MÈ齉ÈÁè Ñù‰MÈ髃‰ÐÁèÑú÷Ú‰UÄ锉ÐÁèÑú‰UÄ邃‰ÐÁèÑú÷Ú‰UăÁ‰ÈÁè Ñù÷Ù‰MÈë\ƒÂ‰ÐÁèÑú÷Ú‰UĉÈÁè Ñù‰MÈë;‰ÐÁèÑú‰UăÁ‰ÈÁè Ñù÷Ù‰MÈë‰ÐÁèÑú‰UĉÈÁè Ñù‰MÈ‹MÄ ¼x‹}È=Àxƒ}Øug¡Äx…Àu‹EäƒÀ‰ÂÁêÑø¼xëFƒøu‹EäÁèEäÑø)¼xë.ƒøu‹EàƒÀ‰ÂÁêÑøÀxë‹EàÁèEàÑø)Àx¡¼x‹UäÁêUäÑú‰Á)щMØ‹ Àx‹}àÁï}àÑÿ‰Ê)ú‰UÜ‹UäƒÂ‰ÓÁëÓÑûËEàƒÀ‰ÇÁïÇÑÿÏ‹M܉L$‹E؉$èðÿÿ‰|$‰$èøïÿÿ¡¼x‰F¡Àx‰F¡¸x‰F¡´x‰F¡´x£¸x‹Uä‰V,‹Mà‰N0‹ẺF4‹UЉV8‹M‹Aƒè‰F@ÇF$ÇF(‹EÔ‰F ƒ=ÐxtJ‹Uä‰T$$‹Mà‰L$ ¡Àx‰D$¡¼x‰D$‰|$‰\$‹E܉D$ ‹U؉T$ÇD$Ç$è"Üÿÿ¡Äx…Àub‰¼x‹F,‹M‰A,‹F0‰A0‹F4‰A4‹F8‰A8‹F<‰A<‹F@‰A@¡àxÁàÇ€‹EØ‹<…à0‹…Ø0‰UÜë(‹Ýd¸‰UÌë‹Ýd¸‹P‰¼x‹@£ÀxƒEÔƒÃ9°xÎþÿÿƒ}‹EÜDljE܃}Ì„n‹MÌé(¸ºƒù‡Fÿ$Ô‹Eܺé2‹EÜ÷غé#‰ú÷Ú¸é‰ú¸é ‰ø÷؉EäÛEäÝ8ÜÉÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹Uä‹EÜ÷؉EäÛEäÞÉÙmàÛ]äÙmâ‹Eä龉ø÷؉EäÛEäÝ8ÜÉÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹UäÛEÜÞÉÙmàÛ]äÙmâ‹Eäë~‰}äÛEäÝ8ÜÉÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹Uä‹EÜ÷؉EäÛEäÞÉÙmàÛ]äÙmâ‹Eäë:‰}äÛEäÝ8ÜÉÙÉÙ}â·Eâ´ f‰EàÙmàÛ]äÙmâ‹UäÛEÜÞÉÙmàÛ]äÙmâ‹Eä¼xÀxƒ}Ôu7¡Äx…Àu=¼xë&ƒøu)=¼xëƒøu ‹UÜÀxë ‹EÜ)ÀxÇD$‹U‰$èzäÿÿ‰Ã‹E؉<…à0‰{,‹U܉…Ø0‰S0…ÿ~…Ò.ƒ}¸º˜DÂ9}Ü‹UÜO׉T$‰D$Ç$ŸèЋEЉC ‹EÜÀx‰D$‰ø¼x‰$èÄãÿÿ¡Àx+E܉D$¡¼x)ø‰$è©ãÿÿƒ}u5ƒ=Ðxt,‰|$¡Àx‰D$ ¡¼x‰D$ÇD$¹Ç$èOÐÿÿë@ƒ}u:ƒ=Ðxt1‹U܉T$‰|$¡Àx‰D$ ¡¼x‰D$ÇD$ÅÇ$è Ðÿÿ¡Äx…Àu=¼xë&ƒøu)=¼xëƒøu ‹EÜÀxë ‹UÜ)Àx‰ØƒÄL[^_]ÃU‰åWVSì¬Ç$Mèâìÿÿ£è0Ç$ièÑìÿÿ£ì0Ç$qèÀìÿÿ£ð0¡¼x‰EÀ‹Àx‰Uă=°xÇE¤ÇE°ÇE´éHÇE¤ÇE°ÇE¬ÇE¨ÇE´»¾`¸¿d¸‰Ú‹Þ=„|=}= „¼= +ƒø„σøfŒ«=t&Œ›féÀ= ¶„U= t&Œ]=„F=f…[féã=¶„Ž=t&#=to=„ª=…éÉ=¶tl=|W=tj=0f…ëfëÇE¤´&éÔ‹׉T$‰$èTéÀ‹ßE´éµ‹ߣì0騋ߣð0雋ߣè0鎋߉ÂÁêÑø£è0ëzÇE°ëq‹ß‹P‰UÀ‹@‰EÄë`‹ß‹P‰U¸‹@‰E¼ƒE¨ëK‹ß‹P‰¼x‹@£ÀxÇE¬ë.ÇÄxë"ÇÄxëÇÄxë ÇÄxƒÃ9°xþÿÿ‹U¼‹E¸‹}Ä‹uÀ‹]°ƒ}¬uwƒ}¨uq‹E°ÁàÄx‹… ¯è0UÀ‰¼x‹…€¯è0UĉÀx‹ è0‰Ê¯…àUÀ‰U¸‰Ê¯…ÀUĉU¼‹…`£Äxé̓}¬…~)ð‰EÌÛEÌÙüÜÉÙÉÙ]¨)ú‰UÌÛEÌÞÉÙU¬ÙE¨Ý•xÿÿÿÙÉÝU€ÙÉÝ\$Ý$èPÍÿÿÝ]ˆ…ÛÝÝÛÉÝÙÝ]Ûè0Ù] ÙE¨ØÈÙE¬ØÈÞÁÙE ØÈØáÙîÛér"ÝÙÙE ëÝÚØÀÙÀØÉØãÙÊÛêsðÝØÝÚÙÉÙ] ëÝØÝÙÙÀÙúÛèztÝØëÝØÙ$è¨ËÿÿëÝÙÝ]˜ÝEˆÜEÙ]äÙEäÝUUØEЉD$ ‰T$Ý$èüÌÿÿ‰uÌÛEÌØE¨ÝE˜ÜMÐÞÁÙüÜÁÙÉÙ}Ê·EÊ´ f‰EÈÙmÈÛ¼xÙmʉ}ÌÛEÌØE¬ÝE˜ÜMØÞÁÞÁÙmÈÛÀxÙmʃ=Ðx„ÝE˜Ý\$(ÙE Ý\$ ÝEÝ\$ÝE€Ý\$Ý…xÿÿÿÝ\$ÇD$ôÇ$èËÿÿëEƒ}¨u?‹ è0Äx‰È¯•à‰E¸‰È¯•À‰E¼‹•`£Äxƒ}°t'ƒ}´u ÇE´éìƒ}´¸EE´‰E´é×ÇD$‹E‰$èíÝÿÿ‰Ã‹UĉT$‹EÀ‰$è˜Ýÿÿ‹U¼‰T$‹E¸‰$è†Ýÿÿ‹UÀ‰S,‹EĉC0‹U¸‰S4‹E¼‰C8‰¼x£Àx‹ð0‰S<¡ì0‰C@¹ M´ M¤‰K ƒ=ÐxtF‰D$$‰T$ ‹C8‰D$‹C4‰D$‹C0‰D$‹C,‰D$‹C‰D$ ‹C‰D$ÇD$Ç$èÔÉÿÿ‰ØĬ[^_]ÃÇD$‹U‰$èÝÿÿ‰Ã‹E¼‰D$‹U¸‰$èÁÜÿÿ‹EĉD$‹UÀ‰$è¯Üÿÿ‹E¸‰C,‹U¼‰S0‹EÀ‰C4‹UĉS8‹E¸£¼x‹U¼‰Àx‹ð0‰S<¡ì0‰C@¹éÿÿÿU‰åWVS졼x‰…(þÿÿ‹Àx‰•0þÿÿÇ$èKæÿÿ‰…þÿÿÇ$è9æÿÿ‰… þÿÿÇ$iè'æÿÿ£ô0Ç$qèæÿÿ£ø0Ç…XþÿÿÇ… ÿÿÿƒ=°xŽ¡Ç…4þÿÿÇ…þÿÿÇ… þÿÿ¾Ç…þÿÿÇ…$þÿÿ¿Ç…,þÿÿÇ…8þÿÿ‰½<þÿÿ‰ò‹õ`¸û„ŸûŒû „hû 0û t&ût&+ƒû…ƒéût&„•ût&ŒJût&„ût&…<féËût&„¡ût&Sû„Ëût&û…ôfé ût&„Dût&…Ìfé)û;t&0û:Âû%t&„âû0t&…Œfë'û<…|fëQ‰ø‹<þÿÿÇ…þÿÿéi‹Õd¸‰D$‰$è, ‰ø‹<þÿÿéI‹ õd¸,þÿÿ‰ø‹<þÿÿé/G…ÿu‹õd¸‰•þÿÿ‰• þÿÿ‹<þÿÿé ‹õd¸‰•þÿÿ‹<þÿÿéò‹õd¸‰•$þÿÿ‰ø…Ò…ÛÇ$.èãÿÿ‰…$þÿÿ‰øé¡ü0‹•4þÿÿ‰„• ÿÿÿ¡äx‰„•Xþÿÿƒ…8þÿÿ‰ø‹<þÿÿé‹õd¸…ÀD…þÿÿ‹4þÿÿ)„ ÿÿÿƒ…8þÿÿÇÄx‰ø‹<þÿÿéU‹õd¸…ÀD…þÿÿ‹•4þÿÿ„• ÿÿÿƒ…8þÿÿÇÄx‰ø‹<þÿÿé‹õd¸…ÀD… þÿÿ‹4þÿÿ„Xþÿÿƒ…8þÿÿÇÄx‰ø‹<þÿÿéß‹õd¸…ÀD… þÿÿ‹•4þÿÿ)„•Xþÿÿƒ…8þÿÿÇÄx‰ø‹<þÿÿ餋õd¸£ô0‰ø‹<þÿÿé‹‹õd¸£ø0‰ø‹<þÿÿérƒ½8þÿÿtS‹4þÿÿ‹Œ ÿÿÿ(þÿÿ‹…4þÿÿ‹„…Xþÿÿ…0þÿÿƒ…4þÿÿ‹4þÿÿÇ„XþÿÿÇ„ ÿÿÿÇ…8þÿÿ‹Õd¸‹P+•(þÿÿ‹4þÿÿ‰” ÿÿÿ‹@+…0þÿÿ‰„Xþÿÿƒ…8þÿÿ‰ø‹<þÿÿéÕ‹õd¸‹P‹4þÿÿ‰” ÿÿÿ‹@‰„Xþÿÿƒ…8þÿÿ‰ø‹<þÿÿé ƒ½8þÿÿ„‹‹…4þÿÿ‹„… ÿÿÿ…(þÿÿ‹•4þÿÿ‹”•Xþÿÿ•0þÿÿƒ…4þÿÿ‹4þÿÿÇ„XþÿÿÇ„ ÿÿÿ‰ø‹<þÿÿÇ…8þÿÿë6‹Õd¸‹P‰•(þÿÿ‰¼x‹@‰…0þÿÿ£Àx‰ø‹<þÿÿë‰ø‹<þÿÿƒÆ95°x~ ‰Ç‰<þÿÿéþúÿÿ‰þÿÿ‹0þÿÿ‹½(þÿÿ‹•4þÿÿƒ½8þÿÿts‹œ• ÿÿÿ<;‹´•Xþÿÿ ‰0þÿÿƒÂ‰•8þÿÿé Ç…4þÿÿÇ…þÿÿÇ… þÿÿ¸Ç…þÿÿÇ…$þÿÿÇ…þÿÿÇ…,þÿÿ‹Äx‹þÿÿ¯•|‹µ þÿÿ¯4•l‹4þÿÿ‰œ ÿÿÿ‰´XþÿÿƒÁ‰8þÿÿ‹½(þÿÿß‹•0þÿÿò‰•0þÿÿ‰ü0‰5äx…À„Ÿƒøu!ƒ½ þÿÿuÇ$Cèßÿÿ‰…þÿÿ‰… þÿÿ‰DþÿÿÛ…DþÿÿÝ\$‰µDþÿÿÛ…DþÿÿÝ$èÃÿÿ•Pþÿÿ…Hþÿÿ‰D$ ‰T$Ý$èOÃÿÿÝ…HþÿÿÝ…PþÿÿÛ… þÿÿÙÀØËÙ½Bþÿÿ·…Bþÿÿ´ f‰…@þÿÿÙ­@þÿÿÛDþÿÿÙ­Bþÿÿ‹•DþÿÿØÉÙ­@þÿÿÛDþÿÿÙ­Bþÿÿ‹…Dþÿÿ‹ ¼xщ<þÿÿ‰ ¼x‹5ÀxƉµ(þÿÿ‰5ÀxÛ…þÿÿÜÊÙÊÙ­@þÿÿÛDþÿÿÙ­Bþÿÿ‹DþÿÿÞÉÙ­@þÿÿÛDþÿÿÙ­Bþÿÿ‹Dþÿÿ)ß)0þÿÿ)• ÿÿÿ)…Xþÿÿ‹µ4þÿÿ)œµ ÿÿÿ)ŒµXþÿÿƒ=ÐxtF‹µ0þÿÿ‰t$$‰|$ ‹µ(þÿÿ‰t$‹µ<þÿÿ‰t$‰L$‰\$‰D$ ‰T$ÇD$Ç$èÆÀÿÿ‹•8þÿÿD‰D$‹M‰ $èÔÿÿ‰…<þÿÿ‰x,‰=¼x‹µ0þÿÿ‰p0‰5Àxƒ½,þÿÿuƒ}u/¡ø0‹•<þÿÿ‰B4¡ô0‰B8ƒ½,þÿÿ¸E…,þÿÿ‰…,þÿÿ‹…,þÿÿ …þÿÿ‹<þÿÿ‰A ‹µ8þÿÿ‰q<‹q‹yƒ½8þÿÿ~B»‹„ ÿÿÿ‹•<þÿÿ‰DÚ@‹”Xþÿÿ‹<þÿÿ‰TÙD×Ɖ|$‰4$èÓÿÿƒÃ98þÿÿË…þÿÿ‹µ<þÿÿ‰F$‹•$þÿÿ‰V(ƒ=Ðx„€‹8þÿÿ‰L$¡Àx‰D$¡¼x‰D$‹F‰D$ ‹F‰D$ÇD$<Ç$è¿ÿÿƒ½8þÿÿ~9‰ó¾‹½8þÿÿ‹CD‰D$ ‹C@‰D$ÇD$µÇ$èG¿ÿÿƒÆƒÃ9÷Ô‹µ<þÿÿ‹F‰D$‹F‰$èFÒÿÿ¡Àx‰D$¡¼x‰$è0Òÿÿ‰ðÄ[^_]ÃU‰åƒì‹E‰$è­õÿÿÉÃU‰åWVSƒì,Ç$&è Üÿÿ‰EØÇ$èþÛÿÿ‰E܃=°xŽV¾ÇEäÇE໿`¸‹ß‚ûþÿÿƒø+‡ÿ$…Œ‹Ýd¸‰D$‰$èËéï¡ìx‰Eà‹èx‰UäƒÆéÖ‹Ýd¸…ÀDEØ)EàƒÆÇÄxé´‹Ýd¸…ÀDEØEàƒÆÇÄxé’‹Ýd¸…ÀDEÜEäƒÆÇÄxës‹Ýd¸…ÀDEÜ)EäƒÆÇÄxëT‹Ýd¸‹P+¼x‰Uà‹@+Àx‰EäƒÆë0‹Ýd¸‹P‰Uà‹@‰EäƒÆë‹Ýd¸‹P‰¼x‹@£ÀxƒÃ9°xÑþÿÿ‹}à‹]ä…öu¡Äx‹}د<…L ‹]ܯ…< ‰=ìx‰èx¡Àx‰D$¡¼x‰$èFÐÿÿ=¼x‰=¼xÀx‰Àx‰\$‰<$è"ÐÿÿÇD$Ç$èOÐÿÿ‰Ãƒ=Ðxt&¡Àx‰D$ ¡¼x‰D$ÇD$ÈÇ$è¼¼ÿÿ‰ØƒÄ,[^_]ÃU‰åƒì(‹U‹M ‚ûþÿÿƒø+w@ÿ$…° ºCë2ºL¶ë%ºRëºSfëºFëºAfëºB¡´x=Ï~‰D$Ç$\ è;Ç$èe½ÿÿ‰ÅÀy‰ ÅÄyƒ=Ðxt ‰D$‰L$ ‰T$ÇD$x Ç$èî»ÿÿƒ´xÉÃU‰åƒì(‰]ô‰uø‰}ü‹]‰Þ¿‘ ¹ó¦—Â’À8Âu Ç$• 蹉\$Ç$0èûþÿÿÇD$Ç$ èíÎÿÿ‹]ô‹uø‹}ü‰ì]ÃU‰åWVSƒì,‹°x…ÛÇEÜÇEäCÇEàéÇÇEܸÇEäCÇEà¾`¸¿l ‹Æêƒú ‡†ÿ$—ÇEäLëz‹Åd¸)UÜën‹Åd¸UÜëb‹Åd¸UàëV‹Åd¸)UàëJ‹Åd¸‹J‰ ¼x‹R‰Àxë/ÇEäRë&ÇEäSëÇEäFëÇEäAt&ëÇEäBƒÀ9Ø…]ÿÿÿƒ=Ðxt"‹E‰D$ ‹Uä‰T$ÇD$` Ç$èUºÿÿ¡Àx‰D$¡¼x‰$è`Íÿÿ‹Eܼx£¼x‹UàÀx‰Àx‰T$‰$è7ÍÿÿÇD$Ç$èdÍÿÿ‹U‰P,‹Uä‰P0ƒÄ,[^_]ÃU‰å]ÃU‰åSƒì‹E‹1ƒÂ‰1úà—rÇ$  è¼Ç$èæºÿÿ‹ 1ƒéù€X»GYBˉ 1ˆ¾ÀƒÄ[]ÃU‰åWVSƒì‹U‰×¸¹ÿÿÿÿò®÷ÑYÿ‰Îƒîx¾Cÿ‰$èjÿÿÿƒëƒîyìƒÄ[^_]ÃU‰åSƒì‹1ƒëû€Xv€; uƒëû€Xr€; tƒëû€Xs€; t ë€; vuæƒÃ€; tøÇD$³ ÇD$¡€x‰$è¸ÿÿ91v ¾ƒÃ‹€x‰T$‰$è͹ÿÿ91wàÇD$Á ÇD$¡€x‰$èH¸ÿÿ¡1=`Yr(¾ƒè£1¡€x‰D$‰$耹ÿÿ¡1=`YsØ¡@¸‰D$ÇD$ÈÇ$€XèG¸ÿÿÇD$ €XÇD$] ÇD$¡€x‰$èÒ·ÿÿÇ$Å èˆþÿÿÇ1€XƒÄ[]ÃU‰åƒì(ƒ=Øx…“ÇD$Ê ÇD$¡€x‰$膷ÿÿ‹E‰D$‹E‰D$‹E‰D$‹E ‰D$ ‹E‰D$ÇD$¡€x‰$èN·ÿÿ¡0‰D$¡Ôx‰D$ ÇD$Ð ÇD$¡€x‰$è·ÿÿè!þÿÿÇØxÉÃU‰åƒì‹1ú`Yr¾ƒê‰1ë8¡@¸‰$èO·ÿÿƒø u ƒÔxëƒøÿuÇ$è è ÿÿÿÇ$è4¸ÿÿ=1HYº€XB1ˆƒÂ‰1¾ÀÉÃU‰åWVSƒì,‹uÇEä¿ècÿÿÿ‰Ãƒøÿu Ç$ è¨þÿÿƒ}äu ƒû,tOƒû)tJƒû"uˆƒÆƒÇè.ÿÿÿ‰Ãƒø"t'ƒøÿuçë ƒû(´&uƒEäfë ƒû)”À¶À)EäƒÇˆƒÆëŽÆ‰$èZüÿÿGƒÄ,[^_]ÃU‰åWVSƒì‹}ÇœèÅþÿÿƒø(t Ç$ è þÿÿÇÈ›à—¾à›ë&¡œ‹È›‰†ƒÀ£œèˆþÿÿƒø)tÈ›¡È›‰$èðþÿÿ‰ÃƒøÿuÆ‹ œƒù à›ºœÇÀ ƒÀ9Ðuóƒ=Ðxt8…É~4»¾à›‹ž‰D$ ‰\$ÇD$. Ç$è]µÿÿƒÃ9œÖ‹G‰Ã€8tƒÃ€;uøƒë9ØwQsÿ€>$u4蜵ÿÿ¶¾Ê‹öDHt‹›‰$èûÿÿë¾Ò‰$è"ûÿÿ‰Þë ¾‰$èûÿÿ‰Þ^ÿ9_v¯ƒÄ[^_]ÃU‰åWVSì|‹}‹u e¡‰Eä1Àèpýÿÿ‰Ã‰$èÕúÿÿƒû(u‰4$èyþÿÿvéݘûÿÿèFýÿÿˆƒÃ< uòƉ|$ÇD$ ; ÇD$dÇD$E€‰$èqµÿÿƒ=ÐxtE€‰D$ÇD$B Ç$è=´ÿÿE€‰$è´úÿÿƒ=Ðxt…˜ûÿÿ‰D$ÇD$B Ç$è ´ÿÿ…˜ûÿÿ‰$èúÿÿƒ=Ðxt‹F‰D$ÇD$B Ç$èÙ³ÿÿ‹F‰$èPúÿÿÇ$ èãùÿÿ…˜ûÿÿ‰D$‰|$ÇD$ U ÇD$dÇD$]€‰$è¡´ÿÿ‰$èÌÏÿÿ‹Uäe3tèh´ÿÿÄ|[^_]ÃU‰åWVSì\'‹E‰…ÄØÿÿe‹‰Uä1Òèùûÿÿ‰Ãƒø tôƒø tï}äµÔØÿÿëR9þu"‹…ÄØÿÿ‰D$Ç$] è ûÿÿÇ$èJ´ÿÿƒøÿu"‹•ÄØÿÿ‰T$Ç$z èùúÿÿÇ$è#´ÿÿˆƒÆè‹ûÿÿ9Ãu¥Æ…ÔØÿÿ‰$èÏÿÿ‰Æ‹…ÄØÿÿ‰$èÏÿÿ‰Ã…Àt9x t ‹•ÄØÿÿ‰T$Ç$¸ è™úÿÿ¸é•‹@‰$躲ÿÿ‰së"‹…ÄØÿÿ‰$èªÎÿÿ‰t$ÇD$ ‰$èàÏÿÿƒ=Ðxt"‰t$ ‹•ÄØÿÿ‰T$ÇD$˜ Ç$è(²ÿÿ‹…ÄØÿÿ‰D$ÇD$ ¯ ÇD$'ÇD$ÔØÿÿ‰$è³ÿÿ‰$è3Îÿÿ‹Uäe3tèϲÿÿÄ\'[^_]ÃU‰å‹Eðx]ÃU‰å‹Eôx]ÃU‰å‹E£ðx]ÃU‰å‹E£ôx]ÃU‰åƒì‹E‰$èÕÿÿÿ‹E ‰$è×ÿÿÿÉÃU‰åVSƒì‹]‹M ‹U‹Es9ÓDÖqÿ9ÁDƉ$œ‰ œ‰ œ£ œÛœ)Ú‰UôÛEôÞùٜۜ)Á‰MôÛEôÞùÙ(œƒÄ[^]ÃU‰åƒì‹E+$œ‰EüÛEüØ œØüÙ}ú·Eú´ f‰EøÙmøÛ]üÙmú‹EüÉÃU‰åƒìÛEØ œØüÙ}þ·Eþ´ f‰EüÙmüÛ]øÙmþ‹EøÉÃU‰åƒì‹E+À0‰EüÛEüØ (œØüÙ}ú·Eú´ f‰EøÙmøÛ]üÙmú‹EüÉÃU‰åƒì‹E‰$èGÿÿÿ‰$è™þÿÿ‹E ‰$è ÿÿÿ‰$è“þÿÿÉÃU‰åƒì‹EÙ(œÙîßév)‰EüÛEüÞÉØ%üÙ}ú·Eú´ f‰EøÙmøÛ]üÙmú‹Eüë'‰EüÛEüÞÉØüÙ}ú·Eú´ f‰EøÙmøÛ]üÙmú‹EüÉÃU‰å]ÃU‰åƒì8‰]ô‰uø‰}ü‹E‰$èàþÿÿ‰Æ‹E‰$èmÿÿÿ‰Ã‹E ‰$èöþÿÿ‰Ç‹E‰$è}þÿÿ‰ÚÁú1Ó)Ó‰\$‰òÁú1Ö)Ö‰t$‰|$ ‰D$ÇD$Ü Ç$èY¯ÿÿ‹]ô‹uø‹}ü‰ì]ÃU‰åWVSƒì<‹}‹u ‹]ÇD$ë Ç$è&¯ÿÿöÃtÇD$î Ç$è ¯ÿÿöÃtÇD$ð Ç$èô®ÿÿ}:u%‹E ‰$è þÿÿ‰D$ÇD$ò Ç$èÈ®ÿÿë/};u&‹U ‰$vèÙýÿÿ‰D$ÇD$÷ Ç$è—®ÿÿ‰<$è}ýÿÿ‰Ã£ðx‰4$èÚýÿÿ£ôx‰D$‰\$ ‹EƒÀ‰D$ÇD$ü Ç$èU®ÿÿ‹EÀ‰Eà…À~I»‹U<štš‰4$èŒýÿÿ‰Eä‰<$èýÿÿ‹Uä‰T$ ‰D$ÇD$ÿ Ç$è®ÿÿƒÃ;]à|¼ÇD$ Ç$èì­ÿÿƒÄ<[^_]ÃU‰åWVSƒì<‹}‹u ‹]ÇD$ Ç$è¾­ÿÿöÃtÇD$î Ç$襭ÿÿöÃtÇD$ð Ç$茭ÿÿ‰<$èrüÿÿ‰Ã£ðx‰4$èÏüÿÿ£ôx‰D$‰\$ ‹EƒÀ‰D$ÇD$ü Ç$èJ­ÿÿ‹EÀ‰Eà…À~I»‹U<štš‰4$èüÿÿ‰Eä‰<$è üÿÿ‹Uä‰T$ ‰D$ÇD$ÿ Ç$èý¬ÿÿƒÃ;]à|¼ÇD$ Ç$èá¬ÿÿƒÄ<[^_]ÃU‰åVSƒì ‹E‰$è´ûÿÿ‰Æ£ðx‹E ‰$èüÿÿ‰Ã£ôx‹E‰$èÌûÿÿ‰D$‰\$ ‰t$ÇD$ Ç$肬ÿÿƒÄ [^]ÃU‰åƒì8‰]ô‰uø‰}ü‹]‹uÇD$ Ç$èR¬ÿÿû:u"‰4$èlûÿÿ‰D$ÇD$ò Ç$è*¬ÿÿë)û;u!‰4$èAûÿÿ‰D$ÇD$÷ Ç$èÿ«ÿÿ‹E‰$èNûÿÿ‰Ã‹E‰$èÕúÿÿ‰Æ‹E ‰$è4ûÿÿ‰Ç‹E‰$è»úÿÿ‰\$‰t$‰|$ ‰D$ÇD$¡ Ç$è©«ÿÿ‹]ô‹uø‹}ü‰ì]ÃU‰åSƒì$‹E ‹UƒøAuƒÂëiƒøBuƒêë_’Òôx‰ôxH¿ƒùw»Óã÷Ãu¸ ‹M‰L$‰D$‰T$ ¡ðx‰D$ÇD$ Ç$è"«ÿÿƒÄ$[]Ã’Òôx‰ôxë»U‰åƒì‹E ‰D$‹E‰$è‡úÿÿÇD$ÇD$L¡Ü ‰$è8ÿÿÿÉÃU‰åƒì‹E‰D$ÇD$7 Ç$豪ÿÿÉÃU‰åƒì¡ôx‰D$ ¡ðx‰D$ÇD$% Ç$胪ÿÿÉÃU‰åƒìèÇÿÿÿÇD$. Ç$èbªÿÿÉÃU‰åƒìÇD$3 Ç$èFªÿÿÉÃU‰åƒìÇD$Ç Ç$è*ªÿÿ¡ x‰$èmªÿÿÉÃU‰åWVSƒìLÇôxÇðxÇœ0dƒ=Œ0u ¡ˆ0£Œ0‹ œ0Í£œ£œ‹5ˆ0…ö~9‹Œ0…Û~/¯ñ¿…ëQ‰ð÷ïÁúÁþ)ò‰œ¯Ë‰È÷ïÁúÁù)ʉœƒ=”0tV¡¼0‹´09Ðu&‹ À0‹¸0‰L$ Á)щL$‰T$‰$èË÷ÿÿëI‹ ¸0)Ó‰\$ ‰D$‰L$‰$èª÷ÿÿë(¡°0‰D$ ¡¬0‰D$¡ y‰D$¡¤y‰$è€÷ÿÿ¡°0‰D$$¡¬0‰D$ ¡ y‰D$¡¤y‰D$¡À0‰D$¡¼0‰D$¡¸0‰D$ ¡´0‰D$ÇD$6 Ç$褨ÿÿ¡°0‰$èñ÷ÿÿ‰Ã¡¬0‰$èv÷ÿÿ‰Æ¡ y‰$èÓ÷ÿÿ‰Ç¡¤y‰$èX÷ÿÿ‰EØ¡À0‰$è´÷ÿÿ‰EÜ¡¼0‰$è8÷ÿÿ‰Eࡸ0‰$è”÷ÿÿ‰Eä¡´0‰$è÷ÿÿ‰\$$‰t$ ‰|$‹U؉T$‹U܉T$‹Uà‰T$‹Uä‰T$ ‰D$ÇD$´ Ç$èê§ÿÿ¡¼0‰$èËöÿÿ‰Ã¡¸0‰$è(÷ÿÿ‹U‰T$‰\$ ‰D$ÇD$S Ç$諧ÿÿèbýÿÿƒÄL[^_]ÃU‰åWVSƒì<‹u‹]‹}‰ð+E‰EäÛEä‰Ø+E ‰EäÛEäÙÉØÈÙÉØÈÞÁÙúÙ]Ø‹E)ð‰EäÛEäÙüÜÉÙÉÙ]܉ø)؉EäÛEäÞÉÙUàÙEÜÝ\$Ý$è1¨ÿÿÝØÙEØØÈÙEÜØÈÙEàØÈÞÁÞéÙÀÙúßèztÙ$èÚ¦ÿÿÝØt&ëÝ؉<$èRöÿÿ‰EÜ‹E‰$èØõÿÿ‰Eà‰$è9öÿÿ‰Ç‰4$èÃõÿÿ‰Ã‹U ‰$è"öÿÿ‰Æ‹E‰$è©õÿÿ‹U܉T$‹Uà‰T$‰|$‰\$‰t$ ‰D$ÇD$` Ç$艦ÿÿƒÄ<[^_]ÃU‰åWVSƒìl‹u‹]‹}ÛEÝ\$‰}ÐÛEÐØ üÝ$èT§ÿÿÝ]¸‰øÁèøÑø¯ø‰øÁè<8Ñÿ‹E¯Àlj}ÐÛEÐÙÀÙúÛèztÝØëÝØÝ$èu¦ÿÿëÝÙÝ]ȉð+E‰EÐÛEÐÝ\$‰Ø+E ‰EÐÛEÐÝ$èë¦ÿÿÝUÀƒ=Ðx„çÝ\$ÝEÈÝ\$ÝE¸Ý\$ÇD$u Ç$èµ¥ÿÿÝEÀÜà Ý]ÀEàU؉T$ ‰D$ÝE¸ÜEÀÝ$èݦÿÿÝEÈÜMØÙüÜÁÙÉÙ}Ö·EÖ´ f‰EÔÙmÔÛ]´ÙmÖÝEÈÜMàÞÁÙmÔÛ]ÐÙmÖ‹}Ѓ=Ðxt‰|$ ‹E´‰D$ÇD$ Ç$è+¥ÿÿ‰$è}ôÿÿ‰E¬‰4$èôÿÿ‰E°߉<$èeôÿÿ‰Ç‹E´ð‰$èêóÿÿ‹U¬‰T$‹U°‰T$‰|$ ‰D$ÇD$ž Ç$èÒ¤ÿÿEàU؉T$ ‰D$ÝEÀÜe¸Ý$è¦ÿÿÝEÈÜMØÙüÜÁÙÉÙ}Ö·EÖ´ f‰EÔÙmÔÛ]ÀÙmÖÝEÈÜMàÞÁÙmÔÛ]ÐÙmÖ‹}Ѓ=Ðxt‰|$ ‹EÀ‰D$ÇD$ Ç$èT¤ÿÿ‰$è¦óÿÿ‰E¸‰4$è/óÿÿ‰Eȉ$èóÿÿ‰ÃuÀ‰4$èóÿÿ‹U¸‰T$‹UȉT$‰\$ ‰D$ÇD$ž Ç$èü£ÿÿƒÄl[^_]ÃÝØÝEÀÜà Ý]ÀEàU؉T$ ‰D$ÝE¸ÜEÀÝ$è¥ÿÿÝEÈÜMØÙüÜÁÙÉÙ}Ö·EÖ´ f‰EÔÙmÔÛ]´ÙmÖÝEÈÜMàÞÁÙmÔÛ]ÐÙmÖ‹}Ðé`þÿÿU‰å]ÃU‰åWVSìüÇ4œÇ,œþÿÿÿÇ…,ûÿÿȽ8ûÿÿ‰½(ûÿÿXþÿÿ‰0ûÿÿÇ… ûÿÿ¾‰ûÿÿëƒÃ‹•$ûÿÿ‰•(ûÿÿf‰3‹,ûÿÿ‹•0ûÿÿDJþ‹(ûÿÿ‰$ûÿÿ9Âù½,ûÿÿ'‡% ‹…,ûÿÿÀ='¿'Fø‰½,ûÿÿD‰$è–£ÿÿ…À„ó +0ûÿÿÑûƒÃ‰…4ûÿÿ‰D$‹…0ûÿÿ‰D$‹•4ûÿÿ‰$è£ÿÿ‹4ûÿÿ y‰$ûÿÿ‰D$‹½(ûÿÿ‰|$‰ $èâ¢ÿÿ‹…0ûÿÿ9…ûÿÿt‰$è|¢ÿÿCÿ‹•4ûÿÿB‹,ûÿÿTJþ9Ór‹½4ûÿÿ‰½0ûÿÿ»éb ‹•$ûÿÿ<‚‹4ûÿÿ‰0ûÿÿƒþ2u »é> ¿„6à‰…4ûÿÿƒø¿„­ƒ=,œþu èæ £,œ¡,œ…ÀÇ,œ¹ë¹=>w¶ˆ€‹…4ûÿÿ=øw]¿”À9ÊuQ¿„À…À…À„ôƒø¶„ë÷؉…4ûÿÿë?ƒ½ ûÿÿƒ• ûÿÿÿÇ,œþÿÿÿƒÇ‹0œ‰‰Æéþýÿÿ¶–À‰•4ûÿÿ…Ò„¢‹4ûÿÿ¶‰ ‰(ûÿÿ¸)È‹4‡‹…4ûÿÿƒèƒøo‡ ÿ$… ¾éüÇ$è èÍèÿÿéëÇÈxéÜÇD$}‹Gø‰$èÅÿÿ‹wüéÁ‹‰D$ÇD$‹Gø‰$è¾ÿÿ‹7é¡‹‰D$ÇD$‹Gô‰$èè½ÿÿ‹7éwü‹‰D$ÇD$‹Gô‰$èŽÿÿ‹6é^wô‹Gü‰D$ÇD$‹‰$袽ÿÿ‹6é;‹‰$è²ÿÿé,‹Gü‰$èüºÿÿé‹Gü‰$趺ÿÿé Ç${èqÅÿÿéû‹Gü‰$èÆÿÿ‰Æéé‹Gü‰$èíÊÿÿ‰Æé׋Gü‰$èÛÊÿÿ‰ÆéÅ‹Gü‰$èÉÏÿÿ‰Æ鳋Gü‰$è7Öÿÿ‰Æé¡‹Gü‰$è%Öÿÿ‰Æé‹Gü‰$èUàÿÿ‰Æé}‹Gü‰$èYàÿÿ‰Æék‹Gü‰$è¿ãÿÿ‰ÆéY‹‰$è=ãÿÿ‰ÆéHÇD$]‹Gø‰$èpÃÿÿ‰Æé.‹Gü‰D$‹Gô‰D$‹Gð‰$èW¾ÿÿ‰ÆéÇ$[èsÄÿÿ‰ÆéûÇD$Ç$èî¹ÿÿé⋉D$‹Gü‰$èعÿÿéÌ‹‰D$‹Gü‰$è¹ÿÿ鶋‰D$‹Gü‰$謹ÿÿé ‹‰D$‹Gü‰$è–¹ÿÿ銋‰D$‹Gü‰$耹ÿÿét‹‰D$‹Gü‰$èj¹ÿÿé^‹‰D$Ç$èS¹ÿÿéG‹‰…ûÿÿÇD$ Ç$èS³ÿÿ‹•ûÿÿ‰T$‰$虹ÿÿ‰D$Ç$è¹ÿÿ鋉D$Ç$èù¸ÿÿé틉D$Ç$%èâ¸ÿÿéÖÇD$‹‰$è˸ÿÿé¿‹‰D$Ç$è´¸ÿÿ騋‰D$Ç$:è¸ÿÿé‘‹‰D$Ç$;膸ÿÿéz‹‰D$Ç$<èo¸ÿÿéc‹‰D$Ç$0èX¸ÿÿéL‹Gü‰D$‹‰$èB¸ÿÿé6‹‰D$Ç$0è+¸ÿÿé‹Gü‰D$‹‰$è¸ÿÿé ‹‰D$‹Gø‰$èñ°ÿÿ‰Æéñ‹‰D$‹Gø‰D$‹Gð‰$èú°ÿÿ‰ÆéÒ‹÷؉D$‹Gø÷؉D$‹Gð‰$è×°ÿÿ‰Æ鯋Gü‰D$‹Gô‰$è–°ÿÿ‰Æé–‹Gü‰D$‹Gô‰D$‹Gè‰$èž°ÿÿ‰Æév‹Gü÷؉D$‹Gô÷؉D$‹Gè‰$èz°ÿÿ‰ÆéRÇD$4‹Gü‰$è®ÿÿ‰ÆÇD$3‹Gô‰$èx®ÿÿ‰t$‰$è°ÿÿ‰Æé¡äU£àUé‹Gü‰D$‹Gô‰D$‹Gè‰$èáµÿÿ‰Æéè¡äU£àUéÙ‹‰D$‹Gø‰D$‹Gì‰$è³µÿÿ‰Æ麋‰$蹸ÿÿÇD$‰$袱ÿÿ‰Æ陋7‹Gü‰$蕸ÿÿ‰t$‰$肱ÿÿ‰Æéy‹wü‹‰$èu¸ÿÿ‰t$‰$èb±ÿÿ‰ÆéY‹‰$è±ÿÿ‰ÆéH‹‰D$‹Gü‰$è_°ÿÿ‰Æé0‹7‹Gü‰D$‹Gø‰$èD°ÿÿ‰t$‰$è±ÿÿ‰Æé ‹wø‹‰D$‹Gü‰$è°ÿÿ‰t$‰$èë°ÿÿ‰Æé⋉D$‹Gü‰$èX¯ÿÿ‰ÆéÊ‹7‹Gü‰D$‹Gø‰$è=¯ÿÿ‰t$‰$謰ÿÿ‰Æ飋wø‹‰D$‹Gü‰$è¯ÿÿ‰t$‰$è…°ÿÿ‰Æé|‹‰D$‹Gü‰$èm°ÿÿ‰Æéd‹Gü‰D$‹‰$èU°ÿÿ‰ÆéL‹7‹Gø‰D$‹Gô‰$è`¯ÿÿ‰t$‰$謵ÿÿ‰Æé%‹7‹Gø‰D$‹Gô‰$蘮ÿÿ‰t$‰$è…µÿÿ‰Æéþ‹7‹Gø‰$èú¶ÿÿ‰t$‰$èeµÿÿ‰ÆéÞ‹wüƒÆéÓ‹wüé˾éÁ‹wø7é·‹wø+7é­‹wø¯7颋Wø‰ÐÁú÷?‰Æé‘‹Gø‰ÂÁú÷?‰Ö逋7÷Þëz‹wüëu‹‰$èt¶ÿÿ‰Æëg‹‰D$‹Gü‰$褫ÿÿ‰ÆëR‹‰D$‹Gü‰$è«ÿÿ‰Æë=‹‰D$‹Gü‰$èz«ÿÿ‰Æë(‹‰D$‹Gü‰$èe«ÿÿ‰Æ닉D$‹Gü‰$èP«ÿÿ‰Æ‹…(ûÿÿÁà)Ç‹…(ûÿÿÀ)Ãlj7‹4ûÿÿ¶ ƒè]· ¿ñ¾”úøwf;ŒÀu ¿´ÀéTõÿÿ¿´ÀéGõÿÿƒ½ ûÿÿuƒ4œÇ$è è[àÿÿë*ƒ½ ûÿÿu!¡,œ…À…Àu»é…Ç,œþÿÿÿ¸àºÀ‰ñ‹µ0ûÿÿ¿ Hƒù¿tƒÁùøwfƒžÝ eŸJ¡eŸÝ Ý •¡•¡Ý >žyž‹žWžhžž÷žÙž»ž•¡Ÿ=ŸŸ•Ÿ~Ÿ…ŸŸ= îŸŒ *¡:¡¡¡•¡•¡•¡•¡ö •¡¡out of space in makenode objlist overflow fixpos returns %d %d got a first of x,y= %d,%d there is no %dth got a last of x,y= %d,%d there is no %dth lastgethere %d %d getpos %o %d getpos returns %d %d fraction = %.2f %d, %d attr %d: %d %d .%s is not in that blockthere is no .%s in that []getblock found s_type=%d, s_val=%d out of space in tostring on %s9´Èv¾Ÿæ?9´Èv¾Ÿæ¿no such variable as %sno such place as %sout of symtab space with %sinto blockadj: dx,dy=%d,%d becomes %d,%d cx,cy=%d,%d M %d %d nobjs wrong%d %d blockadj: type=%d o_x,y=%d,%d;[] %d %d %d %d at %d %d, h=%d, w=%d D©[©©2©m©´©“©Õ©B %d %d %d %d at %d %d, h=%d, w=%d °²°r°Š°°ý°â°±ellipsecircle%s has invalid radius %d C %d %d %d E %d %d %d %d µ+µµµ7µµ‚µ¶dx2,dy2=%g,%g, phi=%g, r,ht=%g,%g arc at %d %d from %d %d to %d %d head %d %d ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPERTû!ù?PERTû!ù¿chopping %d %d %d %d; cur=%d,%d end=%d,%d S or L from %d %d to %d %d with %d elements: ÿÿÿÿÿÿÿÿ2É2É2É2É2É2ÉcɅɧÉÆÉ!ÊåÉ!Ê Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9ÊJÉ9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê9Ê2Éÿÿÿÿÿÿÿÿtoo many text strings (%d) saving %c text %s at %d .PS.PS found inside .PS/.PEIËRË5ËBËYËbËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgËgË.ËT %c %s Í Í¦ÌúÌÍ"̻ͯÌÇÌÓÌ)Í)ÍßÌpushback overflow context is ^ .PE pic: near line %d, file %s end of file inside .PS/.PEend of file in getarg! disaster in dodef arg %d = %s .e %s pushing back `%s' .u %s%sdefinition of %s is too longend of file while defining %sinstalling %s as `%s' .md %s%s used as variable and definition e %d %d %d %d l <>. %d- %d %d %d %d~ c %d %d %d bt %d %d %c%s m %d %d tc. S ... %d %d %d %d %d %d %d %d .PS %d %d %sa %d %d %d %d %d %d rot=%f, hyp=%f, alpha=%f dx,dy = %d,%d l 2 %d %d %d %d .... %du %du %du %du %du %du %du %du ¯ PERTû! @syntax errormemory exhaustedåæáîáîöæç ç@ç`çƒç¦çµçÅçáîÕçæçøç èè.è@èRèdèvèˆè™è³èÓèáîæèÿèé+éAéWéméƒéšéÝéôé ê"ê9êPêgêáîáîÛæ~ê•ê«êÂêáîáîáîáîáîáîáîáîáîØêðêë2ëKëkëëÊëÙëùëì'ìHìhìˆì™ì±ìØìÿìí>íáîeí}í•í¼íãíîîîáîáîáîáîáîáîáîáî î*î4î?îPîaîgîlîáîzîî¤î¹îÎîÄ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ`ÀÿÒÿ¿ÿ¿ÿ¿ÿ¿ÿ)¿ÿ)áÿ)EEEEEEEEEâÿ¿ÿb¿ÿ¿ÿ>¿ÿÆÆãÿ¯ùÿßðWÆ¿ÿ¿ÿÑ¿ÿý7Æ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ````(¿ÿ¿ÿ¿ÿÆÆÆÆ¿ÿ6¿ÿ¿ÿÛÿ>¿ÿß¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿòÿ¿ÿƯ¿ÿúÿ8¿ÿ<J¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ'¿ÿÆÆÆÆÆÆBõÿÒÿ)¿ÿžMq¿ÿ¿ÿ¿ÿ¿ÿ©ÑÿÑÿÑÿÑÿbKÑÿ¿ÿ¿ÿ¿ÿ¿ÿ7¿ÿ¿ÿ¿ÿU¿ÿg†Æ¿ÿÆ‘Æ–^¿ÿ««¿ÿ¿ÿ¿ÿ©``¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ¿ÿ:wRÆbÆ¿ÿÉÿÝÿE¿ÿ¿ÿÆ©Æ©``|ÃÿÑÿ¿ÿ¿ÿ¿ÿ OYZMKXLWNR[S\VUTQ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJP  0 $7$KL.4R KL?@ABCKL*\X.0S0.KL4J6JKL)*W?@ABC1W@ABCD8 R+W W.GHIJX+,../01 ^GHIJdeE0ˆzˆW[L3+pqrstu¥¦W+Y+,../01+–+,+./0101Zÿÿ¾¿ÿÿ¥¦ÿÿEF—ÿÿ™J›LÿÿEÿÿQªSÿÿTLVÿÿÿÿY+¾¿./01±Y³JKLMNOºÿÿ¼ÿÿ ÿÿÿÿ ÿÿÿÿÿÿJKL ÿÿÿÿ+,+,ÿÿ./01MNOÿÿ+,ÿÿÿÿ FEÿÿJ0ÿÿÿÿLÿÿÿÿÿÿÿÿFTÿÿVJÿÿÿÿÿÿYÿÿÿÿQ3ÿÿTÿÿV+,ÿÿÿÿ ÿÿÿÿÿÿJKLMNOÿÿÿÿÿÿFÿÿÿÿÿÿJX ÿÿTUV+,ÿÿÿÿÿÿÿÿ !+,ÿÿ./01ÿÿFÿÿÿÿÿÿJ=+,2./01ÿÿTÿÿV3E=KLMNOLÿÿÿÿFGHIEXÿÿZÿÿÿÿYLÿÿKLMNOKLMNOÿÿYÿÿXÿÿÿÿÿÿÿÿXÿÿZKLMNOKLMNOÿÿÿÿÿÿXÿÿZÿÿÿÿÿÿÿÿZKLMNOKLMNOKLMNOZÿÿÿÿÿÿÿÿZÿÿÿÿÿÿÿÿZKLMNOKLMNOÿÿÿÿÿÿXÿÿÿÿÿÿÿÿX@ABCDKLMNO, |!3RSdeN¿0/de2„…†‡ŠdeaÆ4¾6N,1{kde353cde`bO,,,,,~OfghijƒTUVWXY0“Z[O”ƒƒƒƒ–"#žˆ%&' ¬• ‹ŒŽšœ(\R§S¥)¦«Ÿ ¡¢£¤µ¶‰­*xyn$%&'´®"#P$%&'&Q¸ÂÃ,,(¯°z²)(‘·’)*",,$%&'»*½©pqrstÀÁýÿ  TUVWXY¨deZl "#$%&'rst  ( m)^·ÿ  opqrstu9:;<=>7€ 89:;<=>?@ABCD"#$%&'F"#E$%&'·ÿ(Fpqrst)GHIJ(—˜™)pqrstpqrst›uº˜pqrstpqrst¼˜˜pqrstpqrstpqrst¹ÄÅpqrstpqrst±³fghijpqrst  > KmN]n?UG>329:78<=>>>>>,*;22220+LMW^c_a`bde\RkopqrsVe[OKm G4!1#$%&')"-./5ZTQSlPfghij@>> (6YXFCAB>>JDEH]^^^__``````````abbbbbbbbbbcbdeeffffffffffffffffgghhhhiiiiiiijjjjjjjjjkjljmmmmmmmmmmmmmnnnoooppppppppqqqqqqqqqqqqqq¿¿ ö¿¿¿¿þ¿ ¿ÕØ¿¿ôçéVÿÿªK‚LM+vw_-.]}newline in stringstring too longbad switch yylook %dÉÿ³ôÉÿÉÿmômôËôßôóô8õLõ`õtõˆõœõ°õÄõØõìõcôö öÉÿÉÿÉÿö(ö<öPödöxöŒö ö´öÈöÜöðö÷÷,÷@÷T÷h÷|÷÷¤÷¸÷Ì÷à÷ô÷øø0øDøXølø€ø”ø¨ø¼øÐøäøøø ù ù4ùHù\ùpù„ù˜ù¬ùÀùÔùèùüùú$ú8úLú`útúˆúœú°úÄúØúìúûû(û<ûPûdûxûŒû û´ûÈûÜûðûüü,ü@üTühü|üü¤ü¸üÌüàüôüýý0ý?ýdýxý}ô þˆþ¡þ°þÉÿÄþÕþÿ&ÿ<ÿOÿbÿÿÿÿÿÿÿÿÿF $‡ œõþÿoŒ̃¼ } ô/ØL†,† þÿÿoŒ…ÿÿÿoðÿÿoJ… /j‡z‡Š‡š‡ª‡º‡ʇÚ‡ê‡ú‡ ˆˆ*ˆ:ˆJˆZˆjˆzˆŠˆšˆªˆºˆʈÚˆêˆúˆ ‰XXÌÍÌL>0u0uЊÿÿЊÿÿ –d–d222K2  d_Y€X}}y}z}}}w}}}x}x}}}}x}x}x}x}x}x}x}x}x}x}x}x}x}x}x}x}x}x}}}ƒ~ƒƒ|{tbw&) $"dewwwaxxxxxnxxxoxxxxxQxxxxxxxxxxxExxxxxxxxxxxxxxxxxxxxmxOxxxxw&) $"de€‚f-1/3vcxxx xxxxx xRxxxxxxxVxxxxxxxxxxxxxxxxxxHxxxxxxxxxxxxxxFxxwf-1/3',j#hrxxxxxxxZxxXxxJxxPxxx\xxlxxxqxMxxxxxxxxxxxLxxxxxSxxxxpx',j#h_x x`xxxxxxxxxxuxxTx]xxxxxNx^xxxxxxGx!%+ixxx xYxxxWxx?DxxIxx[x5!%+i(*gkxsx< xx9:(*gkKxx6;8>7=Ux42420.0.CAB@667S4O69O«615 !"#Q$%R&'()*%k+,-.'q/#g(r2)s*t0#h23 !"#X$%T.&'()*Y+,-.U/4$iVZW0 ["d \!`;• ] ^!a2-}$j!b"e+u"f/€-~!c<–/ _+v+w/‚C¦2 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 85D§5’Kª 8Mª 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8::::::::::NªHQ¬IIIIIIIIII&l?›,x>™&m5“=—A &n&o,y?œT­@&pA¡,z,{>š=˜E¨,|U®@žE©V¯X±;<5”=@ŸY³>X²[µY´?\¶@V°]·^¸ABCDJEFG`¹Kaºb»d¾LMNPPPPPPPPPPc¼e¿fÀc½hÃiÄkÅPPPPPPPPPPPPPPPPPPPPPPPPPPlÆmÇnÈoÉPpÊPPPPPPPPPPPPPPPPPPPPPPPPPP1ƒgÁqËrÌtÍuÎvÏgÂ1ƒ188888888888888888888::::::::::::::::::::B¢wÐxÑyÒzÓ{Ô|Ö}×~ØÙB£{Õ€ÚÛ‚ÜB¤„1„B¥HHHHHHHHHHHHHHHHHHHHƒƒ‚Ý…†‡1ƒˆ‰ƒƒƒŠŽ‹Œƒ‘:J•ô–õ—ö˜÷ŒƒŒ„„™ø›ùœúžû ü¡ý£þ¤ÿ¦§¨©1…1†¬1‡­°1ˆ±²ƒƒ1‰³ 1Š¶ · ¸ 1‹1Œ11Ž¹ 111‘Œƒºƒƒ»¼½¾¿ÀÁÂÃÄÅÆÇÈŒƒÉÊ„ÞËÌ Í!Î"Ï#Ð$Ñ%Ò&‡áÓ'Ô(†àÕ)Ö*ˆã‰å‹ê×+ŠçØ,…߇âòÙ-‹ë‰æóÛ.ŠèˆäŽñðŒìÜ/Ý0ÞŠéßàáâãŒíäæåçŒîèéŒïêëìíîïðñòóôAõBöCøDùEúFûGüHýIþJÿKLMNOPQR S T U VWXYZ[]^_`ab c!d"e#f$g'h(i)j*k,,-m.n/o123456879;:=<?>@A~BD€FG‚Hƒâ4I„J…K†L‡Nˆã5å6à2R‰SŠê9î<ß1á3ë:T‹UŒVWŽó@Xè8æ7YZZ[’\“^”ð=ñ>í;_•``ò?b—c˜\e™fšh›iœjkžlŸm nnpqrstu,lwvxyz{|}~­®€¯ƒ²‰µŠ¶‹·‡‡¹Ž¸‘º’»5s7u•¼–½˜˜šš9w:x>{1p2q3r››¡Æ6t8v——žž;y<zŽ¸  ?|¢@}£¤¥¦Z‘§¨©ª¬«°Ï`–±Ð³Ñ´Ò¶¶··¹Õ¸¸¼Ö¾×¿ØÀÙ¥¥n¡ÁÚÂÛÃÜÄÝÅÞÇ««ÈÉÊËÌÍq£Î°¸¸Ïãs¤Ð䇳±p¢v¦Ñåy©‡´ÒæÓç}¬u¥Ôè˜ÀšÁÖéw§x¨{«zª×ê›Â—¾ØëÝìÞížÃ Ä—¿ßàãòá Åâäóåôæõêöë÷ìøíùîïðñóþõÿö÷¶Ó·Ô¢Çøù¥Êúûü£Èý¥Ë¤É«Í§Ì «Î      ÊßÍáËàÎâßîàïáðâñïûñýîúðü   ûý€?€?x?`>¤^°;X?¼^h?€?Ô^XC€?ì^€?€?€?€?€?$1€?,1€?81€?@1€?L1ˆ?X1°E`1Fh1€?t1˜?€1@Hˆ1˜?¬_”1ð? 1 ?¨1€?°1à@¬_¼1°@¬_È1xA¬_Ô1 A¬_à1A¬_ì1@¬_ø1@A¬_2 ?¬_2àD¬_2À?¬_(2Ø?¬_420@¬_@2Ø?¬_L2ðA¬_X2ðD¬_d2˜A¬_p2x@¬_|2B¬_ˆ2€?”2ð2 2€?¬2€?´2€?¼20EÈ2€?Ð2€?Ø2èJì^à2€?è28Kð28Aø2øA3E3ØDÈD3(E3E 3àI(3ØA03¸B`E83€?@3€?H3 L8aP3€?ˆ_X3€?`3(C€?b¸B@D˜?h3€?¬_p3D¬_x3€?€3€?ˆ3ÐD¬_3xE¬_˜3˜E¬_ 3€?¬_¨3XE¬_´3HE¬_¼3€?¬_Ä3HE¬_Ð3¨E¬_Ø3¸E¬_à3¨E¬_è3€?¬_ð3èE¬_ü3`F¬_4F¬_ 4pF¬_4F¬_4¸F¬_$4G¬_,4ÀH¬_44¸F¬_<4ðF¬_D4€?¬_L4F¬_X4€G¬_`4ðG¬_h4¸G¬_p4ˆG¬_x4ˆG¬_€4xH¬_ˆ4 H¬_4€?¬_˜4ðH¬_¤4 I¬_¬4I¬_´4hI¬_¼4°I¬_Ä4PI¬_Ì4€I¬_Ô4ÐI¬_Ü40J¬_ä4J¬_ì4ÈI¬_ô4ÐI¬_5 I¬_ 5ØI¬_5XJ¬_51$5È1¤d,5P1¤d85H1¤dD5@1¤dP501¤d\5(1¤dd51¤dp51¤d|5 0ˆ5ø0¤d”51¤d 5ð0¤d¨5à0¤d´5Ø0¤dÀ5€?Ì5€?Ô5€?Ü5èJ KK€KxK€?ä5˜KK€?ì5HK€?ô5ÀK°K€?ü5HKðK€?6€KˆKxKøK€? 6€?6L¬_6K¬_$6€?¬_,6€?¬_86ÐK¬_D6àK¬_L6¨K¬_T6ØK¬_\6€?¬_d6€?¬_p6èK¬_|6L¬_„6€L¬_Œ6€L¬_”6 L¬_œ6L¬_¤6`L¬_¬6˜L¬_¸6pL¬_À6ÐL¬_È6 O¬_Ð6ÈL¬_Ø6˜L¬_à6ÐL¬_è6M¬_ð6M¬_ø6°L¬_7¸L¬_78M¬_7ØL¬_7PM¬_ 7`M¬_(7ðL¬_07(M¬_87XM¬_@7hM¬_L7M¬_T7M¬_\7˜M¬_d70M¬_l7M¬_t7ÀM¬_|7`M¬_„7 M¬_Œ7 P¬_˜7N¬_ 7€?¬_¨7ÀM¬_´7ðM¬_¼7XN¬_È7°-¤dÐ7 -¤dÜ7˜-¤dä7-¤dì7ˆ-¤dô7€-¤dü7p-¤d8`-¤d8h-¤d8X-¤d 8H-¤d,8@-¤d480-¤d@8(-¤dH8 -¤dP8-¤d\8-¤dd8-¤dl8-¤dx8ø,¤d€8ð,¤dˆ8è,¤d8ÐN˜8ØNàN€? 8POðNpOO`O¨8pOO0O€?°8 O0O8O¸8€?¬_À8¸O¬_Ì80O¬_Ô88O¬_Ü8ÐO¬_ä8ˆO¬_ì8àO¬_ô8€?¬_ü8°O¬_9ðO¬_9°O¬_9P¬_$9P¬_09€?¬_898R¬_D9ÀO¬_L9HR€?¬_T9°O¬_`9€?¬_h9P¬_t9ÈO¬_|9€?¬_„9hR¬_9€?¬_œ9ÐO¬_¨9èO¬_°9€?¬_¸9@P¬_Ä9èO¬_Ì9èO¬_Ô9øO¬_Ü9P¬_ä9€?¬_ì9€?¬_ø9hP¬_:@P¬_ :°P¬_: P¬_:€?¬_$:ÈR@P¬_0:ØR¬_8: P¬_@:€?¬_H:h+¤dT:`+¤d`:X+¤dh:P+¤dp:H+¤d|:@+¤d„:0+¤dŒ:8+¤d”:(+¤dœ:+¤d¨: +¤d°:+¤d¸:+¤dÀ:ø*¤dÌ:+¤dÔ:ð*¤dÜ:ðPHQ€?è:8Q€?ð:ðPHQèPQhQQ(Q€?ø:€Q€?¬_;€?¬_ ;€?¬_;¸Q¬_$;€Q¬_,;ˆQ¬_4;øQ¬_<;R¬_D;R¬_L; Q¬_T;8R¬_\;`TÐQ¬_d;@R€?¬_l;ØQ¬_x;PR¬_€; T€?¬_Œ;°T¬_˜;¸T¬_ ;€?¬_¨;0R¬_´;ÐT¬_¼;€?¬_È;ØT¬_Ô;¸R¬_Ü;ÈR¬_ä;ðT¬_ì;ÈRU¬_ô;U€?¬_ü;@)¤d<8)¤d<0)¤d<()¤d$< )¤d,<)¤d8<)¤d@<)¤dH<ø(¤dP<ð(¤dX<è(¤d`<à(¤dh<Ø(¤dp<Ð(¤d|< SSøR U€?„<S€?Œ<€?”<€?œ<ÈU€?¤<@S¬_¬<¸U¬_´<ÀU¬_¼<€?¬_Ä<€?¬_Ð<V¬_Ü<¨S¬_ä<€?¬_ì<°SÀS¬_ø<€?=€?¬_=ðS¬_=ØSpVV€?¬_=VPV€?¬_(=€?¬_4=xV€?@=˜V(T¨'¤dH=˜'¤dP='¤dX=ˆ'¤d`=€'¤dh=p'¤dt=h'¤d|=`'¤dˆ=X'¤d”=H'¤d =P'¤d¨=€?´=€?¼=€?Ä=èTØT€?Ì=UèT€?¬_Ô=8W@WXà=¸T¬_è=€?ð=€?¬_ø=øT¬_>€? >8U U@UXU`UhUxU`U€?> &¤d>&¤d(>ˆ&¤d4>€&¤d@>x&¤dH>p&¤dP>h&¤d\>X&¤dd>àUèUV(V8VPV€?¬_l>pV¬_x>V V€?€>€?ˆ>€?>€?˜>°V°VH%¤d >@%¤d¨>0%¤d°> %¤d¸>xVøV VW€?À>€?È>€?¬_Ð>°VWÀV(Wà$¤dÜ>Ø$¤dä>Ð$¤dì>È$¤dô>€?ü>ðV€??øV YWÈY0Wp$¤d ?h$¤d?`$¤d ?P$¤d,?€?4?€?Ø0HñÿQè0^ì0ið0t  € Šà ”À ž` ªñÿ´ô0¿ø0Êü0Öäxâ|ìlöñÿÊìxÖèxL  < ñÿñÿ)ñÿ0ñÿ:Ü DñÿK0ä VàŽ]€?iÀòqÀòyÀÇ‚ t‡ tŒ””À*žñÿ¥ô/» /Ì /ß /è€0 ó«Ü7 #§ù °x²È #p®x * œ-Ó¡³ 9æР @ P†¢6 Yà ] ‰ dZ”¶ kœrœw@œœ‚œ‡˜0–M —Øxž¹ÊàR ÖàÕ Û êDœð À  1`‘Ê ðx ;U4Ön [àxb€XÈgœmHœs0|p¾B  „”0‰×< ˆ0•´x›¬ê¤W ³Lœ¹Pœ¿3áö ÅÈxÍêþð²ø ÛÚ^ Tœ9Ûß Ý. ÕšA (GÔ™ 3Ôx: Ö  @ÌxFÄUôxZÞÖ0 ^n ‹Ô v`œÈ}jð …(€0šÖ ¡´0¦¸ œ»Ë¼0а0Ö yÜÕÍa âûîÕ ,œPwTÝ ,y‰'9pÝ) ?¸xFA¥§ N`Y€>S`w[ÐÙ  bfЀ hŒ0n€x€’à—è™àU¡lx¬¤y²ÃäUÍß× Õ¤] Ü0áà‰, çx×g ë„0ø@Èÿ¨y¼x/+Z ;›Ä D¼¢, NÈ›S¸0X3Ý! \€?èdtÀ0yãð €÷£g ‰J×. Žž¬0¤ž«Ày€>°1³à›(º@ð* Á ž Ê 0ÍLwÓ¢Ö< Ùpxñÿå÷R­ ¾Ï¨ †ÑN @¸Äx7ÈÈ: ?¬ð  GXâÜ# ^Ü“ d{ÎC k„x|À™o ƒa£– Œð¥3 •Ðx™Üx hx§€^Ì®6ÎE ´@̆ ¼@¡–Á  ɬ6 ÔÀxÙØ¡ñÿÞ$œá xóÐÍ ú¬xÿ•¡  œf V€ }ð/  0œ" dx+ F ¨0M @‘P T Ë¿ ] q è¢y z `¤- … hœ¡ Ž œ0’ 4œš ×ó$    üÕ  ¦ (œ­ ¤0° 5äþ  ¸ pxñÿ¿ äׄ Ç Ú›( Ï `¸@Ô  ¹@œÜ ð·z ã ÔÒs ê ü /š¦   1 Ìð   œ% ÏËg . ™Ý} 5 j L ^ 2Ž c $‡ i hØh crtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.7065dtor_idx.7067frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxmain.cdefaults.2374print.cprevval.2405misc.csymtab.cblockgen.cprevh.2323prevw.2324boxgen.cprevh.2255prevw.2256circgen.crad.2255rad2.2256arcgen.cprevrad.2257prevh.2256prevw.2255dctrx.2260dctry.2261dtox.2258dtoy.2259nexthv.2262linegen.cprevh.2258prevw.2257prevdx.2255prevdy.2256xtab.2281ytab.2282movegen.cxtab.2265ytab.2266troffgen.ctextgen.cpic2.cpltroff.ctemp.3748picy.cyydestructyypactyytranslateyycheckyytableyydefactyyr2yyr1yypgotoyydefgotopicl.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startfputs@@GLIBC_2.0pointblockgennattrsplinegenboxgenX1makebetweengetarg__libc_csu_finiprintposarc_startdotboxxscalehmaxyytcharY0vmaxdevtypegetheresynerr__fprintf_chk@@GLIBC_2.3.4sqrtf@@GLIBC_2.0setdefaultshmot__gmon_start__yyfnd_Jv_RegisterClasses_fp_hwyyvstopdotlinehpos__isoc99_sscanf@@GLIBC_2.7__printf_chk@@GLIBC_2.3.4spacenstackebuf_finicflagfilenamelinegencropyconvdeltxntextfgets@@GLIBC_2.0getvaryylspyyoutarrowcodegen__libc_start_main@@GLIBC_2.0_IO_getc@@GLIBC_2.0circgencircleyylengboxhvflushextremedefinitionlinenovgotoscale_IO_stdin_usedvposxscfree@@GLIBC_2.0getdatayytextyyunputyymorfg__data_startmovehvxminfflush@@GLIBC_2.0Y1sqrt@@GLIBC_2.0xmaxsymaxsyminunput__ctype_b_loc@@GLIBC_2.3vmotyycharyybgincloseplyyestateyyextrafclose@@GLIBC_2.1erasentext1makevarpbufyymatchsplineinputdeltystderr@@GLIBC_2.0memcpy@@GLIBC_2.0argvalbetweenyyprevioussxminfopen@@GLIBC_2.1lastfloatlinemodlookupclenresetysc__dso_handleyysbufstrcpy@@GLIBC_2.0cmdnamecurx__DTOR_END____libc_csu_initmakenodeprintexprargpymindotyycrankatoi@@GLIBC_2.0ymaxgetpostostringmoveatof@@GLIBC_2.0sxmaxyyolsptextepargstkyybackyylstateDXyytopxconv__bss_startmalloc@@GLIBC_2.0leftthingyyerrordodefyyinhvmode__stack_chk_fail@@GLIBC_2.4movegenyyinputatan2@@GLIBC_2.0trofflabeleprintstdin@@GLIBC_2.0setdirgetblockblockadjdbghshiftyysptryysvecpbstrtextgencbufgetlastrightthingcury_endX0stdout@@GLIBC_2.0yywrapnobjprintfixposstackyyoutputyylvalyylineno__sprintf_chk@@GLIBC_2.3.4vshiftdotextsavetext_IO_putc@@GLIBC_2.0makeattrfreesymtabgetfirstresyynerrsyylexhgotoyscaleDYyyparse_edataellipsemakeposattrobjlistarcgendefusestrcmp@@GLIBC_2.0getcompexit@@GLIBC_2.0pbyylookargcnttroffgenopenpl__i686.get_pc_thunk.bxsincos@@GLIBC_2.1main_initlinexcip/JPIC/main.c0000644000175300001440000001240511513632544012167 0ustar meusers/* XJPIC - host program that parses pic for xcip */ #include "../version.h" #include #include "pic.h" #include "y.tab.h" extern char * tostring(); struct obj *objlist[MAXOBJ]; /* store the elements here */ int nobj = 0; struct attr attr[40]; /* attributes stored here as collected */ int nattr = 0; /* number of entries in attr_list */ struct text text[MAXTEXT]; /* text strings stored here as collected */ int ntext = 0; int ntext1 = 0; /* record ntext here on entry to each figure */ coord curx = 0; coord cury = 0; int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */ int codegen = 0; /* 1=>output for this picture; 0=>no output */ int deltx = 600; /* max x value in output (x100), for scaling */ int delty = 600; /* max y value in output (x100), for scaling */ float scale = 0; /* implies simply scaling by this value; no crop or shift */ int dbg = 0; FILE *yyin; /* input file pointer */ extern int yylval; int lineno = 0; char *filename = "-"; int synerr = 0; char *cmdname; int crop = 1; /* trim off exterior white space if non-zero */ /* You may want to change this if you don't have a 202... */ int devtype = DEV202; int res = 972; /* default is 202 */ int DX = 4; /* used only for old-style troff */ int DY = 4; /* mandatory values for graphic systems CAT: */ /* int devtype = DEVCAT; int res = 432; int DX = 3; int DY = 3; */ float hshift = 0; /* move this far left for text (in em's) */ float vshift = 0.2; /* this far down */ coord sxmin; /* lower limit from s command */ coord symin; coord sxmax = 4096; /* upper */ coord symax = 4096; coord xmin = 30000; /* min values found in actual data */ coord ymin = 30000; coord xmax = -30000; /* max */ coord ymax = -30000; main(argc, argv) char **argv; { int casel, c; cmdname = argv[0]; casel = 0; while (argc > 1 && *argv[1] == '-') { switch (c = argv[1][1]) { case 'V': printf( "%s version %s\n", argv[0], PGM_VERSION ); exit(0); case 'T': if (strcmp(&argv[1][2], "aps") == 0) { res = 720; devtype = DEVAPS; DX = DY = 1; } else if (strcmp(&argv[1][2], "cat") == 0) { res = 432; devtype = DEVCAT; DX = DY = 3; } else if (strcmp(&argv[1][2], "450") == 0) { res = 240; devtype = DEV450; } else { res = atoi(&argv[1][2]); } break; case 'c': crop = 0; break; case 'l': delty = (int)(atoi(&argv[1][2])*100); casel = 0; break; case 'w': case 's': if (argv[1][2] == 0) { argv++; argc--; deltx = (int)(atof(&argv[1][0])*100); } else deltx = (int)(atof(&argv[1][2])*100); if (c == 's') scale = deltx/100; break; case 'd': dbg = 1; break; } argc--; argv++; } if (!casel) delty = deltx; setdefaults(); if (argc <= 1) { yyin = stdin; getdata(yyin); } else while (argc-- > 1) { if ((yyin = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "pic: can't open %s\n", *argv); exit(1); } filename = *argv; getdata(yyin); fclose(yyin); } exit(0); } setdefaults() /* set default sizes for variables like boxht */ { static struct { char *name; int val; } defaults[] ={ "lineht", HT, "linewid", HT, "moveht", HT, "movewid", HT, "dashwid", HT/10, "boxht", HT, "boxwid", WID, "circlerad", HT/2, "arcrad", HT/2, "ellipseht", HT, "ellipsewid", WID, "arrowht", HT/5, "arrowwid", HT/10, "textht", HT, "textwid", WID, "scale", SCALE, NULL, 0 }; int i; for (i = 0; defaults[i].name != NULL; i++) makevar(tostring(defaults[i].name), VARNAME, defaults[i].val); } getdata(fin) register FILE *fin; { char buf[1000], buf1[50]; FILE *svyyin; int svlineno; char *svfilename, *p; lineno = 0; while (fgets(buf, sizeof buf, fin) != NULL) { lineno++; if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') { for (p = &buf[3]; *p == ' '; p++) ; if (*p++ == '<') { svyyin = yyin; svlineno = lineno; svfilename = filename; sscanf(p, "%s", buf1); if ((yyin = fopen(buf1, "r")) == NULL) { fprintf(stderr, "pic: can't open %s\n", buf1); exit(1); } lineno = 0; filename = p; getdata(yyin); fclose(yyin); lineno = svlineno; yyin = svyyin; filename = svfilename; continue; } reset(); yyparse(); /* yylval now contains 'E' or 'F' from .PE or .PF */ if (buf[3] == ' ') /* assume next thing is width */ deltx = delty = atoi(&buf[4])*100; else { /* use scale to determine size */ int t; t = xmax - xmin; if (t == 0) t = ymax - ymin; deltx = delty = (int) ((float) t * ((float) 100 / (float) getvar("scale"))); } dprintf("deltx = %d\n", deltx/100); if (codegen && !synerr) { openpl(&buf[3]); /* puts out .PS, with ht & wid stuck in */ print(); /* assumes \n at end */ closepl(yylval); /* does the .PE/F */ } fflush(stdout); } else fputs(buf, stdout); } } reset() { struct obj *op; int i; extern int nstack; for (i = 0; i < nobj; i++) { op = objlist[i]; if (op->o_type == BLOCK) freesymtab(op->o_val[6]); free(objlist[i]); } nobj = 0; nattr = 0; for (i = 0; i < ntext; i++) free(text[i].t_val); ntext = ntext1 = 0; codegen = synerr = 0; nstack = 0; curx = cury = 0; hvmode = R_DIR; sxmin = symin = 0; sxmax = symax = 4096; xmin = ymin = 30000; xmax = ymax = -30000; } xcip/JPIC/pic.h0000644000175300001440000000460611513632543012026 0ustar meusers#define HEAD1 1 #define HEAD2 2 #define HEAD12 (HEAD1+HEAD2) #define INVIS 4 #define CW_ARC 8 /* clockwise arc */ #define dprintf if(dbg)printf #define PI 3.141592654 #define PI2 PI/2 #define SCALE 200 /* default scale: units/inch */ #define WID 150 /* default width for boxes and ellipses */ #define HT 100 /* default height and line length */ #define MAXOBJ 10000 #define MAXTEXT 2000 #define SYMTAB 2000 #define MAXDEF 10000 #define DEV202 1 #define DEVAPS 2 #define DEVCAT 3 #define DEV450 4 /* these have to be like so, so that we can write */ /* things like R & V, etc. */ #define H 0 #define V 1 #define R_DIR 0 #define U_DIR 1 #define L_DIR 2 #define D_DIR 3 #define ishor(n) (((n) & V) == 0) #define isvert(n) (((n) & V) != 0) #define isright(n) ((n) == R_DIR) #define isleft(n) ((n) == L_DIR) #define isdown(n) ((n) == D_DIR) #define isup(n) ((n) == U_DIR) typedef int coord; struct attr { /* attribute of an object */ int a_type; int a_val; }; struct obj { /* stores various things in variable length */ int o_type; int o_count; /* number of things */ int o_nobj; /* index in objlist */ int o_mode; /* hor or vert */ coord o_x; /* coord of "center" */ coord o_y; int o_nt1; /* 1st index in text[] for this object */ int o_nt2; /* 2nd; difference is #text strings */ int o_attr; /* various attributes of interest */ int o_dotdash; /* kludge in a dot/dash mode */ int o_ddval; /* value of dot/dash expression */ int o_val[1]; /* actually this will be > 1 in general */ }; struct symtab { char *s_name; int s_type; int s_val; struct symtab *s_next; }; struct text { int t_type; char *t_val; }; #define dprintf if(dbg)printf extern int dbg; extern struct obj *objlist[]; extern int nobj; extern struct attr attr[]; extern int nattr; extern struct text text[]; extern int ntext; extern int ntext1; extern coord curx, cury; extern int hvmode; extern int codegen; extern struct obj *makenode(); /* extern char *malloc(); */ extern struct symtab *lookup(), *makevar(); extern int deltx, delty; extern float scale; extern int lineno; extern int synerr; extern int crop; extern int devtype, res, DX, DY; extern coord sxmin, sxmax, symin, symax; extern coord xmin, ymin, xmax, ymax; extern double atof(); struct pushstack { coord p_x; coord p_y; int p_hvmode; coord p_xmin; coord p_ymin; coord p_xmax; coord p_ymax; struct symtab *p_symtab; }; extern struct pushstack stack[]; extern int nstack; xcip/JPIC/pltroff.c0000644000175300001440000001522211513632544012717 0ustar meusers/* * dmd driver */ #include #include #include "y.tab.h" #include "pic.h" #define abs(n) (n >= 0 ? n : -(n)) #define PI 3.141592654 #define PI2 PI/2 extern int res; extern int DX; /* step size in x */ extern int DY; /* step size in y */ extern float hshift; /* how much to move left by for text */ extern float vshift; /* how much down */ /* scaling stuff, specific to typesetter */ /* defined by s command as X0,Y0 to X1,Y1 */ /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */ /* default output is 6x6 inches */ float xscale; float yscale; int hpos = 0; /* current horizontal position in output coordinate system */ int vpos = 0; /* current vertical position; 0 is top of page */ int X0, Y0; /* left bottom of input */ int X1, Y1; /* right top of input */ #define CX 0 /* center of dmd screen */ #define CY 0 #define JERQRES 100 int hmax; /* right end of output */ int vmax; /* top of output (down is positive) */ extern int deltx; extern int delty; extern int xmin, ymin, xmax, ymax, sxmin, symin, sxmax, symax; extern int crop; openpl(s) /* initialize device */ char *s; /* residue of .PS invocation line */ { hpos = vpos = 0; res = JERQRES; if (delty == 0) delty = deltx; /* -w alone implies -s */ hmax = vmax = 8 * res; /* default = 8 x 8 */ if (deltx > 0 && delty > 0) { /* have to change default size */ hmax = res * deltx / 100; vmax = res * delty / 100; } if (crop) { if (xmax == xmin) space(xmin, ymin, xmin + ymax-ymin, ymax); else space(xmin, ymin, xmax, ymin + xmax-xmin); /* assumes 1:1 aspect ratio */ } else space(sxmin, symin, sxmax, symax); printf("... %d %d %d %d %d %d %d %d\n", (xmin), (ymin), (xmax), (ymax), (sxmin), (symin), (sxmax), (symax)); printf("... %du %du %du %du %du %du %du %du\n", xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax), xconv(sxmin), yconv(symin), xconv(sxmax), yconv(symax)); printf(".PS %d %d %s", yconv(ymin), xconv(xmax), s); /* assumes \n comes as part of s */ erase(); } closepl(type) /* clean up after finished */ { printf("S\n"); } move(x, y) /* go to position x, y in external coords */ int x, y; { hgoto(xconv(x)); vgoto(yconv(y)); } movehv(h, v) /* go to internal position h, v */ int h, v; { hgoto(h); vgoto(v); } hmot(n) /* generate n units of horizontal motion */ int n; { hpos += n; } vmot(n) /* generate n units of vertical motion */ int n; { vpos += n; } hgoto(n) { hpos = n; } vgoto(n) { vpos = n; } hvflush() /* get to proper point for output */ { printf("m %d %d\n", hpos, vpos); } troff(s) /* output troff right here */ char *s; { printf("%s\n", s); } label(s, t, nh) /* text s of type t nh half-lines up */ char *s; int t, nh; { if (t == 'A') nh++; else if (t == 'B') nh--; vpos += nh * 10; /* approx 1/2 line */ switch (t) { default: t = ' '; /* FALL THROUGH */ case 'L': case 'A': case 'B': case 'C': case 'R': printf("t %d %d %c%s\n", hpos, vpos, t, s); break; } } arrow(x0, y0, x1, y1, w, h) /* draw arrow (without line), head wid w & len h */ { double alpha, rot, hyp; int dx, dy; extern int dbg; rot = atan2( ((double) w) / 2, (double) h ); hyp = sqrt( (float) (w/2 * w/2 + h * h) ); alpha = atan2((float)(y1-y0), (float)(x1-x0)); if (dbg) printf("rot=%f, hyp=%f, alpha=%f\n", rot, hyp, alpha); dx = hyp * cos(alpha + PI + rot) + 0.5; dy = hyp * sin(alpha + PI + rot) + 0.5; if (dbg) printf("dx,dy = %d,%d\n", dx, dy); /* line(x1+dx, y1+dy, x1, y1); */ printf("l 2 %d %d %d %d\n", xconv(x1+dx), yconv(y1+dy), xconv(x1), yconv(y1)); dx = hyp * cos(alpha + PI - rot) + 0.5; dy = hyp * sin(alpha + PI - rot) + 0.5; if (dbg) printf("dx,dy = %d,%d\n", dx, dy); /* line(x1+dx, y1+dy, x1, y1); */ printf("l 2 %d %d %d %d\n", xconv(x1+dx), yconv(y1+dy), xconv(x1), yconv(y1)); } box(x0, y0, x1, y1, dotdash, ddval) { printf("b"); if (dotdash == DOT) printf(". %d", xsc(ddval)); else if (dotdash == DASH) printf("- %d", xsc(ddval)); printf(" %d %d %d %d\n", xconv(x0), yconv(y0), xconv(x1), yconv(y1)); } circle(x, y, r) { hpos = xconv(x); vpos = yconv(y); printf("c %d %d %d\n", hpos, vpos, xsc(r) ); } spline(x, y, n, p, head) int x, y, n, *p, head; { int i; printf("~ "); if (head & HEAD1) printf("<"); if (head & HEAD2) printf(">"); hpos = xconv(x); vpos = yconv(y); printf(" %d %d %d", n+1, hpos, vpos ); for (i = 0; i < 2 * n; i += 2) { x += p[i]; y += p[i+1]; printf(" %d %d", xconv(x), yconv(y)); } printf("\n"); } line(x, y, n, p, head, dotdash, ddval) int x, y, n, *p, head; int dotdash, ddval; { int i; printf("l "); /* a line */ if (head & HEAD1) printf("<"); if (head & HEAD2) printf(">"); if (dotdash == DOT) printf(". %d", xsc(ddval)); else if (dotdash == DASH) printf("- %d", xsc(ddval)); hpos = xconv(x); vpos = yconv(y); printf(" %d %d %d", n+1, hpos, vpos ); for (i = 0; i < 2 * n; i += 2) { x += p[i]; y += p[i+1]; printf(" %d %d", xconv(x), yconv(y)); } printf("\n"); } ellipse(x, y, r1, r2) { r1 = xsc(r1); r2 = ysc(r2); printf("e %d %d %d %d\n", xconv(x), yconv(y), abs(r1), abs(r2)); } arc(x, y, x0, y0, x1, y1) /* draw arc with center x,y */ { float r; float dx2, dy2, phi, ht; int cx, cy; r = sqrt( (float) (x0-x) * (x0-x) + (float) (y0-y) * (y0-y) ); /* decide which radius is really needed: */ dx2 = (float)(x1 - x0) / 2; dy2 = (float)(y1 - y0) / 2; phi = atan2(dy2, dx2) + PI2; ht = sqrt(r*r - (dx2*dx2 + dy2*dy2)); cx = x0 + dx2 + ht * cos(phi) + 0.5; cy = y0 + dy2 + ht * sin(phi) + 0.5; if (abs(cx-x) >= 5 || abs(cy-y) >= 5) r = -r; /* wrong center was picked */ printf("a %d %d %d %d %d %d\n", xconv(x), yconv(y), xconv(x0), yconv(y0), xconv(x1), yconv(y1)); } erase() /* get to bottom of frame */ { printf("E\n"); fflush(stdout); } point(x, y) /* put point at x,y */ int x, y; { static char *temp = "."; move(x, y); label(temp, 'L', 0); } space(x0, y0, x1, y1) /* set limits of page */ int x0, y0, x1, y1; { if (x0 == x1) x1 = x0 + 1; if (y0 == y1) y1 = y0 - 1; /* kludge */ X0 = x0; Y0 = y0; X1 = x1; Y1 = y1; xscale = (float) hmax / (float) (X1-X0); yscale = (float) vmax / (float) (Y0-Y1); } xconv(x) /* convert x from external to internal form */ int x; { int v; v = (x-X0) * xscale + 0.5; return v + CX; } xsc(x) /* convert x from external to internal form, scaling only */ int x; { int v; v = (x) * xscale + 0.5; return v; } yconv(y) /* convert y from external to internal form */ int y; { int v; y += Y1 - ymax; v = (y-Y1) * yscale + 0.5; return v + CY; } ysc(y) /* convert y from external to internal form, scaling only */ int y; { int v; if (yscale < 0) v = (y) * yscale - 0.5; else v = (y) * yscale + 0.5; return v; } linemod(s) char *s; { } dot() { hvflush(); printf("tc.\n"); } xcip/JPIC/print.c0000644000175300001440000001060111513632543012372 0ustar meusers#include #include "pic.h" #include "y.tab.h" print() { struct obj *p; int i, m; coord x0, y0, x1, y1, ox, oy; for (i = 0; i < nobj; i++) { p = objlist[i]; ox = p->o_x; oy = p->o_y; /* can't get o_val values at this point because they're */ /* optional parts of the obj structure */ m = p->o_mode; switch (p->o_type) { case TROFF: troff(text[p->o_nt1].t_val); break; case BOX: case BLOCK: x1 = p->o_val[0]; y1 = p->o_val[1]; move(ox, oy); dotext(p); /* if there are any text strings */ x0 = ox - (x1+1) / 2; y0 = oy - (y1+1) / 2; x1 = ox + x1 / 2; y1 = oy + y1 / 2; if (p->o_attr & INVIS || p->o_type == BLOCK) ; /* nothing at all */ else box(x0, y0, x1, y1, p->o_dotdash, p->o_ddval); if (ishor(m)) move(isright(m) ? x1 : x0, oy); /* right side */ else move(ox, isdown(m) ? y0 : y1); /* bottom */ break; case BLOCKEND: break; case CIRCLE: x1 = p->o_val[0]; move(ox, oy); dotext(p); if ((p->o_attr & INVIS) == 0) circle(ox, oy, x1); if (ishor(m)) move(ox + isright(m) ? x1 : -x1, oy); else move(ox, oy + isup(m) ? x1 : -x1); break; case ELLIPSE: x1 = p->o_val[0]; y1 = p->o_val[1]; move(ox, oy); dotext(p); if ((p->o_attr & INVIS) == 0) ellipse(ox, oy, x1, y1); if (ishor(m)) move(ox + isright(m) ? x1 : -x1, oy); else move(ox, oy - isdown(m) ? y1 : -y1); break; case ARC: x1 = p->o_val[0]; y1 = p->o_val[1]; move(ox, oy); dotext(p); if (p->o_attr & HEAD1) arrow(x1 - (y1 - oy), y1 + (x1 - ox), x1, y1, p->o_val[4], p->o_val[5]); if (p->o_attr & INVIS) /* probably wrong when it's cw */ move(x1, y1); else arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]); if (p->o_attr & HEAD2) arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox), p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]); if (p->o_attr & CW_ARC) move(x1, y1); /* because drawn backwards */ break; case LINE: case ARROW: case SPLINE: x1 = p->o_val[0]; y1 = p->o_val[1]; move((ox + x1)/2, (oy + y1)/2); /* center */ dotext(p); if (p->o_attr & INVIS) move(x1, y1); else if (p->o_type == SPLINE) spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr); else if (p->o_type == LINE || p->o_type == ARROW) line(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr, p->o_dotdash, p->o_ddval); break; case MOVE: move(ox, oy); dotext(p); break; case TEXT: x1 = p->o_val[0]; y1 = p->o_val[1]; move(ox, oy); label(x1, y1, 0); free(x1); break; } } } dotline(x0, y0, x1, y1, ddtype, ddval) /* dotted line */ coord x0, y0, x1, y1; int ddtype; int ddval; { static int prevval = SCALE/20; /* 20 per inch by default */ int i, numdots; double a, b, sqrt(), dx, dy; if (ddval == 0) ddval = prevval; prevval = ddval; /* don't save dot/dash value */ dx = x1 - x0; dy = y1 - y0; if (ddtype == DOT) { numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5; for (i = 0; i <= numdots; i++) { a = (float) i / (float) numdots; move(x0 + (int)(a * dx), y0 + (int)(a * dy)); dot(); } } else if (ddtype == DASH) { double d, dashsize, spacesize; d = sqrt(dx*dx + dy*dy) + 0.5; if (d <= 2 * prevval) { line(x0, y0, x1, y1); return; } numdots = d / (2 * prevval - 1) + 1; /* ceiling */ dashsize = prevval; spacesize = (d - numdots * dashsize) / (numdots - 1); for (i = 0; i < numdots-1; i++) { a = i * (dashsize + spacesize) / d; b = a + dashsize / d; line(x0 + (int)(a*dx), y0 + (int)(a*dy), x0 + (int)(b*dx), y0 + (int)(b*dy)); a = b; b = a + spacesize / d; move(x0 + (int)(a*dx), y0 + (int)(a*dy)); } line(x0 + (int)(b * dx), y0 + (int)(b * dy), x1, y1); } prevval = SCALE/20; } dotbox(x0, y0, x1, y1, ddtype, ddval) /* dotted or dashed box */ coord x0, y0, x1, y1; int ddtype; int ddval; { dotline(x0, y0, x1, y0, ddtype, ddval); dotline(x1, y0, x1, y1, ddtype, ddval); dotline(x1, y1, x0, y1, ddtype, ddval); dotline(x0, y1, x0, y0, ddtype, ddval); } dotext(p) /* print text strings of p in proper vertical spacing */ struct obj *p; { int i, nhalf; nhalf = p->o_nt2 - p->o_nt1 - 1; for (i = p->o_nt1; i < p->o_nt2; i++) { label(text[i].t_val, text[i].t_type, nhalf); nhalf -= 2; } } xcip/JPIC/boxgen.c0000644000175300001440000000425011513632543012523 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *boxgen(type) { static int prevh = HT; static int prevw = WID; /* golden mean, sort of */ int i, invis, at, ddtype, ddval; int with, xwith, ywith; int h, w; coord x0, y0, x1, y1; struct obj *p, *ppos; h = getvar("boxht"); w = getvar("boxwid"); invis = at = 0; with = xwith = ywith = 0; ddtype = ddval = 0; for (i = 0; i < nattr; i++) { switch (attr[i].a_type) { case HEIGHT: h = attr[i].a_val; break; case WIDTH: w = attr[i].a_val; break; case SAME: h = prevh; w = prevw; break; case WITH: with = attr[i].a_val; /* corner */ break; case AT: ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; at++; break; case INVIS: invis = INVIS; break; case DOT: case DASH: ddtype = attr[i].a_type; ddval = attr[i].a_val; if (ddval == 0) ddval = getvar("dashwid"); break; case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; } } if (with) { switch (with) { case NORTH: ywith = -((h+1) / 2); break; case SOUTH: ywith = h / 2; break; case EAST: xwith = -((w+1) / 2); break; case WEST: xwith = w / 2; break; case NE: xwith = -((w+1) / 2); ywith = -((h+1) / 2); break; case SE: xwith = -((w+1) / 2); ywith = h / 2; break; case NW: xwith = w / 2; ywith = -((h+1) / 2); break; case SW: xwith = w / 2; ywith = h / 2; break; } curx += xwith; cury += ywith; } if (!at) { if (isright(hvmode)) curx += (w+1) / 2; else if (isleft(hvmode)) curx -= w / 2; else if (isup(hvmode)) cury += (h+1) / 2; else cury -= h / 2; } x0 = curx - w / 2; y0 = cury - h / 2; x1 = curx + (w+1) / 2; y1 = cury + (h+1) / 2; extreme(x0, y0); extreme(x1, y1); p = makenode(BOX, 2); p->o_val[0] = w; p->o_val[1] = h; p->o_dotdash = ddtype; p->o_ddval = ddval; p->o_attr = invis; dprintf("B %d %d %d %d at %d %d, h=%d, w=%d\n", x0, y0, x1, y1, curx, cury, h, w); if (isright(hvmode)) curx = x1; else if (isleft(hvmode)) curx = x0; else if (isup(hvmode)) cury = y1; else cury = y0; prevh = h; prevw = w; return(p); } xcip/JPIC/movegen.c0000644000175300001440000000322311513632543012700 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *movegen(type) { static int prevdx, prevdy; int i, dx, dy, some; int defx, defy; struct obj *p; struct obj *ppos; static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ static int ytab[] = { 0, 1, 0, -1 }; defx = getvar("movewid"); defy = getvar("moveht"); dx = dy = some = 0; for (i = 0; i < nattr; i++) { switch (attr[i].a_type) { case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; case SAME: dx = prevdx; dy = prevdy; some++; break; case LEFT: dx -= (attr[i].a_val==0) ? defx : attr[i].a_val; some++; hvmode = L_DIR; break; case RIGHT: dx += (attr[i].a_val==0) ? defx : attr[i].a_val; some++; hvmode = R_DIR; break; case UP: dy += (attr[i].a_val==0) ? defy : attr[i].a_val; some++; hvmode = U_DIR; break; case DOWN: dy -= (attr[i].a_val==0) ? defy : attr[i].a_val; some++; hvmode = D_DIR; break; case TO: ppos = (struct obj *) attr[i].a_val; dx = ppos->o_x - curx; dy = ppos->o_y - cury; some++; break; case BY: ppos = (struct obj *) attr[i].a_val; dx = ppos->o_x; dy = ppos->o_y; some++; break; case FROM: case AT: ppos = (struct obj *) attr[i].a_val; curx = ppos->o_x; cury = ppos->o_y; break; } } if (some) { defx = dx; defy = dy; } else { defx *= xtab[hvmode]; defy *= ytab[hvmode]; } prevdx = defx; prevdy = defy; extreme(curx, cury); curx += defx; cury += defy; extreme(curx, cury); p = makenode(MOVE, 0); dprintf("M %d %d\n", curx, cury); return(p); } xcip/JPIC/makefile0000644000175300001440000000515211513632667012606 0ustar meusers# Copyright (c) 1987 AT&T # All Rights Reserved # THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T # The copyright notice above does not evidence any # actual or intended publication of such source code. # @(#)makefile 1.1.1.2 (8/24/92) include ../stand.defs LEX_CMD=p9plex YACC_CMD=yacc -d MV=mv TC630=../../.. TOOLNAME=xcip/JPIC OBJSHOST=main.o print.o misc.o symtab.o blockgen.o \ boxgen.o circgen.o arcgen.o linegen.o movegen.o \ troffgen.o textgen.o pic2.o pltroff.o \ picy.o picl.o SOURCE=arcgen.c blockgen.c boxgen.c circgen.c driver.c \ epic.c jp.c linegen.c main.c misc.c \ movegen.c pic1.c pic2.c picl.c picy.c \ pltroff.c print.c symtab.c textgen.c troffgen.c \ pic.h y.tab.h picl.l picy.y PRODUCTSHOST=xjpic PRODUCTS5620=$(PRODUCTSHOST) PRODUCTS630=$(PRODUCTSHOST) INSTALLHOST=$(TCBIN)/xjpic INSTALL5620=$(INSTALLHOST) INSTALL630=$(INSTALLHOST) CLEANHOST=$(OBJSHOST) picl.c picy.c y.tab.h CLEAN5620=$(CLEANHOST) CLEAN630=$(CLEANHOST) include ../stand.targ $(TCBIN)/xjpic: xjpic cp xjpic $(TCBIN)/xjpic chmod $(MODEBIN) $(TCBIN)/xjpic xjpic: picy.o picl.o $(OBJSHOST) $(CC) -o xjpic $(OBJSHOST) -lm -ll $(CFLAGS) ######## ######## arcgen.o: arcgen.c arcgen.o: pic.h arcgen.o: y.tab.h $(CC) $(CFLAGS) -c arcgen.c blockgen.o: blockgen.c blockgen.o: pic.h blockgen.o: y.tab.h $(CC) $(CFLAGS) -c blockgen.c boxgen.o: boxgen.c boxgen.o: pic.h boxgen.o: y.tab.h $(CC) $(CFLAGS) -c boxgen.c circgen.o: circgen.c circgen.o: pic.h circgen.o: y.tab.h $(CC) $(CFLAGS) -c circgen.c linegen.o: linegen.c linegen.o: pic.h linegen.o: y.tab.h $(CC) $(CFLAGS) -c linegen.c main.o: main.c main.o: pic.h main.o: ../version.h main.o: y.tab.h $(CC) $(CFLAGS) -c main.c misc.o: misc.c misc.o: pic.h misc.o: y.tab.h $(CC) $(CFLAGS) -c misc.c movegen.o: movegen.c movegen.o: pic.h movegen.o: y.tab.h $(CC) $(CFLAGS) -c movegen.c pic2.o: pic.h pic2.o: pic2.c pic2.o: y.tab.h $(CC) $(CFLAGS) -c pic2.c picl.c: picl.l $(LEX_CMD) -t picl.l > picl.c picl.o: pic.h picl.o: picl.c picl.o: y.tab.h $(CC) $(CFLAGS) -c picl.c picy.c: picy.y $(YACC_CMD) picy.y;\ $(MV) y.tab.c picy.c picy.o: picy.c $(CC) $(CFLAGS) -c picy.c pltroff.o: pic.h pltroff.o: pltroff.c pltroff.o: y.tab.h $(CC) $(CFLAGS) -c pltroff.c print.o: pic.h print.o: print.c print.o: y.tab.h $(CC) $(CFLAGS) -c print.c symtab.o: pic.h symtab.o: symtab.c symtab.o: y.tab.h $(CC) $(CFLAGS) -c symtab.c textgen.o: pic.h textgen.o: textgen.c textgen.o: y.tab.h $(CC) $(CFLAGS) -c textgen.c troffgen.o: pic.h troffgen.o: troffgen.c troffgen.o: y.tab.h $(CC) $(CFLAGS) -c troffgen.c xcip/JPIC/linegen.c0000644000175300001440000001012611513632543012661 0ustar meusers#include #include "pic.h" #include "y.tab.h" struct obj *linegen(type) { static int prevdx = HT; static int prevdy = 0; static int prevw = HT/10; static int prevh = HT/5; int i, j, some, head, ddtype, ddval, invis; int chop, chop1, chop2, x0, y0, x1, y1; double sin(), cos(), atan2(), theta; int defx, defy; struct obj *p, *ppos; static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ static int ytab[] = { 0, 1, 0, -1 }; int ndxy, dx[50], dy[50]; coord nx, ny; nx = curx; ny = cury; defx = getvar("linewid"); defy = getvar("lineht"); prevh = getvar("arrowht"); prevw = getvar("arrowwid"); dx[0] = dy[0] = ndxy = some = head = invis = 0; chop = chop1 = chop2 = 0; ddtype = ddval = 0; for (i = 0; i < nattr; i++) { switch (attr[i].a_type) { case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: savetext(attr[i].a_type, attr[i].a_val); break; case HEAD: head += attr[i].a_val; break; case INVIS: invis = INVIS; break; case CHOP: if (chop++ == 0) chop1 = chop2 = attr[i].a_val; else chop2 = attr[i].a_val; break; case DOT: case DASH: ddtype = attr[i].a_type; ddval = attr[i].a_val; if (ddval == 0) ddval = getvar("dashwid"); break; case SAME: dx[ndxy] = prevdx; dy[ndxy] = prevdy; some++; break; case LEFT: dx[ndxy] -= (attr[i].a_val==0) ? defx : attr[i].a_val; some++; hvmode = L_DIR; break; case RIGHT: dx[ndxy] += (attr[i].a_val==0) ? defx : attr[i].a_val; some++; hvmode = R_DIR; break; case UP: dy[ndxy] += (attr[i].a_val==0) ? defy : attr[i].a_val; some++; hvmode = U_DIR; break; case DOWN: dy[ndxy] -= (attr[i].a_val==0) ? defy : attr[i].a_val; some++; hvmode = D_DIR; break; case HEIGHT: /* length of arrowhead */ prevh = attr[i].a_val; break; case WIDTH: /* width of arrowhead */ prevw = attr[i].a_val; break; case TO: if (some) { nx += dx[ndxy]; ny += dy[ndxy]; ndxy++; dx[ndxy] = dy[ndxy] = some = 0; } ppos = (struct obj *) attr[i].a_val; dx[ndxy] = ppos->o_x - nx; dy[ndxy] = ppos->o_y - ny; some++; break; case BY: ppos = (struct obj *) attr[i].a_val; dx[ndxy] = ppos->o_x; dy[ndxy] = ppos->o_y; some++; break; case THEN: /* turn off any previous accumulation */ if (some) { nx += dx[ndxy]; ny += dy[ndxy]; ndxy++; dx[ndxy] = dy[ndxy] = some = 0; } break; case FROM: case AT: ppos = (struct obj *) attr[i].a_val; nx = curx = ppos->o_x; ny = cury = ppos->o_y; break; } } if (some) { nx += dx[ndxy]; ny += dy[ndxy]; ndxy++; defx = dx[ndxy-1]; defy = dy[ndxy-1]; } else { defx *= xtab[hvmode]; defy *= ytab[hvmode]; dx[ndxy] = defx; dy[ndxy] = defy; ndxy++; nx += defx; ny += defy; } prevdx = defx; prevdy = defy; if (chop) { if (chop == 1 && chop1 == 0) /* just said "chop", so use default */ chop1 = chop2 = getvar("circlerad"); theta = atan2((float) defy, (float) defx); x0 = chop1 * cos(theta); y0 = chop1 * sin(theta); curx += x0; cury += y0; x1 = chop2 * cos(theta); y1 = chop2 * sin(theta); nx -= x1; ny -= y1; dx[0] -= x0; dy[0] -= y0; dx[ndxy-1] -= x1; dy[ndxy-1] -= y1; if(dbg)printf("chopping %d %d %d %d; cur=%d,%d end=%d,%d\n", x0, y0, x1, y1, curx, cury, nx, ny); } p = makenode(type, 5 + 2 * ndxy); curx = p->o_val[0] = nx; cury = p->o_val[1] = ny; if (head || type == ARROW) { p->o_val[2] = prevw; p->o_val[3] = prevh; if (head == 0) head = HEAD2; /* default arrow head */ } p->o_attr = head | invis; p->o_val[4] = ndxy; nx = p->o_x; ny = p->o_y; for (i = 0, j = 5; i < ndxy; i++, j += 2) { p->o_val[j] = dx[i]; p->o_val[j+1] = dy[i]; extreme(nx += dx[i], ny += dy[i]); } p->o_dotdash = ddtype; p->o_ddval = ddval; if (dbg) { printf("S or L from %d %d to %d %d with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy); for (i = 0, j = 5; i < ndxy; i++, j += 2) printf("%d %d\n", p->o_val[j], p->o_val[j+1]); } extreme(p->o_x, p->o_y); extreme(curx, cury); return(p); } struct obj *splinegen(type) { return linegen(type); } xcip/JPIC/pic2.c0000644000175300001440000001106311513632543012076 0ustar meusers#include #include #include "pic.h" #include "y.tab.h" extern FILE *yyin; extern int lineno; extern char *filename; extern int synerr; extern char * tostring(); char *definition(s) /* collect definition for s and install */ char *s; /* definitions picked up lexically */ { char buf[MAXDEF], *p, *tostring(); int c, delim; struct symtab *stp; while ((delim = input()) == ' ' || delim == '\t') ; for (p = buf; (c = input()) != delim; ) { if (p >= buf + sizeof(buf)) { yyerror("definition of %s is too long", s); exit(1); } if (c == EOF) { yyerror("end of file while defining %s", s); exit(1); } *p++ = c; } *p = '\0'; p = tostring(buf); stp = lookup(s); if (stp != NULL) { /* it's there before */ if (stp->s_type != DEFNAME) { yyerror("%s used as variable and definition\n", s); return (char *)NULL; } free(stp->s_val); stp->s_val = (int) p; } else { makevar(tostring(s), DEFNAME, (int) p); } dprintf("installing %s as `%s'\n", s, p); sprintf(buf, ".md %s", s); return(tostring(buf)); /* handled as TROFF */ } char *argstk[10]; /* pointers to actual arguments in argval */ char argval[1000]; /* arguments stored here end to end */ char *argp; /* current position in argval */ int argcnt; /* number of arguments seen so far */ char *defuse(s, p) /* used definition s, found at tbl p */ char *s; struct symtab *p; { int c; char buf[100], buf1[1000], *bp; c = input(); unput(c); /* this only works for macros with no args */ if (c == '(') /* it's name(...) */ dodef(p); else { /* no argument list */ bp = buf1; do { *bp = input(); } while (*bp++ != '\n'); /* collect rest of input line */ *bp = 0; sprintf(buf, ".e %s\n", s); dprintf("pushing back `%s'\n", buf); pbstr(buf); /* terminate use of defined name */ dprintf("pushing back `%s'\n", buf1); pbstr(buf1); dprintf("pushing back `%s'\n", p->s_val); pbstr((char *)p->s_val); unput('\n'); } sprintf(buf, ".u %s%s", s, buf1); return(tostring(buf)); } dodef(stp) /* collect args and push back defn for name in table slot n */ struct symtab *stp; { int i, len; char *p; argcnt = 0; if (input() != '(') yyerror("disaster in dodef\n"); for (argp = argval; (len = getarg(argp)) != -1; argp += len) { argstk[argcnt++] = argp; if (input() == ')') break; } for (i = argcnt; i < 10; i++) argstk[i] = ""; if (dbg) { for (i = 0; i < argcnt; i++) printf("arg %d = %s\n", i, argstk[i]); } /* push them back */ for (p = (char *) stp->s_val; *p; p++) ; /* find the end */ for (--p; p >= (char *) stp->s_val; p--) { if (*(p-1) == '$') { if (isdigit(*p)) { pbstr(argstk[*p - '0' - 1]); p--; } else unput(*p); } else { unput(*p); } } } getarg(p) /* pick up single argument, store in p, return length */ char *p; { int n, c, npar; n = npar = 0; for ( ;; ) { c = input(); if (c == EOF) yyerror("end of file in getarg!\n"); if (npar == 0 && (c == ',' || c == ')')) break; if (c == '"') /* copy quoted stuff intact */ do { *p++ = c; n++; } while ((c = input()) != '"' && c != EOF); else if (c == '(') npar++; else if (c == ')') npar--; n++; *p++ = c; } *p = 0; unput(c); return(n + 1); } #define PBSIZE 16000 char pbuf[PBSIZE]; /* pushback buffer */ char *pb = &pbuf[-1]; /* next pushed back character */ char ebuf[200]; /* collect input here for error reporting */ char *ep = ebuf; input() { register int c; if (pb >= pbuf) { c = *pb--; } else { c = getc(yyin); if (c == '\n') lineno++; else if (c == EOF) { yyerror("end of file inside .PS/.PE"); exit(1); } } if (ep >= ebuf + sizeof ebuf) ep = ebuf; return (*ep++ = c); } unput(c) { if (++pb >= pbuf + sizeof(pbuf) ) { yyerror("pushback overflow\n"); exit(1); } if (--ep < ebuf) ep = ebuf + sizeof(ebuf) - 1; return(*pb = c); } pbstr(s) char *s; { int n; n = strlen(s); while (--n >= 0) unput(s[n]); } yyerror(s, s1, s2, s3, s4) char *s, *s1, *s2, *s3, *s4; { if (synerr) return; fprintf(stderr, "pic: "); fprintf(stderr, s, s1, s2, s3, s4); fprintf(stderr, " near line %d, file %s\n", lineno, filename); eprint(); synerr = 1; } eprint() /* try to print context around error */ { char *p; p = ep - 1; if (p > ebuf && *p == '\n') p--; for ( ; p >= ebuf && *p != '\n'; p--) ; while (*p == '\n') p++; fprintf(stderr, " context is\n\t"); while (p < ep) putc(*p++, stderr); fprintf(stderr, " ^ "); while (pb >= pbuf) putc(*pb--, stderr); fgets(ebuf, sizeof ebuf, yyin); fprintf(stderr, "%s", ebuf); pbstr(".PE\n"); /* safety first */ ep = ebuf; } yywrap() {;} xcip/JPIC/jp.c0000644000175300001440000000633011513632543011653 0ustar meusers/* * jp - interpret pic on dmd */ #include #define YFUDGE 5 /* move chars down this much */ extern POINT current; char input[10000]; char *ip = input; POINT mpos; POINT scanpoint(); main(argc, argv) char *argv[]; { jinit(); sysinit(); spl0(); jBonW(); /* black on white */ getpic(); printpic(); for (;;) { if (button1()) { jclear(); printpic(); } else if (button23()) { jclear(); getpic(); printpic(); } } } getpic() { char temp[10]; register char *start, *ip; static POINT pos = {20,20}; ip = input; do { start = ip; while ((*ip++ = jgetchar()) != '\n') ; } while (*start != 'S'); *ip++ = 0; sprintf(temp, "%d", ip-input); jmoveto(pos); jstring(temp); } printpic() { register int c; int i, n; POINT pos, pos1, pos2; char s[100]; mpos = mouse.xy; cursinhibit(); for (ip = input; *ip; ) { switch (*ip++) { case ' ': case '\n': case '\t': break; case 'm': pos = scanpoint(); jmoveto(add(pos, mpos)); break; case 'e': pos = scanpoint(); scanint(); scanint(); break; case 'c': pos = scanpoint(); jcircle(add(pos, mpos), scanint(), F_STORE); break; case 'a': pos = add(scanpoint(), mpos); pos2 = add(scanpoint(), mpos); pos1 = add(scanpoint(), mpos); jarc(pos, pos1, pos2, F_STORE); break; case 'l': pos = scanpoint(); jmoveto(add(pos, mpos)); pos = scanpoint(); jlineto(add(pos, mpos), F_STORE); break; case 'b': pos1 = add(scanpoint(), mpos); pos2 = add(scanpoint(), mpos); jmoveto(pos1); pos.x = pos2.x; pos.y = pos1.y; jlineto(pos, F_STORE); jlineto(pos2, F_STORE); pos.x = pos1.x; pos.y = pos2.y; jlineto(pos, F_STORE); jlineto(pos1, F_STORE); break; case 't': pos = scanpoint(); while ((c = *ip++) == ' ') ; /* find type */ for (i = 0; (s[i++] = *ip++) != '\n'; ) ; s[i] = 0; pos.y += YFUDGE; n = strwidth(s); switch (c) { case 'C': pos.x -= n/2; break; case 'L': break; case 'R': pos.x -= n; break; } jmoveto(add(pos, mpos)); jstring(s); break; case '~': /* spline, expressed in delta's */ dospline(); break; default: while (*ip++ != '\n') ; break; } } cursallow(); } dospline() { long w, t1, t2, t3; int x[50], y[50]; int i, j, xp, yp, n; long scale = 1000; int steps = 10; POINT p; n = scanint(); for (i = 1; i <= n; i++) { x[i] = scanint(); y[i] = scanint(); } x[0] = x[1]; y[0] = y[1]; x[n+1] = x[n]; y[n+1] = y[n]; p.x = x[0]; p.y = y[0]; jmoveto(add(p, mpos)); for (i = 0; i < n; i++) { for (j = 0; j < steps; j++) { w = scale * j / steps; t1 = w * w / (2 * scale); w = w - scale/2; t2 = 3*scale/4 - w * w / scale; w = w - scale/2; t3 = w * w / (2*scale); p.x = (t1*x[i+2] + t2*x[i+1] + t3*x[i] + scale/2) / scale; p.y = (t1*y[i+2] + t2*y[i+1] + t3*y[i] + scale/2) / scale; jlineto(add(p, mpos), F_STORE); } } } jclear() { cursinhibit(); jrectf(screenmap.rect, F_CLR); cursallow(); } POINT scanpoint() { POINT p; p.x = scanint(); p.y = scanint(); return p; } scanint() { register int n, c; while ((c = *ip++) == ' ' || c == '\t') ; n = 0; do { n = 10 * n + c - '0'; } while ((c = *ip++) >= '0' && c <= '9'); return(n); } xcip/JPIC/picy.y0000644000175300001440000001205711513632543012237 0ustar meusers%token BOX 1 %token ARROW 2 %token CIRCLE 3 %token ARC 4 %token ELLIPSE 5 %token LINE 6 %token MOVE 7 %token TEXT 8 %token TROFF 9 %token SPLINE 10 %token BLOCK 11 %token BLOCKEND 12 %token PRINT %token PLACE %token ATTR %token SPREAD FILL LJUST RJUST ABOVE BELOW %token LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN %token HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE %token PLACENAME VARNAME DEFNAME CORNER HERE LAST NTH SAME BETWEEN AND %token EAST WEST NORTH SOUTH NE NW SE SW CENTER START END %token DOTX DOTY DOTHT DOTWID DOTRAD %token NUMBER %token DIR %token DOT DASH CHOP %token ST /* statement terminator */ %left '+' '-' %left '*' '/' '%' %right UMINUS %{ #include extern int hvmode, codegen; extern float between, lastfloat; %} %% top: piclist | /* empty */ | error { yyerror("syntax error"); } ; piclist: picture | piclist picture ; picture: prim ST { codegen = 1; } | leftbrace piclist '}' { rightthing($1, '}'); $$ = $2; } | PLACENAME ':' picture { makevar($1, PLACENAME, $3); $$ = $3; } | PLACENAME ':' ST picture { makevar($1, PLACENAME, $4); $$ = $4; } | PLACENAME ':' position ST { makevar($1, PLACENAME, $3); $$ = $3; } | VARNAME '=' expr ST { makevar($1, VARNAME, $3); $$ = $1; } | DIR { setdir($1); } | PRINT expr ST { printexpr($2); } | PRINT position ST { printpos($2); } | ST ; leftbrace: '{' { leftthing('{'); } ; prim: BOX attrlist { $$ = boxgen($1); } | CIRCLE attrlist { $$ = circgen($1); } | ELLIPSE attrlist { $$ = circgen($1); } | ARC attrlist { $$ = arcgen($1); } | LINE attrlist { $$ = linegen($1); } | ARROW attrlist { $$ = linegen($1); } | SPLINE attrlist { $$ = splinegen($1); } | MOVE attrlist { $$ = movegen($1); } | TEXT attrlist { $$ = textgen($1); } | TROFF { $$ = troffgen($1); } | lbracket piclist ']' { $$=rightthing($1,']'); } attrlist { $$ = blockgen($1, $2, $4); } ; lbracket: '[' { $$ = leftthing('['); } ; attrlist: attrlist attr | /* empty */ { makeattr(0, 0); } ; attr: ATTR opt_expr { makeattr($1, $2); } | DIR opt_expr { makeattr($1, $2); } | FROM position { makeattr($1, $2); } | TO position { makeattr($1, $2); } | AT position { makeattr($1, $2); } | BY position { makeattr($1, $2); } | WITH CORNER { makeattr(WITH, $2); } | WITH '.' PLACENAME { makeattr(PLACE, getblock(getlast(1,BLOCK), $3)); } | WITH position { makeattr(PLACE, $2); } | SAME { makeattr(SAME, $1); } | textattr { makeattr($1, 0); } | HEAD { makeattr(HEAD, $1); } | DOT opt_expr { makeattr(DOT, $2); } | DASH opt_expr { makeattr(DASH, $2); } | CHOP opt_expr { makeattr(CHOP, $2); } | textlist ; opt_expr: expr | /* empty */ { $$ = 0; } ; textlist: TEXT { makeattr(CENTER, $1); } | TEXT textattr { makeattr($2, $1); } | textlist TEXT { makeattr(CENTER, $2); } | textlist TEXT textattr { makeattr($3, $2); } ; textattr: LJUST | RJUST | SPREAD | FILL | CENTER | ABOVE | BELOW ; position: /* absolute, not relative */ | place | expr ',' expr { $$ = makepos($1, $3); } | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); } | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); } | '(' expr ',' expr ')' { $$ = makepos($2, $4); } | position '+' '(' expr ',' expr ')' { $$ = fixpos($1, $4, $6); } | position '-' '(' expr ',' expr ')' { $$ = fixpos($1, -$4, -$6); } | '(' place ',' place ')' { $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); } | expr { between=lastfloat; } '<' position ',' position '>' { $$ = makebetween($1, $4, $6); } | expr { between=lastfloat; } BETWEEN position AND position { $$ = makebetween($1, $4, $6); } ; place: PLACENAME { $$ = getpos(getvar($1), 0); } | PLACENAME CORNER { $$ = getpos(getvar($1), $2); } | CORNER PLACENAME { $$ = getpos(getvar($2), $1); } | HERE { $$ = gethere($1); } | last type { $$ = getlast($1, $2); } | last type CORNER { $$ = getpos(getlast($1, $2), $3); } | CORNER last type { $$ = getpos(getlast($2, $3), $1); } | NTH type { $$ = getfirst($1, $2); } | NTH type CORNER { $$ = getpos(getfirst($1, $2), $3); } | CORNER NTH type { $$ = getpos(getfirst($2, $3), $1); } | blockname | blockname CORNER { $$ = getpos($1, $2); } | CORNER blockname { $$ = getpos($2, $1); } ; blockname: last BLOCK '.' PLACENAME { $$ = getblock(getlast($1,$2), $4); } | NTH BLOCK '.' PLACENAME { $$ = getblock(getfirst($1,$2), $4); } | PLACENAME '.' PLACENAME { $$ = getblock(getvar($1), $3); } ; last: last LAST { $$ = $1 + 1; } | NTH LAST { $$ = $1; } | LAST { $$ = 1; } ; type: BOX | CIRCLE | ELLIPSE | ARC | LINE | ARROW | SPLINE | BLOCK ; expr: expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | expr '%' expr { $$ = $1 % $3; } | '-' expr %prec UMINUS { $$ = -$2; } | '(' expr ')' { $$ = $2; } | VARNAME { $$ = getvar($1); } | NUMBER | place DOTX { $$ = getcomp($1, $2); } | place DOTY { $$ = getcomp($1, $2); } | place DOTHT { $$ = getcomp($1, $2); } | place DOTWID { $$ = getcomp($1, $2); } | place DOTRAD { $$ = getcomp($1, $2); } ; xcip/makefile0000644000175300001440000001117611513632544012056 0ustar meusers# Copyright (c) 1987 AT&T # All Rights Reserved # THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T # The copyright notice above does not evidence any # actual or intended publication of such source code. # @(#)makefile 1.1.1.1 (8/12/92) include ./stand.defs TC630=../.. TOOLNAME=xcip OBJSHOST= OBJS5620=$(TCTERM)/buttons.o $(TCTERM)/cip.o $(TCTERM)/commands.o \ $(TCTERM)/draw.o $(TCTERM)/edit.o $(TCTERM)/icons.o $(TCTERM)/menus.o \ $(TCTERM)/readPic.o $(TCTERM)/pic.o $(TCTERM)/space.o \ $(TCTERM)/things.o $(TCTERM)/track.o $(TCTERM)/transform.o \ $(TCTERM)/tmenuhit.o OBJS630=$(OBJS5620) OBJSX11=$(OBJS5620) SOURCE=buttons.c cip.c commands.c draw.c edit.c icons.c menus.c pic.c \ readPic.c space.c things.c tmenuhit.c tmenuhit.h track.c transform.c \ xcip.sh xcipfront.sh logo.pic cip.h version.h xcip.1 README PRODUCTSHOST= PRODUCTS5620=$(TCTERM)/xcip.m 1.xcip PRODUCTS630=$(PRODUCTS5620) INSTALLHOST= INSTALL5620=$(TCLIB)/$(TCTERM)/xcip.m $(TCMAN)/1.xcip \ $(TCBIN)/xcip $(TCLIB)/dmdtools/xcip INSTALL630=$(INSTALL5620) SUBDIRSHOST=JPIC SUBDIRS5620=$(SUBDIRSHOST) SUBDIRS630=$(SUBDIRSHOST) include ./stand.targ $(TCBIN)/xcip: xcipfront.sh cp xcipfront.sh $(TCBIN)/xcip chmod $(MODEBIN) $(TCBIN)/xcip $(TCLIB)/dmdtools/xcip: xcip.sh sed "s+DeFdMd+$(DEFDMD)+g" xcip.sh >$(TCLIB)/dmdtools/xcip chmod $(MODEBIN) $(TCLIB)/dmdtools/xcip $(TCLIB)/dmd/xcip.m: dmd/xcip.m cp dmd/xcip.m $(TCLIB)/dmd/xcip.m chmod $(MODELIB) $(TCLIB)/dmd/xcip.m $(TCLIB)/630/xcip.m: 630/xcip.m cp 630/xcip.m $(TCLIB)/630/xcip.m # $(MSTRIP) -m $(TCLIB)/630/xcip.m chmod $(MODELIB) $(TCLIB)/630/xcip.m $(TCMAN)/1.xcip: 1.xcip cp 1.xcip $(TCMAN)/1.xcip chmod $(MODELIB) $(TCMAN)/1.xcip 630/xcip.m: $(OBJS630) $(MCC) $(MCFLAGS) $(OBJS630) -o 630/xcip.m dmd/xcip.m: $(OBJS5620) $(MCC) $(MCFLAGS) $(OBJS5620) -o dmd/xcip.m 1.xcip: xcip.1 nroff -man -T37 $(MANFL) xcip.1 > 1.xcip ######## # X11 version of cip ######## XFLAGS=-DBSD # for SunOS # XFLAGS=-DBSD -I/usr/openwin/include -L/usr/openwin/lib # for SYSVR4: # XFLAGS=-DSYSV -DSVR4 -lnsl -lsocket # for Solaris # XFLAGS=-DSYSV -DSVR4 -I/usr/openwin/include -L/usr/openwin/lib -lnsl -lsocket x11: LIBDMDX11/libj.a $(MAKE) TCTERM=X11 MCC=cc DMD="" \ MCFLAGS="-DX11 -ILIBDMDX11 $(XFLAGS) $(EXTRACFLAGS)" xcip.x11 xcip.x11: $(OBJSX11) $(CC) -o xcip.x11 $(OBJSX11) LIBDMDX11/libj.a $(MCFLAGS) -lX11 LIBDMDX11/libj.a: FRC cd LIBDMDX11; $(MAKE) XFLAGS="$(XFLAGS)" libj.a clean: cleanx11 cleanx11: cd LIBDMDX11; $(MAKE) clean rm -f X11/*.o clobber: clobberx11 clobberx11: cleanx11 rm -f xcip.x11 FRC: ######## # CIP logo # # Convert a series of lines in logo.pic to C data in logo.data. # ######## logo.data: logo.pic grep '^line from' logo.pic | \ sed -e 's/^line from \([0-9][0-9]*\),\([0-9][0-9]*\) to \([0-9][0-9]*\),\([0-9][0-9]*\)/\1,\2,\3,\4,/' \ > logo.data ######## # # dependencies and rules # ######## $(TCTERM)/buttons.o: buttons.c $(TCTERM)/buttons.o: cip.h $(MCC) $(MCFLAGS) -c buttons.c mv buttons.o $(TCTERM)/buttons.o $(TCTERM)/cip.o: cip.c $(TCTERM)/cip.o: cip.h $(TCTERM)/cip.o: tmenuhit.h $(TCTERM)/cip.o: version.h $(MCC) $(MCFLAGS) -c cip.c mv cip.o $(TCTERM)/cip.o $(TCTERM)/commands.o: commands.c $(TCTERM)/commands.o: cip.h $(MCC) $(MCFLAGS) -c commands.c mv commands.o $(TCTERM)/commands.o $(TCTERM)/draw.o: draw.c $(TCTERM)/draw.o: cip.h $(TCTERM)/draw.o: logo.data $(MCC) $(MCFLAGS) -c draw.c mv draw.o $(TCTERM)/draw.o $(TCTERM)/edit.o: edit.c $(TCTERM)/edit.o: cip.h $(MCC) $(MCFLAGS) -c edit.c mv edit.o $(TCTERM)/edit.o $(TCTERM)/icons.o: icons.c $(TCTERM)/icons.o: cip.h $(MCC) $(MCFLAGS) -c icons.c mv icons.o $(TCTERM)/icons.o $(TCTERM)/menus.o: menus.c $(TCTERM)/menus.o: cip.h $(TCTERM)/menus.o: tmenuhit.h $(MCC) $(MCFLAGS) -c menus.c mv menus.o $(TCTERM)/menus.o $(TCTERM)/pic.o: pic.c $(TCTERM)/pic.o: cip.h $(MCC) $(MCFLAGS) -c pic.c mv pic.o $(TCTERM)/pic.o $(TCTERM)/readPic.o: readPic.c $(TCTERM)/readPic.o: cip.h $(MCC) $(MCFLAGS) -c readPic.c mv readPic.o $(TCTERM)/readPic.o $(TCTERM)/space.o: space.c $(TCTERM)/space.o: cip.h $(MCC) $(MCFLAGS) -c space.c mv space.o $(TCTERM)/space.o $(TCTERM)/things.o: things.c $(TCTERM)/things.o: cip.h $(MCC) $(MCFLAGS) -c things.c mv things.o $(TCTERM)/things.o $(TCTERM)/tmenuhit.o: tmenuhit.c $(TCTERM)/tmenuhit.o: tmenuhit.h $(MCC) $(MCFLAGS) -c tmenuhit.c mv tmenuhit.o $(TCTERM)/tmenuhit.o $(TCTERM)/track.o: track.c $(TCTERM)/track.o: cip.h $(MCC) $(MCFLAGS) -c track.c mv track.o $(TCTERM)/track.o $(TCTERM)/transform.o: transform.c $(TCTERM)/transform.o: cip.h $(MCC) $(MCFLAGS) -c transform.c mv transform.o $(TCTERM)/transform.o xcip/draw.c0000644000175300001440000002432711513632544011461 0ustar meusers#include "cip.h" #ifdef DMDTERM #ifdef DMD5620 # include "line.h" #endif # include "layer.h" #endif #define DOT 2 #define DASH 10 #define ARROWwid 10 #define ARROWht 10 #ifndef ONEDOTOH Point PointCurr; #endif extern char *Pgm_name; extern Point jString (); extern Rectangle brushes[]; struct thing addOffset(); /* These operations temporarily reset the window to the drawing sub-window to automatically obtain the clipping operation on drawing graphics. */ #ifdef X11 # define WINDOW &display # define CLIPON set_clip(clip_rect) # define CLIPOFF unset_clip() #else /* X11 */ # define WINDOW P->layer Word * saveBase; Rectangle saveScreen; #define CLIPON \ saveBase = P->layer->base; \ saveScreen = P->layer->rect; \ P->layer->base = addr(P->layer,brushes[PIC].origin); \ P->layer->rect = brushes[PIC] #define CLIPOFF \ P->layer->base = saveBase; \ P->layer->rect = saveScreen #endif /* X11 */ /* This routine clips an arc within rectangle brushes[PIC] */ xarc(p0, p1, p2) Point p0, p1, p2; { CLIPON; arc(WINDOW, p0, p1, p2, F_XOR); CLIPOFF; } /* This routine clips a spline within rectangle brushes[PIC] */ xspline(offset,p, n) Point offset; register Point *p; int n; { CLIPON; spline(offset,p, n); CLIPOFF; } /* This routine clips a line within rectangle brushes[PIC] */ xsegment (p, q) Point p, q; { CLIPON; segment(WINDOW , p, q, F_XOR); CLIPOFF; } draw(t,offset) register struct thing *t; Point offset; { register struct thing *s; Rectangle rc; Point p1,p2; register int u; if (t != (struct thing *) NULL) { /* cursinhibit(); */ switch(t->type) { case CIRCLE: { CLIPON; circle(WINDOW,add(offset,t->origin), t->otherValues.radius,F_XOR); CLIPOFF; break; } case BOX: { CLIPON; rc = raddp(t->bb,offset); if (t->border == DOTTED) { dashedBox(rc,DOT); } else { if (t->border == DASHED) { dashedBox(rc,DASH); } else { box(rc); } } CLIPOFF; break; } case ELLIPSE: { CLIPON; Ellipse(add(offset,t->origin),t->otherValues.ellipse.ht, t->otherValues.ellipse.wid); CLIPOFF; break; } case LINE: { CLIPON; p1 = add(t->origin,offset); p2 = add(t->otherValues.end,offset); if (t->border == DOTTED) { dashedLine(p1,p2,DOT); } else { if (t->border == DASHED) { dashedLine(p1,p2,DASH); } else { segment(WINDOW,p1,p2,F_XOR); } } if ((t->arrow==startARROW)||(t->arrow==doubleARROW)) { arrow(p2,p1); } if ((t->arrow==endARROW)||(t->arrow==doubleARROW)) { arrow(p1,p2); } CLIPOFF; break; } case ARC: { CLIPON; arc (WINDOW , add(offset,t->origin), add(offset,t->otherValues.arc.start), add(offset,t->otherValues.arc.end),F_XOR); CLIPOFF; break; } case TEXT: { CLIPON; drawText(add(offset,t->origin), t->otherValues.text.s, t->otherValues.text.just, t->otherValues.text.spacing, t->otherValues.text.f->f ); CLIPOFF; break; } case SPLINE: { CLIPON; u = t->otherValues.spline.used; spline(offset,t->otherValues.spline.plist,u); if ((t->arrow==startARROW)||(t->arrow==doubleARROW)) { arrow(add(offset,t->otherValues.spline.plist[2]), add(offset,t->otherValues.spline.plist[1])); } if ((t->arrow==endARROW)||(t->arrow==doubleARROW)) { arrow(add(offset,t->otherValues.spline.plist[u-2]), add(offset,t->otherValues.spline.plist[u-1])); } CLIPOFF; break; } case MACRO: { if ((s=t->otherValues.list->parts) != (struct thing *)NULL) { do { draw(s,add(offset,t->origin)); s = s->next; } while (s != t->otherValues.list->parts); } break; } } /* cursallow(); */ } } xbox(r) Rectangle r; { xsegment(r.origin,Pt(r.corner.x,r.origin.y)); xsegment(Pt(r.corner.x,r.origin.y),r.corner); xsegment(r.corner,Pt(r.origin.x,r.corner.y)); xsegment(Pt(r.origin.x,r.corner.y),r.origin); } box(r) Rectangle r; { segment(WINDOW , r.origin,Pt(r.corner.x,r.origin.y),F_XOR); segment(WINDOW , Pt(r.corner.x,r.origin.y),r.corner,F_XOR); segment(WINDOW , r.corner,Pt(r.origin.x,r.corner.y),F_XOR); segment(WINDOW , Pt(r.origin.x,r.corner.y),r.origin,F_XOR); } dashedBox(r,dashsize) Rectangle r; register int dashsize; { dashedLine(r.origin,Pt(r.corner.x,r.origin.y),dashsize); dashedLine(Pt(r.corner.x,r.origin.y),r.corner,dashsize); dashedLine(r.corner,Pt(r.origin.x,r.corner.y),dashsize); dashedLine(Pt(r.origin.x,r.corner.y),r.origin,dashsize); } dashedLine(s,end,dashsize) Point s, end; int dashsize; { register int e, dx, dy, i, toDraw, yinc, xinc, swit; #ifdef X11 /* For better efficiency, using initpoints, points, and endpoints. */ initpoints(&display, F_XOR); #endif /* X11 */ dx = abs(end.x - s.x); dy = abs(end.y - s.y); xinc = ((end.x-s.x)>0)? 1 : -1; yinc = ((end.y-s.y)>0)? 1 : -1; swit = (dy>dx); toDraw = 1; e = (swit)? (2*dx - dy) : (2*dy - dx); for (i=0; i < ((swit) ? dy : dx); i++) { if (i>0 && i%dashsize==0) { toDraw = (toDraw==1)?0:1; } if (toDraw) { #ifdef X11 points(s,F_XOR); #else /* X11 */ point(WINDOW,s,F_XOR); #endif /* X11 */ } if (e>0) { if (swit) { s.x += xinc; } else { s.y += yinc; } e += (swit)? (2*dx - 2*dy) : (2*dy - 2*dx); } else { e += (swit)? 2*dx : 2*dy; } if (swit) { s.y += yinc; } else { s.x += xinc; } } #ifdef X11 endpoints(); #endif /* X11 */ } int degrees(d) register int d; { while (d>360) { d -= 360; } while (d<0) { d += 360; } return(d); } arrow(a, b) /* draw arrow (without line) */ Point a,b; { register int alpha, rot, hyp; register int dx, dy; rot = atan2( ARROWwid / 2, ARROWht); hyp = norm(ARROWwid,ARROWht,0); alpha = atan2(b.y-a.y, b.x-a.x); dx = muldiv(hyp,cos(degrees(alpha + 180 + rot)),1024); dy = muldiv(hyp,sin(degrees(alpha + 180 + rot)),1024); /* line(x1+dx, y1+dy, x1, y1); */ #ifdef DMDTERM if ((b.x==a.x) && (b.y < a.y)) { dy = -dy; } #endif cursinhibit(); segment(WINDOW,add(b,Pt(-dx,dy)),b,F_XOR); cursallow(); dx = muldiv(hyp,cos(degrees(alpha + 180 - rot)),1024); dy = muldiv(hyp,sin(degrees(alpha + 180 - rot)),1024); /* line(x1+dx, y1+dy, x1, y1); */ #ifdef DMDTERM if ((b.x==a.x) && (b.y < a.y)) { dy = -dy; } #endif cursinhibit(); segment(WINDOW,add(b,Pt(dx,-dy)),b,F_XOR); cursallow(); } centeredText(p,s) Point p; register char *s; { string( &defont, s, &display, Pt( p.x - (strwidth(&defont,s)>>1), p.y ), F_XOR ); } flash(b,offset) register Rectangle *b; Point offset; { if (b != (Rectangle *) NULL) { cursinhibit(); rectf( &display, raddp(*b,offset), F_XOR ); cursallow(); } } flashThing(t,offset) register struct thing *t; Point offset; { Rectangle r; if (t != (struct thing *) NULL) { cursinhibit(); switch (t->type) { case CIRCLE: case BOX: case ELLIPSE: case LINE: case ARC: case SPLINE: { draw(t,offset); break; } case MACRO: case TEXT: { /* Must add Pt(1,1) to corner to fill box fully - why ??? */ r.origin = t->bb.origin; r.corner = add( t->bb.corner , Pt(1,1) ); flash( &r , offset ); break; } } cursallow(); } } Ellipse(p,h,w) Point p; register int h, w; { ellipse(WINDOW , p, w>>1, h>>1, F_XOR); } drawZigZag(offset,p,n) Point offset; register Point *p; int n; { register int i; Point j; Point k; if (p != (Point *) NULL) { cursinhibit(); if (n>0) { j = add(offset, p[1]); for (i=2; i<=n; i++) { k = add (offset, p[i]); xsegment(j, k); j = k; } } cursallow(); } } #define SCALE (long) 1000 #define STEPS 10 spline(offset,p, n) Point offset; register Point *p; int n; { register long w, t1, t2, t3; register int i, j; Point q; Point pcurrent; /* Current point */ if (p != (Point *) NULL) { p[0] = p[1]; p[n] = p[n-1]; cursinhibit(); pcurrent = add(offset,p[0]); for (i = 0; i < n-1; i++) { for (j = 0; j < STEPS; j++) { w = SCALE * j / STEPS; t1 = w * w / (2 * SCALE); w = w - SCALE/2; t2 = 3*SCALE/4 - w * w / SCALE; w = w - SCALE/2; t3 = w * w / (2*SCALE); q.x = (t1*p[i+2].x + t2*p[i+1].x + t3*p[i].x + SCALE/2) / SCALE; q.y = (t1*p[i+2].y + t2*p[i+1].y + t3*p[i].y + SCALE/2) / SCALE; segment(&display, pcurrent, add(offset,q), F_XOR); pcurrent = add(offset, q ); } } cursallow(); } } #ifdef DMDTERM Bitmap tempBitmap = { 0, 1, 0, 0, 16, 16, 0 }; #ifdef DMD5620 Word tempIcon[16]; #endif #endif drawIcon(axy,icon) Point axy; register Texture16 * icon; { #ifdef X11 Bitmap *tempBitmap, *balloc(); tempBitmap = balloc(Rect(0, 0, 16, 16)); texture(tempBitmap, tempBitmap->rect, icon, F_STORE); bitblt(tempBitmap, tempBitmap->rect, &display, sub(axy, Pt(8,8)), F_OR); bfree(tempBitmap); #else #ifdef DMD630 tempBitmap.base = icon->bits; #endif #ifdef DMD5620 register int i; register Word word; for( i=0; i<15; i++) { word = icon->bits[i]; tempIcon[i] = word << 16; } tempBitmap.base = tempIcon; #endif bitblt(&tempBitmap, tempBitmap.rect, &display, sub(axy, Pt(8,8)), F_XOR); #endif /* X11 */ } drawCopyright( pt ) Point pt; { pt = string(&defont,"Copyright",&display,pt,F_XOR); drawIcon( add(pt,Pt(11,7)), ©right ); string(&defont,"1995 AT&T",&display,add(pt,Pt(24,0)),F_XOR); string(&defont,"All Rights Reserved",&display,add(pt,Pt(-74,14)),F_XOR); } /**** CIP logo ****/ /* Note: used only in DMD terminals. */ #ifdef DMDTERM typedef struct { Point start; Point end; } Logo_Line; /* Insert line data convert from logo.pic file. */ Logo_Line logo[] = { # include "logo.data" -1,-1,-1,-1 }; drawToolIcon() { register Logo_Line * line; jmoveto( Pt(40,25) ); jstring(Pgm_name); for( line = &logo[0]; line->start.x != -1; line++ ) { #ifdef DMD630 jsegment( Pt( 100 + line->start.x , 900 - line->start.y ), Pt( 100 + line->end.x , 900 - line->end.y ), F_STORE ); #endif #ifdef DMD5620 jsegment( Pt( 25 + line->start.x , 900 - line->start.y ), Pt( 25 + line->end.x , 900 - line->end.y ), F_STORE ); #endif } } #endif /* DMDTERM */ xcip/README0000644000175300001440000000454611513632542011237 0ustar meusers# Copyright (c) 1987 AT&T # All Rights Reserved # THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T # The copyright notice above does not evidence any # actual or intended publication of such source code. PROGRAM: xcip DESCRIPTION: A graphics drawing program with output in pic format TERMINAL: 5620 DMD - requires 5620 DMD Application Development Package 630 MTG - requires 630 MTG Software Development Package COMPUTER: 3B2 3B20 VAX (requires porting the 630 MTG Software Development Package) AMDAHL (requires porting the 630 MTG Software Development Package and/or the 5620 DMD Application Development Package) OPERATING SYSTEM: UNIX System V Release 2 or 3 with Windowing Utilities or the 5620 DMD Core Package installed BUILD PROCEDURE: make DMD630=<630 SDP> DMD5620=<5620 ADP> TCTERM= \ TC630= The <...>'s have the followings meanings: <630 SDP> - full path name to the 630 MTG Software Development Package. It is needed only if TCTERM = 630 or all. It defaults to /usr/opt/630. <5620 ADP> - full path name to the 5620 DMD Application Development Package. It is needed only of TCTERM = 5620 or all. It defaults to /usr/dmd. - terminal for which the is to take place. Possibles values are: 630 - 630 MTG dmd - 5620 DMD all - both 630 and dmd It defaults to 630. - full path name to where the product will be installed. This is needed only for the install action. There is no default. - defines the action to be done. Possible actions are: build - just make the products install - install the products clean - remove .o's clobber - remove the products under the source directory The default action is build. requirements: the following directories must already exist to do the install action: $TC630/bin $TC630/man $TC630/lib/630 $TC630/lib/dmd $TC630/lib/xbin example: make TCTERM=all install # makes and installs for the 630 and 5620 terminals EXECUTION: To run the program, the shell environment variable TC630 must be set and exported to the same value as used to build xcip. The manual page describes how xcip works. xcip/edit.c0000644000175300001440000001653011513632540011442 0ustar meusers#include "cip.h" extern int thingSelected; struct thing * editThing(m,offset,t) Point m; /* Mouse location */ Point offset; /* Offset */ register struct thing *t; /* Thing to be edited */ { register int d,dx,dy,u; Point o, np; if (t != TNULL) { o = t->origin; switch(t->type) { case CIRCLE: { d = norm(o.x-m.x,o.y-m.y,0); if (d< (t->otherValues.radius>>1)) { track(m,offset,MOVE,t); } else { track(m,offset,GROWCIRCLE,t); } d = t->otherValues.radius; break; } case BOX: { np = t->otherValues.corner; dx = (np.x - o.x)>>2; dy = (np.y - o.y)>>2; if (ptinrect(m,Rect(o.x+dx,o.y+dy,np.x-dx,np.y-dy))) { if (t->border != SOLID) { draw(t,offset); xbox(raddp(t->bb,offset)); } t->bb = moveBox(m,t->bb,offset,0); t->otherValues.corner = t->bb.corner; t->origin = t->bb.origin; xbox(raddp(t->bb,offset)); printInfo(t); } else { draw(t,offset); t->origin.x = 0; t->origin.y = 0; t->bb.origin = t->origin; t->bb.corner = t->origin; t->otherValues.corner = t->origin; if (!ptinrect(m,Rect(o.x-dx,o.y-dy,o.x+dx,o.y-dy))) { if (ptinrect(m,Rect(o.x-dx,np.y-dy,o.x+dx,np.y+dy))) { np.y = o.y; } else { if (ptinrect(m,Rect(np.x-dx,np.y-dy,np.x+dx,np.y+dy))) { np = o; } else { if (ptinrect(m,Rect(np.x-dx,o.y-dy,np.x+dx,o.y+dy))) { np.x = o.x; } } } } o = track(np,offset,BOX,t); t->origin.x = min(o.x,np.x); t->origin.y = min(o.y,np.y); t->otherValues.corner.x = max(o.x,np.x); t->otherValues.corner.y = max(o.y,np.y); } break; } case ELLIPSE: { dx = abs(m.x - o.x); dy = abs(m.y - o.y); d = norm(dx,dy,0); if ((dx > dy) && (d > (t->otherValues.ellipse.wid>>2))) { track(m,offset,GROWEWID,t); } else { if ((dx < dy) && (d > (t->otherValues.ellipse.ht>>2))) { track(m,offset,GROWEHT,t); } else { track(m,offset,MOVE,t); } } break; } case LINE: { np=t->otherValues.end; draw(t,offset); if (distance(m,o)otherValues.arc.start))>>1; if (distance(o,m)otherValues.arc.start)< distance(m,t->otherValues.arc.end)) { arcStart(t,offset); } else { arcEnd(t,offset); } } break; } case MACRO: { draw(t,offset); xbox(raddp(t->bb,offset)); t->bb = moveBox(m,t->bb,offset,0); t->origin = t->bb.origin; xbox(raddp(t->bb,offset)); printInfo(t); break; } case TEXT: { /* Allow finer movements in text since bounding box in any case will be increased to fit current alignment. */ int saveAlignment; saveAlignment = currAlignment; #ifdef FINEALIGN currAlignment = max(currAlignment>>1,1); #else /* FINEALIGN */ currAlignment = max(currAlignment>>1,2); #endif /* FINEALIGN */ track(m,offset,MOVE,t); currAlignment = saveAlignment; break; } case SPLINE: { u = t->otherValues.spline.used; d=findNearestPoint(m,t->otherValues.spline.plist,u); if ((t->arrow==startARROW)||(t->arrow==doubleARROW)) { arrow(add(offset,t->otherValues.spline.plist[2]), add(offset,t->otherValues.spline.plist[1])); } if ((t->arrow==endARROW)||(t->arrow==doubleARROW)) { arrow(add(offset,t->otherValues.spline.plist[u-2]), add(offset,t->otherValues.spline.plist[u-1])); } if ((d == u-1) || (d==1)) { xsegment (add(offset,t->otherValues.spline.plist[(d==1)?1:(d-1)]), add(offset,t->otherValues.spline.plist[(d==1)?2:d])); np=track(t->otherValues.spline.plist[(d==1)?2:(d-1)], offset,(d==1)?REVSPLINE:SPLINE,t); /* See note 1 in track.c */ } else { np=track2(offset,t->otherValues.spline.plist[d-1], t->otherValues.spline.plist[d+1], t->otherValues.spline.plist[d]); } xspline(offset,t->otherValues.spline.plist,u); t->otherValues.spline.plist[d]=np; t->origin=t->otherValues.spline.plist[1]; break; } } /* end switch */ boundingBox(t); if( eqpt(t->bb.origin,t->bb.corner) ) { /* edit thing has no size so remove it */ t = deleteThing(t); thingSelected = 0; changeBrush(-1); changeButtons( INITbuttons ); initMessage(); } else { switch (t->type) { case TEXT: case CIRCLE: case ARC: case ELLIPSE: { break; } default: { draw(t,offset); break; } } } } return( t ); } struct thing * copyThing(t,p,offset,drawit) register struct thing *t; /* Thing to be copied. */ Point p; /* Relative location of things bb */ Point offset; /* Absolute location of bb. Used */ /* only top draw the figure. */ int drawit; /* Draw thing if nonzero */ { register struct thing *c; Point *pl; int i, n; if (t != TNULL) { switch(t->type) { case CIRCLE: { if ((c = newCircle(p)) != TNULL) { c->otherValues.radius = t->otherValues.radius; } break; } case BOX: { if ((c=newBox(Rpt(p,add(p,sub(t->bb.corner,t->origin))))) != TNULL) { c->border = t->border; } break; } case ELLIPSE: { if ((c = newEllipse(p)) != TNULL) { c->otherValues = t->otherValues; } break; } case LINE: { if ((c = newLine(p,add(p,sub(t->otherValues.end,t->origin)))) != TNULL) { c->border = t->border; c->arrow = t->arrow; } break; } case ARC: { c = newArc(p,add(p, sub(t->otherValues.arc.end, t->otherValues.arc.start))); c->origin = add (t->origin, sub (p, t->otherValues.arc.start)); /* This is needed because newArc */ /* will compute the wrong origin */ /* sometimes. */ break; } case SPLINE: { n = t->otherValues.spline.used; c = TNULL; if ((pl = (Point *) getSpace ((n+2)*sizeof(Point))) != (Point *)NULL){ p = sub(p, t->origin); for (i=1; i<=n; i++) { pl[i]=add(p,t->otherValues.spline.plist[i]); } if ((c = newSpline(n,n,pl)) != TNULL) { c->arrow = t->arrow; } } break; } case TEXT: { if ((c = newText(p,t->otherValues.text.s)) != TNULL) { c->otherValues.text.f = t->otherValues.text.f; c->otherValues.text.just = t->otherValues.text.just; c->otherValues.text.spacing = t->otherValues.text.spacing; if ((c->otherValues.text.s = getSpace (strlen (t->otherValues.text.s) + 1 )) != NULL) { strcpy (c->otherValues.text.s, t->otherValues.text.s); } else { free (c); c = TNULL; } } break; } case MACRO: { c = newMacro(p,t->otherValues.list); break; } } if (c == TNULL) { return (c); } boundingBox(c); if (drawit) { draw(c,offset); } return(c); } else { return(t); } } /* Returns the index of the point, in plist p, closest to point */ /* given by o. */ int findNearestPoint(o,p,n) register Point *p; /* Plist of spline points */ int n; /* Number of points in Plist */ Point o; /* Mouse location */ { register int i; int f; /* Plist index to point closest to o */ int d; /* Distance between point and o */ int mind = -1; /* Minimum distance */ if (p != (Point *) NULL) { for (i=1; i<=n; i++) { d = norm(o.x-p[i].x, o.y-p[i].y, 0); if ((mind<0) || (mind>d)) { mind = d; f = i; } } return(f); } else { return(-1); } } xcip/xcip.10000644000175300001440000004752711513632542011412 0ustar meusers.if \nZ \{\ .TH XCIP 1 EXPTOOLS\} .if !\nZ \{\ .TH CIP 1 TOOLCHEST\} .SH NAME .if \nZ \{\ xcip\} .if !\nZ \{\ cip\} \- interactive object-based drawing system based on pic for DMD 5620, MTG 630/730, X-window terminals and Sun workstations. .SH SYNOPSIS .if \nZ \{\ \fBxcip\fP\} .if !\nZ \{\ \fBcip\fP\} [\fB-v\fP] [-t dmd|mtg|sun|x] [X-window options] .SH DESCRIPTION .if \nZ \{\ Note: .I xcip is the exptools version of the .I cip program. From here on in this man page when you see .IR cip , read it as .IR xcip . .P\} .I Cip is an interactive drawing system for AT&T Teletype's DMD 5620 and MTG 630/730 bitmap display terminals. It will also work on X-window systems such as Sun workstations running Openwin and 730X terminals. .P Using a set of predefined .IR pic (1) shapes, the user draws and edits objects to construct pictures on the screen of the terminal. These pictures can be stored in a file and later formatted for output to a typesetter using .IR pic (1) and .IR troff (1). .P If the .B -v option is used, the versions of .I cip and the host program .I jpic are printed (and the editor is not brought up). .P The .I cip shell script trys to load the appropriate version of .I cip depending on whether your terminal is a 5620, 630/730 or X-window system. This can be specified explicitly by using the optional .B -t parameter. .P For X-window systems, options such as .B -rv for reverse video and .B -geometry to specify window geometry and placement can be used. For example, to place the .I cip window in upper left hand corner use: .B -g +0+0 .P For the 630 MTG, the .I cip program is automatically saved .I (cached) in the terminal's RAM memory. The next invocation of .I cip will bring up the program quickly without having to download it. To remove .I cip from the terminal's memory without having to power it down use the 630 MTG .I ucache(1) program. .SH SETUP If you are using a 5620, 630 or 730 terminal, you must have the environment variable .B DMD set to the appropriate DMD software directory (and exported). For the DMD 5620 terminal, this must be the DMD 2.0 SGS. (If the old version is used, you will get hundreds of multiply defined messages when .I cip is invoked.) For Computation Center machines this is typically: .PP DMD=/usr/add-on/dmd2.0 (for DMD 5620) .PP DMD=/usr/add-on/630 (for 630 MTG) .PP Make certain you have the exptools bin and $(DMD)/bin on your path. .SH WINDOWS For 5620, 630 or 730 terminals, create a small window and invoke .I cip in it. (The first \fIlayers\fR window receives system messages and thus is not available for .IR cip .) After .I cip downloads, a menu will be available on mouse button 3 to open the editor window. .P The .I cip editor window consists of five areas. The topmost area contains 7 buttons, one for each shape available for drawing (i.e., circle, box, ellipse, line, arc, spline and text). The large middle area is used for drawing and editing pictures. At the bottom are three areas: the leftmost shows information, error messages and file names; the middle area will show a button when editting a macro (click on button to leave macro edit mode); and the rightmost shows the mouse button functions currently available. .SH MOUSE The mouse is used for selection of all menu items, selection of shapes, and editing of objects in the picture area. Button one is usually used to select a shape or an object, button two is used to edit a selected object, and button three displays a menu which is applicable to the current state of .I cip. .TP .B "Button 1" Select a shape to draw with by clicking mouse button 1 on the desired shape button in the top area. The shape can then be used to draw an object in the picture area (see Button 2). .sp If mouse button one is pressed while in the picture area then an enclosing object is selected for editing. In case of overlapping objects, repeated pressings of button one will run through the possibilities. The object selected is blanked out as long as button one is pressed. If the object is text, then an edit marker (an upward pointing triangle) can be placed within the text by moving the mouse .B while holding button 1 down. If there is no object on the screen or if the mouse cursor is far enough away from all objects, then clicking button 1 returns .I cip to its original nothing-selected state. .sp Pressing mouse button one on the \fIedit depth\fP button at the bottom of the screen (shown only when editing macros) exits one level of macro editing. .TP .B "Button 2" Mouse button two is only active when either an object or a shape has been selected. If a shape is selected, button two is used for drawing objects in the picture area. If an object is selected, button two is used for either moving the object or changing its shape, depending on whether the object was selected (via button one) near its center or near its edge, respectively. .TP .B "Button 3" Mouse button three is used to provide a menu of operations that is either of a general nature or specific to a selected shape or object. .IP The general menu is brought up by pressing button three when no object nor shape has been selected and provides the following operations: .TP 15 .I "Get file" Read a file (in restricted .I pic format), adding its contents to the screen. The user is first prompted for a file path name. Once the global file definitions have been read, a rectangle will appear on the screen showing the overall size of the file to be read. Clicking button one brings the picture in centered in the screen (but aligned to grid points). Alternatively, the picture may be moved to a new location by depressing button two. .TP .I "Put file" Writes the screen's contents into a file in .I pic format. Again, the user is prompted for a file path name. If the file already exists, it is copied to the user's home directory under the file name: .I cip.backup. .TP .I "Clear screen" Clear screen, removing the diagram from the editor. This function asks if you are sure, requiring a confirming click of button three or an aborting click of button one or two. .TP .I "Redraw screen" Removes any garbage on screen that may result from interactions with other windows. .TP .I "Define macro" A very useful function for grouping objects into a new entity. Button 2 is used to draw a box around objects to be included in a "macro" in the pic terminology. .TP .I "Undo" Undoes the last operation on an object. A second undo immediately following the first returns the object to its changed state. .TP .I "Show grid" Display (or turn off) a grid (via a secondary menu to the right of the main menu). The user can select the distance between grid points. The user can set the grid distance to follow changes in alignment, or the user can force the grid to a specific size independent of the alignment setting. The range of sizes available in the forced grid mode starts at 4 by 4 and goes up to 16 by 16. .sp If the user has set the grid to follow the alignment, the grid will be redrawn when the user changes the alignment. If in this mode, the user chooses an alignment finer than 4 by 4, the grid will be removed because a grid smaller than 4 by 4 is so small that it is not useful. When the alignment is increased to a larger value of at least 4 by 4 the grid will be restored. .sp If the user has set the grid to a size independent of the alignment setting, the grid will remain on the screen in the size selected no matter what the alignment is subsequently set to. .TP .I "Alignment" Whenever objects are drawn or edited, the coordinates of the objects are forced to be aligned to an imaginary set of grid points. The granularity of this imaginary grid is selected via a secondary menu to the right of the main menu. The choices are any number between 1 and 16. .sp This imaginary grid is independent of the grid that the user can display using the "Show Grid" menu item. The displayed grid can be set to track alignment changes or to remain at a fixed value independent of alignment changes. The preceding section on grid controls explains how the grid operates. .sp The smaller the alignment selected, the more freedom the user will have in placing objects. Using a larger alignment size helps keep symbols lined up with each other. The default alignment size corresponds to an 8 by 8 grid. .sp From the point of view of alignment, it is important to understand that objects always snap to an imaginary grid based on the current alignment setting. Since the displayed grid setting does not have to match the alignment setting, drawn objects will snap to the displayed grid only if the two settings match. .sp To allow for more flexibility in placing text, text objects are allowed to be placed at an alignment value which is about half the current alignment setting. So if the alignment is set to 8, text objects can be placed in 4 pixel increments. .sp When a file is read in via the "Get File" menu command, the objects in that file are placed at the coordinates specified in the file without any regard to the current alignment settings. If the file was originally created with a different alignment setting than that which is currently in use, the objects that are loaded in may not line up properly with the newly drawn objects. .TP .I "Information" Prints remaining memory available in the DMD & MTG terminal and the UNIX directory from which .I cip was down-loaded. .TP .I "Version" Prints the .I cip version. .TP .I "Display Scale" When an object is being drawn or a previously drawn object is selected and is being edited, information about that object is displayed in the message window. This information includes the type of object, the pixel coordinates of the interesting parts of the object, and the height, width, length, diameter, or radius of the object, as appropriate. .sp This secondary menu to the right of the main menu allows the user to control how the height, width, length, diameter, or radius value is displayed. There are two things that can be controlled: (1) the numeric part of the display can be scaled down by a scale factor, and (2) one of several labels representing common units of measurement can be displayed after the number. .sp These two things can be turned on separately or together. The scale factor used to scale the pixel dimensions down can be changed independently of the label that is displayed. .sp For example, if the user has selected a line object that happens to be 104 pixels long, the message window would normally say: .sp 0.25 Line: length=104 .sp 0.25 If the user turns on the scale factor feature and sets the scale factor to 10, the display now shows: .sp 0.25 Line: length=10.4 .sp 0.25 The dimension to be printed is divided by the scale factor before printing. The number of digits printed after the decimal point is determined by the size of the scale factor. Scale factors between 1 and 10, inclusive, get one digit after the decimal point. Scale factors greater than 10 but less than or equal to 100 get two digits, and any scale factor greater than 100 gets three digits. .sp The label part of this facility allows the user to have one of several possible labels appended to the number printed. The choices are: .nf .ta 0.5i 2i inches (displayed as " ) feet and inches (displayed as ' " ) feet (displayed as ' ) yards (displayed as yd. ) miles (displayed as mi. ) millimeters (displayed as mm ) meters (displayed as m ) kilometers (displayed as km ) .ta 0.5i .fi .sp Using the same values from our first example, if the label was set to miles, the message window would say: .sp 0.25 Line: length=104 mi. .sp 0.25 The way that this operates is for the most part very straightforward. The only confusing one is "feet and inches". .sp When the option "feet and inches" is chosen, the units of the dimension are taken to be inches, but before it is displayed the dimension value is divided by 12 to find the number of feet. The remainer from this division is the number of inches. Using our same example, 104 inches is eight feet and eight inches, so the message window now would say: .sp 0.25 Line: length=8'8" .sp 0.25 If a scale factor is set it is applied to the dimension value before it is divided by twelve, and the extra decimal points are displayed with the inches. So, for the same example, this time with a scale factor of 5, we get: .sp 0.25 Line: length=1'8.8" .sp 0.25 ( Because 104 inches divided by 5 is 20.8 inches. Divide 20.8 by 12 we get one foot with a remainder of 8.8 inches.) .sp This feature, feet and inches, can be really interesting when used with scale factor 1, an alignment of 1, and a grid forced to 12. You can move objects in one inch increments, see grid lines every foot, and your dimensions are shown in feet and inches. You have a drawing area that is about 58 feet square. .TP .I "Close window" Returns to the layer window initially used when .I cip was downloaded. The current picture is saved - re-opening the editor window will redraw the picture. The option .I "Quit editor" is available in the closed window menu to leave .IR cip . WARNING: the .I "Quit editor" option does .B not check if the current diagram has been written out! .PP .TP .sp 1 .B " " If the box, line, spline, or text shape is selected, button three brings up a menu used to set global defaults. .TP 15 .I "Arrows" Sets whether lines and splines drawn in the future will have \fINo arrows\fR or arrows at the \fIStart end, Finish end\fR or \fIBoth ends\fR; via a secondary menu to the right of the main menu. .TP .I "Density" Sets line density of lines and boxes to either \fISolid\fP, \fIDashed\fP, or \fIDotted\fP. .TP .I "Point size" Sets point size for text; via a secondary menu to the right of the main menu. This includes all point sizes supported on the DMD 5620 and 630 MTG. Note, however, that your particular printer may not support all of these. .TP .I "Font style" Sets style of text. Includes all font styles supported on the DMD 5620 and 630 MTG. Again, your particular printer may not support all of these. .TP .I "Justify" Sets text justification to \fILeft, Center,\fR or \fIRight\fR. .TP .I "Spacing" Sets spacing between text lines in multi-line text. .PP .TP .sp 1 .B " " If an object in the picture area is selected, depressing button three displays a menu allowing reasonable operations on the selected object. Common operations are: .TP 15 .I "Delete" Deletes selected object. .TP .I "Copy" Copies selected object. Use button 2 to place the new object. If the object is a macro, the copied objects all share the same macro definition. That is, if you edit a macro, all other copies of that macro will be updated also. .TP .I "Reflect x" Reflect around the x-axis. .TP .I "Reflect y" Reflect around the y-axis. .TP .I "Arrow" Place an arrow on (or remove an arrow from) the nearest end of the line or spline selected. .TP .I "Density" Adjust the density of a line or box via a secondary menu to the right of the main menu. .TP .I "Edit" Edit components of a selected macro. Exit edit mode by selecting the \fIedit depth\fP window in the middle area at the bottom of screen. .TP .I "Separate" Separate a macro into component parts or multi-line text into separate single lines. Warning: currently there is no way to combine separate single lines of text into a single multi-line text. .SH KEYBOARD The keyboard is used to enter and edit text in the picture. The following commands (which are a subset of emacs commands with some extensions) are available: .PD 0.2v .TP 15 .I "CNTL-A" Move to start of line. .TP .I "CNTL-B" Move back one character. .TP .I "CNTL-C" Capitalize next character. .TP .I "CNTL-D" Delete next character. .TP .I "CNTL-E" End of line. .TP .I "CNTL-F" Forward one character. .TP .I "CNTL-H" Delete previous character. .TP .I "CNTL-K" Kill text after the cursor. .TP .I "CNTL-U" Delete all previous text. .TP .I "CNTL-W" Delete previous word. .TP .I "CNTL-Y" Retrieve last deletion. .TP .I "Return" Create new line. .TP .I "ESC b" Move back one word. .TP .I "ESC d" Delete next word. .TP .I "ESC CNTL-H" Delete previous word. .TP .I "ESC f" Move forward one word. .TP .I "ESC " Repeat "n" times the command "cmd". .PD .P The text mode is left by clicking a mouse button. Note: The character sequence \\(xx will not be printed: instead it will be interpreted by troff (for example, use \\(bu for bullets). .P The keyboard is also used to enter and edit file names. In this case, entering an Escape or Return character, or clicking a mouse button, will leave this text mode. .P The last file name is retained by the editor between operations. This is to facilitate frequent writes to keep the host updated as a new file is being entered. However, care must be taken to backspace over or delete the original name and enter a new one when it is desired to leave the original file intact. .SH PRINTING DIAGRAMS Diagrams can be printed on any printer that supports .IR troff (1). The shell .IR ciprint (exptools-1) provides a convenient command to print cip-generated pic files on either the Xerox, the Imagen or Postscript printer. .P The diagrams can also be included in documents by using the following: .P .nf \.DS CB \.PS < pic-file-name \.DE .fi .P If the diagram has splines, make sure that the character "~" is not redefined. For example, a common line in the front of documents is: .P .nf \.tr ~ .fi .P This operation must be canceled before the pic file containing splines by issuing: .P .nf \.tr ~~ .fi .if \nZ \{\ .P The pic(1) command must be run before the troff(1) command. Look at the ciprint(exptools-1) shell for an example command sequence and parameters. The .IR exmmx (exptools-1) shell is a convenient command for printing documents containing pic on Xerox. .SH FILES .ta 2i .br bin/xcip shell script for executing .I xcip .br lib/dmd/xcip.m DMD 5620 .I xcip program .br lib/dmd/xcip.m 630/730 MTG .I xcip program .br lib/x/xcip X-window .I xcip program .br bin/xjpic program used by .I xcip to parse pic files\} .SH SEE ALSO .I "Cip User's Manual: One picture is Worth a Thousand Words," Sally A. Browning, TM-82-11276-1. .br pic(1), troff(1), proof(dmd-1) & ucache(dmd-1). .SH WARNINGS We recommend that DMD 5620 terminals have 1 Meg RAM memory so that there will be sufficient space to hold your pictures. MTG 630/730 need more than the minimum 640K memory. Either add the 512K memory board or a Starlan-10 card with 2 or 4 Meg RAM. For the MTG 730+ terminal, just add 2 or 4 of standard 1 Meg SIMMs. .PP On VAXes, do not use a large path name (greater than about 50 characters) on put file as it will cause .I cip to abort! .PP Defining pictures which are too large for the picture frame can have disastrous results when stored and read back. .PP .I Cip relies on the host machine only for file transfers. If the host crashes while you are creating or modifying a picture, there will be no way to save the picture. .B Frequent stores are recommended. .PP The size of your text shown will not necessarily be the same when printed as printers vary. Moral: leave plenty of room for your text. .PP The vertical bar character ("|") in multi-line text strings or in any text string inside a macro can not be read in. .PP .I Cip can not read in an arbitrary pic file since pic has features not supported in the graphical editor. .PP There are numerous fixed limits in the host program, .IR jpic , used in reading a pic file into .I cip. Thus it is quite possible to create and write out a diagram that can not be read back in. To discover why a file can not be read by .I cip do: "jpic .I your-file > temp". The standard error messages, if any, will report where the problem exists. .PP Objects are drawn on the screen using XOR mode. This means that two identical objects placed on top of each other will not appear on the screen. However, the object will be printed. .SH UNEXPECTED BEHAVIOR .PP Rectangles drawn with odd (eg. 1, 3, 5, ...) alignment values tend to crawl around the page when the file is written and later re-read by .IR cip . All other object types work well at any alignment value. Using only even alignment values when drawing rectangles is recommended as a temporary workaround. xcip/space.c0000644000175300001440000000511111513632544011605 0ustar meusers/* MEMORY SPACE ROUTINES */ #include "cip.h" extern short noSpace; #ifdef DMDTERM #ifdef DMD5620 # include "setup.h" #endif #ifdef DMD630 typedef struct aheader { struct aheader * next; long * proc; } aheader; #undef BUSY #define BUSY 3l #define testbusy(p) ((long)p & BUSY) #define clearbusy(p) (aheader *)((long)p & ~BUSY) #endif #ifdef DMD5620 #include #undef spl7 #undef splx #include typedef union aheader { struct { union aheader * Uptr; char * Uproc; } u; union aheader * next; int dummy[1]; int calloc; /* calloc clears an array of integers */ } aheader; #undef BUSY #define BUSY 1 #define testbusy(p) ((long)(p)&BUSY) #define clearbusy(p) (aheader *)((long)(p)&~BUSY) #endif #ifdef DMD630 #undef min #define min(A,B) ((A) < (B) ? (A) : (B)) #endif extern Point PointCurr; extern Texture16 textCursor; extern int backspaceOneWord(); long spaceLeft() { #ifdef DMD5620 register long sum; register aheader * p; register aheader * q; static aheader * startp; static aheader * endp = (aheader *)0; if (!endp) { /* Make calculations just once. */ startp = (aheader *) ((int *)Sys[163]); endp = (aheader *) (( (maxaddr[VALMAXADDR] + (int)Sys[163]) / 2) & 0xfffffffc ); } sum = (long) endp - (long) startp; p = startp; q = clearbusy(p->next); while( p < q ) { if( testbusy(p->next) ) { sum -= (long) q - (long) p; } p = q; q = clearbusy(p->next); } return sum; #endif #ifdef DMD630 register long sum; register aheader * p; register aheader * q; /* Calculate total available alloc space which includes the space above the alloclevel up to the either gclevel or alloclimit, which ever is lower. One could do a "gccompact()" to get more alloc space, but not necessary here. */ sum = min( (long)gclevel , (long)alloclimit ) - (long) memstartp; /* Run through memory blocks in alloc space subtracting from "sum" those that are currently busy. */ for( p = (aheader*)memstartp; p <= (aheader*)alloclevel; p = q ) { q = clearbusy(p->next); if( testbusy(p->next) ) sum -= (long) q - (long) p; } return sum; #endif } #endif /* DMDTERM */ /* This routine allocates memory. */ char * getSpace (numbytes) int numbytes; { char *b; /* Pointer to allocated memory */ if (numbytes < 8) numbytes = 8; if ((b = alloc (numbytes)) == (char *) NULL) { outOfSpace (); return (b); } return (b); } /* This routine prints an error message telling the user xcip is out of space.*/ outOfSpace() { newMessage("Out of Storage - PUT and QUIT"); sleep(240); noSpace = 1; } xcip/cip.h0000644000175300001440000002513011513632542011273 0ustar meusers/* C I P H E A D E R Terminals supported: DMD 5620 "DMD5620" and "DMDTERM" defined DMD 630/730 "DMD630" and "DMDTERM" defined X-window "X11" defined Note: thanks to Dave Kapilow for the X-window emulator package and David Wexelblat for doing most of the port to X. */ #ifdef DMD5620 # define DMDTERM # define MPXTERM # include # include # include # include # define CHAR_EOF 0xff # define stipple # define clearRegion(r) stipple(r) #endif #ifdef DMD630 # define DMDTERM # define MPXTERM # include # include # include # include # include <5620.h> # include # define texture16 texture # define Texture Texture16 # define CHAR_EOF (-1) # define clearRegion(r) rectf( P->layer, r, F_CLR ) #endif #ifdef DMDTERM # define fontheight(f) ((f)->height) # define fontwidth(f,c) ((f)->info[(c)].width) # define Cursor Texture16 #endif #ifdef X11 # include # include # define CORRECTSIZE 1 # define Texture16 Texture # define CHAR_EOF EOF # define clearRegion(r) rectf( &display, r, F_CLR ) #endif #define C_RESHAPE 8 #ifdef DMDTERM # define CORRECTSIZE sameSizeRect( P->layer->rect,\ inset(Rect(Xmin,Ymin,Xmax,Ymax),-BORDER) ) #endif #define BOOL int #define TRUE 1 #define FALSE 0 #ifdef DMD630 # define max(A, B) ((A) > (B) ? (A) : (B)) # define min(A, B) ((A) < (B) ? (A) : (B)) #endif #ifndef abs # define abs(A) ((A)<0 ? -(A) : (A)) #endif #define distance(p,q) norm(q.x-p.x , q.y-p.y , 0 ) #define isletter(C) (((C)>='a' && (C)<='z') || ((C)>='A' && (C)<='Z')) #define isdigit(C) ((C)>='0' && (C)<='9') #define MOUSE_XY (sub(mouse.xy, Pt(1,1))) #ifdef X11 # define Xmin BORDER /* left edge of frame */ # define Ymin BORDER /* top edge of frame */ #else extern short Xmin; /* left edge of frame. */ extern short Ymin; /* top edge of frame. */ #endif /* X11 */ extern Point drawOffset; /* Offset into drawing frame. */ extern Point scrollOffset; /* Offset into drawing frame from scrolling. */ #define LEFTMOST 12 /* Leftmost origin of window. */ #define TOPMOST 12 #define BOTTOMMOST 25 /* Bottommost origin of window. */ #define BOTTOMY 1024 /* Maximum Y on screen */ #ifdef DMD630 # define RIGHTMOST 238 /* Rightmost origin of window. */ # define RIGHTX 1024 /* Maximum X on screen */ #endif #ifdef DMD5620 # define RIGHTMOST 12 /* ???? */ # define RIGHTX 800 /* Maximum X on screen */ #endif #define BORDER 6 #define BrushSize 60 /* Height of brush frame */ #define ButSize 60 /* Height of button frame */ #define LW 2 /* line width for frame boxes */ #define MW 5 /* Margin width between frames*/ #define DefaultXPicSize 770 /* Default width of Pic frame */ #define DefaultYPicSize 840 /* Default height of Pic frame */ #ifdef X11 # define Xmax (Drect.corner.x - BORDER)/* right edge of frame */ # define XPicSize (Drect.corner.x - 2 * (LW + BORDER)) /* Width of Pic frame */ # define Ymax (Drect.corner.y - BORDER)/* left edge of frame */ # define YBR (Ymin+LW+MW+BrushSize+LW)/* y distance of brush frame */ # define YPIC (YBR+2*MW) /* top of drawing frame */ # define Ybut (Ymax - ButSize - 2 * LW)/* Top of button frame */ # define YBOT (Ybut - MW) /* bottom of drawing frame */ # define YPicSize (YBOT - YPIC) /* Height of Pic frame */ # define YCEN ((YBR+Ymin)>>1) /* center line of brush area */ # define Xbut (((Xmax-Xmin)<<1)/3) # define XeditD ((Xmax-Xmin)/2) /* reverse the calculations above to find total width and height */ # define DefaultWidth (DefaultXPicSize + 2 * (LW + BORDER)) # define DefaultHeight (DefaultYPicSize + YPIC + ButSize + (2 * LW) + MW + BORDER) #else /* X11 */ # define XPicSize DefaultXPicSize /* Width of Pic frame */ # define YPicSize DefaultYPicSize /* Height of Pic frame */ # define Xmax (Xmin+XFM) /* right edge of frame */ # define YBR (LW+MW+BrushSize+LW) /* y distance of brush frame */ # define YPIC (Ymin+YBR+MW) /* top of drawing frame */ # define YBOT (YPIC+LW+YPicSize+LW) /* bottom of drawing frame */ # define Ybut (YBOT+MW) /* Top of button frame */ # define Ymax (Ybut+LW+ButSize+LW) /* bottom of frame */ # define YCEN (Ymin+(YBR/2)) /* center line of brush area */ # define Xbut (((XFM*2)/3)-LEFTMOST+Xmin) # define XeditD ((XFM/2)-LEFTMOST+Xmin) #endif /* X11 */ #define XFM (LW+XPicSize+LW) /* x distance of frame */ #define Xtext (Xmin+LW) #define Ytext (Ybut+ButSize/6) #define butHt min(((ButSize-(LW<<2))/3), ((Xmax-Xbut-(3*LW))/18)) #define INSET 4 /* Number of bits in border of selected window. */ #define MSGXMIN (Xmin+INSET+2) /* Message area - X-axis minimum. */ #define MSGYMIN (YBOT+LW+6) /* Message area - Y-axis minimum. */ #define MSGXMAX (XeditD-LW-2) /* Message area - X-axis maximum. */ #define MSGYMAX (Ymax-INSET-1) /* Message area - Y-axis maximum. */ #define TNULL (struct thing *)0 #define MNULL (struct macro *)0 #define CIRCLE 0 #define BOX 1 #define ELLIPSE 2 #define LINE 3 #define ARC 4 #define SPLINE 5 #define TEXT 6 #define MACRO 7 #define NUMBR 7 #define DXBR (XFM/NUMBR) #define MAXTEXT 2000 #define MAXNAMESIZE 256 #define PIC NUMBR #define ED PIC+1 #define BRUSH PIC+1 #define GROWCIRCLE BRUSH+1 #define MOVE BRUSH+2 #define GROWEWID BRUSH+3 #define GROWEHT BRUSH+4 #define REVSPLINE BRUSH+5 #define REVLINE BRUSH+6 #define RADdefault (XFM/24) #define WIDdefault (XFM/8) #define HTdefault (XFM/12) #define nearEDGE 3 #define SOLID 0 #define DASHED 1 #define DOTTED 2 #define startARROW 1 #define endARROW 2 #define doubleARROW 3 #define ROMAN 1 #define ITALIC 2 #define BOLD 3 #define HELVETICA 4 #define HI 5 #define HB 6 #define PALATINO 7 #define PI 8 #define PB 9 #define EXPANDED 10 #define EI 11 #define EB 12 #define CONSTANTWIDTH 13 #define DEFONT 14 #define LEFTJUST 0 #define CENTER 1 #define RIGHTJUST 2 #define POINTSIZE 10 #define INITtextOutName 100 extern int textOutName; #define GRIDoff 0 #define GRIDon 1 #define WHITEfield 1 #define BLACKfield 0 #define INITbuttons 0 #define MENUbuttons 1 #define DRAWbuttons 2 #define EDITbuttons 3 #define SPLINEbuttons 4 #define BLANKbuttons 5 #define MACRObuttons 6 #define COPYbuttons 7 #define MOVEbuttons 8 #define QUITbuttons 9 #define READbuttons 10 #define EXITbuttons 11 #define GLOBbuttons 12 #define DObuttons 13 #define numButtonStates 14 #define HELPSCALE #ifdef HELPSCALE /* * The order and value of these defines must be kept in sync * with the menu entries in the Scale Menu in menus.c . */ #define SCALE_NONE 0 #define SCALE_FACTOR_ONLY 1 #define SCALE_LABEL_ONLY 2 #define SCALE_BOTH 3 #define SCALE_SET_FACTOR 4 #define SCALE_SET_LABEL 5 #define LABEL_NONE 0 #define LABEL_IN 1 #define LABEL_FT_IN 2 #define LABEL_FT 3 #define LABEL_YD 4 #define LABEL_MI 5 #define LABEL_MM 6 #define LABEL_METERS 7 #define LABEL_KM 8 #endif /* HELPSCALE */ #define fontBlk struct FONTBlk struct FONTBlk { short ps; /* Point size */ short num; /* Font style, e.g. ROMAN */ short useCount; Font * f; fontBlk * next; fontBlk * last; }; typedef struct { Point start, end; } pointPair; typedef struct { short ht, wid; } intPair; typedef struct { short used; short size; Point * plist; } pointStream; typedef struct { short just; /* left, center or right */ short spacing; /* 0 = normal spacing */ char * s; fontBlk * f; short outName; } textString; extern short maxTextId; struct macro { char * name; /* If generated macro: 'm' + id. */ short id; /* If generated macro: its number. */ short useCount; Rectangle bb; struct thing * parts; struct macro * next; }; struct thing { short type; Point origin; Rectangle bb; union { short brush; short radius; Point corner; Point end; pointPair arc; intPair ellipse; textString text; pointStream spline; struct macro * list; } otherValues; short arrow; short border; struct thing * next; struct thing * last; }; extern fontBlk *fonts; extern Rectangle *Select(); extern Rectangle moveBox(); extern Rectangle macroBB(); extern struct macro * findMacro(); extern int uniqMacroId(); extern short newMacroId(); extern BOOL cmpMacroParts(); extern struct macro * recordMacro(); #ifndef DMD5620 extern Rectangle canon(); #endif extern struct thing * newCircle(); extern struct thing * newBox(); extern struct thing * newEllipse(); extern struct thing * newLine(); extern struct thing * newArc(); extern struct thing * newText(); extern struct thing * newSpline(); extern struct thing * newMacro(); extern BOOL cmpThings(); extern struct thing * selectThing(); extern struct thing * copyThing(); extern struct thing * deleteThing(); extern struct thing * deleteAllThings(); extern struct thing * insert(); extern struct thing * dummy_insert(); extern struct thing * Remove(); extern struct thing * doMouseButtons(); extern struct thing * place(); extern struct thing * displayCommandMenu(); extern struct thing * displayThingMenu(); extern struct thing * doGet(); extern struct thing * doClear(); extern struct thing * defineMacro(); extern struct thing * makeRelative(); extern struct thing * reflect(); extern Point track(); extern Point track2(); extern Point trackMacro(); extern Point computeArcOrigin(); extern Point jchar(); extern void initMessage(); extern void moreMessage(); extern void newMessage(); extern Point align(); extern Point alignUp(); extern Point alignDown(); extern int alignInt(); extern char *getString(); extern char *getSpace(); extern FILE *popen(); extern fontBlk *findFont(); extern xtipple (); extern char * addBackslashes(); #define FINEALIGN #ifdef FINEALIGN extern short currGridsize; #endif #ifdef HELPSCALE extern short currScaleType; extern short currScaleFactor; extern short currLabelType; #endif extern short currAlignment; extern short currPS; extern short currFont; extern short currJust; extern short currLineType; extern short currBoxType; extern short currLineArrows; extern short currSplineArrows; extern short currSpacing; extern struct thing * firstThing; #ifdef X11 # define CW ave_fontwid(&defont) # define NS fontheight(&defont) extern void initGraphics(); extern Rectangle clip_rect; #endif extern Cursor crossHairs; extern Cursor hourglass; extern Cursor rusure; extern Cursor textCursor; extern Texture grid; extern Texture grid8; #ifdef FINEALIGN extern Texture fineGrid; #endif #ifdef X11 extern Texture copyright; extern Texture lowerTriangle; extern Texture upperTriangle; extern Bitmap markerbm; extern Bitmap markermaskbm; extern Bitmap bgsave; #else extern Texture16 copyright; extern Texture16 lowerTriangle; extern Texture16 upperTriangle; #endif xcip/icons.c0000644000175300001440000001061111513632540011622 0ustar meusers/* Define all textures, cursors and bitmaps here. */ /* */ /* For X11, these must be sent to the X server. */ #include "cip.h" /**** crossHair cursor ****/ #ifdef X11 Cursor crossHairs; unsigned short crossHairs_bits[] = { #else Texture16 crossHairs = { #endif 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0000, 0xFC7E, 0x0000, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0000, }; /**** hourglass cursor ****/ #ifdef X11 Cursor hourglass; unsigned short hourglass_bits[] = { #else Texture16 hourglass = { #endif 0x7FFE, 0x7FFE, 0x2814, 0x2814, 0x27E4, 0x27E4, 0x23C4, 0x2184, 0x2184, 0x2244, 0x24A4, 0x2424, 0x2894, 0x29D4, 0x7FFE, 0x7FFE, }; /**** rusure cursor ****/ #ifdef X11 Cursor rusure; unsigned short rusure_bits[] = { #else Texture16 rusure = { #endif 0X0000, 0X0EA0, 0X0AA0, 0X08A0, 0X08A0, 0X08E0, 0X0000, 0X0000, 0XEAEE, 0X8AAA, 0XEA8E, 0X2A88, 0XEE8E, 0X0000, 0X0000, 0X0000, }; /**** textCursor cursor ****/ #ifdef X11 Cursor textCursor; unsigned short textCursor_bits[] = { #else Texture16 textCursor = { #endif 0x0000, 0x0000, 0x0000, 0xEE97, 0x4892, 0x4862, 0x4C62, 0x4C62, 0x4862, 0x4892, 0x4E92, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; /**** grid texture ****/ #ifdef X11 Texture grid; unsigned short grid_bits[] = { 0,0,0,0,0,0x0200,0,0, 0,0,0,0,0,0,0,0 }; #else Texture grid; #endif /**** grid8 texture ****/ #ifdef X11 Texture grid8; unsigned short grid8_bits[] = {0,0,0,0,0,0x0202,0,0,0,0,0,0,0,0x0202,0,0}; #else Texture grid8; #endif #ifdef FINEALIGN /**** fineGrid texture ****/ #ifdef X11 Texture fineGrid; unsigned short fineGrid_bits[] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; #else Texture fineGrid; #endif /* X11 */ #endif /* FINEALIGN */ /**** copyright icon ****/ #ifdef X11 Texture copyright; unsigned short copyright_bits[] = { #else Texture16 copyright = { #endif 0x0000, 0x0380, 0x0C60, 0x1010, 0x2388, 0x2448, 0x4404, 0x4404, 0x4404, 0x2448, 0x2388, 0x1010, 0x0C60, 0x0380, 0x0000, 0x0000, }; /**** lowerTriangle icon ****/ #ifdef X11 Texture lowerTriangle; unsigned short lowerTriangle_bits[] = { #else Texture16 lowerTriangle = { #endif 0x8000, 0xC000, 0xE000, 0xF000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; /**** upperTriangle icon ****/ #ifdef X11 Texture upperTriangle; unsigned short upperTriangle_bits[] = { #else Texture16 upperTriangle = { #endif 0xF000, 0x7000, 0x3000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; /**** Markerbm & markermaskbm icon ****/ /* Note: for DMDs, a different approach is used. */ #ifdef X11 Bitmap markerbm; unsigned short marker_bits[] = { /* marker icon */ 0x0000, 0x0000, 0x0000, 0x0080, 0x0080, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0FF8, 0x0FF8, 0x0FF8, 0x0FF8, 0x0000, }; Bitmap markermaskbm; unsigned short markerMask_bits[] = { /* one bit bigger marker icon */ 0x0000, 0x0000, 0x0080, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0FF8, 0x0FF8, 0x1FFC, 0x1FFC, 0x1FFC, 0x1FFC, 0x1FFC, }; Bitmap bgsave; unsigned short plain_bits[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #endif #ifdef X11 void initGraphics() { crossHairs = ToCursor((short *)crossHairs_bits, (short *)crossHairs_bits, 7, 7); hourglass = ToCursor((short *)hourglass_bits, (short *)hourglass_bits, 7, 7); rusure = ToCursor((short *)rusure_bits, (short *)rusure_bits, 7, 7); textCursor = ToCursor((short *)textCursor_bits, (short *)textCursor_bits, 7, 7); grid = ToTexture((short *)grid_bits ); grid8 = ToTexture((short *)grid8_bits ); #ifdef FINEALIGN fineGrid = ToTexture((short *)fineGrid_bits ); #endif /* FINEALIGN */ copyright = ToTexture((char *)copyright_bits ); lowerTriangle = ToTexture((char *)lowerTriangle_bits ); upperTriangle = ToTexture((char *)upperTriangle_bits ); markerbm = ToBitmap((short *)marker_bits, 2, 0, 0, 16, 16 ); markermaskbm = ToBitmap((short *)markerMask_bits, 2, 0, 0, 16, 16 ); bgsave = ToBitmap((short *)plain_bits, 2, 0, 0, 16, 16 ); } #endif /* X11 */ xcip/pic.c0000644000175300001440000001013511513632544011267 0ustar meusers#include "cip.h" extern int numLines(); extern char fontString[]; Rectangle BBpic; findBBpic(h) register struct thing *h; { register struct thing *t; Point p1; Point p2; BBpic.origin.x = Xmax-Xmin; BBpic.corner.x=0; BBpic.origin.y = YBOT-YPIC; BBpic.corner.y=0; if ((t=h) != (struct thing *) NULL) { do { if( t->type == TEXT ) { /* Expand out the bounding box to nearest alignment points to insure alignment when reading in picture. */ p1 = alignDown( t->bb.origin ); p2 = alignUp( t->bb.corner ); } else { p1 = t->bb.origin; p2 = t->bb.corner; } BBpic.origin.x = min(BBpic.origin.x,p1.x); BBpic.origin.y = min(BBpic.origin.y,p1.y); BBpic.corner.x = max(BBpic.corner.x,p2.x); BBpic.corner.y = max(BBpic.corner.y,p2.y); t = t->next; } while (t != h); } } Point translate(p,b) Point p; Rectangle b; { return(sub(Pt(p.x,b.corner.y),Pt(b.origin.x,p.y))); } writePIC(t,f,b) register struct thing *t; FILE *f; Rectangle b; { Point p, q, r; register int i; char * s; int adj; switch (t->type) { case CIRCLE: { p = translate(t->origin,b); fprintf(f,"circle rad %d at %d,%d\n", t->otherValues.radius,p.x,p.y); break; } case BOX: { p = translate(t->bb.origin,b); fprintf(f,"box ht %d wid %d with .nw at %d,%d %s\n", t->bb.corner.y - t->bb.origin.y, t->bb.corner.x - t->bb.origin.x,p.x,p.y, (t->border==DOTTED) ? "dotted" : ((t->border==DASHED)?"dashed":"")); break; } case ELLIPSE: { p= translate(t->origin,b); fprintf(f,"ellipse ht %d wid %d at %d,%d\n", t->otherValues.ellipse.ht, t->otherValues.ellipse.wid,p.x,p.y); break; } case LINE: { p = translate(t->origin,b); q = translate(t->otherValues.end,b); fprintf(f,"line "); switch (t->arrow) { case startARROW: { fprintf(f,"<-"); break; } case endARROW: { fprintf(f,"->"); break; } case doubleARROW: { fprintf(f,"<->"); break; } } fprintf(f," from %d,%d to %d,%d ",p.x,p.y,q.x,q.y); if (t->border==DOTTED) { fprintf(f,"dotted"); } else { if (t->border==DASHED) { fprintf(f,"dashed"); } } fprintf(f,"\n"); break; } case ARC: { p = translate(t->otherValues.arc.start,b); q = translate(t->otherValues.arc.end,b); r = translate(t->origin,b); fprintf(f,"arc from %d,%d to %d,%d at %d,%d\n", p.x,p.y,q.x,q.y,r.x,r.y); break; } case TEXT: { if ( numLines(t->otherValues.text.s) > 1 ) { /* multi-line: use macro definition. */ p = translate(t->bb.origin,b); fprintf(f, "t%d with .nw at %d,%d\n", t->otherValues.text.outName, p.x, p.y ); } else { /* single-line: use old method of simple text string. */ i = fontheight(t->otherValues.text.f->f)>>1; /* Adjust text down a little - needed when printed */ adj = fontheight(t->otherValues.text.f->f) >>3; p = translate(Pt(t->origin.x,t->origin.y+i+adj),b); s = addBackslashes(t->otherValues.text.s); font2string(t->otherValues.text.f->num); if( strlen(fontString) == 2 ) fprintf( f, "\"\\f(%s", fontString ); else fprintf( f, "\"\\f%s", fontString ); fprintf(f,"\\s%d\\&%s\\fP\\s0\" at %d,%d%s\n", t->otherValues.text.f->ps, s, p.x, p.y, (t->otherValues.text.just==LEFTJUST)?" ljust" : ((t->otherValues.text.just==RIGHTJUST)?" rjust":"")); } break; } case SPLINE: { fprintf(f,"spline "); switch (t->arrow) { case startARROW: { fprintf(f,"<-"); break; } case endARROW: { fprintf(f,"->"); break; } case doubleARROW: { fprintf(f,"<->"); break; } } for (i=1; iotherValues.spline.used; i++) { p = translate(t->otherValues.spline.plist[i],b); if (i==1) { fprintf(f," from %d,%d",p.x,p.y); } else { fprintf(f,"\\\nto %d,%d",p.x,p.y); } } fprintf(f,"\n"); break; } case MACRO: { p = translate(t->origin,b); fprintf(f,"%s with .nw at %d,%d\n", t->otherValues.list->name,p.x,p.y); break; } } } xcip/things.c0000644000175300001440000012371311513632544012017 0ustar meusers/* Operations on things */ #ifdef DMDTERM # ifndef FONT # define FONT "$DMD/font" # endif FONT #endif /* DMDTERM */ #include "cip.h" #ifdef X11 # include #endif /* X11 */ extern int nextMacroName; extern char *envfont; extern int editDepth; extern struct macro * macroList; extern void StringSize(); extern short fontBells; extern Point alignDown(); extern Point alignUp(); #ifdef HELPSCALE short currScaleType = SCALE_NONE; short currLabelType = LABEL_NONE; short currScaleFactor = 1; #endif struct thing * undo_old = TNULL; /* Copy of original thing. */ struct thing * undo_new = TNULL; /* Points to latest thing. */ /* quadrants for arc start and end points (relative to arc origin) */ #define UPPERLEFT 1 #define UPPERRIGHT 2 #define LOWERRIGHT 3 #define LOWERLEFT 4 struct thing * newCircle(p) Point p; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = CIRCLE; b->origin = p; b->otherValues.radius = RADdefault; boundingBox(b); b->arrow = 0; } return(b); } struct thing * newBox(r) Rectangle r; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = BOX; b->origin = r.origin; b->otherValues.corner = r.corner; boundingBox(b); b->border = currBoxType; b->arrow = 0; } return(b); } struct thing * newEllipse(p) Point p; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = ELLIPSE; b->origin = p; b->otherValues.ellipse.ht = HTdefault; b->otherValues.ellipse.wid = WIDdefault; boundingBox(b); b->border = SOLID; b->arrow = 0; } return(b); } struct thing * newLine(o,c) Point o, c; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = LINE; b->origin = o; b->otherValues.end = c; boundingBox(b); b->border = currLineType; b->arrow = currLineArrows; } return(b); } struct thing * newArc(s,e) Point s, e; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = ARC; b->otherValues.arc.start = s; b->otherValues.arc.end = e; b->origin = computeArcOrigin(s,e); boundingBox(b); b->border = SOLID; b->arrow = 0; } return(b); } struct thing * newText(p,s) Point p; char *s; { register struct thing *b; fontBlk *f; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = TEXT; b->origin = p; f = findFont(currPS,currFont); b->otherValues.text.f = f; b->otherValues.text.just = currJust; b->otherValues.text.spacing = currSpacing; b->otherValues.text.s = s; boundingBox(b); b->border = SOLID; b->arrow = 0; b->otherValues.text.outName = textOutName++; } return(b); } struct thing * newSpline(u,s,p) int u, s; Point *p; { register struct thing *b; if ((b=(struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = SPLINE; b->origin = p[1]; b->otherValues.spline.used = u; b->otherValues.spline.size = s; b->otherValues.spline.plist = p; boundingBox(b); b->border = SOLID; b->arrow = currSplineArrows; } return(b); } struct thing * newMacro(p,l) Point p; struct macro *l; { register struct thing *b; if ((b = (struct thing *) getSpace(sizeof(struct thing))) != TNULL) { b->type = MACRO; b->origin = p; b->otherValues.list = l; l->useCount++; boundingBox(b); b->border = SOLID; b->arrow = 0; } return(b); } /* Compare things. Returns TRUE if things are the same. Will recurse to check out macro things. */ BOOL cmpThings( t1, t2 ) register struct thing * t1; register struct thing * t2; { register int i; register struct thing * tm1; register struct thing * tm2; int n; if( t1->type != t2->type ) return FALSE; if( !eqpt(t1->origin,t2->origin) ) return FALSE; switch( t1->type ) { case CIRCLE: if( (t1->otherValues.radius == t2->otherValues.radius) ) { return TRUE; } else { return FALSE; } case BOX: if( eqpt(t1->otherValues.corner, t2->otherValues.corner) && (t1->border == t2->border) ) { return TRUE; } else { return FALSE; } case ELLIPSE: if( (t1->otherValues.ellipse.ht == t2->otherValues.ellipse.ht) && (t1->otherValues.ellipse.wid == t2->otherValues.ellipse.wid) ) { return TRUE; } else { return FALSE; } case LINE: if( eqpt(t1->otherValues.end, t2->otherValues.end) && (t1->arrow == t2->arrow) && (t1->border == t2->border) ) { return TRUE; } else { return FALSE; } case ARC: if( eqpt(t1->otherValues.arc.start, t2->otherValues.arc.start) && eqpt(t1->otherValues.arc.end, t2->otherValues.arc.end) ) { return TRUE; } else { return FALSE; } case SPLINE: if( (t1->otherValues.spline.used == t2->otherValues.spline.used) && (t1->otherValues.spline.size == t2->otherValues.spline.size) && (t1->arrow == t2->arrow) ) { n = t1->otherValues.spline.used; for( i=1; i<=n; i++ ) { if( !eqpt(t1->otherValues.spline.plist[i], t2->otherValues.spline.plist[i] ) ) return FALSE; } return TRUE; } else { return FALSE; } case TEXT: if( (t1->otherValues.text.just == t2->otherValues.text.just) && (t1->otherValues.text.spacing == t2->otherValues.text.spacing) && (t1->otherValues.text.f == t2->otherValues.text.f) && (strcmp(t1->otherValues.text.s, t2->otherValues.text.s)==0) ) { return TRUE; } else { return FALSE; } case MACRO: t1 = t1->otherValues.list->parts; t2 = t2->otherValues.list->parts; if( (t1 != TNULL) && (t2 != TNULL) ) { tm1 = t1; tm2 = t2; do { if( !cmpThings( tm1, tm2 ) ) return FALSE; tm1 = tm1->next; tm2 = tm2->next; } while( (tm1 != t1) && (tm2 != t2) ); if( (tm1==t1) && (tm2==t2) ) { return TRUE; } } return FALSE; } } /* Adds thing t to list of things. Returns the thing after t. */ struct thing * insert(t,list) register struct thing *t, *list; { if( t != TNULL ) { if( list != TNULL ) { t->next = list; t->last = list->last; list->last->next = t; list->last = t; } else { t->last = t; t->next = t; } return(t->next); /* Note: return next item to put the new thing at the end of the list. This will build the list in order. */ } return(list); } struct thing * dummy_insert(t,list) register struct thing *t, *list; { if( t != TNULL ) { if( list != TNULL ) { t->next = list; t->last = list->last; list->last->next = t; list->last = t; } else { t->last = t; t->next = t; } return(t); } return(list); } void insertFont(t) register fontBlk *t; { if (t != (fontBlk *) NULL) { t->next = fonts; t->last = fonts->last; fonts->last->next = t; fonts->last=t; } } struct thing * Remove(t) register struct thing *t; { if (t != TNULL) { t->last->next = t->next; t->next->last = t->last; } return(( (t==TNULL) || (t==t->next)) ? TNULL : t->next); } /* This routine deletes the given macro from the macro list. It has to scan the macro list looking for that macros entry since there are no back links within the list. */ void removeMacro (m) struct macro *m; { register struct macro *ml; /* Pointer for macro list */ if (m == macroList) { macroList = m->next; } else { for (ml = macroList; ml != MNULL; ml = ml->next) { if (ml->next == m) { /* Macro found delete it. */ ml->next = m->next; } } } if (m->name != (char *)NULL) { free (m->name); } free (m); return; } void freeThing(t) register struct thing * t; { register struct thing * h; if (t!=TNULL) { switch (t->type) { case MACRO: { if (--t->otherValues.list->useCount <= 0) { for (h=t->otherValues.list->parts; h!=TNULL; ) { h = deleteThing (h); } removeMacro (t->otherValues.list); } break; } case TEXT: { t->otherValues.text.f->useCount--; free (t->otherValues.text.s); break; } case SPLINE: { free (t->otherValues.spline.plist); break; } } free((char *) t); } } /* Delete things by removing from linked list of objects and freeing space it occupied. */ struct thing * deleteThing(t) struct thing * t; { struct thing * list; if( t == TNULL ) { return TNULL; } else { if( firstThing == t ) { firstThing = t->next; if( firstThing == t ) { firstThing = TNULL; } } list = Remove(t); freeThing( t ); return list; } } struct thing * deleteAllThings(list) struct thing *list; { register struct thing *h; for (h=list; h!=TNULL; ){ h=deleteThing (h); } return(TNULL); } /* Undo an editted object. Assumes undo_new is pointing to last editted object (linked into the list of objects) and undo_old is a copy of last editted object before it was editted (not linked into the list of objects). */ struct thing * undo( list ) struct thing * list; { struct thing * tmp; if( undo_new != TNULL ) { /* If undo_new is firstThing, then reset firstThing. */ if( firstThing == undo_new ) { firstThing = undo_new->next; if( firstThing == undo_new ) { firstThing = TNULL; } } /* Unlink from object list. */ list = Remove( undo_new ); } if( undo_old != TNULL ) { /* Link into object list. */ list = insert( undo_old, list ); /* If firstThing is null, then set it. */ if( firstThing == TNULL ) { firstThing = list; } } /* Swap old for new. */ tmp = undo_new; undo_new = undo_old; undo_old = tmp; return list; } /* Save thing to be modified in undo_old. */ void save_old( t ) register struct thing * t; { if( undo_old != TNULL ) freeThing( undo_old );/* Reclaim last undo_old space. */ if( t == TNULL ) undo_old = TNULL; else undo_old = copyThing( t, t->origin, Pt(0,0), 0 ); } /* Save new thing in undo_new. */ void save_new( t ) struct thing * t; { undo_new = t; } /* Clear undo list. */ void undo_clear() { if( undo_old != TNULL ) freeThing( undo_old ); undo_old = TNULL; /* Since undo_new is a pointer to a thing in the official list, just reset it to TNULL. */ undo_new = TNULL; } struct thing * selectThing(m,list) Point m; register struct thing *list; { register struct thing *t; register int i; Rectangle r; if (list != TNULL) { /* Cycle thru things by starting with next thing. */ t = list->next; do { switch( t->type ) { case SPLINE: /* See if point is inside imanginary boxes created by each segment of the spline. */ for( i=2; iotherValues.spline.used; i++) { r = canon( t->otherValues.spline.plist[i-1], t->otherValues.spline.plist[i] ); if( ptinrect( m , inset(r,-nearEDGE) ) ) return( t ); } break; case LINE: /* First do a quick check if within bounding box area and then do a refined check to see if close. */ if( ptinrect( m, inset(t->bb,-nearEDGE) ) ) if( (distance(t->origin,t->otherValues.corner) + nearEDGE) >= (distance(t->origin,m) + distance(t->otherValues.corner,m))) return( t ); break; default: /* See if point is inside or near edge of bounding box. */ if( ptinrect( m, inset(t->bb,-nearEDGE) ) ) return( t ); break; } t=t->next; } while (t != list->next); } return ( TNULL ); } boundingBox(t) register struct thing *t; { Point p, q, r; register int i, h; int hi, w; int sx, sy, ex, ey, cx, cy, squad, equad; Font *f; if (t != TNULL) { switch(t->type) { case CIRCLE: { p.x = t->otherValues.radius; p.y = p.x; t->bb.origin = sub(t->origin,p); t->bb.corner = add(t->origin,p); break; } case BOX: { t->bb.origin = t->origin; t->bb.corner = t->otherValues.corner; break; } case ELLIPSE: { p.x = (t->otherValues.ellipse.wid)>>1; p.y = (t->otherValues.ellipse.ht)>>1; t->bb.origin = sub(t->origin,p); t->bb.corner = add(t->origin,p); break; } case LINE: { p = t->origin; q = t->otherValues.end; t->bb = canon (p, q); break; } case ARC: { /* compute radius of arc's circle */ p = t->origin; i = distance(p,t->otherValues.arc.start); /* save coordinates of arc's start, end, and origin points */ sx = t->otherValues.arc.start.x; sy = t->otherValues.arc.start.y; ex = t->otherValues.arc.end.x; ey = t->otherValues.arc.end.y; cx = p.x; cy = p.y; /* determine quadrant of start point w.r.t. origin */ if (sx < cx) { squad = sy < cy ? UPPERLEFT : LOWERLEFT; } else { squad = sy < cy ? UPPERRIGHT : LOWERRIGHT; } /* determine quadrant of end point w.r.t. origin */ if (ex < cx) { equad = ey < cy ? UPPERLEFT : LOWERLEFT; } else { equad = ey < cy ? UPPERRIGHT : LOWERRIGHT; } /* * special case: start and end points are in the same quadrant and * arc is greater than 270 but less than 360 degrees -- bounding box * goes around entire circle of arc */ if (squad == equad && (((squad == UPPERLEFT || squad == UPPERRIGHT) && sx < ex) || ((squad == LOWERLEFT || squad == LOWERRIGHT) && sx > ex))) { t->bb.origin = sub(p,Pt(i,i)); t->bb.corner = add(p,Pt(i,i)); break; } /* * all other cases (i.e., start and end points are in different * quadrants OR in same quadrant and arc is less than 90 degrees) */ /* * The table below indicates the coordinates for the origin and * corner of the bounding box for the arc, given the quadrants of * the start and end points for all cases except the special case * above. Legend: minx = min(sx, ex), miny = min(sy, ey), * maxx = max(sx,ex), and maxy = max(sy, ey). * * \ end point quadrant * \ * start \ UPPER UPPER LOWER LOWER * point \ LEFT RIGHT RIGHT LEFT * quadrant +--------------+--------------+--------------+--------------+ * | (minx,miny) | (cx-i,miny) | (cx-i,miny) | (cx-i,miny) | * UPPER | | | | | * LEFT | (maxx,maxy) | (cx+i,cy+i) | (maxx,cy+i) | (maxx,maxy) | * +--------------+--------------+--------------+--------------+ * | (minx,cy-i) | (minx,miny) | (cx-i,cy-i) | (cx-i,cy-i) | * UPPER | | | | | * RIGHT | (maxx,maxy) | (maxx,maxy) | (maxx,cy+i) | (maxx,maxy) | * +--------------+--------------+--------------+--------------+ * | (minx,cy-i) | (minx,miny) | (minx,miny) | (cx-i,cy-i) | * LOWER | | | | | * RIGHT | (cx+i,maxy) | (cx+i,maxy) | (maxx,maxy) | (cx+i,maxy) | * +--------------+--------------+--------------+--------------+ * | (minx,cy-i) | (minx,miny) | (minx,miny) | (minx,miny) | * LOWER | | | | | * LEFT | (cx+i,cy+i) | (cx+i,cy+i) | (maxx,cy+i) | (maxx,maxy) | * +--------------+--------------+--------------+--------------+ */ if (squad == equad || squad == LOWERLEFT || equad == UPPERLEFT || (squad == LOWERRIGHT && equad == UPPERRIGHT) ) { t->bb.origin.x = min(sx, ex); } else { t->bb.origin.x = cx - i; } if (squad == equad || squad == UPPERLEFT || equad == UPPERRIGHT || (squad == LOWERLEFT && equad == LOWERRIGHT) ) { t->bb.origin.y = min(sy, ey); } else { t->bb.origin.y = cy - i; } if (squad == equad || squad == UPPERRIGHT || equad == LOWERRIGHT || (squad == UPPERLEFT && equad == LOWERLEFT) ) { t->bb.corner.x = max(sx, ex); } else { t->bb.corner.x = cx + i; } if (squad == equad || squad == LOWERRIGHT || equad == LOWERLEFT || (squad == UPPERRIGHT && equad == UPPERLEFT) ) { t->bb.corner.y = max(sy, ey); } else { t->bb.corner.y = cy + i; } break; } case TEXT: { f = t->otherValues.text.f->f; h = fontheight(f); p = add( t->origin , Pt(0,h>>1) ); StringSize(f,t->otherValues.text.spacing,t->otherValues.text.s,&hi,&w); /* Calculate minimal non-aligned bounding box for text */ switch (t->otherValues.text.just) { case CENTER: t->bb.origin = sub( p, Pt(w>>1 , hi>>1) ); t->bb.corner = add( p, Pt(w>>1 , hi>>1) ); break; case LEFTJUST: t->bb.origin = sub( p, Pt(0 , hi>>1) ); t->bb.corner = add( p, Pt(w , hi>>1) ); break; case RIGHTJUST: t->bb.origin = sub( p, Pt(w, hi>>1) ); t->bb.corner = add( p, Pt(0, hi>>1) ); break; } break; } case SPLINE: { p.x = Xmin; p.y=YPIC; q.x=Xmax; q.y=YBOT; for (i=1; iotherValues.spline.used; i++) { r = t->otherValues.spline.plist[i]; p.x = max(p.x,r.x); p.y = max(p.y,r.y); q.x = min(q.x,r.x); q.y = min(q.y,r.y); } t->bb.origin = q; t->bb.corner = p; break; } case MACRO: { t->bb.origin = add(t->origin,t->otherValues.list->bb.origin); t->bb.corner = add(t->origin,t->otherValues.list->bb.corner); break; } } } } Point computeArcOrigin(s,e) Point s,e; { Point t; if (e.xnext; /* Skip over defont entry */ while (f != fonts) { if (f->ps == ps && f->num == n) { return f; } f = f->next; } /* Must load the font. */ if ((f = (fontBlk * )getSpace(sizeof(fontBlk))) == (fontBlk * )NULL) { outOfSpace (); f = fonts; /* Use defont if there is no room */ return f; } font2string( n ); f->ps = ps; #ifdef X11 newMessage("Loading font: "); sprintf(fn, "%s-%d", fontString, ps ); moreMessage(fn); /* * The zeroth element in the Font_strings array has a '%d' for font * size. This will work well for servers with scalable fonts, * notably X11R5 or later. */ f->f = (Font *)malloc(sizeof(Font)); sprintf( fn, Font_strings[n-1][0], ps*10, "100-100" ); *(f->f) = getfont(fn); if (f->f->fid == defont.fid) { /* * silently try *-* for resolution if 100-100 doesn't work. * The 100-100 resolutions don't exist at least on Sunos4. * To make up for that, add 2 to the point size, but avoid * the ones which don't exist in the font arrays; that is, * less than 2, greater than 24, or odd sizes greater than 14. */ ps = ps + 2; if (ps > 24) ps = 24; else if ((ps > 14) && ((ps % 2) == 1)) ps++; sprintf( fn, Font_strings[n-1][0], ps*10, "*-*" ); *(f->f) = getfont(fn); } if (f->f->fid == defont.fid) { moreMessage("\nCould not locate font: "); moreMessage(fn); } else { unsigned long ret; if (XGetFontProperty(f->f, XA_POINT_SIZE, &ret)) { if ((ret/10) != ps) { sprintf(fn, "\nInexact point size match: got %d", ret/10); moreMessage(fn); f->f->fid = defont.fid; /* force fallback */ } } } if (f->f->fid == defont.fid) { /* * Exact match not possible. Probably on X11R4 or earlier. */ sprintf(fn, "\nTrying font: "); moreMessage(fn); moreMessage(Font_strings[n-1][ps]); *(f->f) = getfont(Font_strings[n-1][ps]); sleep(30); /* Hold message for user to read! */ if (f->f->fid == defont.fid) { sprintf(fn, "\nCould not locate font - using default!"); moreMessage(fn); } if( fontBells ) { ringbell(); } } #else /* X11 */ #ifdef DMD630 /*See if font is in font cache. */ sprintf( fname, "%s.%d" , fontString, ps ); f->f = fontrequest( fname ); if( f->f == 0 ) { /* Font is not in cache so attempt to load in. */ #endif if( fontBells ) ringbell(); newMessage("Loading font: "); cursswitch(&hourglass); i = ps + 1; do { /* Look for a font <= R.i */ sprintf(fn, "%s/%s.%d", envfont, fontString, --i ); } while ((i > 0) && (access(fn, 4) != 0)); if (i == 0) { newMessage("Font not found: "); newMessage(fn); sleep(60); f->f = &defont; return f; } newMessage(fn); if ((f->f = getfont(fn)) == (Font * ) NULL) { newMessage("Internal error: getfont failed"); sleep(60); cursSwitch(); f->f = &defont; return f; } newMessage(""); if( fontBells ) ringbell(); #ifdef DMD630 /* Add font to cache. */ /* "fontcache(...) would be preferable, but it aborts - why?? */ fontsave( fname, f->f ); } #endif cursSwitch(); #endif /* X11 */ /* Add font to font list. */ insertFont( f ); f->num = n; f->useCount = 0; f->useCount++; return f; } #ifdef HELPSCALE /* The first entry, "", is for LABEL_NONE */ char *scaleLabels[] = { "", "\"", "' \"", "'", " yd.", " mi.", " mm", " m", " km" }; #endif void printNum( n ) short n; { char s[20]; #ifdef HELPSCALE #ifdef DMD5620 #define Sprintf sprintf #endif short tmpScaleFactor; short tmpLabelType; int whole_n; int frac_n; int precision; int frac_scale; int feet; int inches; char frac_str[20]; tmpScaleFactor = currScaleFactor; tmpLabelType = currLabelType; switch ( currScaleType ) { case SCALE_NONE: sprintf(s,"%d", n ); moreMessage(s); return; case SCALE_LABEL_ONLY: tmpScaleFactor = 1; break; case SCALE_FACTOR_ONLY: tmpLabelType = LABEL_NONE; break; case SCALE_BOTH: default: break; } precision = 0; frac_scale = 1; if ( tmpScaleFactor > 1 ) { precision++; frac_scale *= 10; } if ( tmpScaleFactor > 10 ) { precision++; frac_scale *= 10; } if ( tmpScaleFactor > 100 ) { precision++; frac_scale *= 10; } whole_n = n / tmpScaleFactor; frac_n = muldiv( n%tmpScaleFactor, frac_scale, tmpScaleFactor ); sprintf(s,"%d",frac_n); strcpy(frac_str,".000"); frac_str[1+precision-strlen(s)] = '\0'; strcat(frac_str,s); switch (tmpLabelType) { case LABEL_FT_IN: feet = whole_n / 12; inches = whole_n % 12; sprintf(s,"%d'%d%s\"", feet, inches, ((precision == 0)? "" : frac_str) ); break; case LABEL_NONE: case LABEL_IN: case LABEL_FT: case LABEL_YD: case LABEL_MI: case LABEL_MM: case LABEL_METERS: case LABEL_KM: sprintf(s,"%d%s%s", whole_n, ((precision==0)?"":frac_str), scaleLabels[tmpLabelType] ); break; default: sprintf(s,"%d", n ); break; } #else /* HELPSCALE */ sprintf(s,"%d", n ); #endif /* HELPSCALE */ moreMessage( s ); } #ifdef HELPSCALE void printPureNum( n ) short n; { char s[20]; sprintf(s,"%d", n ); moreMessage( s ); } #endif /* HELPSCALE */ void printPt( p ) Point p; { char s[30]; sprintf(s,"(%d,%d)", p.x, p.y); moreMessage(s); } void printBorder( border ) short border; { switch( border ) { case SOLID: moreMessage("solid"); break; case DASHED: moreMessage("dashed"); break; case DOTTED: moreMessage("dotted"); break; } } void printArrows( arrows ) short arrows; { switch( arrows ) { case 0: moreMessage( "no arrows" ); break; case startARROW: moreMessage( "arrow at start" ); break; case endARROW: moreMessage( "arrow at end" ); break; case doubleARROW: moreMessage( "double arrows" ); break; } } static char * FontStyles[] = { "Roman", "Roman italic", "Roman bold", "Helvetica", "Helvetica italic", "Helvetica bold", "Palatino", "Palatino italic", "Palatino bold", "Expanded", "Expanded italic", "Expanded bold", "Constant width" }; void printFontStyle( fontStyle ) short fontStyle; { if( fontStyle == 0 ) { moreMessage( "Default" ); } else { moreMessage( FontStyles[fontStyle-1] ); } } void printJust( just ) short just; { switch( just ) { case LEFTJUST: moreMessage( "left justified" ); break; case CENTER: moreMessage( "centered" ); break; case RIGHTJUST: moreMessage( "right justified" ); break; } } void printInfo(t) register struct thing * t; { register short n; register struct thing * s; if( t == TNULL ) { initMessage(); return; }; switch( t->type ) { case CIRCLE: newMessage( "Circle: radius=" ); printNum( t->otherValues.radius ); moreMessage( " origin=" ); printPt( t->origin ); break; case BOX: newMessage( "Box: " ); printBorder( t->border ); moreMessage( " height=" ); printNum( t->otherValues.corner.y - t->origin.y ); moreMessage( " width=" ); printNum( t->otherValues.corner.x - t->origin.x ); moreMessage( "\n" ); printPt( t->origin ); moreMessage( " to " ); printPt( t->otherValues.corner ); break; case ELLIPSE: newMessage( "Ellipse: height=" ); printNum( t->otherValues.ellipse.ht ); moreMessage( " width=" ); printNum( t->otherValues.ellipse.wid ); moreMessage( "\norigin=" ); printPt( t->origin ); break; case LINE: newMessage( "Line: length=" ); printNum( (short) distance( t->otherValues.end , t->origin ) ); moreMessage( " " ); printBorder( t->border ); moreMessage( " " ); printArrows( t->arrow ); moreMessage( "\n" ); printPt( t->origin ); moreMessage( " to " ); printPt( t->otherValues.end ); break; case ARC: newMessage( "Arc: radius=" ); printNum( (short) distance( t->otherValues.arc.start, t->origin) ); moreMessage( " origin=" ); printPt( t->origin ); moreMessage( "\nstart=" ); printPt( t->otherValues.arc.start ); moreMessage( " end=" ); printPt( t->otherValues.arc.end ); break; case SPLINE: newMessage( "Spline: " ); #ifdef HELPSCALE printPureNum( t->otherValues.spline.used-1 ); #else printNum( t->otherValues.spline.used-1 ); #endif /* HELPSCALE */ moreMessage( " points " ); printArrows( t->arrow ); break; case TEXT: newMessage( "Text: " ); printFontStyle( t->otherValues.text.f->num ); moreMessage( " point size=" ); #ifdef HELPSCALE printPureNum( t->otherValues.text.f->ps ); #else printNum( t->otherValues.text.f->ps ); #endif /* HELPSCALE */ moreMessage( "\n" ); n = numLines(t->otherValues.text.s); if( n == 1 ) { moreMessage( "1 line "); } else { #ifdef HELPSCALE printPureNum( n ); #else printNum( n ); #endif /* HELPSCALE */ moreMessage( " lines " ); } printJust( t->otherValues.text.just ); n = t->otherValues.text.spacing; if( n == 0 ) { moreMessage(" normal spacing" ); } else { moreMessage( " spacing=" ); #ifdef HELPSCALE printPureNum( n ); #else printNum( n ); #endif /* HELPSCALE */ } /* For Debugging purposes: */ { int hi, wi; StringSize( t->otherValues.text.f->f, t->otherValues.text.spacing, t->otherValues.text.s, &hi, &wi ); moreMessage("\nsize width="); printNum( wi ); moreMessage(" height="); printNum( hi ); } moreMessage("\nBB o=("); printNum( t->bb.origin.x ); moreMessage(","); printNum( t->bb.origin.y ); moreMessage(") c=("); printNum( t->bb.corner.x ); moreMessage(","); printNum( t->bb.corner.y ); moreMessage(")"); break; case MACRO: newMessage( "Macro: " ); n=0; s = t->otherValues.list->parts; if( s != (struct thing *) NULL ) { do { n++; s = s->next; } while ( s != t->otherValues.list->parts ); } #ifdef HELPSCALE printPureNum( n ); #else printNum( n ); #endif /* HELPSCALE */ if( n == 1 ) moreMessage( " object height=" ); else moreMessage( " objects height=" ); printNum( t->bb.corner.y - t->bb.origin.y ); moreMessage( " width=" ); printNum( t->bb.corner.x - t->bb.origin.x ); moreMessage( "\n" ); printPt( t->bb.origin ); moreMessage( " to " ); printPt( t->bb.corner ); break; } } xcip/LIBDMDX11/0000755000175300001440000000000011513632541011572 5ustar meusersxcip/LIBDMDX11/LIBDMDX11.mm0000644000175300001440000013073711513632541013365 0ustar meusers.ND "May 25, 1988" .TL "311401-2299, 311401-0199" "38794-23, 25952" A 5620 Emulator Library for Version 11 X Windows and Suntools .AU "D. A. Kapilow" DAK MH 11228 3596 2B-424 alice!dak .AU "J. I. Helfman" JH MH 11229 5087 2C-535 alice!jon .TM 11228-880525-06TMS 11229-880525-04TMS .fp 5 CW .MT .H 1 "Introduction" An AT&T 5620 terminal emulator library has been implemented to simplify porting the Ninth Edition Unix\(dd 5620 tools to version 11 of the X Window System* (X11) .FS * X Window System is a trademark of M.I.T. .FE and Sun Microsystem's \f5suntools\fR window environment. .FS \(dd Unix is a registered trademark of AT&T. .FE The library has been successfully used to port several tools to the Sun Workstation\(dg. .FS \(dg Sun Workstation is a registered trademark of Sun Microsystems, Inc. .FE The same tool source code can be compiled for either X11 or \f5suntools\fR running under Sun's Berkeley (BSD) derived Unix system (SunOS), or X11 under Ninth Edition Unix. .P The emulator library and many of the tools should easily port to other hardware running Unix and X11 because of the device independence of both the operating system and windowing software. The library should work unmodified on other BSD Unix systems that support X11. While designed for 5620 applications, it should also be possible to port code written for other members of the AT&T DMD terminal family, such as the 630. .P Other 5620 emulator libraries have been written\*(Rf .RS M. E. Meth and C. D. Blewett, \fIA Mux Emulator Running under X-Windows\fR, TM 11229-870827-06TMS .RF \*(Rf. .RS M. J. Hawley and S. J. Leffler, \fIWindows for UNIX at Lucasfilm\fR, Proceedings Summer USENIX Meeting, 1985, pp. 393-406 .RF This work is a refinement and extension of a previous library\*(Rf designed for X11 on a Ninth Edition Unix system. .RS D. A. Kapilow, \fIA Port of the Ninth Edition Unix Kernel, X Window System, and 5620 Tools to the Sun Workstation\fR, TM 11228-871119-17TMS .RF .H 1 "Host-Terminal Model" In the 5620 environment applications are broken into two separate processes that run on different processors. The \fIterminal\fR process is down-loaded to the 5620 and has access to the display, keyboard, and mouse. A cooperating \fIhost\fR process runs on a Unix computer allowing access to Unix resources. On Ninth Edition Unix systems, \f5mux\fR\*(Rf manages the communications to allow multiple host-terminal process pairs to run concurrently over a single serial communications channel. .RS Unix Time-Sharing System, \fIProgrammer's Manual\fR, Ninth Edition, Volume 1, AT&T Bell Laboratories, 1986 .RF This is illustrated in Figure 1 below. .DS CB .FG "AT&T 5620 Terminal Application Model" 3 2 .PS scale=81 box invis ht 240 wid 304 with .sw at 0,0 line <-> from 160,120 to 160,80 box ht 64 wid 80 with .nw at 216,80 box ht 64 wid 80 with .nw at 112,80 box ht 64 wid 80 with .nw at 8,80 box ht 64 wid 80 with .nw at 64,224 "\f4\s10\&2\f1\s0" at 256,33 line <-> from 208,160 to 208,136 box ht 16 wid 216 with .nw at 48,136 "\f4\s10\&AT&T 5620 Terminal\f1\s0" at 48,233 ljust box ht 128 wid 232 with .nw at 40,240 dotted "\f4\s10\&Mux Terminal Operating System\f1\s0" at 156,129 line <-> from 104,160 to 104,136 "\f4\s10\&2\f1\s0" at 208,177 "\f4\s10\&UNIX System\f1\s0" at 8,9 ljust box ht 88 wid 304 with .nw at 0,88 dotted "\f4\s10\&1\f1\s0" at 48,33 "\f4\s10\&1\f1\s0" at 104,177 "\f4\s10\&Host\f1\s0" at 256,65 "\f4\s10\&Host\f1\s0" at 48,65 "\f4\s10\&Terminal\f1\s0" at 208,209 "\f4\s10\&Terminal\f1\s0" at 104,209 "\f4\s10\&Process\f1\s0" at 208,193 "\f4\s10\&Process\f1\s0" at 104,193 box ht 64 wid 80 with .nw at 168,224 line <-> from 192,48 to 216,48 "\f4\s10\&Process\f1\s0" at 256,49 "\f4\s10\&Process\f1\s0" at 48,49 line <-> from 88,48 to 112,48 "\f4\s10\&Process\f1\s0" at 152,33 "\f4\s10\&Host\f1\s0" at 152,49 "\f4\s10\&Mux\f1\s0" at 152,65 .PE .DE .P The two process implementation of applications is maintained in the emulator library. The \fIhost\fR and \fIterminal\fR processes run as separate Unix processes on the same processor and communicate with a bidirectional connection appropriate for the operating system: a pipe in Ninth Edition Unix and a Unix domain socket in BSD Unix. The \fIterminal\fR process may have direct access to the screen as in \f5suntools\fR, or may use another communications channel to a display server as in X11. The X11 case is illustrated in Figure 2 below. .DS CB .FG "Emulator Library Application Model (X11)" 4 2 .PS scale=81 box invis ht 184 wid 432 with .sw at 0,0 box ht 184 wid 336 with .nw at 0,184 dotted line <- from 208,48 to 280,48 "\f4\s10\&Host\f1\s0" at 56,145 "\f4\s10\&Host\f1\s0" at 56,65 line <- from 280,96 to 280,48 "\f4\s10\&Keyboard\f1\s0" at 392,129 "\f4\s10\&Display\f1\s0" at 392,145 "\f4\s10\&Mouse\f1\s0" at 392,113 box ht 64 wid 80 with .nw at 240,160 box ht 64 wid 80 with .nw at 352,160 line <-> from 320,128 to 352,128 "\f4\s10\&X11\f1\s0" at 280,145 "\f4\s10\&Server\f1\s0" at 280,129 "\f4\s10\&Process\f1\s0" at 280,113 "\f4\s10\&1\f1\s0" at 56,113 "\f4\s10\&1\f1\s0" at 168,113 "\f4\s10\&2\f1\s0" at 56,33 "\f4\s10\&\f1\s0" at 56,145 box ht 64 wid 80 with .nw at 128,160 "\f4\s10\&Process\f1\s0" at 168,129 box ht 64 wid 80 with .nw at 16,160 line <-> from 96,128 to 128,128 "\f4\s10\&Process\f1\s0" at 56,129 "\f4\s10\&Terminal\f1\s0" at 168,145 "\f4\s10\&\f1\s0" at 56,33 "\f4\s10\&2\f1\s0" at 168,33 "\f4\s10\&Terminal\f1\s0" at 168,65 "\f4\s10\&\f1\s0" at 56,65 box ht 64 wid 80 with .nw at 16,80 box ht 64 wid 80 with .nw at 128,80 "\f4\s10\&Process\f1\s0" at 56,49 "\f4\s10\&Process\f1\s0" at 168,49 line <-> from 96,48 to 128,48 line <-> from 208,128 to 240,128 "\f4\s10\&UNIX System\f1\s0" at 24,169 ljust .PE .DE .P In many tools implemented as two processes in the 5620 environment, the \fIhost\fR process is used only for file service and data compression between the terminal and host computer. Tools using the emulator library can directly access the file system at high bandwidth so many of the simpler tools can be implemented with a single process. .H 1 "Porting Guide" .P This section describes how to port a tool to the emulator library environment. It assumes familiarity with the interface provided by \f5mux\fR to applications that run on the AT&T 5620 terminal. Section 3.1 and 3.2 give detailed descriptions of the source code changes that must be made in the \fIhost\fR and \fIterminal\fR processes. Section 3.3 summarizes the porting procedure and section 3.4 contains a sample program. .H 2 "Host Process Modifications" Although the \fIhost\fR process does not directly interact with the graphics system, a few source code changes are required for proper operation in the emulator environment. The \fIhost\fR process is responsible for starting the \fIterminal\fR process and establishing the communications channel between the processes. A different mechanism is required to achieve this in the emulator because both processes run on the same processor. .P In the 5620 environment, the \fIhost\fR process usually down-loads the \fIterminal\fR process by calling \f532ld\fR. The following \fIhost\fR process code fragment from the debugger \f5pi\fR, is a simplified version of the code to down-load \f5pads\fR, \f5pi\fR's \fIterminal\fR process, to the 5620. .DS I N 10 \f5int fd; system("/usr/jerq/bin/32ld /usr/jerq/mbin/pads.m"); fd = open("/dev/tty", 2);\fR .DE .P The file descriptor, \f5fd\fR, is used in the \fIhost\fR process to exchange information with the \fIterminal\fR process. .P In the emulator library, both processes run on the same processor so a combination of \f5fork\fR and \f5exec\fR is used. The emulator implementation assumes that file descriptors in the \fIterminal\fR process are arranged so \f5write\fRs to file descriptor 1 send data to the \fIhost\fR process and \f5read\fRs from file descriptor 0 receive data from the \fIhost\fR process. Since a Unix process started with \f5exec\fR inherits open file descriptors, the \fIhost\fR process can properly arrange the file descriptors for the \fIterminal\fR process when it is started. .P Code to start the \fIterminal\fR process for use with the emulator library is shown below: .DS I N 10 \f5int fds[2], pid; /* Establish a bidirectional connection */ #ifdef BSD socketpair(AF_UNIX, SOCK_STREAM, 0, fds); #endif BSD #ifdef V9 pipe(fds); #endif V9 if( (pid=fork())==0 ){ dup2(fds[0], 0); /* Move fds[0] to 0, 1 */ dup2(fds[0], 1); close(fds[0]); /* Close duped fd */ close(fds[1]); /* Close host end fd */ execlp("pads", "pads", (char *)0); _exit(1); } close(fds[0]); /* Close terminal end fd */\fR .DE .P Here the file descriptor, \f5fds[1]\fR, is used in the \fIhost\fR process to communicate with the \fIterminal\fR process. The calls to \f5dup2\fR move the communications channel to the proper file descriptors in the \fIterminal\fR process. .H 2 "Terminal Process Modifications" The \fIterminal\fR process directly interacts with the window system. The emulator library converts 5620 style graphics and I/O requests into the primitives of the underlying window system. In the implementation of the library, compromises had to be made between compatibility with the 5620 code and efficiency of operation in the new environments. Efficiency was given preference over source code changes provided the modifications could be easily made. .H 3 "Preprocessor and Compiling" Before the emulator library can be used, the file \f5jerq.h\fR must be included in \fIterminal\fR process source files. This file redefines many of the 5620 data structures to ones appropriate for the window system. All other references to 5620 related \f5#include\fR files, other than \f5menu.h\fR, should be removed from the source. .P Preprocessor flags are used to compile applications for the different environments. The flags \f5BSD\fR and \f5V9\fR determine the version of the Unix operating system while \f5X11\fR and \f5SUNTOOLS\fR specify the window system. .P On a Sun running Sun's operating system (SunOS), the following line can be used to create a binary for X11. .DS I N 10 \f5cc -DBSD -DX11 -I/usr/jtools/include testfile.c \e /usr/jtools/lib/libj.a -lX11\fR .DE .P The corresponding line for \f5suntools\fR is: .DS I N 10 \f5cc -DBSD -DSUNTOOLS -I/usr/jtools/include testfile.c \e /usr/jtools/lib/libsj.a -lsunwindow -lpixrect\fR .DE .P The libraries have been successfully tested with SunOS releases 3.0 to 3.5, and the Beta release of 4.0. .H 3 "Initialization" A call to the function .DS I N 10 \f5initdisplay(argc, argv) int argc; char **argv;\fR .DE .P should be placed in the beginning of the \fIterminal\fR process. This call hides the details of creating a window on the screen and initializing data structures. \f5Argc\fR, and \f5argv\fR should be the command line arguments passed to \f5main\fR. \f5Initdisplay\fR searches these arguments for window system related parameters such as the X11 geometry specification. .P The operations performed by \f5initdisplay\fR depend heavily on the window system. Under \f5suntools\fR, \f5initdisplay\fR overlays a preexisting window on the screen obtained from the \f5WINDOW_GFX\fR environment variable. Thus the geometry of the tool is determined by the covered window. If a tool using the emulator library requires a new window to run in, \f5shelltool\fR can be called with the tool to be run as an argument. In the \f5suntools\fR environment all tools using the emulator library are configured with a backing store. .P In X11, \f5initdisplay\fR establishes a connection to the X11 server and creates a new window. If a geometry specification is present the window is mapped on the screen in the appropriate position. Otherwise \f5initdisplay\fR calls the window manager to allow the user to determine the tool's size and position on the screen. The X11 backing store is not used in the current implementation because of poor performance. .P In X11, a tool can give size hints to the window manager using two different functions. A call to .DS I N 10 \f5setsizehints(width, height, flags) int width, height, flags;\fR .DE .P can be made before \f5initdisplay\fR is called. \f5Width\fR and \f5height\fR are the dimensions in pixels of the default window size. Most X11 window managers allow the user to override default size hints by using a different mouse button to sweep the window. If \f5flags\fR is non zero, the X11 minimum size hints are also set to \f5width\fR and \f5height\fR, which in most window managers prohibits the user from making a smaller window. .P Alternatively, if an application supplies the routine .DS I N 10 \f5jerqsizehints()\fR .DE .P it will be called from \f5initdisplay\fR after the connection to the X server has been established but before the window is created. This allows the size hints to be computed from the screen's physical parameters such as the pixel resolution and dimensions. An application provided \f5jerqsizehints\fR routine should call \f5setsizehints\fR to set the size hints. .P If neither \f5jerqsizehints\fR nor \f5setsizehints\fR is called, the size hints are set to values appropriate for a 80 column by 24 line window in the default font. Both \f5jerqsizehints\fR and \f5setsizehints\fR are ignored in \f5suntools\fR as the window size is predetermined by the window that is overlaid. .P A call to .DS I N 10 \f5request(resource) int resource;\fR .DE .P should be made before \f5initdisplay\fR is called to inform the emulator library which I/O resources will be required. \f5Resource\fR may be one or more of the bit flags \f5ALARM\fR, \f5CPU\fR, \f5KBD\fR, \f5MOUSE\fR, \f5RCV\fR, and \f5SEND\fR. \f5Request\fR has several differences from the 5620 version: .AL 1 .LI All resources except \f5RCV\fR are implicitly requested. .LI \f5Request\fR must be called before \f5initdisplay\fR and can only be called \fIonce\fR. .LE .P By default \f5initdisplay\fR sets up the mouse tracking so new mouse motion events occur only while one or more of the mouse buttons are pressed. This differs from the 5620 where the global \f5mouse\fR structure is updated regardless of the state of the mouse buttons. Tools that need to track the mouse when the mouse buttons are up should call the function .DS I N 10 \f5mousemotion();\fR .DE .P before the call to \f5initdisplay\fR is made. .P It is an error to call any of the emulator library functions other than \f5mousemotion\fR, \f5request\fR, and \f5setsizehints\fR before the call to \f5initdisplay\fR has returned. .H 3 "Global Data Structures" Several of the global data structures are modified in the emulator library. There is a newly defined structure called \f5Jproc\fR that corresponds to the \f5Proc\fR structure in \f5mux\fR. In the emulator library \f5Jproc\fR has only two fields: an integer \f5state\fR that uses bit flags to store resource information and a \f5cursor\fR pointer used in the implementation of the function \f5cursswitch\fR. The \f5Jproc\fR structure of an application can be accessed through the global pointer \f5P\fR. \f5P->state\fR may be checked to see which resources are available. The bits and their meanings are described below: .VL 12 .LI \f5ALARM\fR Set when a timer started with \f5alarm\fR expires. This bit must be cleared by the application. .LI \f5KBD\fR Set when keyboard input is available and cleared automatically by \f5kbdchar\fR when the keyboard input buffer is empty. .LI \f5RCV\fR Set when input is available from the \fIhost\fR process and cleared automatically by \f5rcvchar\fR when the receive buffer is empty. .LI \f5RESHAPED\fR Set when a window has been reshaped by the user and must be redrawn. This bit must be cleared by the application. An application can determine the size of the new window by examining the global \f5Rectangle Drect\fR. In X11, this bit is also set if a damaged region of the window is exposed. .LE .P The bits \f5MOUSE\fR, \f5SEND\fR, and \f5CPU\fR are for compatibility with the \f5wait\fR and \f5own\fR functions and are never set in \f5P->state\fR. .P As on the 5620, there is a global \f5mouse\fR structure that stores the mouse's position and button states. Unlike the 5620, this structure is not updated asynchronously by the operating system. Mouse position and button updates are hidden in I/O requests. .P The global \f5Rectangle\fRs \f5Drect\fR and \f5display.rect\fR store the dimensions of a tool's window. In the emulator library the upper left hand corner of the display area of a process is the coordinate system origin. Thus the \f5origin\fRs of \f5Drect\fR and \f5display.rect\fR are always set to the point 0,0. On the 5620, these \f5Rectangle\fRs are in screen coordinates. .P There are also several new global data structures that allow applications to directly call routines in the underlying window system. These can be used to do operations that are supported in the window systems but not in the emulator library, such as drawing lines of different width. Code calling these low level functions should be enclosed in preprocessor conditional defines. .P If compiled for X11, the following globals can be accessed .DS I N 10 \f5GC gc; /* X11 graphics context */ Display *dpy; /* X11 display */ int fgpix, bgpix; Colormap colormap; XColor fgcolor, bgcolor;\fR .DE .P while compiling for \f5suntools\fR allows access to .DS I N 10 \f5Pixwin *displaypw;\fR .DE .P For example, to draw a dashed line that is 3 pixels wide in X11, the following code can be used: .DS I N 10 \f5#ifdef X11 XSetLineAttributes(dpy, gc, 3, LineOnOffDash, CapNotLast, JoinMiter); segment(&display,Drect.origin,Drect.corner,F_XOR); #endif X11\fR .DE .P The window system manuals should be consulted for more information on using these data structures\*(Rf .RS Jim Gettys, Ron Newman, Robert Scheifler, \fIXlib - C Language X Interface Protocol Version 11\fR, X Release X.V11R1, 1987. .RF \*(Rf. .RS \fISunView Programmers Guide\fR, Sun Microsystems, Inc., Part No:800-134502, 1986 .RF .H 3 "Graphics" For efficiency reasons cursors, \f5Texture\fRs, and \f5Bitmap\fRs are stored in a format that is compatible with the underlying window system. Three new routines must be used to initialize these structures from bit patterns. The conversions can only be made after \f5initdisplay\fR has returned. .P A \f5Texture\fR on the 5620 is an array of 16 shorts representing a 16x16 bit pattern. Initialization is done by filling the array. For example, the following code defines a grey \f5Texture\fR. .DS I N 10 \f5Texture grey={ 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, };\fR .DE .P In the emulator library \f5Texture\fRs are more complex objects. For example, a \f5Texture\fR in the X11 implementation is a handle to a remote \f5Pixmap\fR data structure maintained by the server. To create a \f5Texture\fR it is necessary call the function \f5ToTexture\fR. The code corresponding to the initialization of \f5grey\fR is show below. .DS I N 10 \f5short grey_bits[]={ 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, }; Texture grey; grey = ToTexture(grey_bits);\fR .DE .P There is a similar function, called \f5ToTexture32\fR to convert 32x32 bit \f5Texture32\fR objects. .P On the 5620, cursors are \f5Texture\fRs. In the emulator library a new object called \f5Cursor\fR is defined. This was necessary because both \f5suntools\fR and X11 represent cursors as special objects. A bit pattern is converted to a \f5Cursor\fR in the emulator library with the function \f5ToCursor\fR. For example, the cursor \f5crossHairs\fR is initialized on the 5620 with the following code. .DS I N 10 \f5Texture crossHairs = { 0x100,0x100,0x100,0x100,0x100,0x100,0x0,0xFC7E, 0x0,0x100,0x100,0x100,0x100,0x100,0x100,0x0, };\fR .DE .P The corresponding code in the emulator is: .DS I N 10 \f5short crossHairs_bits[] = { 0x100,0x100,0x100,0x100,0x100,0x100,0x0,0xFC7E, 0x0,0x100,0x100,0x100,0x100,0x100,0x100,0x0, }; Cursor crossHairs; crossHairs = ToCursor(crossHairs_bits, crossHairs_bits, 7, 7);\fR .DE .P The first argument to \f5ToCursor\fR is a 16x16 bit pattern defining the cursor. On the 5620 and in \f5suntools\fR, these bits are exclusive-ored on the screen. In X11, these bits are set to the foreground color. The second argument is another 16x16 bit pattern that is ignored in \f5suntools\fR. These bits are used as a mask in X11. Bits set in both the first and second bit patterns are set to the foreground color. Bits set in the second bit pattern, but not the first, are set to the background color. Bits not set in the second bit pattern are not changed. If the same bit pattern is given for both arguments, as is done above, the cursor will not be visible in foreground colored regions of the screen. The last two arguments are the x and y offset of the cursor's hot spot relative to the upper left hand corner of the cursor and can be used to set the cursor's active point. This is useful if the cursor is not symmetrical. .P Initialized \f5Bitmap\fRs also require code changes. For example, the following piece of 5620 code creates a 16x16 \f5Bitmap\fR from the bits defined in \f5starbits\fR. .DS I N 10 \f5short starbits[]={ 0x07E0,0x0,0x1F08,0x0,0x0,0x0,0x7FFE,0x0, 0x3FC2,0x0,0x0,0x0,0xFFFF,0x0,0x7FC1,0x0, 0x0,0x0,0xFFFF,0x0,0x1F01,0x0,0x0,0x0, 0x7FFE,0x0,0x0,0x0,0x1008,0x0,0x07E0,0x0, }; Bitmap stardwg={(Word *)starbits, 1, 0, 0, 16, 16};\fR .DE .P \f5Bitmap\fR scan lines are word aligned (4 byte) on the 5620, so the odd shorts must be present in \f5starbits\fR even though they are not used. The 1 in the initialization of \f5stardwg\fR determines the number of words in a scan line and the last four numbers define the \f5Bitmap\fR's \f5Rectangle\fR. .P Assuming the same definition of \f5startbits\fR, the corresponding piece of code for use in the emulator is: .DS I N 10 \f5Bitmap stardwg; stardwg=ToBitmap((char *)starbits, 4, 0, 0, 16, 16);\fR .DE .P The arguments to the function \f5ToBitmap\fR correspond to the initialized data of a \f5Bitmap\fR on the 5620 except the length of a scan line is in bytes instead of words. Word alignment of the bit patterns is not necessary in the emulator library. .P Some 5620 programs use the function \f5addr\fR to directly access the pixels in a \f5Bitmap\fR. \f5Addr\fR returns the address of the \f5Word\fR containing the bit of a given point in a \f5Bitmap\fR. This function is not implemented in the emulator library as the address may not be accessible. For example, in X11 \f5Bitmap\fRs are maintained by the server. Code calling \f5addr\fR will have to be modified to use function calls to access pixels. The function \f5point\fR can be used to set individual pixels, and a new function .DS I N 10 \f5int getpoint(b, p) Bitmap b; Point p;\fR .DE can be used to read back the current value of a pixel. .P The constants that define the dimensions of the screen in pixels, \f5XMAX\fR and \f5YMAX\fR, are undefined in the emulator library. Applications using these constants should substitute \f5Drect.corner.x\fR and \f5Drect.corner.y\fR instead. In the emulator library these values contain the width and height of the window that the application controls. Since \f5Drect\fR does not contain valid data until after \f5initdisplay\fR has returned, initialized data derived from \f5XMAX\fR and \f5YMAX\fR should be changed to assignment statements that are called after \f5initdisplay\fR. .H 3 "Fonts" The emulator library uses the native fonts of the underlying window system. The \f5Font\fR structure is redefined by the preprocessor to correspond to a handle appropriate for the window system: a \f5XFontStruct\fR in X11 and a \f5Pixfont\fR pointer in \f5suntools\fR. .P Code accessing fields in the \f5Font\fR structure will have to be modified. Three macros, \f5fontheight\fR, \f5fontwidth\fR, and \f5fontnchars\fR take a \f5Font\fR pointer as an argument and return the height of a character in pixels, width of a character in pixels, and number of characters in the font respectively. The macros only work correctly on fixed-width fonts. .P To open a \f5Font\fR .DS I N 10 \f5Font getfont(fontname) char *fontname;\fR .DE .P is used. Appropriate \f5fontname\fRs can be determined with \f5xlsfonts\fR for X11 and by examining the directory \f5/usr/lib/fonts/fixedwidthfonts\fR for \f5suntools\fR. .H 3 "I/O" The handling of input in the emulator library is hidden in the routine .DS I N 10 \f5int wait(resource) int resource;\fR .DE .P where \f5resource\fR is a bit vector indicating which resources to wait for. Like the 5620 version, it returns a bit vector indicating which resources are available. The emulator library uses the \f5wait\fR routine to hide many window system dependencies, such as reading and parsing of mouse and keyboard events, flushing the X11 output buffer, and restoring damaged areas of the screen from the backing-store in \f5suntools\fR. Keyboard events are queued in a buffer while mouse events are used to update the global \f5mouse\fR structure. .P \f5Wait\fRing for the \f5KBD\fR, \f5RCV\fR, or \f5ALARM\fR resources has the same behavior in the emulator library and 5620 environments. The \f5CPU\fR and \f5MOUSE\fR resources behave differently. On the 5620, \f5wait(CPU)\fR gives up the processor so other processes on the terminal can run. In the emulator library, the \fIterminal\fR process is a Unix process, so scheduling is determined by the Unix kernel. A \f5wait(CPU)\fR call in the emulator determines if any new input has arrived and processes the results appropriately without blocking. \f5Wait(CPU)\fR is the only way to update the keyboard queue, receive queue, and \f5mouse\fR structure without the possibility of blocking. .P \f5Wait\fRing for the \f5MOUSE\fR on the 5620 blocks the process until it has control of the mouse. In the emulator library it blocks until any new window event is received. Typical events are mouse button hits, button releases, keyboard input, and motion of the mouse. .P The function .DS I N 10 \f5nap(t) int t;\fR .DE .P busy loops for \f5t\fR ticks of a 60 hertz clock on the 5620. The pseudo-code below shows how it is typically used to avoid screen flicker while tracking the mouse. .DS I N 10 \f5for(; button3(); nap(2)) { /* If mouse moved, redraw object */ }\fR .DE .P \f5Nap\fR is equivalent to \f5wait(MOUSE)\fR in the emulator library so applications using it for timing should call \f5sleep\fR instead. .P In the emulator library, care must be taken to avoid infinite loops that wait for mouse changes without calling \f5wait\fR or \f5nap\fR. For example, the following piece of code works correctly on the 5620 since the \f5mouse\fR structure is updated asynchronously but loops indefinitely in the emulator library: .DS I N 10 \f5while(button2());\fR .DE .P It can be corrected with the addition of a call to \f5wait\fR. .DS I N 10 \f5while(button2()) wait(MOUSE);\fR .DE .P The function \f5own\fR can be used to determine which resources are available. Unlike the 5620, \f5own()&MOUSE\fR is always true. .P The functions \f5sendchar\fR and \f5sendnchars\fR are used to send data to the \fIhost\fR process. In the emulator library, these procedures are implemented with non-blocking \f5write\fRs to avoid the possibility of the \fIterminal\fR and \fIhost\fR processes becoming deadlocked. An application may redefine these routines to override the default implementation. For example, in the Ninth Edition Unix implementation of some terminal emulators it is desirable to push line disciplines that require formatted messages on the communications channel between the \fIterminal\fR process and \fIhost\fR shell. These line disciplines allow \f5ioctl\fR calls by Unix programs to be caught and interpreted in the \fIterminal\fR process. .P Similarly, the handling of input from the \fIhost\fR process can be specialized. When \f5wait\fR detects input from the \fIhost\fR process on file descriptor 0, the function .DS I N 10 \f5rcvfill()\fR .DE .P is called. The default \f5rcvfill\fR routine \f5read\fRs the data and places it in the \f5RCV\fR queue with no intermediate processing. An application can provide its own \f5rcvfill\fR routine if the data must be decoded before it is queued. An application supplied \f5rcvfill\fR routine should \f5read\fR the data available from the \fIhost\fR process, decode the message, and place the results in the receive queue with the routine .DS I N 10 \f5rcvbfill(buf, cnt) char *buf; int cnt;\fR .DE .P \f5Rcvbfill\fR copies \f5cnt\fR bytes of data starting at \f5buf\fR into the receive queue and sets the \f5RCV\fR flag in \f5P->state\fR. The routine \f5rcvchar\fR retrieves the data from the receive queue. .P Programs accessing files can use the standard I/O library. Care should be taken not to block while \f5read\fRing device file descriptors or the emulator library may not work correctly. For example, if the X11 server blocks while attempting to send events to a client for more than several seconds, it will close down the connection. .H 3 "Timers" The 5620 timing functions, \f5sleep\fR, \f5alarm\fR and \f5realtime\fR are supported in the emulator library. \f5Sleep\fR and \f5alarm\fR take a single integer argument containing the interval in 60 hertz ticks. The amount of time before \f5sleep\fR returns or the \f5alarm\fR goes off depends on the Unix scheduler and the frequency of the Unix clock. It is rounded up to the best approximation. The \f5sleep\fR and \f5alarm\fR timers are independent of one another and may run concurrently. \f5Sleep\fR will continue to \f5read\fR and queue input while the process is delayed. .H 3 "Exchange Buffer" On the 5620, two independent tools may exchange strings by placing them in a global buffer maintained by \f5mux\fR. In the emulator library, two new functions have been added to provide a similar facility. .DS I N 10 \f5typedef struct String { char *s; /* pointer to string */ short n; /* number used, no terminal null */ short size; /* size of allocated area */ } String; getmuxbuf (str) String *str; setmuxbuf(str) String *str;\fR .DE .P The \f5String\fR structure is used in calls to set and retrieve the global buffer. It is the same structure used in the implementation of the global buffer in \f5mux\fR. \f5S\fR points to a string obtained with \f5gcalloc\fR. \f5Size\fR is the length of the allocated string and \f5n\fR is the number of bytes that contain valid data. .P \f5Setmuxbuf\fR places \f5str->n\fR bytes of the string \f5str->s\fR in the global buffer. \f5Getmuxbuf\fR retrieves a string from the global buffer. If the area pointed to by \f5str->s\fR is not large enough, the region will be freed with \f5gcfree\fR and a new string of appropriate size allocated with \f5gcalloc\fR. The number of valid characters in the returned string is placed in \f5str->n\fR. .P In X11, the global buffer is implemented with the X cut and paste buffers making it possible for tools to exchange strings with other X11 tools. The \f5suntools\fR implementation uses a temporary file that is incompatible with the tools distributed by Sun. The emulator library does not use the \f5Sunview\fR Notifier making compatibility with the \f5suntools\fR exchange buffer extremely difficult. .H 3 "Efficiency Considerations" Code making repetitive graphics calls may run inefficiently in the emulator library. This is particularly noticeable when complex objects are constructed by writing individual pixels with the function \f5point\fR. To improve performance, three new functions may be used when repetitive calls to \f5point\fR operate on a \f5Bitmap\fR with the same drawing \f5Code\fR. .DS I N 10 \f5initpoints(b, f) Bitmap *b; Code f; points(p) Point p; endpoints()\fR .DE .P The function \f5points\fR, should be substituted for each call to \f5point\fR in the repetitive sequence. The sequence is then enclosed between calls to \f5initpoints\fR and \f5endpoints\fR. .P In X11, \f5Points\fR is implemented with the X11 \f5XDrawPoints\fR operator which significantly decreases the traffic between the client and server when compared with multiple \f5XDrawPoint\fR calls. In \f5suntools\fR, \f5initpoints\fR locks the window with a semaphore. This lock avoids two system calls per subsequent graphics call and significantly speeds operation. Enclosing any long sequence of consecutive graphics operations between an \f5initpoints\fR and \f5endpoints\fR usually leads to performance improvements in \f5suntools\fR. .P As mentioned in the \fIGlobal Data Structures\fR section it is possible to call the primitives of the underlying window system. For many complex operations that are not supported by the emulator library such as filling polygons, this can lead to significant performance improvements. .H 3 "Name Space Conflicts" Several of the 5620 primitives have the same names as system calls or library subroutines in the Unix operating system. To allow applications the possibility of accessing the Unix routines, the file \f5jerq.h\fR uses the preprocessor to alter the subroutine names used in the emulator library. The redefined routines are listed below: .DS I N 10 \f5#define nap(x) jnap(x) #define wait(x) jwait(x) #define sleep(x) Jsleep(x) #define alarm(x) Jalarm(x)\fR .DE .P An application desiring access to the Unix routines of the same name should use the preprocessor \f5#undef\fR directive to remove the mappings. .H 3 "Debugging" The different environments provided by the emulator library and 5620 lead to several common program bugs related to the handling of input. On the 5620 the operating system asynchronously updates input related data structures such as the global \f5mouse\fR structure and the keyboard and receive queues. In the emulator, updates to input data structures are hidden in input routines such as \f5wait\fR, \f5nap\fR and \f5sleep\fR. Programs that poll input data structures without intervening calls to the input routines will work correctly on the 5620 but loop indefinitely in the emulator. .P The emulator library also hides other window system operations in the input routines, such as restoring damaged screen areas from the backing-store, on the assumption they will be frequently called. If an application does not call the input routines, a damaged window will not be repaired. .P The buffering of graphics calls in X11 may also lead to debugging peculiarities. Graphics requests are not received by the server until the X11 output buffer is flushed. By default, this does not occur until either a X11 call requires a response from the server, or an emulator library input routine such as \f5wait\fR or \f5nap\fR is called. The buffering of X11 graphics requests can be bypassed by setting the global integer variable, \f5_XDebug\fR, to a non-zero value before the call to \f5initdisplay\fR is made. While applications may run up to an order of magnitude slower without buffering, the output from graphics calls can be seen immediately when single stepped under the control of a debugger. .H 3 "Startup" Since the window systems use different methods to create new windows it is convenient to use a single shell file to invoke the tools. The following file can be used to start the tool \f5cip\fR for both X11 and \f5suntools\fR: .DS I N 10 \f5#!/bin/sh # If not running under suntools, assume X11 DIR=/usr/jtools if [ ! "$WINDOW_ME" ] then exec $DIR/x3bin/cip $* else exec shelltool -Wl cip -Ws 591 802 -Wp 0 80 $DIR/s3bin/cip $* fi\fR .DE .P This file assumes that X11 binaries are in \f5/usr/jtools/x3bin\fR and \f5suntools\fR binaries are in \f5/usr/jtools/s3bin\fR. If the \f5WINDOW_ME\fR environment variable is set the file assumes \f5suntools\fR is running and \f5shelltool\fR is called with the \f5suntools cip\fR binary as an argument. Otherwise it assumes that X11 is running and invokes the X11 binary. With an additional test it is possible to use the same shell file to select appropriate binaries depending on the machine's architecture. .H 3 "Running Emulator Code on the 5620" Most 5620 graphics code that is modified to run with the emulator library can also run on the 5620 provided the preprocessor maps the newly defined structures and functions back into the original 5620 primitives. The following defines cover a major percentage of the source code changes while the other emulator routines that are not 5620 primitives can be implemented in short subroutines. .DS I N 10 \f5#define Cursor Texture #define ToCursor(a,b,c,d) (*(Texture *)(a)) #define ToTexture(t) (*(Texture *)(t)) #define ToTexture32(t) (*(Texture32 *)(t)) #define fontheight(f) ((f)->height) #define fontwidth(f) ((f)->info->width) #define fontnchars(f) ((f)->n) #define initdisplay(c,v)\fR .DE .H 2 "Porting Overview" The following list summarizes how to port an application. It can be used as a step by step guide for most simple 5620 tools. .AL 1 .LI If the application requires both a \fIhost\fR and \fIterminal\fR process, the \fIhost\fR process must be connected to the \fIterminal\fR process with a bidirectional socket or pipe. If the only purpose of the \fIhost\fR process is file access and data compression, it can probably be eliminated. .LI Include the file \f5jerq.h\fR at the top of the \fIterminal\fR source file. If there are references to other 5620 related \f5#include\fR files other than \f5menu.h\fR, remove them. .LI Add the subroutine call \f5initdisplay(argc, argv)\fR early in the program. This must be called before any graphics operations are performed or any conversions of the \f5Cursors\fR, \f5Texture\fRs and initialized \f5Bitmap\fRs are made. If \f5main\fR does not have \f5argc\fR and \f5argv\fR arguments, add them. .LI Move the \f5request\fR call before the call to \f5initdisplay\fR. .LI \f5Cursors\fR, \f5Texture\fRs and initialized \f5Bitmap\fRs must be converted to the appropriate structures using the functions \f5ToCursor\fR, \f5ToTexture\fR, and \f5ToBitmap\fR respectively. Make new declarations for the object and the bits that make up the contents of the object. .LI If the constants \f5XMAX\fR and \f5YMAX\fR are used by the program, \f5Drect.corner.x\fR and \f5Drect.corner.y\fR should be substituted respectively. .LI If the members of \f5Font\fR structures are examined, it is most likely to determine the width, height, or number of characters in the font. The macros \f5fontwidth(fp)\fR, \f5fontheight(fp)\fR, and \f5fontnchars(fp)\fR should be substituted respectively. .LI If \f5addr\fR is called, an appropriate combination of \f5point\fR and \f5getpoint\fR should be substituted. .LI Compile the program with appropriate flags set for the desired run-time environment and link it with the appropriate libraries. .LE .H 2 "Sample Program" Below is a complete program that uses the emulator library. It demonstrates some simple graphics functions, mouse tracking, and the handling of keyboard input. .DS I N 10 \f5#include "jerq.h" main (argc, argv) int argc; char **argv; { int r; request(KBD|MOUSE); initdisplay(argc, argv); for(;;){ r = wait(KBD|MOUSE); if(button1()){ rectf(&display, Drect, F_CLR); rectf(&display, Rect(Drect.origin.x, Drect.origin.y, mouse.xy.x, Drect.corner.y), F_XOR); } else if(button23()) break; if(r&KBD && kbdchar() == 'y') string(&defont, "Hello", &display, Drect.origin, F_XOR); } }\fR .DE .P The calls to \f5request\fR and \f5initdisplay\fR initialize the window. When button 1 is down, the window is cleared and the section of the window to the left of the mouse is inverted. The program exits when mouse button 2 or 3 is pressed. If the character y is typed on the keyboard, the string "Hello" is toggled in the top left corner of the window. .H 1 "Comments" .H 2 "Implementation" Most of the 5620 graphics primitives were easily mapped into the primitives of X11 and \f5suntools\fR. Support of the off screen bit-maps required a little tweaking. Since X11 and \f5suntools\fR don't allow off screen bit-maps to have origin offsets, a flag was added to the \f5Bitmap\fR structure to distinguish screen from memory bit-maps. When the flag indicates a memory bit-map, functions in the emulator library transform the bit-map coordinates appropriately. In the \f5suntools\fR implementation, this flag is also used to call different low-level graphics primitives. Screen bit-maps use Sun's \f5pixwin\fR interface while memory bit-maps use the \f5pixrect\fR interface. .P The most difficult part of the emulator library was efficient construction of the I/O handlers hidden in the \f5wait\fR routine. The notification-based I/O mechanisms provided by the X toolkit and \f5SunView\fR do not map cleanly into the I/O primitives used by the 5620 tools. In the \f5suntools\fR implementation the emulator library handles window events from the operating system and does not make any use of the \f5SunView\fR notifier. Similarly, the X11 implementation directly services the X events. While decoding the window events is tedious in both environments, the code is more efficient and compact than it would have been had the higher level window interfaces been used. .P Creation of a window in both environments requires a substantial amount of code. The \f5initdisplay\fR routine required 126 lines of C source for X11 and 60 lines for \f5suntools\fR. In X11, approximately one third of the initialization code manages interactions between the tool and the window manager. These routines may be useful to application programmers who need to create a window in the different window environments but do not want to use the emulator library. .H 2 "Window Systems" Experience with the three window systems has led to some observations. .P The X11 protocol provided a rich interface to implement the emulation. Having the graphics server separate from the applications has both pros and cons. On the positive side binaries are small and all tools can be executed on remote processors. However, use of a communications channel for graphics has substantial overhead. While this is minimized by buffering output, delays are particularly noticeable for functions that require responses from the server. Reading the value of a pixel back from the screen requires at least two context switches and four system calls. .P In it's current state on the Sun, tools using the emulator library with X11 perform sluggishly when compared with \f5suntools\fR. As the X11 server code matures and becomes better tuned to the hardware, performance should improve. .P Unlike X11, it was difficult to directly handle I/O in the \f5suntools\fR environment. While the low level handling of I/O is remarkably similar to the event mechanism of X11, it is poorly documented. Many of the window system features, such as the maintenance of the border, window layout menus, and cut and paste buffers depend on the \f5SunView\fR Notifier. Providing the standard \f5suntools\fR user interface for operations such as labeling, reshaping, hiding, and moving windows requires an additional Unix process for every tool using the emulator library. .P The \f5suntools\fR environment suffers from excessive generality. For example, the cut and paste buffers can be implemented with temporary files in a few of lines of code. Sun instead opted for a much more general mechanism based on a dynamically binding interprocess communication mechanism. It depends heavily on the Notifier and requires many pages of code to implement. It appears to only be used in the implementation of the cut and paste buffers. .P This philosophy has led to another \f5suntools\fR problem: huge binaries. The smallest graphics program generated, even without pulling in the Notifier code, requires over 230 kilobytes of text space. Shared libraries in the next release of Sun's operating system software will alleviate the problem, but this wouldn't be required if the libraries were more prudently designed. .P The 5620 environment suffers from different problems. The low-bandwidth serial connection has caused many of the applications to be more complicated than necessary. Care must be taken by tool designers to insure that the data traffic between the \fIterminal\fR and \fIhost\fR processes does not overload the connection. A fair amount of the effort in designing a tool for the 5620 is in properly segmenting the work to be done on the different processors. .P A properly segmented tool does have its benefits. The separation of the display processor from the Unix engine avoids sluggish mouse behavior when the Unix processor is busy. Even when run on the same processor, separation of the tool into two processes is desirable since the \fIterminal\fR process can respond to user input while the \fIhost\fR process is busy. From a user's perspective, it is reassuring for menus to continue to pop up while a complicated operation is in progress. .H 1 "Conclusions" Using the emulator library, it is possible to port applications written for the 5620 to both X11 and \f5suntools\fR. Ported tools perform well in both X11 and \f5suntools\fR with only minor source code changes. Tools intended for the 5620 may now be used on a wide variety of hardware. .P The library can also be used as an educational tool for comparing the different window systems. An application programmer familiar with one environment can quickly find corresponding functionality in the other two environments. .SG .rs .sp -1v MH-11228/11229-DAK/JIH-dak/jih .NS 3 References (1-6) .NE xcip/LIBDMDX11/sizehints.c0000644000175300001440000000002511513632540013752 0ustar meusersjerqsizehints () { } xcip/LIBDMDX11/x11.c0000644000175300001440000003242411513632541012354 0ustar meusers#ifdef X11 #include #include "jerq.h" #if defined(BSD) || defined(SYSV) #include #ifdef SYSV #define FNDELAY O_NDELAY #endif #else /* V9 */ #include #endif /* Common */ Rectangle Drect; Bitmap display, Jfscreen; Point Joffset; struct Mouse mouse; static struct JProc sP; struct JProc *P; Font defont; int mouse_alive = 0; int mousewin = 1; int jerqrcvmask = 1; int displayfd; Cursor normalcursor; Cursor nocursor; static Jlocklevel; static short arrow_bits[] = { 0x0000, 0x0008, 0x001c, 0x003e, 0x007c, 0x00f8, 0x41f0, 0x43e0, 0x67c0, 0x6f80, 0x7f00, 0x7e00, 0x7c00, 0x7f00, 0x7fc0, 0x0000 }; #ifdef SVR4 static unsigned short arrow_mask_bits[] = { #else static short arrow_mask_bits[] = { #endif 0x0008, 0x001c, 0x003e, 0x007f, 0x00fe, 0x41fc, 0xe3f8, 0xe7f0, 0xffe0, 0xffc0, 0xff80, 0xff00, 0xff00, 0xffc0, 0xffe0, 0xffc0 }; static short off_bits[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; /* X11 only */ int JfuncOR, JfuncCLR, JfuncXOR; static int hintwidth, hintheight, hintflags; GC gc; Display *dpy; unsigned long fgpix, bgpix, tmppix; Colormap colormap; XColor fgcolor, bgcolor; static unsigned long inputmask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|StructureNotifyMask| ExposureMask|KeyPressMask|PointerMotionHintMask; unsigned char Jrevbits[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; initdisplay(argc, argv) int argc; char *argv[]; { int i; XSizeHints sizehints; XWMHints xwmhints; XSetWindowAttributes xswa; XColor ccolor; XColor tcolor; char *fgcname = 0; char *bgcname = 0; unsigned long planes; char *font; char *geom = 0; int flags; int width, height, x, y; char **ap; Visual *v; Font *fp; if(!(dpy= XOpenDisplay(NULL))){ perror("Cannot open display\n"); exit(-1); } displayfd = ConnectionNumber(dpy); font = XGetDefault(dpy, argv[0], "JerqFont"); if(font == NULL) font = "8x13"; /* EPB: closer match to 630 default than "fixed".*/ colormap = XDefaultColormap(dpy, DefaultScreen(dpy)); bgpix = WhitePixel(dpy, DefaultScreen(dpy)); fgpix = BlackPixel(dpy, DefaultScreen(dpy)); fgcname = XGetDefault(dpy,argv[0],"foreground"); bgcname = XGetDefault(dpy,argv[0],"background"); #ifdef SYSV memset(&sizehints, 0, sizeof(sizehints)); #else bzero(&sizehints, sizeof(sizehints)); #endif ap = argv; i = argc; while(i-- > 0){ if( !strcmp("-font", ap[0]) ){ font = ap[1]; i--; ap++; } else if( !strcmp("-foreground", ap[0]) || !strcmp("-fg", ap[0]) ){ fgcname = ap[1]; i--; ap++; } else if( !strcmp("-background", ap[0]) || !strcmp("-bg", ap[0]) ){ bgcname = ap[1]; i--; ap++; } else if( !strcmp("-reverse", ap[0]) || !strcmp("-rv", ap[0]) ){ tmppix = bgpix; bgpix = fgpix; fgpix = tmppix; } else if( !strcmp("-geometry", ap[0]) || !strcmp("-g", ap[0]) ){ geom = ap[1]; flags = XGeometry(dpy,DefaultScreen(dpy),geom,0, 0,1,1,0,0,&x,&y,&width,&height); if(WidthValue & flags){ sizehints.flags |= USSize; sizehints.width = width; } if(HeightValue & flags){ sizehints.flags |= USSize; sizehints.height = height; } if(XValue & flags){ sizehints.flags |= USPosition; sizehints.x = x; } if(YValue & flags){ sizehints.flags |= USPosition; sizehints.y = y + 20; /* 20 is for titlebar. */ } i--; ap++; } ap++; } /* EPB: get default or user's font, if not found, then get "fixed" font. */ fp = XLoadQueryFont(dpy, font); if( fp ) defont = *fp; else defont = getfont("fixed"); P = &sP; sizehints.width_inc = sizehints.height_inc = 1; sizehints.min_width = sizehints.min_height = 20; sizehints.flags |= PResizeInc|PMinSize; if( !(sizehints.flags & USSize) ){ sizehints.width = defont.max_bounds.width * 80; sizehints.height = (defont.max_bounds.ascent + defont.max_bounds.descent) * 24; sizehints.flags |= PSize; jerqsizehints(); if (hintwidth) sizehints.width = hintwidth; if (hintheight) sizehints.height = hintheight; if (hintflags) { sizehints.min_width = hintwidth; sizehints.min_height = hintheight; } } if (fgcname || bgcname) { v = DefaultVisual(dpy, DefaultScreen(dpy)); if (DefaultDepth(dpy, DefaultScreen(dpy)) != 1 && (v->class == PseudoColor || v->class == GrayScale)) { if (!fgcname) fgcname = "black"; if (!bgcname) bgcname = "white"; if (!XAllocColorCells(dpy,colormap,False,&planes,1, &bgpix, 1)) { perror("Cannot alloc color cells\n"); exit(1); } fgpix = bgpix | planes; XStoreNamedColor(dpy,colormap,fgcname,fgpix, DoRed|DoGreen|DoBlue); XStoreNamedColor(dpy,colormap,bgcname,bgpix, DoRed|DoGreen|DoBlue); } else { if (fgcname && XAllocNamedColor(dpy,colormap,fgcname, &ccolor,&tcolor)) fgpix = ccolor.pixel; if (bgcname && XAllocNamedColor(dpy,colormap,bgcname, &ccolor,&tcolor)) bgpix = ccolor.pixel; } } xswa.event_mask = 0; xswa.background_pixel = bgpix; xswa.border_pixel = fgpix; display.dr = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)), sizehints.x,sizehints.y, sizehints.width, sizehints.height, 2, 0, InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWEventMask | CWBackPixel | CWBorderPixel, &xswa); XSetStandardProperties(dpy, display.dr, argv[0], argv[0], None, argv, argc, &sizehints); xwmhints.input = True; xwmhints.flags = InputHint; XSetWMHints(dpy, display.dr, &xwmhints); XSelectInput(dpy, display.dr, inputmask); XMapWindow(dpy, display.dr); fgcolor.pixel = fgpix; bgcolor.pixel = bgpix; XQueryColor(dpy, colormap, &fgcolor); XQueryColor(dpy, colormap, &bgcolor); gc = XDefaultGC(dpy, DefaultScreen(dpy)); XSetForeground(dpy, gc, fgpix); XSetBackground(dpy, gc, bgpix); XSetWindowBackground(dpy, display.dr, bgpix); if ((fgpix^bgpix)&fgpix) { JfuncOR = GXor; JfuncCLR = GXandInverted; JfuncXOR = GXxor; } else { JfuncOR = GXand; JfuncCLR = GXorInverted; JfuncXOR = GXequiv; } XSetFont(dpy, gc, defont.fid); XSetLineAttributes(dpy, gc, 0, LineSolid, CapNotLast, JoinMiter); Drect.origin.x = 0; Drect.origin.y = 0; Drect.corner.x = sizehints.width; Drect.corner.y = sizehints.height; display.rect = Drect; #ifdef XBUG Jfscreen = display; #else Jfscreen.dr = RootWindow(dpy, DefaultScreen(dpy)); Jfscreen.rect.origin.x = 0; Jfscreen.rect.origin.y = 0; Jfscreen.rect.corner.x = DisplayWidth(dpy, DefaultScreen(dpy)); Jfscreen.rect.corner.y = DisplayHeight(dpy, DefaultScreen(dpy)); #endif /*XBUG*/ normalcursor = ToCursor(arrow_bits, (short *)arrow_mask_bits, 1, 15); nocursor = ToCursor(off_bits, (short *)off_bits, 1, 15); cursswitch(&normalcursor); unset_clip(); while(!(P->state & RESHAPED)) { while (XPending(dpy)) handleinput(); } } /* This must be called before initdisplay */ mousemotion () { mouse_alive = 1; inputmask |= PointerMotionMask; } setsizehints (width, height, flags) { hintwidth = width; hintheight = height; hintflags = flags; } request(what) int what; { if(what & SEND) #if defined(BSD) || defined(SYSV) fcntl(1, F_SETFL, FNDELAY);; #else ioctl(1, FIOWNBLK, 0); #endif if(!(what & RCV)) jerqrcvmask = 0; } Bitmap * balloc (r) Rectangle r; { Bitmap *b; b = (Bitmap *)malloc(sizeof (struct Bitmap)); b->dr = XCreatePixmap(dpy, display.dr, r.cor.x-r.org.x, r.cor.y-r.org.y, DefaultDepth(dpy, DefaultScreen(dpy))); b->flag = BI_OFFSCREEN; b->rect=r; rectf (b, r, F_CLR); return b; } void bfree(b) Bitmap *b; { if(b) { XFreePixmap(dpy, b->dr); free((char *)b); } } Font getfont(s) char *s; { Font *fp; fp = XLoadQueryFont(dpy, s); return fp ? *fp : defont; } Point string (f, s, b, p, c) Font *f; char *s; Bitmap *b; Point p; Code c; { XSetFont(dpy, gc, f->fid); if(b->flag & BI_OFFSCREEN) p = sub(p, b->rect.origin); if(c == F_STORE) { XSetForeground(dpy, gc, fgpix); XDrawImageString(dpy, b->dr, gc, p.x, p.y + f->max_bounds.ascent, s, strlen(s)); } else { XSetFunction(dpy, gc, c); if (c == F_XOR) XSetForeground(dpy, gc, fgpix^bgpix); else XSetForeground(dpy, gc, fgpix); XDrawString(dpy, b->dr, gc, p.x, p.y + f->max_bounds.ascent, s, strlen(s)); } XSetFont(dpy, gc, defont.fid); return(add(p, Pt(strwidth(f,s),0))); } int strwidth (f, s) Font *f; register char *s; { return XTextWidth(f, s, strlen(s)); } /* * Convert a blit style texture to a pixmap which can be used in tiling * or cursor operations. */ Texture ToTexture(bits) register short *bits; { unsigned char mybits[32]; register unsigned char *to; for (to = mybits; to < &mybits[32]; bits++) { *to++ = Jrevbits[(*bits >> 8) & 0xFF]; *to++ = Jrevbits[*bits & 0xFF]; } return XCreateBitmapFromData(dpy,display.dr, mybits, 16, 16); } Cursor ToCursor (source, mask, hotx, hoty) short source[], mask[]; { Texture sp, mp; Cursor c; sp = ToTexture(source); mp = ToTexture(mask); c = XCreatePixmapCursor(dpy, sp, mp, &fgcolor, &bgcolor, hotx, hoty); XFreePixmap(dpy, sp); XFreePixmap(dpy, mp); return(c); } #undef button handleinput () { XEvent ev; KeySym key; unsigned char s[128], *cp; int n; Window rw, cw; int xr, yr, xw, yw; unsigned bstate; for(;;){ XNextEvent(dpy, &ev); switch (ev.type) { case ButtonPress: mouse.buttons |= (8 >> ev.xbutton.button); mouse.xy.x = ev.xbutton.x; mouse.xy.y = ev.xbutton.y; mouse.time = ev.xbutton.time; break; case ButtonRelease: mouse.buttons &= ~(8 >> ev.xbutton.button); mouse.xy.x = ev.xbutton.x; mouse.xy.y = ev.xbutton.y; mouse.time = ev.xbutton.time; break; case MotionNotify: XQueryPointer(dpy, display.dr, &rw, &cw, &xr, &yr, &xw, &yw, &bstate); if(button123() && bstate==0) continue; mouse.xy.x = xw; mouse.xy.y = yw; break; case MapNotify: case NoExpose: break; case ConfigureNotify: if (display.rect.corner.x != ev.xconfigure.width || display.rect.corner.y != ev.xconfigure.height) { display.rect.corner.x = ev.xconfigure.width; display.rect.corner.y = ev.xconfigure.height; Drect = display.rect; #ifdef XBUG Jfscreen = display; #endif unset_clip(); } break; case Expose: while (XCheckTypedEvent(dpy, Expose, &ev)) ; rectf(&display, Drect, F_CLR); P->state |= RESHAPED; break; case KeyPress: mouse.xy.x = ev.xkey.x; mouse.xy.y = ev.xkey.y; mouse.time = ev.xkey.time; n = XLookupString(&ev.xkey, s, sizeof(s), NULL, NULL); if(n > 0){ cp = s; P->state |= KBD; do{ kbdread(cp++); } while (--n); } break; default: break; } return; } } /* * GRABMASK stolen from PointerGrabMask in X11R4/server/dix/events.c * otherwise X11R4 rejects the XGrabPointer */ #define GRABMASK (ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask | PointerMotionHintMask \ | KeymapStateMask | PointerMotionMask | Button1MotionMask | \ Button2MotionMask | Button3MotionMask | ButtonMotionMask ) Jscreengrab() { if (!Jlocklevel) { #ifndef XBUG int dxr, dyr; Window child; XTranslateCoordinates(dpy, display.dr, DefaultRootWindow(dpy), 0,0,&dxr,&dyr, &child); Joffset.x = dxr; Joffset.y = dyr; #endif #if 0 while (XGrabPointer(dpy, display.dr, False, inputmask & GRABMASK, GrabModeAsync, GrabModeAsync, None, *P->cursor, CurrentTime) != GrabSuccess) sleep(6); #endif XSetSubwindowMode(dpy, gc, IncludeInferiors); } Jlocklevel++; } Jscreenrelease() { if (--Jlocklevel <= 0) { Jlocklevel = 0; #if 0 XUngrabPointer(dpy, CurrentTime); #endif XSetSubwindowMode(dpy, gc, ClipByChildren); } } ringbell () { XBell(dpy,50); } set_clip(r) Rectangle r; { XRectangle xr; xr.x = r.origin.x; xr.y = r.origin.y; xr.width = r.corner.x - r.origin.x; xr.height = r.corner.y - r.origin.y; XSetClipRectangles(dpy, gc, r.origin.x, r.origin.y, &xr, 1, Unsorted); } unset_clip() { set_clip(Drect); } #endif /*X11*/ xcip/LIBDMDX11/jerq.h0000644000175300001440000001202111513632541012700 0ustar meusers#ifndef JERQ_H #define JERQ_H #ifdef X11 #include #include #include #ifdef BSD #include #endif /* BSD */ #ifdef SYSV #ifndef SVR4 #include "/usr/X/include/sys/time.h" #else #include #endif #endif #endif /* X11 */ #ifdef SUNTOOLS #include #undef Rect #endif /* SUNTOOLS */ #ifndef NULL #define NULL 0 #endif #define nap(x) jnap(x) #define wait(x) jwait(x) #define Menu JMenu #define sleep(x) Jsleep(x) #define alarm(x) Jalarm(x) #define own() (P->state|MOUSE) #define havemouse() mousewin typedef int Word; /* 32 bits */ typedef unsigned int UWord; /* 32 bits */ typedef struct Point { /* short and to the point */ short x; short y; } Point; typedef struct Rectangle { Point origin; Point corner; } Rectangle; #define cor corner #define org origin typedef struct Bitmap { #ifdef X11 Drawable dr; #endif /* X11 */ #ifdef SUNTOOLS char *dr; #endif /* SUNTOOLS */ Rectangle rect; int flag; #define BI_OFFSCREEN 1 /* Offscreen if set */ } Bitmap; typedef struct Menu{ char **item; /* string array, ending with 0 */ char *(*generator)(); /* used if item == 0 */ short prevhit; /* private to menuhit() */ short prevtop; /* private to menuhit() */ } Menu; struct Mouse { Point xy; int buttons; unsigned long time; }; #define min(x,y) (((x) < (y)) ? (x) : (y)) #define max(x,y) (((x) > (y)) ? (x) : (y)) #ifdef X11 typedef Pixmap Texture; typedef Pixmap Texture32; #define Font XFontStruct #define fontheight(fp) ((fp)->max_bounds.ascent + (fp)->max_bounds.descent) #if 0 #define fontwidth(fp,c) ((fp)->max_bounds.width) #else #define fontwidth(fp,c) (XTextWidth((fp), &(c), 1)) #define ave_fontwid(fp) ((fp)->max_bounds.width) #endif #define fontnchars(fp) ((fp)->max_char_or_byte2+1) #endif /* X11 */ #ifdef SUNTOOLS typedef short *Texture; typedef Word *Texture32; typedef Pixfont *Font; #define fontheight(fp) ((*fp)->pf_defaultsize.y) #define fontwidth(fp) ((*fp)->pf_defaultsize.x) #define fontnchars(fp) 255 #define Cursor JCursor typedef struct Cursor { short *bits; short hotx; short hoty; } Cursor; #endif /* SUNTOOLS */ struct JProc { int state; Cursor *cursor; }; #define RESHAPED 1 /* window has been changed */ #define KBD 2 /* we have keyboard input */ #define RCV 4 /* recevied from "host" proc */ #define MOUSE 8 /* we always have the mouse */ #define SEND 16 /* for request compatability */ #define CPU 32 #define ALARM 64 typedef int Code; #define Rect(a,b,c,d) SRect(a,b,c,d) extern Point Pt(); extern Rectangle SRect(); extern Rectangle Rpt(); #define muldiv(a,b,c) ((long)((a)*((long)b)/(c))) /* * Function Codes */ #ifdef X11 #define F_STORE (GXcopy) /* target = source */ #define F_XOR (GXxor) /* target ^= source */ #define F_OR (JfuncOR) /* function depends on pixel values */ #define F_CLR (JfuncCLR) #endif /* X11 */ #ifdef SUNTOOLS #define F_STORE (PIX_SRC) /* target = source */ #define F_OR (PIX_SRC | PIX_DST) /* target |= source */ #define F_CLR (PIX_NOT(PIX_SRC)&PIX_DST) /* target &= ~source */ #define F_XOR (PIX_SRC ^ PIX_DST) /* target ^= source */ #endif /* SUNTOOLS */ #define button(i) (mouse.buttons&(8>>i)) #define bttn(i) button((i)) #define button1() (mouse.buttons&4) #define bttn1() button1() #define button2() (mouse.buttons&2) #define bttn2() button2() #define button3() (mouse.buttons&1) #define bttn3() button3() #define button12() (mouse.buttons&6) #define bttn12() button12() #define button13() (mouse.buttons&5) #define bttn13() button13() #define button23() (mouse.buttons&3) #define bttn23() button23() #define button123() (mouse.buttons&7) #define bttn123() button123() Rectangle getrectb(), getrect(); #define getrect1() getrectb(4,1) #define getrect2() getrectb(2,1) #define getrect3() getrectb(1,1) #define getrect12() getrectb(6,1) #define getrect13() getrectb(5,1) #define getrect23() getrectb(3,1) #define getrect123() getrectb(7,1) extern Point add(), sub(), mul(), div(), string(); extern Rectangle rsubp(), raddp(), inset(); extern Bitmap *balloc(); extern char *gcalloc(); extern void bfree(), gcfree(); extern void rectf(), rectfD(), bitblt(), bitbltD(), texture(), evtomouse(); #define alloc(n) calloc(n,1) #ifdef X11 extern Texture ToTexture(); extern Texture32 ToTexture32(); extern GC gc; extern Display *dpy; extern unsigned long fgpix, bgpix; extern Colormap colormap; extern XColor fgcolor, bgcolor; extern int JfuncOR, JfuncCLR, JfuncXOR; #define jerqsync() XSynchronize(dpy, 1) #endif /* X11 */ #ifdef SUNTOOLS extern Pixwin *displaypw; extern int damagedone; #ifdef sun386 extern Texture ToTexture(); extern Texture32 ToTexture32(); #else #define ToTexture(x) x #define ToTexture32(x) x #endif #define jerqsync() #endif /* SUNTOOLS */ extern Font getfont(); extern Rectangle Drect; extern Bitmap display, Jfscreen, ToBitmap(); extern Point Joffset; extern int displayfd; extern int jerqrcvmask; extern Cursor ToCursor(), *cursswitch(), normalcursor; extern struct Mouse mouse; extern struct JProc *P; extern Font defont; extern int mousewin; #endif /* JERQ_H */ xcip/LIBDMDX11/ToBitmap.c0000644000175300001440000000257011513632541013461 0ustar meusers#include Bitmap ToBitmap(bits, bytewidth, ox, oy, cx, cy) char *bits; { Bitmap *bm; int dx, dy; register unsigned char *to; int i, lbytes; #ifdef X11 Pixmap pm; unsigned char *mybits; char *malloc(); extern unsigned char Jrevbits[256]; register short *sp; int j; #endif /*X11*/ dx = cx - ox; dy = cy - oy; bm = balloc(Rect(ox, oy, cx, cy)); #ifdef X11 /* * Convert bits from jerq to X11 bitmap format - assumes shorts * chars and longs will also work on 68k word order machines * but not on others (i.e. VAX, 386) */ lbytes = (dx + 7)/8; mybits = (unsigned char *)malloc(lbytes * dy + 4); for(i = 0; i < dy; i++) { to = mybits + i * lbytes; sp = (short *)(bits + i * bytewidth); for (j = (dx + 15)/16; j; j--, sp++) { *to++ = Jrevbits[(*sp >> 8) & 0xFF]; *to++ = Jrevbits[*sp & 0xFF]; } } pm = XCreateBitmapFromData(dpy, display.dr, mybits, dx, dy); /* * Now convert the Bitmap to a Pixmap of the correct depth */ XSetForeground(dpy, gc, fgpix); XSetFunction(dpy, gc, GXcopy); XCopyPlane(dpy, pm, bm->dr, gc, 0, 0, dx, dy, 0, 0, 1); XFreePixmap(dpy, pm); free(mybits); #endif /*X11*/ #ifdef SUNTOOLS lbytes = mpr_d((Pixrect *)bm->dr)->md_linebytes; to = (unsigned char *)mpr_d((Pixrect *)bm->dr)->md_image; for(i = 0; i < dy; i++) { bcopy(bits, to, lbytes); to += lbytes; bits += bytewidth; } #endif /*SUNTOOLS*/ return *bm; } xcip/LIBDMDX11/save.c0000644000175300001440000007457311513632541012714 0ustar meusers#include /* TMENUHIT */ #include #include #define disp Jfscreen #define XMIN disp.rect.origin.x #define XMAX disp.rect.corner.x #define YMIN disp.rect.origin.y #define YMAX disp.rect.corner.y static short checkmark[] = { /* check mark */ 0x0000, 0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0070, 0x00E0, 0x61E0, 0x73C0, 0x3F80, 0x3F00, 0x1E00, 0x1E00, 0x0C00, 0x0000, }; static int firsttime = 1; Bitmap B_checkmark; static short rtarrow[] = { /* right arrow */ 0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00E0, 0x00F8, 0xFFFE, 0xFFFE, 0x00F8, 0x00E0, 0x00C0, 0x00C0, 0x0080, 0x0000, 0x0000, }; Bitmap B_rtarrow; static short black[] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, }; #define T_black FuBaR Texture T_black; static short grey[] = { 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, }; Texture T_grey; int cursxyonly; /* * Macro definitions for commonly used functions. * * scale() - converts value from scalar to another another. * * bound() - insures that a value is between two bounds and * will assign the boundary value should the input * value exceeds the bounds. * xyon() - sets the cursxyonly variable * xyoff() - clears the cursxyonly variable */ #define scale(x, inmin, inmax, outmin, outmax)\ (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin)) #define bound(x, low, high) min(high, max( low, x )) #define xyon() cursxyonly=1 #define xyoff() cursxyonly=0 /* * Constant definitions. * * BORDER - the thickness in pixels for the border * surrounding a menu. * DISPLAY - maximum number of menu items displayed per menu. * DELTA - used in scroll bar for hysterisis checks * BARWIDTH - width of the rectangle for the scroll bar * SPACEPAD - spacing in pixels for use between text and icons * MAXDEPTH - maximum levels depth for nesting menus * MAXCHARS - maximum number of characters allowed per text line. * SELECT,NOSELECT - = tmselect, did a menu selection occur. */ #define BORDER 2 #define DISPLAY 16 #define DELTA 6 #define BARWIDTH 18 #define SPACEPAD 5 #define MAXDEPTH 8 /* don't use too much stack */ #define MAXCHARS 128 #define SELECT 1 #define NOSELECT 2 /* * Tleaf - structure definition unique for each recursion level of * menus. It contains characteristics that are global to * a given menu. * org - the origin point for the menu. * width - the width in pixels of the menu. * items - the number of items in the menu. * txtwdith- number of pixels of the widest text string. * tbranch - contains the coordinates for a rectangle that is * associated with a sub-menu. Except for when treegrow is * set, a submenu can only be displayed while the mouse * cursor is in that menu or its tbranch. * spacing - the number of pixels allocated to the vertical spacing * of items. It is 4 pixels plus the larger of the icons * or the font height. * iconwidth - * the number of pixels allocated horizontally for all * icons. If zero, then no icons are used. * md - menu data for the tleaf * newhit - last hit in the menu */ typedef struct Tleaf { Point org; int width; int items; int txtwidth; Rectangle tbranch; char spacing; char iconwidth; struct menudata *md; int newhit; } Tleaf; /* * Globals * * tnoret - the address of this variable is used whenever a non- * selection is made. * tfill - character array used for generating the text string * used for menu items * treegrow - a flag that when set indicates that sub-menus should * be generated to the lowest leaf based on the previous * values. This is used when menus are generated * initially on a button depression. * tleaf[] - array of type structure Tleaf that contains information * regarding the size and screen location of menus. * tuser_mi - contains a pointer to the menu item in the user's * defined menu structure. * select_menu - the menu that a selection was made from. * tmselect - true is selection is made. If a menu item was selected, * it equals SELECT, otherwise it equals NOSELECT * setorg - set origin of root menu * redraw - redraw menu after selection * wasredraw - returning from a "redraw" via tm_ret(), don't * update prevhit/prevtop because it was already done * and it would break setup's use of tmenuhit * tstatic - flag that indicates a static menu. */ char tfill[MAXCHARS]; int treegrow; Tleaf tleaf[MAXDEPTH]; Titem *tuser_mi; Tmenu *select_menu; int tmselect; int setorg; int redraw; int wasredraw; int tstatic; /* * Titem temp - * a working structure of type Titem used to store the * converted user Titem structure into the internal Titem * structure for processing by the tmhit() code. * * tablegen(i, m) - * The default menu generator for the tmenuhit() routine. * The generator returns an address to a menu item. This * will normally be pointing to the "temp" menu item. * If a user specified menu generator is provided, it is * called here. */ Titem temp; Titem * tablegen(i, m) int i; register Tmenu *m; { register unsigned long *fptr; register unsigned long *tptr; register int count; register unsigned int mask; register int menumap; /* * check the menumap variable. if not defined, then * set it to all fields, else force the text field to * to always be defined in addition to the user's * definition. */ menumap = (m->menumap) ? m->menumap | TM_TEXT : 0xffff; /* * get the titem variable, whether it comes from a generator * function, or is in an array of titems. */ if (m->item == 0) { fptr = (unsigned long *) m->generator(i, m); tuser_mi = (Titem *) fptr; temp = *(Titem *)fptr; } else { for(fptr=(unsigned long *)m->item, mask=0x01; mask != MAX_MASK; mask<<=1) if (menumap & mask) fptr += i; tuser_mi = (Titem *) fptr; /* * set up the from and to pointers, initialize count, and build * the temp structure from the user Titem structure. */ tptr = (unsigned long *) &temp; for(count=0, mask=0x01; count < MAX_TMFIELDS; count++, menumap>>=1) { if (menumap & mask) *tptr++ = *fptr++; else *tptr++ = (unsigned long) 0; } } /* * if the font pointer is not defined, set it to defont. */ if (temp.font == 0) temp.font = &defont; return(&temp); } /* * tmenuhit(m, but, flags) * - entry point for the menuhit routine for tree menus. * It takes four arguments. "m" is a pointer to a * menu routine of type structure Tmenu. "but" is * the button that is assumed to be depressed when * this function is called. When this button is released, * a selection (or non-selection) is made. "expand" is * a flag that application programs can set. When set, * tmenuhit() will initially generate the menu tree to * its lowest leaf based on previous selection values. * "p" is the position of the origin of the root menu. * If p.x or p.y are invalid, the menu is centered on * the mouse. * * tmenuhit() calls scanmenu() to determine the sizes of the * menu and its sub-menus. These sizes are then used to * determine the origin point for each of the menus. These * points are stored in the global variable tleaf[]. tmhit() * is then called with a pointer to the menu structure and that * function will draw each of the menus. */ Titem * tmenuhit(m, but, flags) register Tmenu *m; { register Tmenu *curr_m, *next_m; register Tleaf *t; register int depth; register Point *p; void tmhit(); Tmenu * scanmenu(); if (firsttime) { firsttime = 0; B_checkmark = ToBitmap((char *)checkmark, 2, 0, 0, 16, 16); B_rtarrow = ToBitmap((char *)rtarrow, 2, 0, 0, 16, 16); T_grey = ToTexture(grey); T_black = ToTexture(black); } treegrow = flags & TM_EXPAND; wasredraw = redraw = flags & TM_NORET; tstatic = flags & TM_STATIC; if(setorg = (flags & TM_POINT)) p = (Point *)(&flags + 1); curr_m = m; t = &tleaf[0]; depth = 0; /* * scan menus to determine the sizes of the menus for this * tree growth. */ do { next_m = scanmenu(curr_m, t++); depth++; } while ((curr_m = next_m) && treegrow); /* * set up origin points for each of the menus such that * the bottom-most leaf menu is centered around the mouse * cursor. However, make sure that the menus stay within * screen borders and that maximum overlap cannot occur. * If the mouse cursor is such that it cannot remain in the * bottom most leaf menu and still maintain the non- * overlap requirement, then those menus to the right of * the the mouse will not be displayed. * * The user will have to grow them by sliding the mouse * manually to the right. */ Jscreengrab(); --t; --depth; if(!setorg) { Point tmp; /* * center the menu on the mouse */ tmp = add(mouse.xy,Joffset); t->org.y = tmp.y; t->org.x = bound(tmp.x - (SPACEPAD + (t->iconwidth ? t->iconwidth+SPACEPAD : 0) + t->txtwidth + (t->items > DISPLAY ? BARWIDTH : 0)), XMIN, XMAX-t->width ); for(--t, --depth; t >= &tleaf[0]; --t, --depth) { t->org.x = bound((t+1)->org.x - t->width + (BORDER-1), XMIN, XMAX); t->org.y = (t+1)->org.y; } t++; depth++; } else { /* * put the root menu's origin at p */ t = t - depth; t->org = *p; if((*p).x > XMAX - t->width) t->org.x = XMAX - t->width; t->org.y += bound(m->prevhit, YMIN, min(DISPLAY,t->items)-1)*t->spacing + t->spacing/2; } if (t->org.x == XMIN || setorg) { /* * We've hit the left side, assume overlap has occurred, * and recalculate menu origins. * * Otherwise, the origin point for the root menu was specified. */ for(++t, ++depth; depth < MAXDEPTH; t++, depth++) { t->org.x = bound((t-1)->org.x + (t-1)->width - (BORDER-1), XMIN, XMAX); t->org.y = (t-1)->org.y; } } tmselect = 0; tmhit(m, but, 0); Jscreenrelease(); if(tmselect == SELECT) { /* * make sure the Titem returned is correct if it is * filled in by a generator function */ tablegen(select_menu->prevhit + select_menu->prevtop, select_menu); return(tuser_mi); } else return((Titem *)0); } /* * menudata - A structure used in each recursion. It is a collection * data that is relevant to tmhit() and subroutines that * it calls. This is a single pointer to this structure * that is passed to routines rather than each individual * variable. * m - Member of structure menudata. It points to the menu * data structure containing the information supplied * by the application program for the tmenuhit() function. * top - indicates the index of the topmost item in the * menu to be displayed. This is used only for scrolling * menus. * lines - the number of lines to be displayed in the menu. This * be equal to DISPLAY or is less if the total number of * menu items for a given menu is less. * br - rectangle which defines the scroll bar display. * sr - defines the rectangle that the scroll bar can travel * within. * tr - defines the rectangle for the text portion of the menu. * mr - defines the entire rectangle for the menu. * b - pointer to a bitmap which is dynamically assigned * whenever a menu is generated. This bitmap stores * the area that is obscured by the menu. If no memory * is available, the pointer is not used and the menu * is XOR'ed on top of the existing background. */ typedef struct menudata { Tmenu *m; int top, lines; Rectangle br, sr, tr, mr; /* bar, scroll, text, menu */ Bitmap *b; } Menudata; /* * tmhit(m, but, depth) * - This is the heart of the menu routine. "m" contains * a pointer to a Tmenu structure. "but" is the button * number associated with this menu selection. This * number is needed so it is known which of the remaining * two buttons are available for use as help buttons. * "depth" is passed onto the subroutines called by this * routine to acquire information previously determined * for each of the menus and sub-menus involved in the * initial generation of the menu tree. The depth is also * used to compare against the maximum limit of MAXDEPTH * so as to prevent too much use of the stack space and * the subsequent problems that can result. * * After the initial generation of the menu tree, this * routine basically loops, waiting for mouse input to * determine which menu selection should be highlighted, * whether to exit a sub-menu, or whether to generate a * new sub-menu. * * This routine exits when the "but" button is released * or when the user moves the mouse outside of the right * arrow rectangle or to the left of the menu. * */ void tmhit(m, but, depth) register Tmenu *m; { /* * Definitions of the following stack variables. * * p - contains the mouse position. This variable * also has a shared function initially to * store the origin point for a menu. * savep - contains the old mouse position from the last * poll. This is used only with the scroll bar * to determine whether cursset() is used to keep * the mouse within the scroll bar when it is * being moved. * rside - defines the rectangle where are the sub-menu * icons (B_rtarrow) are displayed in the menu. * When the mouse cursor is in this area, checking * for the existence of a sub-menu is made. * rhit - The rectangle defining the area of the menu * item that is selected. These coordinates are * used for calculating the values of the rectangle * "tbranch", and for calculating the values of the * rectangle for help menus. * mi - pointer to the current menu item of type structure * Titem. * mdata - A structure of the type Menudata that contains * the information regarding the size and layout * of the menu for this depth. This structure was * defined so that a larger number of variables can * passed with a single pointer to different subroutines. * t - Pointer to a global structure that contains the * origin point for a menu at a given depth. These * are generated in tmenuhit() and passed to tmhit() * for the initial generation of the menu tree. They * are changed whenever the a new sub-menu is made. * newtop - contains the index of the menu item that is to * displayed for the menu. Normally this value will * zero, except when scrolling menus are used. * hit - The index value used to indicate the current menu item * that is selected. This value is offset by the value * newtop or md->top to determine the true index into * the menu items for a given menu. * newhit - Functions the same as newhit except it represents * the latest value. "hit" is then updated to * "newhit" after "newhit" has been validated. Validation * includes that the value is not a hit on a greyed item, * and that the value is adjusted (through hysterisis) * to insure that the mouse has been fully moved over * a new selection. */ Point p, savep; Rectangle rside, rhit; register Titem *mi; Menudata mdata; register Tleaf *t; register Menudata *md; register int newtop, hit, newhit, greyed; Tmenu *scanmenu(); #define sro md->sr.origin #define src md->sr.corner #define tro md->tr.origin #define trc md->tr.corner #define mro md->mr.origin #define mrc md->mr.corner #define bro md->br.origin #define brc md->br.corner #define tbro tbranch.origin #define tbrc tbranch.corner /* * Set-up data and other pointers for globals and data to be * passed to other subroutines. This includes the origin point * for the menu, and data regarding the size of the menu itself. */ t = &tleaf[depth]; p = t->org; md = &mdata; md->m = m; /* * If the treegrow flag is set, then this is a first invocation of * the menu tree and menus are to be generated to the bottom most * leaf based on the previous values stored in the menu data * structures. These will be zero if these menus are called for the * first time ever. * * Otherwise, each menu must be scanned by scanmenu() to generate the * necessary data information concerning the menu to be generated. */ tmhit_top: if (!treegrow) { scanmenu(m, t); } if((t->items == 0) || ((t+1)->org.x > add(mouse.xy, Joffset).x)) /* * Unset the treegrow flag if we hit a menu that * is zero-sized or if we have a case of overlapping * menus that caused the menu origins to be re- * calculated and therefore moved to the right of * of the mouse. */ treegrow = 0; /* * Set-up all the rectangles which define the size and layout of * the menu to be generated. Adjustments are made to the origin * for the menu depending on whether or not it fits on the screen. */ mro.x = mro.y = 0; sro.x = sro.y = src.x = tro.x = tro.y = BORDER; bro.x = bro.y = brc.x = brc.y = BORDER; if(t->items <= DISPLAY) md->lines = t->items; else { md->lines = DISPLAY; tro.x += BARWIDTH; src.x += BARWIDTH; } mrc = add(mro, Pt(t->width, min(t->items, md->lines)*t->spacing + BORDER*2)); trc = add(mrc, Pt(-BORDER,-BORDER)); src.y = trc.y; newtop = bound(m->prevtop, 0, t->items - md->lines); p.y -= bound(m->prevhit, 0, md->lines-1)*t->spacing+t->spacing/2; p.x = bound(p.x, XMIN, XMAX-mrc.x); p.y = bound(p.y, YMIN, YMAX-mrc.y); md->sr = raddp(md->sr, p); md->tr = raddp(md->tr, p); md->mr = raddp(md->mr, p); rside = md->mr; rside.origin.x = rside.corner.x - 20 - BORDER; /* * See if there is enough memory to save the bitmap for the * area of the screen that will be obscured as result of the * menu display. If there is, then bitblt that portion of the * screen to the allocated memory. Then clear the screen and * draw the menu border. Additional testing is done to insure * that should the menu be too large to fit in a screen bitmap, * the rectangle of the menu is clipped to the bitmap of the screen. * The variable rhit is temporarily used to store the clipped rect. * * If there isn't enough bitmap memory, then just XOR the menu. */ rhit = md->mr; rectclip(&rhit, disp.rect); md->b = balloc(rhit); cursinhibit(); if(md->b) bitblt(&disp, rhit, md->b, rhit.origin, F_STORE); rectf(&disp, md->mr, (md->b ? F_CLR:F_XOR)); if(md->b) rectf(&disp, inset(md->mr, BORDER-1), F_OR); rectf(&disp, inset(md->mr, BORDER), (md->b ? F_CLR:F_XOR)); cursallow(); /* * Begin that part of the routine where the drawing of the menu * commences. Set up the proper value for the menu item that * will the first item in the display (if this is a scrolling menu, * otherwise this value will be zero). A call to the drawmenu() * routine is made which performs the actual drawing of the menu * contents. */ PaintMenu: md->top = newtop; drawmenu(&mdata, t); mi = 0; /* * This is the major looping code that processes the movement of the * mouse and whether there were any help menus requested. Movement * of the mouse on a sub-menu icon (the B_rtarrow icon) generates a * recursive call to this routine to display the submenu. A current * menu is exited by moving the mouse to the left of the current menu * display except for the topmost (root) menu or when the menu button * is released. Because of race conditions it is possible to change * the button state multiple times, therefore to insure that this * subroutine exits, if tmselect is non-zero, we're really exiting. */ p = add(mouse.xy, Joffset); for(newhit = hit = -1; ((tstatic && ((but && !bttn(but)) || (!but && !bttn123()))) || (!tstatic && ((but && bttn(but)) || (!but && bttn123())))) && (tmselect == 0); nap(2)) { savep=p; p = add(mouse.xy, Joffset); if(cursxyonly && !eqpt(savep, p)) { register int deltax, deltay; /* ** Fake 630 firmware for x-y mouse movement */ deltax = p.x - savep.x; deltay = p.y - savep.y; if (deltax < 0) deltax = -deltax; if (deltay < 0) deltay = -deltay; if (deltax > deltay) p.y = savep.y; else p.x = savep.x; cursset(sub(p,Joffset)); cursset(p); } /* * Set the mouse movement for x-y only mode when the * mouse cursor is within a menu. */ if(ptinrect(p, t->tbranch) || ptinrect(p, md->mr)) xyon(); else xyoff(); /* * Check if the menu should be exited because we are not * generating the entire tree and the mouse is not in the * in the sub-menu icon of the previous menu and the * mouse is to the left of the current menu. */ if(!treegrow && !ptinrect(p, t->tbranch) && depth && (p.x < mro.x)) { break; } /* * Processing when the mouse is in the scroll bar region. */ if(ptinrect(p, md->sr)){ /* * we are still in the scroll bar, so update the * menu appropriately to give the appearance of * scrolling. */ if (ptinrect(p, md->br) && !ptinrect(savep,md->br)){ p.y = (bro.y+brc.y)/2; cursset(sub(p,Joffset)); } if (ptinrect(p, md->br) || ptinrect(savep,md->br)){ newtop = scale(p.y, sro.y, src.y, 0, t->items); newtop = bound(newtop-DISPLAY/2, 0, t->items-DISPLAY); if(newtop != md->top) { erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } } } /* * Processing to determine a menu selection */ newhit = -1; mi = 0; if(ptinrect(p, ((t->items > DISPLAY) ? md->tr:md->mr))) { newhit = bound((p.y-tro.y)/t->spacing, 0, md->lines-1); if(newhit!=hit && hit>=0 && (p.y > (tro.y + hit*t->spacing - 3)) && (p.y < (tro.y + (hit+1)*t->spacing + 3))) newhit = hit; rhit = md->tr; rhit.corner.y = (rhit.origin.y += newhit*t->spacing) + t->spacing; } if(treegrow) { /* * If we're supposed to expand, then make it look * like we've made a selection in this menu. But, * made sure that prevhit makes sense since the * size of the menu may have changed since the last * time menuhit was invoked. */ md->top = m->prevtop; if ((newhit = m->prevhit) >= md->lines) { newhit = -1; treegrow = 0; } } if(newhit != -1) { /* * Get the menu item associated with the latest * newhit value. The subroutine tablegen() also * sets the global tuser_mi which is the menu * item value that eventually is returned to the * user. */ mi = tablegen(md->top+newhit, m); } else tuser_mi = (Titem *)0; /* * Processing that is done after a selection is determined. * This includes generating the reverse video for the current * selection. */ if(newhit != hit) { if(!greyed) flip(md->tr, hit, T_black, t); if(newhit != -1) { if(mi->ufield.grey) { greyed = 1; } else { flip(md->tr, newhit, T_black, t); greyed = 0; } } hit = newhit; } /* * Processing to determine the generation of a sub-menu. * Note that if there are any user-provided functions for * executing before and returning from a sub-menu, that * occurs here. */ if((newhit != -1) && (ptinrect(p, rside) || treegrow)) { if((depth < MAXDEPTH-1) && mi->next && !(mi->ufield.grey&0x01)) { if(mi->dfn) (*mi->dfn)(tuser_mi); (t+1)->tbranch = md->tr; (t+1)->tbro.x = (t+1)->tbrc.x - 20; (t+1)->tbrc.x += BORDER; (t+1)->tbro.y = bound(tro.y + hit*t->spacing - 3, mro.y, mrc.y); (t+1)->tbrc.y = bound(tro.y + (hit+1)*t->spacing + 3, mro.y, mrc.y); if (!treegrow) { (t+1)->org.x = mrc.x - (BORDER-1); (t+1)->org.y = mro.y + newhit*t->spacing + t->spacing/2; } t->md = md; t->newhit = newhit; tmhit(mi->next, but, depth+1); mi = tablegen(t->md->top+newhit, t->md->m); if(mi->bfn) (*mi->bfn)(tuser_mi); } else { treegrow = 0; } } /* * Handles re-drawing of scrolling menus. */ if(newhit==0 && md->top>0){ newtop = md->top-1; p.y += t->spacing; cursset(sub(p,Joffset)); erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } if(newhit==DISPLAY-1 && (md->top < (t->items - md->lines))){ newtop = md->top+1; p.y -= t->spacing; cursset(sub(p,Joffset)); erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } } /* * Exiting menu, clean-up screen and bitmaps */ if(md->b){ cursinhibit(); screenswap(md->b, md->b->rect, md->b->rect); cursallow(); bfree(md->b); } else { erasemenu(&mdata, t, hit, greyed); rectf(&disp, md->mr, F_XOR); rectf(&disp, inset(md->mr, BORDER), F_XOR); } /* * Set-up return value and execute user specified function * on menu item selection IFF the button state has changed. */ if(((tstatic && ((but && bttn(but)) || (!but && bttn123()))) || (!tstatic && ((but && !bttn(but)) || (!but && !bttn123())))) && (tmselect == 0)) { if((mi == 0) || ((mi=tablegen(md->top+newhit, m)) && (mi->ufield.grey & 0x01))) { tmselect = NOSELECT; } else { m->prevhit = hit; m->prevtop = md->top; if(mi->hfn) (*(mi->hfn)) (tuser_mi); if(!redraw) { tm_return: tmselect = SELECT; select_menu = m; } else { if(depth) { mi = tablegen((t-1)->md->top+(t-1)->newhit, (t-1)->md->m); if(mi->bfn) (*mi->bfn) (tuser_mi); for(newtop=1; newtop<=depth; newtop++) { /* * update all the parent menus' * prevhit and prevtop. A small * kludge in that to reduce stack * space, newtop is used and then * reset back at the top. */ (t-newtop)->md->m->prevtop = (t-newtop)->md->top; (t-newtop)->md->m->prevhit = (t-newtop)->newhit; } if(mi->dfn) (*mi->dfn) (tuser_mi); if(!redraw) goto tm_return; } while((tstatic && ((but && bttn(but)) || (!but && bttn123()))) || (!tstatic && ((but && !bttn(but)) || (!but && !bttn123())))) ; p = mro; p.y += hit*t->spacing+t->spacing/2; goto tmhit_top; } } } if(hit>=0 && tmselect==SELECT && !wasredraw) { m->prevhit = hit; m->prevtop = md->top; } /*end*/ } /* * Draws a menu given the Tleaf structure. The position of the * menu is calculated elsewhere. This routine determines the * individual placement of the text and icons within the menu. */ drawmenu(md, t) register Menudata *md; register Tleaf *t; { Point p, q, r; register int i, j, k; register char *from, *to; register Titem *mi; cursinhibit(); if(t->items > DISPLAY){ bro.y = scale(md->top, 0, t->items, sro.y, src.y); bro.x = sro.x + 1; brc.y = scale(md->top+DISPLAY, 0, t->items, sro.y, src.y); brc.x = src.x - 1; rectf(&disp, md->br, F_XOR); } for(j=0, p=tro, i=md->top; i < min(md->top+md->lines, t->items); ++i, ++j){ q = p; mi = tablegen(i, md->m); if(mi->ufield.grey & 0x01) flip(md->tr, j, T_grey, t); q.x += SPACEPAD; if (t->iconwidth) { if(mi->icon) { r = q; r.y += (t->spacing - (mi->icon->rect.corner.y - mi->icon->rect.origin.y))/2; r.x += (t->iconwidth - (mi->icon->rect.corner.x - mi->icon->rect.origin.x))/2; bitblt(mi->icon, mi->icon->rect, &disp, r, (md->b ? F_OR:F_XOR)); } q.x += t->iconwidth + SPACEPAD; } from = mi->text; for(to = &tfill[0]; *from && (to < &tfill[MAXCHARS]); ++from) if(*from & 0x80) { *to = '\0'; k = t->txtwidth - (strbits(tfill,mi->font) + strbits(from+1,mi->font)); while(k > 0) { k -= fontwidth(mi->font); *to++ = *from & 0x7F; } } else *to++ = *from; *to = '\0'; q.x += (t->txtwidth-strbits(tfill,mi->font))/2; q.y += (t->spacing - fontheight(mi->font))/2 + 1; string(mi->font, tfill, &disp, q, (md->b ? F_OR:F_XOR)); if(mi->next) { bitblt(&B_rtarrow, B_rtarrow.rect, &disp, Pt(trc.x-20, p.y+(t->spacing - 16)/2), (md->b ? F_OR:F_XOR)); } if(mi->ufield.grey & 0x01) flip(md->tr, j, T_grey, t); p.y += t->spacing; } cursallow(); } /* * Erase a menu by drawing over it again in XOR mode, * or clearing the rectangle occupied by the menu. The * method depends on whether the menu is being XOR'ed on * top of the current screen contents, or the rectangle * for the menu is alloc'ed memory. This routine is * used for clearing XOR'ed menus, or updating scrolling * menus. */ erasemenu(md, t, hit, greyhit) register Menudata *md; register Tleaf *t; register int hit; { if(md->b) { cursinhibit(); rectf(&disp, inset(md->mr, BORDER), F_CLR); cursallow(); } else { if (!greyhit) flip(md->tr, hit, T_black, t); drawmenu(md, t); } } /* * Routine which looks at a menu and derives the global * characteristics associated with that menu. These are * stored in a Tleaf structure. This routine also returns * a pointer to a submenu, if the submenu exists and was * previously selected as determined by the prevhit and * prevtop values. */ Tmenu * scanmenu(m, t) register Tmenu *m; register Tleaf *t; { register Titem *mi; register int iconwidth, iconheight, Fontheight, rside, length, items; register Tmenu *next_m; Titem *tablegen(); next_m = 0; iconwidth = iconheight = Fontheight = rside = length = items = 0; for(; (mi=tablegen(items, m))->text; ++items) { length = max(length, strbits(mi->text, mi->font)); Fontheight = max(Fontheight, fontheight(mi->font)); if(mi->icon) { iconwidth = max(iconwidth, mi->icon->rect.corner.x - mi->icon->rect.origin.x); iconheight = max(iconheight, mi->icon->rect.corner.y - mi->icon->rect.origin.y); } if(mi->next) { rside=1; if( (items == (m->prevhit + m->prevtop)) && (mi->ufield.grey == 0)) next_m = mi->next; } } t->spacing = 4 + max(Fontheight, iconheight); t->iconwidth = iconwidth; t->txtwidth = length; t->width = BORDER*2 + SPACEPAD + (length ? (SPACEPAD + length):0) + (iconwidth ? iconwidth + SPACEPAD:0) + (rside ? 20:0) + ((items > DISPLAY) ? BARWIDTH:0); t->items = items; return(next_m); } flip(r, n, code, t) Rectangle r; Texture code; register int n; register Tleaf *t; { if(n<0 || n>=t->items) return; r.corner.y = (r.origin.y += t->spacing*n) + t->spacing; texture(&disp, r, &code, F_XOR); } /* * this function is the same as jstrwidth() except that it * masks out the most significant bit in the char, (the * spread bit in spread chars). limits the chars to MAXCHARS. */ strbits(str, font) register char *str; register Font *font; { register int bits; register int chars; chars = bits = 0; while(*str && (chars++ < MAXCHARS)) { bits += fontwidth(font); str++; } return(bits); } /* * The following routine is used by hfn,bfn,dfn when TM_NORET is set * so that a return from the menu can be done by a selected item. * */ void tm_ret() { redraw = 0; tmselect = NOSELECT; } xcip/LIBDMDX11/wait.c0000644000175300001440000000624211513632541012706 0ustar meusers#include "jerq.h" #include "rcv.h" unsigned alarmtime, alarmstart; wait (resource) { int maxfd, smask, ret; unsigned diff; #if defined(BSD) || defined(SYSV) struct timeval tv; #endif /*BSD*/ maxfd = displayfd + 1; for(;;){ #ifdef SUNTOOLS if (damagedone) { fixdamage(); break; } #endif /*SUNTOOLS*/ if (alarmtime) { diff = realtime() - alarmstart; if (diff >= alarmtime) { alarmtime = 0; P->state |= ALARM; } else { alarmstart += diff; alarmtime -= diff; } } if(P->state & resource) break; #ifdef X11 if(XPending(dpy)) goto xin; #endif /*X11*/ smask = (1 << displayfd); if (!Jrcvbuf.blocked) smask |= jerqrcvmask; if (resource & CPU) { #if defined(BSD) || defined(SYSV) tv.tv_sec = 0; tv.tv_usec = 0; ret = select(maxfd, &smask, 0, 0, &tv); #else /* V9 */ ret = select(maxfd, &smask, 0, 0); #endif if (ret == 0) break; } else if (alarmtime) { #if defined(BSD) || defined(SYSV) tv.tv_sec = alarmtime/60; tv.tv_usec = (alarmtime%60) * 16666; ret = select(maxfd, &smask, 0, 0, &tv); #else /* V9 */ ret = select(maxfd, &smask, 0, alarmtime*17); #endif if (ret == 0) { alarmtime = 0; P->state |= ALARM; continue; } } else { #if defined(BSD) || defined(SYSV) ret = select(maxfd, &smask, 0, 0, 0); #else /* V9 */ ret = select(maxfd, &smask, 0, 0x6fffffff); #endif } if (ret == -1) continue; if(smask & jerqrcvmask) rcvfill(); if(smask & (1 << displayfd)){ xin: handleinput(); if(resource & MOUSE) /* We always have the mouse */ break; } } return resource & (P->state|MOUSE); } nap (n) int n; { wait(MOUSE); } alarm(ticks) { alarmtime = ticks; alarmstart = realtime(); P->state &= ~ALARM; } sleep(ticks) { #if defined(BSD) || defined(SYSV) int maxfd, smask, ret; unsigned diff = 0, tleft; struct timeval tv; unsigned start = realtime(); maxfd = displayfd + 1; for(tleft = ticks; diff < tleft; ) { tleft -= diff; #ifdef X11 if(XPending(dpy)) goto xin; #endif /*X11*/ damage: #ifdef SUNTOOLS if (damagedone) { fixdamage(); return; } #endif /*SUNTOOLS*/ smask = (1 << displayfd); if (!Jrcvbuf.blocked) smask |= jerqrcvmask; tv.tv_sec = tleft / 60; tv.tv_usec = (tleft % 60) * 16666; ret = select(maxfd, &smask, 0, 0, &tv); if (ret == 0) break; if (ret == -1) goto damage; if(smask & jerqrcvmask) rcvfill(); if(smask & (1 << displayfd)){ xin: handleinput(); } diff = realtime() - start; start += diff; } if (alarmtime) { if (ticks >= alarmtime) { alarmtime = 0; P->state |= ALARM; } else { alarmstart += ticks; alarmtime -= ticks; } } #else wait(CPU); #undef nap nap(ticks); wait(CPU); if (alarmtime) { int diff = realtime() - alarmstart; if (diff >= alarmtime) { alarmtime = 0; P->state |= ALARM; } alarmstart += diff; alarmtime -= diff; } #endif /*BSD*/ } #if defined(BSD) || defined(SYSV) #else #include #endif realtime() { #if defined(BSD) || defined(SYSV) struct timeval tv; gettimeofday(&tv, 0); return tv.tv_sec * 60 + (tv.tv_usec * 60 / 1000000); #else struct timeb tb; ftime(&tb); return tb.time * 60 + (tb.millitm * 60 / 1000); #endif /*BSD*/ } xcip/LIBDMDX11/circle.c0000644000175300001440000002534111513632540013203 0ustar meusers #include "jerq.h" /* jerq routines: circle, disc, ellipse, eldisc, arc */ /* circle: Form a circle of radius r centered at x1,y1 The boundary is a sequence of vertically, horizontally, or diagonally adjacent points that minimize abs(x^2+y^2-r^2). The circle is guaranteed to be symmetric about the horizontal, vertical, and diagonal axes */ circle (b, p, r, f) Bitmap *b; Point p; { int x1=p.x; register y1 = p.y; register eps = 0; /* x^2 + y^2 - r^2 */ register dxsq = 1; /* (x+dx)^2-x^2*/ register dysq = 1 - 2*r; register exy; int x0 = x1; register y0 = y1 - r; y1 += r; initpoints(b, f); if(f == F_XOR){ /* endpoints coincide */ points(Pt(x0,y0)); points(Pt(x0,y1)); } while(y1 > y0){ points(Pt(x0,y0)); points(Pt(x0,y1)); points(Pt(x1,y0)); points(Pt(x1,y1)); exy = eps + dxsq + dysq; if(-exy <= eps + dxsq){ y1--; y0++; eps += dysq; dysq += 2; } if(exy <= -eps){ x1++; x0--; eps += dxsq; dxsq += 2; } } points(Pt(x0,y0)); points(Pt(x1,y0)); endpoints(); } /* Fill a disc of radius r centered at x1,y1 The boundary is a sequence of vertically, horizontally, or diagonally adjacent points that minimize abs(x^2+y^2-r^2). The circle is guaranteed to be symmetric about the horizontal, vertical, and diagonal axes */ disc (b, p, r, f) Bitmap *b; Point p; int r; int f; { register x1, y1; register eps = 0; /* x^2 + y^2 - r^2 */ int dxsq = 1; /* (x+dx)^2-x^2 */ int dysq = 1 - 2 * r; int exy; register x0; register y0; if(b->flag & BI_OFFSCREEN) p = sub(p, b->rect.origin); x1 = p.x; y1 = p.y; x0 = x1; y0 = y1 - r; x1++; /* to offset jerq's half-open lines */ y1 += r; while(y1 > y0){ exy = eps + dxsq + dysq; if(-exy <= eps + dxsq){ rectf(b, Rect(x0, y0, x1, y0+1), f); rectf(b, Rect(x0, y1, x1, y1+1), f); y1--; y0++; eps += dysq; dysq += 2; } if(exy <= -eps){ x1++; x0--; eps += dxsq; dxsq += 2; } } rectf(b, Rect(x0, y0, x1, y0+1), f); } /* arc: draw an approximate arc centered at x0,y0 of an integer grid and running anti-clockwise from x1,y1 to the vicinity of x2,y2. If the endpoints coincide, draw a complete circle. The "arc" is a sequence of vertically, horizontally, or diagonally adjacent points that minimize abs(x^2+y^2-r^2). The circle is guaranteed to be symmetric about the horizontal, vertical, and diagonal axes */ #define sq(x) ((long)(x)*(x)) #define sgn(x) ((x) < 0 ? -1 : (x)==0 ? 0 : 1) #define mabs(x) (x < 0 ? -x : x) static Point nearby (p1, p2) /* called by arc() */ Point p1, p2; { long eps, exy; /*integers but many bits*/ int d; register dy; register dx; register x1 = p1.x; register y1 = p1.y; register x2 = p2.x; register y2 = p2.y; eps = sq(x2) + sq(y2) - sq(x1) - sq(y1); d = eps>0? -1: 1; for( ; ; eps=exy, x2+=dx, y2+=dy){ if(abs(y2) > abs(x2)){ dy = d*sgn(y2); dx = 0; } else{ dy = 0; dx = d*sgn(x2); if(dx==0) dx = 1; } exy = eps + (2*x2+dx)*dx + (2*y2+dy)*dy; if(mabs(eps) <= mabs(exy)) break; } p2.x = x2; p2.y = y2; return(p2); } arc (bp, p0, p2, p1, f) register Bitmap *bp; Point p0, p1, p2; { register dx, dy; register eps; /* x^2 + y^2 - r^2 */ int dxsq, dysq; /* (x+dx)^2-x^2, ...*/ int ex, ey, exy; p1 = sub(p1, p0); p2 = sub(p2, p0); p2 = nearby(p1, p2); dx = -sgn(p1.y); /* y1==0 is soon fixed */ dy = sgn(p1.x); dxsq = (2*p1.x + dx)*dx; dysq = (2*p1.y + dy)*dy; eps = 0; initpoints(bp, f); do{ if(p1.x == 0){ dy = -sgn(p1.y); dysq = (2*p1.y + dy)*dy; } else if(p1.y == 0){ dx = -sgn(p1.x); dxsq = (2*p1.x + dx)*dx; } ex = abs(eps + dxsq); ey = abs(eps + dysq); exy = abs(eps + dxsq + dysq); if(exBIG? HUGE/u: BIG; register r = v>BIG? HUGE/v: BIG; while(a || b){ if(e>=0 && b){ if(q>b) q = b; e -= q*u; b -= q; } else{ if(r>a) r = a; e += r*v; a -= r; } } return(e); } #define labs(x,y) if((x=y)<0) x = -x #define samesign(x,y) (((int)(x)^(int)(y)) > 0) ellip2 (bp, p0, a, b, p1, p2, f) Point p0, p1, p2; long a, b; register Bitmap *bp; Code f; { int dx = p1.y>0 ? 1 : p1.y<0 ? -1 : p1.x>0 ? -1 : 1; int dy = p1.x>0 ? -1 : p1.x<0 ? 1 : p1.y>0 ? -1 : 1; long a2 = a*a; long b2 = b*b; register long dex = b2*(2*dx*p1.x+1); register long e; register long dey = a2*(2*dy*p1.y+1); register long ex, ey, exy; int partial = !eqpt(p1, p2); if(partial && (p1.x==0 && p2.x==0 && samesign(p1.y, p2.y) || p1.y==0 && p2.y==0 && samesign(p1.x, p2.x))) { segment(bp, add(p0, p1), add(p0,p2), f); return; } e = resid(a, b, p1.x, p1.y); a2 *= 2; b2 *= 2; initpoints(bp, f); do{ labs(ex, e+dex); labs(ey, e+dey); labs(exy, e+dex+dey); if(exy<=ex || ey 0 ? 1 : p1.y < 0 ? -1 : p1.x > 0 ? -1 : 1; int dy = p1.x > 0 ? -1 : p1.x < 0 ? 1 : p1.y > 0 ? -1 : 1; long a2 = a * a; long b2 = b * b; register long dex = b2 * (2 * dx * p1.x + 1); register long e; register long dey = a2 * (2 * dy * p1.y + 1); register long ex, ey, exy; int partial = !eqpt (p1, p2); if(partial && (p1.x == 0 && p2.x == 0 && samesign (p1.y, p2.y) || p1.y == 0 && p2.y == 0 && samesign (p1.x, p2.x))){ segment(bp, add (p0, p1), add (p0, p2), f); return; } e = resid(a, b, p1.x, p1.y); a2 *= 2; b2 *= 2; do{ labs(ex, e + dex); labs(ey, e + dey); labs(exy, e + dex + dey); if(exy <= ex || ey < ex){ p1.y += dy; e += dey; dey += a2; } if(exy <= ey || ex < ey){ p1.x += dx; e += dex; dex += b2; } if(p1.x == 0){ if(abs(p1.y) == b){ dy = -dy; dey = -dey + a2; partial = 0; } else if(!samesign (p1.y, dy) && !partial) continue; /* don't double-draw skinny ends */ } else if(p1.y == 0){ if(abs (p1.x) == a){ dx = -dx; dex = -dex + b2; partial = 0; } else if(!samesign (p1.x, dx) && !partial) continue; } (*action)(bp, add (p0, p1), f); } while(!eqpt (p1, p2)); } static int yaxis; /* used in scan and eldisc */ static int xaxis; /* used in scan and eldisc */ static Point lp; /* used in scan and eldisc */ static void scan (bp, p, f) /* called by eldisc() and ellip1() */ Bitmap *bp; Point p; Code f; { register x, y; if((p.y != lp.y) && (lp.y != -1)){ x = xaxis - lp.x; y = yaxis - lp.y; rectf(bp, Rect(lp.x, lp.y, x+1, lp.y+1), f); rectf(bp, Rect(lp.x, y, x+1, y+1), f); } lp = p; } eldisc (bp, p, a, b, f) Bitmap *bp; Point p; int a, b; Code f; { register x0 = p.x; register y0 = p.y; yaxis = 2*p.y; xaxis = 2*p.x; lp.y = -1; if(a==0 || b==0) segment(bp, Pt(x0-a,y0-b), Pt(x0+a,y0+b), f); else{ ellip1(bp, p, a, b, scan, Pt(0, -b), Pt(-a, 0), f); scan(bp, Pt(0, -1), f); rectf(bp, Rect(p.x-a, p.y, p.x+a+1, p.y+1), f); } } /* elarc routines */ static struct dist { Point s; Point m; long e; } d1, d2; static void test(x, p) /* called by survet() */ Point x; register struct dist *p; { register long dx = x.x - p->s.x; register long dy = x.y - p->s.y; register long e = dx*dx+dy*dy; if(e <= p->e){ p->m = x; p->e = e; } } static void survey(bp, x, f) /* called by elarc() */ Bitmap *bp; Point x; Code f; { test(x, &d1); test(x, &d2); } #define HUGE2 017777777777 #define sgn2(x) ((x)<0? -1 : (x)==0? 0 : 1) /* elarc(bp,p0,a,b,p1,p2,f) draws in bitmap bp an arc of the ellipse centered at p0 with half-axes a,b extending counterclockwise from a point near p1 to a point near p2 args reversed because ellip1 draws clockwise */ elarc (bp, p0, a, b, p1, p2, f) Bitmap *bp; Point p0, p1, p2; Code f; { if(a==0) segment(bp, Pt(p0.x, p1.y), Pt(p0.x, p2.y), f); else if(b==0) segment(bp, Pt(p1.x, p0.y), Pt(p2.x, p0.y), f); else{ int sx1; int sy1; int sx2; int sy2; d1.s = sub(p1, p0); d2.s = sub(p2, p0); sx1 = sgn2(d1.s.x); sy1 = sgn2(d1.s.y); sx2 = sgn2(d2.s.x); sy2 = sgn2(d2.s.y); d1.s.x *= sx1; d1.s.y *= sy1; d2.s.x *= sx2; d2.s.y *= sy2; d1.e = d2.e = HUGE2; survey(bp, Pt(0, b), f); ellip1(bp, Pt(0, 0), a, b, survey, Pt(0,b), Pt(a, 0), f); if(!eqpt(d1.m, d2.m)) point(bp, d1.m, f); ellip1(bp, p0, a, b, point, Pt(d1.m.x*sx1, d1.m.y*sy1), Pt(d2.m.x*sx2, d2.m.y*sy2), f); } } /* dak's points routines for buffering X calls */ #ifdef X11 #define PBSIZE 100 #define flushpt() if (xpcnt) flushpoints(); static XPoint xp[PBSIZE]; static xpcnt; #endif /*X11*/ static Code fc; static ispixmap; static Bitmap *bitm; points (p) Point p; { #ifdef SUNTOOLS point(bitm,p,fc); #endif /*SUNTOOLS*/ #ifdef X11 register XPoint *x; if(ispixmap) p = sub(p, bitm->rect.origin); x = &xp[xpcnt]; x->x = p.x; x->y = p.y; if (++xpcnt == PBSIZE) flushpoints(); #endif /*X11*/ } initpoints (b, f) Bitmap *b; Code f; { if(b->flag & BI_OFFSCREEN) ispixmap = 1; else { #ifdef SUNTOOLS struct rect lkrect; if(!(b->flag & BI_OFFSCREEN)){ win_getsize(displayfd, &lkrect); pw_lock((Pixwin *)b->dr, &lkrect); } #endif /*SUNTOOLS*/ ispixmap = 0; } bitm = b; #ifdef X11 XSetFunction(dpy, gc, f); if (f == F_XOR) XSetForeground(dpy, gc, fgpix^bgpix); else XSetForeground(dpy, gc, fgpix); #endif /*X11*/ fc = f; } endpoints() { #ifdef SUNTOOLS if(!ispixmap) pw_unlock((Pixwin *)bitm->dr); #endif /*SUNTOOLS*/ #ifdef X11 flushpt(); #endif /*X11*/ } #ifdef X11 flushpoints() { if(xpcnt){ XDrawPoints(dpy, bitm->dr, gc, xp, xpcnt, CoordModeOrigin); xpcnt = 0; } } #endif /*X11*/ xcip/LIBDMDX11/util.c0000644000175300001440000000221611513632541012714 0ustar meusers#include "jerq.h" char * gcalloc (nbytes, where) unsigned long nbytes; char **where; { *where=(char *)alloc(nbytes); return *where; } void gcfree (s) char *s; { if (s != 0) free(s); } int curStack = 0; Cursor * curSave = 0; extern Cursor nocursor; cursinhibit () { if( curStack == 0 ) curSave = cursswitch( &nocursor ); curStack++; } cursallow () { curStack--; if( curStack <= 0 ) { cursswitch( curSave ); curStack = 0; } } /* misc functions */ border (b,r,i,f) Bitmap *b; Rectangle r; int i; Code f; { rectf(b, Rect(r.origin.x, r.origin.y, r.corner.x, r.origin.y+i), f); rectf(b, Rect(r.origin.x, r.corner.y-i, r.corner.x, r.corner.y), f); rectf(b, Rect(r.origin.x, r.origin.y+i, r.origin.x+i, r.corner.y-i), f); rectf(b, Rect(r.corner.x-i, r.origin.y+i, r.corner.x, r.corner.y-i), f); } Point Pt(x,y) { Point p; p.x = x; p.y = y; return p; } Rectangle Rect(x1,y1,x2,y2) { Rectangle r; r.origin.x = x1; r.origin.y = y1; r.corner.x = x2; r.corner.y = y2; return r; } Rectangle Rpt(p1, p2) Point p1, p2; { Rectangle r; r.origin.x = p1.x; r.origin.y = p1.y; r.corner.x = p2.x; r.corner.y = p2.y; return r; } xcip/LIBDMDX11/Makefile0000644000175300001440000000106411513632541013233 0ustar meusersinclude ../stand.defs XFLAGS = -DBSD CFLAGS = -I.. -I. -DX11 -DXBUG $(XFLAGS) $(EXTRACFLAGS) SYSLIBS = -lX11 LIB = libj.a LIBS = ${LIB} ${SYSLIBS} COMH= jerq.h menu.h rcv.h OFILES= ToBitmap.o add.o bitblt.o button.o circle.o cos.o getpoint.o \ kbdrcv.o menuhit.o mhit.o muxbuf.o rcvfill.o rev.o sizehints.o \ snd.o util.o wait.o x11.o ${LIB}: ${OFILES} rm -f ${LIB} ar cr ${LIB} ${OFILES} (ranlib ${LIB}) 2>/dev/null || true clean: rm -f ${OFILES} ${LIB} ${TESTS} ${OFILES} ${TESTO}: jerq.h mhit.o t5.o: menu.h kbdrcv.o rcvfill.o wait.o: rcv.h xcip/LIBDMDX11/rcvfill.c0000644000175300001440000000051411513632541013377 0ustar meusers#include "jerq.h" #include "rcv.h" #if defined(BSD) || defined(SYSV) #include #endif rcvfill () { static char rbuf[1024]; register i; i = min (1024, Jrcvbuf.size - Jrcvbuf.cnt); i = read(0, rbuf, i); if (i <= 0) { #if defined(BSD) || defined(SYSV) fcntl(1, F_SETFL, 0); #endif exit(0); } rcvbfill(rbuf, i); } xcip/LIBDMDX11/add.c0000644000175300001440000000403611513632541012471 0ustar meusers#include "jerq.h" /* These routines are NOT portable, but they are fast. */ Point add (a, b) Point a, b; { register short *ap= &a.x, *bp= &b.x; *ap++ += *bp++; *ap += *bp; return a; } Point sub (a, b) Point a, b; { register short *ap= &a.x, *bp= &b.x; *ap++ -= *bp++; *ap -= *bp; return a; } Point mul (a, b) Point a; register b; { register short *ap= &a.x; *(ap++)*=b; *ap*=b; return a; } Point div (a, b) Point a; register b; { register short *ap= &a.x; *(ap++)/=b; *ap/=b; return a; } eqpt (p, q) Point p, q; { register long *pp=(long *)&p, *qq=(long *)&q; return *pp==*qq; } eqrect (r, s) Rectangle r, s; { register long *rr=(long *)&r, *ss=(long *)&s; return *rr++==*ss++ && *rr==*ss; } Rectangle inset (r,n) Rectangle r; register n; { register short *rp= &r.origin.x; *rp++ += n; *rp++ += n; *rp++ -= n; *rp -= n; return r; } /* muldiv is a macro in jerq.h */ ptinrect (p, r) Point p; Rectangle r; { return(p.x >= r.origin.x && p.x < r.corner.x && p.y >= r.origin.y && p.y < r.corner.y); } Rectangle raddp (r, p) Rectangle r; Point p; { register short *rp= &r.origin.x, *pp= &p.x; *rp++ += *pp++; *rp++ += *pp--; *rp++ += *pp++; *rp += *pp; return r; } Rectangle rsubp (r, p) Rectangle r; Point p; { register short *rp= &r.origin.x, *pp= &p.x; *rp++ -= *pp++; *rp++ -= *pp--; *rp++ -= *pp++; *rp -= *pp; return r; } rectXrect(r, s) Rectangle r, s; { #define c corner #define o origin return(r.o.xo.xc.x && bp->o.xc.x && rp->o.yc.y && bp->o.yc.y)==0) return 0; /* They must overlap */ if(rp->origin.xorigin.x) rp->origin.x=bp->origin.x; if(rp->origin.yorigin.y) rp->origin.y=bp->origin.y; if(rp->corner.x>bp->corner.x) rp->corner.x=bp->corner.x; if(rp->corner.y>bp->corner.y) rp->corner.y=bp->corner.y; return 1; } xcip/LIBDMDX11/rcv.h0000644000175300001440000000022411513632540012532 0ustar meusersstruct Jrcvbuf { unsigned char *buf; unsigned char *in; unsigned char *out; int cnt; int size; int blocked; }; extern struct Jrcvbuf Jrcvbuf; xcip/LIBDMDX11/muxbuf.c0000644000175300001440000000372411513632540013251 0ustar meusers#include "jerq.h" #ifdef SUNTOOLS static char *buffile = "/tmp/muxbuf"; #define DOSEL 1 #ifdef DOSEL #include #include #endif #include #endif /*SUNTOOLS*/ typedef struct String{ char *s; /* pointer to string */ short n; /* number used, no terminal null */ short size; /* size of allocated area */ } String; #ifdef DOSEL static char *selbufp; static int context = 0; selread(buffer) Seln_request *buffer; { char *reply; if (*buffer->requester.context == 0) { *buffer ->requester.context = 1; if (buffer == NULL) reply = ""; else reply = buffer->data + sizeof(Seln_attribute); } else reply = buffer->data; while (*reply) *selbufp++ = *reply++; *selbufp = 0; return(SELN_SUCCESS); } #endif /* DOSEL */ getmuxbuf (pmb) String *pmb; { char *ans; int n = 0; #ifdef X11 ans = XFetchBytes(dpy, &n); #endif /*X11*/ #ifdef SUNTOOLS #define BSIZE 4096 char buffer[BSIZE]; int fd; #ifdef DOSEL Seln_client client; Seln_holder holder; holder = seln_inquire(SELN_PRIMARY); if (holder.state != SELN_NONE) { selbufp = buffer; *buffer = 0; context = 0; seln_query (&holder, selread, &context, SELN_REQ_CONTENTS_ASCII, 0, 0); n = strlen(buffer); } #endif /* DOSEL */ if (n == 0) { fd = open(buffile, O_RDONLY); if (fd < 0) return; n = read(fd, buffer, BSIZE); close(fd); } if (n < 0) return; ans = buffer; #endif /*SUNTOOLS*/ if (pmb->size < (n+1)) { pmb->size = n+1; gcalloc(pmb->size, &(pmb->s)); } pmb->n = n; if (n) strncpy(pmb->s, ans, n); pmb->s[n] = 0; #ifdef X11 free(ans); #endif /*X11*/ } setmuxbuf(pmb) String *pmb; { #ifdef X11 XStoreBytes(dpy, pmb->s, pmb->n); #endif/* X11*/ #ifdef SUNTOOLS int fd = open(buffile, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) return; fchmod(fd, 0666); /* Umask may change mode from open */ write(fd, pmb->s, pmb->n); #ifdef DOSEL seln_hold_file(SELN_PRIMARY,buffile); #endif /* DOSEL */ close(fd); #endif /*SUNTOOLS*/ } xcip/LIBDMDX11/kbdrcv.c0000644000175300001440000000304111513632540013206 0ustar meusers#include "jerq.h" #include "rcv.h" #define RCVBUFSIZE 1024 #define HIBUF 1000 #define LOWBUF 256 static unsigned char rcvbuffer[RCVBUFSIZE]; /* buffer for rcv input */ struct Jrcvbuf Jrcvbuf = {rcvbuffer, rcvbuffer, rcvbuffer, 0, RCVBUFSIZE, 0 }; rcvchar () { int i; if (!Jrcvbuf.cnt) return -1; i = *Jrcvbuf.out++; if(Jrcvbuf.out == &Jrcvbuf.buf[Jrcvbuf.size]) Jrcvbuf.out = Jrcvbuf.buf; if(--Jrcvbuf.cnt == 0) P->state &= ~RCV; if (Jrcvbuf.blocked && Jrcvbuf.cnt <= LOWBUF) Jrcvbuf.blocked = 0; return(i); } rcvbfill(buf, cnt) register unsigned char *buf; { register i; unsigned char *ebuf; if (Jrcvbuf.cnt == Jrcvbuf.size) return; ebuf = &Jrcvbuf.buf[Jrcvbuf.size]; i = min (cnt, Jrcvbuf.size - Jrcvbuf.cnt); P->state |= RCV; Jrcvbuf.cnt += i; if (Jrcvbuf.cnt >= HIBUF) Jrcvbuf.blocked = 1; while (i--) { *Jrcvbuf.in++ = *buf++; if (Jrcvbuf.in == ebuf) Jrcvbuf.in = Jrcvbuf.buf; } } #define KBDBUFSIZE 128 static unsigned char kbdbuffer[KBDBUFSIZE]; /* buffer for kbd input */ static struct { unsigned char *buf; unsigned char *in; unsigned char *out; int cnt; int size; } kbdbuf = {kbdbuffer, kbdbuffer, kbdbuffer, 0, KBDBUFSIZE}; kbdchar () { int i; if(!kbdbuf.cnt) return -1; i = *kbdbuf.out++; if(kbdbuf.out == &kbdbuf.buf[kbdbuf.size]) kbdbuf.out = kbdbuf.buf; if(--kbdbuf.cnt == 0) P->state &= ~KBD; return(i); } kbdread (cp) unsigned char *cp; { if(kbdbuf.cnt == kbdbuf.size) return; *kbdbuf.in++ = *cp; kbdbuf.cnt++; if(kbdbuf.in == &kbdbuf.buf[kbdbuf.size]) kbdbuf.in = kbdbuf.buf; } xcip/LIBDMDX11/button.c0000644000175300001440000000552611513632540013260 0ustar meusers#include "jerq.h" #define UP 0 #define DOWN 1 static short boxcurs_bits[] = { 0x43FF, 0xE001, 0x7001, 0x3801, 0x1D01, 0x0F01, 0x8701, 0x8F01, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF, }; static Cursor boxcurs; static int firstime = 1; Rectangle getrect (n) int n; { return getrectb(8>>n, 1); } /* ngetrect: ultimate getrect routine optional clipping rectangle optional blocking for mouse routines optional minimum width and height returns 1 if minimum rectangle is swept */ int ngetrect (r, clip, but, block, minw, minh) register Rectangle *r; /* rectangle */ register Rectangle *clip; /* clipping rectangle, can be 0 */ register int but; /* button 1, 2, or 3, defaults to 1 */ register int block; /* blocking flag 0 or 1 */ register int minw; /* minimum width, can be 0 */ register int minh; /* minimum height, can be 0 */ { if(but == 0) but = 1; *r = getrectb(8>>but, block); if(r->origin.x == 0 && r->origin.y == 0 && r->corner.x == 0 && r->corner.y == 0) return 0; if(r->corner.x - r->origin.x < minw || r->corner.y - r->origin.y < minh) return 0; if(clip && !rectclip(r, *clip)) return 0; return 1; } Rectangle getrectb (n, block) int n, block; { Rectangle r, canon(); Point p1, p2; Cursor *prev; if (firstime) { boxcurs = ToCursor(boxcurs_bits, boxcurs_bits, 8, 8); firstime = 0; } prev = cursswitch(&boxcurs); Jscreengrab(); if(block){ buttons(UP); buttons(DOWN); } if(!(mouse.buttons&n)){ r.origin.x=r.origin.y=r.corner.x=r.corner.y=0; buttons(UP); goto Return; } p1 = add(mouse.xy, Joffset); p2 = p1; r = canon(p1, p2); outline(r); for(; mouse.buttons&n; nap(2)){ outline(r); p2 = add(mouse.xy, Joffset); r = canon(p1, p2); outline(r); } outline(r); /* undraw for the last time */ Return: Jscreenrelease(); cursswitch(prev); r = rsubp(r, Joffset); if(!rectclip(&r, Rpt(Drect.org,Drect.cor))) r.origin.x = r.origin.y = r.corner.x = r.corner.y = 0; return r; } buttons (updown) { while((button123()!=0) != updown) nap(2); } Rectangle canon (p1, p2) Point p1, p2; { Rectangle r; r.origin.x = min(p1.x, p2.x); r.origin.y = min(p1.y, p2.y); r.corner.x = max(p1.x, p2.x); r.corner.y = max(p1.y, p2.y); return(r); } outline(r) Rectangle r; { segment(&Jfscreen, r.org, Pt(r.cor.x, r.org.y), F_XOR); segment(&Jfscreen, Pt(r.cor.x, r.org.y), r.cor, F_XOR); segment(&Jfscreen, r.cor, Pt(r.org.x, r.cor.y), F_XOR); segment(&Jfscreen, Pt(r.org.x, r.cor.y), r.org, F_XOR); } Cursor * cursswitch (cp) Cursor *cp; { Cursor *rc; if (cp == (Cursor *)0) cp = &normalcursor; XDefineCursor(dpy, display.dr, *cp); rc = P->cursor; P->cursor = cp; return rc; } cursset (p) Point p; { XWarpPointer(dpy, display.dr, display.dr, mouse.xy.x, mouse.xy.y, display.rect.corner.x, display.rect.corner.y, p.x, p.y); mouse.xy.x = p.x; mouse.xy.y = p.y; } xcip/LIBDMDX11/cos.c0000644000175300001440000000314011513632541012520 0ustar meusersstatic short costab[91]={ 1024, 1024, 1023, 1023, 1022, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1002, 998, 994, 989, 984, 979, 974, 968, 962, 956, 949, 943, 935, 928, 920, 912, 904, 896, 887, 878, 868, 859, 849, 839, 828, 818, 807, 796, 784, 773, 761, 749, 737, 724, 711, 698, 685, 672, 658, 644, 630, 616, 602, 587, 573, 558, 543, 527, 512, 496, 481, 465, 449, 433, 416, 400, 384, 367, 350, 333, 316, 299, 282, 265, 248, 230, 213, 195, 178, 160, 143, 125, 107, 89, 71, 54, 36, 18, 0, }; cos (x) register x; { x %= 360; if(x<0) x+=360; if(x<=180) return(x<90? costab[x] : -costab[180-x]); return(x<180+90? -costab[x-180] : costab[360-x]); } sin (x) register x; { return(cos(x-90)); } static qatan2 (x, y) register x, y; { if(x=0 && yy>=0) return(qatan2(x, y)); if(xx<0 && yy<=0) return(180+qatan2(x, y)); if(xx<0 && yy>0) return(180-qatan2(x, y)); return(360-qatan2(x, y)); } norm (x,y,z) { return (sqrt(x*x + y*y + z*z)); } sqrtryz (x,y,z) { register long sumsq; sumsq = x*x - y*y - z*z; if(sumsq <= 0) return 0; return(sqrt(sumsq)); } #define MAXROOT 0xb504 sqrt (x) register long x; { register long high = MAXROOT; register long low = 0; register long current = MAXROOT/2; if(x <= 0) return 0; if(x >= MAXROOT*MAXROOT) return(MAXROOT); while(high>low+1){ if(current*current==x) return (current); if(current*current>x) high=current; else low=current; current=(high+low)>>1; } return(current); } xcip/LIBDMDX11/mhit.c0000644000175300001440000001645011513632540012704 0ustar meusers#include "jerq.h" #include "menu.h" #define disp Jfscreen #ifdef SUNTOOLS #undef F_STORE #define F_STORE ((displaypw->pw_pixrect->pr_depth==1) ? \ (PIX_DONTCLIP|PIX_SRC) : PIX_SRC) #endif /* SUNTOOLS */ #define scale(x, inmin, inmax, outmin, outmax)\ (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin)) #define bound(x, low, high) min(high, max( low, x )) Font *font = &defont; #define SPACING (1+fontheight(font)) #define CHARWIDTH ave_fontwid(font) #define DISPLAY 16 #define DELTA 6 #define BARWIDTH 18 #define MAXDEPTH 16 /* don't use too much stack */ #define ARROWIDTH 20 #define CHECKWIDTH 20 static unsigned short tarrow_bits[] = { 0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00E0, 0x00F8, 0xFFFE, 0xFFFE, 0x00F8, 0x00E0, 0x00C0, 0x00C0, 0x0080, 0x0000, 0x0000, }; static Texture tarrow; static int firstime = 1; static short checkmark[] = { /* check mark */ 0x0000, 0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0070, 0x00E0, 0x61E0, 0x73C0, 0x3F80, 0x3F00, 0x1E00, 0x1E00, 0x0C00, 0x0000, }; static Texture tcheckmark; static NMitem * tablegen(i, table) NMitem *table; { return &table[i]; } static char fill[64]; NMitem * nmhit(m, but, depth) register NMenu *m; { register int width, mwidth, i, j, top, newtop, hit, newhit; register int items, lines, length, w, x; Point p, q, savep, baro, barc; Rectangle sr, tr, mr; /* scroll, text, menu */ Rectangle rside, rhit; register Bitmap *b; register char *from, *to; Bitmap *bhelp = 0, *arrow, *B_checkmark; NMitem *(*generator)(), *mi, *table, *ret = 0; int dohfn; int selmnu; #define sro sr.origin #define src sr.corner #define tro tr.origin #define trc tr.corner #define mro mr.origin #define mrc mr.corner if (firstime) { firstime = 0; tarrow = ToTexture((short *)tarrow_bits); tcheckmark = ToTexture(checkmark); } arrow = balloc(Rect(0, 0, 16, 16)); texture(arrow, arrow->rect, &tarrow, F_STORE); B_checkmark = balloc(Rect(0, 0, 16, 16)); texture(B_checkmark, B_checkmark->rect, &tcheckmark, F_STORE); generator = (table=m->item) ? tablegen : m->generator; selmnu = w = x = length = 0; for(items = 0; (mi=(*generator)(items, table))->text; ++items) { register int s = strlen (mi->text); length = max(length, s); if (mi->next) w = max (w, s); else x = max (x, s); if (mi->selected) selmnu = 1; } if(items == 0) return(ret); Jscreengrab(); width = length*CHARWIDTH+10; w *= CHARWIDTH; x *= CHARWIDTH; if (x <= w) mwidth = w + ARROWIDTH; else if (x >= w + 2*ARROWIDTH) mwidth = x; else mwidth = w + ARROWIDTH + (x - w) / 2; mwidth += 10; if (selmnu) mwidth += CHECKWIDTH; sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0; if(items <= DISPLAY) lines = items; else{ lines = DISPLAY; tro.x = src.x = BARWIDTH; sro.x = sro.y = 1; } #define ASCEND 2 tro.y = ASCEND; tro.x += selmnu * CHECKWIDTH; mrc = trc = add(tro, Pt(mwidth, min(items, lines)*SPACING)); src.y = mrc.y-1; newtop = bound(m->prevtop, 0, items-lines); p = add(mouse.xy, Joffset); p.y -= bound(m->prevhit, 0, lines-1)*SPACING+SPACING/2; p.x = bound(p.x-(src.x+mwidth/2), disp.rect.origin.x, disp.rect.corner.x-mrc.x); p.y = bound(p.y, disp.rect.origin.y, disp.rect.corner.y-mrc.y); sr = raddp(sr, p); tr = raddp(tr, p); mr = raddp(mr, p); rside = mr; rside.origin.x = rside.corner.x-20; b = balloc(mr); if(b) bitblt(&disp, mr, b, mro, F_STORE); rectf(&disp, mr, F_OR); PaintMenu: rectf(&disp, inset(mr, 1), F_CLR); top = newtop; if(items > DISPLAY){ baro.y = scale(top, 0, items, sro.y, src.y); baro.x = sr.origin.x; barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y); barc.x = sr.corner.x; rectf(&disp, Rpt(baro,barc), F_XOR); } for(p=tro, i=top; i < min(top+lines, items); ++i){ q = p; mi = generator(i, table); from = mi->text; for(to = &fill[0]; *from; ++from) if(*from & 0x80) for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;) *to++ = *from & 0x7F; else *to++ = *from; *to = '\0'; q.x += (width-strwidth(font,fill))/2; string(&defont, fill, &disp, q, F_XOR); if(mi->next) bitblt(arrow, arrow->rect, &disp, Pt(trc.x-18, p.y-2), F_OR); if(mi->selected) bitblt(B_checkmark, B_checkmark->rect, &disp, Pt(tro.x-18, p.y-2), F_OR); p.y += SPACING; } savep = add(mouse.xy, Joffset); mi = 0; for(newhit = hit = -1; button(but); ){ p = add(mouse.xy, Joffset); if(depth && ((p.x < mro.x) || button(5-but))) { ret = 0; break; } if(ptinrect(p, sr)){ if(ptinrect(savep,tr)){ p.y = (baro.y+barc.y)/2; cursset(sub(p,Joffset)); } newtop = scale(p.y, sro.y, src.y, 0, items); newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY); if(newtop != top) /* ->->-> */ goto PaintMenu; }else if(ptinrect(savep,sr)){ register dx, dy; if(abs(dx = p.x-savep.x) < DELTA) dx = 0; if(abs(dy = p.y-savep.y) < DELTA) dy = 0; if(abs(dy) >= abs(dx)) dx = 0; else dy = 0; p = add(savep, Pt(dx,dy)); cursset(sub(p,Joffset)); } savep = p; newhit = -1; if(ptinrect(p, tr)){ newhit = bound((p.y-tro.y)/SPACING, 0, lines-1); if(newhit!=hit && hit>=0 && abs(tro.y+SPACING*newhit+SPACING/2-p.y) > SPACING/3) newhit = hit; rhit = tr; rhit.origin.y += newhit*SPACING-ASCEND/2; rhit.corner.y = rhit.origin.y + SPACING; } if(newhit == -1) ret = 0, dohfn = 0; else ret = mi = (*generator)(top+newhit, table), dohfn = 1; if(newhit == hit) { if((newhit != -1) && (bhelp == 0) && button1() && mi->help) helpon(mi->help, rhit, &bhelp); else if(bhelp && !button1()) helpoff(&bhelp); } else { Rectangle temp; temp = tr; if (selmnu) temp.origin = sub(temp.origin, Pt(CHECKWIDTH,0)); flip(temp, hit); helpoff(&bhelp); flip(temp, newhit); hit = newhit; if((newhit != -1) && button1() && mi->help) helpon(mi->help, rhit, &bhelp); } if((newhit != -1) && ptinrect(p, rside)) { if(mi->dfn) (*mi->dfn)(mi); if(mi->next && (depth <= MAXDEPTH)) ret = nmhit(mi->next, but, depth+1), dohfn = 0; if(mi->bfn) (*mi->bfn)(mi); } if(newhit==0 && top>0){ newtop = top-1; p.y += SPACING; cursset(sub(p,Joffset)); /* ->->-> */ goto PaintMenu; } if(newhit==DISPLAY-1 && top->-> */ goto PaintMenu; } if (button(but)) nap(2); } if(bhelp) helpoff(&bhelp); if(b){ bitblt(b, b->rect, &disp, b->rect.origin, F_STORE); bfree(b); } if(hit>=0){ m->prevhit = hit; m->prevtop = top; if(ret && ret->hfn && dohfn) (*ret->hfn)(mi); } Jscreenrelease(); return(ret); } flip(r,n) Rectangle r; { if(n<0) return; ++r.origin.x; r.corner.y = (r.origin.y += SPACING*n-1) + SPACING; --r.corner.x; rectf(&disp, r, F_XOR); } helpon(msg, r, bhelp) char *msg; Rectangle r; Bitmap **bhelp; { register w; w = strwidth(&defont, msg)+10; if(r.corner.x+w < disp.rect.corner.x){ r.origin.x = r.corner.x; r.corner.x += w; } else{ r.corner.x = r.origin.x; r.origin.x -= w; } if(*bhelp = balloc(r = inset(r, -1))){ bitblt(&disp, r, *bhelp, r.origin, F_STORE); rectf(&disp, r, F_OR); rectf(&disp, inset(r, 1), F_XOR); string(&defont,msg,&disp,add(r.origin, Pt(5, 1)),F_XOR); } } helpoff (bhelp) Bitmap **bhelp; { Bitmap *bh; if(bh = *bhelp){ bitblt(bh, bh->rect, &disp, bh->rect.origin, F_STORE); bfree(bh); *bhelp = 0; } } xcip/LIBDMDX11/rev.c0000644000175300001440000000035711513632541012537 0ustar meusers#include main() { int x; int b; int y; for (x = 0; x < 256; x++) { y = 0; for (b = 0; b < 8; b++) { if (x & (1< sendchar(c) char c; { sendnchars(1, &c); } sendnchars (n, p) char *p; int n; { int i; int maxfd, rmask, wmask; maxfd = displayfd + 1; while(n){ i = write(1, p, n); if(i > 0){ n -= i; p += i; continue; } #ifdef BSD if(i < 0 && errno == EWOULDBLOCK){ #else #ifdef SYSV if(i == 0){ #else /*V9*/ if(i < 0 && errno == EBUSY){ #endif /*SYSV*/ #endif /*BSD*/ do{ #ifdef X11 while (XPending(dpy)) handleinput(); #endif /*X11*/ rmask = (1 << displayfd) | jerqrcvmask; wmask = 2; #if defined(BSD) || defined(SYSV) select(maxfd, &rmask, &wmask, 0, 0); #else select(maxfd, &rmask, &wmask, 0x6fffffff); #endif if (rmask & jerqrcvmask) rcvfill(); if (rmask & (1 << displayfd)) handleinput(); } while(!wmask); } else exit(1); } } xcip/LIBDMDX11/tmenuhit.h0000644000175300001440000000460211513632541013602 0ustar meusers/* * Defines for Tmenu and Titem menu structures. * Old menu structures can be found in . */ typedef struct Titem { char *text; /* string for menu */ struct { unsigned short uval; /* user field */ unsigned short grey; /* flag indicates invalid selection */ } ufield; struct Tmenu *next; /* pointer to sub-menu */ Bitmap *icon; /* pointer to the icons bitmap */ #ifdef X11 Font *font; #else struct Font *font; /* font defined for this item */ #endif void (*dfn)(); /* execute function before sub-menu */ void (*bfn)(); /* execute function after sub-menu */ void (*hfn)(); /* execute function on selection */ } Titem; typedef struct Tmenu { Titem *item; /* Titem array, ending with text=0 */ short prevhit; /* private to menuhit() */ short prevtop; /* private to menuhit() */ Titem *(*generator)(); /* used if item == 0 */ short menumap; /* bit definition for user Titem structure */ } Tmenu; /* * The following bit definitions are for the user to define * the structure of the user Titem structure. These bits are * stored in the menumap data member, which converts the user * Titem structure into that of the Titem structure defined above. */ #define TM_TEXT 0x0001 /* defines the text field */ #define TM_UFIELD 0x0002 /* defines the ufield field */ #define TM_NEXT 0x0004 /* defines the next field */ #define TM_ICON 0x0008 /* defines the icon field */ #define TM_FONT 0x0010 /* defines the font field */ #define TM_DFN 0x0020 /* defines the dfn field */ #define TM_BFN 0x0040 /* defines the bfn field */ #define TM_HFN 0x0080 /* defines the hfn field */ #define TM_EXPAND 1 /* expand submenus on invocation */ #define TM_NORET 2 /* don't return until non-selection */ #define TM_STATIC 4 /* select on button depression */ #define TM_POINT 8 /* specify a point for the root menu */ #define MAX_TMFIELDS 9 /* number of fields in Titem */ #define MAX_MASK 0x0100 /* upper limit bit definition */ extern void tm_ret(); /* return function from TM_NORET */ extern Titem *tmenuhit(); /* This is the button 3's global menu item */ typedef struct Titem1 { char *text; struct { unsigned short uval; unsigned short grey; } ufield; struct Tmenu *next; Bitmap *icon; void (*dfn)(); } Titem1; extern Bitmap B_checkmark; extern Bitmap B_rtarrow; xcip/LIBDMDX11/getpoint.c0000644000175300001440000000102211513632541013562 0ustar meusers#include "jerq.h" /* * Read back the value of a pixel */ getpoint(b,p) Bitmap *b; Point p; { int bit; #ifdef X11 XImage *im; if(b->flag & BI_OFFSCREEN) p = sub(p, b->rect.origin); im = XGetImage(dpy, b->dr, p.x, p.y, 1, 1, 1, XYPixmap); bit = (*im->data != 0); XDestroyImage(im); #endif /*X11*/ #ifdef SUNTOOLS if(b->flag & BI_OFFSCREEN) { p = sub(p, b->rect.origin); bit = (pr_get((Pixrect *)b->dr, p.x, p.y) != 0); } else bit = (pw_get((Pixwin *)b->dr, p.x, p.y) != 0); #endif /*SUNTOOLS*/ return (bit); } xcip/LIBDMDX11/menu.h0000644000175300001440000000067711513632541012721 0ustar meusers#define hmenuhit(m,b) nmhit(m,b,0) typedef struct NMitem { char *text; char *help; int selected; struct NMenu *next; void (*dfn)(), (*bfn)(), (*hfn)(); long data; /* user only */ } NMitem; typedef struct NMenu { NMitem *item; /* NMitem array, ending with text=0 */ NMitem *(*generator)(); /* used if item == 0 */ short prevhit; /* private to menuhit() */ short prevtop; /* private to menuhit() */ } NMenu; extern NMitem *nmhit(); xcip/LIBDMDX11/sunview.c0000644000175300001440000002316011513632541013440 0ustar meusers#ifdef SUNTOOLS #include "jerq.h" #include #include #include #include #include #include /* Common */ Rectangle Drect; Bitmap display, Jfscreen; Point Joffset; struct Mouse mouse; static struct JProc sP; struct JProc *P; Font defont; int mouse_alive = 0; int mousewin = 1; int jerqrcvmask = 1; int displayfd; Cursor normalcursor; static Jlocklevel; static short arrow_bits[] = { 0x0000, 0x0008, 0x001c, 0x003e, 0x007c, 0x00f8, 0x41f0, 0x43e0, 0x67c0, 0x6f80, 0x7f00, 0x7e00, 0x7c00, 0x7f00, 0x7fc0, 0x0000 }; static short arrow_mask_bits[] = { 0x0008, 0x001c, 0x003e, 0x007f, 0x00fe, 0x41fc, 0xe3f8, 0xe7f0, 0xffe0, 0xffc0, 0xff80, 0xff00, 0xff00, 0xffc0, 0xffe0, 0xffc0 }; /* Sunview only */ Pixwin *displaypw; int damagedone; static struct fullscreen *Jfscp; static int screendepth; #define MAXKEY 64 #define KEYOFF KEY_LEFTFIRST static char *kcbuf[MAXKEY]; static char kctype[MAXKEY]; static char kbufstr[512]; static char *kbufp = kbufstr; #define event_is_key(event) \ ((event_id(event) >= KEY_LEFTFIRST) && (event_id(event) <= KEY_BOTTOMRIGHT)) initdisplay (argc, argv) int argc; char **argv; { extern char *getenv(); extern struct pixrectops mem_ops; int gfx; int designee; struct inputmask mask; struct rect gfxrect; static winch_catcher(); signal(SIGWINCH, winch_catcher); gfx = open(getenv("WINDOW_GFX"), 0); if(gfx < 0){ perror("cannot get graphics window"); exit(1); } designee = win_nametonumber(getenv("WINDOW_GFX")); displayfd = win_getnewwindow(); win_insertblanket(displayfd, gfx); close(gfx); defont = pf_default(); displaypw = pw_open(displayfd); win_getrect(displayfd, &gfxrect); screendepth = displaypw->pw_pixrect->pr_depth; if(!(displaypw->pw_prretained = mem_create(gfxrect.r_width, gfxrect.r_height, 1))) perror("initdisplay: mem_create"); display.dr = (char *)displaypw; Drect.origin.x = Drect.origin.y = 0; Drect.corner.x = gfxrect.r_width; Drect.corner.y = gfxrect.r_height; display.rect = Drect; P = &sP; input_imnull(&mask); if(mouse_alive) win_setinputcodebit(&mask, LOC_MOVE); win_setinputcodebit(&mask, MS_LEFT); win_setinputcodebit(&mask, MS_MIDDLE); win_setinputcodebit(&mask, MS_RIGHT); win_setinputcodebit(&mask, LOC_DRAG); win_setinputcodebit(&mask, LOC_WINENTER); win_setinputcodebit(&mask, LOC_WINEXIT); ttyswparse(&mask); /* Parse $HOME/ttyswrc */ mask.im_flags |= IM_NEGEVENT; mask.im_flags |= IM_ASCII; win_setinputmask(displayfd, &mask, 0, designee); normalcursor = ToCursor(arrow_bits, arrow_mask_bits, 1, 15); cursswitch(&normalcursor); rectf(&display, Drect, F_CLR); Joffset.x = 0; Joffset.y = 0; P->state |= RESHAPED; if (damagedone) fixdamage(); } /* * Catch SIGWINCH signal when window is damaged */ static winch_catcher () { signal(SIGWINCH, winch_catcher); /* for /usr/5bin/cc */ damagedone = 1; } fixdamage() { struct rect gfxrect; int x, y; damagedone = 0; pw_damaged(displaypw); win_getrect(displayfd, &gfxrect); if (Drect.corner.x != gfxrect.r_width || Drect.corner.y != gfxrect.r_height) { Drect.corner.x = gfxrect.r_width; Drect.corner.y = gfxrect.r_height; display.rect = Drect; P->state |= RESHAPED; pw_donedamaged(displaypw); pr_destroy(displaypw->pw_prretained); displaypw->pw_prretained = 0; rectf(&display, Drect, F_CLR); displaypw->pw_prretained = mem_create(gfxrect.r_width, gfxrect.r_height, 1); } else { pw_repairretained(displaypw); pw_donedamaged(displaypw); } } /* This must be called before initdisplay */ mousemotion () { mouse_alive = 1; } setsizehints () {} request(what) int what; { if(what & SEND) fcntl(1, F_SETFL, FNDELAY); if(!(what & RCV)) jerqrcvmask = 0; } Bitmap * balloc (r) Rectangle r; { Bitmap *b; b = (Bitmap *)malloc(sizeof (struct Bitmap)); b->dr = (char *)mem_create(r.cor.x - r.org.x, r.cor.y - r.org.y, 1); b->flag = BI_OFFSCREEN; b->rect=r; rectf (b, r, F_CLR); return b; } void bfree(b) Bitmap *b; { if(b) { pr_destroy((Pixrect *)b->dr); free((char *)b); } } Font getfont(s) char *s; { return(pf_open(s)); } Point string (f, s, b, p, c) Font *f; char *s; Bitmap *b; Point p; Code c; { if(b->flag & BI_OFFSCREEN) p = sub(p, b->rect.origin); if(b->flag & BI_OFFSCREEN){ struct pr_prpos where; where.pr = (Pixrect *)b->dr; where.pos.x = p.x; where.pos.y = p.y - (*f)->pf_char['A'].pc_home.y; pf_text(where, c, *f, s); } else pw_text((Pixwin *)b->dr, p.x, p.y - (*f)->pf_char['A'].pc_home.y, c, *f, s); return(add(p, Pt(strwidth(f,s),0))); } int strwidth (f, s) Font *f; register char *s; { struct pr_size size; size = pf_textwidth(strlen(s), *f, s); return(size.x); } #ifdef sun386 Texture ToTexture(bits) register short *bits; { short *mybits = (short *)malloc((unsigned)16*sizeof(short)); register short *to = mybits; extern struct pixrectops mem_ops; static struct mpr_data d = {mpr_linebytes(16,1), (short *)0, {0, 0}, 0, 0}; static struct pixrect pix = {&mem_ops, 16, 16, 1, (caddr_t)&d}; while(to < &mybits[16]) *to++ = *bits++; d.md_image = mybits; d.md_flags &= ~MP_I386; /* turn off "already modified" bit */ d.md_flags |= MP_STATIC;/* turn on static bit */ pr_flip(&pix); return mybits; } #endif Cursor ToCursor (source, mask, hotx, hoty) short source[], mask[]; { Cursor c; #ifdef sun386 c.bits = ToTexture(source); #else c.bits = source; #endif c.hotx = hotx; c.hoty = hoty; return(c); } #define BUTTON1 0x4 #define BUTTON2 0x2 #define BUTTON3 0x1 handleinput () { struct inputevent ie; int more; unsigned char c; static grabbed; static struct timeval tv; unsigned int mask; for(;;){ if(input_readevent(displayfd, &ie) == -1){ perror("input_readevent: "); break; } mouse.xy.x = ie.ie_locx; mouse.xy.y = ie.ie_locy; mouse.time = ie.ie_time.tv_sec*1000 + ie.ie_time.tv_usec/1000; if(event_is_ascii(&ie)){ c = ie.ie_code; kbdread(&c); P->state |= KBD; } else if (event_is_key(&ie)&& event_is_down(&ie)) { char *cp; cp = kcbuf[ie.ie_code-KEYOFF]; if (cp) { if (kctype[ie.ie_code-KEYOFF]) rcvbfill(cp, strlen(cp)); else { while (*cp) kbdread(cp++); P->state |= KBD; } } } else if(event_is_button(&ie)){ switch(ie.ie_code){ case MS_LEFT: if(win_inputnegevent(&ie)){ mouse.buttons &= ~BUTTON1; } else{ mouse.buttons |= BUTTON1; if(!grabbed){ win_grabio(displayfd); grabbed = 1; } } break; case MS_MIDDLE: if(win_inputnegevent(&ie)){ mouse.buttons &= ~BUTTON2; } else{ mouse.buttons |= BUTTON2; if(!grabbed){ win_grabio(displayfd); grabbed = 1; } } break; case MS_RIGHT: if(win_inputnegevent(&ie)){ mouse.buttons &= ~BUTTON3; } else{ mouse.buttons |= BUTTON3; if(!grabbed){ win_grabio(displayfd); grabbed = 1; } } break; case LOC_WINENTER: mousewin=1; break; case LOC_WINEXIT: mousewin=0; break; } if(!button123() && grabbed){ win_releaseio(displayfd); grabbed = 0; } } /* break if there is nothing to read */ mask = 1 << displayfd; if ((more = select(displayfd + 1, &mask, 0, 0, &tv)) == -1){ perror("handleinput:"); break; } if(!more) break; } } Jscreengrab() { if (!Jlocklevel) { if (screendepth == 1) { Jfscp = fullscreen_init(displayfd); Jfscreen.dr = (char *)Jfscp->fs_pixwin; Jfscreen.rect.origin.x = Jfscp->fs_screenrect.r_left; Jfscreen.rect.origin.y = Jfscp->fs_screenrect.r_top; Jfscreen.rect.corner.x = Jfscp->fs_screenrect.r_left + Jfscp->fs_screenrect.r_width; Jfscreen.rect.corner.y = Jfscp->fs_screenrect.r_top + Jfscp->fs_screenrect.r_height; } else Jfscreen = display; } Jlocklevel++; } Jscreenrelease() { if (--Jlocklevel <= 0) { Jlocklevel = 0; if (screendepth == 1) fullscreen_destroy(Jfscp); } } ringbell () { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; win_bell(displayfd,tv,0); } ttyswparse(mask) struct inputmask *mask; { char fbuf[200]; FILE *fp; char line[100], cmd[30], arg1[30], arg2[100]; int i,k; sprintf(fbuf,"%s/.ttyswrc",getenv("HOME")); if ((fp = fopen(fbuf,"r")) == (FILE*) NULL) return; while (fgets(line, sizeof (line), fp)) { if (line[0] == '#') continue; /* crude using scanf, but quick and dirty */ i = sscanf(line, "%[^ \t\n]%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n",cmd, arg1, arg2); if ((i == 3) && (strcmp(cmd,"mapi") == 0 || strcmp(cmd,"mapo") == 0 )) { k = ttyswrcdecode(arg1); if (k < 0) continue; k -= KEYOFF; if (k < 0 || k >= MAXKEY) continue; win_setinputcodebit(mask, k+KEYOFF); kcbuf[k] = kbufp; if (strcmp(cmd,"mapo") == 0) kctype[k] = 1; kparse(arg2); } } fclose(fp); } kparse(s) char *s; { int c,i; char *dp; while (c = *s++) { switch(c) { case '^': *kbufp++ = *s++ & 037; break; case '\\': dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; c = *s++; nextc: if (*dp++ == c) { *kbufp++ = *dp++; break; } dp++; if (*dp) goto nextc; if (isdigit(c)) { c -= '0', i = 2; do c <<= 3, c |= *s++ - '0'; while (--i && isdigit(*s)); } default: *kbufp++ = c; break; } } *kbufp++ = 0; } ttyswrcdecode( s) char *s; { int i; if (strcmp(s, "LEFT") == 0) return (KEY_BOTTOMLEFT); else if (strcmp(s, "RIGHT") == 0) return (KEY_BOTTOMRIGHT); else if (isdigit(s[1])) { i = atoi(&s[1]); if (i < 1 || i > 16) return (-1); switch (s[0]) { case 'L': if (i == 1 || (i > 4 && i < 11)) { return (-1); } else return (KEY_LEFT(i)); case 'R': return (KEY_RIGHT(i)); case 'T': case 'F': return (KEY_TOP(i)); } } return (-1); } #endif /* SUNTOOLS */ xcip/LIBDMDX11/bitblt.c0000644000175300001440000001657111513632541013230 0ustar meusers/* bitblt routines */ #include "jerq.h" void bitblt (sb, r, db, p, f) Bitmap *sb, *db; Rectangle r; /* in source bitmap */ Point p; /* in dest bitmap */ Code f; { int wd = r.corner.x - r.origin.x; int ht = r.corner.y - r.origin.y; if(sb->flag & BI_OFFSCREEN) r.origin = sub(r.origin, sb->rect.origin); if(db->flag & BI_OFFSCREEN) p = sub(p, db->rect.origin); #ifdef X11 /* * This should work but doesn't - the color frame buffer currently * doesn't support using the planemask of the CG with XCopyArea * FIX IT when it works as described in the X manual */ #if 1 XSetFunction(dpy, gc, f); if (f != F_STORE) XSetPlaneMask(dpy, gc, fgpix^bgpix); XCopyArea(dpy, sb->dr, db->dr, gc, r.origin.x, r.origin.y, wd, ht, p.x, p.y); if (f != F_STORE) XSetPlaneMask(dpy, gc, 0xFFFFFFFF); #endif #if 0 if (f == F_STORE || f == F_OR) { XSetFunction(dpy, gc, f); XCopyArea(dpy, sb->dr, db->dr, gc, r.origin.x, r.origin.y, wd, ht, p.x, p.y); } else { if (f == F_XOR) f = JfuncXOR; XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, fgpix^bgpix); XSetBackground(dpy, gc, 0); XCopyPlane(dpy, sb->dr, db->dr, gc, r.origin.x, r.origin.y, wd, ht, p.x, p.y, fgpix^bgpix); XSetBackground(dpy, gc, bgpix); } #endif #endif /*X11*/ #ifdef SUNTOOLS if(sb->flag & BI_OFFSCREEN){ if(db->flag & BI_OFFSCREEN) /* pr to pr */ pr_rop((Pixrect *)db->dr, p.x, p.y, wd, ht, f, (Pixrect *)sb->dr, r.origin.x, r.origin.y); else /* pr to pw */ pw_write((Pixwin *)db->dr, p.x, p.y, wd, ht, f, (Pixrect *)sb->dr, r.origin.x, r.origin.y); } else{ if(db->flag & BI_OFFSCREEN) /* pw to pr */ pw_read((Pixrect *)db->dr, p.x, p.y, wd, ht, f, (Pixwin *)sb->dr, r.origin.x, r.origin.y); else /* pw to pw */ pw_copy((Pixwin *)db->dr, p.x, p.y, wd, ht, f, (Pixwin *)sb->dr, r.origin.x, r.origin.y); } #endif /*SUNTOOLS*/ } void point (b, p, f) Bitmap *b; Point p; Code f; { int i; if(b->flag & BI_OFFSCREEN) p = sub(p, b->rect.origin); #ifdef X11 XSetFunction(dpy, gc, f); if (f == F_XOR) XSetForeground(dpy, gc, fgpix^bgpix); else XSetForeground(dpy, gc, fgpix); XDrawPoint(dpy, b->dr, gc, p.x, p.y); #endif /*X11*/ #ifdef SUNTOOLS switch(f){ case F_STORE: case F_OR: if(b->flag & BI_OFFSCREEN) pr_put((Pixrect *)b->dr, p.x, p.y, 1); else pw_put((Pixwin *)b->dr, p.x, p.y, 1); break; case F_CLR: if(b->flag & BI_OFFSCREEN) pr_put((Pixrect *)b->dr, p.x, p.y, 0); else pw_put((Pixwin *)b->dr, p.x, p.y, 0); break; case F_XOR: if(b->flag & BI_OFFSCREEN) { i = pr_get((Pixrect *)b->dr,p.x,p.y); pr_put((Pixrect *)b->dr, p.x, p.y, !i); } else { i = pw_get((Pixwin *)b->dr,p.x,p.y); pw_put((Pixwin *)b->dr, p.x, p.y, !i); } break; } #endif /*SUNTOOLS*/ } void rectf (b, r, f) Bitmap *b; Rectangle r; Code f; { Point diff; diff = sub(r.corner, r.origin); if(b->flag & BI_OFFSCREEN) r.origin = sub(r.origin, b->rect.origin); #ifdef X11 if (f == F_CLR) { XSetFunction(dpy,gc,F_STORE); XSetForeground(dpy,gc,bgpix); } else if (f == F_XOR) { XSetFunction(dpy,gc,f); XSetForeground(dpy,gc,bgpix^fgpix); } else { XSetFunction(dpy,gc,f); XSetForeground(dpy,gc,fgpix); } XFillRectangle(dpy, b->dr, gc,r.origin.x,r.origin.y,diff.x,diff.y); #endif /*X11*/ #ifdef SUNTOOLS switch(f){ case F_STORE: case F_OR: f = PIX_NOT(PIX_SRC); break; case F_CLR: f = PIX_SRC; break; case F_XOR: f = PIX_NOT(PIX_SRC) ^ PIX_DST; break; } if(b->flag & BI_OFFSCREEN) pr_rop((Pixrect *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, 0, 0, 0); else pw_write((Pixwin *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, 0, 0, 0); #endif /*SUNTOOLS*/ } screenswap (bp, rect, screenrect) register Bitmap *bp; Rectangle rect; Rectangle screenrect; { bitblt(&display, screenrect, bp, rect.origin, F_XOR); bitblt(bp, rect, &display, screenrect.origin, F_XOR); bitblt(&display, screenrect, bp, rect.origin, F_XOR); } void segment (b, p, q, f) Bitmap *b; Point p, q; Code f; { int i; if(b->flag & BI_OFFSCREEN){ p = sub(p, b->rect.origin); q = sub(q, b->rect.origin); } #ifdef X11 XSetFunction(dpy, gc, f); if (f == F_XOR) XSetForeground(dpy, gc, fgpix^bgpix); else XSetForeground(dpy, gc, fgpix); XDrawLine(dpy, b->dr, gc, p.x, p.y, q.x, q.y); #endif /*X11*/ #ifdef SUNTOOLS /* Blit compatability - don't set the last pixel */ if(b->flag & BI_OFFSCREEN){ i = pr_get((Pixrect *)b->dr,q.x,q.y); pr_vector((Pixrect *)b->dr, p.x, p.y, q.x, q.y, f, 1); pr_put((Pixrect *)b->dr, q.x, q.y, i); } else{ i = pw_get((Pixwin *)b->dr,q.x,q.y); pw_vector((Pixwin *)b->dr, p.x, p.y, q.x, q.y, f, 1); pw_put((Pixwin *)b->dr, q.x, q.y, i); } #endif /*SUNTOOLS*/ } void texture (b, r, tile, f) Bitmap *b; Rectangle r; Texture *tile; Code f; { #ifdef SUNTOOLS extern struct pixrectops mem_ops; static struct mpr_data d = {mpr_linebytes(16,1), (short *)0, {0, 0}, 0, 0}; static struct pixrect textrect = {&mem_ops, 16, 16, 1, (caddr_t)&d}; #endif /*SUNTOOLS*/ Point diff; diff = sub(r.cor, r.org); if (b->flag & BI_OFFSCREEN) r.org = sub(r.org, b->rect.org); #ifdef X11 if (f == F_CLR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, F_STORE); XSetForeground(dpy, gc, bgpix); } else if (f == F_XOR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, bgpix^fgpix); } else if (f == F_OR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, fgpix); } else { /* F_STORE */ XSetFillStyle(dpy, gc, FillOpaqueStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, fgpix); } XSetStipple(dpy, gc, *tile); XFillRectangle(dpy, b->dr, gc, r.org.x, r.org.y, diff.x, diff.y); XSetFillStyle(dpy, gc, FillSolid); #endif /*X11*/ #ifdef SUNTOOLS d.md_image = *tile; if(b->flag & BI_OFFSCREEN) pr_replrop((Pixrect *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, &textrect, r.origin.x, r.origin.y); else pw_replrop((Pixwin *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, &textrect, r.origin.x, r.origin.y); #endif /*SUNTOOLS*/ } void texture32 (b, r, tile, f) Bitmap *b; Rectangle r; Texture32 *tile; Code f; { #ifdef SUNTOOLS extern struct pixrectops mem_ops; static struct mpr_data d = {mpr_linebytes(32,1), (short *)0, {0, 0}, 0, 0}; static struct pixrect textrect32 = {&mem_ops, 32, 32, 1, (caddr_t)&d}; #endif /*SUNTOOLS*/ Point diff; diff = sub(r.cor, r.org); if (b->flag & BI_OFFSCREEN) r.org = sub(r.org, b->rect.org); #ifdef X11 if (f == F_CLR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, F_STORE); XSetForeground(dpy, gc, bgpix); } else if (f == F_XOR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, bgpix^fgpix); } else if (f == F_OR) { XSetFillStyle(dpy, gc, FillStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, fgpix); } else { /* F_STORE */ XSetFillStyle(dpy, gc, FillOpaqueStippled); XSetFunction(dpy, gc, f); XSetForeground(dpy, gc, fgpix); } XSetStipple(dpy, gc, *tile); XFillRectangle(dpy, b->dr, gc, r.org.x, r.org.y, diff.x, diff.y); XSetFillStyle(dpy, gc, FillSolid); #endif /*X11*/ #ifdef SUNTOOLS d.md_image = (short *)*tile; if(b->flag & BI_OFFSCREEN) pr_replrop((Pixrect *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, &textrect32, r.origin.x, r.origin.y); else pw_replrop((Pixwin *)b->dr, r.origin.x, r.origin.y, diff.x, diff.y, f, &textrect32, r.origin.x, r.origin.y); #endif /*SUNTOOLS*/ } xcip/LIBDMDX11/menuhit.c0000644000175300001440000000747411513632541013423 0ustar meusers#include "jerq.h" #define disp Jfscreen #ifdef SUNTOOLS #undef F_STORE #define F_STORE ((displaypw->pw_pixrect->pr_depth==1) ? \ (PIX_DONTCLIP|PIX_SRC) : PIX_SRC) #endif /* SUNTOOLS */ #define scale(x, inmin, inmax, outmin, outmax)\ (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin)) #define bound(x, low, high) min(high, max( low, x )) #define DISPLAY 16 #define BARWIDTH 18 static char **table; static char * tablegen(i) { return table[i]; } menuhit (m, but) register Menu *m; int but; { register int width, i, j, top, newtop, hit, newhit, items; register int lines, length; Point p, q, savep, baro, barc; Rectangle sr, tr, mr; /* scroll, text, menu */ register Bitmap *b; register char *s, *(*generator)(), *from, *to; char fill[64]; Font *font = &defont; int spacing = fontheight(font); int charwidth = ave_fontwid(font); #define sro sr.origin #define src sr.corner #define tro tr.origin #define trc tr.corner #define mro mr.origin #define mrc mr.corner generator = (table=m->item) ? tablegen : m->generator; length = width = items = 0; for( ; s=(*generator)(items); ++items) { length = max(length, strlen(s)); width = max(width, strwidth(font,s)); } if(items == 0){ while(button(but)); return -1; } Jscreengrab(); width += 10; sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0; if(items <= DISPLAY) lines = items; else{ lines = DISPLAY; tro.x = src.x = BARWIDTH; sro.x = sro.y = 1; } tro.y = 1; mrc = trc = add(Pt(tro.x, mro.y), Pt(width, min(items, lines)*spacing+2)); trc.y = src.y = mrc.y-1; newtop = bound(m->prevtop, 0, items-lines); p = add(mouse.xy, Joffset); p.y -= bound(m->prevhit, 0, lines-1)*spacing+spacing/2; p.x = bound(p.x-(src.x+width/2), disp.rect.origin.x, disp.rect.corner.x-mrc.x); p.y = bound(p.y, disp.rect.origin.y, disp.rect.corner.y-mrc.y); sr = raddp(sr, p); tr = raddp(tr, p); mr = raddp(mr, p); b = balloc(mr); if(b) bitblt(&disp, mr, b, mro, F_STORE); rectf(&disp, mr, F_OR); PaintMenu: rectf(&disp, inset(mr, 1), F_CLR); top = newtop; if(items > DISPLAY){ baro.y = scale(top, 0, items, sro.y, src.y); baro.x = sr.origin.x; barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y); barc.x = sr.corner.x; rectf(&disp, Rpt(baro,barc), F_XOR); } for(p=tro, i=top; i < min(top+lines, items); ++i){ q = p; from = generator(i); for(to = &fill[0]; *from; ++from) if(*from & 0x80) for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;) *to++ = *from & 0x7F; else *to++ = *from; *to = '\0'; q.x += (width-strwidth(font,fill))/2; string(font, fill, &disp, q, F_XOR); p.y += spacing; } savep = add(mouse.xy, Joffset); for(newhit = hit = -1; button(but); jnap(2)){ p = add(mouse.xy, Joffset); if(ptinrect(p, sr)){ if(ptinrect(savep,tr)){ p.y = (baro.y+barc.y)/2; cursset(sub(p,Joffset)); } newtop = scale(p.y, sro.y, src.y, 0, items); newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY); if(newtop != top) goto PaintMenu; } savep = p; newhit = -1; if(ptinrect(p, tr)){ newhit = bound((p.y-tro.y)/spacing, 0, lines-1); if(newhit!=hit && hit>=0 && abs(tro.y+spacing*newhit+spacing/2-p.y) > spacing/3) newhit = hit; } if(newhit != hit){ flip(tr, hit, spacing); flip(tr, hit = newhit, spacing); } if(newhit==0 && top>0){ newtop = top-1; p.y += spacing; cursset(sub(p,Joffset)); goto PaintMenu; } if(newhit==DISPLAY-1 && toprect, &disp, b->rect.origin, F_STORE); bfree(b); } Jscreenrelease(); if(hit>=0){ m->prevhit = hit; m->prevtop = top; return hit+top; }else return -1; } flip(r,n,spacing) Rectangle r; { if(n<0) return; ++r.origin.x; r.corner.y = (r.origin.y += spacing*n) + spacing; --r.corner.x; rectf(&disp, r, F_XOR); } xcip/ciprint.sh0000644000175300001440000000563111513632542012357 0ustar meusers#!/bin/sh # C I P R I N T # # Print out pic files from cip or xcip. # Supports printers: Xerox 9700, Imagin i300 and Postscript. # Uses old and new troff, pic, dx9700 and prt. VERSION="x5.0" FONTSIZE="TX97.ti10p" # Supports font sizes 7 & 10. PRINTER_TYPE=xr # Printer default - override with -t option. PO="0.4" # Position offset - override with -o option. VERS_FLAG=0 # Determine version of Documenter's WorkBench (DWB). if [ "${DWB}" = "" ] then DWBV=`where dwbv` if [ "$DWBV" = "" ] then if test -d /usr/add-on/dwb2.0a then DWB="2" else DWB="1" fi else DWB=`dwbv | cut -f2 -d" "` fi fi args="" files="" until test ${#} -eq 0 do case ${1} in -\?) echo "usage: $0 [-V?] [-o offset] [-t xr|i300 ] [-f12] [printer_args] [files]" exit 0 ;; -V|-v) VERS_FLAG=1 echo "$0 version ${VERSION}" echo "" ;; -o) shift PO="${1}" ;; -o*) PO=`echo $1 |sed -e "s/^-o//"` ;; -t|-T) shift PRINTER_TYPE="${1}" ;; -t*|-T*) PRINTER_TYPE=`echo $1 |sed -e "s/^-.//"` ;; -[f]12) FONTSIZE="TX97.ti12p" # Supports font sizes 9 & 12. ;; -[f]10) FONTSIZE="TX97.ti10p" # Supports font sizes 7 & 10. ;; -*) args="${args} ${1}" ;; +*) args="${args} ${1}" ;; *) files="${files} ${1}" ;; esac shift done case ${PRINTER_TYPE} in xr) # Form command line. The grep at end removes from standard error # numerous meaningless number messages from dx9700. case ${DWB} in 1*) PROCESS_LINE="pic -TX97 - 2>/dev/null | \ troff -mm -${FONTSIZE} - 2>/dev/null | \ ( ndx9700 | opr -txr -r ${args} ) 2>&1 | grep -v '^([0-9]' >&2" ;; 2*) PROCESS_LINE="pic -D - 2>/dev/null | \ troff -mm -${FONTSIZE} - 2>/dev/null | \ ( dx9700 | opr -txr -r ${args} ) 2>&1 | grep -v '^([0-9]' >&2" ;; *) PROCESS_LINE="pic - 2>/dev/null | \ troff -mm -${FONTSIZE} - 2>/dev/null | \ ( dx9700 | opr -txr -r ${args} ) 2>&1 | grep -v '^([0-9]' >&2" ;; esac;; i300) if [ "${IDEST}" = "" ] then echo "Warning: the environment variable IDEST is not set to an i300 destination." echo "" fi case ${DWB} in 1*) PROCESS_LINE="pic -T300 - | troff -mm -Ti300 - | i300 ${args}" ;; 2*) PROCESS_LINE="pic -D - | troff -mm -Ti300 - | i300 ${args}" ;; *) PROCESS_LINE="pic - | troff -mm -Ti300 - | i300 ${args}" ;; esac;; prt) PROCESS_LINE="pic -Tpost - | troff -mm -Tpost | prt -l troff ${args}" ;; *) echo "$0: ERROR: Printer type [-t ${PRINTER_TYPE}] is invalid" >&2 exit 1 ;; esac FIRST=1 # flag for first file. ( echo ".lg 0" # turn off ligation; eg. "ff" echo ".rm )k" # turn off tick marks at top of page echo ".PH" # turn off page headers for i in ${files} do if [ $FIRST = 1 ] ; then FIRST=0 else echo ".bp" # break to next page fi echo ".po ${PO}i" # position over inches echo ".DS CB" # center picture cat $i echo ".DE" done ) | if [ $VERS_FLAG = 1 ] then echo ${PROCESS_LINE} else eval ${PROCESS_LINE} fi xcip/dmd/0000755000175300001440000000000011513632544011114 5ustar meusersxcip/tmenuhit.c0000644000175300001440000007374211513632542012364 0ustar meusers/* TMENUHIT */ #ifdef DMD5620 /* Note: tmenuhit is built into the DMD 630 ROMS. For X11, using the menus program in LIBDMDX11. */ #include #include #include "tmenuhit.h" static Word checkmark[] = { /* check mark */ 0x00000000, 0x00030000, 0x00070000, 0x000E0000, 0x001C0000, 0x00380000, 0x00700000, 0x00E00000, 0x61E00000, 0x73C00000, 0x3F800000, 0x3F000000, 0x1E000000, 0x1E000000, 0x0C000000, 0x00000000, }; Bitmap B_checkmark = { (Word *) checkmark, 1, 0, 0, 16, 16, 0 }; static Word rtarrow[] = { /* right arrow */ 0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00E0, 0x00F8, 0xFFFE, 0xFFFE, 0x00F8, 0x00E0, 0x00C0, 0x00C0, 0x0080, 0x0000, 0x0000, }; Bitmap B_rtarrow = { (Word *) rtarrow, 1, 16, 0, 32, 16, 0 }; int cursxyonly; /* * The following set of definitions take advantage of built-in * routines available because of the definitions in the * file and the standalone vector tables. */ #define realmouse #define Jcursinhibit #define Jcursallow #include #define mouse realmouse /* * Macro definitions for commonly used functions. * * scale() - converts value from scalar to another another. * * bound() - insures that a value is between two bounds and * will assign the boundary value should the input * value exceeds the bounds. * xyon() - sets the cursxyonly variable * xyoff() - clears the cursxyonly variable */ #define scale(x, inmin, inmax, outmin, outmax)\ (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin)) #define bound(x, low, high) min(high, max( low, x )) #define xyon() cursxyonly=1 #define xyoff() cursxyonly=0 /* * Constant definitions. * * BORDER - the thickness in pixels for the border * surrounding a menu. * DISPLAY - maximum number of menu items displayed per menu. * DELTA - used in scroll bar for hysterisis checks * BARWIDTH - width of the rectangle for the scroll bar * SPACEPAD - spacing in pixels for use between text and icons * MAXDEPTH - maximum levels depth for nesting menus * MAXCHARS - maximum number of characters allowed per text line. * SELECT,NOSELECT - = tmselect, did a menu selection occur. */ #define BORDER 2 #define DISPLAY 16 #define DELTA 6 #define BARWIDTH 18 #define SPACEPAD 5 #define MAXDEPTH 8 /* don't use too much stack */ #define MAXCHARS 128 #define SELECT 1 #define NOSELECT 2 /* * Tleaf - structure definition unique for each recursion level of * menus. It contains characteristics that are global to * a given menu. * org - the origin point for the menu. * width - the width in pixels of the menu. * items - the number of items in the menu. * txtwdith- number of pixels of the widest text string. * tbranch - contains the coordinates for a rectangle that is * associated with a sub-menu. Except for when treegrow is * set, a submenu can only be displayed while the mouse * cursor is in that menu or its tbranch. * spacing - the number of pixels allocated to the vertical spacing * of items. It is 4 pixels plus the larger of the icons * or the font height. * iconwidth - * the number of pixels allocated horizontally for all * icons. If zero, then no icons are used. * md - menu data for the tleaf * newhit - last hit in the menu */ typedef struct Tleaf { Point org; int width; int items; int txtwidth; Rectangle tbranch; char spacing; char iconwidth; struct menudata *md; int newhit; } Tleaf; /* * Globals * * tnoret - the address of this variable is used whenever a non- * selection is made. * tfill - character array used for generating the text string * used for menu items * treegrow - a flag that when set indicates that sub-menus should * be generated to the lowest leaf based on the previous * values. This is used when menus are generated * initially on a button depression. * tleaf[] - array of type structure Tleaf that contains information * regarding the size and screen location of menus. * tuser_mi - contains a pointer to the menu item in the user's * defined menu structure. * select_menu - the menu that a selection was made from. * tmselect - true is selection is made. If a menu item was selected, * it equals SELECT, otherwise it equals NOSELECT * setorg - set origin of root menu * redraw - redraw menu after selection * wasredraw - returning from a "redraw" via tm_ret(), don't * update prevhit/prevtop because it was already done * and it would break setup's use of tmenuhit * tstatic - flag that indicates a static menu. */ char tfill[MAXCHARS]; int treegrow; Tleaf tleaf[MAXDEPTH]; Titem *tuser_mi; Tmenu *select_menu; int tmselect; int setorg; int redraw; int wasredraw; int tstatic; /* * Titem temp - * a working structure of type Titem used to store the * converted user Titem structure into the internal Titem * structure for processing by the tmhit() code. * * tablegen(i, m) - * The default menu generator for the tmenuhit() routine. * The generator returns an address to a menu item. This * will normally be pointing to the "temp" menu item. * If a user specified menu generator is provided, it is * called here. */ Titem temp; Titem * tablegen(i, m) int i; register Tmenu *m; { register unsigned long *fptr; register unsigned long *tptr; register int count; register unsigned int mask; register int menumap; /* * check the menumap variable. if not defined, then * set it to all fields, else force the text field to * to always be defined in addition to the user's * definition. */ menumap = (m->menumap) ? m->menumap | TM_TEXT : 0xffff; /* * get the titem variable, whether it comes from a generator * function, or is in an array of titems. */ if (m->item == 0) { fptr = (unsigned long *) m->generator(i, m); } else { for(fptr=(unsigned long *)m->item, mask=0x01; mask != MAX_MASK; mask<<=1) if (menumap & mask) fptr += i; } tuser_mi = (Titem *) fptr; /* * set up the from and to pointers, initialize count, and build * the temp structure from the user Titem structure. */ tptr = (unsigned long *) &temp; for(count=0, mask=0x01; count < MAX_TMFIELDS; count++, menumap>>=1) { if (menumap & mask) *tptr++ = *fptr++; else *tptr++ = (unsigned long) 0; } /* * if the font pointer is not defined, set it to defont. */ if (temp.font == 0) temp.font = &defont; return(&temp); } /* * tmenuhit(m, but, flags) * - entry point for the menuhit routine for tree menus. * It takes four arguments. "m" is a pointer to a * menu routine of type structure Tmenu. "but" is * the button that is assumed to be depressed when * this function is called. When this button is released, * a selection (or non-selection) is made. "expand" is * a flag that application programs can set. When set, * tmenuhit() will initially generate the menu tree to * its lowest leaf based on previous selection values. * "p" is the position of the origin of the root menu. * If p.x or p.y are invalid, the menu is centered on * the mouse. * * tmenuhit() calls scanmenu() to determine the sizes of the * menu and its sub-menus. These sizes are then used to * determine the origin point for each of the menus. These * points are stored in the global variable tleaf[]. tmhit() * is then called with a pointer to the menu structure and that * function will draw each of the menus. */ Titem * tmenuhit(m, but, flags) register Tmenu *m; { register Tmenu *curr_m, *next_m; register Tleaf *t; register int depth; register Point *p; void tmhit(); Tmenu * scanmenu(); treegrow = flags & TM_EXPAND; wasredraw = redraw = flags & TM_NORET; tstatic = flags & TM_STATIC; if(setorg = (flags & TM_POINT)) p = (Point *)(&flags + 1); curr_m = m; t = &tleaf[0]; depth = 0; /* * scan menus to determine the sizes of the menus for this * tree growth. */ do { next_m = scanmenu(curr_m, t++); depth++; } while ((curr_m = next_m) && treegrow); /* * set up origin points for each of the menus such that * the bottom-most leaf menu is centered around the mouse * cursor. However, make sure that the menus stay within * screen borders and that maximum overlap cannot occur. * If the mouse cursor is such that it cannot remain in the * bottom most leaf menu and still maintain the non- * overlap requirement, then those menus to the right of * the the mouse will not be displayed. * * The user will have to grow them by sliding the mouse * manually to the right. */ --t; --depth; if(!setorg) { /* * center the menu on the mouse */ t->org.y = mouse.xy.y; t->org.x = bound(mouse.xy.x - (SPACEPAD + (t->iconwidth ? t->iconwidth+SPACEPAD : 0) + t->txtwidth + (t->items > DISPLAY ? BARWIDTH : 0)), 0, XMAX-t->width ); for(--t, --depth; t >= &tleaf[0]; --t, --depth) { t->org.x = bound((t+1)->org.x - t->width + (BORDER-1), 0, XMAX); t->org.y = (t+1)->org.y; } t++; depth++; } else { /* * put the root menu's origin at p */ t = t - depth; t->org = *p; if((*p).x > XMAX - t->width) t->org.x = XMAX - t->width; t->org.y += bound(m->prevhit, 0, min(DISPLAY,t->items)-1)*t->spacing + t->spacing/2; } if (t->org.x == 0 || setorg) { /* * We've hit the left side, assume overlap has occurred, * and recalculate menu origins. * * Otherwise, the origin point for the root menu was specified. */ for(++t, ++depth; depth < MAXDEPTH; t++, depth++) { t->org.x = bound((t-1)->org.x + (t-1)->width - (BORDER-1), 0, XMAX); t->org.y = (t-1)->org.y; } } tmselect = 0; tmhit(m, but, 0); if(tmselect == SELECT) { /* * make sure the Titem returned is correct if it is * filled in by a generator function */ tablegen(select_menu->prevhit + select_menu->prevtop, select_menu); return(tuser_mi); } else return((Titem *)0); } /* * menudata - A structure used in each recursion. It is a collection * data that is relevant to tmhit() and subroutines that * it calls. This is a single pointer to this structure * that is passed to routines rather than each individual * variable. * m - Member of structure menudata. It points to the menu * data structure containing the information supplied * by the application program for the tmenuhit() function. * top - indicates the index of the topmost item in the * menu to be displayed. This is used only for scrolling * menus. * lines - the number of lines to be displayed in the menu. This * be equal to DISPLAY or is less if the total number of * menu items for a given menu is less. * br - rectangle which defines the scroll bar display. * sr - defines the rectangle that the scroll bar can travel * within. * tr - defines the rectangle for the text portion of the menu. * mr - defines the entire rectangle for the menu. * b - pointer to a bitmap which is dynamically assigned * whenever a menu is generated. This bitmap stores * the area that is obscured by the menu. If no memory * is available, the pointer is not used and the menu * is XOR'ed on top of the existing background. */ typedef struct menudata { Tmenu *m; int top, lines; Rectangle br, sr, tr, mr; /* bar, scroll, text, menu */ Bitmap *b; } Menudata; /* * tmhit(m, but, depth) * - This is the heart of the menu routine. "m" contains * a pointer to a Tmenu structure. "but" is the button * number associated with this menu selection. This * number is needed so it is known which of the remaining * two buttons are available for use as help buttons. * "depth" is passed onto the subroutines called by this * routine to acquire information previously determined * for each of the menus and sub-menus involved in the * initial generation of the menu tree. The depth is also * used to compare against the maximum limit of MAXDEPTH * so as to prevent too much use of the stack space and * the subsequent problems that can result. * * After the initial generation of the menu tree, this * routine basically loops, waiting for mouse input to * determine which menu selection should be highlighted, * whether to exit a sub-menu, or whether to generate a * new sub-menu. * * This routine exits when the "but" button is released * or when the user moves the mouse outside of the right * arrow rectangle or to the left of the menu. * */ void tmhit(m, but, depth) register Tmenu *m; { /* * Definitions of the following stack variables. * * p - contains the mouse position. This variable * also has a shared function initially to * store the origin point for a menu. * savep - contains the old mouse position from the last * poll. This is used only with the scroll bar * to determine whether cursset() is used to keep * the mouse within the scroll bar when it is * being moved. * rside - defines the rectangle where are the sub-menu * icons (B_rtarrow) are displayed in the menu. * When the mouse cursor is in this area, checking * for the existence of a sub-menu is made. * rhit - The rectangle defining the area of the menu * item that is selected. These coordinates are * used for calculating the values of the rectangle * "tbranch", and for calculating the values of the * rectangle for help menus. * mi - pointer to the current menu item of type structure * Titem. * mdata - A structure of the type Menudata that contains * the information regarding the size and layout * of the menu for this depth. This structure was * defined so that a larger number of variables can * passed with a single pointer to different subroutines. * t - Pointer to a global structure that contains the * origin point for a menu at a given depth. These * are generated in tmenuhit() and passed to tmhit() * for the initial generation of the menu tree. They * are changed whenever the a new sub-menu is made. * newtop - contains the index of the menu item that is to * displayed for the menu. Normally this value will * zero, except when scrolling menus are used. * hit - The index value used to indicate the current menu item * that is selected. This value is offset by the value * newtop or md->top to determine the true index into * the menu items for a given menu. * newhit - Functions the same as newhit except it represents * the latest value. "hit" is then updated to * "newhit" after "newhit" has been validated. Validation * includes that the value is not a hit on a greyed item, * and that the value is adjusted (through hysterisis) * to insure that the mouse has been fully moved over * a new selection. */ Point p, savep; Rectangle rside, rhit; register Titem *mi; Menudata mdata; register Tleaf *t; register Menudata *md; register int newtop, hit, newhit, greyed; Tmenu *scanmenu(); #define sro md->sr.origin #define src md->sr.corner #define tro md->tr.origin #define trc md->tr.corner #define mro md->mr.origin #define mrc md->mr.corner #define bro md->br.origin #define brc md->br.corner #define tbro tbranch.origin #define tbrc tbranch.corner /* * Set-up data and other pointers for globals and data to be * passed to other subroutines. This includes the origin point * for the menu, and data regarding the size of the menu itself. */ t = &tleaf[depth]; p = t->org; md = &mdata; md->m = m; /* * If the treegrow flag is set, then this is a first invocation of * the menu tree and menus are to be generated to the bottom most * leaf based on the previous values stored in the menu data * structures. These will be zero if these menus are called for the * first time ever. * * Otherwise, each menu must be scanned by scanmenu() to generate the * necessary data information concerning the menu to be generated. */ tmhit_top: if (!treegrow) { scanmenu(m, t); } if((t->items == 0) || ((t+1)->org.x > mouse.xy.x)) /* * Unset the treegrow flag if we hit a menu that * is zero-sized or if we have a case of overlapping * menus that caused the menu origins to be re- * calculated and therefore moved to the right of * of the mouse. */ treegrow = 0; /* * Set-up all the rectangles which define the size and layout of * the menu to be generated. Adjustments are made to the origin * for the menu depending on whether or not it fits on the screen. */ mro.x = mro.y = 0; sro.x = sro.y = src.x = tro.x = tro.y = BORDER; bro.x = bro.y = brc.x = brc.y = BORDER; if(t->items <= DISPLAY) md->lines = t->items; else { md->lines = DISPLAY; tro.x += BARWIDTH; src.x += BARWIDTH; } mrc = add(mro, Pt(t->width, min(t->items, md->lines)*t->spacing + BORDER*2)); trc = add(mrc, Pt(-BORDER,-BORDER)); src.y = trc.y; newtop = bound(m->prevtop, 0, t->items - md->lines); p.y -= bound(m->prevhit, 0, md->lines-1)*t->spacing+t->spacing/2; p.x = bound(p.x, 0, XMAX-mrc.x); p.y = bound(p.y, 0, YMAX-mrc.y); md->sr = raddp(md->sr, p); md->tr = raddp(md->tr, p); md->mr = raddp(md->mr, p); rside = md->mr; rside.origin.x = rside.corner.x - 20 - BORDER; /* * See if there is enough memory to save the bitmap for the * area of the screen that will be obscured as result of the * menu display. If there is, then bitblt that portion of the * screen to the allocated memory. Then clear the screen and * draw the menu border. Additional testing is done to insure * that should the menu be too large to fit in a screen bitmap, * the rectangle of the menu is clipped to the bitmap of the screen. * The variable rhit is temporarily used to store the clipped rect. * * If there isn't enough bitmap memory, then just XOR the menu. */ rhit = md->mr; rectclip(&rhit, physical.rect); md->b = balloc(rhit); Jcursinhibit(); if(md->b) bitblt(&physical, rhit, md->b, rhit.origin, F_STORE); rectf(&physical, md->mr, (md->b ? F_CLR:F_XOR)); if(md->b) rectf(&physical, inset(md->mr, BORDER-1), F_OR); rectf(&physical, inset(md->mr, BORDER), (md->b ? F_CLR:F_XOR)); Jcursallow(); /* * Begin that part of the routine where the drawing of the menu * commences. Set up the proper value for the menu item that * will the first item in the display (if this is a scrolling menu, * otherwise this value will be zero). A call to the drawmenu() * routine is made which performs the actual drawing of the menu * contents. */ PaintMenu: md->top = newtop; drawmenu(&mdata, t); mi = 0; /* * This is the major looping code that processes the movement of the * mouse and whether there were any help menus requested. Movement * of the mouse on a sub-menu icon (the B_rtarrow icon) generates a * recursive call to this routine to display the submenu. A current * menu is exited by moving the mouse to the left of the current menu * display except for the topmost (root) menu or when the menu button * is released. Because of race conditions it is possible to change * the button state multiple times, therefore to insure that this * subroutine exits, if tmselect is non-zero, we're really exiting. */ p = mouse.xy; for(newhit = hit = -1; ((tstatic && ((but && !bttn(but)) || (!but && !bttn123()))) || (!tstatic && ((but && bttn(but)) || (!but && bttn123())))) && (tmselect == 0); nap(2)) { savep=p; p = mouse.xy; if(cursxyonly && !eqpt(savep, p)) { register int deltax, deltay; /* ** Fake 630 firmware for x-y mouse movement */ deltax = p.x - savep.x; deltay = p.y - savep.y; if (deltax < 0) deltax = -deltax; if (deltay < 0) deltay = -deltay; if (deltax > deltay) p.y = savep.y; else p.x = savep.x; cursset(p); } /* * Set the mouse movement for x-y only mode when the * mouse cursor is within a menu. */ if(ptinrect(p, t->tbranch) || ptinrect(p, md->mr)) xyon(); else xyoff(); /* * Check if the menu should be exited because we are not * generating the entire tree and the mouse is not in the * in the sub-menu icon of the previous menu and the * mouse is to the left of the current menu. */ if(!treegrow && !ptinrect(p, t->tbranch) && depth && (p.x < mro.x)) { break; } /* * Processing when the mouse is in the scroll bar region. */ if(ptinrect(p, md->sr)){ /* * we are still in the scroll bar, so update the * menu appropriately to give the appearance of * scrolling. */ if (ptinrect(p, md->br) && !ptinrect(savep,md->br)){ p.y = (bro.y+brc.y)/2; cursset(p); } if (ptinrect(p, md->br) || ptinrect(savep,md->br)){ newtop = scale(p.y, sro.y, src.y, 0, t->items); newtop = bound(newtop-DISPLAY/2, 0, t->items-DISPLAY); if(newtop != md->top) { erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } } } /* * Processing to determine a menu selection */ newhit = -1; mi = 0; if(ptinrect(p, ((t->items > DISPLAY) ? md->tr:md->mr))) { newhit = bound((p.y-tro.y)/t->spacing, 0, md->lines-1); if(newhit!=hit && hit>=0 && (p.y > (tro.y + hit*t->spacing - 3)) && (p.y < (tro.y + (hit+1)*t->spacing + 3))) newhit = hit; rhit = md->tr; rhit.corner.y = (rhit.origin.y += newhit*t->spacing) + t->spacing; } if(treegrow) { /* * If we're supposed to expand, then make it look * like we've made a selection in this menu. But, * made sure that prevhit makes sense since the * size of the menu may have changed since the last * time menuhit was invoked. */ md->top = m->prevtop; if ((newhit = m->prevhit) >= md->lines) { newhit = -1; treegrow = 0; } } if(newhit != -1) { /* * Get the menu item associated with the latest * newhit value. The subroutine tablegen() also * sets the global tuser_mi which is the menu * item value that eventually is returned to the * user. */ mi = tablegen(md->top+newhit, m); } else tuser_mi = (Titem *)0; /* * Processing that is done after a selection is determined. * This includes generating the reverse video for the current * selection. */ if(newhit != hit) { if(!greyed) { flip(md->tr, hit, T_black, t); } if(mi->ufield.grey) { greyed = 1; } else { flip(md->tr, newhit, T_black, t); greyed = 0; } hit = newhit; } /* * Processing to determine the generation of a sub-menu. * Note that if there are any user-provided functions for * executing before and returning from a sub-menu, that * occurs here. */ if((newhit != -1) && (ptinrect(p, rside) || treegrow)) { if((depth < MAXDEPTH-1) && mi->next && !(mi->ufield.grey&0x01)) { if(mi->dfn) (*mi->dfn)(tuser_mi); (t+1)->tbranch = md->tr; (t+1)->tbro.x = (t+1)->tbrc.x - 20; (t+1)->tbrc.x += BORDER; (t+1)->tbro.y = bound(tro.y + hit*t->spacing - 3, mro.y, mrc.y); (t+1)->tbrc.y = bound(tro.y + (hit+1)*t->spacing + 3, mro.y, mrc.y); if (!treegrow) { (t+1)->org.x = mrc.x - (BORDER-1); (t+1)->org.y = mro.y + newhit*t->spacing + t->spacing/2; } t->md = md; t->newhit = newhit; tmhit(mi->next, but, depth+1); mi = tablegen(t->md->top+newhit, t->md->m); if(mi->bfn) (*mi->bfn)(tuser_mi); } else { treegrow = 0; } } /* * Handles re-drawing of scrolling menus. */ if(newhit==0 && md->top>0){ newtop = md->top-1; p.y += t->spacing; cursset(p); erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } if(newhit==DISPLAY-1 && (md->top < (t->items - md->lines))){ newtop = md->top+1; p.y -= t->spacing; cursset(p); erasemenu(&mdata, t, hit, greyed); /* ->->-> */ goto PaintMenu; } } /* * Exiting menu, clean-up screen and bitmaps */ if(md->b){ Jcursinhibit(); screenswap(md->b, md->b->rect, md->b->rect); Jcursallow(); bfree(md->b); } else { erasemenu(&mdata, t, hit, greyed); rectf(&physical, md->mr, F_XOR); rectf(&physical, inset(md->mr, BORDER), F_XOR); } /* * Set-up return value and execute user specified function * on menu item selection IFF the button state has changed. */ if(((tstatic && ((but && bttn(but)) || (!but && bttn123()))) || (!tstatic && ((but && !bttn(but)) || (!but && !bttn123())))) && (tmselect == 0)) { if((mi == 0) || ((mi=tablegen(md->top+newhit, m)) && (mi->ufield.grey & 0x01))) { tmselect = NOSELECT; } else { m->prevhit = hit; m->prevtop = md->top; if(mi->hfn) (*(mi->hfn)) (tuser_mi); if(!redraw) { tm_return: tmselect = SELECT; select_menu = m; } else { if(depth) { mi = tablegen((t-1)->md->top+(t-1)->newhit, (t-1)->md->m); if(mi->bfn) (*mi->bfn) (tuser_mi); for(newtop=1; newtop<=depth; newtop++) { /* * update all the parent menus' * prevhit and prevtop. A small * kludge in that to reduce stack * space, newtop is used and then * reset back at the top. */ (t-newtop)->md->m->prevtop = (t-newtop)->md->top; (t-newtop)->md->m->prevhit = (t-newtop)->newhit; } if(mi->dfn) (*mi->dfn) (tuser_mi); if(!redraw) goto tm_return; } while((tstatic && ((but && bttn(but)) || (!but && bttn123()))) || (!tstatic && ((but && !bttn(but)) || (!but && !bttn123())))) ; p = mro; p.y += hit*t->spacing+t->spacing/2; goto tmhit_top; } } } if(hit>=0 && tmselect==SELECT && !wasredraw) { m->prevhit = hit; m->prevtop = md->top; } /*end*/ } /* * Draws a menu given the Tleaf structure. The position of the * menu is calculated elsewhere. This routine determines the * individual placement of the text and icons within the menu. */ drawmenu(md, t) register Menudata *md; register Tleaf *t; { Point p, q, r; register int i, j, k; register char *from, *to; register Titem *mi; Jcursinhibit(); if(t->items > DISPLAY){ bro.y = scale(md->top, 0, t->items, sro.y, src.y); bro.x = sro.x + 1; brc.y = scale(md->top+DISPLAY, 0, t->items, sro.y, src.y); brc.x = src.x - 1; rectf(&physical, md->br, F_XOR); } for(j=0, p=tro, i=md->top; i < min(md->top+md->lines, t->items); ++i, ++j){ q = p; mi = tablegen(i, md->m); if(mi->ufield.grey & 0x01) flip(md->tr, j, T_grey, t); q.x += SPACEPAD; if (t->iconwidth) { if(mi->icon) { r = q; r.y += (t->spacing - (mi->icon->rect.corner.y - mi->icon->rect.origin.y))/2; r.x += (t->iconwidth - (mi->icon->rect.corner.x - mi->icon->rect.origin.x))/2; bitblt(mi->icon, mi->icon->rect, &physical, r, (md->b ? F_OR:F_XOR)); } q.x += t->iconwidth + SPACEPAD; } from = mi->text; for(to = &tfill[0]; *from && (to < &tfill[MAXCHARS]); ++from) if(*from & 0x80) { *to = '\0'; k = t->txtwidth - (strbits(tfill,mi->font) + strbits(from+1,mi->font)); while(k > 0) { k -= mi->font->info[*to++ = *from & 0x7F].width; } } else *to++ = *from; *to = '\0'; q.x += (t->txtwidth-strbits(tfill,mi->font))/2; q.y += (t->spacing - mi->font->height)/2 + 1; ; string(mi->font, tfill, &physical, q, (md->b ? F_OR:F_XOR)); if(mi->next) { bitblt(&B_rtarrow, B_rtarrow.rect, &physical, Pt(trc.x-20, p.y+(t->spacing - 16)/2), (md->b ? F_OR:F_XOR)); } if(mi->ufield.grey & 0x01) flip(md->tr, j, T_grey, t); p.y += t->spacing; } Jcursallow(); } /* * Erase a menu by drawing over it again in XOR mode, * or clearing the rectangle occupied by the menu. The * method depends on whether the menu is being XOR'ed on * top of the current screen contents, or the rectangle * for the menu is alloc'ed memory. This routine is * used for clearing XOR'ed menus, or updating scrolling * menus. */ erasemenu(md, t, hit, greyhit) register Menudata *md; register Tleaf *t; register int hit; { if(md->b) { Jcursinhibit(); rectf(&physical, inset(md->mr, BORDER), F_CLR); Jcursallow(); } else { if (!greyhit) flip(md->tr, hit, T_black, t); drawmenu(md, t); } } /* * Routine which looks at a menu and derives the global * characteristics associated with that menu. These are * stored in a Tleaf structure. This routine also returns * a pointer to a submenu, if the submenu exists and was * previously selected as determined by the prevhit and * prevtop values. */ Tmenu * scanmenu(m, t) register Tmenu *m; register Tleaf *t; { register Titem *mi; register int iconwidth, iconheight, fontheight, rside, length, items; register Tmenu *next_m; Titem *tablegen(); next_m = 0; iconwidth = iconheight = fontheight = rside = length = items = 0; for(; (mi=tablegen(items, m))->text; ++items) { length = max(length, strbits(mi->text, mi->font)); fontheight = max(fontheight, mi->font->height); if(mi->icon) { iconwidth = max(iconwidth, mi->icon->rect.corner.x - mi->icon->rect.origin.x); iconheight = max(iconheight, mi->icon->rect.corner.y - mi->icon->rect.origin.y); } if(mi->next) { rside=1; if( (items == (m->prevhit + m->prevtop)) && (mi->ufield.grey == 0)) next_m = mi->next; } } t->spacing = 4 + max(fontheight, iconheight); t->iconwidth = iconwidth; t->txtwidth = length; t->width = BORDER*2 + SPACEPAD + (length ? (SPACEPAD + length):0) + (iconwidth ? iconwidth + SPACEPAD:0) + (rside ? 20:0) + ((items > DISPLAY) ? BARWIDTH:0); t->items = items; return(next_m); } flip(r, n, code, t) Rectangle r; Texture code; register int n; register Tleaf *t; { if(n<0 || n>=t->items) return; r.corner.y = (r.origin.y += t->spacing*n) + t->spacing; texture(&physical, r, &code, F_XOR); } /* * this function is the same as jstrwidth() except that it * masks out the most significant bit in the char, (the * spread bit in spread chars). limits the chars to MAXCHARS. */ strbits(str, font) register char *str; register Font *font; { register int bits; register int chars; chars = bits = 0; while(*str && (chars++ < MAXCHARS)) { bits += font->info[*str++ & 0x7f].width; } return(bits); } /* * The following routine is used by hfn,bfn,dfn when TM_NORET is set * so that a return from the menu can be done by a selected item. * */ void tm_ret() { redraw = 0; tmselect = NOSELECT; } #endif xcip/readPic.c0000644000175300001440000003213011513632544012062 0ustar meusers#include "cip.h" #ifdef X11 #include #else extern char *strchr(); extern char *strrchr(); #endif #ifdef X11 #define CEOF EOF #endif #ifdef DMD630 #define CEOF (-1) #endif #ifdef DMD5620 #define CEOF 0xff #endif char c; char *getText(); Point getPoint(); struct macro *findMacro(); extern Point align(); extern struct macro *macroList; #ifdef X11 extern Cursor hourglass; #else /* X11 */ extern Texture16 hourglass; #endif /* X11 */ char tempStr[MAXTEXT]; Point readPicOffset; struct thing * readPic(fp,h) register FILE *fp; register struct thing *h; { register struct thing *t, *l; struct macro *m; Rectangle r; register int num, i, a , b; Point *plist, p, q; register char *s, type; while ( c != CEOF) { t = TNULL; type = c; getChar(fp); switch(type) { case CEOF: case ' ': case '\n': case '\t': { break; } case 'm': { /* moveto */ p = getPoint(fp); break; } case 'e': { /* ellipse */ p = getPoint(fp); if ((t = newEllipse(p)) == TNULL) { c = CEOF; /* Terminate */ } else { t->otherValues.ellipse.wid = (getInt(fp))<<1; t->otherValues.ellipse.ht = (getInt(fp))<<1; } break; } case 'c': { /* circle */ p = getPoint(fp); if ((t = newCircle(p)) == TNULL) { c = CEOF; } else { t->otherValues.radius = getInt(fp); } break; } case 'a': { /* arc */ p = getPoint(fp); q = getPoint(fp); if ((t = newArc(q,getPoint(fp))) == TNULL) { c = CEOF; /* Terminate */ } else { t->origin = p; } break; } case 'l': { /* line */ a=0; skipWhiteSpace(fp); if (c=='<') { a += startARROW; getChar(fp); } if (c=='>') { a += endARROW; getChar(fp); } if (c=='.' || c=='-') { b = (c=='.')? DOTTED : DASHED; getChar(fp); getInt(fp); /*size*/ } else { b = SOLID; } num = getInt(fp); q = getPoint(fp); for (i=1; iborder = b; t->arrow = a; boundingBox(t); draw(t,add(drawOffset,scrollOffset)); h = insert(t,h); q = p; } break; } case 'b': { /* box */ if (c=='.' || c=='-') { a = (c=='.')? DOTTED : DASHED; getChar(fp); getInt(fp); /*size*/ } else { a = SOLID; } p = getPoint(fp); q = getPoint(fp); if ((t = newBox(canon (p, q))) == TNULL) { c = CEOF; /* terminate */ } else { t->border = a; } break; } case 't': { /* text */ if (c!='c') { p = getPoint(fp); skipWhiteSpace(fp); type = c; getChar(fp); s = getText(fp,'\n'); extractFontandPointSize( s, &currFont, &currPS ); if ((t = newText(p,s)) == TNULL) { c = CEOF; /* Terminate */ } else { Font * f; f = t->otherValues.text.f->f; t->origin.y -= fontheight(f) >> 1; /* Adjust test up a little - needed when printed. */ t->origin.y -= fontheight(f) >>3; boundingBox(t); switch(type) { case 'C': case 'c': { t->otherValues.text.just = CENTER; break; } case 'L': case 'l': { t->otherValues.text.just = LEFTJUST; break; } case 'R': case 'r': { t->otherValues.text.just = RIGHTJUST; break; } } } } break; } case '~': { a = 0; skipWhiteSpace(fp); if (c=='<') { a += startARROW; getChar(fp); } if (c=='>') { a += endARROW; getChar(fp); } num = getInt(fp); plist= (Point *) getSpace((num+3)*sizeof(Point)); if (plist==(Point *) NULL) { c = CEOF; /* Terminate */ break; } for (i=1; i<=num; i++) { plist[i]=getPoint(fp); } plist[num+1]=plist[num]; if ((t = newSpline(num+1,num,plist)) == TNULL) { c = CEOF; } else { t->arrow = a; } break; } case '.': { switch (c) { case 'P': { cursswitch ((Cursor *)NULL); getBox (fp,h); /* Get x and y offsets */ cursswitch (&hourglass); break; } case 'U': case 'u': { /* start of macro */ int j; Point a; char *ns; short yDiff; short height; j = 0; getChar(fp); skipWhiteSpace(fp); s = getText(fp,' '); flushLine(fp); l = readPic(fp,TNULL); /* See Note 1 */ if( (s[0] == 't') && isdigit(s[1]) ) { /* This a TEXT string in macro form */ if(l==TNULL) { t = TNULL; free (s); break; } r.origin.x = Xmax; r.origin.y = YBOT; r.corner.x = 0; r.corner.y = 0; if( (t=l) != TNULL ){ do { /* remove individual text lines */ draw(t,add(drawOffset,scrollOffset)); /* Find minimal non-aligned bounding box. */ r.origin.x = min(r.origin.x, t->bb.origin.x); r.origin.y = min(r.origin.y, t->bb.origin.y); r.corner.x = max(r.corner.x, t->bb.corner.x); r.corner.y = max(r.corner.y, t->bb.corner.y); for( i = 0; t->otherValues.text.s[i] != '\0'; i++) tempStr[j++] = t->otherValues.text.s[i]; tempStr[j++] = '\r'; /* Here is a real kludge!!! Decrement the text name number the number of text lines, so that the final multi-line text thing has the "next" name number. */ textOutName--; t = t->next; } while( t != l ); tempStr[j-1] = '\0'; switch (l->otherValues.text.just) { case CENTER: a.x = (r.origin.x + r.corner.x) >> 1; break; case LEFTJUST: a.x = r.origin.x; break; case RIGHTJUST: a.x = r.corner.x; break; } yDiff = l->next->origin.y - l->origin.y; height = fontheight(l->otherValues.text.f->f); a.y = ((r.origin.y + r.corner.y)>>1) - (height>>1); if( (ns = (char *) getSpace(strlen(tempStr)+1)) == NULL ) { tempStr[0] = '\0'; ns = ""; } for( j=0; tempStr[j] != '\0'; j++ ) ns[j] = tempStr[j]; ns[j]='\0'; t = newText(a,ns); t->otherValues.text.f = findFont(l->otherValues.text.f->ps, l->otherValues.text.f->num); t->otherValues.text.just = l->otherValues.text.just; t->otherValues.text.spacing = yDiff - height; deleteAllThings(l); free(s); } } else { /* This is an ordinary macro */ r = macroBB(l); if( (t=l)!=TNULL ) { do { makeRelative(t,r.origin); t = t->next; } while (t != l); } if( (m = findMacro(s)) == MNULL ) { /* Macro is not in editor, so add macro definition. */ m = recordMacro(l,rsubp(r,r.origin),s); } else { /* There is another macro with same name. */ if( cmpMacroParts(l, m->parts ) ) { /* The macros are identical, so free up list of things just allocated. Macro will reference the first def. */ deleteAllThings(l); free(s); } else { /* The macros having the same name are different, so create a new name. */ free(s); s = getSpace(8); /* 'm' + 6 digits + '\0' */ sprintf( s, "m%d", newMacroId() ); m = recordMacro(l,rsubp(r,r.origin),s); } } t = newMacro(r.origin,m); } break; } case 'E': case 'e': { /* end of macro */ flushLine(fp); return(h); } default: { flushLine(fp); break; } } break; } case 'p': /* Error message: "pic: syntax error ..." */ moreMessage("\np"); s = getText(fp,'\n'); moreMessage(s); moreMessage("\n"); sleep(90); free(s); s = getText(fp,'\n'); moreMessage(s); moreMessage("\n"); free(s); s = getText(fp,'\n'); moreMessage(s); free(s); break; default: { flushLine(fp); break; } } if ((t != TNULL) && (t->type != LINE)) { boundingBox(t); if (t->type != MACRO) { draw(t,add(drawOffset,scrollOffset)); } h = insert(t,h); } } return(h); } /* This little routine reads the next two numbers (height and width) */ /* from fp and calculates the coordinates of a box of that size */ /* centered in the picture drawing area. It then draws the box */ /* on the screen and allows the user to change its location. */ /* The final results are readPicOffset being set to the */ /* origin of this box. */ getBox (fp, h) FILE *fp; struct thing *h; { int height, width; Rectangle r; Point offset; getChar(fp); getChar(fp); height = getInt (fp); width = getInt (fp); r.origin = align( Pt( (XPicSize>>1)-(width>>1), (YPicSize>>1)-(height>>1) ) ); r = rsubp(r, scrollOffset); readPicOffset = r.origin; r.corner = r.origin; r.corner.x += width; r.corner.y += height; offset = add(drawOffset, scrollOffset); cursset( add(r.origin,offset) ); xbox (raddp(r,offset)); /* Show the box on the screen */ ringbell(); changeButtons (READbuttons); while (!button12 () || button3()) { wait (MOUSE); } if (button2 ()) { r = moveBox (r.origin, r, offset, 0); readPicOffset = r.origin; } xbox (raddp(r,offset)); /* Remove the box */ changeButtons (BLANKbuttons); } Point getPoint(f) FILE *f; { Point p; p.x = getInt(f) + readPicOffset.x; p.y = getInt(f) + readPicOffset.y; return(p); } int getInt(f) FILE *f; { register int i = 0; int negNum = 0; skipWhiteSpace(f); if( c == '-' ) { negNum = 1; getChar(f); } while( c>='0' && c<='9' ) { i = 10 * i + c - '0'; getChar(f); } if( negNum ) { i = -i; } return( i ); } getChar(f) FILE *f; { c = getc(f); } skipWhiteSpace(f) FILE *f; { while( c==' ' || c=='\t' ) getChar(f); } char tempStrGetText[MAXTEXT]; char * getText(f,term) FILE *f; register char term; { register char *ss, *t, *tt; register int i; for (i=0; c != term; getChar(f)) { if (i < MAXTEXT) { tempStrGetText[i++]=c; } } tempStrGetText[i]=0; if ((t = (char *) getSpace(strlen(tempStrGetText)+1))==NULL) { return( 0 ); } for (ss = tempStrGetText, tt = t; *tt++ = *ss++;) { } getChar(f); return(t); } flushLine(f) FILE *f; { while (c != '\n') { getChar(f); } getChar(f); } extractFontandPointSize( s, font_ptr, ps_ptr ) register char * s; short * font_ptr; short * ps_ptr; { register short ps; register int f, i, j, k, len; char c1, c2; char *p1, *p2; char buf[20]; if (!strncmp(s,"\\v'",3)) { /* get rid of vertical motions */ p1 = strchr(s,'\'') + 1; p1 = strchr(p1,'\''); p2 = p1 + 1; p1 = strrchr(s, '\''); *p1 = 0; p1 = strrchr(s, '\\'); *p1 = '\0'; for (p1=s; *p2 != '\0'; p1++,p2++) *p1 = *p2; *p1 = '\0'; } len = strlen(s); if ((strcmp(&s[len-6],"\\f1\\s0") && s[0]=='\\' && s[1]=='f') || (strcmp(&s[len-6],"\\fP\\s0") && s[0]=='\\' && s[1]=='f')) { strncpy(buf,&s[len-6],6); if( s[2] == '(' ) { /* 2 character font name */ c1 = s[3]; c2 = s[4]; i = 7; } else { /* 1 character font name */ c1 = s[2]; c2 = ' '; i = 5; } switch(c1) { case '1': case 'R': { f = ROMAN; break; } case '2': case 'I': { f = ITALIC; break; } case '3': case 'B': { f = BOLD; break; } case 'C': { f = CONSTANTWIDTH; break; } case 'H': { switch(c2) { case 'B': f = HB; break; case 'I': f = HI; break; default: f = HELVETICA; break; } break; } case 'P': { switch(c2) { case 'B': f = PB; break; case 'I': f = PI; break; default: f = PALATINO; break; } break; } case 'E': { switch(c2) { case 'B': f = EB; break; case 'I': f = EI; break; default: f = EXPANDED; break; } break; } default: { f = ROMAN; break; } } /* Handle one or two digit point size */ ps = s[i++] - '0'; if ((ps <= 3) && (isdigit(s[i]))) ps = ps*10 + s[i++] - '0'; strncpy(&buf[6],s,i); buf[6+i] = '\0'; k = strlen(buf); if (s[i] == '\\' && s[i+1] == '&') { i += 2; /* Skip over \& */ } /* Move in text string */ for (j=0; i&2 exit 1 fi # See if we should use X XCIP_OBJ=${TOOLS}/lib/x/$CIP if [ "$USEX" = "" -a -x "$XCIP_OBJ" ] then case $TERM in xterm|sun-cmd|x11) USEX="YES" break ;; *) if [ "$DISPLAY" != "" ] then USEX="YES" fi ;; esac fi if [ "$USEX" = "YES" ] then if [ "$VERSION" != "" ] then # Printout versions of cip and jpic. $XCIP_OBJ -V echo "" | $JPIC -V else # Invoke X-window cip: eval $XCIP_OBJ $PARMS fi exit 0 fi # # Invoke dmd portion # exec ${TOOLS}/lib/dmdtools/dmdtool $CIP $VERSION xcip/logo.pic0000644000175300001440000000574211513632543012014 0ustar meusers.nf .PS scale=100 box invis ht 808 wid 754 with .sw at 0,0 line from 500,442 to 514,410 line from 388,690 to 496,440 line from 462,618 to 466,608 line from 382,752 to 394,752 line from 466,610 to 462,602 line from 284,440 to 388,690 line from 462,602 to 446,594 line from 512,422 to 514,410 line from 394,724 to 392,722 line from 392,722 to 392,718 line from 452,618 to 462,618 line from 282,442 to 274,422 line from 394,752 to 394,724 line from 432,586 to 414,578 line from 384,750 to 384,726 line from 440,612 to 452,618 line from 384,722 to 384,718 line from 384,718 to 392,718 line from 364,578 to 346,592 line from 408,596 to 426,604 line from 382,752 to 382,724 line from 414,578 to 364,578 line from 382,724 to 394,724 line from 384,718 to 270,446 line from 212,234 to 230,248 line from 76,502 to 76,508 line from 14,576 to 24,560 line from 222,266 to 244,214 line from 38,510 to 204,252 line from 74,496 to 76,502 line from 0,566 to 14,576 line from 246,204 to 252,194 line from 6,548 to 198,248 line from 48,516 to 214,260 line from 38,550 to 46,540 line from 44,554 to 62,536 line from 22,520 to 42,540 line from 236,208 to 244,214 line from 204,242 to 226,258 line from 244,214 to 248,206 line from 0,566 to 10,550 line from 12,550 to 28,524 line from 20,558 to 36,534 line from 28,564 to 222,266 line from 84,490 to 74,492 line from 38,550 to 44,554 line from 62,538 to 64,530 line from 62,536 to 86,490 line from 52,546 to 62,538 line from 32,506 to 54,522 line from 224,222 to 236,230 line from 218,228 to 234,240 line from 198,248 to 236,208 line from 236,208 to 244,202 line from 244,202 to 250,206 line from 198,248 to 222,266 line from 6,548 to 28,564 "\fB\s12\&CIP LOGO\f1\s0" at 392,796 "\fR\s12\&(Use line segments only.)\f1\s0" at 396,768 line from 744,104 to 744,0 line from 216,104 to 216,80 line from 656,104 to 656,80 line from 480,104 to 480,80 line from 304,104 to 304,80 line from 568,104 to 568,80 line from 128,104 to 128,80 line from 40,104 to 40,0 line from 392,104 to 392,80 line from 40,104 to 744,104 line from 744,0 to 40,0 line from 532,230 to 540,226 line from 554,264 to 562,260 line from 584,230 to 710,230 line from 598,338 to 608,332 line from 660,440 to 670,434 line from 700,502 to 710,496 line from 638,404 to 648,398 line from 504,188 to 754,592 line from 710,434 to 710,230 line from 718,534 to 728,528 line from 618,370 to 626,366 line from 754,188 to 504,188 line from 576,302 to 586,296 line from 680,470 to 690,464 line from 754,592 to 754,188 line from 710,434 to 584,230 line from 276,426 to 264,410 line from 274,444 to 266,426 line from 266,426 to 264,410 line from 272,446 to 286,440 line from 496,440 to 510,446 line from 390,750 to 390,726 line from 354,606 to 368,596 line from 392,718 to 510,446 line from 368,596 to 408,596 line from 504,442 to 512,422 line from 382,724 to 384,722 .PE .fi xcip/cip.c0000644000175300001440000010003111513632542011260 0ustar meusers#include "cip.h" #include "version.h" #ifndef X11 #include #ifdef DMD630 #include #endif #ifdef DMD5620 #define jinit #define dellayer #define newlayer #define mpxnewwind #include #endif #endif /* X11 */ #ifdef X11 # include "menu.h" #else /* X11 */ # ifdef DMD630 # include # endif # ifdef DMD5620 # include "tmenuhit.h" # include # endif #endif /* X11 */ #ifdef X11 extern NMenu alignMenu; extern NMenu spacingMenu; extern NMenu justMenu; extern NMenu psMenu; #else /* X11 */ extern Tmenu alignMenu; extern Tmenu spacingMenu; extern Tmenu justMenu; extern Tmenu psMenu; #endif /* X11 */ char *Pgm_name; char *Jpic_pgm; #define Xbut1 ((Xbut+(Xmax-Xbut)/6)+4) #define Xbut2 (((Xmax+Xbut)>>1)-4) #define Xbut3 ((Xmax-(Xmax-Xbut)/6)-8) #define Ybut123 (Ybut+((ButSize*3)>>2)) #define _GETENV 9 #define BUTDEPTH 4 /* Bit depth for 3-D button. */ Point jchar(); extern Point PointCurr; #ifdef DMDTERM short Xmin; /* Left edge of frame. */ short Ymin; /* Top edge of frame. */ #endif #ifdef X11 Rectangle clip_rect; /* clipping rectangle for drawing */ #endif /* X11 */ char * MessagePnt; char MessageBuf[1024] = ""; int StartUp; Point drawOffset; /* Offset into drawing frame. */ Point scrollOffset; /* Offset into drawing frame from scrolling. */ int videoState = WHITEfield; Rectangle brushes[NUMBR+2]; int currentBrush = {-1}; int copyFlag = 0; int thingSelected = 0; int editDepth = 0; int buttonState = 0; int anyChgs = 0; short fontBells = 1; fontBlk *fonts = {(fontBlk *)NULL}; fontBlk *defFont; int textOutName = INITtextOutName; int left_hand; int gridState = GRIDoff; #ifdef FINEALIGN /* * If the currGridsize variable is < 0, then the grid value is set * to follow the alignment value. */ short currGridsize = 0; #endif short currAlignment = 8; short currPS = 10; short currFont = ROMAN; short currJust = CENTER; short currLineType = SOLID; short currBoxType = SOLID; short currLineArrows = 0; short currSplineArrows = 0; short currSpacing = 0; struct thing * firstThing = TNULL ; char *but1text[numButtonStates] = { "select", "", "select", "select", "", "", "abort", "select", "select", "no", "center", "OK", "select", "abort" }; char *but2text[numButtonStates] = { "move all", "", "draw", "edit", "draw", "", "draw box", "copy", "move", "no", "move box", "OK", "draw", "abort" }; char *but3text[numButtonStates] = { "main menu", "menu", "", "menu", "end spline", "", "", "menu", "menu", "yes", "", "OK", "glbl menu", "do" }; extern insertFont (); extern long spaceLeft(); #ifdef X11 extern Cursor hourglass; extern Cursor textCursor; #else /* X11 */ extern Texture16 hourglass; extern Texture16 textCursor; #endif /* X11 */ short noSpace; /* Indicates out of initial amount of memory */ char *envfont; char *strcat(); #ifdef X11 #define HEIGHT 10.5 #define WIDTH 8.5 #define MM_INCH 25.4 #define MINBORDER 20 jerqsizehints() { double pix_inch; int width, height; #if CHOOSESIZEBYINCHES pix_inch = (XDisplayHeight(dpy, 0) * MM_INCH)/XDisplayHeightMM(dpy, 0); width = pix_inch * WIDTH; height = pix_inch * HEIGHT; #else width = DefaultWidth; height = DefaultHeight; #endif if (width > (XDisplayWidth(dpy, 0) - MINBORDER)) width = XDisplayWidth(dpy, 0) - MINBORDER; if (height > XDisplayHeight(dpy, 0) - MINBORDER) height = XDisplayHeight(dpy, 0) - MINBORDER; setsizehints (width, height, 1); } typedef int (*Ifunc)(); Ifunc SaveHandler; int handler(disp, err) Display *disp; XErrorEvent *err; { fprintf(stderr,"In error handler\n"); (*SaveHandler)(disp, err); return(0); } #endif X11 main(argc,argv) int argc; char * argv[]; { struct thing * currentThing = TNULL; Pgm_name = &argv[0][strlen(argv[0])]; while(--Pgm_name > &argv[0][0]) { if (*Pgm_name == '/') { Pgm_name++; break; } } #ifdef DMD630 /* Save xcip in cache always. */ cache( Pgm_name, A_NO_SHOW ); #endif if (Pgm_name[strlen(Pgm_name)-2] == '.') /* cut off ".m" */ Pgm_name[strlen(Pgm_name)-2] = '\0'; if (Pgm_name[0] == 'x') Jpic_pgm = "xjpic"; else Jpic_pgm = "jpic"; #ifdef X11 if ( argc > 1 && argv[1][0]=='-' && argv[1][1]=='V' ) { printf( "%s version %s\n", Pgm_name, PGM_VERSION ); exit(0); } request( KBD | MOUSE ); initdisplay(argc, argv); /* initialize Kapilow's X11 emulator package */ initGraphics(); /* initialize cursors, textures & bitmaps. */ #else /* X11 */ #ifdef DMD5620 jinit(); #endif request( KBD | MOUSE | RCV | SEND ); /* Get the font directory from param list. */ envfont = argv[1]; P->state |= RESHAPED; /* Indicate frames not drawn yet. */ #endif /* X11 */ noSpace = 0; currentBrush = -1; buttonState = INITbuttons; thingSelected = 0; copyFlag = 0; StartUp = 1; /* The values to initialize prevhit with depends on what * which menu index xcip thinks is the default value for * the selection made from that menu. The prevhit numbers have * to be consistent with the menu indexes (from cip.h or * menus.c) into the menu definitions (in menus.c) that * correspond to the initial values of these variables * (defined here, in cip.c): * for alignMenu, see currAlignment * for psMenu, see currPS * for justMenu, see currJust * for spacingMenu, see currSpacing */ #ifdef FINEALIGN alignMenu.prevhit = 7; alignMenu.prevtop = 0; #else alignMenu.prevhit = 1; alignMenu.prevtop = 0; #endif /* FINEALIGN */ spacingMenu.prevhit = 4; spacingMenu.prevtop = 0; justMenu.prevhit = 1; justMenu.prevtop = 0; psMenu.prevhit = 8; psMenu.prevtop = 0; initFontList (); for (;;) { currentThing = doMouseButtons( currentThing, Pt(0,0) ); #ifdef X11 /* for some mysterous reason, must do nap here instead of wait(mouse) in doMouseButtons() for correct behavior. */ /* nap(2); */ #endif } } #ifdef DMDTERM Rectangle origRect = {8,8,200,100}; /* Holds original layer size, initialize to upper left. */ originalLayer() { #ifdef DMD630 reshape( origRect ); #endif #ifdef DMD5620 register struct Layer * l; register struct Proc * p = P; dellayer (p->layer); /* Delete the current layer */ p->state &= ~MOVED; p->state |= RESHAPED; l = newlayer(origRect); /* and create a new one. */ if (l == 0) { /* If not enough room, squish the */ /* layer to tell user no room. */ origRect.corner = add (origRect.origin, Pt (100, 50)); l = newlayer (origRect); if (l == 0) { exit (); /* Too bad!! */ } } /* Set up new process table. */ p->layer = l; p->rect = inset (origRect, 2); setdata (p); mpxnewwind (p, C_RESHAPE); #endif } resizeLayer() { Rectangle r; register struct Layer *l; register struct Proc *p =P; long temp; origRect = p->layer->rect; /* Position opened window based on position of close window. */ if( origRect.origin.x < 10 ) { Xmin = LEFTMOST; } else if( origRect.corner.x > (RIGHTX - 10) ) { Xmin = RIGHTMOST; } else { /* Take an average postion */ temp = (origRect.origin.x + origRect.corner.x) >> 1; Xmin = ( (temp * (RIGHTMOST-LEFTMOST) ) / RIGHTX ) + LEFTMOST; } if( origRect.origin.y < 10 ) { Ymin = TOPMOST; } else if( origRect.corner.y > (BOTTOMY - 10) ) { Ymin = BOTTOMMOST; } else { /* Take an average postion */ temp = (origRect.origin.y + origRect.corner.y) >> 1; Ymin = ( (temp * (BOTTOMMOST-TOPMOST) ) / BOTTOMY ) + TOPMOST; } r.origin.x = Xmin; r.origin.y = Ymin; r.corner.x = Xmax; r.corner.y = Ymax; r = inset(r,-BORDER); /* Make the window bigger */ drawOffset.x = Xmin; drawOffset.y = YPIC; brushInit(); /* Init outline of brush boxes. */ #ifdef DMD630 reshape( r ); #endif #ifdef DMD5620 dellayer (p->layer); /* Delete the current layer */ p->state &= ~MOVED; p->state |= RESHAPED; l = newlayer (r); /* and create a new one. */ if (l == 0) { /* If not enough room, squish the */ /* the layer to tell user no room. */ r.origin = origRect.origin; r.corner = add (origRect.origin, Pt (100,50)); l = newlayer (r); if (l == 0) { exit (); /* No more space at all */ } } /* Set up new process table. */ p->layer = l; p->rect = inset (r, 2); setdata (p); mpxnewwind (p, C_RESHAPE); #endif if (CORRECTSIZE) { redrawLayer(); } } #endif /* DMDTERM */ redrawLayer() { int t; char *tempStr; cursinhibit(); #ifdef X11 brushInit(); /* Init outline of brush boxes. */ #endif drawFrame(); /* display drawing area and brushes */ #ifdef X11 drawOffset.x = Xmin; drawOffset.y = YPIC; clip_rect = Rect(brushes[PIC].origin.x-2*LW, brushes[PIC].origin.y-44, brushes[PIC].corner.x-2*LW, brushes[PIC].corner.y-43); #endif /* X11 */ doRedraw(); if (videoState == BLACKfield) { #ifdef X11 rectf(&display, Drect, F_XOR); #else /* X11 */ rectf(&display, Jrect, F_XOR); #endif /* X11 */ } if (editDepth) { drawEDbutton (editDepth); } if (currentBrush > -1) { t = currentBrush; currentBrush = -1; changeBrush(t); } cursallow(); P->state &= ~RESHAPED; if (StartUp) { putVersion(); StartUp = 0; } else { PointCurr.x = MSGXMIN; PointCurr.y = MSGYMIN; /* Redisplay the message area. */ MessagePnt = MessageBuf; tempStr = alloc(strlen(MessageBuf)+1); strcpy(tempStr,MessageBuf); moreMessage(tempStr); free(tempStr); } } brushInit() { register int x; register int i; x=Xmin; for (i=0; i> 1; /* Divide by 2. */ Point m; Point p[6]; drawButtonPicture( brushes[i] ); r = (YBR*3)>>3; m = div( add( brushes[i].origin, sub(brushes[i].corner,Pt(hb,hb)) ), 2); switch (i) { case CIRCLE: { circle(&display, m,r,F_XOR); break; } case BOX: { box(Rect(m.x-r,m.y-r,m.x+r,m.y+r)); break; } case ELLIPSE: { Ellipse(m,(r<<1),DXBR-(8*LW)); break; } case LINE: { segment(&display, Pt(m.x-r,m.y),Pt(m.x+r,m.y),F_XOR); break; } case ARC: { arc(&display, Pt(m.x,m.y+r),Pt(m.x+r,m.y),Pt(m.x-r,m.y),F_XOR); break; } case SPLINE: { p[1] = sub(m,Pt(r,r)); p[2] = add(m,Pt(r>>1,-r)); p[3] = sub(m,Pt(r>>1,-r)); p[4] = add(m,Pt(r,r)); spline(Pt(0,0),p,5); break; } case TEXT: { centeredText(sub(m,Pt(0,10)),"Text"); break; } } } Rectangle * Select(t, m, offset) struct thing *t; Point m; Point offset; { register int i; for( i=0; ((i<=ED+1)&&(!ptinrect(m,brushes[i]))); i++ ) ; if( i == PIC ) { /* Selected inside picture drawing area. */ return(&brushes[PIC]); /* temporary */ } else if( i == ED ) { /* Selected EDIT button. */ if( editDepth > 0 ) { drawEDbutton(editDepth); /* Undraw edit button */ if( (--editDepth)!=0 ) { drawEDbutton(editDepth); } } changeBrush(-1); if (thingSelected) { drawSelectionLines (t, offset); thingSelected = 0; } changeButtons(INITbuttons); return( (Rectangle *) NULL); } else if( i < PIC ) { /* Selected one of the brush types at top. */ if( currentBrush != i ) { /* Change to selected brush if not already selected, otherwise, de-select it (by falling to following code). */ changeBrush(i); return(&brushes[i]); } } /* Selected outside everything - make no selection. */ changeBrush(-1); changeButtons(INITbuttons); return( (Rectangle *) NULL); } Buttons() { register int i; #ifdef DMDTERM /* Determine if mouse if left of right handed. */ # ifdef DMD630 left_hand = setupval( S_PREF, 6 ); # endif # ifdef DMD5620 left_hand = VALMOUSE; # endif #endif for (i=1; i <= LW; i++) box( Rect(Xbut+i-1,Ybut+i-1,Xmax-i,Ymax-i) ); centeredText(Pt(Xbut2,Ytext), "Mouse Buttons Usage"); writeButtonLabels(buttonState); } labeledButton(p,s) Point p; register char *s; { register int w; register int bh; bh = butHt; #ifdef X11 w = (strwidth(&defont,s)+8)>>1; #else /* X11 */ w = (jstrwidth(s)+8)>>1; #endif /* X11 */ if (w<=4) { w=bh; } centeredText(add(p,Pt(0,(bh>>1)-10)),s); box(Rpt(sub(p,Pt(w,bh)),add(p,Pt(w,bh)))); } Point jString(s) register char *s; { PointCurr=string(&defont,s,&display,PointCurr,F_XOR); return PointCurr; } Point jchar(c) register char c; { char s[2]; s[0]=c; s[1] = '\0'; return(jString(s)); } drawSelectionLines(t,p) register struct thing *t; Point p; { Point p1; if (t!=TNULL) { if (t->type==SPLINE) { drawZigZag(p,t->otherValues.spline.plist, t->otherValues.spline.used); } else if (t->type==ARC) { p1 = add(t->origin,p); xsegment(p1,add(p,t->otherValues.arc.start)); xsegment(p1,add(p,t->otherValues.arc.end)); } } } #ifdef DMDTERM Bitmap gridBm = { (Word *)&grid, 1, 0, 0, 16, 16, 0 }; #endif #ifdef FINEALIGN #ifdef DMDTERM Bitmap fineGridBm = { (Word *)&fineGrid, 1, 0, 0, 16, 16, 0 }; #endif /* DMDTERM */ #endif /* FINEALIGN */ drawGrid() { #ifdef X11 #ifdef FINEALIGN register int xpos; register int ypos; int bmapwid; int tmpGridsize; Rectangle insetRect; Rectangle inLayer, in_fineGridAnyBm; Bitmap * fineGridAnyBmP; unsigned short x_fineGrid_bits[16]; /* * insetRect is a rectangle that defines the coordinates * of the drawing area in &display (was P->layer.) */ insetRect = inset(Rect(Xmin,YPIC,Xmax,YBOT), LW ); /* cursinhibit(); */ tmpGridsize = currGridsize < 0 ? -currGridsize : currGridsize; switch( tmpGridsize ) { case 1: case 2: case 3: break; /* case 1: */ /* For a tmpGridsize of 1, every single pixel on * the display gets turned on, so replacing the * normal algorithm with a call to rectf makes for * a very fast operation. */ /* rectf( &display, insetRect, F_XOR ); * break; */ /* case 2: */ case 4: case 8: case 16: /* For grid sizes which are a power of two, * a texture can be generated and painted on the * screen. */ /* * Pixels are painted inside the texture to line up with * the point Pt(Xmin,YPIC). * Set the bits of x_fineGrid_bits that must be on. */ /* fineGrid = T_white; */ for( ypos = 0 ; ypos < 16; ypos++ ) { x_fineGrid_bits[ypos] = 0; } for( xpos = (Xmin & 0xf) % tmpGridsize; xpos < 16; xpos += tmpGridsize ) { for( ypos = (YPIC & 0xf) % tmpGridsize; ypos < 16; ypos += tmpGridsize ) /* point(&fineGridBm, Pt(xpos,ypos), F_STORE); */ { /* set bit xpos in row ypos. */ x_fineGrid_bits[ypos] |= 0x8000 >> xpos; } } /* all bits set, initialize Texture from bits. */ fineGrid = ToTexture((short *)x_fineGrid_bits ); /* Then the texture is painted on the insetRect * inside the layer. */ /* texture16( P->layer, insetRect, &grid, F_XOR ); */ texture( &display, insetRect, &fineGrid, F_XOR ); break; /* case 3: */ case 5: case 6: case 7: case 9: case 10: case 11: case 12: case 13: case 14: case 15: /* * For grid sizes which are not a power of two, * a bitmap is generated which is 16*gridsize pixels * wide. Pixels for the appropiate grid size are painted * onto the bitmap to align with Pt(Xmin,YPIC). * * The this bitmap is bitblt'ed all over the screen, * one section at a time. */ { /* Allocate Bitmap. */ bmapwid = 16*tmpGridsize; fineGridAnyBmP = balloc(Rect(0, 0, bmapwid, bmapwid)); if( fineGridAnyBmP == (Bitmap *)0 ) { newMessage("Not enough memory for fast grid."); goto slow_grid; } /* Erase Bitmap. */ rectf( fineGridAnyBmP, fineGridAnyBmP->rect, F_CLR ); /* Fill Bitmap with correct pattern. */ initpoints( fineGridAnyBmP, F_STORE ); for( xpos = (Xmin & 0xf) % tmpGridsize; xpos < bmapwid; xpos += tmpGridsize ) { for( ypos = (YPIC & 0xf) % tmpGridsize; ypos < bmapwid; ypos += tmpGridsize ) { /* point( fineGridAnyBmP, Pt(xpos,ypos), F_STORE); */ points( Pt(xpos,ypos) ); } } endpoints(); /* Copy Bitmap to screen. */ for( ypos = YPIC&~0xf; ypos < YBOT; ypos+=bmapwid ) { for( xpos = Xmin&~0xf; xpos < Xmax; xpos+=bmapwid ) { /* Clip the rectangle at (xpos,ypos) * to within the drawing area. */ inLayer = Rect( xpos, ypos, xpos + bmapwid, ypos + bmapwid); in_fineGridAnyBm = inLayer; if( rectclip(&inLayer,insetRect) != 1 ) continue; /* Find the coordinates in fineGridAnyBmP. */ in_fineGridAnyBm.origin.x = inLayer.origin.x - in_fineGridAnyBm.origin.x; in_fineGridAnyBm.origin.y = inLayer.origin.y - in_fineGridAnyBm.origin.y; in_fineGridAnyBm.corner.x = bmapwid + inLayer.corner.x - in_fineGridAnyBm.corner.x; in_fineGridAnyBm.corner.y = bmapwid + inLayer.corner.y - in_fineGridAnyBm.corner.y; /* bitblt(fineGridAnyBmP, in_fineGridAnyBm, P->layer, inLayer.origin, F_XOR ); */ bitblt(fineGridAnyBmP, in_fineGridAnyBm, &display, inLayer.origin, F_XOR ); } wait(CPU); } bfree(fineGridAnyBmP); } break; /* * This algorithm is slower than the bitmap algorithm and * is only used when the other one can not be used due to * a shortage of memory. */ slow_grid: { register int y, gs, x, zy, zx; gs = tmpGridsize; zx = insetRect.origin.x; for( x = Xmin; x < zx; x += gs ) ; zx = insetRect.corner.x; for( ; x < zx; x += gs ) { zy = insetRect.origin.y; for( y = YPIC; y < zy; y += gs ) ; zy = insetRect.corner.y; for( ; y < zy; y += gs ) { /* point( P->layer, Pt(x, y), F_XOR ); */ point( &display, Pt(x, y), F_XOR ); } wait(CPU); } } break; default: break; } /* cursallow(); */ /* X11 */ #else /* FINEALIGN */ /* X11 */ if( currAlignment > 2 ) { if( currAlignment == 8 ) { texture( &display, inset(Rect(Xmin,YPIC,Xmax,YBOT), LW), &grid8, F_XOR); } else { texture( &display, inset(Rect(Xmin,YPIC,Xmax,YBOT), LW), &grid, F_XOR ); } } return; #endif /* FILEALIGN */ /* X11 */ #else /* not X11 */ #ifdef FINEALIGN register int xpos; register int ypos; int bmapwid; int tmpGridsize; Rectangle insetRect; Rectangle inLayer, in_fineGridAnyBm; Bitmap * fineGridAnyBmP; #ifdef DMD5620 register int i; Texture16 grid16; #endif /* * insetRect is a rectangle that defines the coordinates * of the drawing area in P->layer. */ insetRect = inset(Rect(Xmin,YPIC,Xmax,YBOT), LW ); cursinhibit(); tmpGridsize = currGridsize < 0 ? -currGridsize : currGridsize; switch( tmpGridsize ) { case 1: case 2: case 3: break; /* case 1: */ /* For a tmpGridsize of 1, every single pixel on * the display gets turned on, so replacing the * normal algorithm with a call to rectf makes for * a very fast operation. */ /* rectf( P->layer, insetRect, F_XOR ); break; */ /* case 2: */ case 4: case 8: case 16: /* For grid sizes which are a power of two, * a texture can be generated and painted on the * screen. */ /* * Pixels are painted inside the texture to line up with * the point Pt(Xmin,YPIC). */ fineGrid = T_white; for( xpos = (Xmin & 0xf) % tmpGridsize; xpos < 16; xpos += tmpGridsize ) for( ypos = (YPIC & 0xf) % tmpGridsize; ypos < 16; ypos += tmpGridsize ) point(&fineGridBm, Pt(xpos,ypos), F_STORE); /* Then the texture is painted on the insetRect * inside the layer. */ #ifdef DMD630 texture16( P->layer, insetRect, &fineGrid, F_XOR ); #endif #ifdef DMD5620 for( i=0; i<16; i++ ) { grid16.bits[i] = (short) (fineGrid.bits[i] >> 16); } texture16( P->layer, insetRect, &grid16, F_XOR ); #endif break; /* case 3: */ case 5: case 6: case 7: case 9: case 10: case 11: case 12: case 13: case 14: case 15: /* * For grid sizes which are not a power of two, * a bitmap is generated which is 16*gridsize pixels * wide. Pixels for the appropiate grid size are painted * onto the bitmap to align with Pt(Xmin,YPIC). * * The this bitmap is bitblt'ed all over the screen, * one section at a time. */ { /* Allocate Bitmap. */ bmapwid = 16*tmpGridsize; fineGridAnyBmP = balloc(Rect(0, 0, bmapwid, bmapwid)); if( fineGridAnyBmP == (Bitmap *)0 ) { newMessage("Not enough memory for fast grid."); goto slow_grid; } /* Erase Bitmap. */ rectf( fineGridAnyBmP, fineGridAnyBmP->rect, F_CLR ); /* Fill Bitmap with correct pattern. */ for( xpos = (Xmin & 0xf) % tmpGridsize; xpos < bmapwid; xpos += tmpGridsize ) for( ypos = (YPIC & 0xf) % tmpGridsize; ypos < bmapwid; ypos += tmpGridsize ) point( fineGridAnyBmP, Pt(xpos,ypos), F_STORE); /* Copy Bitmap to screen. */ for( ypos = YPIC&~0xf; ypos < YBOT; ypos+=bmapwid ) { for( xpos = Xmin&~0xf; xpos < Xmax; xpos+=bmapwid ) { /* Clip the rectangle at (xpos,ypos) * to within the drawing area. */ inLayer = Rect( xpos, ypos, xpos + bmapwid, ypos + bmapwid); in_fineGridAnyBm = inLayer; if( rectclip(&inLayer,insetRect) != 1 ) continue; /* Find the coordinates in fineGridAnyBmP. */ in_fineGridAnyBm.origin.x = inLayer.origin.x - in_fineGridAnyBm.origin.x; in_fineGridAnyBm.origin.y = inLayer.origin.y - in_fineGridAnyBm.origin.y; in_fineGridAnyBm.corner.x = bmapwid + inLayer.corner.x - in_fineGridAnyBm.corner.x; in_fineGridAnyBm.corner.y = bmapwid + inLayer.corner.y - in_fineGridAnyBm.corner.y; bitblt(fineGridAnyBmP, in_fineGridAnyBm, P->layer, inLayer.origin, F_XOR ); } wait(CPU); } bfree(fineGridAnyBmP); } break; /* * This algorithm is slower than the bitmap algorithm and * is only used when the other one can not be used due to * a shortage of memory. */ slow_grid: { register int y, gs, x, zy, zx; gs = tmpGridsize; zx = insetRect.origin.x; for( x = Xmin; x < zx; x += gs ) ; zx = insetRect.corner.x; for( ; x < zx; x+ = gs ) { zy = insetRect.origin.y; for( y = YPIC; y < zy; y += gs ) ; zy = insetRect.corner.y; for( ; y < zy; y += gs ) { point( P->layer, Pt(x, y), F_XOR ); } wait(CPU); } } break; default: break; } cursallow(); /* not X11 */ #else /* FINEALIGN */ /* not X11 */ int xpos; int ypos; int xpos8; int ypos8; #ifdef DMD5620 register int i; Texture16 grid16; #endif if( currAlignment > 2 ) { grid = T_white; xpos = (Xmin) & 15; /* mod 16 */ ypos = (YPIC) & 15; cursinhibit(); point( &gridBm, Pt(xpos,ypos), F_STORE ); if( currAlignment == 8 ) { xpos8 = (Xmin+8) & 15; /* mod 16 */ ypos8 = (YPIC+8) & 15; point( &gridBm, Pt(xpos,ypos8), F_STORE ); point( &gridBm, Pt(xpos8,ypos), F_STORE ); point( &gridBm, Pt(xpos8,ypos8), F_STORE ); } #ifdef DMD630 texture16( P->layer, inset(Rect(Xmin,YPIC,Xmax,YBOT), LW ), &grid, F_XOR ); #endif #ifdef DMD5620 for( i=0; i<16; i++ ) { grid16.bits[i] = (short) (grid.bits[i] >> 16); } texture16( P->layer, inset(Rect(Xmin,YPIC,Xmax,YBOT), LW ), &grid16, F_XOR ); #endif cursallow(); } /* not X11 */ #endif /* FILEALIGN */ #endif /* X11 */ } drawEDbutton(depth) int depth; { char s[5]; Point p; register int dy; Rectangle tmp; drawButtonPicture( brushes[ED] ); tmp = Rpt( add( brushes[ED].origin, Pt(LW+1,LW+1) ), sub( brushes[ED].corner, Pt(LW+BUTDEPTH-1,LW+BUTDEPTH-1)) ); flash(&tmp, Pt(0,0)); p.x = (brushes[ED].corner.x + brushes[ED].origin.x)>>1; p.y = brushes[ED].origin.y + 5; centeredText(p,"edit depth"); p.y += 18; sprintf(s,"%d",depth); centeredText(p,s); p.y += 20; centeredText(p,"(button)"); } drawButtonPicture(r) Rectangle r; { /* Remove triangular corners. */ drawIcon( Pt(r.origin.x+8, r.corner.y-BUTDEPTH+8), &lowerTriangle ); drawIcon( Pt(r.corner.x-BUTDEPTH+8, r.origin.y+8), &upperTriangle ); rectf( &display, r, F_XOR ); rectf( &display, Rpt( add( r.origin, Pt(LW,LW) ), sub( r.corner, Pt(LW+BUTDEPTH,LW+BUTDEPTH))), F_XOR ); /* Draw diagonal line for corner. */ segment( &display, sub(r.corner,Pt(BUTDEPTH,BUTDEPTH)), r.corner, F_XOR ); /* Draw two lines to show edges. */ segment( &display, Pt(r.origin.x+1 , r.corner.y-BUTDEPTH ), Pt(r.corner.x-BUTDEPTH , r.corner.y-BUTDEPTH ), F_XOR ); segment( &display, Pt(r.corner.x-BUTDEPTH , r.origin.y+1 ), Pt(r.corner.x-BUTDEPTH , r.corner.y-BUTDEPTH ), F_XOR ); } changeBrush(new) register int new; { Rectangle tmp; if (currentBrush>-1) { tmp = Rpt( add( brushes[currentBrush].origin, Pt(LW+1,LW+1) ), sub( brushes[currentBrush].corner, Pt(LW+BUTDEPTH-1,LW+BUTDEPTH-1) ) ) , flash(&tmp, Pt(0,0)); } if (new>-1) { tmp = Rpt( add( brushes[new].origin, Pt(LW+1,LW+1) ), sub( brushes[new].corner, Pt(LW+BUTDEPTH-1,LW+BUTDEPTH-1) ) ) , flash(&tmp, Pt(0,0)); } currentBrush = new; } /* Writes in "Mouse Buttons" sub-window the button operation description. */ changeButtons(new) register int new; { if (buttonState != new) { writeButtonLabels(buttonState); writeButtonLabels(new); buttonState = new; } } writeButtonLabels(i) register int i; { if( left_hand ) { labeledButton(Pt(Xbut3,Ybut123),but1text[i]); labeledButton(Pt(Xbut2,Ybut123),but2text[i]); labeledButton(Pt(Xbut1,Ybut123),but3text[i]); } else { labeledButton(Pt(Xbut1,Ybut123),but1text[i]); labeledButton(Pt(Xbut2,Ybut123),but2text[i]); labeledButton(Pt(Xbut3,Ybut123),but3text[i]); } } initFontList () { if ((fonts=(fontBlk *)getSpace(sizeof(fontBlk))) == (fontBlk *) NULL) { newMessage ("No memory in terminal"); sleep (100); exit (0); } fonts->f = &defont; fonts->ps = 10; fonts->num = DEFONT; fonts->useCount = 0; fonts->next = fonts; fonts->last = fonts; } putVersion() { /* note: xcip -V finds these strings from the object file */ /* the extra blank at the end delimits it from following strings */ newMessage( Pgm_name ); moreMessage( " version " ); moreMessage( PGM_VERSION ); moreMessage( " " ); drawCopyright( Pt(Xtext+180,Ytext-7) ); } sameSizeRect( rectA, rectB ) Rectangle rectA; Rectangle rectB; { return eqpt( sub(rectA.corner,rectA.origin) , sub(rectB.corner,rectB.origin) ); } /* Go to next line in message area, scroll message lines up if at bottom. */ static void nextLine() { char *p,*p1; extern char * strchr(); PointCurr.x = MSGXMIN; PointCurr.y += NS; /* Newline Size. Height of a character. */ if( PointCurr.y > (MSGYMAX-NS) ) { /* Scroll up message lines. */ bitblt( &display, Rect(MSGXMIN, MSGYMIN+NS, MSGXMAX, MSGYMAX), &display, Pt(MSGXMIN, MSGYMIN), F_STORE ); clearRegion( Rect( MSGXMIN, MSGYMAX-NS, MSGXMAX, MSGYMAX ) ); PointCurr.y -= NS; *MessagePnt = '\0'; p = strchr(MessageBuf, '\n'); if (p == 0) p = &MessageBuf[strlen(MessageBuf)]; if ((int)(p - MessageBuf) > (MSGXMAX-CW)) p = &MessageBuf[(MSGXMAX-CW)]; p1 = alloc(strlen(p)+1); strcpy(p1, p); strcpy(MessageBuf, p1); free(p1); MessagePnt = &MessageBuf[strlen(MessageBuf)]; } } /* This routine clears the message area and sets a pointer to the beginning of it. */ void initMessage () { PointCurr.x = MSGXMIN; PointCurr.y = MSGYMIN; clearRegion( Rect( MSGXMIN, MSGYMIN, MSGXMAX, MSGYMAX ) ); MessageBuf[0] = '\0'; MessagePnt = MessageBuf; } /* This routine displays a string at 'PointCurr'. */ void moreMessage (str) char * str; { while( *str != '\0' ) { if( (*str == '\n') || (*str == '\r') ) { nextLine(); *MessagePnt++ = '\n'; } else if( *str == '' ) { ringbell(); } else if( *str == ' ' ) { /* Ignore tabs. */ } else { if( PointCurr.x > (MSGXMAX-CW) ) nextLine(); jchar( *str ); *MessagePnt++ = *str; } str++; } *MessagePnt = '\0'; } /* This routine displays a message at the bottom of the cip layer */ void newMessage (str) char *str; { initMessage (); moreMessage (str); } /* This routine displays given string in message box and then awaits * for user to edit it - terminated by return or mouse buttons. The * new string is returned in the first parameter. The function returns * which button was used and 4 for any other reason. */ getMessage (str) char *str; { register char c; register int i; Point startPoint; int r = 4; char *p; /* wait for release of all buttons */ for(;button123();nap(2)) ; startPoint = PointCurr; p = MessagePnt; moreMessage(str); i = strlen(str); cursswitch( &textCursor ); clearKeyboard(); do { wait( KBD | MOUSE ); if (P->state & RESHAPED) redrawLayer(); if( button1() ) { r = 1; break; } if( button2() ) { r = 2; break; } if( button3() ) { r = 3; break; } if (own() & KBD ) { c = kbdchar(); if( (c=='\033') || (c == '\r') ) break; if (i>0) { /* erase present string */ PointCurr = startPoint; MessagePnt = p; moreMessage(str); } #ifdef DMD5620 if (c >= 0x82 && c <= 0x89) { int j,k; j = c - 0x82; k = 0; while ((c = BRAM->pfkeys[j][k].byte) && (++k <= PFKEYSIZE)) { if (i >= MAXNAMESIZE) { ringbell (); str[i] = '\0'; break; } else { str[i++] = c; } } } else { #endif switch (c) { case '@': case 'U'-'@': { i=0; str[0] = '\0'; break; } case 'W'-'@': { i = backspaceOneWord(str,i); break; } case '\b': { str[(i>0)? --i : 0] = '\0'; break; } default: { if (i >= MAXNAMESIZE) { ringbell (); } else { str[i++] = c; str[i] = '\0'; } break; } } #ifdef DMD5620 } #endif PointCurr = startPoint; MessagePnt = p; moreMessage(str); } } while ( 1 ); /* Wait for all buttons to be released. */ for(;button123();nap(2)) ; cursSwitch (); return r; } void printSpace() { char S[40]; #ifdef DMDTERM # ifdef DMD630 sprintf( S, "space: bytes remaining: %ld\n", spaceLeft() ); # endif # ifdef DMD5620 sprintf( S, "space: bytes remaining: %d\n", spaceLeft() ); # endif newMessage( S ); #endif /* DMDTERM */ } #define CEOF 0xff void printPWD() { register FILE * fp; register int c; register int i; static char s[MAXNAMESIZE+1] = {'\0'}; moreMessage("pwd: "); /* Check if pwd has already been done. */ if( s[0] == '\0' ) { /* Go to host to do pwd */ fp = popen("pwd","r"); if( fp == (FILE *) NULL ) { moreMessage("failed\n"); return; } c = getc( fp ); i = 0; #ifdef DMD5620 while( (c >= '\040') && (c <= '\176') && (i < MAXNAMESIZE) ) #else while( (c != CHAR_EOF) && (i < MAXNAMESIZE) ) #endif { s[i++] = (char) c; c = getc( fp ); } s[i] = '\0'; pclose(fp); } moreMessage(s); moreMessage("\n"); } void printChgStatus() { /* Temporarily inhibit until implemented: if( anyChgs ) moreMessage("*** diagram has been changed since last store ***"); else moreMessage("no changes since last store"); */ } xcip/stand.defs0000644000175300001440000000650611513632544012333 0ustar meusers# Copyright (c) 1987 AT&T # All Rights Reserved # THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T # The copyright notice above does not evidence any # actual or intended publication of such source code. ### Standard Defines ### ######## # # Macro definitions # # MODEBIN is used by descendent makefiles to set the file mode # for executable products. # # MODELIB is used by descendent makefiles to set the file mode # for non-executable products. # # DMD630 is $DMD for 630 applications # DMD5620 is $DMD for 5620 applications # - these must be set on the command line for toolchest builds # # DMDSYS is the directory for layers include files and libraries # # DEFDMD is the default $DMD if $DMD is not set (if any) # # TCTERM is terminal to build for: 630 or dmd, or all for both # # EXTRACFLAGS is extra CFLAGS to be passed to all Unix program # compile and link commands, that is, $(CC) # # ######## MODEBIN=775 MODELIB=664 DMD630=unknown DMD5620=unknown DMDSYS=$(DMD) DEFDMD= TCTERM=all EXTRACFLAGS=-O # CFLAGS is often overridden in individual makefiles; when it is, # $(EXTRACFLAGS) should be part of the overriding. # makefiles that link host programs should always include $(CFLAGS) at # the END of the link command in case EXTRACFLAGS includes -l libraries. CFLAGS=$(EXTRACFLAGS) # -rZ0 is for TOOLCHEST man pages and -rZ1 is for EXPTOOLS man pages MANFL=-rZ0 # -DMD630 is defined by dmdcc for 630 MCFLAGS630=-O MCFLAGS5620=-O -DDMD5620 MCC=$(DMD)/bin/dmdcc MDIS630=bin/mc68dis MDIS5620=bin/m32dis MAR630=bin/mc68ar MAR5620=bin/m32ar MSTRIP630=bin/mc68strip MSTRIP5620=bin/m32strip MLORDER630=bin/mc68lorder MLORDER5620=bin/m32lorder TCLIB=$(TC630)/lib TCBIN=$(TC630)/bin TCSRC=$(TC630)/src TCMAN=$(TC630)/man # possible locations for hostagent library LIBWINPATHS= $(DMDSYS)/lib/libwindows.a $(DMDSYS)/lib/hostagent.o # default clean and clobber values CLEANHOST=$(OBJSHOST) CLEAN5620=$(OBJS5620) CLEAN630=$(OBJS630) CLOBBERHOST=$(PRODUCTSHOST) CLOBBER5620=$(PRODUCTS5620) CLOBBER630=$(PRODUCTS630) ######## # # In order for the macro definitions specified on the # command line to be passed to decendent makefiles # they must be included in the following generic macro definition. # # You can set EXTRAMACROS to pass extra macros definitions along, # for example: # EXTRAMACROS='TC630=$(TC630)' # will override the default path names for the install directory # (the default TC630 is relative path names pointing to one level # above this so they're different in each makefile; that's why TC630 # is not normally part of MACROS). # # ######## MACROS=MODEBIN=$(MODEBIN) MODELIB=$(MODELIB) TCTERM=$(TCTERM) \ DMD630=$(DMD630) DMD5620=$(DMD5620) DMDSYS=$(DMDSYS) DEFDMD=$(DEFDMD) \ MANFL=$(MANFL) EXTRACFLAGS="$(EXTRACFLAGS)" $(EXTRAMACROS) # Need to specify TCTERM before and after $(MACROS) because some 'make's # take precedence left to right and some take right to left MACROS5620=TCTERM=dmd $(MACROS) TCTERM=dmd MCFLAGS="$(MCFLAGS5620)" \ DMD=$(DMD5620) MAR=$(DMD5620)/$(MAR5620) MDIS=$(DMD5620)/$(MDIS5620) \ MSTRIP=$(DMD5620)/$(MSTRIP5620) MLORDER=$(DMD5620)/$(MLORDER5620) MACROS630=TCTERM=630 $(MACROS) TCTERM=630 MCFLAGS="$(MCFLAGS630)" \ DMD=$(DMD630) MAR=$(DMD630)/$(MAR630) MDIS=$(DMD630)/$(MDIS630) \ MSTRIP=$(DMD630)/$(MSTRIP630) MLORDER=$(DMD630)/$(MLORDER630) ### Specific Defines ### xcip/HISTORY0000644000175300001440000004273011513632544011442 0ustar meusers WORK DONE ON XCIP Release 2.3: * xjpic: increased size of macros. * Correct movement of objects on reading and writing cycles. * Global setting of justification and style. * Make bounding boxes grow to fit grid points. * Ask for confirmation on getfile if something on screen. * Generalize fonts to allow constant width fonts. * Start object selection with macro just created. * Bug: prevent user from setting very large point size. Release 2.4: * Text printed a bit higher than displayed in xcip. Release 2.5: * Don't delete the text string right away if it becomes empty while editing. * Odd segment number splines not read in correctly. Release 3.1: * Available for Teletype 630 MTG terminal. * General undo operation. * Macros jump around when moved. * Print out type and attributes on the selected object. * Separate arrow menus for spline and lines, etc. * Ciprint: centers picture horizontally at top of the page. * Ciprint: support Xerox 9700 and Imagen I300. * Ciprint: support for both DWB 1 and DWB 2. * Secondary menus off to the right of the main menu using 630 tmenu function. * Put file operation copies old file if it exists to a backup file named: xcip.backup. * Get file operation can handle much larger pic files (uses new xjpic host program). * Takes advantage of the caching in the 630 terminal. * Takes advantage of the font caching in the 630 terminal. Fonts once downloaded are shared among all windows in the terminal. * Arcs can now be easily editted! * New PRINTING DIAGRAMS section in xcip manual page contains hints on how to print your diagrams in documents. * New information operation on main menu; prints out memory remaining in terminal and the UNIX directory from which xcip was down-loaded. * New logo displayed in closed window. * The standalone version of xcip is no longer available. Release 3.2: * Fixes problem preventing many "put file" operations (from 3.1). Release 3.3: * 630 crashes when opening and closing windows - P->layer->base saved too infrequently for draw routine clipping. Thanks to Jeff Schneiderman. * Writing to pic file of unused macros. Release 3.4: * Bounding box for arcs is too big - fixed by Rich Trommer. * Fixed exceptions still common on 630 - file pointer was being changed in doPut to point a local area buffer. This caused garbage collection problems when the file pointer was freed. Thanks to Jeff Schneiderman. * New -v command line option to print out version of xcip. * Uses /bin/cp instead cp in put_file operation file backup. Release 3.5: * Xcip shell uses JPATH to find DMD object. * Object selection is much faster. * Recognize TERM set to 630* or 5620* or dmd2.0*. * Reflecting macros on X-axis now works. * xjpic: can handle larger macros. * xjpic: can read into xcip extra wide diagrams. * xjpic: new -v version option * man page change: new sections on SETUP and COMPARISON WITH CIP. * does not create defunct UNIX processes. * ciprint accepts -T as well as -t. * ciprint checks for unset IDEST. * Use "who am i" to determine if in first window (as in sdled). * Test in xcip shell whether xjpic exists. * Creating of macros while editing a macro is now correct. Was an offset problem. * The pwd is correct if xcip is brought up in another directory. * Warn users about file name paths over 60 characters. * Fixed by making visible when mouse moves: When I am typing text and the invisible cursor wanders off the screen, it's not clear why hitting the buttons fails to end the insert. When I manage to move the invisible cursor back into the xcip layer and end the insert, the cursor isn't restored and stays invisible until I move it outside the layer and back again. - iextinct!dcn * Quiting xcip in a full window is no longer available. * On 630 terminal, xcip is always cached now (no -c option). Release 3.5a: * Fixed exception when a font can not be found and default font is used instead (found by John Kant). * Fixed bug in findBBpic() was not calculating the bounding box for text at bottom of diagram correctly resulting in an invis box in pic being to small. Release 3.5b: * Fixed exception of undo of macro or text separate operation (found by Jon Luers). * Fixed exception resulting from deleting objects in macro while editing it, leaving the macro edit mode, and still finding copies of the macro around which give an exception when touched (found by Len Kasday). Release 3.5c: * More portable detection whether xcip is being run in the system window or not (thanks to Danny Zerkel). * In certain cases arcs will display as complete circles in xcip. It turns out that a negative number is generated by xjpic which was not handled by getInt in readPic.c. See file fixed.bugs/arc.bug, from John Kruk. Release 4.0a: * Port to run on Sun servers under layers on DMD terminals. Release 4.0b: * Fixed undo infinite loop found in test version 3.5c by Alan Hastings. * Order of objects is not changed in successive get and put files. * Above enhancement fixed bug: creating a macro while editing a macro results in a recursive macro call in generated pic file. * Added subset of emacs commands when editing text objects. * Displays xjpic parsing errors in message window. * Added updates to tmenuhit for 5620 terminals. (Display->Physical, cursinhibit->Jcursinhibit, MAX_TMFIELDS from 9 to 8) * In generated text strings, fixed bug to restore font style to P (prefix) instead of 1. * Fixed xcip shell to use work under emacsterm by adding "-x" option to ttype call. * Fixed ciprint shell to work under DWB 3.1 (use dx9700 not ndx9700). Release 4.0c: * Note, a dead-end. See HISTORY file. Release 4.0d: * Fixed exception bug occuring during "put file" if first object is a macro and the macro is separated. Thanks to Mike Hartrey for reproducible scenario and David Wexelblat for partial fix. * Fixed spaceLeft() routine for 630/730 terminals to not hang in infinite loop. Release 4.1a: * David Wexelblat's X11 version of xcip. Distributed informally to some Sun 3 and 4 users. Release 4.1b: * Fixed minor problems in Wexelblat's version to work again on 630 and 5620. (Things were not #ifdef correctly.) * Fixed undo of newly created object to undo newly created object and not some other random object. (Changes in place() function return t instead of h and in doMouseButtons() function to back up one object.) * Increased maximum size of text to 2000. Had to make local string variables based on MAXTEXT in editText and getText global to avoid stack overflow. * Fixed nextLine() function to work when scrolling up messages when using Wexelblat's MessageBuf array. Removed #ifdefs so that all xcip types will use MessageBuf (there are a few isolated cases where this benefits 5620/630 users). * Adjusted message area window size to avoid partially erasing rightmost vertical border. * Fixed X11 version buttons to look 3-D (LowerTriangle & UpperTriangle icons not happening). Changed order of calls in drawIcon. (Mystery: why does this work for the DMD terminals as it uses the XOR instead of OR code?) * Modified Dave Kapilow's x11.c file as follows: 1) handle -geometry specifying only x and y positions. 2) added -reverse to do reverse video. 3) changed default font to be "8x13" instead of "fixed". 4) added abbreviations: -g, -rv, -fg and -bg 5) implemented cursinhibit() and cursallow() functions. * Internal improvements: 1) Put definitions of textures, curses and bitmaps together in one file. 2) Eliminated some "#ifdef X11" by making code common. * Added "Version" to main menu. * Fixed bug occuring when selecting outside picture area resulting in large black box highlighted. Bug in Select() for all terminal types. * Fixed bug in getBox() where a rectangle was passed to cursset() instead of a point. * Fixed movement of objects over repetitive read/write operations. 1) In xjpic changed deltx & delty to be int instead of float. 2) Removed JpicFix() in readPic.c 3) Removed in writePic() an extra ">>3" adjustment for multiline text as it was effectively being done twice. 4) Changed line 295 in readPic.c to prevent truncation error. * Modified findFont() for X11: 1) ringbell only once and sleep to see message. 2) to try fallback if first font has inexact point size. 3) modified to use font size ps, not ps+2, as it appears closer to print out. 4) changed Palatino_italic_fonts for courier medium from i to o. * Picked up fixes in Wexelblat's July's version: 1) DMDLIBX11/x11.c: SAYSV/BSD portability fix 2) Change drawing of windows to use box instead of rectf for better X window performance. Made some chgs in size of box. 3) Fix size of ellipse drawn in brush so it fits better. 4) Restore buttons if put_file is cancelled. 5) Reset thingSelected if thing is deleted by resizing to zero. 6) Fix scalable font selection. * Fixed exception occuring when the parts of a macro being editted are all deleted and then the macro is exited. * Fixed X version problem that hangs xcip when a keyboard character is entered when not expected. * Now support odd numbered spacing in text Spacing menu. * Spline problems fixed. ------ Following entries by Dave Dykstra unless otherwise noted --------- Releases 4.2 - 4.4: (Note: I don't know which of these fixes were in which intermediate releases 4.2, 4.3, or 4.4) * Jpic modified to change some integer arithmetic into floating point arithmetic, in particular: deltx = delty = 100 * ((float) t / (float) getvar("scale")) * The DMD5620 version changed to treat any non-ascii input as the end of end of input rather than just a CHAR_EOF Release 4.5: (Note: this one was temporarily called versions 'x4.1b' and 'x5.0' while I was trying to figure out what version numbering scheme I should use) * Front end shell script split into to 2 parts. The first part determines whether to use X version or DMD version. If DMD, uses 'dmdtool' to determine difference between 5620 or 630 and then calls the second part. In addition to being more robust in its distinguishing between the two types of terminal, the use of 'dmdtool' means that xdmdld and xjx will be used instead of dmdld and jx. Also, if the second script is installed by itself as 'cip', it will instead use dmdld and jx and find the download executable in $DMD/lib/cip.m. This makes it easy to use the same binaries in both exptools and under $DMD. The algorithm for determining whether or not to use the X version (on machine on which the X version is supported) changed: if the $DISPLAY variable is set or if $TERM is xterm|sun-cmd|x11, the X version will be used. It used to be that if $DISPLAY was set and $TERM were set to something that looked like a 5620 or 630, the non-X version would be used; now the X version will. The "-t" option which explicitly tells xcip which type to use changed subtly: it will now only distinguish between the X and non-X versions, it will not distinguish between 630 and 5620. A "-t x" or "-t sun" will say use the X version and a "-t mtg" or "-t dmd" will say use one of the non-X versions and the script will re-determine whether to use the 630 or 5620 version. * Core dump in xjpic print.c fixed: it was mallocing a structure that was of variable length with different number of parameters. However, it always read two parameters into local variables x1 and y1 whether they were there or not; apparently this went off the end of a page on an amdahl and caused a core dump. * Bug which caused fonts sizes 2 points too small to be selected on X versions fixed. Fonts which could not be found in an exact match were chosen to be 2 points too small; this happens most often on X servers without scalable fonts, that is, pre-X11R5 servers. This X code was originally written by David Wexelblat which incorrectly added 2 to the point size even for the exact matches; Eugene Bordelon had noticed that to be incorrect and took it out. However, it needed the +2 for non-exact matches because the first two elements in the font mapping arrays are special and need to be skipped. * A couple minor changes to improve portability to SVR4. Release 4.6: * Jpic bug fixes thanks to Ton Kramer: * suggested changing the floating point arithmetic changed in release 4.4 to the following: deltx = delty = 100 * (float) t / (float) getvar("scale") This works better on Eugene's test suite test1 for reading and writing without changes. The code from version 4.1b works just as well deltx = delty = t * (100 / getvar("scale")) so I'll stick with it. * elipses with height 48 and width 80 on 8x8 grids were read in as elipses with height 46 and width 80. The fix is in function "ysc()" in pltroff.c. If yscale is negative, subtract 0.5 instead of add 0.5. * Added Eugene's test suite to the source code. Release 4.6b: * I should have used Ton's code for the floating point arithmetic on "scale" because that works better if the user edits the 'scale' variable in the pic file. In fact, I thought I had used that but I accidentally used the version where it was commented out and Eugene's version was back in. The original change in version 4.4 was apparently an attempt to fix this problem. This version changes it to a compromise: (float) t * ((float) 100 / (float) getvar("scale")) This has the same results as Ton's version but is more intuitive because the 100 is related to the scale and is in the same order as the original. Release 4.6c: * Added in some ifdefed-out code for future use: FINEALIGN and HELPSCALE. Code from Franco Barber. Will probably be enabled in a future release. Release 4.6d: * More ifdefed-out code from Franco Barber in the FINEALIGN and HELPSCALE features. * Fix from Franco Barber to initialize "prevhit" values on menus to the default entries. Without it, sub-menus can be selected even though they weren't actually entered. * Fixed a bug where the invisible bounding box written out around a picture that is less than 200 pixels or so wide while the xcip window is to the far right side of a 730 screen would force the box to still be 200 pixels wide. * Moved the copyright message a little to the right to allow room for the 4 character wide version numbers of xcip.m. Release 4.7: * Enabled FINEALIGN and HELPSCALE defines. Release 4.7b: * Added fine, medium, and coarse in parentheses in the alignment menu behind 2, 8, and 16, respectively for information. Release 4.7c: * Removed ".m" from the backup file name; this had been accidentally inserted in (probably) release 4.5. Release 4.8: 12/21/95 * Fixed font scaling problem on Suns by choosing -100-100- resolutions in the X font names. Also, choose the adobe family for helvetica, times, and courier because the defaults (at least on Solaris 2.3) choose the wrong size for some point sizes. Thanks to Joe Davison for the pointer to the "xfontsel" program which allows one to easily experiment with those parameters. Also note (at least on Solaris 2.3) that there is no point size 22 so it drops down to display point size 20. I also removed the "+2" added to point sizes for inexact matches which I added in version 4.5, because it was incorrect; the first 2 locations in the font arrays are special, but they are already automatically skipped because there's never a point size of 0 or 1. * Made the default button 2 behavior be to move the whole picture on the screen, similar to a suggestion from Gene Bordelon. Added a variable called "scrollOffset" which is the x/y offset that the picture has been moved, manipulated in a new routine "moveAll". Clearing the screen resets the scrollOffset to 0,0. * Renamed the globals Xoffset and Yoffset to a Point called readPicOffset and moved it to readPic.c because that's the only place it's used. * Changed the Copyright year to 1995 from 1985. Release 4.8b: 1/4/96 * The 100-100 fonts did not exist on Sunos4 (X11R4 presumably) so I had to compromise: Try the 100-100 fonts first, and if those can't be found, silently drop back to *-*. At the same time it drops back to *-*, add 2 to the point size but do it more intelligently than in the past by making sure it can always select a valid font in the font arrays. Kept the "adobe" wherever Sunos4 had an adobe font. Extended the font arrays to also always have a "-*-" for every field instead of stopping with just a "-*" after the point size because I found that it made a difference on Solaris (X11R5). If an exact match for a font cannot be found, a message displaying that fact will now appear for at least 1/2 second instead of possibly being overwritten immediately. * Made the default height and width for the X version to be the same number of pixels as on the 730 rather than a certain number of inches. There's not enough pixels available for height on Suns, but there is for width and the program was choosing fewer than it needed, especially on the Sunos machine I tested. Release 4.8c: SGI portability changes 3/6/96 * changed dpy->fd in initdisplay() to ConnectionNumber(dpy). * changed fgpix, bgpix, and tmppix globals in x11.c from int to unsigned long. * changed the externs of fgpix and gbpix in jerq.h from int to unsigned long. * changed &ev in call to XLookupColor in handleinput() to &ev.xkey. xcip/version.h0000644000175300001440000000011711513632544012205 0ustar meusers /* this is the version for both cip.m and jpic */ #define PGM_VERSION "4.8c" xcip/transform.c0000644000175300001440000000414011513632543012525 0ustar meusers#include "cip.h" struct thing * Transform(t, p) register struct thing *t; Point p; { Rectangle r; register Point *plist; register int i; Point temp; if (t->type == MACRO) { if (p.y != 0) { t->bb.origin.y = p.y - t->bb.origin.y; t->bb.corner.y = p.y - t->bb.corner.y; } else { t->bb.origin.x = p.x - t->bb.origin.x; t->bb.corner.x = p.x - t->bb.corner.x; } t->bb = canon (t->bb.origin, t->bb.corner); t->origin = t->bb.origin; return (t); } if (p.y != 0) { /* x-axis - change y coordinate */ t->origin.y = p.y - t->origin.y; } else { /* y-axis - change x coordinate */ t->origin.x = p.x - t->origin.x; } switch(t->type) { case CIRCLE: case ELLIPSE: { break; } case TEXT: { if (p.y != 0) { t->origin.y -= fontheight(t->otherValues.text.f->f); } break; } case BOX: { if (p.y != 0) { t->otherValues.corner.y = p.y - t->otherValues.corner.y; } else { t->otherValues.corner.x = p.x - t->otherValues.corner.x; } r = canon (t->origin, t->otherValues.corner); t->origin = r.origin; t->otherValues.corner = r.corner; break; } case LINE: { if (p.y != 0) { t->otherValues.end.y = p.y - t->otherValues.end.y; } else { t->otherValues.end.x = p.x - t->otherValues.end.x; } break; } case ARC: { if (p.y != 0) { t->otherValues.arc.start.y = p.y - t->otherValues.arc.start.y; t->otherValues.arc.end.y = p.y - t->otherValues.arc.end.y; } else { t->otherValues.arc.start.x = p.x - t->otherValues.arc.start.x; t->otherValues.arc.end.x = p.x - t->otherValues.arc.end.x; } temp = t->otherValues.arc.start; t->otherValues.arc.start = t->otherValues.arc.end; t->otherValues.arc.end = temp; break; } case SPLINE: { plist = t->otherValues.spline.plist; for (i=0; iotherValues.spline.used; i++) { if (p.y == 0) { plist[i].x = p.x - plist[i].x; } else { plist[i].y = p.y - plist[i].y; } } break; } } boundingBox(t); return(t); } xcip/X11/0000755000175300001440000000000011513632541010716 5ustar meusersxcip/ciprint.10000644000175300001440000000313511513632543012103 0ustar meusers.TH CIPRINT 1 EXPTOOLS .tr ~ .SH NAME ciprint \- prints the pic files from cip and xcip .SH SYNOPSIS .B "ciprint [-V?] [-o offset] [-t xr|i300|prt] [-f12] [printer-args] pic-files" .SH DESCRIPTION .I Ciprint prints the pic files generated by .I cip and .IR xcip "," one file per page, on either a Xerox 9700 (\fB-t~xr\fR), an Imagin i300 (\fB-t~i300\fR) printer, or some unison (\fB-t~prt\fR) printer. (Note: that the unison prt command will direct output to printers such as Xerox, Imagin or Postscript-based.) .I Ciprint is a shell that uses pic(1) and troff(1) and either dx9700(1), i300(exptools-1) or prt(1) commands. Each picture will be centered horizontally at the top of the page. .P By default it uses the Xerox 9700 printer with text point sizes of 7 and 10 only. With the .B "-f12" option, sizes 9 and 12 only are supported. Text of sizes other than these, will be resized automatically. The Imagin and most postscript printers support most all font styles and point sizes available in .IR xcip "." .P The .B "-o" parameter allows one to specify an offset from left side of the page. The default is "0.4". .P The optional .I printer-args are used for example to specify the number of copies (e.g. -c3 ). .P The .B "-V" option prints out the version of .I ciprint (no files are printed). .SH SEE ALSO cip(dmd-1), xcip(exptools-1), pic(1), troff(1), dx9700(1), prt(1) & i300(exptools-1) .SH WARNINGS Xerox will simply not print pages (giving no warning) that exceed its internal limits. A common example is a picture containing many vertical dotted lines. The Imagen also has limits but they are much greater. xcip/testsuite/0000755000175300001440000000000011513632543012400 5ustar meusersxcip/testsuite/test70000644000175300001440000001714511513632542013400 0ustar meusers.nf .PS scale=100 define t100 | [ box invis ht 612 wid 22 with .sw at 0,0 "\fB\s16\&2\fP\s0" at 11,600 "\fB\s16\&3\fP\s0" at 11,563 "\fB\s16\&4\fP\s0" at 11,526 "\fB\s16\&5\fP\s0" at 11,489 "\fB\s16\&6\fP\s0" at 11,452 "\fB\s16\&7\fP\s0" at 11,415 "\fB\s16\&8\fP\s0" at 11,378 "\fB\s16\&9\fP\s0" at 11,341 "\fB\s16\&10\fP\s0" at 11,304 "\fB\s16\&11\fP\s0" at 11,267 "\fB\s16\&12\fP\s0" at 11,230 "\fB\s16\&14\fP\s0" at 11,193 "\fB\s16\&16\fP\s0" at 11,156 "\fB\s16\&18\fP\s0" at 11,119 "\fB\s16\&20\fP\s0" at 11,82 "\fB\s16\&22\fP\s0" at 11,45 "\fB\s16\&24\fP\s0" at 11,8 ] | box invis ht 688 wid 728 with .sw at 0,0 t100 with .nw at 37,637 "\f(CW\s24\&A1\fP\s0" at 704,36 "\f(PB\s24\&A1\fP\s0" at 480,34 "\f(PI\s24\&A1\fP\s0" at 432,33 "\f(HI\s24\&A1\fP\s0" at 280,34 "\fH\s24\&A1\fP\s0" at 240,34 "\f(PA\s24\&A1\fP\s0" at 388,33 "\f(HB\s24\&A1\fP\s0" at 328,34 "\fB\s24\&A1\fP\s0" at 168,34 "\fI\s24\&A1\fP\s0" at 128,34 "\fR\s24\&A1\fP\s0" at 88,34 "\fE\s24\&A1\fP\s0" at 536,36 "\f(EI\s24\&A1\fP\s0" at 584,36 "\f(EB\s24\&A1\fP\s0" at 632,36 "\f(CW\s22\&A1\fP\s0" at 704,76 "\f(PB\s22\&A1\fP\s0" at 472,76 "\f(PI\s22\&A1\fP\s0" at 432,75 "\f(HI\s22\&A1\fP\s0" at 280,74 "\fH\s22\&A1\fP\s0" at 240,74 "\f(PA\s22\&A1\fP\s0" at 392,75 "\f(HB\s22\&A1\fP\s0" at 328,74 "\fB\s22\&A1\fP\s0" at 168,74 "\fI\s22\&A1\fP\s0" at 128,74 "\fR\s22\&A1\fP\s0" at 88,74 "\fE\s22\&A1\fP\s0" at 536,76 "\f(EI\s22\&A1\fP\s0" at 584,76 "\f(EB\s22\&A1\fP\s0" at 632,76 "\f(CW\s20\&A1\fP\s0" at 704,116 "\f(PB\s20\&A1\fP\s0" at 472,116 "\f(PI\s20\&A1\fP\s0" at 432,117 "\f(HI\s20\&A1\fP\s0" at 280,114 "\fH\s20\&A1\fP\s0" at 240,114 "\f(PA\s20\&A1\fP\s0" at 392,116 "\f(HB\s20\&A1\fP\s0" at 328,114 "\fB\s20\&A1\fP\s0" at 168,114 "\fI\s20\&A1\fP\s0" at 128,114 "\fR\s20\&A1\fP\s0" at 88,114 "\fE\s20\&A1\fP\s0" at 536,116 "\f(EI\s20\&A1\fP\s0" at 584,116 "\f(EB\s20\&A1\fP\s0" at 632,116 "\f(CW\s18\&A1\fP\s0" at 704,144 "\f(PB\s18\&A1\fP\s0" at 472,150 "\f(PI\s18\&A1\fP\s0" at 432,150 "\f(HI\s18\&A1\fP\s0" at 280,149 "\fH\s18\&A1\fP\s0" at 240,149 "\f(PA\s18\&A1\fP\s0" at 392,151 "\f(HB\s18\&A1\fP\s0" at 328,149 "\fB\s18\&A1\fP\s0" at 168,150 "\fI\s18\&A1\fP\s0" at 128,149 "\fR\s18\&A1\fP\s0" at 88,150 "\fE\s18\&A1\fP\s0" at 536,144 "\f(EI\s18\&A1\fP\s0" at 584,144 "\f(EB\s18\&A1\fP\s0" at 632,144 "\f(CW\s16\&A1\fP\s0" at 704,191 "\f(PB\s16\&A1\fP\s0" at 472,190 "\f(PI\s16\&A1\fP\s0" at 432,191 "\f(HI\s16\&A1\fP\s0" at 280,189 "\fH\s16\&A1\fP\s0" at 240,189 "\f(PA\s16\&A1\fP\s0" at 392,191 "\f(HB\s16\&A1\fP\s0" at 328,189 "\fB\s16\&A1\fP\s0" at 168,190 "\fI\s16\&A1\fP\s0" at 128,189 "\fR\s16\&A1\fP\s0" at 88,190 "\fE\s16\&A1\fP\s0" at 536,191 "\f(EI\s16\&A1\fP\s0" at 584,191 "\f(EB\s16\&A1\fP\s0" at 632,190 "\f(CW\s14\&A1\fP\s0" at 704,224 "\f(PB\s14\&A1\fP\s0" at 472,224 "\f(PI\s14\&A1\fP\s0" at 432,225 "\f(HI\s14\&A1\fP\s0" at 280,224 "\fH\s14\&A1\fP\s0" at 240,224 "\f(PA\s14\&A1\fP\s0" at 392,224 "\f(HB\s14\&A1\fP\s0" at 328,224 "\fB\s14\&A1\fP\s0" at 168,223 "\fI\s14\&A1\fP\s0" at 128,223 "\fR\s14\&A1\fP\s0" at 88,223 "\fE\s14\&A1\fP\s0" at 536,224 "\f(EI\s14\&A1\fP\s0" at 584,224 "\f(EB\s14\&A1\fP\s0" at 632,224 "\f(CW\s12\&A1\fP\s0" at 704,264 "\f(PB\s12\&A1\fP\s0" at 472,265 "\f(PI\s12\&A1\fP\s0" at 432,266 "\f(HI\s12\&A1\fP\s0" at 280,264 "\fH\s12\&A1\fP\s0" at 240,264 "\f(PA\s12\&A1\fP\s0" at 392,265 "\f(HB\s12\&A1\fP\s0" at 328,264 "\fB\s12\&A1\fP\s0" at 168,263 "\fI\s12\&A1\fP\s0" at 128,263 "\fR\s12\&A1\fP\s0" at 88,263 "\fE\s12\&A1\fP\s0" at 536,264 "\f(EI\s12\&A1\fP\s0" at 584,264 "\f(EB\s12\&A1\fP\s0" at 632,264 "\f(CW\s11\&A1\fP\s0" at 704,305 "\f(PB\s11\&A1\fP\s0" at 472,305 "\f(PI\s11\&A1\fP\s0" at 432,306 "\f(HI\s11\&A1\fP\s0" at 280,298 "\fH\s11\&A1\fP\s0" at 240,298 "\f(PA\s11\&A1\fP\s0" at 392,305 "\f(HB\s11\&A1\fP\s0" at 328,305 "\fB\s11\&A1\fP\s0" at 168,305 "\fI\s11\&A1\fP\s0" at 128,305 "\fR\s11\&A1\fP\s0" at 88,305 "\fE\s11\&A1\fP\s0" at 536,305 "\f(EI\s11\&A1\fP\s0" at 584,305 "\f(EB\s11\&A1\fP\s0" at 632,305 "\f(CW\s9\&A1\fP\s0" at 704,375 "\f(PB\s9\&A1\fP\s0" at 472,379 "\f(PI\s9\&A1\fP\s0" at 432,378 "\f(HI\s9\&A1\fP\s0" at 280,378 "\fH\s9\&A1\fP\s0" at 240,378 "\f(PA\s9\&A1\fP\s0" at 392,379 "\f(HB\s9\&A1\fP\s0" at 328,378 "\fB\s9\&A1\fP\s0" at 168,378 "\fI\s9\&A1\fP\s0" at 128,378 "\fR\s9\&A1\fP\s0" at 88,378 "\fE\s9\&A1\fP\s0" at 536,375 "\f(EI\s9\&A1\fP\s0" at 584,375 "\f(EB\s9\&A1\fP\s0" at 632,374 "\f(CW\s8\&A1\fP\s0" at 704,411 "\f(PB\s8\&A1\fP\s0" at 472,412 "\f(PI\s8\&A1\fP\s0" at 432,410 "\f(HI\s8\&A1\fP\s0" at 280,410 "\fH\s8\&A1\fP\s0" at 240,410 "\f(PA\s8\&A1\fP\s0" at 392,411 "\f(HB\s8\&A1\fP\s0" at 328,410 "\fB\s8\&A1\fP\s0" at 168,410 "\fI\s8\&A1\fP\s0" at 128,410 "\fR\s8\&A1\fP\s0" at 88,410 "\fE\s8\&A1\fP\s0" at 536,411 "\f(EI\s8\&A1\fP\s0" at 584,411 "\f(EB\s8\&A1\fP\s0" at 632,411 "\f(CW\s10\&A1\fP\s0" at 704,337 "\f(PB\s10\&A1\fP\s0" at 472,339 "\f(PI\s10\&A1\fP\s0" at 432,338 "\f(HI\s10\&A1\fP\s0" at 280,337 "\fH\s10\&A1\fP\s0" at 240,337 "\f(PA\s10\&A1\fP\s0" at 392,339 "\f(HB\s10\&A1\fP\s0" at 328,337 "\fB\s10\&A1\fP\s0" at 168,337 "\fI\s10\&A1\fP\s0" at 128,337 "\fR\s10\&A1\fP\s0" at 88,337 "\fE\s10\&A1\fP\s0" at 536,337 "\f(EI\s10\&A1\fP\s0" at 584,337 "\f(EB\s10\&A1\fP\s0" at 632,337 "\f(CW\s7\&A1\fP\s0" at 704,448 "\f(PB\s7\&A1\fP\s0" at 472,452 "\f(PI\s7\&A1\fP\s0" at 432,450 "\f(HI\s7\&A1\fP\s0" at 280,451 "\fH\s7\&A1\fP\s0" at 240,451 "\f(PA\s7\&A1\fP\s0" at 392,451 "\f(HB\s7\&A1\fP\s0" at 328,451 "\fB\s7\&A1\fP\s0" at 168,451 "\fI\s7\&A1\fP\s0" at 128,451 "\fR\s7\&A1\fP\s0" at 88,451 "\fE\s7\&A1\fP\s0" at 536,449 "\f(EI\s7\&A1\fP\s0" at 584,450 "\f(EB\s7\&A1\fP\s0" at 632,450 "\f(CW\s6\&A1\fP\s0" at 704,491 "\f(PB\s6\&A1\fP\s0" at 472,492 "\f(PI\s6\&A1\fP\s0" at 432,490 "\f(HI\s6\&A1\fP\s0" at 280,491 "\fH\s6\&A1\fP\s0" at 240,491 "\f(PA\s6\&A1\fP\s0" at 392,491 "\f(HB\s6\&A1\fP\s0" at 328,491 "\fB\s6\&A1\fP\s0" at 168,491 "\fI\s6\&A1\fP\s0" at 128,491 "\fR\s6\&A1\fP\s0" at 88,491 "\fE\s6\&A1\fP\s0" at 536,492 "\f(EI\s6\&A1\fP\s0" at 584,494 "\f(EB\s6\&A1\fP\s0" at 632,494 "\f(CW\s5\&A1\fP\s0" at 704,521 "\f(PB\s5\&A1\fP\s0" at 472,524 "\f(PI\s5\&A1\fP\s0" at 432,522 "\f(HI\s5\&A1\fP\s0" at 280,523 "\fH\s5\&A1\fP\s0" at 240,523 "\f(PA\s5\&A1\fP\s0" at 392,523 "\f(HB\s5\&A1\fP\s0" at 328,521 "\fB\s5\&A1\fP\s0" at 168,523 "\fI\s5\&A1\fP\s0" at 128,523 "\fR\s5\&A1\fP\s0" at 88,523 "\fE\s5\&A1\fP\s0" at 536,522 "\f(EI\s5\&A1\fP\s0" at 584,523 "\f(EB\s5\&A1\fP\s0" at 632,523 "\f(CW\s4\&A1\fP\s0" at 704,563 "\f(PB\s4\&A1\fP\s0" at 472,564 "\f(PI\s4\&A1\fP\s0" at 432,572 "\f(HI\s4\&A1\fP\s0" at 280,563 "\fH\s4\&A1\fP\s0" at 240,563 "\f(PA\s4\&A1\fP\s0" at 392,563 "\f(HB\s4\&A1\fP\s0" at 328,562 "\fB\s4\&A1\fP\s0" at 168,563 "\fI\s4\&A1\fP\s0" at 128,563 "\fR\s4\&A1\fP\s0" at 88,563 "\fE\s4\&A1\fP\s0" at 536,564 "\f(EI\s4\&A1\fP\s0" at 584,565 "\f(EB\s4\&A1\fP\s0" at 632,565 "\f(CW\s3\&A1\fP\s0" at 704,603 "\f(PB\s3\&A1\fP\s0" at 472,604 "\f(PI\s3\&A1\fP\s0" at 432,612 "\f(HI\s3\&A1\fP\s0" at 280,603 "\fH\s3\&A1\fP\s0" at 240,603 "\f(PA\s3\&A1\fP\s0" at 392,603 "\f(HB\s3\&A1\fP\s0" at 328,603 "\fB\s3\&A1\fP\s0" at 168,603 "\fI\s3\&A1\fP\s0" at 128,603 "\fR\s3\&A1\fP\s0" at 88,603 "\fE\s3\&A1\fP\s0" at 536,604 "\f(EI\s3\&A1\fP\s0" at 584,606 "\f(EB\s3\&A1\fP\s0" at 632,606 "\f(CW\s2\&A1\fP\s0" at 704,635 "\f(PB\s2\&A1\fP\s0" at 472,636 "\f(PI\s2\&A1\fP\s0" at 432,634 "\f(HI\s2\&A1\fP\s0" at 280,635 "\fH\s2\&A1\fP\s0" at 240,635 "\f(PA\s2\&A1\fP\s0" at 392,635 "\f(HB\s2\&A1\fP\s0" at 328,635 "\fB\s2\&A1\fP\s0" at 168,635 "\fI\s2\&A1\fP\s0" at 128,635 "\fR\s2\&A1\fP\s0" at 88,635 "\fE\s2\&A1\fP\s0" at 536,636 "\f(EI\s2\&A1\fP\s0" at 584,638 "\f(EB\s2\&A1\fP\s0" at 632,638 "\fB\s20\&R RI RB H HI HB P PI PB E EI EB CW\fP\s0" at 400,673 line from 64,688 to 64,0 line from 0,656 to 720,656 .PE .fi xcip/testsuite/README0000644000175300001440000000250711513632542013263 0ustar meusersThis directory consists of a series of test files to check out xcip. test1: Checks against movement of objects after multiple read/writes. 1. Turn on grid. 2. Get_file test1 (move to left side) 3. Put_file test1a 4. Get_file test1a (do not clear, center) 5. Check that boxes, circles and text have not moved. 6. diff test1 test1a test2: Checks xcip window screen size. *** NOTE: this test does not work on Sun workstations running xcip *** *** as box will be greater than screen size! *** 1. Turn on grid. 2. Get_file test2 (center) 3. Check that box goes thru outer most grid points. test3: Checks printing of xjpic error message when doing get_file. 1. Get_file test3 test4: test5: Checks against movement of objects after multiple read/writes. 1. Turn on grid. 2. Get_file test5 (center) 3. Put_file test5a 4. Get_file test5a (do not clear, center) 5. Check that all dissappears. test6: Loads all fonts. 1. Get_file test6 2. Check against printout. test7: Loads all fonts and sizes. 1. Get_file test7 2. Check against printout. test8: Loads Roman text in tight enclosing boxes. 1. Get_file test8 2. Check against printout. test9: Loads Helvetica text in tight enclosing boxes. 1. Get_file test9 2. Check against printout. xcip/testsuite/test90000644000175300001440000000334211513632542013374 0ustar meusers.nf .PS scale=100 define m2 | [ box invis ht 24 wid 208 with .sw at 0,0 "\fH\s16\&ABCDEFGHIJKLMN\fP\s0" at 104,9 box ht 24 wid 208 with .nw at 0,24 ] | define m1 | [ box invis ht 24 wid 184 with .sw at 0,0 "\fH\s14\&ABCDEFGHIJKLMN\fP\s0" at 92,8 box ht 24 wid 184 with .nw at 0,24 ] | define m6 | [ box invis ht 32 wid 264 with .sw at 0,0 "\fH\s20\&ABCDEFGHIJKLMN\fP\s0" at 132,14 box ht 24 wid 264 with .nw at 0,32 ] | define m5 | [ box invis ht 32 wid 280 with .sw at 0,0 box ht 32 wid 280 with .nw at 0,32 "\fH\s22\&ABCDEFGHIJKLMN\fP\s0" at 140,12 ] | define m4 | [ box invis ht 40 wid 296 with .sw at 0,0 "\fH\s24\&ABCDEFGHIJKLMN\fP\s0" at 148,18 box ht 32 wid 296 with .nw at 0,40 ] | define m7 | [ box invis ht 16 wid 120 with .sw at 0,0 "\fH\s8\&ABCDEFGHIJKLMN\fP\s0" at 60,6 box ht 16 wid 120 with .nw at 0,16 ] | define m0 | [ box invis ht 32 wid 232 with .sw at 0,0 "\fH\s18\&ABCDEFGHIJKLMN\fP\s0" at 116,15 box ht 24 wid 232 with .nw at 0,32 ] | define m8 | [ box invis ht 16 wid 152 with .sw at 0,0 "\fH\s10\&ABCDEFGHIJKLMN\fP\s0" at 76,6 box ht 16 wid 136 with .nw at 8,16 ] | define m3 | [ box invis ht 24 wid 160 with .sw at 0,0 "\fH\s12\&ABCDEFGHIJKLMN\fP\s0" at 80,13 box ht 16 wid 160 with .nw at 0,24 ] | box invis ht 408 wid 368 with .sw at 0,0 m2 with .nw at 104,240 "\fH\s10\&24\fP\s0" at 16,24 "\fH\s10\&12\fP\s0" at 104,324 "\fH\s10\&22\fP\s0" at 16,76 m1 with .nw at 120,288 "\fH\s10\&20\fP\s0" at 28,128 m6 with .nw at 88,144 "\fH\s10\&10\fP\s0" at 112,360 m5 with .nw at 80,96 "\fH\s10\&18\fP\s0" at 56,176 m4 with .nw at 72,40 m7 with .nw at 160,408 m0 with .nw at 96,192 m8 with .nw at 144,368 "\fH\s10\&16\fP\s0" at 68,228 m3 with .nw at 136,328 "\fH\s10\&14\fP\s0" at 88,276 "\fH\s10\&8\fP\s0" at 124,396 .PE .fi xcip/testsuite/test30000644000175300001440000005057311513632542013376 0ustar meusers.nf .PS scale=100 define t557 | [ box invis ht 34 wid 58 with .sw at 0,0 "\fR\s5\&Send for \f1\s0" at 29,29 "\fR\s5\&review by \f1\s0" at 29,21 "\fR\s5\&installing \f1\s0" at 29,13 "\fR\s5\&on ihlpb \f1\s0" at 29,5 ] | define t558 | [ box invis ht 30 wid 56 with .sw at 0,0 "\fR\s5\&Review \f1\s0" at 28,25 "\fR\s5\&for design\f1\s0" at 28,15 "\fR\s5\&document \f1\s0" at 28,5 ] | define t559 | [ box invis ht 20 wid 56 with .sw at 0,0 "\fR\s5\&Design \f1\s0" at 28,15 "\fR\s5\&document \f1\s0" at 28,5 ] | define t560 | [ box invis ht 20 wid 38 with .sw at 0,0 "\fR\s5\&Tear \f1\s0" at 19,15 "\fR\s5\&review\f1\s0" at 19,5 ] | define t561 | [ box invis ht 40 wid 46 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 23,35 "\fR\s5\&bringup \f1\s0" at 23,25 "\fR\s5\&for EX2\f1\s0" at 23,15 "\fR\s5\&& ML3 \f1\s0" at 23,5 ] | define t562 | [ box invis ht 40 wid 46 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 23,35 "\fR\s5\&bringup \f1\s0" at 23,25 "\fR\s5\&for EX2\f1\s0" at 23,15 "\fR\s5\&& ML3 \f1\s0" at 23,5 ] | define t563 | [ box invis ht 40 wid 48 with .sw at 0,0 "\fR\s5\&Build \f1\s0" at 24,35 "\fR\s5\&ODD \f1\s0" at 24,25 "\fR\s5\&for EX2\f1\s0" at 24,15 "\fR\s5\&& ML3 \f1\s0" at 24,5 ] | define t564 | [ box invis ht 40 wid 48 with .sw at 0,0 "\fR\s5\&Build \f1\s0" at 24,35 "\fR\s5\&ODD \f1\s0" at 24,25 "\fR\s5\&for EX2\f1\s0" at 24,15 "\fR\s5\&& ML3 \f1\s0" at 24,5 ] | define t565 | [ box invis ht 40 wid 48 with .sw at 0,0 "\fR\s5\&Build \f1\s0" at 24,35 "\fR\s5\&ODD \f1\s0" at 24,25 "\fR\s5\&for EX2\f1\s0" at 24,15 "\fR\s5\&& ML3 \f1\s0" at 24,5 ] | define t566 | [ box invis ht 50 wid 48 with .sw at 0,0 "\fR\s5\&Prepare \f1\s0" at 24,45 "\fR\s5\&EX2 & \f1\s0" at 24,35 "\fR\s5\&ML3 \f1\s0" at 24,25 "\fR\s5\&design \f1\s0" at 24,15 "\fR\s5\&package \f1\s0" at 24,5 ] | define t567 | [ box invis ht 50 wid 48 with .sw at 0,0 "\fR\s5\&Prepare \f1\s0" at 24,45 "\fR\s5\&EX2 & \f1\s0" at 24,35 "\fR\s5\&ML3 \f1\s0" at 24,25 "\fR\s5\&design \f1\s0" at 24,15 "\fR\s5\&package \f1\s0" at 24,5 ] | define t594 | [ box invis ht 40 wid 46 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 23,35 "\fR\s5\&bringup \f1\s0" at 23,25 "\fR\s5\&for EX2\f1\s0" at 23,15 "\fR\s5\&& ML3 \f1\s0" at 23,5 ] | define t595 | [ box invis ht 50 wid 50 with .sw at 0,0 "\fR\s5\&Final \f1\s0" at 25,45 "\fR\s5\&ODD \f1\s0" at 25,35 "\fR\s5\&build \f1\s0" at 25,25 "\fR\s5\&and test \f1\s0" at 25,15 "\fR\s5\&on EES \f1\s0" at 25,5 ] | define t596 | [ box invis ht 20 wid 38 with .sw at 0,0 "\fR\s5\&Data \f1\s0" at 19,15 "\fR\s5\&freeze \f1\s0" at 19,5 ] | define t597 | [ box invis ht 40 wid 48 with .sw at 0,0 "\fR\s5\&Build \f1\s0" at 24,35 "\fR\s5\&ODD \f1\s0" at 24,25 "\fR\s5\&for EX2\f1\s0" at 24,15 "\fR\s5\&& ML3 \f1\s0" at 24,5 ] | define t598 | [ box invis ht 40 wid 48 with .sw at 0,0 "\fR\s5\&Build \f1\s0" at 24,35 "\fR\s5\&ODD \f1\s0" at 24,25 "\fR\s5\&for EX2\f1\s0" at 24,15 "\fR\s5\&& ML3 \f1\s0" at 24,5 ] | define t625 | [ box invis ht 20 wid 26 with .sw at 0,0 "\fR\s5\&SLE\f1\s0" at 13,15 "\fR\s5\&Dart\f1\s0" at 13,5 ] | define t626 | [ box invis ht 20 wid 40 with .sw at 0,0 "\fR\s5\&Switch \f1\s0" at 20,15 "\fR\s5\&Trans \f1\s0" at 20,5 ] | define t627 | [ box invis ht 40 wid 52 with .sw at 0,0 "\fR\s5\&Quality \f1\s0" at 26,35 "\fR\s5\&Fund \f1\s0" at 26,25 "\fR\s5\&for area \f1\s0" at 26,15 "\fR\s5\&55 \f1\s0" at 26,5 ] | define t628 | [ box invis ht 30 wid 58 with .sw at 0,0 "\fR\s5\&Intro \f1\s0" at 29,25 "\fR\s5\&to AT&T \f1\s0" at 29,15 "\fR\s5\&Operations\f1\s0" at 29,5 ] | define t629 | [ box invis ht 20 wid 42 with .sw at 0,0 "\fR\s5\&Switch \f1\s0" at 21,15 "\fR\s5\&Arch. \f1\s0" at 21,5 ] | define t630 | [ box invis ht 30 wid 40 with .sw at 0,0 "\fR\s5\&One \f1\s0" at 20,25 "\fR\s5\&Day \f1\s0" at 20,15 "\fR\s5\&Aware \f1\s0" at 20,5 ] | define t631 | [ box invis ht 20 wid 32 with .sw at 0,0 "\fR\s5\&Shell \f1\s0" at 16,15 "\fR\s5\&Lang.\f1\s0" at 16,5 ] | define t632 | [ box invis ht 20 wid 40 with .sw at 0,0 "\fR\s5\&AA \f1\s0" at 20,15 "\fR\s5\&meeting\f1\s0" at 20,5 ] | define t633 | [ box invis ht 40 wid 54 with .sw at 0,0 "\fR\s5\&Unix \f1\s0" at 27,35 "\fR\s5\&System \f1\s0" at 27,25 "\fR\s5\&Doc. \f1\s0" at 27,15 "\fR\s5\&Macros \f1\s0" at 27,5 ] | define t634 | [ box invis ht 20 wid 70 with .sw at 0,0 "\fR\s5\&Software \f1\s0" at 35,15 "\fR\s5\&Architecture \f1\s0" at 35,5 ] | define t689 | [ box invis ht 50 wid 74 with .sw at 0,0 "\fR\s5\&Complete \f1\s0" at 37,45 "\fR\s5\&document \f1\s0" at 37,35 "\fR\s5\&on \"First step\f1\s0" at 37,25 "\fR\s5\&to an ODD \f1\s0" at 37,15 "\fR\s5\&Engineer \f1\s0" at 37,5 ] | define t690 | [ box invis ht 60 wid 74 with .sw at 0,0 "\fR\s5\&Compile \f1\s0" at 37,55 "\fR\s5\&and distribute\f1\s0" at 37,45 "\fR\s5\&document \f1\s0" at 37,35 "\fR\s5\&on \"First step\f1\s0" at 37,25 "\fR\s5\&to an ODD \f1\s0" at 37,15 "\fR\s5\&Engineer \f1\s0" at 37,5 ] | define t691 | [ box invis ht 26 wid 92 with .sw at 0,0 "\fR\s7\&U.S. savings \f1\s0" at 46,20 "\fR\s7\&bond canvanser\f1\s0" at 46,7 ] | define t481 | [ box invis ht 50 wid 48 with .sw at 0,0 "\fR\s5\&Prepare \f1\s0" at 24,45 "\fR\s5\&EX2 & \f1\s0" at 24,35 "\fR\s5\&ML3 \f1\s0" at 24,25 "\fR\s5\&design \f1\s0" at 24,15 "\fR\s5\&package \f1\s0" at 24,5 ] | define t485 | [ box invis ht 50 wid 48 with .sw at 0,0 "\fR\s5\&Prepare \f1\s0" at 24,45 "\fR\s5\&EX2 & \f1\s0" at 24,35 "\fR\s5\&ML3 \f1\s0" at 24,25 "\fR\s5\&design \f1\s0" at 24,15 "\fR\s5\&package \f1\s0" at 24,5 ] | define t486 | [ box invis ht 40 wid 46 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 23,35 "\fR\s5\&bringup \f1\s0" at 23,25 "\fR\s5\&for EX2\f1\s0" at 23,15 "\fR\s5\&& ML3 \f1\s0" at 23,5 ] | define t487 | [ box invis ht 40 wid 52 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 26,35 "\fR\s5\&bring+up \f1\s0" at 26,25 "\fR\s5\&for EX2\f1\s0" at 26,15 "\fR\s5\&& ML3 \f1\s0" at 26,5 ] | define t488 | [ box invis ht 40 wid 46 with .sw at 0,0 "\fR\s5\&Mini \f1\s0" at 23,35 "\fR\s5\&bringup \f1\s0" at 23,25 "\fR\s5\&for EX2\f1\s0" at 23,15 "\fR\s5\&& ML3 \f1\s0" at 23,5 ] | define m0 | [ box invis ht 32 wid 680 with .sw at 0,0 "\fR\s10\&14\f1\s0" at 172,22 "\fR\s10\&21\f1\s0" at 196,22 "\fR\s10\&28\f1\s0" at 220,22 "\fR\s10\&5\f1\s0" at 256,22 "\fR\s10\&12\f1\s0" at 280,22 "\fR\s10\&19\f1\s0" at 304,22 "\fR\s10\&26\f1\s0" at 328,22 "\fR\s10\&2\f1\s0" at 360,22 "\fR\s10\&9\f1\s0" at 384,22 "\fR\s10\&16\f1\s0" at 408,22 "\fR\s10\&23\f1\s0" at 432,22 "\fR\s10\&30\f1\s0" at 456,22 "\fR\s10\&6\f1\s0" at 488,22 "\fR\s10\&13\f1\s0" at 512,22 "\fR\s10\&20\f1\s0" at 536,22 "\fR\s10\&27\f1\s0" at 560,22 "\fR\s10\&4\f1\s0" at 592,22 "\fR\s10\&11\f1\s0" at 616,22 "\fR\s10\&18\f1\s0" at 640,22 "\fR\s10\&25\f1\s0" at 664,22 "\fR\s10\&3\f1\s0" at 24,22 "\fR\s10\&10\f1\s0" at 48,22 "\fR\s10\&17\f1\s0" at 72,22 "\fR\s10\&24\f1\s0" at 100,22 "\fR\s10\&31\f1\s0" at 120,22 line from 24,0 to 24,16 line from 48,0 to 48,16 line from 96,16 to 96,0 line from 200,16 to 200,0 line from 224,16 to 224,0 line from 264,8 to 280,8 line from 288,8 to 272,8 line from 296,8 to 272,8 line from 288,8 to 304,8 line from 256,8 to 664,8 line from 272,8 to 280,8 line from 296,8 to 304,8 line from 280,16 to 280,0 line from 304,16 to 304,0 line from 328,16 to 328,0 line from 384,16 to 384,0 line from 432,16 to 432,0 line from 456,16 to 456,0 line from 560,16 to 560,0 line from 488,16 to 488,0 line from 616,16 to 616,0 line from 664,16 to 664,0 line from 592,16 to 592,0 line from 264,8 to 272,8 line from 152,16 to 152,0 line from 176,16 to 176,0 line from 256,8 to 0,8 line from 0,8 to 0,32 line from 640,0 to 640,16 line from 536,0 to 536,16 line from 512,0 to 512,16 line from 408,0 to 408,16 line from 360,0 to 360,16 line from 256,0 to 256,16 line from 120,0 to 120,16 line from 72,0 to 72,16 "\fR\s10\&7\f1\s0" at 152,22 ] | define m1 | [ box invis ht 872 wid 704 with .sw at 0,0 box ht 24 wid 40 with .nw at 336,352 line from 352,432 to 352,352 dotted line from 344,432 to 352,432 dotted line from 344,480 to 344,464 dotted line from 320,496 to 320,480 dotted t557 with .nw at 279,535 box ht 40 wid 48 with .nw at 296,408 box ht 32 wid 56 with .nw at 232,408 line from 272,432 to 272,408 dotted t558 with .nw at 232,405 line from 112,432 to 112,408 dotted box ht 48 wid 40 with .nw at 336,544 box ht 48 wid 48 with .nw at 280,544 box ht 24 wid 56 with .nw at 200,520 line from 240,464 to 240,496 dotted t559 with .nw at 200,518 t560 with .nw at 97,402 line from 656,432 to 656,408 dotted t561 with .nw at 649,404 line from 576,464 to 576,488 dotted line from 528,432 to 528,408 dotted t562 with .nw at 513,404 line from 608,432 to 608,408 dotted line from 320,432 to 320,408 dotted t563 with .nw at 296,408 t564 with .nw at 584,404 line from 472,432 to 472,408 dotted t565 with .nw at 448,404 t566 with .nw at 544,539 t567 with .nw at 416,539 line from 88,432 to 88,448 "\fR\s10\&7\f1\s0" at 168,454 "\fR\s10\&14\f1\s0" at 188,454 "\fR\s10\&21\f1\s0" at 212,454 "\fR\s10\&28\f1\s0" at 236,454 "\fR\s10\&5\f1\s0" at 272,454 "\fR\s10\&12\f1\s0" at 296,454 "\fR\s10\&19\f1\s0" at 320,454 "\fR\s10\&26\f1\s0" at 344,454 "\fR\s10\&2\f1\s0" at 376,454 "\fR\s10\&9\f1\s0" at 400,454 "\fR\s10\&16\f1\s0" at 424,454 "\fR\s10\&23\f1\s0" at 448,454 "\fR\s10\&30\f1\s0" at 472,454 "\fR\s10\&6\f1\s0" at 504,454 "\fR\s10\&13\f1\s0" at 528,454 "\fR\s10\&20\f1\s0" at 552,454 "\fR\s10\&27\f1\s0" at 576,454 "\fR\s10\&4\f1\s0" at 608,454 "\fR\s10\&11\f1\s0" at 632,454 "\fR\s10\&18\f1\s0" at 656,454 "\fR\s10\&25\f1\s0" at 680,454 "\fR\s10\&3\f1\s0" at 40,454 "\fR\s10\&10\f1\s0" at 64,454 "\fR\s10\&17\f1\s0" at 88,454 "\fR\s10\&24\f1\s0" at 116,454 "\fR\s10\&31\f1\s0" at 136,454 line from 40,432 to 40,448 line from 64,432 to 64,448 line from 112,448 to 112,432 line from 216,448 to 216,432 line from 240,448 to 240,432 line from 280,440 to 296,440 line from 304,440 to 288,440 line from 312,440 to 288,440 line from 304,440 to 320,440 line from 272,440 to 680,440 line from 288,440 to 296,440 line from 312,440 to 320,440 line from 296,448 to 296,432 line from 320,448 to 320,432 line from 344,448 to 344,432 line from 400,448 to 400,432 line from 448,448 to 448,432 line from 472,448 to 472,432 line from 576,448 to 576,432 line from 632,448 to 632,432 line from 680,448 to 680,432 line from 608,448 to 608,432 line from 280,440 to 288,440 line from 168,448 to 168,432 line from 192,448 to 192,432 line from 16,440 to 16,416 line from 272,440 to 16,440 line from 16,440 to 16,464 line from 656,432 to 656,448 line from 552,432 to 552,448 line from 504,432 to 504,448 line from 528,432 to 528,448 line from 424,432 to 424,448 line from 376,432 to 376,448 line from 272,432 to 272,448 line from 136,432 to 136,448 box ht 48 wid 48 with .nw at 584,408 box ht 48 wid 48 with .nw at 448,408 box ht 24 wid 0 with .nw at 704,384 box ht 48 wid 48 with .nw at 648,408 box ht 48 wid 48 with .nw at 512,408 box ht 48 wid 48 with .nw at 368,408 line from 400,432 to 400,408 dotted line from 424,464 to 424,488 dotted box ht 56 wid 40 with .nw at 544,544 box ht 56 wid 40 with .nw at 416,544 t594 with .nw at 373,404 box ht 32 wid 40 with .nw at 96,408 line from 344,480 to 320,480 dotted line from 344,496 to 344,480 dotted t595 with .nw at 335,543 t596 with .nw at 341,350 t597 with .nw at 96,602 t598 with .nw at 232,602 line from 192,656 to 192,640 line from 168,656 to 168,640 line from 112,656 to 112,640 line from 136,656 to 136,640 line from 216,656 to 216,640 line from 320,656 to 320,640 line from 376,656 to 376,640 line from 400,656 to 400,640 line from 552,656 to 552,640 line from 632,656 to 632,640 line from 280,648 to 288,648 line from 608,656 to 608,640 "\fR\s10\&10\f1\s0" at 64,662 "\fR\s10\&3\f1\s0" at 40,662 "\fR\s10\&18\f1\s0" at 656,662 "\fR\s10\&11\f1\s0" at 632,662 "\fR\s10\&4\f1\s0" at 608,662 "\fR\s10\&27\f1\s0" at 576,662 "\fR\s10\&20\f1\s0" at 552,662 "\fR\s10\&13\f1\s0" at 528,662 "\fR\s10\&6\f1\s0" at 504,662 "\fR\s10\&30\f1\s0" at 472,662 "\fR\s10\&23\f1\s0" at 448,662 "\fR\s10\&16\f1\s0" at 424,662 "\fR\s10\&9\f1\s0" at 400,662 "\fR\s10\&2\f1\s0" at 376,662 "\fR\s10\&26\f1\s0" at 344,662 "\fR\s10\&19\f1\s0" at 320,662 "\fR\s10\&12\f1\s0" at 296,662 "\fR\s10\&5\f1\s0" at 272,662 "\fR\s10\&28\f1\s0" at 236,662 "\fR\s10\&21\f1\s0" at 216,662 "\fR\s10\&14\f1\s0" at 188,662 "\fR\s10\&25\f1\s0" at 680,662 "\fR\s10\&7\f1\s0" at 168,662 "\fR\s10\&31\f1\s0" at 136,662 "\fR\s10\&24\f1\s0" at 116,662 "\fR\s10\&17\f1\s0" at 88,662 line from 152,672 to 152,624 line from 256,672 to 256,624 line from 360,672 to 360,624 line from 488,672 to 488,624 line from 592,672 to 592,624 line from 16,672 to 16,624 line from 680,656 to 680,640 box ht 24 wid 40 with .nw at 120,192 box ht 24 wid 32 with .nw at 72,152 line from 88,168 to 88,152 dotted t625 with .nw at 75,150 line from 528,216 to 528,192 dotted t626 with .nw at 412,190 t627 with .nw at 514,192 line from 424,216 to 424,192 dotted t628 with .nw at 347,305 line from 376,248 to 376,272 dotted t629 with .nw at 327,186 line from 344,216 to 344,192 dotted t630 with .nw at 204,185 line from 216,216 to 216,192 dotted t631 with .nw at 152,298 line from 64,216 to 64,192 dotted box ht 40 wid 48 with .nw at 80,312 box ht 32 wid 32 with .nw at 152,304 box ht 40 wid 64 with .nw at 344,312 box ht 40 wid 48 with .nw at 512,192 box ht 24 wid 40 with .nw at 408,192 box ht 32 wid 32 with .nw at 328,192 line from 112,248 to 112,272 dotted line from 168,248 to 168,272 dotted t632 with .nw at 120,190 line from 136,216 to 136,192 dotted t633 with .nw at 85,312 box ht 24 wid 64 with .nw at 40,192 t634 with .nw at 41,190 line from 16,224 to 16,200 box ht 40 wid 40 with .nw at 200,192 m0 with .nw at 16,248 t689 with .nw at 179,59 line from 216,80 to 216,88 dotted line from 216,88 to 216,64 dotted t690 with .nw at 263,60 line from 272,88 to 272,64 dotted t691 with .nw at 46,58 box ht 40 wid 104 with .nw at 40,64 box ht 64 wid 72 with .nw at 264,64 box ht 56 wid 80 with .nw at 176,64 "\fR\s10\&21\f1\s0" at 212,110 "\fR\s10\&28\f1\s0" at 236,110 "\fR\s10\&5\f1\s0" at 272,110 "\fR\s10\&12\f1\s0" at 296,110 "\fR\s10\&19\f1\s0" at 320,110 "\fR\s10\&26\f1\s0" at 344,110 "\fR\s10\&2\f1\s0" at 376,110 "\fR\s10\&9\f1\s0" at 400,110 "\fR\s10\&16\f1\s0" at 424,110 "\fR\s10\&23\f1\s0" at 448,110 "\fR\s10\&30\f1\s0" at 472,110 "\fR\s10\&6\f1\s0" at 504,110 "\fR\s10\&13\f1\s0" at 528,110 "\fR\s10\&20\f1\s0" at 552,110 "\fR\s10\&27\f1\s0" at 576,110 "\fR\s10\&4\f1\s0" at 608,110 "\fR\s10\&11\f1\s0" at 632,110 "\fR\s10\&18\f1\s0" at 656,110 "\fR\s10\&25\f1\s0" at 680,110 "\fR\s10\&3\f1\s0" at 40,110 "\fR\s10\&10\f1\s0" at 64,110 "\fR\s10\&17\f1\s0" at 88,110 "\fR\s10\&24\f1\s0" at 116,110 "\fR\s10\&31\f1\s0" at 136,110 line from 40,88 to 40,104 line from 64,88 to 64,104 line from 112,104 to 112,88 line from 216,104 to 216,88 line from 240,104 to 240,88 line from 280,96 to 296,96 line from 304,96 to 288,96 line from 312,96 to 288,96 line from 304,96 to 320,96 line from 272,96 to 680,96 line from 288,96 to 296,96 line from 312,96 to 320,96 line from 296,104 to 296,88 line from 320,104 to 320,88 line from 344,104 to 344,88 line from 400,104 to 400,88 line from 448,104 to 448,88 line from 472,104 to 472,88 line from 576,104 to 576,88 line from 504,104 to 504,88 line from 632,104 to 632,88 line from 680,104 to 680,88 line from 608,104 to 608,88 line from 280,96 to 288,96 line from 168,104 to 168,88 line from 192,104 to 192,88 line from 272,96 to 16,96 line from 16,72 to 16,120 line from 152,248 to 152,200 line from 256,248 to 256,200 line from 360,248 to 360,200 line from 488,248 to 488,200 line from 592,248 to 592,200 line from 152,120 to 152,72 line from 256,120 to 256,72 line from 360,120 to 360,72 line from 488,120 to 488,72 line from 592,120 to 592,72 line from 152,464 to 152,416 line from 256,464 to 256,416 line from 360,464 to 360,416 line from 488,464 to 488,416 line from 592,464 to 592,416 line from 656,88 to 656,104 line from 552,88 to 552,104 line from 528,88 to 528,104 line from 424,88 to 424,104 line from 376,88 to 376,104 line from 272,88 to 272,104 line from 136,88 to 136,104 line from 88,88 to 88,104 "\fR\s10\&7\f1\s0" at 168,110 "\fR\s10\&14\f1\s0" at 188,110 line from 88,88 to 88,64 dotted line from 64,88 to 64,64 dotted line from 656,656 to 656,640 line from 504,656 to 504,640 line from 576,656 to 576,640 line from 528,656 to 528,640 line from 472,656 to 472,640 line from 448,656 to 448,640 line from 424,656 to 424,640 line from 344,656 to 344,640 line from 296,656 to 296,640 line from 272,656 to 272,640 line from 312,648 to 320,648 line from 288,648 to 296,648 line from 16,648 to 680,648 line from 304,648 to 320,648 line from 312,648 to 288,648 line from 304,648 to 288,648 line from 280,648 to 296,648 line from 240,656 to 240,640 line from 40,640 to 40,656 line from 64,640 to 64,648 line from 64,648 to 64,656 line from 88,640 to 88,656 t481 with .nw at 72,747 "\fR\s7\&P11.0\f1\s0" at 296,709 "\fR\s7\&P10.0\f1\s0" at 184,705 line from 296,696 to 296,672 dotted line from 192,696 to 192,672 dotted line from 40,672 to 40,696 dotted "\fR\s7\&P9.0\f1\s0" at 44,705 line from 296,640 to 296,608 dotted line from 240,640 to 240,608 dotted line from 216,696 to 216,672 dotted t485 with .nw at 208,747 line from 192,640 to 192,608 dotted t486 with .nw at 177,606 t487 with .nw at 26,602 box ht 48 wid 48 with .nw at 176,608 box ht 16 wid 0 with .nw at 224,576 box ht 48 wid 48 with .nw at 96,608 box ht 48 wid 48 with .nw at 24,608 box ht 56 wid 40 with .nw at 208,752 box ht 56 wid 40 with .nw at 72,752 line from 88,672 to 88,696 dotted line from 112,640 to 112,608 dotted line from 40,640 to 40,608 dotted box ht 48 wid 48 with .nw at 288,608 box ht 48 wid 48 with .nw at 232,608 t488 with .nw at 293,602 line from 64,776 to 64,792 line from 112,792 to 112,776 line from 216,792 to 216,776 line from 240,792 to 240,776 line from 280,784 to 296,784 line from 304,784 to 288,784 line from 312,784 to 288,784 line from 304,784 to 320,784 line from 272,784 to 680,784 line from 288,784 to 296,784 line from 312,784 to 320,784 line from 296,792 to 296,776 line from 320,792 to 320,776 line from 344,792 to 344,776 line from 400,792 to 400,776 line from 448,792 to 448,776 line from 472,792 to 472,776 line from 576,792 to 576,776 line from 504,792 to 504,776 line from 632,792 to 632,776 line from 680,792 to 680,776 line from 608,792 to 608,776 line from 280,784 to 288,784 line from 168,792 to 168,776 line from 192,792 to 192,776 line from 16,784 to 16,768 line from 272,784 to 16,784 line from 16,784 to 16,808 line from 656,776 to 656,792 line from 552,776 to 552,792 line from 528,776 to 528,792 line from 424,776 to 424,792 line from 376,776 to 376,792 line from 272,776 to 272,792 line from 136,776 to 136,792 line from 88,776 to 88,792 "\fR\s10\&7\f1\s0" at 168,798 "\fR\s10\&OCT\f1\s0" at 592,862 line from 152,784 to 152,832 line from 256,784 to 256,832 "\fR\s10\&MAY\f1\s0" at 20,862 "\fR\s10\&JUNE\f1\s0" at 152,862 line from 16,848 to 16,856 line from 152,848 to 152,856 line from 256,840 to 256,856 line from 256,840 to 256,848 line from 360,784 to 360,848 line from 256,832 to 256,848 line from 152,832 to 152,848 line from 16,808 to 16,840 line from 16,840 to 16,848 line from 488,784 to 488,856 line from 360,848 to 360,856 line from 592,784 to 592,856 "\fR\s10\&JULY\f1\s0" at 260,862 "\fR\s10\&AUGUST\f1\s0" at 364,862 "\fR\s10\&SEPT\f1\s0" at 492,862 "\fR\s10\&14\f1\s0" at 188,798 "\fR\s10\&21\f1\s0" at 212,798 "\fR\s10\&28\f1\s0" at 236,798 "\fR\s10\&5\f1\s0" at 272,798 "\fR\s10\&12\f1\s0" at 296,798 "\fR\s10\&19\f1\s0" at 320,798 "\fR\s10\&26\f1\s0" at 344,798 "\fR\s10\&2\f1\s0" at 376,798 "\fR\s10\&9\f1\s0" at 400,798 "\fR\s10\&16\f1\s0" at 424,798 "\fR\s10\&23\f1\s0" at 448,798 "\fR\s10\&30\f1\s0" at 472,798 "\fR\s10\&6\f1\s0" at 504,798 "\fR\s10\&13\f1\s0" at 528,798 "\fR\s10\&20\f1\s0" at 552,798 "\fR\s10\&27\f1\s0" at 576,798 "\fR\s10\&4\f1\s0" at 608,798 "\fR\s10\&11\f1\s0" at 632,798 "\fR\s10\&18\f1\s0" at 656,798 "\fR\s10\&25\f1\s0" at 680,798 "\fR\s10\&3\f1\s0" at 40,798 "\fR\s2\&10\f1\s0" at 64,796 "\fR\s10\&17\f1\s0" at 88,798 "\fR\s10\&24\f1\s0" at 116,798 "\fR\s10\&31\f1\s0" at 136,798 line from 40,776 to 40,792 ] | box invis ht 944 wid 704 with .sw at 0,0 m1 with .nw at 0,872 "\fR\s10\&INTEGRATION SCHEDULE\f1\s0" at 216,934 .PE .fi xcip/testsuite/test60000644000175300001440000000740611513632542013376 0ustar meusers.nf .PS scale=100 define t174 | [ box invis ht 46 wid 114 with .sw at 0,0 "\f(CW\s16\&Constant\f1\s0" at 4,34ljust "\f(CW\s16\&Width\f1\s0" at 4,11ljust ] | define t168 | [ box invis ht 50 wid 82 with .sw at 0,0 "\fB\s16\&Roman\f1\s0" at 4,37ljust "\fB\s16\&Bold\f1\s0" at 4,12ljust ] | define t165 | [ box invis ht 50 wid 76 with .sw at 0,0 "\fI\s16\&Roman\f1\s0" at 4,37ljust "\fI\s16\&Itallic\f1\s0" at 4,12ljust ] | define t161 | [ box invis ht 50 wid 119 with .sw at 0,0 "\f(HI\s16\&Helvectica\f1\s0" at 4,37ljust "\f(HI\s16\&Itallic\f1\s0" at 4,12ljust ] | define t158 | [ box invis ht 68 wid 480 with .sw at 0,0 "\f(CW\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,56ljust "\f(CW\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,33ljust "\f(CW\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,10ljust ] | define t154 | [ box invis ht 74 wid 441 with .sw at 0,0 "\fH\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\fH\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\fH\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | define t190 | [ box invis ht 50 wid 120 with .sw at 0,0 "\f(HB\s16\&Helvectica\f1\s0" at 4,37ljust "\f(HB\s16\&Bold\f1\s0" at 4,12ljust ] | define t194 | [ box invis ht 52 wid 86 with .sw at 0,0 "\f(PI\s16\&Palatino\f1\s0" at 4,38ljust "\f(PI\s16\&Itallic\f1\s0" at 4,12ljust ] | define t195 | [ box invis ht 78 wid 445 with .sw at 0,0 "\f(PI\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,64ljust "\f(PI\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,38ljust "\f(PI\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,12ljust ] | define t193 | [ box invis ht 78 wid 439 with .sw at 0,0 "\f(PA\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,64ljust "\f(PA\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,38ljust "\f(PA\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,12ljust ] | define t187 | [ box invis ht 74 wid 455 with .sw at 0,0 "\f(HB\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\f(HB\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\f(HB\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | define t150 | [ box invis ht 74 wid 452 with .sw at 0,0 "\f(HI\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\f(HI\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\f(HI\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | define t186 | [ box invis ht 74 wid 447 with .sw at 0,0 "\fB\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\fB\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\fB\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | define t182 | [ box invis ht 74 wid 453 with .sw at 0,0 "\fI\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\fI\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\fI\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | define t178 | [ box invis ht 74 wid 426 with .sw at 0,0 "\fR\s16\&abcdefghijklmnopqrstuvwxyz\f1\s0" at 4,61ljust "\fR\s16\&ABCDEFGHIJKLMNOPQRSTUVWXYZ\f1\s0" at 4,36ljust "\fR\s16\&0123456789!@#$%^&*()-_=+[]{}\\\\`~'\";:<>,./?\f1\s0" at 4,11ljust ] | box invis ht 765 wid 620 with .sw at 0,0 t174 with .nw at -2,57 "\fR\s16\&Roman\f1\s0" at 3,672 ljust "\fB\s24\&\f1\s0" at 326,682 "\fB\s24\&Fonts\f1\s0" at 275,746 t168 with .nw at -2,538 t165 with .nw at -2,618 "\fH\s16\&Helvectica\f1\s0" at 3,432 ljust t161 with .nw at -2,378 t158 with .nw at 142,68 t154 with .nw at 142,470 t190 with .nw at -2,298 "\f(HB\s14\&\f1\s0" at 35,274 ljust "\f(HB\s10\&\f1\s0" at 27,284 ljust "\f(PA\s16\&Palatino\f1\s0" at 3,191 ljust "\f(PA\s16\&\f1\s0" at 219,183 ljust t194 with .nw at -2,138 t195 with .nw at 142,151 t193 with .nw at 142,231 t187 with .nw at 142,310 t150 with .nw at 142,390 t186 with .nw at 142,550 t182 with .nw at 142,630 t178 with .nw at 142,710 .PE xcip/testsuite/test10000644000175300001440000000174211513632542013366 0ustar meusers.nf .PS scale=100 define t104 | [ box invis ht 48 wid 90 with .sw at 0,0 "\fR\s10\&AFSC\fP\s0" at 45,38 "\fR\s10\&ENTERS\fP\s0" at 45,22 "\fR\s10\&CTR TICKET\fP\s0" at 45,6 ] | define m1 | [ box invis ht 48 wid 48 with .sw at 0,0 circle rad 24 at 24,24 ] | define m0 | [ box invis ht 64 wid 128 with .sw at 0,0 box ht 64 wid 128 with .nw at 0,64 ] | define m2 | [ box invis ht 62 wid 128 with .sw at 0,0 box ht 62 wid 128 with .nw at 0,62 ] | box invis ht 564 wid 128 with .sw at 0,0 "\fH\s12\&2A\fP\s0" at 64,536 circle rad 32 at 64,222 "\fR\s10\&CTR\fP\s0" at 68,216 m1 with .nw at 40,564 m1 with .nw at 40,48 m0 with .nw at 0,460 m0 with .nw at 0,350 m2 with .nw at 0,150 "\fH\s12\&2Z\fP\s0" at 64,20 "\fR\s10\&CWC\fP\s0" at 60,114 t104 with .nw at 15,342 "\fR\s10\&AFSC\fP\s0" at 64,426 line -> from 64,396 to 64,350 line -> from 64,286 to 64,254 line -> from 64,190 to 64,150 line -> from 64,88 to 64,48 "\fR\s10\&Referral\fP\s0" at 96,498 line -> from 64,516 to 64,460 .PE .fi xcip/testsuite/test50000644000175300001440000001616411513632542013376 0ustar meusers.nf .PS scale=100 define t101 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t102 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t117 | [ box invis ht 26 wid 20 with .sw at 0,0 "\fR\s7\&PD\fP\s0" at 10,19 "\fR\s7\&PD\fP\s0" at 10,5 ] | define t118 | [ box invis ht 36 wid 20 with .sw at 0,0 "\fR\s7\&PD\fP\s0" at 10,29 "\fR\s7\&PD\fP\s0" at 10,17 "\fR\s7\&PD\fP\s0" at 10,5 ] | define t119 | [ box invis ht 48 wid 20 with .sw at 0,0 "\fR\s7\&PD\fP\s0" at 10,41 "\fR\s7\&PD\fP\s0" at 10,29 "\fR\s7\&PD\fP\s0" at 10,17 "\fR\s7\&PD\fP\s0" at 10,5 ] | define t120 | [ box invis ht 48 wid 26 with .sw at 0,0 "\fR\s7\&300\fP\s0" at 13,41 "\fR\s7\&MB\fP\s0" at 13,29 "\fR\s7\&\fP\s0" at 13,17 "\fR\s7\&QIC\fP\s0" at 13,5 ] | define t131 | [ box invis ht 50 wid 38 with .sw at 0,0 "\fR\s16\&570\fP\s0" at 19,35 "\fR\s16\&MB\fP\s0" at 19,9 ] | define t132 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t101 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t102 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t136 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t137 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t139 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t141 | [ box invis ht 36 wid 14 with .sw at 0,0 "\fR\s7\&O\fP\s0" at 7,29 "\fR\s7\&L\fP\s0" at 7,17 "\fR\s7\&S\fP\s0" at 7,5 ] | define t142 | [ box invis ht 38 wid 14 with .sw at 0,0 "\fR\s8\&O\fP\s0" at 7,31 "\fR\s8\&L\fP\s0" at 7,18 "\fR\s8\&S\fP\s0" at 7,5 ] | define m22 | [ box invis ht 136 wid 128 with .sw at 0,0 box ht 136 wid 128 with .nw at 0,136 "\fR\s16\&TAPE\fP\s0" at 60,69 ] | define m15 | [ box invis ht 40 wid 128 with .sw at 0,0 t101 with .nw at 113,36 t102 with .nw at 1,36 "\fR\s16\&BCU\fP\s0" at 64,21 box ht 40 wid 128 with .nw at 0,40 line from 112,40 to 112,0 line from 16,40 to 16,0 ] | define m3 | [ box invis ht 304 wid 144 with .sw at 0,0 box ht 304 wid 144 with .nw at 0,304 ] | define m0 | [ box invis ht 40 wid 128 with .sw at 0,0 box ht 40 wid 128 with .nw at 0,40 "\fR\s16\&FAN UNIT\fP\s0" at 64,15 ] | define m23 | [ box invis ht 32 wid 112 with .sw at 0,0 "\fR\s16\&GROWTH\fP\s0" at 58,15 ] | define m21 | [ box invis ht 56 wid 24 with .sw at 0,0 "\fR\s7\&PD\fP\s0" at 12,42 box ht 56 wid 24 with .nw at 0,56 ] | define m20 | [ box invis ht 56 wid 24 with .sw at 0,0 t117 with .nw at 2,51 box ht 56 wid 24 with .nw at 0,56 ] | define m19 | [ box invis ht 56 wid 24 with .sw at 0,0 t118 with .nw at 2,48 box ht 56 wid 24 with .nw at 0,56 ] | define m18 | [ box invis ht 56 wid 24 with .sw at 0,0 t119 with .nw at 2,54 box ht 56 wid 24 with .nw at 0,56 ] | define m1 | [ box invis ht 56 wid 40 with .sw at 0,0 t120 with .nw at 7,54 box ht 56 wid 24 with .nw at 8,56 ] | define m11 | [ box invis ht 64 wid 24 with .sw at 0,0 "\fR\s7\&MB\fP\s0" at 12,37 "\fR\s7\&300\fP\s0" at 12,25 "\fR\s7\&MB\fP\s0" at 12,11 box ht 56 wid 24 with .nw at 0,56 "\fR\s7\&300\fP\s0" at 12,51 ] | define m17 | [ box invis ht 56 wid 24 with .sw at 0,0 box ht 56 wid 24 with .nw at 0,56 "\fR\s7\&300\fP\s0" at 12,49 "\fR\s7\&MB\fP\s0" at 12,37 ] | define m16 | [ box invis ht 56 wid 56 with .sw at 0,0 t131 with .nw at 9,53 box ht 56 wid 56 with .nw at 0,56 ] | define m2 | [ box invis ht 88 wid 128 with .sw at 0,0 t132 with .nw at 1,36 line from 0,40 to 16,40 line from 0,48 to 16,48 box ht 88 wid 128 with .nw at 0,88 line from 16,88 to 16,0 line from 24,88 to 24,0 line from 32,88 to 32,0 line from 40,88 to 40,0 line from 48,88 to 48,0 line from 56,88 to 56,0 line from 64,88 to 64,0 line from 72,88 to 72,0 line from 80,88 to 80,0 line from 88,88 to 88,0 line from 96,88 to 96,0 line from 104,88 to 104,0 line from 112,88 to 112,0 line from 120,88 to 120,0 ] | define m14 | [ box invis ht 40 wid 128 with .sw at 0,0 t136 with .nw at 113,36 t137 with .nw at 1,36 "\fR\s16\&ELBU\fP\s0" at 60,19 box ht 40 wid 128 with .nw at 0,40 line from 112,40 to 112,0 line from 16,40 to 16,0 ] | define m13 | [ box invis ht 40 wid 128 with .sw at 0,0 t139 with .nw at 1,36 box ht 40 wid 128 with .nw at 0,40 line from 16,40 to 16,0 line from 112,40 to 112,0 "\fR\s16\&GCU\fP\s0" at 60,23 t141 with .nw at 113,36 ] | define m12 | [ box invis ht 56 wid 48 with .sw at 0,0 t142 with .nw at 1,45 line from 16,56 to 16,0 line from 32,56 to 32,0 box ht 56 wid 48 with .nw at 0,56 ] | define m4 | [ box invis ht 1 wid 144 with .sw at 0,0 line from 0,1 to 144,1 ] | define m10 | [ box invis ht 88 wid 128 with .sw at 0,0 box ht 88 wid 128 with .nw at 0,88 line from 32,64 to 96,64 line from 96,64 to 96,0 "\fR\s16\&ACP\fP\s0" at 64,41 line from 32,0 to 32,64 ] | define m5 | [ box invis ht 56 wid 24 with .sw at 0,0 "\fR\s7\&B\fP\s0" at 14,35 "\fR\s7\&B\fP\s0" at 14,11 "\fR\s7\&I\fP\s0" at 14,23 "\fR\s7\&D\fP\s0" at 14,47 ] | define m9 | [ box invis ht 96 wid 24 with .sw at 0,0 "\fR\s7\&A\fP\s0" at 10,71 "\fR\s7\&E\fP\s0" at 10,85 "\fR\s7\&S\fP\s0" at 10,7 "\fR\s7\&C\fP\s0" at 10,19 "\fR\s7\&/\fP\s0" at 10,33 "\fR\s7\&P\fP\s0" at 10,45 "\fR\s7\&D\fP\s0" at 10,59 ] | define m8 | [ box invis ht 48 wid 24 with .sw at 0,0 "\fR\s7\&D\fP\s0" at 14,25 "\fR\s7\&P\fP\s0" at 14,11 "\fR\s7\&A\fP\s0" at 14,39 ] | define m6 | [ box invis ht 56 wid 24 with .sw at 0,0 "\fR\s7\&D\fP\s0" at 14,23 "\fR\s7\&A\fP\s0" at 14,35 "\fR\s7\&P\fP\s0" at 14,11 "\fR\s7\&E\fP\s0" at 14,47 ] | define m7 | [ box invis ht 32 wid 48 with .sw at 0,0 "\fR\s16\&SPC\fP\s0" at 26,15 ] | box invis ht 776 wid 752 with .sw at 0,0 m22 with .nw at 8,768 m15 with .nw at 8,568 m3 with .nw at 0,776 m0 with .nw at 8,520 m23 with .nw at 536,312 "\fR\s16\&BASIC\fP\s0" at 68,441 "\fR\s16\&ABUS\fP\s0" at 224,441 "\fR\s16\&DCC\fP\s0" at 380,441 "\fR\s16\&DCC\fP\s0" at 528,441 "\fR\s16\&SPC\fP\s0" at 664,231 "\fR\s16\&MBSPC\fP\s0" at 680,441 "\fR\s16\&GROWTH\fP\s0" at 664,181 "\fR\s16\&\fP\s0" at 664,155 m0 with .nw at 328,216 m22 with .nw at 40,192 m21 with .nw at 392,56 m20 with .nw at 360,56 m19 with .nw at 328,56 m18 with .nw at 296,56 m1 with .nw at 256,56 m11 with .nw at 232,64 m17 with .nw at 200,64 m17 with .nw at 616,536 m17 with .nw at 648,536 m16 with .nw at 288,144 m2 with .nw at 344,376 m15 with .nw at 352,152 m14 with .nw at 472,216 m13 with .nw at 192,216 m12 with .nw at 224,152 m3 with .nw at 608,776 m11 with .nw at 616,680 m11 with .nw at 648,608 m11 with .nw at 616,608 m11 with .nw at 648,680 m3 with .nw at 32,336 m4 with .nw at 608,616 m4 with .nw at 608,544 m4 with .nw at 528,272 m10 with .nw at 496,160 m5 with .nw at 256,400 m5 with .nw at 184,600 m9 with .nw at 280,408 m8 with .nw at 208,400 m6 with .nw at 232,400 m7 with .nw at 672,376 .PE .fi xcip/testsuite/test20000644000175300001440000000024011513632543013360 0ustar meusers.nf .PS scale=100 box invis ht 832 wid 760 with .sw at 0,0 box ht 832 wid 760 with .nw at 0,832 "\fR\s24\&BOX THAT FILLS XCIP SCREEN\fP\s0" at 400,442 .PE .fi xcip/testsuite/test80000644000175300001440000000334211513632542013373 0ustar meusers.nf .PS scale=100 define m2 | [ box invis ht 24 wid 224 with .sw at 0,0 "\fR\s16\&ABCDEFGHIJKLMN\fP\s0" at 112,9 box ht 24 wid 208 with .nw at 8,24 ] | define m1 | [ box invis ht 32 wid 184 with .sw at 0,0 "\fR\s14\&ABCDEFGHIJKLMN\fP\s0" at 92,15 box ht 24 wid 184 with .nw at 0,32 ] | define m6 | [ box invis ht 32 wid 296 with .sw at 0,0 "\fR\s20\&ABCDEFGHIJKLMN\fP\s0" at 148,14 box ht 24 wid 280 with .nw at 8,32 ] | define m5 | [ box invis ht 32 wid 328 with .sw at 0,0 "\fR\s22\&ABCDEFGHIJKLMN\fP\s0" at 164,12 box ht 32 wid 312 with .nw at 8,32 ] | define m4 | [ box invis ht 40 wid 312 with .sw at 0,0 "\fR\s24\&ABCDEFGHIJKLMN\fP\s0" at 156,18 box ht 32 wid 296 with .nw at 8,40 ] | define m7 | [ box invis ht 16 wid 120 with .sw at 0,0 "\fR\s8\&ABCDEFGHIJKLMN\fP\s0" at 60,6 box ht 16 wid 120 with .nw at 0,16 ] | define m0 | [ box invis ht 32 wid 248 with .sw at 0,0 "\fR\s18\&ABCDEFGHIJKLMN\fP\s0" at 124,15 box ht 24 wid 232 with .nw at 8,32 ] | define m8 | [ box invis ht 16 wid 136 with .sw at 0,0 "\fR\s10\&ABCDEFGHIJKLMN\fP\s0" at 68,6 box ht 16 wid 136 with .nw at 0,16 ] | define m3 | [ box invis ht 24 wid 168 with .sw at 0,0 "\fR\s12\&ABCDEFGHIJKLMN\fP\s0" at 84,13 box ht 16 wid 152 with .nw at 8,24 ] | box invis ht 408 wid 384 with .sw at 0,0 m2 with .nw at 96,240 "\fR\s10\&24\fP\s0" at 16,24 "\fR\s10\&12\fP\s0" at 104,324 "\fR\s10\&22\fP\s0" at 16,76 m1 with .nw at 120,288 "\fR\s10\&20\fP\s0" at 28,128 m6 with .nw at 72,144 "\fR\s10\&10\fP\s0" at 112,360 m5 with .nw at 56,96 "\fR\s10\&18\fP\s0" at 56,176 m4 with .nw at 64,40 m7 with .nw at 160,408 m0 with .nw at 88,192 m8 with .nw at 152,368 "\fR\s10\&16\fP\s0" at 68,228 m3 with .nw at 128,328 "\fR\s10\&14\fP\s0" at 88,276 "\fR\s10\&8\fP\s0" at 124,396 .PE .fi xcip/logo.data0000644000175300001440000000316111513632544012144 0ustar meusers500,442,514,410, 388,690,496,440, 462,618,466,608, 382,752,394,752, 466,610,462,602, 284,440,388,690, 462,602,446,594, 512,422,514,410, 394,724,392,722, 392,722,392,718, 452,618,462,618, 282,442,274,422, 394,752,394,724, 432,586,414,578, 384,750,384,726, 440,612,452,618, 384,722,384,718, 384,718,392,718, 364,578,346,592, 408,596,426,604, 382,752,382,724, 414,578,364,578, 382,724,394,724, 384,718,270,446, 212,234,230,248, 76,502,76,508, 14,576,24,560, 222,266,244,214, 38,510,204,252, 74,496,76,502, 0,566,14,576, 246,204,252,194, 6,548,198,248, 48,516,214,260, 38,550,46,540, 44,554,62,536, 22,520,42,540, 236,208,244,214, 204,242,226,258, 244,214,248,206, 0,566,10,550, 12,550,28,524, 20,558,36,534, 28,564,222,266, 84,490,74,492, 38,550,44,554, 62,538,64,530, 62,536,86,490, 52,546,62,538, 32,506,54,522, 224,222,236,230, 218,228,234,240, 198,248,236,208, 236,208,244,202, 244,202,250,206, 198,248,222,266, 6,548,28,564, 744,104,744,0, 216,104,216,80, 656,104,656,80, 480,104,480,80, 304,104,304,80, 568,104,568,80, 128,104,128,80, 40,104,40,0, 392,104,392,80, 40,104,744,104, 744,0,40,0, 532,230,540,226, 554,264,562,260, 584,230,710,230, 598,338,608,332, 660,440,670,434, 700,502,710,496, 638,404,648,398, 504,188,754,592, 710,434,710,230, 718,534,728,528, 618,370,626,366, 754,188,504,188, 576,302,586,296, 680,470,690,464, 754,592,754,188, 710,434,584,230, 276,426,264,410, 274,444,266,426, 266,426,264,410, 272,446,286,440, 496,440,510,446, 390,750,390,726, 354,606,368,596, 392,718,510,446, 368,596,408,596, 504,442,512,422, 382,724,384,722, xcip/menus.c0000644000175300001440000011602111513632542011642 0ustar meusers#include "cip.h" #ifdef X11 # include "menu.h" #else /* X11 */ # ifdef DMD630 # include # endif # ifdef DMD5620 # include "tmenuhit.h" # include # endif #endif /* X11 */ extern int currentBrush; extern int copyFlag; extern int thingSelected; extern int editDepth; extern int gridState; extern int videoState; extern int buttonState; extern short fontBells; extern short noSpace; extern struct macro * macroList; extern Rectangle brushes[]; extern struct thing * Transform(); extern struct thing * undo(); extern void undo_clear(); extern Point jString(); extern void getKbdChar(); extern void printSpace(); extern void printPWD(); extern void printChgStatus(); #ifdef DMDTERM /**** TITEM STRUCTURES ****/ /* Basic Titem structure with only text field. */ typedef struct BasicItem { char * text; /* string for menu */ } BasicItem; /* Checkmark Titem structure with text and icon fields. */ typedef struct ChkmarkItem { char * text; /* string for menu */ Bitmap * icon; /* pointer to the icons bitmap */ } ChkmarkItem; /* Top menu Titem structure with text and next fields. */ typedef struct TopMenuItem { char * text; /* string for menu */ Tmenu * next; /* pointer to sub-menu */ } TopMenuItem; #ifdef HELPSCALE /* Mid-level menu Titem structure with text, icon, and sub-menu fields. */ typedef struct MidMenuChkmarkItem { char * text; /* string for menu */ Tmenu * next; /* pointer to sub-menu */ Bitmap * icon; /* pointer to the icons bitmap */ } MidMenuChkmarkItem; #endif /* HELPSCALE */ #endif /* DMDTERM */ /**** MENU RELATED FUNCTIONS ****/ /* Set a checkmark in specified menu at specified index and clearing checkmarks off all other items in menu. */ #ifdef X11 void setChkmark( tmenu, index ) NMenu * tmenu; short index; { register NMitem * ci; register int i; ci = tmenu->item; for( i=0; ci->text != NULL; ci++, i++ ) { ci->selected = (i==index) ? 1 : 0 ; } } #else /* X11 */ void setChkmark( tmenu, index ) Tmenu * tmenu; short index; { register ChkmarkItem * ci; register int i; ci = (ChkmarkItem *) tmenu->item; for( i=0; ci->text != NULL; ci++, i++ ) { ci->icon = (i==index) ? &B_checkmark : 0 ; } } #ifdef HELPSCALE void setChkmarkMidmenu( tmenu, index ) Tmenu * tmenu; short index; { register MidMenuChkmarkItem * ci; register int i; ci = (MidMenuChkmarkItem *) tmenu->item; for( i=0; ci->text != NULL; ci++, i++ ) { ci->icon = (i==index) ? &B_checkmark : 0 ; } } #endif /* HELPSCALE */ #endif /* X11 */ /* Returns index in the menu of the selected item (starting at 0). */ int indexHit( tmenu) #ifdef X11 NMenu * tmenu; #else /* X11 */ Tmenu * tmenu; #endif /* X11 */ { return tmenu->prevhit + tmenu->prevtop ; } /**** Point size menu ****/ int pointSizes[] = { 2,3,4,5,6,7,8,9,10,11,12,14,16,18,20,22,24 }; #ifdef X11 NMitem psText[] = { "2\240","",0,0,0,0,0,0, "3\240","",0,0,0,0,0,0, "4\240","",0,0,0,0,0,0, "5\240","",0,0,0,0,0,0, "6\240","",0,0,0,0,0,0, "7\240","",0,0,0,0,0,0, "8\240","",0,0,0,0,0,0, "9\240","",0,0,0,0,0,0, "10\240","",0,0,0,0,0,0, "11\240","",0,0,0,0,0,0, "12\240","",0,0,0,0,0,0, "14\240","",0,0,0,0,0,0, "16\240","",0,0,0,0,0,0, "18\240","",0,0,0,0,0,0, "20\240","",0,0,0,0,0,0, "22\240","",0,0,0,0,0,0, "24\240","",0,0,0,0,0,0, 0 }; NMenu psMenu = { psText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem psText[] = { "2\240", 0, "3\240", 0, "4\240", 0, "5\240", 0, "6\240", 0, "7\240", 0, "8\240", 0, "9\240", 0, "10\240", 0, "11\240", 0, "12\240", 0, "14\240", 0, "16\240", 0, "18\240", 0, "20\240", 0, "22\240", 0, "24\240", 0, 0 }; Tmenu psMenu = { (Titem *) psText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ /* Convert from point size to index into menu. */ int psIndex( ps ) int ps; { register int i; for( i=0; pointSizes[i] < ps; i++ ) ; return i; } #define indexPS(i) (pointSizes[i]) /**** Font menu (Order must agree with constants found in cip.h) ****/ #ifdef X11 NMitem fontText[] = { "Roman\240", "",0,0,0,0,0,0, " Italic\240", "",0,0,0,0,0,0, " Bold\240", "",0,0,0,0,0,0, "Helvetica\240", "",0,0,0,0,0,0, " Italic\240", "",0,0,0,0,0,0, " Bold\240", "",0,0,0,0,0,0, "Palatino\240", "",0,0,0,0,0,0, " Italic\240", "",0,0,0,0,0,0, " Bold\240", "",0,0,0,0,0,0, "Expanded\240", "",0,0,0,0,0,0, " Italic\240", "",0,0,0,0,0,0, " Bold\240", "",0,0,0,0,0,0, "Constant width ", "",0,0,0,0,0,0, 0 }; NMenu fontMenu = { fontText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem fontText[] = { "Roman\240", 0, " Italic\240", 0, " Bold\240", 0, "Helvetica\240", 0, " Italic\240", 0, " Bold\240", 0, "Palatino\240", 0, " Italic\240", 0, " Bold\240", 0, "Expanded\240", 0, " Italic\240", 0, " Bold\240", 0, "Constant width ", 0, 0 }; Tmenu fontMenu = { (Titem *) fontText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ /* Convert from font num to index into menu. */ #define fontIndex(num) ((num)-1) #define indexFont(i) ((i)+1) /**** Justification menu (Order must agree with constants in cip.h) ****/ #ifdef X11 NMitem justText[] = { "Left\240", "",0,0,0,0,0,0, "Center\240", "",0,0,0,0,0,0, "Right\240", "",0,0,0,0,0,0, 0 }; NMenu justMenu = { justText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem justText[] = { "Left\240", 0, "Center\240", 0, "Right\240", 0, 0 }; Tmenu justMenu = { (Titem *) justText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #define justIndex(just) (just) #define indexJust(i) (i) /**** Space menu ****/ #ifdef X11 NMitem spaceText[] = { "-4\240", "",0,0,0,0,0,0, "-3\240", "",0,0,0,0,0,0, "-2\240", "",0,0,0,0,0,0, "-1\240", "",0,0,0,0,0,0, "Normal\240", "",0,0,0,0,0,0, "+1\240", "",0,0,0,0,0,0, "+2\240", "",0,0,0,0,0,0, "+3\240", "",0,0,0,0,0,0, "+4\240", "",0,0,0,0,0,0, "+5\240", "",0,0,0,0,0,0, "+6\240", "",0,0,0,0,0,0, "+7\240", "",0,0,0,0,0,0, "+8\240", "",0,0,0,0,0,0, "+9\240", "",0,0,0,0,0,0, "+10\240", "",0,0,0,0,0,0, "+11\240", "",0,0,0,0,0,0, "+12\240", "",0,0,0,0,0,0, "+13\240", "",0,0,0,0,0,0, "+14\240", "",0,0,0,0,0,0, "+15\240", "",0,0,0,0,0,0, "+16\240", "",0,0,0,0,0,0, "+17\240", "",0,0,0,0,0,0, "+18\240", "",0,0,0,0,0,0, "+19\240", "",0,0,0,0,0,0, "+20\240", "",0,0,0,0,0,0, "+21\240", "",0,0,0,0,0,0, "+22\240", "",0,0,0,0,0,0, "+23\240", "",0,0,0,0,0,0, "+24\240", "",0,0,0,0,0,0, "+25\240", "",0,0,0,0,0,0, "+26\240", "",0,0,0,0,0,0, 0 }; NMenu spacingMenu = { spaceText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem spaceText[] = { "-4\240", 0, "-3\240", 0, "-2\240", 0, "-1\240", 0, "Normal\240", 0, "+1\240", 0, "+2\240", 0, "+3\240", 0, "+4\240", 0, "+5\240", 0, "+6\240", 0, "+7\240", 0, "+8\240", 0, "+9\240", 0, "+10\240", 0, "+11\240", 0, "+12\240", 0, "+13\240", 0, "+14\240", 0, "+15\240", 0, "+16\240", 0, "+17\240", 0, "+18\240", 0, "+19\240", 0, "+20\240", 0, "+21\240", 0, "+22\240", 0, "+23\240", 0, "+24\240", 0, "+25\240", 0, "+26\240", 0, 0 }; Tmenu spacingMenu = { (Titem *)spaceText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #define spaceMin -4 #define spaceMax 26 #define spacingIndex(sp) ((sp)+4) #define indexSpacing(i) ((i)-4) /**** Density menu ****/ #ifdef X11 NMitem densityText[] = { "Solid\240", "",0,0,0,0,0,0, "Dashed\240", "",0,0,0,0,0,0, "Dotted\240", "",0,0,0,0,0,0, 0 }; NMenu densityMenu = { densityText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem densityText[] = { "Solid\240", 0, "Dashed\240", 0, "Dotted\240", 0, 0 }; Tmenu densityMenu = { (Titem *) densityText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #define densityIndex(den) (den) #define indexDensity(i) (i) /**** Arrow menu ****/ #ifdef X11 NMitem arrowText[] = { "No arrows\240", "",0,0,0,0,0,0, "Start end\240", "",0,0,0,0,0,0, "Finish end\240", "",0,0,0,0,0,0, "Both ends\240", "",0,0,0,0,0,0, 0 }; NMenu arrowMenu = { arrowText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem arrowText[] = { "No arrows\240", 0, "Start end\240", 0, "Finish end\240", 0, "Both ends\240", 0, 0 }; Tmenu arrowMenu = { (Titem *) arrowText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #define arrowIndex(a) (a) #define indexArrow(i) (i) /**** Grid menu ****/ #ifdef FINEALIGN int gridLevels[] = { 0,-1,4,5,6,7,8,9,10,11,12,13,14,15,16 }; #endif #ifdef X11 NMitem gridText[] = { #ifdef FINEALIGN "Off\240", "",0,0,0,0,0,0, "Follow Alignment\240", "",0,0,0,0,0,0, "4\240", "",0,0,0,0,0,0, "5\240", "",0,0,0,0,0,0, "6\240", "",0,0,0,0,0,0, "7\240", "",0,0,0,0,0,0, "8\240", "",0,0,0,0,0,0, "9\240", "",0,0,0,0,0,0, "10\240", "",0,0,0,0,0,0, "11\240", "",0,0,0,0,0,0, "12\240", "",0,0,0,0,0,0, "13\240", "",0,0,0,0,0,0, "14\240", "",0,0,0,0,0,0, "15\240", "",0,0,0,0,0,0, "16\240", "",0,0,0,0,0,0, 0 #else /* FINEALIGN */ "Off\240", "",0,0,0,0,0,0, "On\240", "",0,0,0,0,0,0, 0 #endif /* FINEALIGN */ }; NMenu gridMenu = { gridText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem gridText[] = { #ifdef FINEALIGN "Off\240", 0, "Follow Alignment\240", 0, "4\240", 0, "5\240", 0, "6\240", 0, "7\240", 0, "8\240", 0, "9\240", 0, "10\240", 0, "11\240", 0, "12\240", 0, "13\240", 0, "14\240", 0, "15\240", 0, "16\240", 0, 0 #else /* FINEALIGN */ "Off\240", 0, "On\240", 0, 0 #endif /* FINEALIGN */ }; Tmenu gridMenu = { (Titem *) gridText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #ifdef FINEALIGN /* Convert from gridSize to index into menu. */ int gridIndex( g ) int g; { register int i; /* Special case for currGridsize < 0 (follow alignment) */ if ( g < 0 ) { return 1; } for( i=0; gridLevels[i] < g; i++ ) ; return i; } #define indexGrid(i) (gridLevels[(i)]) #else /* FINEALIGN */ #define gridIndex(a) (a) #define indexGrid(i) (i) #endif /* FINEALIGN */ /**** Alignment menu ****/ #ifdef FINEALIGN int alignLevels[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; #else int alignLevels[] = { 2,8,16 }; #endif #ifdef X11 NMitem alignText[] = { #ifdef FINEALIGN "1\240", "",0,0,0,0,0,0, "2 (fine)\240", "",0,0,0,0,0,0, "3\240", "",0,0,0,0,0,0, "4\240", "",0,0,0,0,0,0, "5\240", "",0,0,0,0,0,0, "6\240", "",0,0,0,0,0,0, "7\240", "",0,0,0,0,0,0, "8 (medium)\240", "",0,0,0,0,0,0, "9\240", "",0,0,0,0,0,0, "10\240", "",0,0,0,0,0,0, "11\240", "",0,0,0,0,0,0, "12\240", "",0,0,0,0,0,0, "13\240", "",0,0,0,0,0,0, "14\240", "",0,0,0,0,0,0, "15\240", "",0,0,0,0,0,0, "16 (coarse)\240", "",0,0,0,0,0,0, 0 #else /* FINEALIGN */ "fine (2)\240", "",0,0,0,0,0,0, "medium (8)\240", "",0,0,0,0,0,0, "coarse (16)\240", "",0,0,0,0,0,0, 0 #endif /* FINEALIGN */ }; NMenu alignMenu = { alignText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem alignText[] = { #ifdef FINEALIGN "1\240", 0, "2 (fine)\240", 0, "3\240", 0, "4\240", 0, "5\240", 0, "6\240", 0, "7\240", 0, "8 (medium)\240", 0, "9\240", 0, "10\240", 0, "11\240", 0, "12\240", 0, "13\240", 0, "14\240", 0, "15\240", 0, "16 (coarse)\240", 0, 0 #else /* FINEALIGN */ "fine (2)\240", 0, "medium (8)\240", 0, "coarse (16)\240", 0, 0 #endif /* FINEALIGN */ }; Tmenu alignMenu = { (Titem *)alignText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ /* Convert from point size to index into menu. */ int alignIndex( a ) int a; { register int i; for( i=0; alignLevels[i] < a; i++ ) ; return i; } #define indexAlign(i) (alignLevels[i]) #ifdef HELPSCALE /**** Display Scale Menu ****/ /* * The order of the entries in this menu must be kept in sync * with the defines in cip.h . */ #ifdef X11 NMitem labelText[] = { "none\240", "",0,0,0,0,0,0, "inches\240", "",0,0,0,0,0,0, "feet and inches\240", "",0,0,0,0,0,0, "feet\240", "",0,0,0,0,0,0, "yards\240", "",0,0,0,0,0,0, "miles\240", "",0,0,0,0,0,0, "millimeters\240", "",0,0,0,0,0,0, "meters\240", "",0,0,0,0,0,0, "kilometers\240", "",0,0,0,0,0,0, 0 }; NMenu labelMenu = { labelText, 0, 0, 0 }; #else /* X11 */ ChkmarkItem labelText[] = { "none\240", 0, "inches\240", 0, "feet and inches\240", 0, "feet\240", 0, "yards\240", 0, "miles\240", 0, "millimeters\240", 0, "meters\240", 0, "kilometers\240", 0, 0 }; Tmenu labelMenu = { (Titem *)labelText, 0, 0, 0, TM_TEXT | TM_ICON }; #endif /* X11 */ #ifdef X11 NMitem scaleText[] = { "Off\240", "",0,0,0,0,0,0, "Scale Factor Only\240", "",0,0,0,0,0,0, "Label Only\240", "",0,0,0,0,0,0, "Both On\240", "",0,0,0,0,0,0, "Set Scale Factor\240", "",0,0,0,0,0,0, "Set Label\240", "",0,&labelMenu,0,0,0,0, 0 }; NMenu scaleMenu = { scaleText, 0, 0, 0 }; #else /* X11 */ MidMenuChkmarkItem scaleText[] = { "Off\240", 0,0, "Scale Factor Only\240", 0,0, "Label Only\240", 0,0, "Both On\240", 0,0, "Set Scale Factor\240", 0,0, "Set Label\240", &labelMenu,0, 0 }; Tmenu scaleMenu = { (Titem *)scaleText, 0, 0, 0, TM_TEXT|TM_ICON|TM_NEXT }; #endif /* X11 */ /* Convert from scale to index into menu. */ #define scaleIndex(a) (a) #define indexScale(i) (i) #define labelIndex(a) (a) #define indexLabel(i) (i) #endif /* HELPSCALE */ /**** Line menu ****/ #ifdef X11 NMitem lineText[] = { "Density\240", "",0,&densityMenu,0,0,0,0, "Arrow\240", "",0,0,0,0,0,0, "Reflect x\240", "",0,0,0,0,0,0, "Reflect y\240", "",0,0,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu lineMenu = { lineText, 0, 0, 0 }; #else /* X11 */ TopMenuItem lineText[] = { "Density\240", &densityMenu, "Arrow\240", 0, "Reflect x\240", 0, "Reflect y\240", 0, "Copy\240", 0, "Delete\240", 0, 0 }; Tmenu lineMenu = { (Titem *)lineText, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ /**** Global line menu ****/ #ifdef X11 NMitem gLineText[] = { "Density\240", "",0,&densityMenu,0,0,0,0, "Arrows\240", "",0,&arrowMenu,0,0,0,0, 0 }; NMenu gLineMenu = { gLineText, 0, 0, 0 }; #else /* X11 */ TopMenuItem gLineText[] = { "Density\240", &densityMenu, "Arrows\240", &arrowMenu, 0 }; Tmenu gLineMenu = { (Titem *)gLineText, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ /**** Box menu ****/ #ifdef X11 NMitem boxText[] = { "Density\240", "",0,&densityMenu,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu boxMenu = { boxText, 0, 0, 0 }; #else /* X11 */ TopMenuItem boxText[] = { "Density\240", &densityMenu, "Copy\240", 0, "Delete\240", 0, 0 }; Tmenu boxMenu = { (Titem *)boxText, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ /**** Circle menu ****/ #ifdef X11 NMitem circleText[] = { "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu circleMenu = { circleText, 0, 0, 0 }; #else /* X11 */ BasicItem circleText[] = { "Copy\240", "Delete\240", 0 }; Tmenu circleMenu = { (Titem *)circleText, 0, 0, 0, TM_TEXT }; #endif /* X11 */ /**** Spline menu ****/ #ifdef X11 NMitem splineText[] = { "Arrow\240", "",0,0,0,0,0,0, "Reflect x\240", "",0,0,0,0,0,0, "Reflect y\240", "",0,0,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu splineMenu = { splineText, 0, 0, 0 }; #else /* X11 */ BasicItem splineText[] = { "Arrow\240", "Reflect x\240", "Reflect y\240", "Copy\240", "Delete\240", 0 }; Tmenu splineMenu = { (Titem *)splineText, 0, 0, 0, TM_TEXT }; #endif /* X11 */ /**** Arc menu ****/ #ifdef X11 NMitem arcText[] = { "Reflect x\240", "",0,0,0,0,0,0, "Reflect y\240", "",0,0,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu arcMenu = { arcText, 0, 0, 0 }; #else /* X11 */ BasicItem arcText[] = { "Reflect x\240", "Reflect y\240", "Copy\240", "Delete\240", 0 }; Tmenu arcMenu = { (Titem *)arcText, 0, 0, 0, TM_TEXT }; #endif /* X11 */ /**** Macro menu ****/ #ifdef X11 NMitem macroText[] = { "Edit\240", "",0,0,0,0,0,0, "Separate\240", "",0,0,0,0,0,0, "Reflect x\240", "",0,0,0,0,0,0, "Reflect y\240", "",0,0,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu macroMenu = { macroText, 0, 0, 0 }; #else /* X11 */ BasicItem macroText[] = { "Edit\240", "Separate\240", "Reflect x\240", "Reflect y\240", "Copy\240", "Delete\240", 0 }; Tmenu macroMenu = { (Titem *)macroText, 0, 0, 0, TM_TEXT }; #endif /* X11 */ /**** Text object menu ****/ #ifdef X11 NMitem textText[] = { "Point size\240", "",0,&psMenu,0,0,0,0, "Font style\240", "",0,&fontMenu,0,0,0,0, "Justify\240", "",0,&justMenu,0,0,0,0, "Spacing\240", "",0,&spacingMenu,0,0,0,0, "Separate\240", "",0,0,0,0,0,0, "Copy\240", "",0,0,0,0,0,0, "Delete\240", "",0,0,0,0,0,0, 0 }; NMenu textMenu = { textText, 0, 0, 0 }; #else /* X11 */ TopMenuItem textText[] = { "Point size\240", &psMenu, "Font style\240", &fontMenu, "Justify\240", &justMenu, "Spacing\240", &spacingMenu, "Separate\240", 0, "Copy\240", 0, "Delete\240", 0, 0 }; Tmenu textMenu = { (Titem *) textText, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ /**** Global TEXT menu ****/ #ifdef X11 NMitem gTextData[] = { "Point size\240", "",0,&psMenu,0,0,0,0, "Font style\240", "",0,&fontMenu,0,0,0,0, "Justify\240", "",0,&justMenu,0,0,0,0, "Spacing\240", "",0,&spacingMenu,0,0,0,0, 0 }; NMenu gTextMenu = { gTextData, 0, 0, 0 }; #else /* X11 */ TopMenuItem gTextData[] = { "Point size\240", &psMenu, "Font style\240", &fontMenu, "Justify\240", &justMenu, "Spacing\240", &spacingMenu, 0 }; Tmenu gTextMenu = { (Titem *) gTextData, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ /**** Command menu ****/ #define GET 0 #define PUT 1 #define CLEAR 2 #define REDRAW 3 #define DEFINEMACRO 4 #define UNDO 5 #define GRIDTOGGLE 6 #define ALIGNMENT 7 #define XCIPINFO 8 #define XCIPVERS 9 #ifdef HELPSCALE # define DISPSCALE 10 # ifndef X11 # define ORIGWINDOW 11 # else /* X11 */ # define QUIT 11 # endif /* X11 */ #else /* HELPSCALE */ # ifndef X11 # define ORIGWINDOW 10 # else /* X11 */ # define QUIT 10 # endif /* X11 */ #endif /* HELPSCALE */ #ifdef X11 NMitem commandText[] = { "Get file\240", "",0,0,0,0,0,0, "Put file\240", "",0,0,0,0,0,0, "Clear screen\240", "",0,0,0,0,0,0, "Redraw screen\240", "",0,0,0,0,0,0, "Define macro\240", "",0,0,0,0,0,0, "Undo\240", "",0,0,0,0,0,0, "Grid\240", "",0,&gridMenu,0,0,0,0, "Alignment\240", "",0,&alignMenu,0,0,0,0, "Information\240", "",0,0,0,0,0,0, "Version\240", "",0,0,0,0,0,0, #ifdef HELPSCALE "Display Scale\240", "",0,&scaleMenu,0,0,0,0, #endif /* HELPSCALE */ "Quit\240", "",0,0,0,0,0,0, 0 }; NMenu commandMenu = { commandText, 0, 0, 0 }; #else /* X11 */ TopMenuItem commandText[] = { "Get file\240", 0, "Put file\240", 0, "Clear screen\240", 0, "Redraw screen\240", 0, "Define macro\240", 0, "Undo\240", 0, "Grid\240", &gridMenu, "Alignment\240", &alignMenu, "Information\240", 0, "Version\240", 0, #ifdef HELPSCALE "Display Scale\240", &scaleMenu, #endif /* HELPSCALE */ "Close window\240", 0, 0 }; Tmenu commandMenu = { (Titem *)commandText, 0, 0, 0, TM_TEXT|TM_NEXT }; #endif /* X11 */ struct thing * reflect(t, p, axis) register struct thing * t; Point p; /* Offset */ char axis; /* Either 'x' or 'y' */ { struct thing * h; drawSelectionLines (t, p); draw (t, p); h = (axis == 'x') ? Transform (t, Pt(0, t->bb.corner.y+t->bb.origin.y)) : Transform (t, Pt(t->bb.corner.x+t->bb.origin.x, 0)); draw (t, p); drawSelectionLines (t, p); return (h); } void copyOperation() { if( !noSpace ) { copyFlag = 1; changeButtons( COPYbuttons ); } } struct thing * deleteOperation(t,p) struct thing * t; Point p; /* Offset */ { drawSelectionLines(t,p); draw(t, p); t = deleteThing(t); thingSelected = 0; copyFlag = 0; changeButtons( INITbuttons ); return( t ); } struct thing * separateLineText(t,p) struct thing * t; Point p; { register int lp; register int i; register int q; char * ls; char * s; char * ss; struct thing * nt; struct thing * h; Font * f; int ncr = 0; /* number of carriage returns */ int start = 0; draw(t,p); /* erase present text */ h = t; f = t->otherValues.text.f->f; ls = t->otherValues.text.s; for(i=0;ls[i]!='\0';i++) { if(ls[i] == '\r') ncr++; } lp = -( ((fontheight(f)+t->otherValues.text.spacing)*ncr) >> 1 ); for(i = 0; i <= ncr; i++) { for(q = start; (ls[q] != '\r') && (ls[q] != '\0'); q++) ; if ( (ss=getSpace(q-start+1)) != NULL ) { s = ss; for(q = start; (ls[q] != '\r') && (ls[q] != '\0'); q++) *s++ = ls[q]; *s='\0'; } nt = newText( Pt(t->origin.x, (t->origin.y + lp) ), ss); nt->otherValues.text.f = findFont(t->otherValues.text.f->ps, t->otherValues.text.f->num); nt->otherValues.text.just = t->otherValues.text.just; boundingBox(nt); draw(nt,p); h = insert(nt,h); start = q + 1; lp = lp + fontheight(f) + t->otherValues.text.spacing; } thingSelected = 0; changeButtons( INITbuttons ); return( deleteThing(t) ); } struct thing * displayThingMenu(m,ta,p) Point m; /* Mouse location */ Point p; /* Offset */ struct thing ** ta; /* address of thing to be displayed */ { register struct thing * t; register short item; register int b; int oldED; register struct thing * pts; register struct thing * h; register struct thing * g; struct thing * f; struct macro * mac; Rectangle r; #ifdef X11 NMitem * ti; #else /* X11 */ Titem * ti; #endif /* X11 */ t = *ta; switch(t->type) { case LINE: setChkmark( &densityMenu, densityIndex(t->border) ); #ifdef X11 ti = hmenuhit( &lineMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( &lineMenu, 3, TM_EXPAND ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( indexHit(&lineMenu) ) { case 0: /* Density */ draw(t,p); t->border = indexDensity( indexHit(&densityMenu) ); draw(t,p); break; case 1: /* Arrow - add or remove arrowheads */ draw(t,p); if (distance(m,t->origin) < distance(m,t->otherValues.end)) { if ((t->arrow==startARROW)|| (t->arrow==doubleARROW)) { t->arrow -= startARROW; } else { t->arrow += startARROW; } } else { if ((t->arrow==endARROW)|| (t->arrow==doubleARROW)) { t->arrow -= endARROW; } else { t->arrow += endARROW; } } draw(t,p); break; case 2: /* Reflect x */ t = reflect(t, p, 'x'); break; case 3: /* Reflect y */ t = reflect(t, p, 'y'); break; case 4: /* Copy */ copyOperation(); break; case 5: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; case BOX: setChkmark( &densityMenu, densityIndex(t->border) ); #ifdef X11 ti = hmenuhit( &boxMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( &boxMenu, 3, TM_EXPAND ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( indexHit(&boxMenu) ) { case 0: /* Density */ draw(t,p); t->border = indexDensity( indexHit(&densityMenu) ); draw(t,p); break; case 1: /* Copy */ copyOperation(); break; case 2: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; case MACRO: #ifdef X11 ti = hmenuhit( ¯oMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( ¯oMenu, 3, 0 ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( item = indexHit(¯oMenu) ) { case 0: /* edit macro */ oldED = editDepth; pts = t->otherValues.list->parts; /* Draw edit button when editDepth==1, other times */ /* undraw button. */ if ((editDepth)!=0) { drawEDbutton(editDepth); } drawEDbutton(++editDepth); changeButtons (INITbuttons); thingSelected = 0; p = sub( p, add( drawOffset, scrollOffset ) ); while (editDepth>oldED) { pts = doMouseButtons(pts, add(p,t->origin) ); #ifdef X11 /* nap(2); */ #endif /* X11 */ } p = add( p, add( drawOffset, scrollOffset) ); t->otherValues.list->parts = pts; if (pts != TNULL) { r = macroBB(pts); /* get outline */ /* Origin is offset by new r.origin */ t->origin = add( t->origin, r.origin ); /* Offset all parts by new r.origin */ g = pts; do { makeRelative(g,r.origin); g = g->next; } while (g != pts); /* Set list->bb such that its origin is 0 */ t->otherValues.list->bb = rsubp( r, r.origin); boundingBox( t ); undo_clear(); } else { /* Macro is now empty - delete all references. */ undo_clear(); /* Make certain macro is not in undo list. */ mac = t->otherValues.list; while(1) { if( t->type == MACRO ) { if( t->otherValues.list == mac ) { /* Must be very careful here. The macro node itself is deleted on the last reference. */ if( mac->useCount <= 1 ) { /* Last reference - delete and then leave loop. */ t = deleteThing( t ); break; } else { t = deleteThing( t ); } } else { t = t->next; } } else { t = t->next; } #ifndef X11 sw(1); #endif } *ta = TNULL; } doRedraw(); break; case 1: /* separate */ if (firstThing == t) { firstThing = t->next; if (firstThing == t) { firstThing = TNULL; } } h = Remove(t); /* Cut macro from thing list */ t->otherValues.list->useCount--; m = sub(Pt(0,0),t->origin); /* Go thru macro's thing list and make everything relative */ if ((g=t->otherValues.list->parts)!=TNULL) { if (t->otherValues.list->useCount > 0) { do { /* Copy list */ g = g->next; /* Only arcs are not copied at their origins. */ f = copyThing (g, (g->type == ARC) ? g->otherValues.arc.start : g->origin, Pt(0,0), 0); /* 0: object wont be drawn */ f = makeRelative (f, m); h = insert (f, h); } while (g != t->otherValues.list->parts); } else { do{ /* Move list */ g = g->next; g = makeRelative(g,m); f = g; g = Remove (f); h = insert (f, h); } while (g != TNULL); removeMacro (t->otherValues.list); } } thingSelected = 0; copyFlag = 0; changeButtons(INITbuttons); free(t); /* Remove macro thing */ *ta = TNULL; if (firstThing == TNULL) { firstThing = h; } t = h; undo_clear(); break; case 2: /* Reflect x */ case 3: /* Reflect y */ draw (t, p); if ((g = t->otherValues.list->parts) != TNULL) { r = t->otherValues.list->bb; do { h = (item == 2) ? Transform(g,Pt(0,r.origin.y+r.corner.y)) : Transform(g,Pt(r.origin.x+r.corner.x,0)); g = g->next; } while (g != t->otherValues.list->parts); } if (editDepth) { /* Only draw if not at level 0 */ draw (t, p); } else { /* otherwise, redraw entire screen. */ doRedraw(); } break; case 4: /* Copy */ copyOperation(); break; case 5: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; case TEXT: setChkmark( &psMenu, psIndex(t->otherValues.text.f->ps) ); setChkmark( &fontMenu, fontIndex(t->otherValues.text.f->num) ); setChkmark( &justMenu, justIndex(t->otherValues.text.just) ); setChkmark( &spacingMenu, spacingIndex(t->otherValues.text.spacing) ); #ifdef X11 ti = hmenuhit( &textMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &textMenu, 3, TM_EXPAND ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; switch( indexHit( &textMenu ) ) { case 0: /* point size */ draw(t,p); /* erase thing */ t->otherValues.text.f->useCount--; t->otherValues.text.f = findFont(indexPS(indexHit(&psMenu)), t->otherValues.text.f->num); boundingBox(t); draw(t,p); break; case 1: /* font style */ draw(t,p); t->otherValues.text.f->useCount--; t->otherValues.text.f = findFont(t->otherValues.text.f->ps, indexFont(indexHit(&fontMenu))); boundingBox(t); draw(t,p); break; case 2: /* justification */ draw(t,p); t->otherValues.text.just = indexJust(indexHit( &justMenu )); boundingBox(t); draw(t,p); break; case 3: /* spacing */ draw(t,p); t->otherValues.text.spacing = indexSpacing(indexHit(&spacingMenu)); boundingBox(t); draw(t,p); break; case 4: /* separate lines of text */ t = separateLineText(t,p); *ta = TNULL; undo_clear(); break; case 5: /* Copy */ copyOperation(); break; case 6: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; break; } break; case CIRCLE: case ELLIPSE: #ifdef X11 ti = hmenuhit( &circleMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( &circleMenu, 3, 0 ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( indexHit(&circleMenu) ) { case 0: /* Copy */ copyOperation(); break; case 1: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; case ARC: #ifdef X11 ti = hmenuhit( &arcMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( &arcMenu, 3, TM_EXPAND ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( indexHit(&arcMenu) ) { case 0: /* Reflect x */ t = reflect(t, p, 'x'); break; case 1: /* Reflect y */ t = reflect(t, p, 'y'); break; case 2: /* Copy */ copyOperation(); break; case 3: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; case SPLINE: #ifdef X11 ti = hmenuhit( &splineMenu, 3 ); if( ti == (NMitem * )NULL ) #else /* X11 */ ti = tmenuhit( &splineMenu, 3, 0 ); if( ti == (Titem * )NULL ) #endif /* X11 */ break; switch( indexHit(&splineMenu) ) { case 0: /* arrow */ b = t->otherValues.spline.used; if (distance(m,t->origin)< distance(m,t->otherValues.spline.plist[b])) { if ((t->arrow==startARROW)|| (t->arrow==doubleARROW)) { t->arrow -= startARROW; } else { t->arrow += startARROW; } arrow(add(p,t->otherValues.spline.plist[2]), add(p,t->otherValues.spline.plist[1])); } else { if ((t->arrow==endARROW)|| (t->arrow==doubleARROW)) { t->arrow -= endARROW; } else { t->arrow += endARROW; } arrow(add(p,t->otherValues.spline.plist[b-2]), add(p,t->otherValues.spline.plist[b-1])); } break; case 1: /* Reflect x */ t = reflect(t, p, 'x'); break; case 2: /* Reflect y */ t = reflect(t, p, 'y'); break; case 3: /* Copy */ copyOperation(); break; case 4: /* Delete */ t = deleteOperation(t,p); *ta = TNULL; } break; } /* end of switch on t->type */ return(t); } RUsure () { int savebuttonstate; int ret; ret = 0; cursswitch (&rusure); savebuttonstate = buttonState; if (CORRECTSIZE) { changeButtons( QUITbuttons ); } while (!button123()) { if (P->state & RESHAPED) redrawLayer(); nap(2); } if (button3()) ret = 1; changeButtons( savebuttonstate ); while (button123()) nap(2); cursSwitch(); return (ret); } struct thing * displayCommandMenu(h, offset) struct thing * h; Point offset; { #ifdef X11 register NMitem * ti; #else /* X11 */ register Titem * ti; #endif /* X11 */ int newAlign; int newGrid; switch( currentBrush ) { case TEXT: setChkmark( &psMenu, psIndex(currPS) ); setChkmark( &fontMenu, fontIndex(currFont) ); setChkmark( &justMenu, justIndex(currJust) ); setChkmark( &spacingMenu, spacingIndex(currSpacing) ); #ifdef X11 ti = hmenuhit( &gTextMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &gTextMenu, 3, TM_EXPAND ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; switch( indexHit( &gTextMenu ) ) { case 0: /* Point size */ currPS = indexPS( indexHit( &psMenu ) ); break; case 1: /* Font style */ currFont = indexFont( indexHit( &fontMenu ) ); break; case 2: /* Justify */ currJust = indexJust( indexHit( &justMenu ) ); break; case 3: /* Spacing */ currSpacing = indexSpacing( indexHit( &spacingMenu ) ); break; } break; case BOX: setChkmark( &densityMenu, densityIndex(currBoxType) ); #ifdef X11 ti = hmenuhit( &densityMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &densityMenu, 3, 0 ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; currBoxType = indexDensity( indexHit( &densityMenu ) ); break; case SPLINE: setChkmark( &arrowMenu, arrowIndex(currSplineArrows) ); #ifdef X11 ti = hmenuhit( &arrowMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &arrowMenu, 3, 0 ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; currSplineArrows = indexArrow( indexHit( &arrowMenu ) ); break; case LINE: setChkmark( &densityMenu, densityIndex(currLineType) ); setChkmark( &arrowMenu, arrowIndex(currLineArrows) ); #ifdef X11 ti = hmenuhit( &gLineMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &gLineMenu, 3, TM_EXPAND ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; switch( indexHit( &gLineMenu ) ) { case 0: /* Density */ currLineType = indexDensity( indexHit( &densityMenu ) ); break; case 1: /* Arrows */ currLineArrows = indexArrow( indexHit( &arrowMenu ) ); break; } break; case CIRCLE: case ELLIPSE: case ARC: case MACRO: /* No menu when these brushes are selected */ for( ; button3(); nap(2) ); break; default: /* Use main menu when no brush is selected */ setChkmark( &alignMenu, alignIndex(currAlignment) ); #ifdef FINEALIGN setChkmark( &gridMenu, gridIndex(currGridsize) ); #else /* FINEALIGN */ setChkmark( &gridMenu, gridIndex(gridState) ); #endif /* FINEALIGN */ #ifdef HELPSCALE # ifdef X11 setChkmark( &scaleMenu, scaleIndex(currScaleType) ); # else setChkmarkMidmenu( &scaleMenu, scaleIndex(currScaleType) ); # endif /* X11 */ setChkmark( &labelMenu, labelIndex(currLabelType) ); #endif /* HELPSCALE */ #ifdef X11 ti = hmenuhit( &commandMenu, 3 ); if( ti == (NMitem *) NULL ) #else /* X11 */ ti = tmenuhit( &commandMenu, 3, TM_EXPAND ); if( ti == (Titem *) NULL ) #endif /* X11 */ break; switch( indexHit( &commandMenu ) ) { case GET: /* Get file */ fontBells = 0; h = doGet(h); ringbell(); fontBells = 1; break; case PUT: /* Put file */ undo_clear(); /* Must clear out any macros in save area else they will be written out even if unused! */ doPut(); ringbell(); break; case CLEAR: if (RUsure()) { h = doClear(h); } break; case DEFINEMACRO: if (!noSpace) { h = defineMacro(h,offset); } break; case UNDO: h = undo(h); doRedraw(); break; case REDRAW: doRedraw(); break; case GRIDTOGGLE: #ifdef FINEALIGN newMessage(""); newGrid = indexGrid( indexHit( &gridMenu ) ); /* if newGrid == -1 set grid to follow alignment */ if ( newGrid == -1 ) { newGrid = -1 * currAlignment; if ( currAlignment < 4 ) { moreMessage("Alignment too small for a useful grid,\n"); moreMessage("so grid display has been inhibited."); } } /* * If the displayed grid size has changed, * redraw the grid. */ if ( newGrid != currGridsize && -newGrid != currGridsize ) { /* if grid was on, turn it off */ if ( gridState == GRIDon ) { drawGrid(); } /* set new size and draw new grid */ currGridsize = newGrid; gridState = (newGrid == 0) ?GRIDoff:GRIDon; if ( gridState == GRIDon ) { drawGrid(); } } #else /* FINEALIGN */ newMessage("Grid displayed is based on the alignment\nsetting."); moreMessage(" No grid is displayed when\nalignment is 2."); newGrid = indexGrid( indexHit( &gridMenu ) ); if( newGrid != gridState ) { drawGrid(); gridState = newGrid; } #endif /* FINEALIGN */ break; case ALIGNMENT: newAlign = indexAlign( indexHit( &alignMenu ) ); #ifdef FINEALIGN if ( newAlign > 0 ) { currAlignment = newAlign; } /* * A negative grid size means that the grid * is following the alignment. */ if ( currGridsize < 0 ) { newMessage(""); if ( currAlignment < 4 ) { moreMessage("Alignment too small for a useful grid,\n"); moreMessage("so grid display has been inhibited."); } newGrid = -1 * currAlignment; /* * If the displayed grid size has changed, * redraw the grid. */ if ( newGrid != currGridsize ) { /* if grid was on, turn it off */ if( gridState == GRIDon ) { drawGrid(); } /* set new size, draw new grid */ currGridsize = newGrid; gridState = (newGrid == 0) ? GRIDoff:GRIDon; if ( gridState == GRIDon ) { drawGrid(); } } } #else if( newAlign != currAlignment ) { if( gridState == GRIDon ) { drawGrid(); /* erases present grid */ currAlignment = newAlign; drawGrid(); } else { currAlignment = newAlign; } } #endif /* FINEALIGN */ break; case XCIPINFO: cursswitch(&hourglass); initMessage(); printSpace(); printPWD(); printChgStatus(); cursSwitch(); break; case XCIPVERS: putVersion(); break; #ifdef HELPSCALE case DISPSCALE: { int newType; int newLabel; int newFactor; int saveB; int r; char numbuff[100]; newType = indexScale( indexHit( &scaleMenu ) ); switch (newType) { case SCALE_NONE: case SCALE_LABEL_ONLY: currScaleType = newType; break; case SCALE_FACTOR_ONLY: case SCALE_BOTH: currScaleType = newType; sprintf(numbuff,"%s %d\n", "The current scale factor is", currScaleFactor ); newMessage(numbuff); break; case SCALE_SET_FACTOR: saveB = buttonState; newMessage("Change scale factor to: "); changeButtons(DObuttons); sprintf(numbuff,"%d",currScaleFactor); r = getMessage(numbuff); changeButtons(saveB); if( r == 3 || r == 4 ) { newFactor = atoi(numbuff); if( newFactor > 0 ) { switch (currScaleType) { case SCALE_NONE: currScaleType = SCALE_FACTOR_ONLY; break; case SCALE_LABEL_ONLY: currScaleType = SCALE_BOTH; } currScaleFactor = newFactor; } else { newMessage("*** scale must be an integer and > 0 ***"); } } else { newMessage("*** change scale aborted ***"); } break; case SCALE_SET_LABEL: newLabel = indexLabel(indexHit(&labelMenu)); if ( currLabelType != LABEL_NONE && newLabel == LABEL_NONE ) { switch ( currScaleType ) { case SCALE_BOTH: currScaleType = SCALE_FACTOR_ONLY; break; case SCALE_LABEL_ONLY: currScaleType = SCALE_NONE; break; } } if ( currLabelType == LABEL_NONE && newLabel != LABEL_NONE ) { switch ( currScaleType ) { case SCALE_NONE: currScaleType = SCALE_LABEL_ONLY; break; case SCALE_FACTOR_ONLY: currScaleType = SCALE_BOTH; break; } } currLabelType = newLabel; break; } } break; #endif /* HELPSCALE */ #ifdef X11 case QUIT: if (RUsure()) { exit (1); } break; #else case ORIGWINDOW: originalLayer(); break; #endif } break; } return(h); } doRedraw() { register struct thing *t; eraseAll(); t = firstThing; if( t != TNULL ) { do { if (t->type==MACRO) boundingBox(t); draw(t, add(drawOffset, scrollOffset)); t = t->next; #ifndef X11 sw(1); /* give up CPU */ #endif } while( t != firstThing ); } } #ifdef DMD5620 void setdata (p) /* Setdata routine copied from layersys/boot.c */ register struct Proc *p; { register struct udata *u = ((struct udata *)p->data); u->Drect = p->rect; u->Jdisplayp = p->layer; } #endif xcip/stand.targ0000644000175300001440000000406211513632542012340 0ustar meusers# Copyright (c) 1987 AT&T # All Rights Reserved # THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T # The copyright notice above does not evidence any # actual or intended publication of such source code. ### Standard Targets ### build install clean clobber: @if [ "$(TCTERM)" = dmd ]; \ then \ $(MAKE) $(MACROS5620) ACTION=$@ subdirdmd $@dmd; \ elif [ "$(TCTERM)" = all ]; \ then \ $(MAKE) $(MACROS5620) ACTION=$@ subdirdmd $@dmd; \ $(MAKE) $(MACROS630) ACTION=$@ subdir630 $@630; \ elif [ "$(TCTERM)" = 630 ]; \ then \ $(MAKE) $(MACROS630) ACTION=$@ subdir630 $@630; \ else \ echo make: Invalid terminal type \`$(TCTERM)\'; \ exit 1; \ fi subdirdmd: @DS="$(SUBDIRS5620)"; \ for D in $$DS; do \ (set -x; cd $$D; \ exec $(MAKE) $(MACROS5620) $(ACTION)); \ done subdir630: @DS="$(SUBDIRS630)"; \ for D in $$DS; do \ (set -x; cd $$D; \ exec $(MAKE) $(MACROS630) $(ACTION)); \ done builddmd: $(PRODUCTS5620) @echo make: made $@ build630: $(PRODUCTS630) @echo make: made $@ installdmd: $(INSTALL5620) striphost @echo make: made $@ install630: $(INSTALL630) striphost @echo make: made $@ striphost: @IH="$(INSTALLHOST)"; \ for I in $$IH; do \ if [ -f "$$I" ]; then \ (set -x;strip $$I); \ fi; \ done buildhost: $(PRODUCTSHOST) installhost: $(INSTALLHOST) striphost cleanhost: cleanhosthere clobberhost: clobberhosthere buildhost installhost cleanhost clobberhost: @DS="$(SUBDIRSHOST)"; \ for D in $$DS; do \ (set -x; cd $$D; \ exec $(MAKE) $(MACROS) $@); \ done @echo make: made $@ # some systems cannot take rm -f of nothing so add "xx" in case variable empty cleandmd: rm -f xx $(CLEAN5620) @echo make: made $@ clean630: rm -f xx $(CLEAN630) @echo make: made $@ cleanhosthere: rm -f xx $(CLEANHOST) clobberdmd: cleandmd rm -f xx $(CLOBBER5620) @echo make: made $@ clobber630: clean630 rm -f xx $(CLOBBER630) @echo make: made $@ clobberhosthere: cleanhosthere clobberhosthere: rm -f xx $(CLOBBERHOST) ### Additional Dependencies ### xcip/tmenuhit.h0000644000175300001440000000452611513632544012365 0ustar meusers/* * Defines for Tmenu and Titem menu structures. * Old menu structures can be found in . */ typedef struct Titem { char *text; /* string for menu */ struct { unsigned short uval; /* user field */ unsigned short grey; /* flag indicates invalid selection */ } ufield; struct Tmenu *next; /* pointer to sub-menu */ Bitmap *icon; /* pointer to the icons bitmap */ struct Font *font; /* font defined for this item */ void (*dfn)(); /* execute function before sub-menu */ void (*bfn)(); /* execute function after sub-menu */ void (*hfn)(); /* execute function on selection */ } Titem; typedef struct Tmenu { Titem *item; /* Titem array, ending with text=0 */ short prevhit; /* private to menuhit() */ short prevtop; /* private to menuhit() */ Titem *(*generator)(); /* used if item == 0 */ short menumap; /* bit definition for user Titem structure */ } Tmenu; /* * The following bit definitions are for the user to define * the structure of the user Titem structure. These bits are * stored in the menumap data member, which converts the user * Titem structure into that of the Titem structure defined above. */ #define TM_TEXT 0x0001 /* defines the text field */ #define TM_UFIELD 0x0002 /* defines the ufield field */ #define TM_NEXT 0x0004 /* defines the next field */ #define TM_ICON 0x0008 /* defines the icon field */ #define TM_FONT 0x0010 /* defines the font field */ #define TM_DFN 0x0020 /* defines the dfn field */ #define TM_BFN 0x0040 /* defines the bfn field */ #define TM_HFN 0x0080 /* defines the hfn field */ #define TM_EXPAND 1 /* expand submenus on invocation */ #define TM_NORET 2 /* don't return until non-selection */ #define TM_STATIC 4 /* select on button depression */ #define TM_POINT 8 /* specify a point for the root menu */ #define MAX_TMFIELDS 8 /* number of fields in Titem */ #define MAX_MASK 0x0100 /* upper limit bit definition */ extern void tm_ret(); /* return function from TM_NORET */ extern Titem *tmenuhit(); /* This is the button 3's global menu item */ typedef struct Titem1 { char *text; struct { unsigned short uval; unsigned short grey; } ufield; struct Tmenu *next; Bitmap *icon; void (*dfn)(); } Titem1; extern Bitmap B_checkmark; extern Bitmap B_rtarrow; xcip/xcip.sh0000644000175300001440000000362111513632544011651 0ustar meusers# # dmd/630 cip/xcip script # CIP=`basename $0` case $CIP in x*) JPIC=xjpic; JX=xjx;; *) JPIC=jpic; JX=jx;; esac if ismpx - then : else echo "$CIP not available in standalone mode - use layers" >&2 exit 1 fi DMD=${DMD:-DeFdMd} if [ "$DMD" = "" ] then echo $CIP: 'environment variable $DMD must be set' >&2 exit 1 fi dmdobj=${DMDLIB:-$DMD/lib}/$CIP.m # Print out version if requested. (Note: this does not work on VAXes or # '386es because its byte ordering is reversed.) if [ "$1" = "-V" ] then sed -n -e "/ version /p" ${dmdobj} 2>/dev/null | \ sed -n -e "s/.*\( version [0-9a-zA-Z]*\.[0-9a-zA-Z]*\).*/$CIP \1/p" echo "" | $JPIC -V exit 0 fi # Test if download is attempted in the window that will receive system # and other messages. These messages can hang up reads & writes. # This test does not work on old pty layers. Just set "mesg n" to try to # prevent messages from getting in. if [ "$DMDAGENT" != "" -a "$DMDAGENTDIR" = "" ] then mesg n else MYTTY=`tty <&2|sed 's-/dev/--'` if [ "`who|awk '{if ($2 == \"'$MYTTY'\") print $2}'`" != "" ] then echo "$CIP should NOT be downloaded in this window as this window" >&2 echo " will be the one receiving system and other messages." >&2 echo " Create another window and run $CIP in it." >&2 exit 1 fi fi # Determine font directory. fontpath=${DMD}/font:/usr/add-on/dmd2.0/font if [ "${DMDLIB}" != "" ] then fontpath=${DMDLIB}/../xfont:$fontpath fi if [ "${FONT}" != "" ] then # Add user supplied font directory to FONT path. fontpath=${FONT}:${fontpath} fi for fontdir in `echo ${fontpath}|sed 's/:/ /g'` do if [ -f ${fontdir}/R.10 ] then break; fi done if [ ! -f ${fontdir}/R.10 ] then echo "$CIP: a DMD/MTG font directory not found - set FONT to font" >&2 echo " directory and export FONT." >&2 exit 1 fi # Finally... invoke jx to download $CIP.m! $JX ${dmdobj} ${fontdir} xcip/buttons.c0000644000175300001440000002422611513632542012216 0ustar meusers#include "cip.h" extern Point align(); extern struct thing * editThing(); extern int currentBrush, copyFlag, thingSelected, editDepth; extern Rectangle brushes[]; extern int gridState, videoState, buttonState; extern void printInfo(); extern void printNum(); extern void save_old(); extern void save_new(); int charPos = 0; int same_obj = 1; #ifdef DMDTERM char *resizeText[] = { " Open window ", " Quit editor ", NULL}; Menu resizeMenu = {resizeText}; Texture16 menucursor = { 0xFFC0, 0x8040, 0x8040, 0x8040, 0xFFC0, 0xFFC0, 0xFE00, 0xFEF0, 0x80E0, 0x80F0, 0x80B8, 0xFE1C, 0x800E, 0x8047, 0x8042, 0xFFC0}; #endif struct thing * doMouseButtons(t,offset) register struct thing *t; Point offset; { Point m; Rectangle * b; struct thing * t1; struct thing * tmp; if (CORRECTSIZE) { #ifdef DMDTERM if (P->state & MOVED ) { /* Window has been moved so must reset global variables. */ Xmin = P->layer->rect.origin.x + BORDER; Ymin = P->layer->rect.origin.y + BORDER; drawOffset.x = Xmin; drawOffset.y = YPIC; brushInit(); P->state &= ~(MOVED|RESHAPED); } else #endif if (P->state & RESHAPED) { /* Redraw screen if layer has been reshaped */ redrawLayer(); #ifdef X11 return(t); #endif } if ((own () & MOUSE) && ptinrect (MOUSE_XY, brushes[PIC])) { if (P->cursor != &crossHairs) { cursswitch (&crossHairs); } } else { if (P->cursor == &crossHairs) { cursswitch ((Texture16 *)0); } } #ifdef DMDTERM } else { /* Not the correct size. Don't go to main menu until layer is full size */ cursswitch(&menucursor); while ( !button3() ) { sleep(2); #ifdef DMD630 if( (P->state & RESHAPED) && !(P->state & MOVED) ) #endif #ifdef DMD5620 if( (P->state & RESHAPED) ) #endif { drawToolIcon(); P->state &= ~RESHAPED; } } cursswitch ((Word *)NULL); switch ( menuhit(&resizeMenu, 3) ) { case 0: /* Open window */ { resizeLayer(); break; } case 1: /* Exit editor */ { if (RUsure ()) exit(); break; } } return (t); #endif } /* Add drawing frame absolute position and scrolling offset to offset. */ offset = add( add(drawOffset, scrollOffset), offset ); wait( MOUSE|KBD ); m = sub(MOUSE_XY,offset); /* BUTTON 1 PRESSED */ if ( button1() ) { /* Delete empty text string as no longer editing it */ if( thingSelected && (t->type==TEXT) ) if( t->otherValues.text.s[0] == '\0' ) t = deleteThing(t); b = Select(t, add(m,offset), offset); if ( b == &brushes[PIC]) { /* Pressed inside picture drawing area */ copyFlag=0; t1 = selectThing(m,t); if (thingSelected==1) { drawSelectionLines(t,offset); } if (t1 != TNULL) { t = t1; thingSelected = 1; changeBrush(-1); same_obj = 0; if (t->type==MACRO||t->type==TEXT) { changeButtons(MOVEbuttons); } else { changeButtons(EDITbuttons); } flashThing(t,offset); printInfo(t); if(t->type==TEXT) { charPos = moveTextSpot(t,offset); } else { while( button1() ) nap(2); } drawSelectionLines(t,offset); flashThing(t,offset); } else { /* Nothing selected in picture area */ thingSelected = 0; changeBrush(-1); changeButtons( INITbuttons ); initMessage(); } } else { /* Pressed in brush, edit level or some outside picture area */ initMessage(); same_obj = 0; if (thingSelected==1) { drawSelectionLines(t,offset); thingSelected = 0; } if (b != (Rectangle *) NULL ) { /* Brush area selected */ copyFlag=0; thingSelected = 0; switch( currentBrush ) { case TEXT: case BOX: case SPLINE: case LINE: changeButtons(GLOBbuttons); break; default: changeButtons(DRAWbuttons); break; } } } for (; button1(); nap(2)) ; /* BUTTON 2 PRESSED */ } else if( button2() ) { if( thingSelected ) { if( copyFlag ) { drawSelectionLines( t, offset ); t = insert( copyThing( t, align(m), offset, 1 ), t )->last; drawSelectionLines( t, offset ); /* clear button 2 - only one copy per click */ for ( ; button2(); nap(2)) ; } else { if( !same_obj ) { same_obj = 1; save_old( t ); } t = editThing(m,offset,t); save_new( t ); } } else { /* No thing is selected */ if ((currentBrush>=0)&&(ptinrect(add(m,offset),brushes[PIC]))) { if (currentBrush==SPLINE) changeButtons(SPLINEbuttons); save_old( TNULL ); t = place(currentBrush,m,t,offset); if( firstThing == TNULL ) firstThing = t; save_new( t ); /* Backup one object, so that when object is selected, then the newly created object will be selected first. Note, that selectThing() goes to next object in list. */ if( t != TNULL ) t = t->last; switch( currentBrush ) { case TEXT: case BOX: case SPLINE: case LINE: changeButtons(GLOBbuttons); break; default: changeButtons(DRAWbuttons); break; } } else { moveAll(); } } /* BUTTON 3 PRESSED */ } else if (button3()) { if (thingSelected) { if( !same_obj ) { same_obj = 1; save_old( t ); } tmp = t; /* Note: t may be deleted, so must use tmp. */ t = displayThingMenu( m, &tmp, offset ); printInfo( tmp ); save_new( tmp ); } else { t = displayCommandMenu( t, offset ); } /* KEYBOARD INPUT RECEIVED */ } else if (own() & KBD ) { if (thingSelected && (t->type==TEXT) ) { if( !same_obj ) { same_obj = 1; save_old( t ); } charPos = editText(t,offset,charPos); boundingBox(t); printInfo(t); save_new( t ); } else { /* Ignore text, but must eat it up to prevent hanging. */ kbdchar(); } } return(t); } moveAll() { extern Rectangle BBpic; Point offset; Rectangle r; eraseAll(); findBBpic( firstThing ); /* * I don't entirely understand why these offsets are the * ones needed (and especially why the drawingOffset and * BBpic.origin need to be both in 'r' and in 'offset'), * but after a lot of trial and error I found that these are * what is needed. - Dave Dykstra, 12/21/95 */ r = raddp(BBpic, add(drawOffset, scrollOffset)); offset = add(drawOffset, BBpic.origin); xbox( raddp(r, offset) ); r = moveBox(MOUSE_XY, r, offset, 1); newMessage( "Offset was " ); printPt( scrollOffset ); scrollOffset = r.origin; moreMessage( " now " ); printPt( scrollOffset ); doRedraw(); } struct thing * place(b,p,h,os) register int b; Point p, os; struct thing *h; { register struct thing *t; register Point *plist, *olist; register int i, used, room; struct thing dummy; register char * s; p = align(p); switch (b) { case CIRCLE: { t = newCircle(p); if( t != TNULL ) { t->otherValues.radius = 2; draw(t,os); h = insert(t,h); track(p,os,GROWCIRCLE,t); } break; } case BOX: { t = newBox(Rpt(p,p)); if( t != TNULL ) { h = insert(t,h); track(p,os,BOX,t); draw(t,os); } break; } case ELLIPSE: { t = newEllipse(p); if( t != TNULL ) { t->otherValues.ellipse.ht = 2; t->otherValues.ellipse.wid = 2; draw(t,os); h = insert(t,h); track(p,os,ELLIPSE,t); } break; } case LINE: { t = newLine( p, p ); if( t != TNULL ) { h = insert(t,h); track(p,os,LINE,t); draw(t,os); } break; } case ARC: { t = newArc( p, p ); if( t != TNULL ) { h = insert(t,h); track(p,os,ARC,t); draw(t,os); } break; } case SPLINE: { if ((plist = (Point *)getSpace(5*sizeof(Point)))!=(Point *)NULL) { h = dummy_insert(&dummy,h); h->type = -1; /* Set this to invalid value so printInfo() called later will not print. */ plist[1]=p; used = 1; room = 3; do { if (used==room) { olist = plist; room <<= 1; plist = (Point *) getSpace((room+2)*sizeof(Point)); if (plist==(Point *)NULL) { draw (&dummy, os); h = Remove (&dummy); plist = olist; /* Free list later */ used = 0; break; } for (i=1; i<=used; i++) { plist[i]=olist[i]; } free(olist); } if (button2()) { ++used; plist[used]= track(plist[used-1],os,LINE,h); xsegment(add(os,plist[used-1]), add(os,plist[used])); initMessage(); printNum( (short) used ); moreMessage( " points" ); } nap(2); if (P->state & RESHAPED) { redrawLayer(); drawZigZag(os,plist,used); } } while (!button3()); for (; button3(); ) nap(2); drawZigZag(os,plist,used); if (used>2) { t = newSpline(++used,room,plist); draw(t,os); printInfo(t); } else { t = TNULL; free (plist); } h = Remove(&dummy); h = insert(t,h); } break; } case TEXT: { int cursorOn; int charPos; Point m; cursorOn = 1; charPos = 0; s = getSpace(1); s[0] = '\0'; t = newText(p,s); printInfo(t); if( t==TNULL ) break; while( button123() ) nap(2); cursswitch( &textCursor ); changeButtons(EXITbuttons); clearKeyboard(); m = mouse.xy; while (1) { wait( KBD | MOUSE ); if (P->state & RESHAPED) { redrawLayer(); draw(t,os); } if( own() & KBD ) { if( cursorOn ) { cursSwitch(); cursinhibit(); cursorOn = 0; } charPos = editText(t,os,charPos); printInfo(t); } if( !eqpt(m,mouse.xy) && !cursorOn ) { cursorOn = 1; m = mouse.xy; cursallow(); cursSwitch(); } if( own() & MOUSE ) { if( button123() ) break; } }; if( !cursorOn ) { cursorOn = 1; cursallow(); cursSwitch(); } while( button123() ) nap(2); h = insert(t,h); if( t->otherValues.text.s[0] == '\0' ) { h = deleteThing(t); t = TNULL; initMessage(); } break; } } if( t == TNULL ) { return( h ); } else { boundingBox(t); if( eqpt(t->bb.origin,t->bb.corner) ) { /* thing created has no size so remove it */ h = deleteThing(t); return( h ); } else { return( t ); } } } clearKeyboard() { for (; kbdchar() != -1; ) ; } xcip/track.c0000644000175300001440000003216011513632544011622 0ustar meusers#include "cip.h" extern Rectangle brushes[]; extern void printInfo(); extern void printPt(); #ifdef DMD5620 /* No float on DMD 5620 terminals! */ #define float int #endif /* Rounds the given integer based on currAlignment. */ int alignInt(i) int i; { if( currAlignment > 0 ) { if( i >= 0 ) { return ( ( (i+(currAlignment>>1)) / currAlignment) * currAlignment); } else { return ( ( (i-(currAlignment>>1)) / currAlignment) * currAlignment); } } else { return( i ); } } int alignByInt(i, value ) register int i; register int value; { if( i >= 0 ) { return ( ( (i+value) / currAlignment) * currAlignment); } else { return ( ( (i-value) / currAlignment) * currAlignment); } } /* Rounds the point given based on currAlignment. */ Point align(p) Point p; { if( currAlignment > 0 ) { p.x = alignInt(p.x); p.y = alignInt(p.y); } return p; } Point alignUp(p) Point p; { if( currAlignment > 0 ) { p.x = alignByInt( p.x, currAlignment-1 ); p.y = alignByInt( p.y, currAlignment-1 ); } return( p ); } Point alignDown(p) Point p; { if( currAlignment > 0 ) { p.x = alignByInt( p.x, 0 ); p.y = alignByInt( p.y, 0 ); } return( p ); } Point track(p,offset,b,th) Point p,offset; int b; register struct thing *th; { Point t, ot; Rectangle r; cursinhibit(); if ( b != ARC ) { p = add(p,offset); ot = p; } else { ot = add(p,offset); } if( th != TNULL ) { do { t = add( align( sub(MOUSE_XY,offset) ), offset ); if ((t.x!=ot.x)||(t.y!=ot.y)) { switch (b) { case BOX: { xbox( canon(p, ot) ); r = canon(p,t); xbox( r ); th->origin = sub( r.origin, offset ); th->otherValues.corner = sub( r.corner, offset ); break; } case ARC: { th->type = ARC; th->otherValues.arc.start = p; th->otherValues.arc.end = sub( ot,offset ); th->origin=computeArcOrigin( p, sub( ot,offset )); if (!eqpt(th->otherValues.arc.start, th->otherValues.arc.end)) { draw(th,offset); } th->otherValues.arc.end = sub( t,offset ); th->origin=computeArcOrigin( p, sub( t,offset )); draw(th,offset); break; } case LINE: { xsegment(p,ot); xsegment(p,t); th->origin = sub( p, offset ); th->otherValues.end = sub( t, offset ); break; } case REVLINE: { xsegment(p,ot); xsegment(p,t); th->origin = sub( t, offset ); th->otherValues.end = sub( p, offset ); break; } case SPLINE: { xsegment(p,ot); xsegment(p,t); break; } case REVSPLINE: { /* See note 1 */ xsegment(ot,p); xsegment(t,p); break; } case GROWCIRCLE: { draw(th,offset); th->otherValues.radius=alignInt(distance(add(th->origin,offset),t)); draw(th,offset); break; } case MOVE: { draw(th,offset); th->origin = sub(t,offset); draw(th,offset); break; } case GROWEHT: { draw(th,offset); th->otherValues.ellipse.ht = abs(th->origin.y-t.y+offset.y)<<1; draw(th,offset); break; } case GROWEWID: { draw(th,offset); th->otherValues.ellipse.wid = abs(th->origin.x-t.x+offset.x)<<1; draw(th,offset); break; } case ELLIPSE: { draw(th,offset); th->otherValues.ellipse.wid = (abs(th->origin.x-t.x+offset.x))<<1; th->otherValues.ellipse.ht = abs(th->origin.y-t.y+offset.y)<<1; draw(th,offset); break; } } ot = t; printInfo( th ); } nap(2); } while (bttn2()); } switch (b) { case ARC: draw(th,offset); break; case BOX: xbox (canon (p, ot)); boundingBox( th ); break; case LINE: case REVLINE: xsegment(p,ot); break; } cursallow(); return(sub(t,offset)); } /* NOTE 1: */ /* Lines drawn and undrawn using XOR mode must always be drawn in the */ /* same direction. This is because the last point on the line is not */ /* drawn. The same line drawn twice, but in opposite directions */ /* will leave two points on the screen. So, because of this when */ /* the tracking routine is tracking a spline from p[2] to p[1] the */ /* line must be drawn in the opposite direction (from p[1] to p[2]). */ /* Therefore, the need for the REVSPLINE value. */ Point track2(offset,o1, o2, p) Point offset, o1, o2, p; { Point op; o1 = add(offset,o1); o2 = add(offset,o2); op = add(offset,p); do { cursinhibit (); p = add( align( sub(MOUSE_XY,offset) ), offset ); if ((p.x!=op.x)||(p.y!=op.y)) { xsegment(o1,op); xsegment(op,o2); xsegment(o1,p); xsegment(p,o2); } op = p; cursallow (); nap(2); } while (bttn2()); return(sub(p,offset)); } Point trackMacro(p,offset) Point p,offset; { Point t, ot; cursinhibit(); p = add(p,offset); ot = p; do { t = add( align( sub(MOUSE_XY,offset) ), offset ); if ((t.x!=ot.x)||(t.y!=ot.y)) { xbox( canon(p, ot) ); xbox( canon(p, t) ); ot = t; } nap(2); } while (bttn2()); xbox (canon (p, ot)); cursallow(); return(sub(t,offset)); } Rectangle moveBox(p,r,offset,originonly) Point p; Point offset; Rectangle r; int originonly; { Point op; Rectangle or; cursinhibit(); or = r; op = align(p); op = p; do { p = align(sub(MOUSE_XY,offset)); r.origin = align( add(or.origin,sub(p,op)) ); if( !eqpt( r.origin, or.origin ) ) { r.corner = add( or.corner, sub(r.origin,or.origin) ); xbox( raddp(or,offset) ); xbox( raddp(r, offset) ); initMessage(); printPt( r.origin ); if (!originonly) { moreMessage( " to " ); printPt( r.corner ); } op = p; or = r; } nap(2); } while (bttn2()); cursallow(); return(r); } arcOrigin(t,offset) register struct thing *t; Point offset; { Point oc, c, s, e, om, m, org, mid, A, B, tempP, newP; long sin_a, sin_b, cos_a, cos_b, num, den; cursinhibit(); s = add(offset,t->otherValues.arc.start); e = add(offset,t->otherValues.arc.end); org = add(offset,t->origin); mid = div(add(s,e),2); oc = org; om = oc; do { /*if not a full circle or just a point*/ if ((s.x != e.x) || (s.y != e.y)) { m = add( align( sub(MOUSE_XY,offset) ), offset ); if (distance(m,om) !=0) { /*if mouse moved*/ if (distance(m,oc) != 0) { /*if mouse not already at origin*/ if ((s.x - e.x) == 0) { /*if it is a horizontal bisector*/ c.x = m.x; c.y =org.y; } else if ((s.y -e.y) == 0) { /*else if it is a vertical bisector*/ c.x = org.x; c.y =m.y; } else { /********************* sin_a = (mid.y -oc.y)/d1 cos_a = (mid.x -oc.x)/d1 sin_b = (m.y -oc.y)/d2 cos_b = (m.x -oc.x)/d2 c.x = d2*cos_a*(cos_a*cos_b -sin_a*sin_b) + oc.x; c.y = d2*sin_a*(cos_a*cos_b -sin_a*sin_b) + oc.y; ***********************/ /*let's find two points on the line that bisects the arc. Nominally*/ /*this would be the origin, and the midpoint of the line between */ /*the start of the arc and the end of the arc. However, if the arc is*/ /*a semi-circle, then these two points are coincident. Therefore */ /* we will use the mid-point, and determine a second point whose distance*/ /* from the mid-point is non-zero except for the vertical and */ /*horizontal conditions which have been handled separately.*/ if (s.y < mid.y) { tempP = s; } else { tempP = e; } newP.x = mid.x + (mid.y - tempP.y); /*newP is second point*/ newP.y = mid.y + (tempP.x - mid.x); if (mid.x > newP.x) { B= mid; A= newP; } else { B= newP; A = mid; } sin_a = (long)(m.y - A.y); cos_a = (long)(m.x - A.x); sin_b = (long)(B.y -A.y); cos_b = (long)(B.x -A.x); if (m.x origin = sub(c,offset); printInfo(t); } } } } nap(2); } while (bttn2()); cursallow(); } arcStart(t,offset) register struct thing *t; Point offset; { Point oc, s, e, oe, os,orig_e, temp_e; float d,od; register int i, delta; int x_change, y_change, x1,y1; cursinhibit(); os = add(offset,t->otherValues.arc.start); oc = add(offset,t->origin); oe = add(offset,t->otherValues.arc.end); orig_e = oe; if ((od = (float)distance(os,oc)) >0) { /*if original radius not 0 */ do { s = add( align( sub(MOUSE_XY,offset) ), offset ); if (distance(s,os)>2) { /*if change > 2*/ if ((d = (float)distance (s,oc)) > 0) { /*if new radius not 0 */ t->otherValues.arc.start=sub(s,offset); e.x = oc.x + (orig_e.x -oc.x)*(d/od); e.y = oc.y + (orig_e.y -oc.y)*(d/od); /*the value for "e" may be wrong due to roundoff error*/ /*so we are going to refine it*/ if(distance(e,oc) != (int)d) { /*if we need to change it*/ if(distance(e,oc) < (int)d) { /*if we need to grow it*/ delta =1; } else { delta = -1; } temp_e.x = e.x; /*use values just calculated*/ temp_e.y = e.y; x1 = orig_e.x - oc.x; if (x1 <0) x1 = - x1; y1 = orig_e.y - oc.y; if (y1 < 0) y1 = - y1; i=0; while (1) { /*we will break when we have changed it enough*/ ++i; /*first, find out if delta x is greater than delta y*/ if (x1 >= y1) { x_change = i*delta; y_change = (x_change * y1)/x1; } else { y_change = i*delta; x_change = (y_change *x1)/y1; } if (temp_e.x < oc.x) { x_change = -x_change; } if (temp_e.y < oc.y) { y_change = -y_change; } e.x = temp_e.x + x_change; e.y = temp_e.y + y_change; /*now we have the formulas for growing or shrinking*/ if (delta ==1) { if(distance(e,oc) >= (int)d) { /*if grown enough*/ break; } } else if(distance(e,oc) <= (int)d) { /*if shrunk enough*/ break; } } } t->otherValues.arc.end = sub(e,offset); eraseAndDrawArc(oc,oe,os,oc,e,s); os = s; oe = e; printInfo(t); } } nap(2); } while (bttn2()); } else do { nap(2); } while (bttn2()); cursallow(); } arcEnd(t,offset) register struct thing *t; Point offset; { Point oc, s, e, oe, os,orig_s, temp_s; float d,od; register int i, delta; int x_change, y_change, x1,y1; cursinhibit(); os = add(offset,t->otherValues.arc.start); orig_s = os; oe = add(offset,t->otherValues.arc.end); oc = add(offset,t->origin); if ((od = (float)distance(oe,oc)) > 0) { /*if original radius not 0 */ do { e = add( align( sub(MOUSE_XY,offset) ), offset ); if (distance(e,oe)>2) { /*if change > 2*/ if ((d = (float)distance (e,oc)) > 0) { /*if new radius not 0 */ t->otherValues.arc.end = sub(e,offset); s.x = oc.x + (orig_s.x -oc.x)*(d/od); s.y = oc.y + (orig_s.y -oc.y)*(d/od); /*the value for "s" may be wrong due to roundoff error*/ /*so we are going to refine it*/ if(distance(s,oc) !=(int)d) { /*if we need to change it*/ if(distance(s,oc) < (int)d) { /*if we need to grow it*/ delta =1; } else { delta = -1; } temp_s.x = s.x; /*use values just calculated*/ temp_s.y = s.y; x1 = orig_s.x - oc.x; if (x1 <0) x1 = - x1; y1 = orig_s.y - oc.y; if (y1 < 0) y1 = - y1; i=0; while (1) { /*we will break when we have changed it enough*/ ++i; /*first, find out if delta x is greater than delta y*/ if (x1 >= y1) { x_change = i*delta; y_change = (x_change * y1)/x1; } else { y_change = i*delta; x_change = (y_change *x1)/y1; } if (temp_s.x < oc.x) { x_change = -x_change; } if (temp_s.y < oc.y) { y_change = -y_change; } s.x = temp_s.x + x_change; s.y = temp_s.y + y_change; /*now we have the formulas for growing or shrinking*/ if (delta ==1) { if(distance(s,oc) >= (int)d) { /*if grown enough*/ break; } } else if(distance(s,oc) <= (int)d) { /*if shrunk enough*/ break; } } } t->otherValues.arc.start = sub(s,offset); eraseAndDrawArc(oc,oe,os,oc,e,s); oe = e; os = s; printInfo(t); } } nap(2); } while (bttn2()); } else do { nap(2); } while (bttn2()); cursallow(); } eraseAndDrawArc(oc,oe,os,c,e,s) Point oc, oe, os, c, e, s; { cursinhibit(); xarc(oc,os,oe); xsegment(oc,os); xsegment(oc,oe); xarc(c,s,e); xsegment(c,s); xsegment(c,e); cursallow(); }