📄 test10.c
字号:
/* $Header: /cvsroot/lesstif/lesstif/test/Xm/menushell/test10.c,v 1.4 2003/07/12 18:36:14 dannybackx Exp $ * Simulate bug #566315 "NEdit - new window ignores all input" */#include <Xm/XmAll.h>#include <Xm/MenuShell.h>#include <X11/keysym.h>#include <stdio.h>#include <stdlib.h>#include <sys/fcntl.h>#include <sys/stat.h>Widget toplevel;Widget menuShell;XtAppContext TheAppContext;Display *TheDisplay;#define MAX_ARGS 32#define MAXPATHLEN 256#define MAX_LIST_KEYSTROKES 16#define MAX_LIST_KESTROKE_WAIT 16#define GFN_OK 123#define GFN_CANCEL 124#define SHORT 1static String fallback[] = { "*a-open.accelerator: Ctrl<Key>o", "*b-open.accelerator: Ctrl<Key>o", "*c-open.accelerator: Ctrl<Key>o", "*d-open.accelerator: Ctrl<Key>o", "*a-exit.accelerator: Ctrl<Key>c", NULL};static int SelectResult = GFN_CANCEL;static char *HelpExist = "This is some help text";static int ErrorDone; /* Flag to mark dialog completed */static Widget ErrorDialog; /* Dialog widget for error msgs */typedef void (*menuCallbackProc)();#define MENU_WIDGET(w) (XmGetPostedFromWidget(XtParent(w)))static int compareThruSlash(const char *string1, const char *string2);static char *nextSlash(char *ptr);static char *prevSlash(char *ptr);static void copyThruSlash(char **toString, char **fromString);static void makeListTypeable(Widget listW);int CompressPathname(char *pathname);static void closeCB(Widget w, XtPointer window, XtPointer callData);/* * Yes this leaks like hell */char *ComposeName(char *p, char *s){ char *r = XtMalloc(strlen(p) + strlen(s)+2); strcpy(r, p); strcat(r, "-"); strcat(r, s); return r;}static voidEditExistingFile(void *inWindow, const char *name, const char *path, int flags, char *geometry, int iconic, const char *languageMode);extern const char*GetCurrentDir(void)/* return non-NULL value for the current working directory. If system call fails, provide a fallback value */{ static char curdir[MAXPATHLEN]; if (!getcwd(curdir, MAXPATHLEN)) { perror("NEdit: getcwd() fails"); strcpy(curdir, "."); } return (curdir);}#define SET_ONE_RSRC(widget, name, newValue) \{ \ static Arg tmpargs[1] = {{name, (XtArgVal)0}}; \ tmpargs[0].value = (XtArgVal)newValue; \ XtSetValues(widget, tmpargs, 1); \}intCompressPathname(char *pathname){ char *buf, *inPtr, *outPtr; struct stat statbuf; /* (Added by schwarzenberg) ** replace multiple slashes by a single slash */ inPtr=pathname; buf=(char *)malloc(strlen(pathname)+2); outPtr=buf; while (*inPtr) { *outPtr=*inPtr++; if(*outPtr=='/') { while(*inPtr=='/') inPtr++; } outPtr++; } *outPtr=0; strcpy(pathname, buf); /* compress out . and .. */ inPtr = pathname; outPtr = buf; /* copy initial / */ copyThruSlash(&outPtr, &inPtr); while (inPtr != NULL) { /* if the next component is "../", remove previous component */ if (compareThruSlash(inPtr, "../")) { *outPtr = 0; /* If the ../ is at the beginning, or if the previous component is a symbolic link, preserve the ../. It is not valid to compress ../ when the previous component is a symbolic link because ../ is relative to where the link points. If there's no S_ISLNK macro, assume system does not do symbolic links. */#ifdef S_ISLNK if(outPtr-1 == buf || (lstat(buf, &statbuf) == 0 && S_ISLNK(statbuf.st_mode))) { copyThruSlash(&outPtr, &inPtr); } else#endif { /* back up outPtr to remove last path name component */ outPtr = prevSlash(outPtr); inPtr = nextSlash(inPtr); } } else if (compareThruSlash(inPtr, "./")) { /* don't copy the component if it's the redundant "./" */ inPtr = nextSlash(inPtr); } else { /* copy the component to outPtr */ copyThruSlash(&outPtr, &inPtr); } } /* updated pathname with the new value */ if (strlen(buf)>MAXPATHLEN) { fprintf(stderr, "NEdit: CompressPathname(): file name too long %s\n", pathname); free(buf); return 1; } else { strcpy(pathname, buf); free(buf); return 0; }}static char*nextSlash(char *ptr){ for(; *ptr!='/'; ptr++) { if (*ptr == '\0') return NULL; } return ptr + 1;}static char*prevSlash(char *ptr){ for(ptr -= 2; *ptr!='/'; ptr--); return ptr + 1;}static intcompareThruSlash(const char *string1, const char *string2){ while (TRUE) { if (*string1 != *string2) return FALSE; if (*string1 =='\0' || *string1=='/') return TRUE; string1++; string2++; }}static voidcopyThruSlash(char **toString, char **fromString){ char *to = *toString; char *from = *fromString; while (TRUE) { *to = *from; if (*from =='\0') { *fromString = NULL; return; } if (*from=='/') { *toString = to + 1; *fromString = from + 1; return; } from++; to++; }}intNormalizePathname(char *pathname){ /* if this is a relative pathname, prepend current directory */#ifdef __EMX__ /* OS/2, ...: welcome to the world of drive letters ... */ if (!_fnisabs(pathname)) {#else if (pathname[0] != '/') {#endif char *oldPathname; size_t len; /* make a copy of pathname to work from */ oldPathname=(char *)malloc(strlen(pathname)+1); strcpy(oldPathname, pathname); /* get the working directory and prepend to the path */ strcpy(pathname, GetCurrentDir()); /* check for trailing slash, or pathname being root dir "/": don't add a second '/' character as this may break things on non-un*x systems */ len=strlen(pathname); /* GetCurrentDir() returns non-NULL value */ if ( len==0 ? 1 : pathname[len-1] != '/' ) { strcat(pathname, "/"); } strcat(pathname, oldPathname); free(oldPathname); } /* compress out .. and . */ return CompressPathname(pathname);}intParseFilename(const char *fullname, char *filename, char *pathname){ int fullLen = strlen(fullname); int i, pathLen, fileLen;#ifdef VMS /* find the last ] or : */ for (i=fullLen-1; i>=0; i--) { if (fullname[i] == ']' || fullname[i] == ':') break; }#else /* UNIX */ char *viewExtendPath; int scanStart; /* For clearcase version extended paths, slash characters after the "@@/" should be considered part of the file name, rather than the path */ if ((viewExtendPath = strstr(fullname, "@@/")) != NULL) scanStart = viewExtendPath - fullname - 1; else scanStart = fullLen - 1; /* find the last slash */ for (i=scanStart; i>=0; i--) { if (fullname[i] == '/') break; }#endif /* move chars before / (or ] or :) into pathname,& after into filename */ pathLen = i + 1; fileLen = fullLen - pathLen; if (pathname) { if (pathLen > MAXPATHLEN) { return 1; } strncpy(pathname, fullname, pathLen); pathname[pathLen] = 0; } if (filename) { if (fileLen > MAXPATHLEN) { return 2; } strncpy(filename, &fullname[pathLen], fileLen); filename[fileLen] = 0; }#ifdef VMS return 0;#else /* UNIX specific... Modify at a later date for VMS */ if(pathname) return NormalizePathname(pathname); else return 0;#endif}void AddMotifCloseCallback(Widget shell, XtCallbackProc closeCB, void *arg){ static Atom wmpAtom, dwAtom = 0; Display *display = XtDisplay(shell); /* deactivate the built in delete response of killing the application */ XtVaSetValues(shell, XmNdeleteResponse, XmDO_NOTHING, NULL); /* add a delete window protocol callback instead */ if (dwAtom == 0) { wmpAtom = XmInternAtom(display, "WM_PROTOCOLS", FALSE); dwAtom = XmInternAtom(display, "WM_DELETE_WINDOW", FALSE); } XmAddProtocolCallback(shell, wmpAtom, dwAtom, closeCB, arg);}void ManageDialogCenteredOnPointer(Widget dialogChild){ Widget shell = XtParent(dialogChild); Boolean mappedWhenManaged; XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, NULL); XtVaSetValues(shell, XmNmappedWhenManaged, False, NULL); XtManageChild(dialogChild); XtMapWidget(shell); XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, NULL);}static void doErrorDialog(const char *errorString, const char *filename){ char string[255]; XmString mString; ErrorDone = False; sprintf(string, errorString, filename); mString = XmStringCreateLtoR(string, XmSTRING_DEFAULT_CHARSET); SET_ONE_RSRC(ErrorDialog, XmNmessageString, mString); XmStringFree(mString); ManageDialogCenteredOnPointer(ErrorDialog); while (!ErrorDone) XtAppProcessEvent (XtWidgetToApplicationContext(ErrorDialog), XtIMAll); XtUnmanageChild(ErrorDialog);}static void existOkCB(Widget w, Boolean * client_data, XmFileSelectionBoxCallbackStruct *call_data){ char *filename; /* name of chosen file */ int fd; /* file descriptor */ int length; /* length of file name */ fprintf(stderr, "existOkCB\n"); XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename); SelectResult = GFN_OK; length = strlen(filename); if (length == 0 || filename[length-1] == '/') { doErrorDialog("Please select a file to open", NULL); XtFree(filename); return; } else if ((fd = open(filename, O_RDONLY,0)) == -1) { doErrorDialog("Error: can't open %s ", filename); XtFree(filename); return; } else close(fd); XtFree(filename); *client_data = True; /* done with dialog */}static void existCancelCB(Widget w, Boolean * client_data, caddr_t call_data){ SelectResult = GFN_CANCEL; *client_data = True; /* done with dialog */}static void existHelpCB(Widget w, Widget helpPanel, caddr_t call_data){ ManageDialogCenteredOnPointer(helpPanel);}static void closeCB(Widget w, XtPointer window, XtPointer callData){ exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -