23 #include <sys/types.h> 27 #include <X11/Intrinsic.h> 28 #include <X11/StringDefs.h> 29 #include <X11/Xaw/Paned.h> 30 #include <X11/Xaw/AsciiText.h> 31 #include <X11/Xaw/Label.h> 32 #include <X11/Xaw/Viewport.h> 33 #include <X11/Xaw/Command.h> 34 #include <X11/Xaw/Box.h> 35 #include <X11/Shell.h> 51 String *popup_sens_list;
71 static void CRaction(Widget, XEvent*, String*, Cardinal*);
72 static void QUaction(Widget, XEvent*, String*, Cardinal*);
73 static void Quit(Widget, XtPointer, XtPointer);
74 static void Save(Widget, XtPointer, XtPointer);
75 static void SaveAs(Widget, XtPointer, XtPointer);
76 static void Source(Widget, XtPointer, XtPointer);
77 static void Load(Widget, XtPointer, XtPointer);
78 static void Change(Widget, XtPointer, XtPointer);
79 static void DoSaveAs(Widget, XtPointer, XtPointer);
81 static void DoLoad(Widget, XtPointer, XtPointer);
89 static void ToTop(Widget, XtPointer, XEvent*, Boolean*);
92 static void PopUpHelp(Widget, XtPointer, XtPointer);
93 static void PopDownHelp(Widget, XtPointer, XtPointer);
131 "<Key>Return: cr_action()\n<Key>Delete: delete-next-character()";
139 static String fallback_resources[] = {
141 "xeditor.xeditor.background: lightgrey",
142 "xeditor.xeditor.buttonbox.background: lightblue",
143 "xeditor.xeditor.buttonbox.Command.background: yellow",
145 "xeditor.popup.form.background: lightblue",
146 "xeditor.popup.form.Command.background: yellow",
147 "xeditor.popup.form.Label.background: pink",
149 "xeditor.popup_m.form_m.background: pink",
150 "xeditor.popup_m.form_m.Command.background: yellow",
152 "xeditor.popup_h.form_h.background: lightgrey",
153 "xeditor.popup_h.form_h.buttonbox.background: lightblue",
154 "xeditor.popup_h.form_h.buttonbox.Command.background: yellow",
155 "xeditor.popup_h.form_h.buttonbox.Label.background: pink",
159 static XtActionsRec actions[] = {
174 XtAppContext app_con;
177 XtToolkitInitialize();
178 app_con = XtCreateApplicationContext();
179 XtAppSetFallbackResources(app_con, fallback_resources);
180 Xdisplay = XtOpenDisplay(app_con,
NULL,
NULL,
"Xeditor",
NULL, 0,
183 fprintf(stderr,
"Error: can't open display\n");
186 XtAppAddActions(app_con, actions,
XtNumber(actions));
198 XtAppMainLoop(app_con);
219 XErrorEvent *errorev;
223 XGetErrorText(display, errorev->error_code, ErrorMessage, 1024);
224 printf(ErrorMessage);
239 Widget action = XtNameToWidget(XtParent(caller),
"action");
242 XtCallCallbacks(action, XtNcallback,
NULL);
257 quit = XtNameToWidget(caller,
"xeditor.buttonbox.quit");
259 quit = XtNameToWidget(caller,
"form.cancel");
261 quit = XtNameToWidget(caller,
"form_h.buttonbox.cancel_h");
263 quit = XtNameToWidget(caller,
"form_m.cancel_m");
266 XtCallCallbacks(quit, XtNcallback,
NULL);
280 static char tmpl[] =
"/tmp/xeXXXXXX";
285 w->
shell = XtAppCreateShell(
NULL,
"Jspice3",
286 applicationShellWidgetClass, Xdisplay,
NULL, 0);
287 XtOverrideTranslations(w->
shell, XtParseTranslationTable(wmTranslations));
288 w->
form = XtVaCreateManagedWidget(
"xeditor", formWidgetClass,
291 w->
butbox = XtVaCreateManagedWidget(
"buttonbox", boxWidgetClass,
294 XtNleft, XtChainLeft,
295 XtNright, XtChainLeft,
296 XtNbottom, XtChainTop,
300 w->
title = XtVaCreateManagedWidget(
"titlelabel", labelWidgetClass,
305 XtNhorizDistance, 20,
306 XtNleft, XtChainLeft,
307 XtNright, XtChainLeft,
308 XtNbottom, XtChainTop,
313 button = XtVaCreateManagedWidget(
"quit", commandWidgetClass,
317 XtAddCallback(button, XtNcallback,
Quit, (XtPointer)w);
318 XtOverrideTranslations(button, XtParseTranslationTable(butTranslations));
320 button = XtVaCreateManagedWidget(
"save", commandWidgetClass,
324 XtAddCallback(button, XtNcallback,
Save, (XtPointer)w);
325 XtSetSensitive(button,
False);
327 button = XtVaCreateManagedWidget(
"save_as", commandWidgetClass,
331 XtAddCallback(button, XtNcallback,
SaveAs, (XtPointer)w);
332 XtOverrideTranslations(button, XtParseTranslationTable(butTranslations));
335 button = XtVaCreateManagedWidget(
"source", commandWidgetClass,
339 XtAddCallback(button, XtNcallback,
Source, (XtPointer)w);
340 XtOverrideTranslations(button, XtParseTranslationTable(butTranslations));
343 button = XtVaCreateManagedWidget(
"load", commandWidgetClass,
347 XtAddCallback(button, XtNcallback,
Load, (XtPointer)w);
348 XtOverrideTranslations(button, XtParseTranslationTable(butTranslations));
350 button = XtVaCreateManagedWidget(
"help", commandWidgetClass,
355 XtAddCallback(button, XtNcallback,
PopUpHelp, (XtPointer)w);
356 XtOverrideTranslations(button, XtParseTranslationTable(butTranslations));
358 XtAddCallback(button, XtNcallback,
PopUpHelp, (XtPointer)
"xeditor");
361 w->text = XtVaCreateManagedWidget(
"main_text", asciiTextWidgetClass,
363 XtNtype, XawAsciiFile,
364 XtNeditType, XawtextRead,
365 XtNallowResize,
True,
366 XtNscrollHorizontal, XawtextScrollWhenNeeded,
367 XtNscrollVertical, XawtextScrollWhenNeeded,
368 XtNfromVert, w->butbox,
371 XtNstring,
"/dev/null",
374 XtAddCallback(XawTextGetSource(w->text), XtNcallback,
Change,
376 XtOverrideTranslations(w->text, XtParseTranslationTable(textTranslations));
378 XtRealizeWidget(w->shell);
379 w->wm_delete = XInternAtom(Xdisplay,
"WM_DELETE_WINDOW",
False);
380 XSetWMProtocols(Xdisplay, XtWindow(w->shell), &w->wm_delete, 1);
382 if (fname && *fname) {
389 fname = (
char*)mktemp(tmpl);
392 XtVaSetValues(w->text, XtNstring, fname,
NULL);
396 XtVaSetValues(w->text, XtNeditType, XawtextEdit,
NULL);
398 XtVaSetValues(w->title, XtNlabel, fname,
NULL);
399 w->TextChanged =
False;
411 Quit(caller, client_data, call_data)
414 XtPointer client_data, call_data;
418 if (w->TextChanged && (w->Last !=
QUIT)) {
421 "Text has been modified. Hit Quit again to quit", w);
424 XtDestroyWidget(w->
shell);
434 Save(caller, client_data, call_data)
437 XtPointer client_data, call_data;
444 XtVaGetValues(w->
title, XtNlabel, &fname,
NULL);
448 if (!XawAsciiSaveAsFile(XawTextGetSource(w->
text), fname)) {
456 if (w->TextChanged) {
457 w->TextChanged =
False;
458 XtAddCallback(XawTextGetSource(w->
text), XtNcallback,
Change,
461 XtSetSensitive(caller,
False);
474 XtPointer client_data, call_data;
478 XawTextPosition begin, end;
481 XawTextGetSelectionPos(w->
text, &begin, &end);
483 XtVaGetValues(w->
title, XtNlabel, &fname,
NULL);
497 XtPointer client_data, call_data;
504 if (w->TextChanged) {
507 PopUpMessage(
"Unknown error, can't create temp file", w);
511 if (!XawAsciiSaveAsFile(XawTextGetSource(w->
text), fname)) {
512 PopUpMessage(
"Unknown error, can't write temp file", w);
522 XtVaGetValues(w->
title, XtNlabel, &fname,
NULL);
534 Load(caller, client_data, call_data)
537 XtPointer client_data, call_data;
540 char *newfname =
NULL;
542 if (w->TextChanged && (w->Last !=
LOAD)) {
545 "Text has been modified. Hit Load again to load", w);
561 XtPointer client_data, call_data;
566 w->TextChanged =
True;
567 XtSetSensitive(XtNameToWidget(w->
butbox,
"save"),
True);
568 XtRemoveCallback(caller, XtNcallback,
Change, (XtPointer)w);
577 XtPointer client_data, call_data;
579 String fname, oldfname;
581 XawTextPosition begin, end;
589 if (fname && *fname) {
597 XawTextGetSelectionPos(w->
text, &begin, &end);
600 if (!XawAsciiSaveAsFile(XawTextGetSource(w->
text), fname)) {
604 XtVaGetValues(w->
title, XtNlabel, &oldfname,
NULL);
605 if (
same(fname, oldfname)) {
606 if (!w->TextChanged) {
611 XtFree(w->saved_as), w->saved_as =
NULL;
612 w->TextChanged =
False;
613 XtSetSensitive(XtNameToWidget(w->
butbox,
"save"),
False);
614 XtAddCallback(XawTextGetSource(w->
text), XtNcallback,
Change,
621 w->saved_as = XtMalloc(strlen(fname) + 1);
622 strcpy(w->saved_as, fname);
623 if (w->TextChanged) {
624 w->TextChanged =
False;
625 XtAddCallback(XawTextGetSource(w->
text), XtNcallback,
Change,
628 mesg =
"Text saved under new name";
633 if ((fp = fopen(fname,
"w")) ==
NULL) {
637 string = XFetchBytes(Xdisplay, &len);
638 for (s =
string; len; s++,len--)
642 mesg =
"Selected block saved";
654 while (isspace(*s)) s++;
655 while (isspace(*t)) t++;
656 for (; *s && *t; s++, t++)
657 if (*s != *t)
return (
False);
658 if (*s && !isspace(*s))
return (
False);
659 if (*t && !isspace(*t))
return (
False);
669 XtPointer client_data, call_data;
677 if (fname && *fname) {
685 XtVaSetValues(w->
text, XtNeditType, XawtextRead,
NULL);
687 XtVaSetValues(w->
text, XtNstring,
"/dev/null",
NULL);
689 XtVaSetValues(w->
text, XtNstring, fname,
NULL);
690 XtVaSetValues(w->
text, XtNeditType, XawtextEdit,
NULL);
695 XtDestroyWidget(w->
title);
696 w->
title = XtVaCreateManagedWidget(
"titlelabel", labelWidgetClass,
701 XtNhorizDistance, 20,
702 XtNleft, XtChainLeft,
703 XtNright, XtChainLeft,
704 XtNbottom, XtChainTop,
710 if (w->TextChanged) {
711 w->TextChanged =
False;
712 XtSetSensitive(XtNameToWidget(w->
butbox,
"save"),
False);
713 XtAddCallback(XawTextGetSource(w->
text), XtNcallback,
Change,
725 PopUpInput(initial_str, action_str, action_callback,
w)
727 String initial_str, action_str;
728 void (*action_callback)();
735 Dimension width, b_width,
d;
738 w->
popup = XtVaCreatePopupShell(
"popup", transientShellWidgetClass,
740 XtOverrideTranslations(w->
popup, XtParseTranslationTable(wmTranslations));
741 XtAddEventHandler(w->
popup, VisibilityChangeMask,
742 False, ToTop, (XtPointer)w);
744 form = XtVaCreateManagedWidget(
"form", formWidgetClass, w->popup,
747 label = XtVaCreateManagedWidget(
"label", labelWidgetClass,
749 XtNlabel,
"Enter filename: ",
750 XtNleft, XtChainLeft,
751 XtNright, XtChainLeft,
756 w->popup_text = XtVaCreateManagedWidget(
"text", asciiTextWidgetClass,
759 XtNleft, XtChainLeft,
760 XtNright, XtChainRight,
761 XtNeditType, XawtextEdit,
763 XtNresize, XawtextResizeWidth,
764 XtNstring, initial_str,
766 XtOverrideTranslations(w->popup_text,
767 XtParseTranslationTable(oneLineTranslations));
769 action = XtVaCreateManagedWidget(
"action", commandWidgetClass,
771 XtNlabel, action_str,
772 XtNfromVert, w->popup_text,
773 XtNleft, XtChainLeft,
774 XtNright, XtChainLeft,
776 XtOverrideTranslations(action, XtParseTranslationTable(butTranslations));
778 cancel = XtVaCreateManagedWidget(
"cancel", commandWidgetClass,
781 XtNfromVert, w->popup_text,
782 XtNfromHoriz, action,
783 XtNleft, XtChainLeft,
784 XtNright, XtChainLeft,
787 XtAddCallback(cancel, XtNcallback,
PopDownInput, (XtPointer)w);
788 XtAddCallback(action, XtNcallback, action_callback, (XtPointer)w);
789 XtRealizeWidget(w->popup);
790 XSetWMProtocols(Xdisplay, XtWindow(w->popup), &w->wm_delete, 1);
795 XtNborderWidth, &b_width,
796 XtNdefaultDistance, &d,
798 width -= 2*(b_width + d + 1);
799 XtVaSetValues(w->popup_text, XtNwidth, width,
NULL);
801 XtPopup(w->popup, XtGrabNone);
802 XtSetKeyboardFocus(w->popup, w->popup_text);
803 XtSetKeyboardFocus(w->shell, w->popup);
804 for (p = w->popup_sens_list; *p; p++)
805 XtSetSensitive(XtNameToWidget(w->butbox, *p),
False);
814 XtPointer client_data, call_data;
819 XtSetKeyboardFocus(w->
shell, None);
822 XtSetSensitive(XtNameToWidget(w->
butbox, *p),
True);
837 XColor visualcolor, exactcolor;
839 popup = XtVaCreatePopupShell(
"popup_m", transientShellWidgetClass,
841 XtOverrideTranslations(popup, XtParseTranslationTable(wmTranslations));
842 XtAddEventHandler(popup, VisibilityChangeMask,
843 False, ToTop, (XtPointer)w);
845 form = XtVaCreateManagedWidget(
"form_m", formWidgetClass, popup,
848 cancel = XtVaCreateManagedWidget(
"cancel_m", commandWidgetClass,
851 XtNleft, XtChainLeft,
852 XtNright, XtChainLeft,
855 XAllocNamedColor(Xdisplay,
856 DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)),
857 "red", &exactcolor, &visualcolor);
858 label = XtVaCreateManagedWidget(
"label_m", labelWidgetClass,
860 XtNlabel, message_str,
861 XtNleft, XtChainLeft,
862 XtNright, XtChainLeft,
863 XtNfromHoriz, cancel,
866 XtNborderColor, visualcolor.pixel,
873 XtRealizeWidget(popup);
874 XSetWMProtocols(Xdisplay, XtWindow(popup), &w->wm_delete, 1);
877 XtSetSensitive(w->popup,
False);
878 XtSetSensitive(w->form,
False);
879 XtSetKeyboardFocus(w->shell, form);
880 XtPopup(popup, XtGrabExclusive);
889 XtPointer client_data, call_data;
899 XtSetKeyboardFocus(w->
shell, None);
911 Dimension width, height, b_width;
912 Position x, y, max_x, max_y;
914 XtVaGetValues(master,
919 XtNborderWidth, &b_width,
925 x += (Position)width/2;
926 y += (Position)height/2;
931 XtNborderWidth, &b_width,
936 x -= (Position)width/2;
938 y -= (Position)height/2;
940 if (y > (max_y = (Position) (XtScreen(sub)->height - height))) y = max_y;
942 XtVaSetValues(sub, XtNx, x, XtNy, y,
NULL);
956 char *msg =
"Error: can't %s file %s";
959 if (!fname)
return (
NOGO);
960 while (isspace(*fname)) fname++;
961 if (!*fname)
return (
NOGO);
963 if (!
access(fname, F_OK)) {
965 if (stat(fname, &st))
968 if ((st.st_mode&S_IFMT) != S_IFLNK &&
969 (st.st_mode&S_IFMT) != S_IFREG)
goto bad;
977 if (!
access(fname,F_OK))
goto bad;
984 if (!
access(fname,F_OK))
goto bad;
985 fp = fopen(fname,
"w");
992 sprintf(buf, msg, (mode == R_OK) ?
"read" :
"write", fname);
1000 ToTop(caller, clientdata, event, ctd)
1003 XtPointer clientdata;
1010 XVisibilityEvent *vev = (XVisibilityEvent*)event;
1013 if (vev->state == VisibilityFullyObscured) {
1014 xv.sibling = XtWindow(w->
shell);
1015 xv.stack_mode = Above;
1016 XReconfigureWMWindow(vev->display, vev->window,
1017 DefaultScreen(vev->display), CWSibling|CWStackMode, &xv);
1022 static char help_text[] =
"\ 1024 Quit: Exit the editor\n\ 1025 Save: Save the current buffer to the named file\n\ 1026 Save As: Save the current buffer or marked block to a new file\n\ 1027 Load: Input a new text file for editing\n\ 1028 Help: Bring up help text\n\n\ 1030 Ctrl-a Beginning Of Line Meta-b Backward Word\n\ 1031 Ctrl-b Backward Character Meta-f Forward Word\n\ 1032 Ctrl-d Delete Next Character Meta-i Insert File\n\ 1033 Ctrl-e End Of Line Meta-k Kill To End Of Paragraph\n\ 1034 Ctrl-f Forward Character Meta-q Form Paragraph\n\ 1035 Ctrl-g Multiply Reset Meta-v Previous Page\n\ 1036 Ctrl-h Delete Previous Character Meta-y Insert Current Selection\n\ 1037 Ctrl-j Newline And Indent Meta-z Scroll One Line Down\n\ 1038 Ctrl-k Kill To End Of Line Meta-d Delete Next Word\n\ 1039 Ctrl-l Redraw Display Meta-D Kill Word\n\ 1040 Ctrl-m Newline Meta-h Delete Previous Word\n\ 1041 Ctrl-n Next Line Meta-H Backward Kill Word\n\ 1042 Ctrl-o Newline And Backup Meta-< Beginning Of File\n\ 1043 Ctrl-p Previous Line Meta-> End Of File\n\ 1044 Ctrl-r Search/Replace Backward Meta-] Forward Paragraph\n\ 1045 Ctrl-s Search/Replace Forward Meta-[ Backward Paragraph\n\ 1046 Ctrl-t Transpose Characters Delete Delete next character\n\ 1047 Ctrl-u Multiply by 4 Meta-Delete Delete Previous Word\n\ 1048 Ctrl-v Next Page Meta-Shift-Delete Kill Previous Word\n\ 1049 Ctrl-w Kill Selection Meta-Backspace Delete Previous Word\n\ 1050 Ctrl-y Unkill Meta-Shift-Backspace Kill Previous Word\n\ 1051 Ctrl-z Scroll One Line Up\n\n\ 1052 Pointer button bindings (cut and paste text):\n\ 1053 Button 1 Down Start Selection\n\ 1054 Button 1 Motion Adjust Selection\n\ 1055 Button 1 Up End Selection (cut)\n\n\ 1056 Button 2 Down Insert Current Selection (paste)\n\n\ 1057 Button 3 Down Extend Current Selection\n\ 1058 Button 3 Motion Adjust Selection\n\ 1059 Button 3 Up End Selection (cut)\n";
1065 PopUpHelp(caller, client_data, call_data)
1068 XtPointer client_data, call_data;
1080 XtVaGetValues(w->
shell, XtNx, &x, XtNy, &y,
NULL);
1083 popup = XtVaCreatePopupShell(
"popup_h", transientShellWidgetClass,
1088 XtOverrideTranslations(popup, XtParseTranslationTable(wmTranslations));
1090 form = XtVaCreateManagedWidget(
"form_h", formWidgetClass, popup,
1093 butbox = XtVaCreateManagedWidget(
"buttonbox", boxWidgetClass,
1096 XtNleft, XtChainLeft,
1097 XtNright, XtChainLeft,
1098 XtNbottom, XtChainTop,
1102 label = XtVaCreateManagedWidget(
"label_h", labelWidgetClass,
1104 XtNlabel,
"Xeditor Help",
1108 cancel = XtVaCreateManagedWidget(
"cancel_h", commandWidgetClass,
1111 XtNfromHoriz, label,
1114 text = XtVaCreateManagedWidget(
"text_h", asciiTextWidgetClass,
1116 XtNtype, XawAsciiString,
1117 XtNeditType, XawtextRead,
1118 XtNallowResize,
True,
1119 XtNscrollHorizontal, XawtextScrollWhenNeeded,
1120 XtNscrollVertical, XawtextScrollWhenNeeded,
1121 XtNfromVert, butbox,
1124 XtNstring, help_text,
1125 XtNdisplayCaret,
False,
1128 wpass = (Widget*)XtMalloc(2*
sizeof(Widget));
1131 XtAddCallback(cancel, XtNcallback,
PopDownHelp, (XtPointer)wpass);
1132 XtRealizeWidget(popup);
1133 XSetWMProtocols(Xdisplay, XtWindow(popup), &w->
wm_delete, 1);
1134 XtPopup(popup, XtGrabNone);
1135 XtSetSensitive(XtNameToWidget(w->
butbox,
"help"),
False);
1144 XtPointer client_data, call_data;
1146 Widget *w = (Widget*)client_data;
1149 XtSetSensitive(XtNameToWidget(w[1],
"help"),
True);
1161 if (
index(buf,
'~')) {
1182 while (*
string && isspace(*
string))
1185 if (*
string !=
'~') {
1186 ret = XtMalloc(strlen(
string) + 1);
1193 if (!*
string || *
string ==
'/') {
1194 pw = getpwuid(getuid());
1199 while ((c = *
string) && c !=
'/')
1208 strcat(buf,
string);
1213 ret = XtMalloc(strlen(buf) + 1);
1226 XtPointer client_data, call_data;
1231 wl.
wl_word = (
char*)client_data;
1254 { printf(
"This doesn't exist without X!\n"); }
1270 fprintf(
cp_err,
"Xeditor is available under X only\n");
void cp_pathfix(char *buf)
static char buf[MAXPROMPT]
char * tilde_expand(char *string)
static char * sens_list[]
static char * butTranslations
static void PopDownHelp()
struct wordlist * wl_prev
int access(char *pth, int m)
static char * textTranslations
static char * oneLineTranslations
static int errorhandler()
static char * wmTranslations
void CenterWidgetOnWidget()
static void message(char *instr, char *outstr)
char * index(char *s, char c) const
struct wordlist * wl_next
int main(int argc, char **argv)
void com_xeditor(wordlist *wl)