/* fileutils.c -- * File handling routines. */ #include #include #include #include #include #include #include "globaldefs.h" #include "fileutils.h" #include "keyboard.h" #include "text.h" #include "trace.h" #include "utils.h" #ifdef _NO_PROTO static void readfilecb() ; #else /* static void readfilecb(Widget, Widget, XmFileSelectionBoxCallbackStruct *) ; */ static void readfilecb(Widget, XtPointer, XtPointer) ; #endif XmStringCharSet charset = XmSTRING_DEFAULT_CHARSET ; static void readfilecb(w, scrolledtext, cbs) Widget w ; /* Widget scrolledtext ; XmFileSelectionBoxCallbackStruct *cbs ; */ XtPointer scrolledtext, cbs ; { char *filename ; XtUnmanageChild(w) ; if (!XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value, charset, &filename)) return ; if (!*filename) { fprintf(stderr, "No file selected.\n") ; XtFree(filename) ; return ; } ReadFile((Widget) scrolledtext, filename) ; } /* returns ERROR when couldn't read file */ int ReadFile(scrolledtext, filename) Widget scrolledtext ; char *filename ; { struct stat statb ; FILE *fp ; char *text, tmpbuf[100] ; unsigned size ; int i, c ; XmString label ; TextUserData *textu = GetUserData(scrolledtext) ; if (stat(filename, &statb) == -1 || (statb.st_mode & S_IFMT) != S_IFREG || !(fp = fopen(filename, "r"))) { if ((statb.st_mode & S_IFMT) == S_IFREG) { perror("kp") ; } else { sprintf(tmpbuf, "%s: not a regular file\n", filename) ; Doerror(scrolledtext, tmpbuf, "This means the file you tried to open\n\ wasn't an ordinary file or didn't exist and couldn't be\nopened for reading.") ; } XtFree(filename) ; return (ERROR) ; } size = BUFSIZ ; text = XtMalloc(size) ; for (i = 0 ; (c = getc(fp)) != EOF ;) { if (i >= size-5) { size += BUFSIZ ; text = XtRealloc(text, size) ; } if ((char) c == '\n') { if (i) { if (text[i-1] == '\n') { if (i > 1 && text[i-2] == '\n') i-- ; /* skip empty lines */ } else if (text[i-1] != ' ') text[i++] = ' ' ; } } else if ((char) c == '\b') if (i) i-- ; /* erase _^Hc (underline) and c^Hc (doublestrike) */ if (isprint((char) c) || isspace((char) c)) text[i++] = (char) c ; } XtFree(filename) ; text[i] = '\0' ; if (textu->original) XtFree(textu->original) ; textu->original = text ; if (textu->filtered) { XtFree(textu->filtered) ; textu->filtered = NULL ; } ReinitStats(scrolledtext) ; RedrawKeyboard(scrolledtext) ; /* Set "isreading" flag in XmNuserData to True while reading because XmNmodifyVerifyCallback will be called in this case too */ textu->isreading = True ; XmTextSetString(scrolledtext, text) ; textu->isreading = False ; /* dirty */ XmTextSetInsertionPosition(scrolledtext, 1) ; XmTextSetInsertionPosition(scrolledtext, 0) ; fclose(fp) ; label = XmStringCreateSimple("Filter: off ") ; XtVaSetValues(filterlabel, XmNlabelString, label, NULL) ; XmStringFree(label) ; return (OK) ; } void LoadFile(w, scrolledtext, state) Widget w ; Widget scrolledtext ; XmPushButtonCallbackStruct *state ; { static Widget dialog ; XmString label1, label2, label3 ; if (!dialog) { dialog = XmCreateFileSelectionDialog(scrolledtext, "loadfile", NULL, 0) ; XtAddCallback(dialog, XmNokCallback, readfilecb, scrolledtext) ; XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)XtUnmanageChild, NULL) ; XtUnmanageChild(XmFileSelectionBoxGetChild(dialog, XmDIALOG_FILTER_LABEL)) ; XtUnmanageChild(XmFileSelectionBoxGetChild(dialog, XmDIALOG_FILTER_TEXT)) ; XtUnmanageChild(XmFileSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)) ; label1 = XmStringCreateSimple("Load") ; label2 = XmStringCreateSimple("Chdir") ; label3 = XmStringCreateSimple("Cancel") ; XtVaSetValues(dialog, XmNokLabelString, label1, XmNapplyLabelString, label2, XmNcancelLabelString, label3, XmNlistVisibleItemCount, 16, XmNtextColumns, 50, NULL) ; XmStringFree(label1) ; XmStringFree(label2) ; XmStringFree(label3) ; } XtManageChild(dialog) ; } /* because Motif 1.1 shared libs refer to an obsolete function which no longer exists in HP-UX 8.0*; These are not called, and return statements are here just to make gcc happy */ #ifdef __hpux char *regcmp() { return ((char *) NULL) ; } char *regex() { return ((char *) NULL) ; } #endif void LoadInitScreen(w, scrolledtext, cbs) Widget w ; Widget scrolledtext ; XmPushButtonCallbackStruct *cbs ; { XmString label ; TextUserData *textu = GetUserData(scrolledtext) ; static char *initmessage = "Welcome to the Keyboard Practicer (KP)! \n\n\ Hit the key that is indicated by the cursor. The cursor will advance \n\ if you hit the right key. \n\n\ This is the initial screen. \n\ Select the \"Load file\" button in the File menu to try other files. \n\ Select the \"Reload initial screen\" button in the File menu to get back here. \n\n\ You might want to play around with the Options menu too. \n\n\ Enjoy! :) \n" ; if (textu->original) XtFree(textu->original) ; textu->original = XtNewString(initmessage) ; if (textu->filtered) { XtFree(textu->filtered) ; textu->filtered = NULL ; } textu->isreading = True ; XmTextSetString(scrolledtext, initmessage) ; textu->isreading = False ; RedrawKeyboard(scrolledtext) ; /* dirty */ XmTextSetInsertionPosition(scrolledtext, 1) ; XmTextSetInsertionPosition(scrolledtext, 0) ; label = XmStringCreateSimple("Filter: off ") ; XtVaSetValues(filterlabel, XmNlabelString, label, NULL) ; XmStringFree(label) ; ReinitStats(scrolledtext) ; }