static short minifindpopup (Point pt){ /* search the popuprects array, and return the index of the item whose rect contains the indicated point. we only look at the portion of the rect that displays the popup arrow. if the point isn't in any of the rects, return -1. */ register hdlminirecord hm = minidata; register short i; Rect r; for (i = 0; i < (**hm).ctpopups; i++) { r = (**hm).popuprects [i]; r.left = r.right - popuparrowwidth; if (pointinrect (pt, r)) return (i); } /*for*/ return (-1); } /*minifindpopup*/
static short oppointlevel (Point pt) { /* give me a point in the display rectangle, and I'll tell you what level it refers to. to visualize the process, draw vertical lines on the screen at (**outlinedata).lineindent increments. each line corresponds to a level in the outline. we match the pt up with the levels. */ register hdloutlinerecord ho = outlinedata; hdlheadrecord hsummit = (**ho).hsummit; Rect r = (**ho).outlinerect; short indent; insetrect (&r, -draggingsloppix, -draggingsloppix); if (!pointinrect (pt, r)) /*too sloppy -- no move*/ return (-1); indent = (pt.h - (**ho).outlinerect.left) - (opnodeindent (hsummit) + dragginghotspot); return ((**hsummit).headlevel + divround (indent, (**ho).lineindent)); } /*oppointlevel*/
static boolean tableverbadjustcursor (Point pt) { register hdltableformats hf = tableformatsdata; short col; if (pointinrect (pt, (**hf).tablerect)) { if (tablefindcolumnguide (pt, &col)) { setcursortype (cursorisverticalrails); return (true); } return (opsetcursor (pt)); } if (adjustpopupcursor (pt, (**hf).kindpopuprect)) return (true); if (adjustpopupcursor (pt, (**hf).sortpopuprect)) return (true); setcursortype (cursorisarrow); return (true); } /*tableverbadjustcursor*/
boolean pointinscrollbar (Point pt, hdlscrollbar hscrollbar) { hdlscrollbar h = hscrollbar; if (h == nil) /*defensive driving*/ return (false); return (pointinrect (pt, (**h).contrlRect)); } /*pointinscrollbar*/
static boolean aboutmousedown (Point pt, tyclickflags flags) { #pragma unused (flags) /* 1/24/91 dmb: to allow the home window to be dragged with a single click, even when it's not already the front window, the dontconsumefrontclicks flag is set in its config. in order to avoid reacting to button clicks or clicks in the close box or on the flag (which aren't even visiable when the window is inactive), we test to make sure that the window has been activated before considering taking any special actions. */ hdlaboutrecord hc = aboutdata; Rect r; ccunblockmsg (); /*any mouse click re-enables background messages*/ if ((**hc).flbigwindow) { if (ccgettextitemrect (urlitem, &r) && pointinrect (pt, r)) { if (trackicon (r, &ccdrawurlitem)) if (!ccrunurlscript ()) sysbeep (); return (true); } } if (ccgetagentpopuprect (&r)) { /*see if click is in agents popup*/ if (pointinrect (pt, r)) { /*click in agents popup*/ --r.top; if (ccagentpopuphit (r, pt)) ccdrawagentpopup (); return (true); } } return (true); } /*aboutmousedown*/
static boolean tableverbmousedown (Point pt, tyclickflags flags) { register hdltableformats hf = tableformatsdata; short col; if (pointinrect (pt, (**hf).titlerect)) return (tabletitleclick (pt)); if (pointinrect (pt, (**hf).iconrect)) { if (!(**hf).fliconenabled) return (true); return (tablezoombuttonhit ()); } if (pointinrect (pt, (**hf).kindpopuprect)) return (tablekindpopuphit (pt)); if (pointinrect (pt, (**hf).sortpopuprect)) return (tablesortpopuphit (pt)); if (pointinrect (pt, (**hf).tablerect)) { if (tablefindcolumnguide (pt, &col)) return (tableadjustcolwidth (pt, col)); return (opmousedown (pt, flags)); } /* ouch (); */ return (true); } /*tableverbmousedown*/
static boolean langerroradjustcursor (Point pt) { if (pointinrect (pt, (**langerrordata).iconrect)) { if (!(**langerrordata).flcallbackconsumed) { setcursortype (cursorisgo); return (true); } } setcursortype (cursorisarrow); return (true); } /*langerroradjustcursor*/
static short minifindtextobject (Point pt) { /* search the textrects array, and return the index of the item whose rect contains the indicated point. if the point isn't in any of the rects, return -1. */ register hdlminirecord hm = minidata; register short i; for (i = 0; i < (**hm).cttextitems; i++) { if (pointinrect (pt, (**hm).textrects [i])) return (i); } /*for*/ return (-1); } /*minifindtextobject*/
static int f_process_imap(struct request *r, FILE *fp) { char input[PATHLEN], default_url[PATHLEN]; struct token tok[2 * MAXVERTS + 2]; point testpoint, pointarray[MAXVERTS]; long dist, mindist; int i, k, l, line, sawpoint, text; char *t, *u, *url; const char *status; testpoint.x = 0; testpoint.y = 0; text = 1; if (r->args) { t = strchr(r->args, ','); if (t == 0 || *++t == 0) { r->status = 400; return 0; } testpoint.x = atol(r->args); testpoint.y = atol(t); if (testpoint.x || testpoint.y) text = 0; } line = 0; sawpoint = 0; *default_url = 0; mindist = 0; status = 0; url = 0; while (fgetline(input, PATHLEN, fp) != -1) { if (++line > MAXLINES) { status = "too many lines"; break; } l = separate(input, tok, 2 * MAXVERTS + 2); if (l < 2) continue; if (l % 2) { status = "odd number of coords"; break; } t = input + tok[0].pos; t[tok[0].len] = 0; u = input + tok[1].pos; u[tok[1].len] = 0; i = 2; k = 0; while (i < l) { pointarray[k].x = atol(input + tok[i++].pos); pointarray[k++].y = atol(input + tok[i++].pos); } if (k >= MAXVERTS) { status = "too many points"; break; } if (!strcmp(t, "default")) strcpy(default_url, u); else if (!strcmp(t, "text")) { if (text) { url = u; break; } } else if (!strcmp(t, "point")) { if (k < 1) { status = "no point"; break; } if (text == 0) { dist = sqr(pointarray[0].x - testpoint.x) + sqr(pointarray[0].y - testpoint.y); if (sawpoint == 0 || dist < mindist) { sawpoint = 1; mindist = dist; strcpy(default_url, u); } } } else if (!strcmp(t, "rect")) { if (k < 2) { status = "too few rect points"; break; } if (text == 0 && pointinrect(testpoint, pointarray)) { url = u; break; } } else if (!strcmp(t, "circle")) { if (k < 2) { status = "too few circle points"; break; } if (text == 0 && pointincircle(testpoint, pointarray)) { url = u; break; } } else if (!strcmp(t, "spoly")) { if (k < 3) { status = "too few spoly points"; break; } if (text == 0 && pointinpoly(testpoint, pointarray, k)) { url = u; break; } } else if (!strcmp(t, "poly")) { if (k < 3) { status = "too few poly points"; break; } if (text == 0 && pointinpoly(testpoint, pointarray, k) & 1) { url = u; break; } } else { status = "unknown keyword"; break; } } if (status) { log_d("imagemap: %s on line %d of %s", status, line, r->path_translated); r->status = 500; return 0; } if (url == 0) if (*default_url) url = default_url; if (url) { l = snprintf(r->newloc, PATHLEN, "%s", url); if (l >= PATHLEN) { log_d("imagemap: url too large"); r->status = 500; return 0; } r->location = r->newloc; r->status = 302; return 0; } r->status = 204; return 0; }
int main(int argc, char **argv) { char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE], errstr[MAXLINE]; double testpoint[2], pointarray[MAXVERTS][2]; int i, j, k; FILE *fp; char *t; double dist, mindist; int sawpoint = 0; if (argc != 2) servererr("Wrong number of arguments, client may not support ISMAP."); mapname=getenv("PATH_INFO"); if((!mapname) || (!mapname[0])) servererr("No map name given. Please read the <A HREF=\"http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemapping.html\">instructions</A>.<P>"); mapname++; if(!(t = strchr(argv[1],','))) servererr("Your client doesn't support image mapping properly."); *t++ = '\0'; testpoint[X] = (double) atoi(argv[1]); testpoint[Y] = (double) atoi(t); /* * if the mapname contains a '/', it represents a unix path - * we get the translated path, and skip reading the configuration file. */ if (strchr(mapname,'/')) { strcpy(conf,getenv("PATH_TRANSLATED")); goto openconf; } if ((fp = fopen(CONF_FILE, "r")) == NULL){ /* Assume new style request if CONF_FILE doesn't exist */ goto openconf; } while(!(mygetline(input,MAXLINE,fp))) { char confname[MAXLINE]; if((input[0] == '#') || (!input[0])) continue; for(i=0;isname(input[i]) && (input[i] != ':');i++) confname[i] = input[i]; confname[i] = '\0'; if(!strcmp(confname,mapname)) goto found; } /* * if mapname was not found in the configuration file, it still * might represent a file in the server root directory - * we get the translated path, and check to see if a file of that * name exists, jumping to the opening of the map file if it does. */ if(feof(fp)) { struct stat sbuf; strcpy(conf,getenv("PATH_TRANSLATED")); if (!stat(conf,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG)) goto openconf; else servererr("Map not found in configuration file."); } found: fclose(fp); while(isspace(input[i]) || input[i] == ':') ++i; for(j=0;input[i] && isname(input[i]);++i,++j) conf[j] = input[i]; conf[j] = '\0'; openconf: if(!(fp=fopen(conf,"r"))){ sprintf(errstr, "Couldn't open configuration file: %s", conf); servererr(errstr); } while(!(mygetline(input,MAXLINE,fp))) { char type[MAXLINE]; char url[MAXLINE]; char num[10]; if((input[0] == '#') || (!input[0])) continue; type[0] = '\0';url[0] = '\0'; for(i=0;isname(input[i]) && (input[i]);i++) type[i] = input[i]; type[i] = '\0'; while(isspace(input[i])) ++i; for(j=0;input[i] && isname(input[i]);++i,++j) url[j] = input[i]; url[j] = '\0'; if(!strcmp(type,"default") && !sawpoint) { strcpy(def,url); continue; } k=0; while (input[i]) { while (isspace(input[i]) || input[i] == ',') i++; j = 0; while (isdigit(input[i])) num[j++] = input[i++]; num[j] = '\0'; if (num[0] != '\0') pointarray[k][X] = (double) atoi(num); else break; while (isspace(input[i]) || input[i] == ',') i++; j = 0; while (isdigit(input[i])) num[j++] = input[i++]; num[j] = '\0'; if (num[0] != '\0') pointarray[k++][Y] = (double) atoi(num); else { fclose(fp); servererr("Missing y value."); } } pointarray[k][X] = -1; if(!strcmp(type,"poly")) if(pointinpoly(testpoint,pointarray)) sendmesg(url); if(!strcmp(type,"circle")) if(pointincircle(testpoint,pointarray)) sendmesg(url); if(!strcmp(type,"rect")) if(pointinrect(testpoint,pointarray)) sendmesg(url); if(!strcmp(type,"point")) { /* Don't need to take square root. */ dist = ((testpoint[X] - pointarray[0][X]) * (testpoint[X] - pointarray[0][X])) + ((testpoint[Y] - pointarray[0][Y]) * (testpoint[Y] - pointarray[0][Y])); /* If this is the first point, or the nearest, set the default. */ if ((! sawpoint) || (dist < mindist)) { mindist = dist; strcpy(def,url); } sawpoint++; } } if(def[0]) sendmesg(def); servererr("No default specified."); }
/* NCSA Imagemap files use: method URL coord1 coord2 * CERN Imagemap files use: method (coord1) (coord2) URL * This version of imagemap will probably work with either in the same file, * as long as a full line is in one format or the other. */ int send_imagemap(per_request* reqInfo, struct stat* fi, char allow_options) { char *input, *def, *szPoint, *url, *type; double testpoint[2], pointarray[MAXVERTS][2]; int i, j, k; int error_num = 0; FILE *fp; char *t; double dist, mindist = -1; int sawpoint = 0; int sawparen = 0; int Found = 0; input = newString(HUGE_STRING_LEN,STR_TMP); def = newString(MAX_STRING_LEN,STR_TMP); szPoint = newString(MAX_STRING_LEN,STR_TMP); type = newString(MAX_STRING_LEN,STR_TMP); url = newString(MAX_STRING_LEN,STR_TMP); def[0] = '\0'; strcpy(szPoint, reqInfo->args); if(!(t = strchr(szPoint,','))) { error_num = IMAP_ERR_INCORRECT_ARGS; goto imagemap_error; } *t++ = '\0'; testpoint[X] = (double) atoi(szPoint); testpoint[Y] = (double) atoi(t); if(!(fp=FOpen(reqInfo->filename,"r"))){ log_reason(reqInfo, "File permissions deny server access", reqInfo->filename); freeString(input); freeString(def); freeString(szPoint); freeString(url); freeString(type); die(reqInfo, SC_FORBIDDEN, reqInfo->url); } while (!Found && fgets(input,HUGE_STRING_LEN,fp)) { char num[10]; /* Skip lines with # as comments and blank lines */ if((input[0] == '#') || (!input[0])) continue; type[0] = '\0';url[0] = '\0'; /* Copy the shape keyword into type */ for(i=0;!isspace(input[i]) && (input[i]);i++) type[i] = input[i]; type[i] = '\0'; /* Forward to next word */ while(isspace(input[i])) ++i; /* If no coordinates, must be url for default, or NCSA format */ if (input[i] != '(') { for(j=0;input[i] && !isspace(input[i]);++i,++j) url[j] = input[i]; url[j] = '\0'; } /* Handle default keyword */ if(!strcmp(type,"default") && !sawpoint) { strcpy(def,url); continue; } /* Looking for Coordinates */ k=0; while (input[i]) { /* Move over spaces and commas */ while (isspace(input[i]) || input[i] == ',') i++; /* Under CERN, coordinates are in parenthesis */ if (input[i] == '(') { sawparen = 1; while (isspace(input[++i])); } /* Copy digits into num array */ j = 0; while (isdigit(input[i])) num[j++] = input[i++]; num[j] = '\0'; if (!j) break; pointarray[k][X] = (double) atoi(num); /* Skip to next digit */ while (isspace(input[i]) || input[i] == ',') i++; /* Copy other number into num */ j = 0; while (isdigit(input[i])) num[j++] = input[i++]; num[j] = '\0'; if (!j && !sawparen && k > 0) { pointarray[k++][Y] = -127; break; } if (j) pointarray[k++][Y] = (double) atoi(num); else { error_num = IMAP_ERR_INCORRECT_COORDS; FClose(fp); goto imagemap_error; } /* End of parenthesis for coordinates under CERN */ if (input[i] == ')') { i++; sawparen = 0; } else if (sawparen) { error_num = IMAP_ERR_CERN_MISSING_RIGHT_PAREN; FClose(fp); goto imagemap_error; } } if (url[0] == '\0' && input[i]) { while (isspace(input[i])) i++; for (j = 0; input[i] && !isspace(input[i]); ++i, ++j) url[j] = input[i]; url[j] = '\0'; } pointarray[k][X] = -1; if(!strncmp(type, "poly", 4)) if(pointinpoly(testpoint,pointarray)) Found = 1; if(!strncmp(type, "circ", 4)) if(pointincircle(testpoint,pointarray)) Found = 1; if(!strncmp(type, "rect", 4)) if(pointinrect(testpoint,pointarray)) Found = 1; if(!strcmp(type,"point")) { /* Don't need to take square root. */ dist = ((testpoint[X] - pointarray[0][X]) * (testpoint[X] - pointarray[0][X])) + ((testpoint[Y] - pointarray[0][Y]) * (testpoint[Y] - pointarray[0][Y])); /* If this is the first point, or the nearest, set the default. */ if ((! sawpoint) || (dist < mindist)) { mindist = dist; strcpy(def,url); } sawpoint++; } } if(Found) { sendmesg(reqInfo, url, fp); goto imagemap_ok; } else { if(def[0]) { sendmesg(reqInfo, def, fp); goto imagemap_ok; } } /* No reason to log each of these as an "error" */ /* log_reason(reqInfo, "No default defined in imagemap.", reqInfo->filename); */ FClose(fp); freeString(input); freeString(def); freeString(szPoint); freeString(url); freeString(type); die(reqInfo, SC_NO_CONTENT, reqInfo->url); return 0; imagemap_ok: FClose(fp); freeString(input); freeString(def); freeString(szPoint); freeString(url); freeString(type); return 1; imagemap_error: freeString(input); freeString(def); freeString(szPoint); freeString(url); freeString(type); log_reason(reqInfo,imagemap_errors[error_num-1],reqInfo->filename); die(reqInfo,SC_BAD_IMAGEMAP,imagemap_errors[error_num-1]); return -1; }
pascal void ScrollThumbActionProc (void) { SInt32 theValue; hdlscrollbar hscrollbar; Point thePoint; Rect theRect; long ctscroll; tydirection dir; long currvalue; hdlwindowinfo h = shellwindowinfo; short baselineoffset; if (h == nil) /*defensive driving*/ return; hscrollbar = (**h).vertscrollbar; if (!flverticalscroll) hscrollbar = (**h).horizscrollbar; zerorect (&theRect); GetBestControlRect (hscrollbar, &theRect, &baselineoffset); //theRect = (**hscrollbar).contrlRect; if (flverticalscroll) insetrect (&theRect, -kThumbTrackLengthSlop, -kThumbTrackWidthSlop); else insetrect (&theRect, -kThumbTrackWidthSlop, -kThumbTrackLengthSlop); GetMouse (&thePoint); if (pointinrect (thePoint, theRect)) theValue = CalcValueFromPoint (hscrollbar, thePoint); else theValue = gStartValue; currvalue = (**h).vertscrollinfo.cur; if (theValue != GetControlValue (hscrollbar)) { // if we scrolled EnableDrawing (); ctscroll = theValue - GetControlValue (hscrollbar); dir = scrolldirection (flverticalscroll, ctscroll > 0); (*shellglobals.scrollroutine) (dir, false, abs (ctscroll)); (**h).vertscrollinfo.cur = theValue; DisableDrawing (); } /*if*/ return; } /*ScrollThumbActionProc*/
static boolean langerrormousedown (Point pt, tyclickflags flags) { #pragma unused (flags) /* 7/16/90 DW: wired off the consumption of the error callback, if you want it back on, just switch on the code that's commented out, and the script icon will go dim, the cursor adjustment won't happen, and no mouseclicks will be handled for clicking on the script button. 4.1b4 dmb: use custom tracking code so we can popup a menu after mouse has been down a fraction of a second. */ register hdllangerrorrecord hle = langerrordata; Rect r; boolean flinrectnow, flwasinrect; boolean flconsumed = false; unsigned long timemoved; short threshhold = getmousedoubleclicktime () * 2 / 3; if ((**hle).flcallbackconsumed) return (false); r = (**hle).iconrect; if (pointinrect (pt, r)) { setcursortype (cursorisarrow); /*get rid of funny appendage*/ langerrordrawicon (true); /*show icon in depressed state*/ // if (!mousetrack (r, langerrordrawicon)) /*if false, mouse didn't stay in rectangle*/ // return (false); flwasinrect = true; /*at least for the first iteration of loop*/ timemoved = gettickcount (); while (mousestilldown ()) { /*stay in holding pattern*/ getmousepoint (&pt); flinrectnow = pointinrect (pt, r); if (flinrectnow != flwasinrect) { langerrordrawicon (flinrectnow); timemoved = gettickcount (); } else if (flinrectnow && gettickcount () - timemoved > (unsigned) threshhold) { langerrorpopupmenu (); flconsumed = true; } flwasinrect = flinrectnow; } /*while*/ if (flwasinrect) { langerrordrawicon (false); /*show icon in un-depressed state*/ if (!flconsumed) langerrorbuttonhit (); } } return (true); } /*langerrormousedown*/
static boolean minimousedown (Point pt, tyclickflags flags) { register hdlminirecord hm = minidata; short item; Rect r; minicheckselectall (); /*if a selectall is pending, do it now*/ item = minifindtextobject (pt); if (item >= 0) { miniactivatemessage (false); (**hm).activetextitem = item; if (!minisetwpglobals (item)) return (false); wpclick (pt, flags); (*(**hm).texthitroutine) (pt); shellevent.when = gettickcount (); mouseup (shellevent.when, shellevent.where.h, shellevent.where.v, shellevent.what); /*textedit may swallow the mouseup event when tracking click*/ return (true); } if (pointinrect (pt, (**hm).msgrect)) { if (minisetactivewpglobals ()) wpactivate (false); (**hm).activetextitem = -1; miniactivatemessage (true); } r = (**hm).iconrect; if (pointinrect (pt, r)) { if ((**hm).fliconenabled) if (trackicon (r, minidrawicon)) return (miniiconhit (false)); return (true); } bundle { /*check for mousedown in a popup*/ register short x; x = minifindpopup (pt); if (x >= 0) { /*mousedown was in a popup*/ return (minipopuphit (x)); } } /* ouch (); */ return (true); } /*minimousedown*/
void opdraggingmove (Point ptstart, hdlheadrecord hsource) { /* 9/22/93 dmb: need to validate a drag just like a copy. also need to provide for client sorting, like a paste */ long tc = 0; tyhotspot hotspot; Point pt; tydirection dir; if (!((**outlinedata).validatecopycallback) (STR_move)) return; clearbytes ((ptrchar) &hotspot, longsizeof (hotspot)); hotspot.pt = ptstart; hotspot.hsource = hsource; /* opgetwindowhandle (pt, &hotspot.sourcewindowhandle); hotspot.destwindowhandle = hotspot.sourcewindowhandle; */ if (true /*claystartdrag(ptstart, hsource) != noErr*/) { while (mousestilldown ()) { getmousepoint (&pt); #if false Handle currentwindow; if (!pointinrect (pt, (*FrontWindow ()).portRect)) Debugger (); opgetwindowhandle (pt, ¤twindow); if (currentwindow != hotspot.destwindowhandle) { /*pointing into another window*/ opsetwindowhandlecontext (hotspot.destwindowhandle); operasehotspot (&hotspot); hotspot.destwindowhandle = currentwindow; opsetwindowhandlecontext (hotspot.destwindowhandle); opupdatehotspot (ptstart, pt, &hotspot); } #endif if ((gettickcount () - tc) > draggingscrollrate) { if (mousecheckautoscroll (pt, (**outlinedata).outlinerect, false, &dir)) { opscrollfordrag (&hotspot, dir); tc = gettickcount (); } } opupdatehotspot (ptstart, pt, &hotspot); } /*while*/ operasehotspot (&hotspot); /*user let up on the button*/ opmovetohotspot (&hotspot); } // if noErr } /*opdraggingmove*/