mikew@wyse.wyse.com (Mike Wexler) (02/18/89)
Submitted-by: shipley@web.berkeley.edu Posting-number: Volume 3, Issue 14 Archive-name: browserw/part01 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: README AUTHOR Browser.c Browser.h BrowserP.h # ListWidget.patch Makefile browser.3x main.c patchlevel.h # Wrapped by mikew@wyse on Fri Feb 17 09:15:16 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(391 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThis Directory contains the source for a Directory Browser Widget and a Xtest program. For this program to work the Athena List widget must Xwork also I and included a patch that will stop the Athena List widget Xfrom dumping core (this patch dose not fix the problem cause, just the Xsymptom). Please mail any bug (and/or fixes) to: X X shipley@widow.Berkeley.Edu X -or- X ucbvax!widow!shipley END_OF_FILE if test 391 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'AUTHOR' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'AUTHOR'\" else echo shar: Extracting \"'AUTHOR'\" \(713 characters\) sed "s/^X//" >'AUTHOR' <<'END_OF_FILE' X(Message inbox:687) XReturn-Path: shipley%WEB.Berkeley.EDU@lilac.berkeley.edu XReceived: by wyse.wyse.com (5.58/Wyse master/5-13-88) X id AA07715; Sat, 31 Dec 88 03:05:26 PST XFrom: shipley%WEB.Berkeley.EDU@lilac.berkeley.edu XReceived: from lilac.Berkeley.EDU by uunet.UU.NET (5.59/1.14) X id AA02624; Sat, 31 Dec 88 01:00:15 EST XReceived: from web-2e.berkeley.edu X by lilac.berkeley.edu (5.54 (CFC 4.22.3)/1.16.18B) X id AA13855; Fri, 30 Dec 88 21:58:39 PST XReceived: by web-2e.berkeley.edu (3.2/SMI-3.0DEV3.9MXl) X id AA02582; Fri, 30 Dec 88 22:01:50 PST XDate: Fri, 30 Dec 88 22:01:50 PST XMessage-Id: <8812310601.AA02582@web-2e.berkeley.edu> XTo: mikew@wyse.wyse.com XSubject: BrowserWidget X X Xmkdir Browser Xcd Browser END_OF_FILE if test 713 -ne `wc -c <'AUTHOR'`; then echo shar: \"'AUTHOR'\" unpacked with wrong size! fi # end of 'AUTHOR' fi if test -f 'Browser.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Browser.c'\" else echo shar: Extracting \"'Browser.c'\" \(31119 characters\) sed "s/^X//" >'Browser.c' <<'END_OF_FILE' X#if ( !defined(lint) && !defined(Pete_copyright)) X#define Pete_copyright 1 Xstatic char pete_copyright[] = "\ X Copyright 1986 by Peter Shipley All rights reserved\n\ X\n\ X Copy permission is hereby granted provided that this notice is\n\ X retained on all partial or complete copies.\n\ X\n\ X please mail questions and fixes to shipley@widow,berkeley.edu\n"; X#endif X X X#include <stdio.h> X#include <errno.h> X#include <ctype.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/file.h> X#include <sys/param.h> X#include <sys/dir.h> X#include <signal.h> X X#include <X11/Xlib.h> X#include <X11/IntrinsicP.h> X/* X#include <X11/Shell.h> X#include <X11/Form.h> X*/ X#include <X11/cursorfont.h> X/* #include <X11/Xlibint.h> */ X#include <X11/AsciiText.h> X#include <X11/StringDefs.h> X#include <X11/Xos.h> X#include <X11/Xutil.h> X#include <X11/Command.h> X#include <X11/List.h> X#include <X11/Viewport.h> X#include <X11/Xmu.h> X X X#include "BrowserP.h" X X/* Private Definitions */ X Xstatic int def_spacing = 10; X X X /* {name, class, type, size, offset, default_type, default_addr}, */ Xstatic XtResource resources[] = { X {XtNvalue, XtCValue, XtRString, sizeof(String), X XtOffset(BrowserWidget, browser.path), XtRString, NULL}, X {XtNdefaultDistance, XtCThickness, XtRInt, sizeof(int), X XtOffset(BrowserWidget, browser.spacing), XtRInt,(caddr_t)&def_spacing}, X {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(BrowserWidget, browser.sel_callback), XtRCallback, NULL}, X {XtNopenCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(BrowserWidget, browser.can_callback), XtRCallback, NULL}, X {XtNfunction, XtCFunction, XtRFunction, sizeof (XtWorkProc), X XtOffset(BrowserWidget, browser.testProc), XtRFunction, NULL}, X {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), X XtOffset(BrowserWidget, browser.reverse_video), XtRString, "FALSE"} X}; X Xstatic Boolean SetValues(), ConstraintSetValues(); Xstatic XtGeometryResult GeometryManager(); Xstatic list_type *createFileList(); X Xextern int alphasort(); X X Xstatic void CreateLabelWidget(), /* random Widget creation func. */ X CreateFileListWidget(), X CreateErrorWidget(), X CreateCommandButtons(), X X CreateCursors(), X X followdir(), X Bdestroy(), /* callback to deallocate shit */ X /* toolkit failures */ X X UpDateLabel(), /* Update the path label */ X LocalNotify(), /* generic callback */ X#ifdef DEBUG X showList(), /* DEBUG func. (prints current list) */ X#endif DEBUG X X prev_callback(), X next_callback(), X path_completion(), X kill_callback(), X X dummy(), /* a do nothing func. */ X X _openCall(), /* callback for open button */ X _cancelCall(), /* callback for cancel button */ X X ChangeManaged(), X Initialize(), X Resize(), X Realize(), X RefigureLocations(), X ConstraintInitialize(), X X showError(), X clearError(), X X SetWorkState(), X X deleteList(); /* de-allocate current list */ X X#ifdef DEBUG X#define printList(X) (void) fprintf(stderr, \ X "list->count = %d\tmin = '%s'\tmax = '%s'\n", \ X X->count, X->namelist[0], X->namelist[X->count -1]); X#endif DEBUG X X X X XBrowserClassRec browserClassRec = { X { /* core_class fields */ X /* superclass */ (WidgetClass) &compositeClassRec, X /* class_name */ "Browser", X /* widget_size */ sizeof(BrowserRec), X /* class_initialize */ NULL, X /* class_part_init */ NULL, X /* class_inited */ FALSE, X /* initialize */ Initialize, X /* initialize_hook */ NULL, X /* realize */ Realize, X /* actions */ NULL, X /* num_actions */ 0, X /* resources */ resources, X /* num_resources */ XtNumber(resources), X /* xrm_class */ NULLQUARK, X /* compress_motion */ TRUE, X /* compress_exposure */ TRUE, X /* compress_enterleave*/ TRUE, X /* visible_interest */ FALSE, X /* destroy */ Bdestroy, X /* resize */ Resize, X /* expose */ XtInheritExpose, X /* set_values */ SetValues, X /* set_values_hook */ NULL, X /* set_values_almost */ XtInheritSetValuesAlmost, X /* get_values_hook */ NULL, X /* accept_focus */ NULL, X /* version */ XtVersion, X /* callback_private */ NULL, X /* tm_table */ NULL, X /* query_geometry */ XtInheritQueryGeometry, /* %%% fix this! */ X /* display_accelerator*/ XtInheritDisplayAccelerator, X /* extension */ NULL X }, X { /* composite_class fields */ X /* geometry_manager */ GeometryManager, X /* change_managed */ NULL, /* ChangeManaged, */ X /* insert_child */ XtInheritInsertChild, X /* delete_child */ XtInheritDeleteChild, X /* extension */ NULL X }, X { /* browser_class fields */ X /* empty */ 0 X } X}; X XWidgetClass browserWidgetClass = (WidgetClass)&browserClassRec; X X/**************************************************************** X * X * Private Procedures X * X ****************************************************************/ X Xstatic void CreateCursors(br) XBrowserWidget br; X{ X Xstatic XColor b = { 0, 0, 0, 0 }; /* black */ Xstatic XColor f = { 0, 65535, 65535, 65535 }; /* white */ X X#ifdef nodef XXColor f, b; X X if (XtDisplay(br)->cursor_font == None) { X XtDisplay(br)->cursor_font = XLoadFont (XtDisplay(br), CURSORFONT); X if (XtDisplay(br)->cursor_font) { X XtWarning("failed to open cursor_font"); X return; X } X } X X if(br->browser.reverse_video) { X f = foreground; X b = background; X } else { X b = foreground; X f = background; X } X X br->browser.ArrowCursor = XCreateGlyphCursor(XtDisplay(br), X XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font, X XC_left_ptr, XC_left_ptr +1, &f, &b); X X br->browser.CrossCursor = XCreateGlyphCursor(XtDisplay(br), X XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font, X XC_cross, XC_cross +1, &f, &b); X X br->browser.ClockCursor = XCreateGlyphCursor(XtDisplay(br), X XtDisplay(br)->cursor_font, XtDisplay(br)->cursor_font, X XC_watch, XC_watch +1, &f, &b); X#endif nodef X X /* get the standard Cursors */ X br->browser.ArrowCursor = XCreateFontCursor(XtDisplay(br), XC_left_ptr); X br->browser.CrossCursor = XCreateFontCursor(XtDisplay(br), XC_cross); X br->browser.ClockCursor = XCreateFontCursor(XtDisplay(br), XC_watch); X X /* recolor cursor is we are displayed in reverse video. */ X if(br->browser.reverse_video) { X XRecolorCursor(XtDisplay(br), br->browser.CrossCursor, &f, &b); X XRecolorCursor(XtDisplay(br), br->browser.ClockCursor, &f, &b); X } X X return; X} X X/* ARGSUSED */ Xstatic void Initialize(request, new) X Widget request, new; X{ X BrowserWidget br = (BrowserWidget)new; X X X if(br->core.width == 0) br->core.width = 400; X if(br->core.height == 0) br->core.height = 350; X X /* allocate room for path data */ X br->browser.labelpath = XtMalloc(MAXPATHLEN); X br->browser.basepath = XtMalloc(MAXPATHLEN); X X /* labelpath NEEDS to be NULL */ X bzero(br->browser.labelpath, MAXPATHLEN); X X /* copy the base into an interal string */ X (void) strcpy(br->browser.basepath, br->browser.path); X X CreateCursors(br); X X /* get the dirt on the basepath */ X br->browser.list = (list_type *) createFileList(br, br->browser.path); X X#ifdef DEBUG X showList(br->browser.list); X#endif DEBUG X X /* Guess what these do ... */ X CreateLabelWidget(br); X X CreateErrorWidget(br); X X CreateFileListWidget(br); X X CreateCommandButtons(br); X X /* set the Keyboard Focus */ X XtSetKeyboardFocus(br, br->browser.b_label); X X /* display the current path */ X UpDateLabel(br, TRUE); X X return; X} X X Xstatic void CreateLabelWidget(br) XBrowserWidget br; X{ XXtTranslations text_tran; X X static String newtextTranslations = X "Ctrl<Key>W: prev_callback()\n\ X Ctrl<Key>M: next_callback()\n\ X Ctrl<Key>J: next_callback()\n\ X <Key>0xFF0D: next_callback()\n\ X <Key>0xFF0A: next_callback()\n\ X Meta<Key>I: dummy()\n\ X Ctrl<Key>C: kill_callback()\n\ X <Key>0xFF1B: path_completion()\n\ X Ctrl<Key>[: path_completion()\n"; X X static XtActionsRec newtext_actions[] = { X {"prev_callback", prev_callback}, X {"next_callback", next_callback}, X {"path_completion", path_completion}, X {"kill_callback", kill_callback}, X {"dummy", dummy} X }; X X static Arg label_arg[] = { X {XtNstring, (XtArgVal) NULL}, X {XtNcursor, (XtArgVal) NULL}, X {XtNlength, (XtArgVal) MAXPATHLEN}, X {XtNtextOptions, (XtArgVal) editable}, X {XtNeditType, (XtArgVal) XttextEdit}, X {XtNjustify, (XtArgVal) XtJustifyLeft}, X {XtNborderWidth, (XtArgVal) 0}, X {XtNresize, (XtArgVal) FALSE} X }; X X label_arg[0].value = (XtArgVal) br->browser.labelpath; X label_arg[1].value = (XtArgVal) br->browser.CrossCursor; X X br->browser.b_label = XtCreateManagedWidget("Browser_label", X asciiStringWidgetClass, br, label_arg, XtNumber(label_arg)); X X /* install the new actions record */ X XtAddActions(newtext_actions, XtNumber(newtext_actions)); X X /* creat a Translation Table */ X text_tran = XtParseTranslationTable(newtextTranslations); X X /* install the new Translation Table */ X XtOverrideTranslations(br->browser.b_label, text_tran); X X return; X} X X Xstatic void CreateFileListWidget(br) XBrowserWidget br; X{ XXtTranslations list_trans; X X static Arg view_args[] = { X {XtNallowVert, (XtArgVal) TRUE}, X {XtNforceBars, (XtArgVal) TRUE}, X {XtNresize, (XtArgVal) FALSE}, X {XtNuseRight, (XtArgVal) TRUE} X }; X X static String newTranslations = X "<Btn1Down>: Set()\n\ X <Btn1Down>(2+): Notify()\n"; X X static XtCallbackRec list_call[] = { X {(XtCallbackProc) _openCall, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X }; X X static Arg list_args[] = { X {XtNlist, (XtArgVal) NULL}, X {XtNnumberStrings, (XtArgVal) NULL}, X {XtNcallback, (XtArgVal) list_call}, X {XtNverticalList, (XtArgVal) TRUE}, X {XtNforceColumns, (XtArgVal) 1}, X {XtNdefaultColumns, (XtArgVal) 1}, X {XtNcolumnSpacing, (XtArgVal) 1000} X }; X X X list_call[0].closure = (caddr_t) br; X X list_args[0].value = (XtArgVal) br->browser.list->list; X list_args[1].value = (XtArgVal) br->browser.list->count; X X /* create a viewport widget so the list widget will have scrollbars */ X br->browser.b_view = XtCreateManagedWidget( "view", viewportWidgetClass, X br, view_args, XtNumber(view_args)); X X /* Create the list widget at a child of the viewport widget */ X br->browser.b_list = XtCreateManagedWidget( "list", listWidgetClass, X br->browser.b_view, list_args, XtNumber(list_args)); X X /* Parse the replacement TranslationTable and install it */ X list_trans = XtParseTranslationTable(newTranslations); X XtOverrideTranslations(br->browser.b_list, list_trans); X X return; X} X Xstatic void CreateErrorWidget(br) XBrowserWidget br; X{ X static Arg error_list[] = { X {XtNjustify, (XtArgVal) XtJustifyLeft}, X {XtNborderWidth, (XtArgVal) 0}, X {XtNresize, (XtArgVal) FALSE}, X {XtNlabel, (XtArgVal) ">"} X }; X X br->browser.b_error = XtCreateManagedWidget("error", labelWidgetClass, X br, error_list, XtNumber(error_list)); X return; X} X X Xstatic void CreateCommandButtons(br) XBrowserWidget br; X{ X static XtCallbackRec cancel_call[] = { X {(XtCallbackProc) _cancelCall, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X }; X X static XtCallbackRec open_call[] = { X {(XtCallbackProc) _openCall, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X }; X X static Arg comm_args[] = { X {XtNcursor, (XtArgVal) NULL}, X {XtNlabel, (XtArgVal) "Open"}, X {XtNcallback, (XtArgVal) open_call}, X {XtNresize, (XtArgVal) FALSE}, X {XtNresizable, (XtArgVal) FALSE}, X {XtNwidth, (XtArgVal) 70} X }; X X comm_args[0].value = (XtArgVal) br->browser.ArrowCursor; X X /* compleate the callback data arrays */ X open_call[0].closure = cancel_call[0].closure = (caddr_t) br; X X /* create the open button */ X br->browser.b_open = XtCreateManagedWidget( "open", commandWidgetClass, X br, comm_args, XtNumber(comm_args) ); X X /* reuses the arg array for the Cancel button */ X comm_args[1].value = (XtArgVal) "Cancel"; X comm_args[2].value = (XtArgVal) cancel_call; X X /* and now the Cancel command button */ X br->browser.b_cancel = XtCreateManagedWidget( "Cancel", commandWidgetClass, X br, comm_args, XtNumber(comm_args)); X X return; X} X X Xstatic void RefigureLocations(wi) X BrowserWidget wi; X{ X BrowserWidget br = (BrowserWidget)wi; X X Position x, y, y1; X X#ifdef DEBUG X (void) fputs("RefigureLocations called\n", stderr); X#endif DEBUG X X /* first we do the label bar */ X XtConfigureWidget(br->browser.b_label, X br->browser.spacing, br->browser.spacing, /* x & y*/ X br->core.width -(br->browser.spacing *2) /* width */ X -(br->browser.b_label->core.border_width *2), X br->browser.b_label->core.height, /* height */ X br->browser.b_label->core.border_width); /* border */ X X /* here we calc the Y Position for the selection list & buttons */ X y1 = br->browser.b_label->core.height X +(br->browser.spacing *2) X +(br->browser.b_label->core.border_width *2); X X X /* calc the X Position for the buttons */ X x = br->core.width -br->browser.spacing -br->browser.b_cancel->core.width; X X /* Position the first button */ X XtMoveWidget(br->browser.b_open, x, y1); X X XtMoveWidget(br->browser.b_cancel, x, X y1 +br->browser.spacing X +br->browser.b_open->core.height X +(br->browser.b_open->core.border_width *2)); X X X /* here we calc the Y Position error area */ X y = br->core.height -br->browser.spacing -br->browser.b_error->core.height X -(br->browser.b_error->core.border_width *2); X X XtConfigureWidget(br->browser.b_error, X br->browser.spacing, y, /* x & y */ X br->core.width -(br->browser.spacing *2) /* width */ X -(br->browser.b_error->core.border_width *2), X br->browser.b_error->core.height, /* height */ X br->browser.b_error->core.border_width); /* border */ X X X X XtConfigureWidget(br->browser.b_view, X br->browser.spacing, y1, /* x & y */ X x -(br->browser.b_view->core.border_width *2) /* width */ X -(br->browser.spacing *2), X y -(br->browser.b_view->core.border_width *2) /* height */ X -y1 -br->browser.spacing, X br->browser.b_view->core.border_width); /* border */ X X /* done */ X return; X} X X Xstatic void Realize(wi, value_mask, attributes) XWidget wi; XMask *value_mask; XXSetWindowAttributes *attributes; X{ X X#ifdef DEBUG X (void) fputs("Realize called\n", stderr); X#endif DEBUG X X XtCreateWindow(wi, (unsigned int) InputOutput, X (Visual *) CopyFromParent, *value_mask, attributes); X X RefigureLocations((BrowserWidget) wi); X X XDefineCursor(XtDisplay(wi), XtWindow(wi), X ((BrowserWidget) wi)->browser.CrossCursor); X X return; X} X X Xstatic void Resize(w) X Widget w; X{ X X#ifdef DEBUG X (void) fputs("Resize called\n", stderr); X#endif DEBUG X X RefigureLocations((BrowserWidget) w); X X return; X} X X X/* ARGSUSED */ Xstatic XtGeometryResult GeometryManager(w, request, reply) X Widget w; X XtWidgetGeometry *request; X XtWidgetGeometry *reply; /* RETURN */ X{ X#ifdef DEBUG X (void) fprintf(stderr, "GeometryManager called: %s\n", w->core.name); X#endif DEBUG X X return XtGeometryNo; X} X X X X/* ARGSUSED */ Xstatic Boolean SetValues(current, request, new) X Widget current, request, new; X{ X BrowserWidget br = (BrowserWidget)new; X BrowserWidget old = (BrowserWidget)current; X X#ifdef DEBUG X (void) fputs("SetValues called\n", stderr); X#endif DEBUG X X if(br->browser.path != old->browser.path X || br->browser.path != NULL X && (old->browser.path != NULL X && strcmp(br->browser.path, old->browser.path))) X { X /* delete the old list */ X deleteList(old->browser.list); X X /* copy the new path into a safe area */ X (void) strcpy(br->browser.basepath, br->browser.path); X X /* create list of file to select from */ X br->browser.list = createFileList(br, br->browser.path); X X /* Update the displayed list */ X XtListChange(br->browser.b_list, br->browser.list->list, X br->browser.list->count, 0, TRUE); X X /* update the displayed label */ X UpDateLabel(br, TRUE); X X } X X return( FALSE ); X} X X/* this is the util. for creating file listings */ Xstatic list_type *createFileList(br, selection) XBrowserWidget br; Xchar *selection; X{ Xregister Cardinal i; Xstruct stat stat_buf; Xlist_type *ret_list; Xextern errno; X X errno = 0; X X /* open requested directory */ X if (selection == (char *) NULL) X selection = "."; X X /* malloc the return list */ X ret_list = (list_type *) XtMalloc(sizeof (list_type)); X X X /* report fuckups */ X if (ret_list == NULL) { X return (list_type *) NULL; X } X X ret_list->count = X scandir(selection, &ret_list->namelist, br->browser.testProc, X alphasort); X X /* test the scaning */ X if(ret_list->count == -1) { X#ifdef DEBUG X XtWarning("Fucked up in opening dir"); X#endif DEBUG X XtFree((char *) ret_list); X return (list_type *) NULL; X } X X ret_list->list = (char **)XtCalloc(ret_list->count +1, sizeof(char *)); X ret_list->mode = (int *) XtCalloc(ret_list->count, sizeof(int)); X X for(i=0; i < ret_list->count; i++) { X int len; X char tbuf[MAXNAMLEN +2]; X X /* get the length of the file name for later use [and reuse] */ X len = strlen(ret_list->namelist[i]->d_name) + 2; X X /* copy file name into a new buffer */ X ret_list->list[i] = X strcpy( XtMalloc(len), ret_list->namelist[i]->d_name); X X /* copy the current directory into a tempory space */ X (void) strcpy(tbuf, selection); X X /* add a "/" to the current directory path if it's not there already */ X if (tbuf[strlen(tbuf) -1] != '/') X (void) strcat(tbuf, "/"); X X /* tack on the current file name */ X (void) strcat(tbuf, ret_list->list[i]); X X /* get the status of our 'file', if we fail ignore the file */ X if ( stat(tbuf, &stat_buf) != 0 ) { X#ifdef DEBUG X (void) perror(ret_list->namelist[i]->d_name); X XtWarning("Fucked up in stating file"); X#endif DEBUG X showError(br, ret_list->list[i]); X continue; X } X X ret_list->mode[i] = stat_buf.st_mode; X X /* add the '/' to the end of the name to indicate directrices, etc..*/ X switch (ret_list->mode[i] & S_IFMT) { X case S_IFDIR: X (void) strcat(ret_list->list[i], "/"); X break; X case S_IFSOCK: X (void) strcat(ret_list->list[i], "="); X break; X default: X if ( (stat_buf.st_mode & ~S_IFMT) & 0111) X (void) strcat(ret_list->list[i], "*"); X break; X } X } X X /* null out the next slot [it should be null from calloc but..] */ X ret_list->list[i +1] = (char *) NULL; X X#ifdef DEBUG X printList(ret_list); X#endif DEBUG X X /* return with our work */ X return ret_list; X} X X X/* A clean up utility */ Xstatic void deleteList(dead_list) Xlist_type *dead_list; X{ Xregister int i; X X /* Test to see it we have a list */ X if(dead_list == (list_type *) NULL) X return; X X /* free the strings */ X for(i=0; i < dead_list->count; i++) { X XtFree( (char *) dead_list->list[i]); X } X X XtFree((char *) dead_list->namelist); X XtFree((char *) dead_list->list); X XtFree((char *) dead_list); X X return; X} X X X X/*ARGUSED*/ Xstatic void _cancelCall(wi, client_data, call_data) XWidget wi; Xcaddr_t client_data; Xcaddr_t call_data; X{ XBrowserWidget br = (BrowserWidget)client_data; X X /* Change the Cursors to a clock so the they think we're fuckup */ X SetWorkState(br, TRUE); X X /* Clear the error line*/ X clearError(br); X X XtCallCallbacks((Widget) br, XtNcancelCallback, (char *) NULL); X X /* Tell the user we are done */ X SetWorkState(br, FALSE); X X return; X} X X X/*ARGUSED*/ Xstatic void _openCall(wi, client_data, call_data) XWidget wi; Xcaddr_t client_data; Xcaddr_t call_data; X{ Xint i; XXtListReturnStruct *ret_value; XBrowserWidget br = (BrowserWidget)client_data; X X /* Clear the error line*/ X clearError(br); X X /* get the current selected list */ X ret_value = XtListShowCurrent(br->browser.b_list); X i = ret_value->index; X X /* free as soon as we don't need */ X XtFree((char *)ret_value); X X X /* test to see it there is a current seletion */ X if( i != XT_LIST_NONE ) { X X /* Change the Cursors to a clock so the they think we're fuckup */ X SetWorkState(br, TRUE); X X /* test if we are looking at a directory or not */ X if ( br->browser.list->mode[i] & (S_IFMT & S_IFDIR) ) X followdir(br, br->browser.list->namelist[i]->d_name); X else X XtCallCallbacks((Widget) br, XtNopenCallback, X br->browser.list->namelist[i]->d_name); X X /* Tell the user we are done */ X SetWorkState(br, FALSE); X X } X X return; X} X X X X Xstatic void followdir(br, new_path) XBrowserWidget br; XString new_path; X{ Xregister u_int i; Xchar *c; Xchar t_path[MAXPATHLEN]; Xlist_type *t_list; X X /* reset the error index */ X clearError(br); X X#ifdef DEBUG X (void) fputs("followdir\n", stderr); X#endif DEBUG X X /* just in case save the old path and lists */ X (void) strcpy(t_path, br->browser.basepath); X t_list = br->browser.list; X X /* see it we are just backing up one dir, there has to be a better way.. */ X if( strncmp(new_path, "..", 2) == 0 ) { X X /* get the last occurance of the char '/' in the string */ X c = rindex(br->browser.basepath, '/'); X X /* report if it is not possible to back out */ X if(c == (char *)NULL) { X showError(br, "Burp!: could not track '/'"); X return; X } X X /* check if we index'ed to root's "/" */ X if ( c == br->browser.basepath ) { X (void) strcpy(br->browser.basepath, "/"); X } else { X /* Null out the rest of the string */ X while( *c != '\0') *c++ = '\0'; X } X X } else { X X i = strlen(br->browser.basepath) -1; X X if (br->browser.basepath[i] != '/') X (void) strcat(br->browser.basepath, "/"); X X (void) strcat(br->browser.basepath, new_path); X X i = strlen(br->browser.basepath) -1; X X if (br->browser.basepath[i] == '/') X br->browser.basepath[i] = (char) NULL; X } X X /* create a new list of files useing the new base path */ X br->browser.list = createFileList(br, br->browser.basepath); X X /* Test the new list, if error report it and restore old values */ X if (br->browser.list == (list_type *) NULL) { X showError(br, br->browser.basepath); X (void) strcpy(br->browser.basepath, t_path); X br->browser.list = t_list; X return; X } X X /* free the storage used by the current list */ X deleteList(t_list); X X#ifdef DEBUG X showList(br->browser.list); X (void) fprintf(stderr, "basepath = `%s`\n", br->browser.basepath); X#endif DEBUG X X /* Update the path label with the new path */ X UpDateLabel(br, TRUE); X X /* Update the listing with the new list */ X XtListChange(br->browser.b_list, br->browser.list->list, br->browser.list->count, 0, TRUE); X X return; X} X X#ifdef DEBUG Xstatic void showList(ll) Xlist_type *ll; X{ Xregister int i; X X for (i=0; i < ll->count; i++) X (void) fprintf(stderr, X "%d:\tlist->list[i] = `%s`\tnamelist[i]->d_name= `%s`\tmode = %lo\n", X i, ll->list[i], ll->namelist[i]->d_name, ll->mode[i]); X X printList(ll); X X return; X} X#endif DEBUG X Xstatic void UpDateLabel(br, copy) XBrowserWidget br; XBoolean copy; X{ XXtTextPosition len; X X /* Unset whatever maybe highlighted */ X XtTextUnsetSelection(br->browser.b_label); X X /* copy the real path in the shown path */ X if(copy) X (void) strcpy(br->browser.labelpath, br->browser.basepath); X X /* get the length of the current path */ X len = (XtTextPosition) strlen(br->browser.labelpath); X X /* set the last position in the buffer */ X XtTextSetLastPos(br->browser.b_label, len); X X /* move the Cursor to the last position in the buffer */ X XtTextSetInsertionPoint(br->browser.b_label, len); X X return; X} X X/* this is the callback for our widget when it it is destroyed */ Xstatic void Bdestroy(wi) XWidget wi; X{ X BrowserWidget br = (BrowserWidget)wi; X X#ifdef DEBUG X (void) fputs("Bdestroy called\n", stderr); X#endif DEBUG X X deleteList(br->browser.list); X X XtFree(br->browser.basepath); X XtFree(br->browser.labelpath); X X XFreeCursor(br->browser.ArrowCursor); X XFreeCursor(br->browser.CrossCursor); X XFreeCursor(br->browser.ClockCursor); X X return; X} X Xstatic void Xprev_callback(wi) XWidget wi; X{ Xchar *c; XBrowserWidget br = (BrowserWidget)XtParent(wi); X X /* clear the error window */ X clearError(br); X X /* get the last occurance of the char '/' in the string */ X c = rindex(br->browser.labelpath, '/'); X X /* report if it is not possible to back out */ X if(c == (char *)NULL) { X showError(br, "Burp!: could not track '/'"); X XBell(XtDisplay(br), 0); X return; X } X X /* check if we index'ed to root's "/" */ X if ( c == br->browser.labelpath ) { X (void) strcpy(br->browser.labelpath, "/"); X } else { X /* Null out the rest of the string */ X while( *c != '\0') *c++ = '\0'; X } X X /* have the label reflect the change */ X UpDateLabel(br, FALSE); X X return; X} X Xstatic void next_callback(wi) XWidget wi; X{ Xstruct stat stat_buf; XBrowserWidget br = (BrowserWidget)XtParent(wi); X X#ifdef DEBUG X (void) fputs("next_callback called\n", stderr); X#endif DEBUG X X /* turn off input and set the cursors to a clock */ X SetWorkState(br, TRUE); X X /* clear the error window */ X clearError(br); X X /* get the status of our 'file', if we fail ignore the file */ X if ( stat(br->browser.labelpath, &stat_buf) != 0 ) { X showError(br, br->browser.labelpath); X } X X if (stat_buf.st_mode & (S_IFMT & S_IFDIR) ) { X list_type *t_list = br->browser.list; X X br->browser.list = createFileList(br, br->browser.labelpath); X X /* Test the new list */ X if (br->browser.list == (list_type *) NULL) { X X /* (void) strcpy(br->browser.basepath, t_path); */ X br->browser.list = t_list; X showError(br, br->browser.labelpath); X SetWorkState(br, FALSE); X return; X } X X /* Update the listing with the new list */ X XtListChange(br->browser.b_list, br->browser.list->list, X br->browser.list->count, 0, TRUE); X X (void) strcpy(br->browser.basepath, br->browser.labelpath); X X /* this should not be needed */ X UpDateLabel(br, FALSE); X X } else X XtCallCallbacks(br, XtNopenCallback, br->browser.labelpath); X X SetWorkState(br, FALSE); X X return; X} X Xstatic void path_completion(wi) XWidget wi; X{ Xchar *c; Xint len; Xint dir_count; Xu_int i; Xu_int hit=0; Xchar selection[MAXPATHLEN]; Xchar name[MAXNAMLEN]; Xstruct direct **dir_list; XBoolean free; XBrowserWidget br = (BrowserWidget)XtParent(wi); X X X#ifdef DEBUG X (void) fputs("path_completion called\n", stderr); X#endif DEBUG X X clearError(br); X X /* get the last occurance of the char '/' in the string */ X c = rindex(br->browser.labelpath, '/'); X X /* report if it is not possible to back out */ X if(c == (char *)NULL) { X c = br->browser.labelpath; X /* X showError(br, "Burp!: could not track '/'"); X return; X */ X } X X /* move forward to skip the '/' */ X *c++; X X len = strlen(c); X X /* we will have trouble it these strings are not nulled */ X bzero(name, MAXNAMLEN); X bzero(selection, MAXPATHLEN); X X (void) strncpy(selection, br->browser.labelpath, X ((int)c -(int)br->browser.labelpath)); X X if (strcmp(selection, br->browser.basepath) == 0) { X dir_count = br->browser.list->count; X dir_list = br->browser.list->namelist; X free = FALSE; X } else { X dir_count = scandir(selection, &dir_list, br->browser.testProc, X alphasort); X X if ( dir_count == -1) { X showError(br, selection); X return; X } X X free = TRUE; X } X X /* Enter Loop only if there is something to do */ X if (len > 0) { X for(i=0; i < dir_count; i++) X if ( strncmp(c, dir_list[i]->d_name, len) == 0) { X /* if this is the first match copy if in full */ X hit++; X if(hit == 1) X (void) strcpy(name, dir_list[i]->d_name); X else { X register int j=0; X X for(; dir_list[i]->d_name[j] == name[j]; j++); X X name[j] = '\0'; X X if(j == len) X break; X } X } X X X /* Ugly Ugly Ugly */ X if(hit == 0) { X X XBell(XtDisplay(br), 0); X showError(br, "No matches found"); X X } else { X X /* if we matched more then once ring bell */ X if(hit > 1) { X char tbuf[MAXPATHLEN]; X X (void) strcpy(tbuf, "\""); X (void) strcat(tbuf, c); X (void) strcat(tbuf, "\": ambiguous"); X X XBell(XtDisplay(br), 0); X showError(br, tbuf); X } X X /* if we matched ANYTHING add the result to the current path*/ X if(hit) { X (void) strcpy(c, name); X UpDateLabel(br, FALSE); X } X } X X X } X X if(free) X XtFree((char *) dir_list); X X return; X} X Xstatic void dummy() X{ X#ifdef DEBUG X (void) fputs("dummy called\n", stderr); X#endif DEBUG X return; X} X X/* this is call if the user types in a Cont-C */ Xstatic void kill_callback(wi) XWidget wi; X{ XBrowserWidget br = (BrowserWidget)XtParent(wi); X X XtCallCallbacks(br, XtNcancelCallback, NULL); X X return; X} X Xstatic void clearError(br) XBrowserWidget br; X{ X X static Arg update_arg[] = { X {XtNlabel, (XtArgVal) ">"} X }; X X errno = 0; X X#ifdef DEBUG X (void) fputs("clearError called\n", stderr); X#endif DEBUG X X XtSetValues(br->browser.b_error, update_arg, XtNumber(update_arg)); X X return; X} X X X/* X * This func displays the current error in X * a error window on the browser window X */ Xstatic void showError(br, string) XBrowserWidget br; Xchar *string; X{ Xchar tbuf[MAXPATHLEN +80]; Xextern char *sys_errlist[]; Xextern int sys_nerr; Xextern int errno; X X static Arg update_arg[] = { X {XtNlabel, (XtArgVal) NULL} X }; X X if (string != (char *) NULL) X (void) strcpy(tbuf, string); X else X (void) strcpy(tbuf, "Error"); X X#ifdef DEBUG X (void) perror(tbuf); X#endif DEBUG X X if (errno > 0 && errno < sys_nerr) { X (void) strcat(tbuf, ": "); X (void) strcat(tbuf, sys_errlist[errno]); X } X X update_arg[0].value = (XtArgVal) tbuf; X X XBell(XtDisplay(br), 0); X X if(XtIsRealized(br)) X XtSetValues(br->browser.b_error, update_arg, XtNumber(update_arg)); X X return; X} X Xstatic void SetWorkState(br, state) XBrowserWidget br; XBoolean state; X{ X X if (state) { X XDefineCursor(XtDisplay(br), XtWindow(br), br->browser.ClockCursor); X XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_list), X br->browser.ClockCursor); X XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_label), X br->browser.ClockCursor); X X X XtSetSensitive(br->browser.b_open, FALSE); X XtSetSensitive(br->browser.b_label, FALSE); X XtSetSensitive(br->browser.b_cancel, FALSE); X X } else { X X XDefineCursor(XtDisplay(br), XtWindow(br), br->browser.CrossCursor); X XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_list), X br->browser.ArrowCursor); X XDefineCursor(XtDisplay(br), XtWindow(br->browser.b_label), X br->browser.CrossCursor); X X XtSetSensitive(br->browser.b_open, TRUE); X XtSetSensitive(br->browser.b_label, TRUE); X XtSetSensitive(br->browser.b_cancel, TRUE); X } X X return; X} X X/********************************************************************** X * X * Public routines X * X **********************************************************************/ X X/* none */ X X X/* END OF TEXT */ END_OF_FILE if test 31119 -ne `wc -c <'Browser.c'`; then echo shar: \"'Browser.c'\" unpacked with wrong size! fi # end of 'Browser.c' fi if test -f 'Browser.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Browser.h'\" else echo shar: Extracting \"'Browser.h'\" \(2121 characters\) sed "s/^X//" >'Browser.h' <<'END_OF_FILE' X#if ( !defined(lint) && !defined(Pete_copyright)) X#define Pete_copyright 1 Xstatic char pete_copyright[] = "\ X Copyright 1986 by Peter Shipley All rights reserved\n\ X\n\ X Copy permission is hereby granted provided that this notice is\n\ X retained on all partial or complete copies.\n\ X\n\ X please mail questions and fixes to shipley@widow,berkeley.edu\n"; X#endif X X#ifndef _Browser_h X#define _Browser_h X X#include <X11/Constraint.h> X X/*********************************************************************** X * X * Browser Widget X * X ***********************************************************************/ X X/* Parameters: X X Name Class RepType Default Value X ---- ----- ------- ------------- X background Background Pixel XtDefaultBackground X border BorderColor Pixel XtDefaultForeground X borderWidth BorderWidth Dimension 1 X defaultDistance Thickness int 4 X destroyCallback Callback Pointer NULL X height Height Dimension computed at realize X mappedWhenManaged MappedWhenManaged Boolean True X sensitive Sensitive Boolean True X width Width Dimension computed at realize X x Position Position 0 X y Position Position 0 X X*/ X X/* Constraint parameters: X X Name Class RepType Default Value X ---- ----- ------- ------------- X bottom Edge XtEdgeType XtRubber X fromHoriz Widget Widget (left edge of browser) X fromVert Widget Widget (top of browser) X horizDistance Thickness int defaultDistance X left Edge XtEdgeType XtRubber X resizable Boolean Boolean False X right Edge XtEdgeType XtRubber X top Edge XtEdgeType XtRubber X vertDistance Thickness int defaultDistance X X*/ X X X X#define XtNopenCallback "openCallback" X#define XtNcancelCallback "cancelCallback" X X#define XtNdefaultDistance "defaultDistance" X#define XtNresizable "resizable" X X#define XtCEdge "Edge" X#define XtCWidget "Widget" X X#define XtRWidget "Widget" X Xtypedef struct _BrowserClassRec *BrowserWidgetClass; Xtypedef struct _BrowserRec *BrowserWidget; X Xextern WidgetClass browserWidgetClass; X X#endif _Browser_h X END_OF_FILE if test 2121 -ne `wc -c <'Browser.h'`; then echo shar: \"'Browser.h'\" unpacked with wrong size! fi # end of 'Browser.h' fi if test -f 'BrowserP.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'BrowserP.h'\" else echo shar: Extracting \"'BrowserP.h'\" \(2195 characters\) sed "s/^X//" >'BrowserP.h' <<'END_OF_FILE' X#if ( !defined(lint) && !defined(Pete_copyright)) X#define Pete_copyright 1 Xstatic char pete_copyright[] = "\ X Copyright 1986 by Peter Shipley All rights reserved\n\ X\n\ X Copy permission is hereby granted provided that this notice is\n\ X retained on all partial or complete copies.\n\ X\n\ X please mail questions and fixes to shipley@widow,berkeley.edu\n"; X#endif X/* Browser widget private definitions */ X X#ifndef _BrowserP_h X#define _BrowserP_h X X#include "Browser.h" X#include <X11/CompositeP.h> X Xtypedef struct {int empty;} BrowserClassPart; X Xtypedef struct _BrowserClassRec { X CoreClassPart core_class; X CompositeClassPart composite_class; X BrowserClassPart browser_class; X} BrowserClassRec; X Xextern BrowserClassRec browserClassRec; X X Xtypedef struct _list_type { X char **list; /* a list of strings for listWidget*/ X struct direct **namelist; X int count; X int *mode; X} list_type; X X Xtypedef struct _BrowserPart { X String basepath; /* Current scaned path */ X String labelpath; /* Current displayed scaned path */ X String path; /* starting path */ X X Widget b_view; /* Viewport widget for scrollbar*/ X Widget b_list; /* listWidget, child of Viewport */ X Widget b_open; /* "Open" command widget */ X Widget b_cancel; /* "Cancel" command widget */ X Widget b_label; /* path label */ X Widget b_error; /* error output */ X X int spacing; X X XtWorkProc testProc; /* pointer to fun that returns Boolean X takes a String for a arg and test X if it should be included in X selection list */ X Boolean reverse_video; X X Cursor ArrowCursor; /* Cursor for list & command widget */ X Cursor CrossCursor; /* Cursor for formWidget */ X Cursor ClockCursor; /* Wait Cursor list & command widget */ X X XtCallbackList sel_callback; /* callback func. for Cancel widget */ X XtCallbackList can_callback; /* callback func. for Open widget */ X X list_type *list; /* struct containing list data */ X X} BrowserPart; X Xtypedef struct _BrowserRec { X CorePart core; X CompositePart composite; X BrowserPart browser; X} BrowserRec; X X#endif _BrowserP_h END_OF_FILE if test 2195 -ne `wc -c <'BrowserP.h'`; then echo shar: \"'BrowserP.h'\" unpacked with wrong size! fi # end of 'BrowserP.h' fi if test -f 'ListWidget.patch' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ListWidget.patch'\" else echo shar: Extracting \"'ListWidget.patch'\" \(170 characters\) sed "s/^X//" >'ListWidget.patch' <<'END_OF_FILE' X447,453d446 X< if ( item >= lw->list.nitems ) { X< #ifdef DEBUG X< XtWarning("ListWidget: HighlightBackground: item > nitems\n"); X< #endif DEBUG X< return; X< } X< END_OF_FILE if test 170 -ne `wc -c <'ListWidget.patch'`; then echo shar: \"'ListWidget.patch'\" unpacked with wrong size! fi # end of 'ListWidget.patch' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1189 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XDEST = /global/bin X XEXTHDRS = /usr/include/signal.h \ X /usr/include/stdio.h X XHDRS = Browser.h \ X BrowserP.h X XLDFLAGS = -L/global/lib X XCFLAGS = -g -I/global/include X#-DDEBUG X XLIBS = -lXaw -lXmu -lXt -lX11 X XLINKER = /bin/cc X XCC = /bin/cc X XMAKEFILE = Makefile X XOBJS = Browser.o \ X main.o X XPRINT = enscript X XPROGRAM = test X XSRCS = Browser.c \ X main.c X Xall: $(PROGRAM) X X$(PROGRAM): $(OBJS) X @echo "Loading $(PROGRAM) ... " X $(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) X @echo "done" X Xclean:; /bin/rm -f $(OBJS) *~ \#* core X Xdepend:; @mkmf -d -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST) X Xindex:; ctags -wx $(HDRS) $(SRCS) ; X Xinstall: $(PROGRAM) X @echo Installing $(PROGRAM) in $(DEST) X @install -s $(PROGRAM) $(DEST) X Xprint:; @$(PRINT) $(HDRS) $(SRCS) X Xprogram: $(PROGRAM) X Xlint:; lint $(SRCS) -I/usr/X11 -I. X Xtags: $(HDRS) $(SRCS) X ctags -tw $(HDRS) $(SRCS) X Xupdate: $(DEST)/$(PROGRAM) X X$(DEST)/$(PROGRAM): $(SRCS) $(LIBS) $(HDRS) $(EXTHDRS) X @make -f $(MAKEFILE) DEST=$(DEST) install X Xnew: clean $(PROGRAM) X X### X XBrowser.o: BrowserP.h Browser.h Xmain.o: Browser.h END_OF_FILE if test 1189 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'browser.3x' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'browser.3x'\" else echo shar: Extracting \"'browser.3x'\" \(3828 characters\) sed "s/^X//" >'browser.3x' <<'END_OF_FILE' X(Message inbox:717) XReturn-Path: shipley%WEB.Berkeley.EDU@lilac.berkeley.edu XReceived: by wyse.wyse.com (5.58/Wyse master/5-13-88) X id AA02643; Wed, 4 Jan 89 22:53:38 PST XFrom: shipley%WEB.Berkeley.EDU@lilac.berkeley.edu XReceived: from lilac.Berkeley.EDU by uunet.UU.NET (5.59/1.14) X id AA25181; Thu, 5 Jan 89 01:42:01 EST XReceived: from e260-4f.berkeley.edu X by lilac.berkeley.edu (5.54 (CFC 4.22.3)/1.16.19) X id AA06780; Wed, 4 Jan 89 22:40:27 PST XReceived: by e260-4f.berkeley.edu (3.2/SMI-3.0DEV3.9MXl) X id AA02312; Wed, 4 Jan 89 22:43:36 PST XMessage-Id: <8901050643.AA02312@e260-4f.berkeley.edu> XTo: ames!mailrus!umix!wyse.com!mcf.uucp!mikew@cad.Berkeley.EDU XCc: shipley%widow.Berkeley.EDU@lilac.berkeley.edu, mikew@wyse.wyse.com XSubject: Re: browser widget XIn-Reply-To: Your message of Wed, 04 Jan 89 10:58:55 PST. X <8901041858.AA00866@wyse.wyse.com> XDate: Wed, 04 Jan 89 22:43:32 PST X X X> Could you send me a man page for the browser widget? X> Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 X> Moderator of comp.sources.x X X.TH BrowserWidget 3X X.SH NAME XBrowserWidget - Dialog widet for selecting files X.SH DESCRIPTION XThe BrowserWidget is a Utility widget which prompts Xthe user ror file sectection. X.SH RESOURCES X.TS Xl l l l. X_ X\fBName Type Default Description\fR X= XXtNvalue XtRString NULL T{ Xfull path to directory to start Browsing XT} XXtNdefaultDistance XtRInt 10 T{ Xdistance between subwidgets inside BrowserWidget XT} XXtNopenCallback XtCallbackList NULL Callbacks for open button XXtNcancelCallback XtCallbackList NULL Callbacks for cansel button XXtNdestroyCallback XtCallbackList NULL Callbacks for XtDestroyWidget XXtNmappedWhenManaged Boolean True Whether XtMapWidget is automatic XXtNfunction Boolean (*func)() NULL see below XXtNreverseVideo Boolean FALSE display widget in reverse video X_ X.TE X.IP XtNvalue XThe resource \*QXtNvalue\*U defines the base directory which the BrowserWidget Xuse to start querying user from. XThis resource has no default value thus it \fBmust be given\fR. X.\" X.IP XtNdefaultDistance XThe resource \*QXtNdefaultDistance\*U defines the distance Xbetween the child widgets of the BrowserWidget. X.\" X.IP XtNopenCallback XThis callback is called when the user selects a file. X.\" X.IP XtNcancelCallback XThis callback is called when the user selects the cancel button. X.\" X.IP XtNfunction XThis resource is a pointer to a function whose argument is Xa pointer to a directory entry for each file in the directory Xcurrently being scaned; the function should return TRUE if the Xdirectory entry is to be included. XIf this pointer is null, then all the directory entries will be included. X.\" X.IP "Other resources" XThe resource for the open button is \*Qopen\*U; the resource for the cancel Xbutton is \*Qcancel\*U. These can be used to change the default labels. X.\" X.SH USE XThe BrowserWidget takes command via mouse actions or keyboard entery. XSelection using the mouse is done by ether double clicking on the Xdesired file of directory, or by clicking once on the desired entry Xand selecting the open button. XSelection using the keyboard is very much like using file completion Xin the C-shell. XGenerally you type a partial filename followed by an ESC character Xand the BrowserWidget fills in the remaining unambiguous characters Xof partial filename XIf the user enters a Control-C the cancel callback will be called. XSelection is done by entering a line feed for or carrage return. X.LP XIf the selected directory entry is a directory the directory will Xbe followed and the menu will be redisplayed else the selected file Xwill be returned as a part of the open callback. X.\" X.SH SEE ALSO Xscandir(3) X.\" X.SH BUGS XViewport sometime gets confused about the size of the ListWidget (menu) Xand the user will be unable to use scrollbar. XListWidget will dump core if the user mouses to quickly. END_OF_FILE if test 3828 -ne `wc -c <'browser.3x'`; then echo shar: \"'browser.3x'\" unpacked with wrong size! fi # end of 'browser.3x' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(2200 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/dir.h> X#include <sys/param.h> X#include <X11/Intrinsic.h> X#include <X11/Cardinals.h> X#include <X11/List.h> X#include <X11/StringDefs.h> X#include "Browser.h" X X XArg args[20]; XWidget toplevel; X Xstatic XrmOptionDescRec options[] = { X{"-label", "*label", XrmoptionSepArg, NULL} X}; X X Xvoid Syntax(call) X char *call; X{ X (void) fprintf( stderr, "Usage: %s\n", call ); X X return; X} X X Xstatic void ss(wi, client_data, call_data) XWidget wi; Xcaddr_t client_data; Xcaddr_t call_data; X{ X (void) fprintf(stderr, "select %s\n", call_data); X X return; X} X Xstatic void cc(wi, client_data, call_data) XWidget wi; Xcaddr_t client_data; Xcaddr_t call_data; X{ Xextern Widget toplevel; X X (void) fputs("cancel\n", stderr); X X XtDestroyWidget(toplevel); X X exit(0); X} X Xstatic void dd(wi, client_data, call_data) XWidget wi; Xcaddr_t client_data; Xcaddr_t call_data; X{ X (void) fprintf(stderr, "all is dead\n"); X X return; X} X Xstatic Boolean tt(d) Xstruct direct *d; X{ X return !(d->d_name[0] == '.' && d->d_name[1]==0); X} X Xvoid main(argc, argv) Xunsigned int argc; Xchar **argv; X{ Xregister Cardinal n; XWidget L_widget; Xextern Widget toplevel; X Xstatic XtCallbackRec cancel_call[] = { X { cc, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X}; X Xstatic XtCallbackRec destroy_call[] = { X { dd, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X}; X Xstatic XtCallbackRec list_call[] = { X { ss, (caddr_t) NULL}, X {(XtCallbackProc) NULL, (caddr_t) NULL} X}; X X toplevel = XtInitialize( NULL, "XLabel", X options, XtNumber(options), X &argc, argv ); X X n = ZERO; X XtSetArg(args[n], XtNvalue, "/usr"); n++; X XtSetArg(args[n], XtNopenCallback, list_call); n++; X XtSetArg(args[n], XtNcancelCallback,cancel_call); n++; X XtSetArg(args[n], XtNheight, 350); n++; X XtSetArg(args[n], XtNwidth, 400); n++; X XtSetArg(args[n], XtNfunction, tt); n++; X XtSetArg(args[n], XtNdestroyCallback, destroy_call); n++; X X L_widget = XtCreateManagedWidget( "browser", browserWidgetClass, X toplevel, args, n ); X X X XtRealizeWidget(toplevel); X XtMainLoop(); X} END_OF_FILE if test 2200 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(22 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X#define PATCHLEVEL 0 X END_OF_FILE if test 22 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330 Moderator of comp.sources.x