Redo ICS input box with generic popup
[xboard.git] / filebrowser / selfile.c
index 4298e30..2e34955 100644 (file)
@@ -61,6 +61,16 @@ extern int errno;
 #include <X11/Xaw/Cardinals.h>
 
 #include "selfile.h"
+#include "xstat.h"
+
+/* added missing prototypes */
+extern void SFdrawList(int,int);
+extern void SFinitFont();
+extern void SFcreateGC();
+extern int SFchdir(char *);
+extern void SFupdatePath();
+extern void SFsetText(char *);
+extern char SFstatChar(struct stat*);
 
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 1024
@@ -129,6 +139,8 @@ XtIntervalId SFdirModTimerId;
 
 int (*SFfunc)();
 
+Boolean SFpathFlag; // [HGM]
+
 static char *oneLineTextEditTranslations = "\
        <Key>Return:    redraw-display()\n\
        Ctrl<Key>M:     redraw-display()\n\
@@ -146,7 +158,7 @@ SFexposeList(w, n, event, cont)
                return;
        }
 
-       SFdrawList(n, SF_DO_NOT_SCROLL);
+       SFdrawList((int)(intptr_t)n, SF_DO_NOT_SCROLL);
 }
 
 /* ARGSUSED */
@@ -418,9 +430,9 @@ SFcreateWidgets(toplevel, prompt, ok, cancel)
                        scrollbarWidgetClass, selFileLists[n], arglist, i);
 
                XtAddCallback(selFileVScrolls[n], XtNjumpProc,
-                       SFvFloatSliderMovedCallback, (XtPointer) n);
+                       SFvFloatSliderMovedCallback, (XtPointer)(intptr_t) n);
                XtAddCallback(selFileVScrolls[n], XtNscrollProc,
-                       SFvAreaSelectedCallback, (XtPointer) n);
+                       SFvAreaSelectedCallback, (XtPointer)(intptr_t) n);
 
                i = 0;
 
@@ -435,9 +447,9 @@ SFcreateWidgets(toplevel, prompt, ok, cancel)
                        scrollbarWidgetClass, selFileLists[n], arglist, i);
 
                XtAddCallback(selFileHScrolls[n], XtNjumpProc,
-                       SFhSliderMovedCallback, (XtPointer) n);
+                       SFhSliderMovedCallback, (XtPointer)(intptr_t) n);
                XtAddCallback(selFileHScrolls[n], XtNscrollProc,
-                       SFhAreaSelectedCallback, (XtPointer) n);
+                       SFhAreaSelectedCallback, (XtPointer)(intptr_t) n);
        }
 
        i = 0;
@@ -496,17 +508,17 @@ SFcreateWidgets(toplevel, prompt, ok, cancel)
 
        for (n = 0; n < NR; n++) {
                XtAddEventHandler(selFileLists[n], ExposureMask, True,
-                       SFexposeList, (XtPointer) n);
+                       SFexposeList, (XtPointer)(intptr_t) n);
                XtAddEventHandler(selFileLists[n], EnterWindowMask, False,
-                       SFenterList, (XtPointer) n);
+                       SFenterList, (XtPointer)(intptr_t) n);
                XtAddEventHandler(selFileLists[n], LeaveWindowMask, False,
-                       SFleaveList, (XtPointer) n);
+                       SFleaveList, (XtPointer)(intptr_t) n);
                XtAddEventHandler(selFileLists[n], PointerMotionMask, False,
-                       SFmotionList, (XtPointer) n);
+                       SFmotionList, (XtPointer)(intptr_t) n);
                XtAddEventHandler(selFileLists[n], ButtonPressMask, False,
-                       SFbuttonPressList, (XtPointer) n);
+                       SFbuttonPressList, (XtPointer)(intptr_t) n);
                XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False,
-                       SFbuttonReleaseList, (XtPointer) n);
+                       SFbuttonReleaseList, (XtPointer)(intptr_t) n);
        }
 
        XtAddEventHandler(selFileField, KeyPressMask, False,
@@ -588,15 +600,16 @@ SFopenFile(name, mode, prompt, failed)
     return fp;
 }
 
+void
 SFtextChanged()
 {
 
        if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
-               (void) strcpy(SFcurrentPath, SFtextBuffer);
+         (void) strncpy(SFcurrentPath, SFtextBuffer, MAXPATHLEN);
 
                SFtextPos = XawTextGetInsertionPoint(selFileField);
        } else {
-               (void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer);
+         (void) strcat(strncpy(SFcurrentPath, SFstartDir, MAXPATHLEN), SFtextBuffer);
 
                SFtextPos = XawTextGetInsertionPoint(selFileField) +
                        strlen(SFstartDir);
@@ -608,6 +621,7 @@ SFtextChanged()
        }
 
        SFupdatePath();
+       return;
 }
 
 static char *
@@ -617,7 +631,7 @@ SFgetText()
                SFtextBuffer);
 }
 
-static
+static void
 SFprepareToReturn()
 {
        SFstatus = SEL_FILE_NULL;
@@ -630,6 +644,7 @@ SFprepareToReturn()
                        "XsraSelFile: can't return to current directory"
                );
        }
+       return;
 }
 
 FILE *
@@ -663,6 +678,12 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed,
                cancel = "Cancel";
        }
 
+       if(SFpathFlag != (mode && mode[0] == 'p')) { // [HGM] ignore everything that is not a directory
+               if(SFdirs) XtFree(SFdirs);
+               SFdirs = NULL; // kludge to throw away all cached info
+               SFpathFlag = !SFpathFlag;
+       }
+
        if (firstTime) {
                firstTime = 0;
                SFdisplay = XtDisplay(toplevel);
@@ -694,11 +715,11 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed,
                XtAppError(SFapp, "XsraSelFile: can't get current directory");
        }
        (void) strcat(SFstartDir, "/");
-       (void) strcpy(SFcurrentDir, SFstartDir);
+       (void) strncpy(SFcurrentDir, SFstartDir, MAXPATHLEN);
 
        if (init_path) {
                if (init_path[0] == '/') {
-                       (void) strcpy(SFcurrentPath, init_path);
+                 (void) strncpy(SFcurrentPath, init_path, MAXPATHLEN);
                        if (strncmp(
                                SFcurrentPath,
                                SFstartDir,
@@ -709,12 +730,12 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed,
                                SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
                        }
                } else {
-                       (void) strcat(strcpy(SFcurrentPath, SFstartDir),
+                 (void) strcat(strncpy(SFcurrentPath, SFstartDir, MAXPATHLEN),
                                init_path);
                        SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
                }
        } else {
-               (void) strcpy(SFcurrentPath, SFstartDir);
+         (void) strncpy(SFcurrentPath, SFstartDir, MAXPATHLEN);
        }
 
        SFfunc = show_entry;
@@ -736,6 +757,10 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed,
                        break;
                case SEL_FILE_OK:
                        *name_return = SFgetText();
+                       if(mode && (mode[0] == 'p' || mode[0] == 'f')) { // [HGM] for use in file-option browse button
+                               SFprepareToReturn();
+                               return stderr;
+                       }
                        if (fp = SFopenFile(*name_return, mode,
                                            prompt, failed)) {
                                SFprepareToReturn();