william@CS.UCLA.EDU (William Cheng) (12/18/90)
Submitted-by: william@CS.UCLA.EDU (William Cheng) Posting-number: Volume 10, Issue 65 Archive-name: tgif/patch6.02 Patch-To: Volume 7, Issue 56-76 (original: tgif-1.2) Patch-To: Volume 8, Issue 46-48 (Patch1: tgif-1.2 => tgif-1.9) Patch-To: Volume 8, Issue 58-60 (Patch2: tgif-1.9 => tgif-1.12) Patch-To: Volume 8, Issue 87-89 (Patch3: tgif-1.12 => tgif-1.13) Patch-To: Volume 8, Issue 94 (Patch4: tgif-1.13 => tgif-1.14) Patch-To: Volume 8, Issue 95 (Patch5: tgif-1.14 => tgif-1.15) ---------------------------------> cut here <--------------------------------- *** names.c.orig Sat Oct 27 17:49:07 1990 --- names.c Sat Oct 27 17:49:08 1990 *************** *** 6,10 **** #ifndef lint static char RCSid[] = ! "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/names.c,v 1.6 90/07/27 14:39:29 william Exp $"; #endif --- 6,10 ---- #ifndef lint static char RCSid[] = ! "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/names.c,v 1.10 90/10/26 15:40:34 william Exp $"; #endif *************** *** 20,23 **** --- 20,24 ---- #include "button.e" #include "cursor.e" + #include "file.e" #include "font.e" #include "mainloop.e" *************** *** 33,37 **** --- 34,50 ---- #define ROW_HEIGHT (defaultFontHeight+1) + typedef struct _DspList { + char itemstr[MAXPATHLENGTH+1]; + char pathstr[MAXPATHLENGTH+1]; + int directory; + struct _DspList * next; + } DspList; + + extern char * getenv (); + char curDomainName[MAXPATHLENGTH]; + char curDomainPath[MAXPATHLENGTH]; + char curDir[MAXPATHLENGTH]; + char curSymDir[MAXPATHLENGTH]; static Window nameBaseWin; *************** *** 55,61 **** static GC revNameGC; void InitNames () { ! char * c_ptr; XGCValues values; --- 68,342 ---- static GC revNameGC; + static DspList * symbolList = NULL; + static int numSymbols; + static DspList * dirList = NULL; + static int numDirEntries; + + static DspList * topOfSymLinkList = NULL; + static DspList * topOfDirLinkList = NULL; + + static + char * ReadPath (path_str, dir_str) + char * path_str, * dir_str; + { + register char * s1, * s2; + + s1 = path_str; + if (*s1 == '~') + { + strcpy (dir_str, homeDir); + s2 = &dir_str[strlen(dir_str)]; + s1++; + } + else + s2 = dir_str; + + for ( ; *s1 != '\0' && *s1 != ':'; s1++) + if (*s1 == '\\') + strcpy (s1, s1+1); + else + *s2++ = *s1; + + *s2 = '\0'; + if (*s1 == ':') s1++; + return (s1); + } + + void ParseSymPath (path_str) + char * path_str; + { + register char * s, c; + register int i; + char dir_str[MAXPATHLENGTH]; + + for (i = 0, s = path_str; *s != '\0'; ) + { + s = ReadPath (s, dir_str); + if (dir_str != '\0') i++; + } + symPath = (char * *) calloc (i, sizeof (char *)); + symPathNumEntries = i; + for (i = 0, s = path_str; *s != '\0'; ) + { + s = ReadPath (s, dir_str); + if (dir_str != '\0') + { + symPath[i] = (char *) calloc (MAXPATHLENGTH, sizeof (char)); + strcpy (symPath[i], dir_str); + i++; + } + } + strcpy (curDomainPath, path_str); + } + + static + DspList * SymbolListing () + { + int i, len, path_index, count = 0, reject; + char path[MAXPATHLENGTH], s[MAXPATHLENGTH]; + DspList * dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1; + DIR * dirp; + struct direct * d; + struct stat stat_buf; + + head_ptr = tail_ptr = NULL; + for (path_index = 0; path_index < symPathNumEntries; path_index++) + { + strcpy (path, symPath[path_index]); + if ((dirp = opendir (path)) == NULL) + continue; + + while ((d = readdir (dirp)) != NULL) + { + len = strlen (d->d_name); + if (len > 4 && (strcmp (".sym", &d->d_name[len-4]) == 0)) + d->d_name[len-4] = '\0'; + else + continue; + + if (head_ptr == NULL) + { + head_ptr = tail_ptr = (DspList *) calloc (1, sizeof(DspList)); + strcpy (head_ptr->itemstr, d->d_name); + strcpy (head_ptr->pathstr, path); + } + else + { + p1 = NULL; + reject = FALSE; + for (p = head_ptr; p != NULL; p = p->next) + { + if (strcmp (d->d_name, p->itemstr) == 0) + { + reject = TRUE; + break; + } + else if (LargerStr (d->d_name, p->itemstr)) + p1 = p; + else + { + dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); + strcpy (dsp_ptr->itemstr, d->d_name); + strcpy (dsp_ptr->pathstr, path); + break; + } + } + if (reject) continue; + + dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); + dsp_ptr->next = p; + strcpy (dsp_ptr->itemstr, d->d_name); + strcpy (dsp_ptr->pathstr, path); + + if (p == NULL) + { /* dsp_ptr has the largest element */ + tail_ptr->next = dsp_ptr; + tail_ptr = dsp_ptr; + } + else if (p1 == NULL) + head_ptr = dsp_ptr; + else + p1->next = dsp_ptr; + } + count++; + } + closedir (dirp); + } + numSymbols = count; + return (head_ptr); + } + + static + void BuildSymbolList () + { + register int i; + register DspList * dsp_ptr; + + if (symbolList != NULL) cfree (symbolList); + + symbolList = (DspList *) calloc (numSymbols, sizeof (DspList)); + dsp_ptr = topOfSymLinkList; + for (i = 0; i < numSymbols; i++, dsp_ptr = dsp_ptr->next) + { + strcpy (symbolList[i].itemstr, dsp_ptr->itemstr); + strcpy (symbolList[i].pathstr, dsp_ptr->pathstr); + symbolList[i].next = &symbolList[i+1]; + cfree (dsp_ptr); + } + symbolList[numSymbols].next = NULL; + topOfSymLinkList = NULL; + } + + static + DspList * DirListing (Path) + char * Path; + { + DspList * dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1; + DIR * dirp; + struct direct * d; + int len, count = 0; + char path[MAXPATHLENGTH], s[MAXPATHLENGTH]; + struct stat stat_buf; + + if (*Path == '\0') + { + strcpy (path, "/"); + if ((dirp = opendir (path)) == NULL) return (NULL); + } + else + { + strcpy (path, Path); + if ((dirp = opendir (path)) == NULL) return (NULL); + strcat (path, "/"); + } + + head_ptr = tail_ptr = NULL; + + while ((d = readdir (dirp)) != NULL) + { + len = strlen (d->d_name); + if (len > 4 && (strcmp (".obj", &d->d_name[len-4]) == 0)) + { + d->d_name[len-4] = '\0'; + dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); + dsp_ptr->directory = FALSE; + strcpy (dsp_ptr->itemstr, d->d_name); + } + else if (strcmp (d->d_name, ".") == 0) + continue; + else + { + strcpy (s, path); + strcat (s, d->d_name); + stat (s, &stat_buf); + if (stat_buf.st_mode & S_IFDIR) + { + dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); + dsp_ptr->directory = TRUE; + strcat (d->d_name, "/"); + strcpy (dsp_ptr->itemstr, d->d_name); + } + else + continue; + } + if (head_ptr == NULL) + head_ptr = tail_ptr = dsp_ptr; + else + { + p1 = NULL; + for (p = head_ptr; p != NULL; p = p->next) + if (LargerStr (d->d_name, p->itemstr)) + p1 = p; + else + break; + + dsp_ptr->next = p; + if (p == NULL) + { /* dsp_ptr has the largest element */ + tail_ptr->next = dsp_ptr; + tail_ptr = dsp_ptr; + } + else if (p1 == NULL) + head_ptr = dsp_ptr; + else + p1->next = dsp_ptr; + } + count++; + } + + closedir (dirp); + numDirEntries = count; + return (head_ptr); + } + + static + void BuildDirList () + { + register int i; + register DspList * dsp_ptr; + + if (topOfDirLinkList != NULL) + { + if (dirList != NULL) cfree (dirList); + + dirList = (DspList *) calloc (numDirEntries, sizeof (DspList)); + dsp_ptr = topOfDirLinkList; + for (i = 0; i < numDirEntries; i++, dsp_ptr = dsp_ptr->next) + { + strcpy (dirList[i].itemstr, dsp_ptr->itemstr); + strcpy (dirList[i].pathstr, dsp_ptr->pathstr); + dirList[i].directory = dsp_ptr->directory; + dirList[i].next = &dirList[i+1]; + cfree (dsp_ptr); + } + dirList[numDirEntries].next = NULL; + topOfDirLinkList = NULL; + } + } + void InitNames () { ! int default_found = FALSE; ! char * c_ptr, domain_str[20], sym_path[80]; XGCValues values; *************** *** 79,82 **** --- 360,366 ---- *curDomainName = '\0'; + *curDomainPath = '\0'; + *curSymDir = '\0'; + strcpy (curDir, bootDir); if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "DoubleClickInterval")) != *************** *** 85,90 **** --- 369,407 ---- else doubleClickInterval = 300; + + if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "DefaultDomain")) != NULL) + { + sprintf (domain_str, "Domain%s", c_ptr); + if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, domain_str)) != NULL) + { + if (*c_ptr != '\0') + { + strcpy (curDomainName, c_ptr); + sprintf (sym_path, "TGIF_%s", c_ptr); + default_found = TRUE; + } + } + } + + if (!default_found || (c_ptr = getenv (sym_path)) == NULL) + ParseSymPath ("."); + else + if (strlen (c_ptr) >= MAXPATHLENGTH-1) + ParseSymPath ("."); + else + ParseSymPath (c_ptr); + if ((topOfSymLinkList = SymbolListing ()) != NULL) BuildSymbolList (); } + void UpdateDirInfo () + { + if ((topOfDirLinkList = DirListing (curDir)) != NULL) BuildDirList (); + } + + void UpdateSymInfo () + { + if ((topOfSymLinkList = SymbolListing ()) != NULL) BuildSymbolList (); + } + void CleanUpNames () { *************** *** 91,94 **** --- 408,414 ---- XFreeGC (mainDisplay, nameGC); XFreeGC (mainDisplay, revNameGC); + + if (symbolList != NULL) cfree (symbolList); + if (dirList != NULL) cfree (dirList); } *************** *** 145,149 **** register int i; int top, len, end, pixel; - DspItem * diptr; XGCValues values; --- 465,468 ---- *************** *** 181,188 **** static ! void RedrawNameBaseWindow (Str, str_start, button_start, W, H) ! char * Str; ! int str_start, button_start; { int top = defaultFontAsc+2; --- 500,536 ---- static ! void RedrawNamePath (Path, X, Y) ! char * Path; ! int X, Y; { + int len = strlen (Path), cursor_x, cursor_y; + char * c_ptr; + + cursor_y = Y-defaultFontAsc; + + XClearArea (mainDisplay, nameBaseWin, X, Y-defaultFontAsc, + ITEM_LEN*defaultFontWidth+4, defaultFontHeight+4, False); + XDrawRectangle (mainDisplay, nameBaseWin, nameGC, X, cursor_y-2, + ITEM_LEN*defaultFontWidth+8, defaultFontHeight+4); + + if (len > ITEM_LEN) + { + c_ptr = &(Path[len-ITEM_LEN]); + len = ITEM_LEN; + } + else + c_ptr = Path; + + cursor_x = X+2+len*defaultFontWidth; + XDrawString (mainDisplay, nameBaseWin, nameGC, X+2, Y, c_ptr, len); + XDrawLine (mainDisplay, nameBaseWin, nameGC, cursor_x, + cursor_y, cursor_x, cursor_y+defaultFontHeight); + } + + static + void RedrawNameBaseWindow (Str, Path, str_start, path_start, button_start, W, H) + char * Str, * Path; + int str_start, path_start, button_start, W, H; + { int top = defaultFontAsc+2; *************** *** 190,199 **** XDrawString (mainDisplay, nameBaseWin, nameGC, str_start, ROW_HEIGHT+top, Str, strlen(Str)); ! buttonBBox[0].lty = buttonBBox[1].lty = (ITEM_DSPED+4) * ROW_HEIGHT; buttonBBox[0].ltx = button_start; ! DisplayButton (nameBaseWin, "OK", 8, &buttonBBox[0], BUTTON_NORMAL); buttonBBox[1].ltx = buttonBBox[CONFIRM_YES].rbx + 1 + defaultFontWidth; ! DisplayButton (nameBaseWin, "CANCEL", 8, &buttonBBox[1], BUTTON_NORMAL); } --- 538,548 ---- XDrawString (mainDisplay, nameBaseWin, nameGC, str_start, ROW_HEIGHT+top, Str, strlen(Str)); + RedrawNamePath (Path, path_start, 3*ROW_HEIGHT+top); ! buttonBBox[0].lty = buttonBBox[1].lty = (ITEM_DSPED+6) * ROW_HEIGHT; buttonBBox[0].ltx = button_start; ! DisplayButton (nameBaseWin, "OK", 8, &(buttonBBox[0]), BUTTON_NORMAL); buttonBBox[1].ltx = buttonBBox[CONFIRM_YES].rbx + 1 + defaultFontWidth; ! DisplayButton (nameBaseWin, "CANCEL", 8, &(buttonBBox[1]), BUTTON_NORMAL); } *************** *** 213,221 **** dsp_ptr[i] = c_ptr; len = strlen (DLPtr->itemstr); ! for (j = len; j >= 0 && DLPtr->itemstr[j] != '/'; j--) ; ! if (j >= 0) ! strcpy (c_ptr, (&DLPtr->itemstr[j])+1); else strcpy (c_ptr, DLPtr->itemstr); c_ptr += MAXPATHLENGTH; } --- 562,576 ---- dsp_ptr[i] = c_ptr; len = strlen (DLPtr->itemstr); ! if (!DLPtr->directory) ! { ! for (j = len; j >= 0 && DLPtr->itemstr[j] != '/'; j--) ; ! if (j >= 0) ! strcpy (c_ptr, (&(DLPtr->itemstr[j]))+1); ! else ! strcpy (c_ptr, DLPtr->itemstr); ! } else strcpy (c_ptr, DLPtr->itemstr); + c_ptr += MAXPATHLENGTH; } *************** *** 343,362 **** static ! int Names (Str) ! char * Str; { ! int x, y, pixel, button_widths, str_width, graph_width, w, h; ! int str_start, button_start, graph_start, index; ! int dsp_w, dsp_h; ! XEvent input, ev; ! int i, len, looping = TRUE, grabbed = FALSE; ! char buf[80]; ! XKeyEvent * key_ev; ! XButtonEvent * button_ev; ! KeySym key_sym; XComposeStatus c_stat; XSetWindowAttributes win_attrs; ! int win_x, win_y, win_w, win_h, win_d, win_brdr_w; ! Window root_win; dsp_w = DisplayWidth (mainDisplay, mainScreen); --- 698,729 ---- static ! int LargerStr (S1, S2) ! register char * S1, * S2; ! /* returns TRUE if S1 > S2 */ { ! while (*S1 == *S2 && *S1 != '\0' && *S2 != '\0') { S1++; S2++; } ! ! return (*S1 > *S2); ! } ! ! static ! int DirNames (TopStr, SelStr) ! char * TopStr, * SelStr; ! { ! int pixel, button_widths, str_width, graph_width; ! int str_start, button_start, graph_start, index; ! int dsp_w, dsp_h, x, y, w, h, i, len, exposure = 0; ! XEvent input, ev; ! int looping = TRUE, changing, grabbed = FALSE, name_index; ! char buf[80], name[MAXPATHLENGTH], full_name[MAXPATHLENGTH]; ! char dir_name[MAXPATHLENGTH], sel_str[MAXPATHLENGTH]; ! XKeyEvent * key_ev; ! XButtonEvent * button_ev; ! KeySym key_sym; XComposeStatus c_stat; XSetWindowAttributes win_attrs; ! int win_x, win_y, win_w, win_h, win_d, win_brdr_w; ! Window root_win; ! DspList * dsp_ptr, * head_dsp_ptr; dsp_w = DisplayWidth (mainDisplay, mainScreen); *************** *** 365,369 **** button_widths = ButtonWidth("OK", 8) + ButtonWidth("CANCEL", 8) + defaultFontWidth; ! str_width = defaultFontWidth * strlen (Str); graph_width = nameDspWinW + scrollBarW + 2 * brdrW; --- 732,736 ---- button_widths = ButtonWidth("OK", 8) + ButtonWidth("CANCEL", 8) + defaultFontWidth; ! str_width = defaultFontWidth * strlen (TopStr); graph_width = nameDspWinW + scrollBarW + 2 * brdrW; *************** *** 381,385 **** } button_start = (w - button_widths) / 2; ! h = (6 + ITEM_DSPED) * ROW_HEIGHT; win_x = (w > dsp_w) ? 0 : (dsp_w - w)/2; --- 748,752 ---- } button_start = (w - button_widths) / 2; ! h = (8 + ITEM_DSPED) * ROW_HEIGHT; win_x = (w > dsp_w) ? 0 : (dsp_w - w)/2; *************** *** 393,397 **** if ((nameDspWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, graph_start, ! 3*ROW_HEIGHT, nameDspW, nameDspH, brdrW, myBorderPixel, myBgPixel)) == 0) { printf ("Could not create desired popup window!\n"); exit (-1); } --- 760,764 ---- if ((nameDspWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, graph_start, ! 5*ROW_HEIGHT, nameDspW, nameDspH, brdrW, myBorderPixel, myBgPixel)) == 0) { printf ("Could not create desired popup window!\n"); exit (-1); } *************** *** 398,402 **** if ((nameScrollWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, ! graph_start+nameDspWinW, 3*ROW_HEIGHT, scrollBarW, nameDspH, brdrW, myBorderPixel, myBgPixel)) == 0) { printf ("Could not create desired popup scroll window!\n"); exit (-1); } --- 765,769 ---- if ((nameScrollWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, ! graph_start+nameDspWinW, 5*ROW_HEIGHT, scrollBarW, nameDspH, brdrW, myBorderPixel, myBgPixel)) == 0) { printf ("Could not create desired popup scroll window!\n"); exit (-1); } *************** *** 419,425 **** --- 786,1122 ---- KeyPressMask | ButtonPressMask | ExposureMask); + strcpy (dir_name, curDir); + justClicked = FALSE; while (looping) { + nameEntries = numDirEntries; + if (topOfDirLinkList == NULL) + nameDspPtr = MakeNameDspItemArray (nameEntries, dirList); + else + nameDspPtr = MakeNameDspItemArray (nameEntries, topOfDirLinkList); + nameFirst = 0; + nameMarked = 0; + + strcpy (full_name, dir_name); + strcat (full_name, "/"); + name[0] = '\0'; + name_index = 0; + + if (exposure >= 3) + { + XClearWindow (mainDisplay, nameBaseWin); + XClearWindow (mainDisplay, nameDspWin); + XClearWindow (mainDisplay, nameScrollWin); + RedrawNameBaseWindow (TopStr, full_name, str_start, graph_start, + button_start, w, h); + RedrawNameScrollWin (); + RedrawDspWindow (); + } + + changing = TRUE; + while (changing) + { + XNextEvent (mainDisplay, &input); + if (input.type == Expose) + { + if (input.xany.window == nameBaseWin) + { + RedrawNameBaseWindow (TopStr, full_name, str_start, graph_start, + button_start, w, h); + exposure++; + } + else if (input.xany.window == nameScrollWin) + { + RedrawNameScrollWin (); + exposure++; + } + else if (input.xany.window == nameDspWin) + { + RedrawDspWindow (); + exposure++; + } + + /* if (!grabbed) + { + XGrabKeyboard (mainDisplay, nameBaseWin, False, + GrabModeAsync, GrabModeAsync, CurrentTime); + grabbed = TRUE; + } */ + + continue; + } + else if (input.type == KeyPress) + { + key_ev = &(input.xkey); + XLookupString (key_ev, buf, 80, &key_sym, &c_stat); + + if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') || + (buf[0]=='\n' && (key_sym & 0xff)=='\n')) + { + changing = FALSE; + index = nameMarked; + } + else if (buf[0]=='\033' && (key_sym & 0xff)=='\033') + { + looping = FALSE; + changing = FALSE; + index = INVALID; + } + else if (buf[0] == '\b' || buf[0] == '\177') + { + if (name_index != 0) + { + name[--name_index] = '\0'; + strcpy (full_name, dir_name); + strcat (full_name, "/"); + strcat (full_name, name); + for (i = 0; i < nameEntries; i++) + if (strncmp (nameDspPtr[i], name, name_index) == 0) + break; + + if (i < nameEntries) + { + if (i < nameFirst) + nameFirst = i; + else if (i >= nameFirst+ITEM_DSPED) + { + if (i < nameEntries-ITEM_DSPED) + nameFirst = i; + else + nameFirst = nameEntries-ITEM_DSPED; + } + nameMarked = i; + RedrawNamePath (full_name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); + RedrawNameScrollWin (); + RedrawDspWindow (); + } + } + } + else if (key_sym>='\040' && key_sym<='\177') + { + if (buf[0] == '$') + { + i = (nameEntries == 0) ? 0 : nameEntries-1; + strcpy (name, nameDspPtr[i]); + } + else + { + name[name_index++] = buf[0]; + name[name_index] = '\0'; + for (i = 0; i < nameEntries; i++) + if (strncmp (nameDspPtr[i], name, name_index) == 0) + break; + } + + if (i < nameEntries) + { + if (i < nameFirst) + nameFirst = i; + else if (i >= nameFirst+ITEM_DSPED) + { + if (i < nameEntries-ITEM_DSPED) + nameFirst = i; + else + nameFirst = nameEntries-ITEM_DSPED; + } + nameMarked = i; + + strcpy (full_name, dir_name); + strcat (full_name, "/"); + strcat (full_name, name); + RedrawNamePath (full_name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); + RedrawNameScrollWin (); + RedrawDspWindow (); + } + else + name[--name_index] = '\0'; + } + } + else if (input.type == ButtonPress) + { + button_ev = &(input.xbutton); + if (button_ev->window == nameBaseWin) + { + if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[0])) + { + changing = FALSE; + index = nameMarked; + } + else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[1])) + { + looping = FALSE; + changing = FALSE; + index = INVALID; + } + } + else if (button_ev->window == nameScrollWin) + NameScrollHandler (button_ev); + else if (button_ev->window == nameDspWin) + { + if (NameDspHandler (button_ev) != INVALID) + { + changing = FALSE; + index = nameMarked; + } + else if (nameMarked != INVALID) + { + strcpy (name, nameDspPtr[nameMarked]); + strcpy (full_name, dir_name); + strcat (full_name, "/"); + strcat (full_name, name); + RedrawNamePath (full_name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); + } + } + } + } + + if (index != INVALID) strcpy (sel_str, nameDspPtr[index]); + + cfree (*nameDspPtr); + cfree (nameDspPtr); + + if (index == INVALID) break; + + if (sel_str[strlen(sel_str)-1] == '/') + { + sel_str[strlen(sel_str)-1] = '\0'; + if (strcmp (sel_str, "..") == 0) + { + for (i = strlen(dir_name)-1; i>=0 && dir_name[i]!='/'; i--) ; + if (i < 0) + dir_name[0] = '\0'; + else + dir_name[i] = '\0'; + } + else + { + strcat (dir_name, "/"); + strcat (dir_name, sel_str); + } + + dsp_ptr = topOfDirLinkList; + for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr); + topOfDirLinkList = NULL; + + Msg ("Generating list of file names, please wait ..."); + if ((topOfDirLinkList = DirListing (dir_name)) == NULL) + { + *sel_str = '\0'; + break; + } + Msg (""); + } + else + break; + } + if (grabbed) XUngrabKeyboard (mainDisplay, CurrentTime); + + strcpy (SelStr, dir_name); + strcat (SelStr, "/"); + strcat (SelStr, sel_str); + + if (index == INVALID) + DisplayButton (nameBaseWin, okCancelStr[1], 8, &buttonBBox[1], + BUTTON_INVERT); + else + DisplayButton (nameBaseWin, okCancelStr[0], 8, &buttonBBox[0], + BUTTON_INVERT); + + XDestroyWindow (mainDisplay, nameBaseWin); + XSync (mainDisplay, FALSE); + while (XCheckMaskEvent (mainDisplay, ExposureMask, &input)) ; + return (index); + } + + static + int ChooseAName (TopStr, SelStr) + char * TopStr, * SelStr; + { + int button_widths, str_width, graph_width; + int str_start, button_start, graph_start, index; + int dsp_w, dsp_h, x, y, w, h, i, len; + XEvent input, ev; + int changing = TRUE, grabbed = FALSE, name_index; + char buf[80], name[MAXPATHLENGTH]; + XKeyEvent * key_ev; + XButtonEvent * button_ev; + KeySym key_sym; + XComposeStatus c_stat; + XSetWindowAttributes win_attrs; + int win_x, win_y, win_w, win_h, win_d, win_brdr_w; + + dsp_w = DisplayWidth (mainDisplay, mainScreen); + dsp_h = DisplayHeight (mainDisplay, mainScreen); + + button_widths = ButtonWidth("OK", 8) + ButtonWidth("CANCEL", 8) + + defaultFontWidth; + str_width = defaultFontWidth * strlen (TopStr); + graph_width = nameDspWinW + scrollBarW + 2 * brdrW; + + if (str_width > graph_width) + { + w = str_width + 4 * defaultFontWidth; + str_start = 2 * defaultFontWidth; + graph_start = (w - graph_width) / 2; + } + else + { + w = graph_width + 4 * defaultFontWidth; + str_start = (w - str_width) / 2; + graph_start = 2 * defaultFontWidth; + } + button_start = (w - button_widths) / 2; + h = (8 + ITEM_DSPED) * ROW_HEIGHT; + + win_x = (w > dsp_w) ? 0 : (dsp_w - w)/2; + win_y = (h > dsp_h) ? 0 : (dsp_h - h)/3; + + if ((nameBaseWin = XCreateSimpleWindow (mainDisplay, rootWindow, + win_x, win_y, w, h, brdrW, myBorderPixel, myBgPixel)) == 0) + { printf ("Could not create desired popup window!\n"); exit (-1); } + + XDefineCursor (mainDisplay, nameBaseWin, defaultCursor); + + if ((nameDspWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, graph_start, + 5*ROW_HEIGHT, nameDspW, nameDspH, brdrW, myBorderPixel, + myBgPixel)) == 0) + { printf ("Could not create desired popup window!\n"); exit (-1); } + + if ((nameScrollWin = XCreateSimpleWindow (mainDisplay, nameBaseWin, + graph_start+nameDspWinW, 5*ROW_HEIGHT, scrollBarW, nameDspH, + brdrW, myBorderPixel, myBgPixel)) == 0) + { printf ("Could not create desired popup scroll window!\n"); exit (-1); } + + win_attrs.save_under = True; + XChangeWindowAttributes (mainDisplay, nameBaseWin, CWSaveUnder, &win_attrs); + + XSetTransientForHint (mainDisplay, nameBaseWin, mainWindow); + + XMapWindow (mainDisplay, nameBaseWin); + XSelectInput (mainDisplay, nameBaseWin, + KeyPressMask | ButtonPressMask | ExposureMask); + + XMapWindow (mainDisplay, nameDspWin); + XSelectInput (mainDisplay, nameDspWin, + KeyPressMask | ButtonPressMask | ExposureMask); + + XMapWindow (mainDisplay, nameScrollWin); + XSelectInput (mainDisplay, nameScrollWin, + KeyPressMask | ButtonPressMask | ExposureMask); + + justClicked = FALSE; + + Msg (""); + + name[0] = '\0'; + name_index = 0; + nameMarked = INVALID; + + while (changing) + { XNextEvent (mainDisplay, &input); if (input.type == Expose) *************** *** 426,430 **** { if (input.xany.window == nameBaseWin) ! RedrawNameBaseWindow (Str, str_start, button_start, w, h); else if (input.xany.window == nameScrollWin) RedrawNameScrollWin (); --- 1123,1128 ---- { if (input.xany.window == nameBaseWin) ! RedrawNameBaseWindow (TopStr, name, str_start, graph_start, ! button_start, w, h); else if (input.xany.window == nameScrollWin) RedrawNameScrollWin (); *************** *** 432,436 **** RedrawDspWindow (); ! if (!grabbed) { XGrabKeyboard (mainDisplay, nameBaseWin, False, --- 1130,1134 ---- RedrawDspWindow (); ! /* if (!grabbed) { XGrabKeyboard (mainDisplay, nameBaseWin, False, *************** *** 437,441 **** GrabModeAsync, GrabModeAsync, CurrentTime); grabbed = TRUE; ! } continue; --- 1135,1139 ---- GrabModeAsync, GrabModeAsync, CurrentTime); grabbed = TRUE; ! } */ continue; *************** *** 446,466 **** XLookupString (key_ev, buf, 80, &key_sym, &c_stat); ! if (buf[0] == '\r' || buf[0] == '\n') { ! looping = FALSE; index = nameMarked; } ! else if (buf[0] == '\033') { ! looping = FALSE; index = INVALID; } else if (key_sym>='\040' && key_sym<='\177') { if (buf[0] == '$') i = (nameEntries == 0) ? 0 : nameEntries-1; else for (i = 0; i < nameEntries; i++) ! if (*nameDspPtr[i] == buf[0]) break; if (i < nameEntries) { --- 1144,1202 ---- XLookupString (key_ev, buf, 80, &key_sym, &c_stat); ! if ((buf[0]=='\r' && (key_sym & 0xff)=='\r') || ! (buf[0]=='\n' && (key_sym & 0xff)=='\n')) { ! changing = FALSE; index = nameMarked; } ! else if (buf[0]=='\033' && (key_sym & 0xff)=='\033') { ! changing = FALSE; index = INVALID; } + else if (buf[0] == '\b' || buf[0] == '\177') + { + if (name_index != 0) + { + name[--name_index] = '\0'; + for (i = 0; i < nameEntries; i++) + if (strncmp (nameDspPtr[i], name, name_index) == 0) + break; + + if (i < nameEntries) + { + if (i < nameFirst) + nameFirst = i; + else if (i >= nameFirst+ITEM_DSPED) + { + if (i < nameEntries-ITEM_DSPED) + nameFirst = i; + else + nameFirst = nameEntries-ITEM_DSPED; + } + nameMarked = i; + RedrawNamePath (name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); + RedrawNameScrollWin (); + RedrawDspWindow (); + } + } + } else if (key_sym>='\040' && key_sym<='\177') { if (buf[0] == '$') + { i = (nameEntries == 0) ? 0 : nameEntries-1; + strcpy (name, nameDspPtr[i]); + } else + { + name[name_index++] = buf[0]; + name[name_index] = '\0'; for (i = 0; i < nameEntries; i++) ! if (strncmp (nameDspPtr[i], name, name_index) == 0) ! break; ! } ! if (i < nameEntries) { *************** *** 475,481 **** --- 1211,1222 ---- } nameMarked = i; + + RedrawNamePath (name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); RedrawNameScrollWin (); RedrawDspWindow (); } + else + name[--name_index] = '\0'; } } *************** *** 487,491 **** if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[0])) { ! looping = FALSE; index = nameMarked; } --- 1228,1232 ---- if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[0])) { ! changing = FALSE; index = nameMarked; } *************** *** 492,496 **** else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[1])) { ! looping = FALSE; index = INVALID; } --- 1233,1237 ---- else if (PointInBBox (button_ev->x, button_ev->y, buttonBBox[1])) { ! changing = FALSE; index = INVALID; } *************** *** 502,508 **** if (NameDspHandler (button_ev) != INVALID) { ! looping = FALSE; index = nameMarked; } } } --- 1243,1256 ---- if (NameDspHandler (button_ev) != INVALID) { ! changing = FALSE; index = nameMarked; } + else if (nameMarked != INVALID) + { + strcpy (name, nameDspPtr[nameMarked]); + name_index = strlen (name); + RedrawNamePath (name, graph_start, + 3*ROW_HEIGHT+defaultFontAsc+2); + } } } *************** *** 514,519 **** --- 1262,1270 ---- BUTTON_INVERT); else + { + strcpy (SelStr, nameDspPtr[index]); DisplayButton (nameBaseWin, okCancelStr[0], 8, &buttonBBox[0], BUTTON_INVERT); + } XDestroyWindow (mainDisplay, nameBaseWin); *************** *** 523,698 **** } ! static ! int LargerStr (S1, S2) ! register char * S1, * S2; ! /* returns TRUE if S1 > S2 */ { ! while (*S1 == *S2 && *S1 != '\0' && *S2 != '\0') { S1++; S2++; } ! return (*S1 > *S2); ! } ! ! static ! DspList * DirListing (Path, Extension, Entries) ! char * Path, * Extension; ! int * Entries; ! { ! DspList * dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1; ! DIR * dirp; ! struct direct * d; ! int len, ext_len, count = 0; ! char ext[MAXPATHLENGTH]; ! ! if (*Path == '\0') { ! if ((dirp = opendir (".")) == NULL) return (NULL); ! } ! else ! { ! if ((dirp = opendir (Path)) == NULL) return (NULL); ! } ! strcpy (ext, "."); ! strcat (ext, Extension); ! ext_len = strlen (ext); ! head_ptr = tail_ptr = NULL; ! ! while ((d = readdir (dirp)) != NULL) ! { ! len = strlen (d->d_name); ! if (len > ext_len && (strcmp (ext, &d->d_name[len-ext_len]) == 0)) ! { ! d->d_name[len-ext_len] = '\0'; ! dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); ! strcpy (dsp_ptr->itemstr, d->d_name); ! if (head_ptr == NULL) ! head_ptr = tail_ptr = dsp_ptr; ! else ! { ! p1 = NULL; ! for (p = head_ptr; p != NULL; p = p->next) ! if (LargerStr (d->d_name, p->itemstr)) ! p1 = p; ! else ! break; ! ! dsp_ptr->next = p; ! if (p == NULL) ! { /* dsp_ptr has the largest element */ ! tail_ptr->next = dsp_ptr; ! tail_ptr = dsp_ptr; ! } ! else if (p1 == NULL) ! head_ptr = dsp_ptr; ! else ! p1->next = dsp_ptr; ! } ! count++; ! } } ! ! closedir (dirp); ! *Entries = count; ! return (head_ptr); } ! int SelectFileName (Extension, Str, SelStr) ! char * Extension, * Str, * SelStr; { ! register int i, index; ! char s[MAXPATHLENGTH], full_name[MAXPATHLENGTH]; DspList * dsp_ptr; ! sprintf (s, "Generating list of file names, please wait ..."); Msg (s); - strcpy (full_name, curDomainName); ! if ((dsp_ptr = DirListing (curDomainName, Extension, &nameEntries)) == NULL) ! { ! strcpy (s, "No appropriate files to select from."); ! Msg (s); ! *SelStr = '\0'; ! return (INVALID); ! } ! nameDspPtr = MakeNameDspItemArray (nameEntries, dsp_ptr); nameFirst = 0; nameMarked = 0; ! if ((index = Names (Str)) == INVALID) ! *SelStr = '\0'; else ! strcpy (SelStr, nameDspPtr[index]); ! ! for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr); ! cfree (nameDspPtr[0]); cfree (nameDspPtr); ! s[0] = '\0'; ! Msg (s); ! return (index); } static ! DspList * DomainListing (Path, Entries) ! char * Path; int * Entries; { ! DspList * dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1; ! DIR * dirp, * dp; ! struct direct * d; ! struct stat stat_buf; ! int count = 0; ! char path[255], s[255]; ! if (*Path == '\0') ! strcpy (path, "."); ! else ! strcpy (path, Path); ! if ((dirp = opendir (path)) == NULL) return (NULL); - strcat (path, "/"); head_ptr = tail_ptr = NULL; ! ! while ((d = readdir (dirp)) != NULL) { ! strcpy (s, path); ! strcat (s, d->d_name); ! ! stat (s, &stat_buf); ! if (stat_buf.st_mode & S_IFDIR) { ! dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); ! strcpy (dsp_ptr->itemstr, d->d_name); ! if (head_ptr == NULL) ! head_ptr = tail_ptr = dsp_ptr; ! else ! { ! p1 = NULL; ! for (p = head_ptr; p != NULL; p = p->next) ! if (LargerStr (d->d_name, p->itemstr)) ! p1 = p; ! else ! break; ! dsp_ptr->next = p; ! if (p == NULL) ! { /* dsp_ptr has the largest element */ ! tail_ptr->next = dsp_ptr; ! tail_ptr = dsp_ptr; ! } ! else if (p1 == NULL) ! head_ptr = dsp_ptr; else ! p1->next = dsp_ptr; } ! count++; } } - - closedir (dirp); - *Entries = count; return (head_ptr); } --- 1274,1406 ---- } ! int SelectFileName (MsgStr, SelStr) ! char * MsgStr, * SelStr; { ! int index = INVALID, saved_num_dir_entries; ! DspList * dsp_ptr; ! saved_num_dir_entries = numDirEntries; ! if ((index = DirNames (MsgStr, SelStr)) == INVALID) { ! numDirEntries = saved_num_dir_entries; ! dsp_ptr = topOfDirLinkList; ! for ( ; dsp_ptr != NULL; dsp_ptr = dsp_ptr->next) cfree (dsp_ptr); ! topOfDirLinkList = NULL; ! *SelStr = '\0'; ! return (INVALID); } ! BuildDirList (); ! Msg (""); ! return (index); } ! int SelectSymbolName (SelSymName, PathName) ! char * SelSymName, * PathName; { ! register int i, index = INVALID; ! char s[MAXPATHLENGTH], msg[MAXSTRING]; DspList * dsp_ptr; ! sprintf (s, ! "Generating a list of symbol names in '%s' domain, please wait ...", ! curDomainName); Msg (s); ! /* if ((topOfSymLinkList = SymbolListing ()) == NULL) */ ! /* { */ ! /* Msg ("No symbol found!"); */ ! /* SelSymName[0] = '\0'; */ ! /* PathName[0] = '\0'; */ ! /* return (INVALID); */ ! /* } */ ! /* BuildSymbolList (); */ ! nameEntries = numSymbols; ! nameDspPtr = MakeNameDspItemArray (nameEntries, symbolList); nameFirst = 0; nameMarked = 0; ! sprintf (msg, "Please select a symbol to INSTANTIATE in the '%s' domain ...", ! curDomainName); ! if ((index = ChooseAName (msg, SelSymName)) == INVALID) ! { ! *SelSymName = '\0'; ! *PathName = '\0'; ! } else ! { ! strcpy (SelSymName, nameDspPtr[index]); ! strcpy (PathName, symbolList[index].pathstr); ! } ! cfree (*nameDspPtr); cfree (nameDspPtr); ! Msg (""); return (index); } + int GetSymbolPath (SymName, PathName) + char * SymName, * PathName; + { + register int i; + + for (i = 0; i < numSymbols; i++) + if (strcmp (SymName, symbolList[i].itemstr) == 0) + { + strcpy (PathName, symbolList[i].pathstr); + return (TRUE); + } + return (FALSE); + } + static ! DspList * DomainListing (Entries) int * Entries; { ! register int i, default_index = 0; ! char s[MAXSTRING], * c_ptr; ! DspList * dsp_ptr = NULL, * head_ptr, * tail_ptr, * p, * p1; ! if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, "MaxDomains")) == NULL) ! return (NULL); ! *Entries = atoi (c_ptr); head_ptr = tail_ptr = NULL; ! for (i = 0; i < *Entries; i++) { ! sprintf (s, "Domain%1d", i); ! if ((c_ptr = XGetDefault (mainDisplay, TOOL_NAME, s)) == NULL) { ! for ( ; head_ptr != NULL; head_ptr = head_ptr->next) cfree (head_ptr); ! return (NULL); ! } ! dsp_ptr = (DspList *) calloc (1, sizeof(DspList)); ! strcpy (dsp_ptr->itemstr, c_ptr); ! if (head_ptr == NULL) ! head_ptr = tail_ptr = dsp_ptr; ! else ! { ! p1 = NULL; ! for (p = head_ptr; p != NULL; p = p->next) ! if (LargerStr (dsp_ptr->itemstr, p->itemstr)) ! p1 = p; else ! break; ! ! dsp_ptr->next = p; ! if (p == NULL) ! { /* dsp_ptr has the largest element */ ! tail_ptr->next = dsp_ptr; ! tail_ptr = dsp_ptr; } ! else if (p1 == NULL) ! head_ptr = dsp_ptr; ! else ! p1->next = dsp_ptr; } } return (head_ptr); } *************** *** 701,712 **** char * SelStr; { ! register int i, index; ! char s[MAXPATHLENGTH]; ! DspList * dsp_ptr; Msg ("Generating list of domain names, please wait ..."); ! if ((dsp_ptr = DomainListing (curDomainName, &nameEntries)) == NULL) { *SelStr = '\0'; return (INVALID); --- 1409,1421 ---- char * SelStr; { ! int index; ! char s[MAXPATHLENGTH]; ! DspList * dsp_ptr; Msg ("Generating list of domain names, please wait ..."); ! if ((dsp_ptr = DomainListing (&nameEntries)) == NULL) { + Msg ("No domain names found."); *SelStr = '\0'; return (INVALID); *************** *** 717,721 **** nameMarked = 0; ! if ((index = Names ("PLEASE SELECT NEW DOMAIN ...")) == INVALID) *SelStr = '\0'; else --- 1426,1430 ---- nameMarked = 0; ! if ((index = ChooseAName ("Please select a new DOMAIN ...", "")) == INVALID) *SelStr = '\0'; else *************** *** 730,732 **** --- 1439,1465 ---- return (index); + } + + void SetCurDir (FileName) + char * FileName; + { + register int i; + char file_name[MAXPATHLENGTH]; + + if (*FileName != '/') + strcpy (file_name, bootDir); + else + strcpy (file_name, FileName); + + for (i = strlen(file_name)-1; i>=0 && file_name[i]!='/'; i--) ; + + if (i < 0) + TwoLineMsg ("Error: No '/' found in SetCurDir ().", + " curDir and curFileName not set."); + else + { + strcpy (curFileName, &file_name[i+1]); + file_name[i] = '\0'; + strcpy (curDir, file_name); + } } ---------------------------------> cut here <--------------------------------- -- Bill Cheng // UCLA Computer Science Department // (213) 206-7135 3277 Boelter Hall // Los Angeles, California 90024 // USA william@CS.UCLA.EDU ...!{uunet|ucbvax}!cs.ucla.edu!william dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only. -- dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.