Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 593372 Details for
Bug 834191
copy and cut in the XmTextWidget don't work
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
Program to demonstrate the bug. Compile with gcc textedit.c -o textedit /usr/lib64/libXm.so.3 -lXt -lX11 -g
textedit.c (text/x-c), 65.37 KB, created by
Albert Flügel
on 2012-06-21 07:25:02 UTC
(
hide
)
Description:
Program to demonstrate the bug. Compile with gcc textedit.c -o textedit /usr/lib64/libXm.so.3 -lXt -lX11 -g
Filename:
MIME Type:
Creator:
Albert Flügel
Created:
2012-06-21 07:25:02 UTC
Size:
65.37 KB
patch
obsolete
>/* Written mainly by Albert Fl"ugel, some useful parts by > * Dan Heller and Paula Ferguson. > * Copyright 1995 ZN Bochum, 1994 O'Reilly & Associates, Inc. > * Permission to use, copy, and modify this program without > * restriction is hereby granted, as long as this copyright > * notice appears in each copy of the program source code. > * This program is freely distributable without licensing fees and > * is provided without guarantee or warrantee expressed or implied. > * This program is -not- in the public domain. > */ > >/* editor.c -- create a full-blown Motif editor application complete > * with a menubar, facilities to read and write files, text find > * and replace, clipboard support and so forth. > */ >#include <Xm/Text.h> >#include <Xm/TextF.h> >#include <Xm/LabelG.h> >#include <Xm/Label.h> >#include <Xm/CascadeB.h> >#include <Xm/ToggleBG.h> >#include <Xm/PushBG.h> >#include <Xm/PushB.h> >#include <Xm/RowColumn.h> >#include <Xm/Protocols.h> >#include <Xm/MainW.h> >#include <Xm/PanedW.h> >#include <Xm/Form.h> >#include <Xm/FileSB.h> >#include <Xm/DialogS.h> >#include <Xm/ToggleBG.h> >#include <X11/Xos.h> >#include <stdio.h> >#include <sys/types.h> >#include <sys/stat.h> >#include <stdlib.h> >#if !defined(sgi) && !defined(__QNX__) && !defined(linux) >#include <sys/mode.h> >#endif >#include <signal.h> > >char **extras_names = NULL; >char **extras_cmds = NULL; >int num_extras = 0; > >Widget text_edit, find_text, replace_text, lineno_text, text_output, > toplevel, no_backup_button, autoindent_button, readonly_button, > wraplines_button, find_menu, find_pair_dialog = NULL, > find_pair_radio_box, find_pair_form, find_pair_right_form, > curly_sel, round_sel, ccommsel, other_sel, tmp_widget, > pat_one_text, pat_two_text, find_pair_pane; >char *act_filename = NULL; > >#define TEXT_EXTRAS_FILE ".textedit_extras" > >#define FILE_OPEN 0 >#define FILE_SAVE 1 >#define FILE_SAVE_AS 2 >#define FILE_INSERT 3 >#define FILE_EMPTY 4 >#define FILE_EXIT 5 > >#define EDIT_CUT 0 >#define EDIT_COPY 1 >#define EDIT_PASTE 2 >#define EDIT_UNDO 3 >#define EDIT_CLEAR 4 > >#define SEARCH_FIND_NEXT 0 >#define SEARCH_FIND_PREVIOUS 1 >#define SEARCH_REPLACE 2 >#define SEARCH_FIND_AND_REPLACE 3 >#define SEARCH_REPLACE_AND_FIND 4 >#define SEARCH_SHOW_ALL 5 >#define SEARCH_REPLACE_ALL 6 >#define SEARCH_FIND_PAIR 7 >#define SEARCH_CLEAR 9999 > >#define VIEW_WHAT_LINE 0 >#define VIEW_GOTO_LINE 1 > >#define OPTIONS_NO_BACKUP 0 > >#define INSERT_ACTION 1 >#define DELETE_ACTION 2 >#define CUT_ACTION 3 >#define PASTE_ACTION 4 >#define BACKSP_ACTION 5 >#define CUTPASTE_ACTION 6 > >#define OPENING_DISPLAY 1 > >#define TEXTRECFILE 0x01 >#define EDITRECFILE 0x02 > >int max_undos = 100; > >struct edit_record { > XmTextPosition ins_start, ins_end, del_start, del_end; > char *del_string; > int del_strlen; > char *ins_string; > int ins_strlen; > char type; >}; > >struct edit_record act_edit = { > 0, 0, 0, 0, "", 0, "", 0, INSERT_ACTION > }; > >struct edit_record *all_edits; > >int act_edit_nr = 0; >int first_edit_nr = 0; >int total_edits = 0; >int this_is_no_edit = 0; >int sth_highlighted = 0; > >int motion_from = -1; >int motion_to = -1; >char moved = 0; > >int textpos_to_move_to = 0; >int a_file_is_to_rm = 0; > >XmTextBlock act_ins_text; > >Boolean auto_indent = False; >Boolean readonly = False; >Boolean no_backup = False; >mode_t filemode = 0; > >char textdumpfile[256], editdumpfile[256], recovercmd[256]; >char *textrecfile, *editrecfile; >int recover = 0; >Boolean readonly_forced = 0; >int initial_line = -1; > >int exitflag = 0; > >int *gargc; >char **gargv; > >void pre_modify_cb(Widget, XtPointer, XtPointer); >void post_modify_cb(Widget, XtPointer, XtPointer); >void motion_cb(Widget, XtPointer, XtPointer); >void set_title(); >void auto_indent_cb(); >void wraplines_cb(); >void readonly_cb(); >void usage(char *); >void save_on_hup(int); >void safe_exit(int); >void emergency_exit(int); >void maybe_exit(); >int read_file(char *, char *, int); >void set_wm_interactions(); >void goto_line(); >void find_sel(); >void repl_sel(); >void termproc(); >void get_options(); >void get_extras_menu(); >void file_cb(), edit_cb(), find_cb(), view_cb(), no_backup_cb(); >void extras_proc(); > >String transl = "<Btn2Down>: copy-primary()"; >String linnotransl = "<Key>Return: GotoLine()"; >String findtransl = "<Key>Return: FindSelection()"; >String repltransl = "<Key>Return: ReplaceWith()"; > >XtActionsRec actions[] = { {"GotoLine", goto_line}, > {"FindSelection", find_sel}, > {"ReplaceWith", repl_sel}, }; > >Atom wm_delete_window; >Atom wm_protocols; > >static char * >strrstr(char * string, char * substr) >{ > int len, sublen; > char *cptr; > > len = strlen(string); > sublen = strlen(substr); > > if(len < sublen || len == 0 || sublen == 0) > return(NULL); > > for(cptr = string + len - sublen; cptr >= string; cptr--) > if(*cptr == substr[0]) > if(!strncmp(cptr, substr, sublen)) > return(cptr); > > return(NULL); >} > >#define NUM_LOCSTR 20 > >static XmString *locstrs = NULL; >static int num_locstrs = 0; > >static XmString >xmstr(char * str) /* a very useful hack */ >{ > int i; > XmString *new_strs; > > if(!str){ > for(i = 0; i < num_locstrs; i++) > if(locstrs[i]) > XmStringFree(locstrs[i]); > if(locstrs) > free(locstrs); > locstrs = NULL; > num_locstrs = 0; > return(NULL); > } > > new_strs = (XmString *) malloc((num_locstrs + 1) * sizeof(XmString)); > if(!new_strs) > return(NULL); > > memcpy(new_strs, locstrs, sizeof(XmString) * num_locstrs); > if(locstrs) > free(locstrs); > locstrs = new_strs; > locstrs[num_locstrs] = XmStringCreateLocalized(str); > if(!locstrs[num_locstrs]) > return(NULL); > > num_locstrs++; > return(locstrs[num_locstrs - 1]); >} > > >main(argc, argv) >int argc; >char *argv[]; >{ > XtAppContext app_context; > Widget main_window, menubar, form, find_panel, dummy_widget; > Arg args[20]; > int n = 0, i, j; > XmString open, save, exitstr, exit_acc, file, edit, cut, > clear, copy, paste, find, next, replace, replace_all, > open_acc, save_acc, save_as_acc, save_as, cut_acc, > copy_acc, paste_acc, prev, find_next_acc, > find_prev_acc, find_and_replace, replace_and_find, > find_repl_acc, what_line, line_to_goto, what_line_acc, > goto_line_acc, view, insert, empty, undo, undo_acc, > tmpstr, option; > char buf[256], *cptr; > Atom WM_DELETE_WINDOW; > XtTranslations trsl; > struct stat statb; > > get_extras_menu(); > > XtSetLanguageProc (NULL, NULL, NULL); > > strcpy(buf, argv[0]); > cptr = strrchr(buf, '/'); > if(cptr) > cptr++; > else > cptr = buf; > > if(cptr[0] >= 'a' && cptr[0] <= 'z') > cptr[0] = cptr[0] - 'a' + 'A'; > > atexit(termproc); > exitflag = OPENING_DISPLAY; > > gargc = &argc; > gargv = argv; > > toplevel = XtVaAppInitialize (&app_context, cptr, > NULL, 0, &argc, argv, NULL, XmNdeleteResponse, XmDO_NOTHING, > NULL); > > gargc = &argc; > gargv = argv; > > exitflag = 0; > > XtAppAddActions(app_context, actions, > sizeof(actions) / sizeof(*actions)); > > set_title(); > > XmRepTypeInstallTearOffModelConverter (); > > main_window = XtVaCreateWidget ("mainWindow", > xmMainWindowWidgetClass, toplevel, NULL); > > /* Create a simple MenuBar that contains three menus */ > menubar = XmVaCreateSimpleMenuBar (main_window, "menubar", > XmVaCASCADEBUTTON, xmstr("File"), 'l', > XmVaCASCADEBUTTON, xmstr("Edit"), 'E', > XmVaCASCADEBUTTON, xmstr("View"), 'i', > XmVaCASCADEBUTTON, xmstr("Find"), 'f', > NULL); > > /* First menu is the File menu -- callback is file_cb() */ > XmVaCreateSimplePulldownMenu (menubar, "fileMenu", 0, file_cb, > XmVaPUSHBUTTON, xmstr("Open ..."), 'O', > "Alt<Key>o", xmstr("Alt+O"), > XmVaPUSHBUTTON, xmstr("Save ..."), 'S', > "Alt<Key>s", xmstr("Alt+S"), > XmVaPUSHBUTTON, xmstr("Save As ..."), 'A', > "Alt<Key>a", xmstr("Alt+A"), > XmVaPUSHBUTTON, xmstr("Insert ..."), 'I', NULL, NULL, > XmVaPUSHBUTTON, xmstr("Empty Text"), 'E', NULL, NULL, > /*XmVaSEPARATOR,*/ > XmVaPUSHBUTTON, xmstr("Exit"), 'x', > "Alt<Key>F4"/*"Ctrl<Key>c"*/, xmstr("Alt+F4"), > NULL); > > /* ...create the "Edit" menu -- callback is edit_cb() */ > XmVaCreateSimplePulldownMenu (menubar, "editMenu", 1, edit_cb, > XmVaPUSHBUTTON, xmstr("Cut"), 't', "Alt<Key>x", xmstr("Alt+X"), > XmVaPUSHBUTTON, xmstr("Copy"), 'C', "Alt<Key>c", xmstr("Alt+C"), > XmVaPUSHBUTTON, xmstr("Paste"), 'P', "Alt<Key>v", xmstr("Alt+V"), > XmVaPUSHBUTTON, xmstr("Undo"), 'U', "Alt<Key>z", xmstr("Alt+Z"), >/* XmVaSEPARATOR, > XmVaPUSHBUTTON, xmstr("Clear"), 'l', NULL, NULL,*/ > NULL); > > /* ...create the "View" menu -- callback is view_cb() */ > XmVaCreateSimplePulldownMenu (menubar, "viewMenu", 2, view_cb, > XmVaPUSHBUTTON, xmstr("What Line ?"), 'W', > "Alt<Key>w", xmstr("Alt+W"), > XmVaPUSHBUTTON, xmstr("Goto Line"), 'G', > "Alt<Key>g", xmstr("Alt+G"), > NULL); > > /* create the "Find" menu -- callback is find_cb() */ > find_menu = > XmVaCreateSimplePulldownMenu (menubar, "findMenu", 3, find_cb, > XmVaPUSHBUTTON, xmstr("Find Next"), 'N', > "Ctrl<Key>f", xmstr("Ctrl+F"), > XmVaPUSHBUTTON, xmstr("Find Previous"), 'P', > "Ctrl Shift<Key>f", xmstr("Ctrl+Shift+F"), > XmVaPUSHBUTTON, xmstr("Replace"), 'R', > "Ctrl <Key>r", xmstr("Ctrl+R"), > XmVaPUSHBUTTON, xmstr("Find and Replace"), 'i', NULL, NULL, > XmVaPUSHBUTTON, xmstr("Replace and Find"), 'e', NULL, NULL, > XmVaPUSHBUTTON, xmstr("Show All"), 'A', NULL, NULL, > XmVaPUSHBUTTON, xmstr("Replace All"), 'l', NULL, NULL, > XmVaPUSHBUTTON, xmstr("Find Pair ..."), 'l', NULL, NULL, > NULL); > > option = XmStringCreateLocalized("Options"); > > dummy_widget = XmCreatePulldownMenu(menubar, "optionMenu", NULL, 0); > XtVaCreateManagedWidget("Options", > xmCascadeButtonWidgetClass, menubar, > XmNlabelString, option, > XmNmnemonic, 'p', > XmNsubMenuId, dummy_widget, > NULL); > XmStringFree(option); > >#if 0 > tmpstr = XmStringCreateLocalized("Wrap Lines"); > wraplines_button = XtVaCreateManagedWidget("Wrap Lines", > xmToggleButtonGadgetClass, dummy_widget, NULL); > XmStringFree(tmpstr); > XtAddCallback(wraplines_button, XmNvalueChangedCallback, > wraplines_cb, 0); >#endif > tmpstr = XmStringCreateLocalized("Auto-Indent"); > autoindent_button = XtVaCreateManagedWidget("Auto-Indent", > xmToggleButtonGadgetClass, dummy_widget, NULL); > XmStringFree(tmpstr); > XtAddCallback(autoindent_button, XmNvalueChangedCallback, > auto_indent_cb, 0); > tmpstr = XmStringCreateLocalized("No Backup"); > no_backup_button = XtVaCreateManagedWidget("No Backup", > xmToggleButtonGadgetClass, dummy_widget, NULL); > XmStringFree(tmpstr); > tmpstr = XmStringCreateLocalized("Read-Only"); > readonly_button = XtVaCreateManagedWidget("Read-Only", > xmToggleButtonGadgetClass, dummy_widget, NULL); > XmStringFree(tmpstr); > XtAddCallback(readonly_button, XmNvalueChangedCallback, > readonly_cb, 0); > > if(num_extras > 0){ > dummy_widget = XmCreatePulldownMenu(menubar, "extrasMenu", NULL, 0); > XtVaCreateManagedWidget("Extras", > xmCascadeButtonWidgetClass, menubar, > XmNlabelString, xmstr("Extras"), > XmNsubMenuId, dummy_widget, > NULL); > for(i = 0; i < num_extras; i++){ > tmp_widget = XtVaCreateManagedWidget(extras_names[i], > xmPushButtonGadgetClass, dummy_widget, NULL); > XtAddCallback(tmp_widget, XmNactivateCallback, extras_proc, i); > } > } > xmstr(NULL); > > XtManageChild (menubar); > > /* create a form work are */ > form = XtVaCreateWidget ("form", > xmFormWidgetClass, main_window, NULL); > > /* create horizontal RowColumn inside the form */ > find_panel = XtVaCreateWidget ("findPanel", > xmRowColumnWidgetClass, form, > XmNorientation, XmHORIZONTAL, > XmNpacking, XmPACK_TIGHT, > XmNtopAttachment, XmATTACH_FORM, > XmNleftAttachment, XmATTACH_FORM, > XmNrightAttachment, XmATTACH_FORM, > NULL); > /* Create three TextField widgets with Labels... */ > XtVaCreateManagedWidget ("Search:", > xmLabelGadgetClass, find_panel, NULL); > find_text = XtVaCreateManagedWidget ("findText", > xmTextFieldWidgetClass, find_panel, NULL); > XtVaCreateManagedWidget (" Replace:", > xmLabelGadgetClass, find_panel, NULL); > replace_text = XtVaCreateManagedWidget ("replaceText", > xmTextFieldWidgetClass, find_panel, NULL); > XtVaCreateManagedWidget (" Line-Number:", > xmLabelGadgetClass, find_panel, NULL); > lineno_text = XtVaCreateManagedWidget ("linenoText", > xmTextFieldWidgetClass, find_panel, NULL); > XtManageChild (find_panel); > > text_output = XtVaCreateManagedWidget ("textOutput", > xmTextFieldWidgetClass, form, > XmNeditable, False, > XmNcursorPositionVisible, False, > XmNshadowThickness, 0, > XmNleftAttachment, XmATTACH_FORM, > XmNrightAttachment, XmATTACH_FORM, > XmNbottomAttachment, XmATTACH_FORM, > NULL); > > n = 0; > XtSetArg (args[n], XmNrows, 10); n++; > XtSetArg (args[n], XmNcolumns, 80); n++; > XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; > XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; > XtSetArg (args[n], XmNtopWidget, find_panel); n++; > XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; > XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; > XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; > XtSetArg (args[n], XmNbottomWidget, text_output); n++; > text_edit = XmCreateScrolledText (form, "textEdit", args, n); > XtAddCallback (text_edit, XmNmodifyVerifyCallback, pre_modify_cb, NULL); > XtAddCallback (text_edit, XmNvalueChangedCallback, post_modify_cb, NULL); > XtAddCallback (text_edit, XmNmotionVerifyCallback, motion_cb, NULL); > XtManageChild (text_edit); > > trsl = XtParseTranslationTable(transl); > XtOverrideTranslations(text_edit, trsl); > > trsl = XtParseTranslationTable(linnotransl); > XtOverrideTranslations(lineno_text, trsl); > > trsl = XtParseTranslationTable(findtransl); > XtOverrideTranslations(find_text, trsl); > > trsl = XtParseTranslationTable(repltransl); > XtOverrideTranslations(replace_text, trsl); > > XtManageChild (form); > XtManageChild (main_window); > > all_edits = (struct edit_record *) > malloc(max_undos * sizeof(struct edit_record)); > > for(i = 0; i < max_undos; i++){ > memcpy(all_edits + i, &act_edit, sizeof(act_edit)); > all_edits[i].ins_string = (char *) malloc(sizeof(char)); > all_edits[i].del_string = (char *) malloc(sizeof(char)); > } > all_edits[0].type = PASTE_ACTION; > > get_options(); > > if(act_filename){ > i = readonly; > > if(read_file(act_filename, buf, 0)){ > cptr = act_filename + strlen(act_filename) - 1; > if(*cptr == '/'){ > sprintf(buf, > "%s is the name of a directory. Filename ignored.", > act_filename); > act_filename = NULL; > } > else{ > j = strlen(act_filename); > if(cptr = strrchr(act_filename, '/')){ > *(cptr) = '\0'; > if(!act_filename[0] && j < 2){ > sprintf(buf, "/ is a directory. Filename ignored."); > act_filename = NULL; > } > else{ > if(*act_filename && stat(act_filename, &statb) == -1){ > sprintf(buf, "The directory %s does not exist. Filename ignored.", > act_filename); > act_filename = NULL; > } > else{ > *cptr = '/'; > j = stat(act_filename, &statb); > if(j != -1 && S_ISDIR(statb.st_mode)){ > sprintf(buf, "%s is a directory. Filename ignored.", > act_filename); > act_filename = NULL; > } > } > } > *cptr = '/'; > } > } > > if(act_filename) > sprintf(buf, > "%s not found. File will be created when saving.", > act_filename); > } > > set_title(); > > XmTextSetString(text_output, buf); > > if(initial_line >= 0){ > sprintf(buf, "%d", initial_line); > XmTextSetString(lineno_text, buf); > goto_line(); > } > > if(readonly_forced) > readonly = i; > } > > if(recover){ > if(read_file(textrecfile, buf, 0)){ > fprintf(stderr, "Recovering failed.\n"); > exit(0); > } > else > a_file_is_to_rm |= TEXTRECFILE; > > if(load_edits()){ > fprintf(stderr, "Recovering partially failed, sorry.\n"); > act_edit_nr = first_edit_nr = total_edits = 0; > } > else > a_file_is_to_rm |= EDITRECFILE; > > if(act_filename) > if(!strcmp(act_filename, "")) > act_filename = NULL; > > set_title(); > > XmTextSetString(text_output, buf); > > } > > XtVaSetValues(autoindent_button, XmNset, auto_indent, NULL); > XtVaSetValues(readonly_button, XmNset, readonly, NULL); > XtVaSetValues(no_backup_button, XmNset, no_backup, NULL); > > tmpnam(textdumpfile); > tmpnam(editdumpfile); > strcat(textdumpfile, ".textedit.text"); > strcat(editdumpfile, ".textedit.edit"); > sprintf(recovercmd, "%s -recover %s %s &", argv[0], textdumpfile, > editdumpfile); > > signal(SIGTERM, safe_exit); > signal(SIGINT, safe_exit); > signal(SIGBUS, emergency_exit); > signal(SIGSEGV, emergency_exit); > signal(SIGHUP, save_on_hup); > > XtRealizeWidget (toplevel); > set_wm_interactions(); > XtAppMainLoop (app_context); >} > >void >get_options() >{ > int i; > > recover = 0; > readonly_forced = False; > if(act_filename) > free(act_filename); > act_filename = NULL; > > for(i = 1; i < *gargc; i++){ > if(! strcmp(gargv[i], "+ai")) > auto_indent = True; > else if(! strcmp(gargv[i], "-ai")) > auto_indent = False; > else if(! strcmp(gargv[i], "+ro")){ > readonly_forced = True; > readonly = True; > } > else if(! strcmp(gargv[i], "-ro")){ > readonly_forced = True; > readonly = False; > } > else if(! strcmp(gargv[i], "+nb")) > no_backup = True; > else if(! strcmp(gargv[i], "-nb")) > no_backup = False; > else if(! strcmp(gargv[i], "-recover")){ > recover = 1; > textrecfile = gargv[i + 1]; > editrecfile = gargv[i + 2]; > i += 2; > } > else if(gargv[i][0] == '-') > usage(gargv[0]); > else if(gargv[i][0] == '+' > && gargv[i][1] >= '0' && gargv[i][1] <= '9') > sscanf(gargv[i] + 1, "%d", &initial_line); > else{ > if(act_filename) > usage(gargv[0]); > act_filename = strdup(gargv[i]); > } > } >} > >void >reset_act_edit() >{ > act_edit.ins_start = act_edit.ins_end = act_edit.del_start > = act_edit.del_end = 0; > act_edit.type = PASTE_ACTION; >} > >void >set_title() >{ > char buf[256], *cptr; > int i; > > sprintf(buf, "Editor: %s %s", act_filename ? > act_filename : "[No Filename]", > total_edits > 0 ? "(edited)" : ""); > > XtVaSetValues(toplevel, XmNtitle, buf, NULL); > > sprintf(buf, "%s", act_filename ? > act_filename : "[No Filename]"); > > for(cptr = buf + strlen(buf); *cptr != '/' && cptr >= buf; cptr--); > if(*cptr == '/') > cptr++; > if(cptr < buf) > cptr = buf; > > for(i = 0; *cptr; i++, cptr++) > buf[i] = *cptr; > buf[i] = '\0'; > for(; cptr >= buf; cptr--) > *(cptr + 1) = *cptr; > buf[0] = '('; > > cptr = buf + 1; > if(total_edits > 0){ > cptr = buf; > buf[i + 1] = ')'; > buf[i + 2] = '\0'; > } > > XtVaSetValues(toplevel, XmNiconName, cptr, NULL); >} > >void >evaluate_change() >{ > char act_action, *string, *text, *cptr; > int *ip, finish, textpos, i; > struct edit_record *er; > > text = NULL; > > if(act_edit.del_start < act_edit.del_end && act_edit.ins_start < act_edit.ins_end){ > act_action = CUTPASTE_ACTION; > act_edit.ins_start -= act_edit.del_end - act_edit.del_start; > act_edit.ins_end -= act_edit.del_end - act_edit.del_start; > > goto found_action; > } > if(act_edit.del_start == act_edit.del_end - 1){ > if(act_edit.ins_start != act_edit.del_start){ > act_action = BACKSP_ACTION; > act_edit.ins_start--; > act_edit.ins_end--; > } > else{ > act_action = DELETE_ACTION; > } > } > else if(act_edit.del_start < act_edit.del_end){ > act_action = CUT_ACTION; > act_edit.ins_start = act_edit.ins_end = act_edit.del_start; > } > if(act_edit.ins_end == act_edit.ins_start + 1){ > act_action = INSERT_ACTION; > } > else if(act_edit.ins_start < act_edit.ins_end){ > act_action = PASTE_ACTION; > } > > found_action: > act_edit.type = act_action; > > finish = 0; > if(all_edits[act_edit_nr].ins_end != act_edit.ins_start > || act_action == BACKSP_ACTION){ > finish = 1; > > if(all_edits[act_edit_nr].ins_end - 1 == act_edit.ins_start > && act_action == BACKSP_ACTION > && (all_edits[act_edit_nr].type == DELETE_ACTION > || all_edits[act_edit_nr].type == BACKSP_ACTION)) > finish = 0; > } > else if(act_action == PASTE_ACTION || act_action == CUT_ACTION > || act_action == CUTPASTE_ACTION) > finish = 1; > else{ > if(all_edits[act_edit_nr].type != act_action){ > if((all_edits[act_edit_nr].type != DELETE_ACTION > && all_edits[act_edit_nr].type != BACKSP_ACTION) || > (act_action != DELETE_ACTION > && act_action != BACKSP_ACTION)){ > finish = 1; > } > } > } > if(act_action == INSERT_ACTION) > if(act_edit.ins_string[0] == '\n') > finish = 1; > > if(finish){ > act_edit_nr = (act_edit_nr + 1)/* % max_undos*/; > > if(act_edit_nr >= max_undos){ > max_undos += 50; > all_edits = realloc(all_edits, max_undos * sizeof(*all_edits)); > for(i = max_undos - 50; i < max_undos; i++){ > memset(all_edits + i, 0, sizeof(*all_edits)); > all_edits[i].ins_string = malloc(1); > all_edits[i].del_string = malloc(1); > all_edits[i].type = PASTE_ACTION; > } > } > > if(act_edit_nr == first_edit_nr){ > first_edit_nr = (first_edit_nr + 1) % max_undos; > } > > total_edits++; > > er = &(all_edits[act_edit_nr]); > > er->ins_start = er->ins_end = er->del_start = er->del_end = > act_edit.ins_start; > er->del_strlen = er->ins_strlen = 0; > strcpy(er->del_string, ""); > } > > if(act_action == INSERT_ACTION){ > if(act_edit.ins_string[0] == '\n'){ > int num_inserts; > > if(auto_indent){ > text = XmTextGetString(text_edit); > > textpos = (int) XmTextGetCursorPosition(text_edit); > > for(i = textpos; i > 0 && text[i - 1] != '\n'; i--); > > for(num_inserts = 0; > isspace(text[i + num_inserts]) > && text[i + num_inserts] != '\n'; > num_inserts++); > > act_ins_text->ptr = XtRealloc(act_ins_text->ptr, sizeof(char) > * (num_inserts + 1)); > cptr = act_ins_text->ptr; > memcpy(cptr + 1, text + i, num_inserts * sizeof(char)); > cptr[0] = '\n'; > > act_ins_text->length = num_inserts + 1; > > act_edit.ins_end += num_inserts; > } > } > } > > switch(act_action){ > case DELETE_ACTION: > case BACKSP_ACTION: > case CUT_ACTION: > case CUTPASTE_ACTION: > if(! text) > text = XmTextGetString(text_edit); > break; > } > > er = &(all_edits[act_edit_nr]); > ip = &(er->del_strlen); > > switch(act_action){ > case BACKSP_ACTION: > string = (char *) malloc(sizeof(char) * (2 + *ip)); > strncpy(string + 1, er->del_string, *ip); > string[0] = text[act_edit.del_start]; > string[*ip + 1] = '\0'; > > (*ip)++; > free(er->del_string); > er->del_string = string; > break; > > case DELETE_ACTION: > string = (char *) malloc(sizeof(char) * (2 + *ip)); > strncpy(string, er->del_string, *ip); > string[*ip] = text[act_edit.del_start]; > string[*ip + 1] = '\0'; > > (*ip)++; > free(er->del_string); > er->del_string = string; > break; > > case INSERT_ACTION: > act_edit.ins_start = er->ins_start; > break; > > case CUT_ACTION: > case CUTPASTE_ACTION: > *ip = act_edit.del_end - act_edit.del_start; > string = (char *) malloc(sizeof(char) * (1 + *ip)); > strncpy(string, text + act_edit.del_start, *ip); > string[*ip] = '\0'; > > free(er->del_string); > er->del_string = string; > break; > > } > > er->ins_start = act_edit.ins_start; > er->ins_end = act_edit.ins_end; > er->del_start = act_edit.del_start; > er->del_end = act_edit.del_end; > er->type = act_action; > > getout: > if(text) > XtFree(text); >} > >void >insert_text(char ** text, int textlength, char * string, int stringlen, > int insert_pos) >{ > char *newtext; > > newtext = (char *) malloc(sizeof(char) * (textlength + stringlen + 3)); > > memcpy(newtext, *text, sizeof(char) * insert_pos); > memcpy(newtext + insert_pos, string, sizeof(char) * stringlen); > memcpy(newtext + insert_pos + stringlen, *text + insert_pos, > sizeof(char) * (textlength - insert_pos)); > newtext[textlength + stringlen] = '\0'; > > free(*text); > *text = newtext; >} > >void >delete_text(char ** text, int textlength, int delpos, int dellen) >{ > int i; > > for(i = delpos; i < textlength - dellen; i++) > (*text)[i] = (*text)[i + dellen]; > > if(dellen > 0) > (*text)[i] = '\0'; >} > >void >undo_actual() >{ > char *text, buf[256]; > int textlen; > > if(act_edit_nr == first_edit_nr && readonly) > return; > > if(act_edit_nr == first_edit_nr){ > if(total_edits) > XmTextSetString(text_output, "Maximum number of unedits reached."); > else{ > XmTextSetString(text_output, "Nothing more to unedit."); > } > > XBell(XtDisplay(toplevel), 50); > > return; > } > > if(readonly){ > XBell(XtDisplay(toplevel), 50); > > sprintf(buf, "Text is read-only ! You may toggle this option."); > > XmTextSetString(text_output, buf); > > return; > } > >#if 0 > text = XmTextGetString(text_edit); > textlen = (int) XmTextGetLastPosition(text_edit); >#endif > > this_is_no_edit = 1; > >#if 0 > delete_text(&text, textlen, all_edits[act_edit_nr].ins_start, > all_edits[act_edit_nr].ins_end - > all_edits[act_edit_nr].ins_start); > insert_text(&text, textlen, all_edits[act_edit_nr].del_string, > all_edits[act_edit_nr].del_strlen, > all_edits[act_edit_nr].del_start); > > XmTextSetString(text_edit, text); >#endif > > XmTextReplace(text_edit, all_edits[act_edit_nr].ins_start, > all_edits[act_edit_nr].ins_end, > all_edits[act_edit_nr].del_string); > > XmTextSetCursorPosition(text_edit, all_edits[act_edit_nr].del_end); > XmTextSetInsertionPosition(text_edit, all_edits[act_edit_nr].del_end); > >#if 0 > XFree(text); >#endif > > act_edit_nr--; > if(act_edit_nr < 0) > act_edit_nr = (act_edit_nr + max_undos) % max_undos; > > memcpy(&act_edit, all_edits + act_edit_nr, sizeof(act_edit)); > act_edit.type = PASTE_ACTION; > > total_edits--; > > if(total_edits == 0){ > set_title(); > } >} > >void >pre_modify_cb(Widget w, XtPointer client_data, XtPointer call_data) >{ > XmTextVerifyPtr text_call_data; > XmTextPosition pos; > char *str, buf[256]; > > if(sth_highlighted){ > pos = XmTextGetLastPosition(text_edit); > XmTextSetHighlight (text_edit, 0, pos, XmHIGHLIGHT_NORMAL); > sth_highlighted = 0; > } > > if(this_is_no_edit){ > this_is_no_edit = 0; > return; > } > > text_call_data = (XmTextVerifyPtr) call_data; > > if(readonly){ > text_call_data->doit = False; > > XBell(XtDisplay(toplevel), 50); > > sprintf(buf, "Text is read-only ! You may toggle this option."); > > XmTextSetString(text_output, buf); > > return; > } > > act_ins_text = text_call_data->text; > act_edit.ins_start = act_edit.ins_end = text_call_data->currInsert; > if(text_call_data->text->length > 0){ > act_edit.ins_end = text_call_data->currInsert > + text_call_data->text->length; > } > act_edit.del_start = text_call_data->startPos; > act_edit.del_end = text_call_data->endPos; > act_edit.ins_string = text_call_data->text->ptr; > > if(moved) > act_edit.ins_start = motion_to; > > moved = 0; > > evaluate_change(); > > if(total_edits == 1){ > set_title(); > } >} > >void >post_modify_cb(Widget w, XtPointer client_data, XtPointer call_data) >{ >} > >void >motion_cb(Widget w, XtPointer client_data, XtPointer call_data) >{ > XmTextVerifyPtr text_call_data; > XmTextPosition pos; > > if(sth_highlighted){ > pos = XmTextGetLastPosition(text_edit); > XmTextSetHighlight (text_edit, 0, pos, XmHIGHLIGHT_NORMAL); > sth_highlighted = 0; > } > > text_call_data = (XmTextVerifyPtr) call_data; > > motion_from = text_call_data->currInsert; > motion_to = text_call_data->newInsert; > moved = 1; > > if(a_file_is_to_rm){ > if(a_file_is_to_rm & EDITRECFILE) > unlink(editrecfile); > if(a_file_is_to_rm & TEXTRECFILE) > unlink(textrecfile); > > a_file_is_to_rm = 0; > } >} > > >int >read_file(char * filename, char * return_msg, int inserting) >{ > struct stat statb; > int fault = 0, len; > FILE *fp; > char *text; > XmTextPosition insertion_position; > > strcpy(return_msg, ""); > > /* make sure the file is a regular text file and open it */ > if (stat (filename, &statb) == -1) > fault = 1; > else if ((statb.st_mode & S_IFMT) != S_IFREG) > fault = 1; > else if(!(fp = fopen (filename, "r"))) > fault = 1; > > if(fault) { > sprintf (return_msg, "Can't read %s.", filename); > XmTextSetString (text_output, return_msg); > return(1); > } > > /* put the contents of the file in the Text widget by > * allocating enough space for the entire file, reading the > * file into the space, and using XmTextSetString() to show > * the file. > */ > len = statb.st_size; > if (!(text = XtMalloc ((unsigned)(len+1)))) /* +1 for NULL */ > sprintf (return_msg, "%s: XtMalloc(%ld) failed", len, filename); > else { > if (fread (text, sizeof (char), len, fp) != len) > sprintf (return_msg, "Warning: did not read entire file!"); > else > sprintf (return_msg, "%s %ld bytes from %s.", > inserting ? "Inserted" : "Loaded", len, filename); > text[len] = 0; /* NULL-terminate */ > > if(inserting){ > insertion_position = XmTextGetInsertionPosition(text_edit); > XmTextInsert (text_edit, insertion_position, text); > } > else{ > if(len > 0) > this_is_no_edit = 1; > > XmTextSetString (text_edit, text); > act_edit_nr = first_edit_nr = total_edits = 0; > > reset_act_edit(); > > fclose(fp); > > fp = fopen(filename, "a"); > if(fp) > fclose(fp); > > readonly = (! fp); > > fp = NULL; > > XtVaSetValues(readonly_button, XmNset, readonly, NULL); > > if(readonly) > strcat(return_msg, " File is read-only."); > } > } > > if(fp) > fclose(fp); > > filemode = statb.st_mode; > > return(0); >} > >int >save_file(char * filename, char * return_msg) >{ > struct stat statb; > FILE *fp; > int len; > char *text, buf[256]; > Boolean file_there; > > if(file_there = (! stat(filename, &statb))) > filemode = statb.st_mode; > > fp = fopen(filename, "a"); > > if(!fp){ > strcpy(return_msg, "File is not writable, text not saved."); > > XBell(XtDisplay(toplevel), 50); > > return(1); > } > else > fclose(fp); > > XtVaGetValues(no_backup_button, XmNset, &no_backup, NULL); > > if(! no_backup){ > sprintf(buf, "%s%%", filename); > > fp = fopen(buf, "r"); > > if(fp){ > fclose(fp); > > fp = fopen(buf, "a"); > if(fp) > fclose(fp); > else{ > strcpy(return_msg, > "Backup file is not writable, text not saved."); > strcat(return_msg, " You toggle the backup option."); > > XBell(XtDisplay(toplevel), 50); > > return(1); > } > } > > if(file_there){ > if(rename(filename, buf)){ > strcpy(return_msg, "Cannot backup file, text not saved."); > strcat(return_msg, " You may try to toggle the backup option."); > > XBell(XtDisplay(toplevel), 50); > > return(1); > } > } > } > > if (!(fp = fopen (filename, "w"))) { > perror (filename); > sprintf (return_msg, "Can't save to %s.", filename); > XmTextSetString (text_output, return_msg); > XtFree (filename); > return(1); > } > /* saving -- get text from Text widget... */ > text = XmTextGetString (text_edit); > len = XmTextGetLastPosition (text_edit); > /* write it to file (check for error) */ > if (fwrite (text, sizeof (char), len, fp) != len) > strcpy (return_msg, "Warning: did not write entire file!"); > else { > /* make sure a newline terminates file */ > if (text[len-1] != '\n') > fputc ('\n', fp); > sprintf (return_msg, "Saved %ld bytes to %s.", len, filename); > } > fclose(fp); > > if(filemode) > chmod(filename, filemode); > > act_edit_nr = first_edit_nr = total_edits = 0; > > reset_act_edit(); > > return(0); >} > >/* file_select_cb() -- callback routine for "OK" button in > * FileSelectionDialogs. > */ >void >file_select_cb(dialog, client_data, call_data) >Widget dialog; >XtPointer client_data; >XtPointer call_data; >{ > char buf[256], *filename; > long len; > int reason = (int) client_data; > XmFileSelectionBoxCallbackStruct *cbs = > (XmFileSelectionBoxCallbackStruct *) call_data; > > if (!XmStringGetLtoR (cbs->value, XmFONTLIST_DEFAULT_TAG, &filename)) > return; /* must have been an internal error */ > > if (*filename == '\0') { > XtFree (filename); > XBell (XtDisplay (text_edit), 50); > XmTextSetString (text_output, "Choose a file."); > return; /* nothing typed */ > } > > if (reason == FILE_SAVE_AS) { > save_file(filename, buf); > } > else if(reason == FILE_SAVE) { > fprintf(stderr, "Internal Error: sdferww.\n"); > } > else if(reason == FILE_OPEN) { > read_file(filename, buf, 0); > } > else { /* reason == FILE_INSERT */ > read_file(filename, buf, 1); > } > XmTextSetString (text_output, buf); /* purge output message */ > > if(reason != FILE_INSERT){ > if(act_filename) > free(act_filename); > act_filename = strdup(filename); > if(! act_filename){ > fprintf(stderr, "malloc failed.\n"); > } > } > > /* free all allocated space. */ > XtFree (filename); > XtUnmanageChild (dialog); > > set_title(); >} > >/* popdown_cb() -- callback routine for "Cancel" button. */ >void >popdown_cb (w, client_data, call_data) >Widget w; >XtPointer client_data; >XtPointer call_data; >{ > XtUnmanageChild (w); >} > >void >maybe_exit() >{ > if(total_edits){ > if(sth_highlighted == 25) > exit(0); > > XBell(XtDisplay(toplevel), 50); > > XmTextSetString(text_output, "Warning: Text has been modified, but not saved. Choose \"Exit\" again to really exit."); > > sth_highlighted = 25; > > return; > } > > exit(0); >} > >/* file_cb() -- a menu item from the "File" pulldown menu was selected */ >void >file_cb(w, client_data, call_data) >Widget w; >XtPointer client_data; >XtPointer call_data; >{ > static Widget open_dialog = NULL, save_dialog = NULL, ins_dialog = NULL; > Widget dialog = NULL; > XmString button, title; > int reason = (int) client_data; > char buf[256]; > > if (reason == FILE_EXIT){ > maybe_exit(); > return; > } > > XmTextSetString (text_output, NULL); /* clear message area */ > > if(reason == FILE_OPEN && total_edits){ > XBell(XtDisplay(toplevel), 50); > > XmTextSetString(text_output, > "Warning: Actual text has been modified and is not saved !"); > } > > if(reason == FILE_EMPTY){ > XmTextSetString(text_edit, ""); > return; > } > if (reason == FILE_OPEN && open_dialog) > dialog = open_dialog; > else if (reason == FILE_SAVE_AS && save_dialog) > dialog = save_dialog; > else if(reason == FILE_INSERT && ins_dialog) > dialog = ins_dialog; > else if(reason == FILE_SAVE){ > if(! act_filename) > reason = FILE_SAVE_AS; > else if(total_edits == 0){ > strcpy(buf, "File has not been modified, save operation ignored."); > XmTextSetString (text_output, buf); > return; > } > else{ > strcpy(buf, ""); > save_file(act_filename, buf); > XmTextSetString (text_output, buf); > set_title(); > return; > } > } > > if (dialog) { > XtManageChild (dialog); > /* make sure that dialog is raised to top of window stack */ > XMapRaised (XtDisplay (dialog), XtWindow (XtParent (dialog))); > return; > } > > dialog = XmCreateFileSelectionDialog (text_edit, "Files", NULL, 0); > XtAddCallback (dialog, XmNcancelCallback, popdown_cb, NULL); > XtAddCallback (dialog, XmNokCallback, file_select_cb, (void *)reason); > if (reason == FILE_OPEN) { > button = XmStringCreateLocalized ("Open"); > title = XmStringCreateLocalized ("Open File"); > open_dialog = dialog; > } > if(reason == FILE_SAVE_AS){ > button = XmStringCreateLocalized ("Save"); > title = XmStringCreateLocalized ("Save File"); > save_dialog = dialog; > } > if(reason == FILE_INSERT){ > button = XmStringCreateLocalized ("Insert"); > title = XmStringCreateLocalized ("Insert File"); > ins_dialog = dialog; > } > > XtVaSetValues (dialog, > XmNokLabelString, button, > XmNdialogTitle, title, > NULL); > XmStringFree (button); > XmStringFree (title); > XtManageChild (dialog); >} > >void >set_new_pos( > char *text, > XmTextPosition oldpos, > XmTextPosition newpos) >{ > int i, j; > short rows; > XmTextPosition toppos; > > XtVaGetValues(text_edit, > XmNrows, &rows, > XmNtopCharacter, &toppos, NULL); > > if(toppos > newpos){ > i = 0; > for(j = newpos; j <= toppos; j++) > if(text[j] == '\n') > i++; > XmTextScroll(text_edit, -i - rows / 5); > } > else{ > i = 0; > for(j = toppos; j <= newpos; j++) > if(text[j] == '\n') > i++; > > if(i > rows * 6 / 7 && i < rows * 3 / 2){ > XmTextScroll(text_edit, i - rows * 6 / 7); > } > if(i < rows / 7){ > XmTextScroll(text_edit, i - rows / 7); > } > if(i >= rows * 3 / 2){ > XmTextScroll(text_edit, i - rows / 2); > } > } > > XtVaSetValues(text_edit, XmNcursorPosition, newpos, NULL); >} > >void >find_sel() >{ > XmTextPosition pos; > > pos = XmTextGetInsertionPosition(text_edit); > > XmTextSetSelection(text_edit, pos, pos, CurrentTime); > > find_cb(find_menu, (XtPointer) SEARCH_FIND_NEXT, (XtPointer) NULL); >} > >void >repl_sel() >{ > find_cb(find_menu, (XtPointer) SEARCH_REPLACE, (XtPointer) NULL); >} > >Widget >top_shell(Widget ch) >{ > while(ch && !XtIsWMShell(ch)) > ch = XtParent(ch); > > return(ch); >} > >/* For interactions with the window-manager */ >Atom find_pair_wm_delete_window; >Atom find_pair_wm_protocols; > >int find_pair_mode = 0; >char *left_pat = NULL; >char *right_pat = NULL; > > >/* window-delete handler */ >static void >find_pair_client_msg_handler( > Widget w, > XtPointer closure, > XEvent *event) >{ > XClientMessageEvent *c; > > c = (XClientMessageEvent *) event; > > if (event->type != ClientMessage || > c->message_type != find_pair_wm_protocols) > return; > > find_pair_dialog = NULL; >} > >static void >set_find_pair_mode( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > XmToggleButtonCallbackStruct *state; > > state = (XmToggleButtonCallbackStruct *) call_data; > > if(state->set) > find_pair_mode = (int) client_data; >} > >static void >find_pair_proc( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > int mode = (int) client_data; > int leftlen, rightlen, actpos, tlen, leftfound, rightfound; > int i, count; > char *text = NULL; > char *cptr, *rcptr, *lcptr; > char *left_pat_to_find, *right_pat_to_find; > > XmTextSetString (text_output, ""); > > if(left_pat) > XtFree(left_pat); > if(right_pat) > XtFree(right_pat); > > left_pat = XmTextGetString(pat_one_text); > right_pat = XmTextGetString(pat_two_text); > actpos = XmTextGetInsertionPosition(text_edit); > text = XmTextGetString(text_edit); > tlen = XmTextGetLastPosition(text_edit); > > switch(find_pair_mode){ > case 0: > left_pat_to_find = "{"; > right_pat_to_find = "}"; > break; > case 1: > left_pat_to_find = "("; > right_pat_to_find = ")"; > break; > case 2: > left_pat_to_find = "/*"; > right_pat_to_find = "*/"; > break; > default: > left_pat_to_find = (left_pat ? left_pat : ""); > right_pat_to_find = (right_pat ? right_pat : ""); > } > > leftlen = strlen(left_pat_to_find); > rightlen = strlen(right_pat_to_find); > > if(!leftlen && mode != 2){ > XmTextSetString (text_output, "No left pattern specified"); > goto done_find_pair; > } > if(!rightlen && mode != 2){ > XmTextSetString (text_output, "No right pattern specified"); > goto done_find_pair; > } > > switch(mode){ > case 0: > cptr = strstr(text + actpos, left_pat_to_find); > > if(!cptr){ > XmTextSetString (text_output, "Left Side not found"); > goto done_find_pair; > } > > leftfound = cptr - text; > > cptr += leftlen; > count = 1; > while(count > 0){ > lcptr = strstr(cptr, left_pat_to_find); > rcptr = strstr(cptr, right_pat_to_find); > > if(!rcptr){ > XmTextSetString (text_output, "Pair not found"); > goto done_find_pair; > } > > if(lcptr){ > if(lcptr < rcptr){ > count++; > cptr = lcptr + leftlen; > } > else{ > count--; > cptr = rcptr + rightlen; > } > } > else{ > count--; > cptr = rcptr + rightlen; > } > } > > rightfound = rcptr - text; > > XmTextSetSelection(text_edit, > leftfound, rightfound + rightlen, CurrentTime); > XmTextSetHighlight(text_edit, leftfound, rightfound + rightlen, > XmHIGHLIGHT_SELECTED); > if(strcmp(left_pat_to_find, right_pat_to_find)){ > XmTextSetInsertionPosition(text_edit, rightfound); > XmTextSetCursorPosition(text_edit, rightfound); > XmTextSetInsertionPosition(text_edit, leftfound + 1); > XmTextSetCursorPosition(text_edit, leftfound + 1); > } > else{ > XmTextSetInsertionPosition(text_edit, leftfound); > XmTextSetCursorPosition(text_edit, leftfound); > XmTextSetInsertionPosition(text_edit, rightfound + rightlen); > XmTextSetCursorPosition(text_edit, rightfound + rightlen); > } > sth_highlighted = 1; > > break; > case 1: > text[actpos] = '\0'; > cptr = strrstr(text, right_pat_to_find); > > if(!cptr){ > XmTextSetString (text_output, "Right Side not found"); > goto done_find_pair; > } > > rightfound = cptr - text; > > *cptr = '\0'; > count = 1; > while(count > 0){ > lcptr = strrstr(text, left_pat_to_find); > rcptr = strrstr(text, right_pat_to_find); > > if(!lcptr){ > XmTextSetString (text_output, "Pair not found"); > goto done_find_pair; > } > > if(rcptr){ > if(lcptr < rcptr){ > count++; > cptr = rcptr; > *cptr = '\0'; > } > else{ > count--; > cptr = lcptr; > *cptr = '\0'; > } > } > else{ > count--; > cptr = lcptr; > *cptr = '\0'; > } > } > > leftfound = lcptr - text; > > XmTextSetSelection(text_edit, > leftfound, rightfound + rightlen, CurrentTime); > XmTextSetHighlight(text_edit, leftfound, rightfound + rightlen, > XmHIGHLIGHT_SELECTED); > if(strcmp(left_pat_to_find, right_pat_to_find)){ > XmTextSetInsertionPosition(text_edit, leftfound); > XmTextSetCursorPosition(text_edit, leftfound); > XmTextSetInsertionPosition(text_edit, rightfound + rightlen - 1); > XmTextSetCursorPosition(text_edit, rightfound + rightlen - 1); > } > else{ > XmTextSetInsertionPosition(text_edit, rightfound + rightlen); > XmTextSetCursorPosition(text_edit, rightfound + rightlen); > XmTextSetInsertionPosition(text_edit, leftfound); > XmTextSetCursorPosition(text_edit, leftfound); > } > sth_highlighted = 1; > > break; > case 2: > XtDestroyWidget(find_pair_dialog); > find_pair_dialog = NULL; > break; > } > > done_find_pair: > if(text) > XtFree(text); >} > >void >popup_find_pair_dialog() >{ > Position x, y; > Widget pat_label, pat_one_label, action_form, find_forw_button, > pat_two_label, find_backw_button, find_done_button; > > if(find_pair_dialog){ > XMapRaised (XtDisplay (find_pair_dialog), XtWindow (find_pair_dialog)); > > return; > } > > find_pair_dialog = XtVaCreatePopupShell("findPair", > transientShellWidgetClass, toplevel, > XmNdeleteResponse, XmDESTROY, > XmNtitle, "Find Pair", > NULL); > > find_pair_pane = XtVaCreateManagedWidget("findPairPane", > xmPanedWindowWidgetClass, find_pair_dialog, > NULL); > find_pair_form = XtVaCreateManagedWidget("findPairForm", > xmFormWidgetClass, find_pair_pane, > NULL); > find_pair_radio_box = XtVaCreateManagedWidget("findPairSel", > xmRowColumnWidgetClass, find_pair_form, > XmNradioAlwaysOne, True, > XmNradioBehavior, True, > XmNentryClass, xmToggleButtonGadgetClass, > XmNisHomogeneous, True, > XmNtraversalOn, True, > XmNnavigationType, XmTAB_GROUP, > NULL); > > curly_sel = XtVaCreateManagedWidget("curlySel", > xmToggleButtonGadgetClass, find_pair_radio_box, > XmNset, (find_pair_mode == 0), > XmNlabelString, xmstr("{ }"), > NULL); > XtAddCallback(curly_sel, XmNvalueChangedCallback, set_find_pair_mode, 0); > round_sel = XtVaCreateManagedWidget("roundSel", > xmToggleButtonGadgetClass, find_pair_radio_box, > XmNset, (find_pair_mode == 1), > XmNlabelString, xmstr("( )"), > NULL); > XtAddCallback(round_sel, XmNvalueChangedCallback, set_find_pair_mode, 1); > ccommsel = XtVaCreateManagedWidget("ccommsel", > xmToggleButtonGadgetClass, find_pair_radio_box, > XmNset, (find_pair_mode == 2), > XmNlabelString, xmstr("/* */"), > NULL); > XtAddCallback(ccommsel, XmNvalueChangedCallback, set_find_pair_mode, 2); > other_sel = XtVaCreateManagedWidget("other_sel", > xmToggleButtonGadgetClass, find_pair_radio_box, > XmNset, (find_pair_mode == 3), > XmNlabelString, xmstr("other"), > NULL); > XtAddCallback(other_sel, XmNvalueChangedCallback, set_find_pair_mode, 3); > > pat_label = XtVaCreateManagedWidget("patLabel", > xmLabelGadgetClass, find_pair_form, > XmNlabelString, xmstr("Other Enclosing Pair:"), > XmNleftAttachment, XmATTACH_WIDGET, > XmNleftWidget, find_pair_radio_box, > XmNleftOffset, 20, > XmNtopAttachment, XmATTACH_FORM, > XmNtopOffset, 10, > NULL), > pat_one_label = XtVaCreateManagedWidget("patOneLabel", > xmLabelGadgetClass, find_pair_form, > XmNlabelString, xmstr("Left: "), > XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, > XmNleftWidget, pat_label, > XmNtopAttachment, XmATTACH_WIDGET, > XmNtopWidget, pat_label, > XmNtopOffset, 10, > NULL), > pat_one_text = XtVaCreateManagedWidget ("patOneText", > xmTextFieldWidgetClass, find_pair_form, > XmNleftAttachment, XmATTACH_WIDGET, > XmNleftWidget, pat_one_label, > XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET, > XmNtopWidget, pat_one_label, > XmNcolumns, 8, > NULL); > pat_two_label = XtVaCreateManagedWidget("patOneLabel", > xmLabelGadgetClass, find_pair_form, > XmNlabelString, xmstr("Right:"), > XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, > XmNleftWidget, pat_label, > XmNtopAttachment, XmATTACH_WIDGET, > XmNtopWidget, pat_one_text, > NULL), > pat_two_text = XtVaCreateManagedWidget ("patTwoText", > xmTextFieldWidgetClass, find_pair_form, > XmNcolumns, 8, > XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, > XmNleftWidget, pat_one_text, > XmNtopAttachment, XmATTACH_WIDGET, > XmNtopWidget, pat_one_text, > NULL); > XmTextSetString(pat_one_text, (left_pat ? left_pat : "")); > XmTextSetString(pat_two_text, (right_pat ? right_pat : "")); > > action_form = XtVaCreateManagedWidget("doFindPair", > xmFormWidgetClass, find_pair_pane, > NULL); > find_forw_button = XtVaCreateManagedWidget("findPairForw", > xmPushButtonGadgetClass, action_form, > XmNlabelString, xmstr("Forward"), > NULL); > XtAddCallback(find_forw_button, XmNactivateCallback, find_pair_proc, 0); > find_backw_button = XtVaCreateManagedWidget("findPairForw", > xmPushButtonGadgetClass, action_form, > XmNlabelString, xmstr("Backward"), > XmNleftAttachment, XmATTACH_WIDGET, > XmNleftWidget, find_forw_button, > NULL); > XtAddCallback(find_backw_button, XmNactivateCallback, find_pair_proc, 1); > find_done_button = XtVaCreateManagedWidget("findPairForw", > xmPushButtonGadgetClass, action_form, > XmNlabelString, xmstr("Done"), > XmNleftAttachment, XmATTACH_WIDGET, > XmNleftWidget, find_backw_button, > NULL); > xmstr(NULL); > XtAddCallback(find_done_button, XmNactivateCallback, find_pair_proc, 2); > > XtManageChild(find_pair_pane); > > XtVaGetValues(toplevel, XtNx, &x, XtNy, &y, NULL); > XtVaSetValues(find_pair_dialog, XtNx, x + 100, XtNy, y + 10, NULL); > XtPopup(find_pair_dialog, XtGrabNone); > >/* get atoms */ > find_pair_wm_delete_window = XInternAtom(XtDisplay(find_pair_dialog), > "WM_DELETE_WINDOW", False); > find_pair_wm_protocols = XInternAtom(XtDisplay(find_pair_dialog), > "WM_PROTOCOLS", False); > >/* set protocol hints */ > XSetWMProtocols(XtDisplay(find_pair_dialog), XtWindow(find_pair_dialog), > &find_pair_wm_delete_window, 1); > >/* install event handler */ > XtAddEventHandler(find_pair_dialog, (EventMask) 0, True, > (XtEventHandler) find_pair_client_msg_handler, NULL); >} > >/* find_cb() -- a menu item from the "Search" pulldown menu selected */ >void >find_cb(w, client_data, call_data) >Widget w; >XtPointer client_data; >XtPointer call_data; >{ > char *find_pat = NULL, *string = NULL, *new_pat = NULL; > char buf[256], findbuf[1000]; > XmTextPosition pos, first, last, act_pos, toppos, oldpos, oldtop; > int len, nfound = 0, textlen, i, j; > int find_len, pattern_len, repl_len; > int reason = (int) client_data; > Boolean found = False, selected; > XmTextDirection find_dir; > > pos = 0; > > XmTextSetString (text_output, NULL); /* clear message area */ > > textlen = XmTextGetLastPosition (text_edit); > pos = textlen; > XmTextSetHighlight (text_edit, 0, pos, XmHIGHLIGHT_NORMAL); > > if (reason == SEARCH_CLEAR) { > goto cleanup_find; > } > > if(reason == SEARCH_FIND_PAIR){ > popup_find_pair_dialog(); > goto cleanup_find; > } > > selected = XmTextGetSelectionPosition(text_edit, &first, &last); > if(selected && first >= last) > selected = 0; > > if (!(string = XmTextGetString (text_edit)) || !*string) { > XmTextSetString (text_output, "No text to find."); > goto cleanup_find; > } > if(!(find_pat = XmTextGetString (find_text)) || (!*find_pat && !selected)){ > XmTextSetString (text_output, "Specify a find pattern."); > goto cleanup_find; > } > > new_pat = XmTextGetString (replace_text); > repl_len = pattern_len = strlen (new_pat); > > find_len = strlen (find_pat); > > oldpos = XmTextGetCursorPosition (text_edit); > XtVaGetValues(text_edit, XmNtopCharacter, &oldtop, NULL); > > if(selected){ > find_len = last - first; > if(find_len > 999){ > XmTextSetString (text_output, > "Cannot get whole selection for search."); > goto cleanup_find; > } > strncpy(findbuf, string + first, last - first); > findbuf[last - first] = '\0'; > pos = first + (reason == SEARCH_FIND_PREVIOUS ? -1 : 1); > } > else{ > strcpy(findbuf, find_pat); > pos = oldpos; > if(reason == SEARCH_FIND_PREVIOUS) > pos--; > } > > if(reason == SEARCH_REPLACE || reason == SEARCH_REPLACE_AND_FIND){ > if(!selected){ > XmTextSetString (text_output, "No selection to replace."); > goto cleanup_find; > } > XmTextReplace (text_edit, first, last, new_pat); > if(reason == SEARCH_REPLACE){ > sprintf(buf, "Replaced text at position %ld", first); > XmTextSetString (text_output, buf); > goto cleanup_find; > } > reason = SEARCH_FIND_NEXT; > } > > if(pos < 0) > pos = textlen + 1; > else if(pos > textlen + 1) > pos = 0; > > if (reason == SEARCH_FIND_NEXT || reason == SEARCH_FIND_PREVIOUS > || reason == SEARCH_FIND_AND_REPLACE) { > if(reason == SEARCH_FIND_PREVIOUS) > find_dir = XmTEXT_BACKWARD; > else > find_dir = XmTEXT_FORWARD; > > found = XmTextFindString (text_edit, pos, findbuf, > find_dir, &pos); > if (!found){ > if(reason == SEARCH_FIND_PREVIOUS) > pos = textlen + 1; > else > pos = 0; > > found = XmTextFindString (text_edit, pos, findbuf, > find_dir, &pos); > } > if (found){ > nfound++; > set_new_pos(string, oldpos, pos + find_len); > if(reason == SEARCH_FIND_AND_REPLACE){ > XmTextReplace(text_edit, pos, pos + find_len, new_pat); > XmTextSetCursorPosition(text_edit, pos + strlen(new_pat)); > } > else{ > XmTextSetHighlight (text_edit, pos, pos + find_len, > XmHIGHLIGHT_SELECTED); > XmTextSetSelection(text_edit, pos, pos + find_len, CurrentTime); > } > } > } > else { /* reason == SEARCH_SHOW_ALL || reason == SEARCH_REPLACE_ALL */ > pos = 0; > act_pos = XmTextGetInsertionPosition(text_edit); > do { > found = XmTextFindString (text_edit, pos, findbuf, > XmTEXT_FORWARD, &pos); > if (found) { > nfound++; > if (reason == SEARCH_SHOW_ALL) { > XmTextSetHighlight (text_edit, pos, pos + find_len, > XmHIGHLIGHT_SELECTED); > sth_highlighted = 1; > } > else{ > XmTextSetInsertionPosition(text_edit, pos + find_len); > XmTextSetCursorPosition(text_edit, pos + find_len); > XmTextReplace (text_edit, pos, pos + find_len, new_pat); > pos += repl_len - 1; > } > pos++; > } > } > while (found); > XmTextSetInsertionPosition(text_edit, act_pos); > XmTextSetCursorPosition(text_edit, act_pos); > } > > if (nfound == 0) > XmTextSetString (text_output, "Pattern not found."); > else { > switch (reason) { > case SEARCH_FIND_NEXT : > case SEARCH_FIND_PREVIOUS : > sprintf (buf, "Pattern found at position %ld.", pos); > /*XmTextSetInsertionPosition (text_edit, pos);*/ > break; > case SEARCH_FIND_AND_REPLACE: > sprintf (buf, "Replaced Pattern at position %ld.", pos); > break; > case SEARCH_SHOW_ALL : > sprintf (buf, "Found %d occurrences.", nfound); > break; > case SEARCH_REPLACE_ALL : > sprintf (buf, "Made %d replacements.", nfound); > } > XmTextSetString (text_output, buf); > } > > cleanup_find: > if(string) > XtFree (string); > if(find_pat) > XtFree (find_pat); > if(new_pat) > XtFree (new_pat); >} > >/* edit_cb() -- the callback routine for the items in the edit menu */ >void >edit_cb(widget, client_data, call_data) >Widget widget; >XtPointer client_data; >XtPointer call_data; >{ > Boolean result = True; > int reason = (int) client_data; > XEvent *event = ((XmPushButtonCallbackStruct *) call_data)->event; > Time when; > > XmTextSetString (text_output, NULL); /* clear message area */ > > if (event != NULL && > reason == EDIT_CUT || reason == EDIT_COPY || reason == EDIT_CLEAR) { > switch (event->type) { > case ButtonRelease : > when = event->xbutton.time; > break; > case KeyRelease : > when = event->xkey.time; > break; > default: > when = CurrentTime; > break; > } > } > > switch (reason) { > case EDIT_CUT : > result = XmTextCut (text_edit, when); > break; > case EDIT_COPY : > result = XmTextCopy (text_edit, when); > break; > case EDIT_PASTE : > result = XmTextPaste (text_edit); > break; > case EDIT_UNDO: > undo_actual(); > break; > case EDIT_CLEAR : > XmTextClearSelection (text_edit, when); > break; > } > if (result == False) > XmTextSetString (text_output, "There is no selection."); >} > >unsigned long >find_line_idx(Widget textedit, unsigned long position) >{ > char * text; > unsigned long len, i, lineno = 0; > > len = XmTextGetLastPosition (textedit); > if(len < position){ > return(-1); > } > > text = XmTextGetString (textedit); > if(! text){ > XmTextSetString (text_output, "There is no Text."); > return(-1); > } > > for(i = 0; i < position; i++){ > if(text[i] == '\n') > lineno++; > } > > XtFree(text); > > return(lineno); >} > > >/* view_cb() -- a menu item from the "View" pulldown menu selected */ >void >view_cb(w, client_data, call_data) >Widget w; >XtPointer client_data; >XtPointer call_data; >{ > int i, lineno, reason = (int) client_data; > char buf[100], *cptr, *text; > XmTextPosition first, last, cursorpos; > Boolean got_selection, got_cursor; > Position cursorline, selline, x; > > if(reason == VIEW_WHAT_LINE){ > got_selection = XmTextGetSelectionPosition(text_edit, &first, &last); > if(first >= last) > got_selection = 0; > if(got_selection){ > selline = find_line_idx(text_edit, first) + 1; > got_selection = (selline > 0); > } > > cursorpos = XmTextGetCursorPosition(text_edit); > cursorline = find_line_idx(text_edit, cursorpos) + 1; > got_cursor = (cursorline > 0); > > if(got_cursor && got_selection) > sprintf(buf, "Selection starts in line %lu, Cursor is in line %lu.", > (unsigned long) selline, (unsigned long) cursorline); > else if(got_cursor) > sprintf(buf, "Cursor is in line %lu.", > (unsigned long) cursorline); > else if(got_selection) > sprintf(buf, "Selection starts in line %lu.", > (unsigned long) selline); > else > sprintf(buf, "Strange: Can't get cursor position."); > > XmTextSetString (text_output, buf); > } > if(reason == VIEW_GOTO_LINE){ > goto_line(); > } >} > >void >goto_line() >{ > char *cptr, buf[100], *text; > int i, lineno, cursorpos, j; > XmTextPosition oldpos; > > cptr = XmTextGetString(lineno_text); > > if(! cptr[0]){ > XtFree(cptr); > return; > } > > i = sscanf(cptr, "%d", &lineno); > > if(i < 1){ > sprintf(buf, "Cannot read a line number from \"%s\".", cptr); > XtFree(cptr); > XmTextSetString(text_output, buf); > return; > } > > XtFree(cptr); > > text = cptr = XmTextGetString(text_edit); > cursorpos = 0; > oldpos = XmTextGetCursorPosition(text_edit); > > for(i = 0; i < lineno - 1; i++){ > while(*cptr && *cptr != '\n'){ > cptr++; > cursorpos++; > } > > if(! *cptr){ > sprintf(buf, "Text has only %d line%s.", i + 1, i ? "s" : ""); > XmTextSetString (text_output, buf); > XtFree(text); > return; > } > > cptr++; > cursorpos++; > } > > set_new_pos(text, oldpos, cursorpos); > > XtFree(text); > > XmTextSetString (text_output, ""); > >} > >void >wraplines_cb( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > Boolean wrap_lines; > > XtVaGetValues(wraplines_button, XmNset, &wrap_lines, NULL); > > XtVaSetValues(text_edit, XmNscrollHorizontal, wrap_lines, > XmNwordWrap, True, NULL); >} > >void >auto_indent_cb( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > XtVaGetValues(autoindent_button, XmNset, &auto_indent, NULL); >} > >void >readonly_cb( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > XtVaGetValues(readonly_button, XmNset, &readonly, NULL); >} > >void >save_on_hup(int sigc) >{ > char buf[256], nam[256]; > > signal(sigc, save_on_hup); > > if(act_filename) > strcpy(nam, act_filename); > else{ > tmpnam(nam); > > fprintf(stderr, "Got signal HUP, saved actual text as %s.\n", nam); > } > > save_file(nam, buf); > > set_title(); > > XmTextSetString(text_output, buf); >} > >void >safe_exit(int sigc) >{ > char buf[256]; > > signal(sigc, safe_exit); > > if(! total_edits) > exit(0); > > sprintf(buf, "Got signal %d, text has been modified, not exiting.", > sigc); > > XmTextSetString(text_output, buf); > > XBell(XtDisplay(toplevel), 50); >} > >int >dump_edits() >{ > FILE *fp; > int i; > > fp = fopen(editdumpfile, "w"); > > if(!fp) > return(1); > > fprintf(fp, "%d %d %d %d %d %d %d %d \005%s\005\n", > act_edit_nr, first_edit_nr, > total_edits, motion_from, motion_to, moved, max_undos, > (int) XmTextGetCursorPosition(text_edit), > act_filename ? act_filename : ""); > > for(i = 0; i < max_undos; i++){ > fprintf(fp, "%d %d %d %d \005%s\005 %d \005%s\005 %d %d\n", > all_edits[i].ins_start, all_edits[i].ins_end, > all_edits[i].del_start, all_edits[i].del_end, > all_edits[i].del_string, all_edits[i].del_strlen, > all_edits[i].ins_string, all_edits[i].ins_strlen, > (int) all_edits[i].type); > } > > fclose(fp); > > return(0); >} > >int >load_edits() >{ > FILE *fp; > int i, j, k, cpos; > char a, buf[256]; > > fp = fopen(editrecfile, "r"); > > if(!fp) > return(1); > > if(fscanf(fp, "%d%d%d%d%d%d%d%d", > &act_edit_nr, &first_edit_nr, &total_edits, > &motion_from, &motion_to, &moved, &max_undos, &cpos) > < 8){ > fclose(fp); > return(1); > } > > do{ > if(EOF == fscanf(fp, "%c", &a)){ > fclose(fp); > return(1); > } > } while(a != '\005'); > > k = -1; > do{ > k++; > > if(EOF == fscanf(fp, "%c", buf + k)){ > fclose(fp); > return(1); > } > } while(buf[k] != '\005'); > > buf[k] = '\0'; > > act_filename = strdup(buf); > all_edits = (struct edit_record *) > malloc(max_undos * sizeof(struct edit_record)); > if(!all_edits){ > fclose(fp); > return(1); > } > > for(i = 0; i < max_undos; i++){ > if(fscanf(fp, "%d%d%d%d", > &(all_edits[i].ins_start), &(all_edits[i].ins_end), > &(all_edits[i].del_start), &(all_edits[i].del_end)) > < 4){ > fclose(fp); > return(1); > } > > do{ > if(EOF == fscanf(fp, "%c", &a)){ > fclose(fp); > return(1); > } > > } while(a != '\005'); > > k = -1; > do{ > k++; > > if(EOF == fscanf(fp, "%c", buf + k)){ > fclose(fp); > return(1); > } > } while(buf[k] != '\005'); > > buf[k] = '\0'; > > all_edits[i].del_string = strdup(buf); > if(! all_edits[i].del_string){ > fclose(fp); > return(1); > } > > if(fscanf(fp, "%d", &(all_edits[i].del_strlen)) < 1){ > fclose(fp); > return(1); > } > > do{ > if(EOF == fscanf(fp, "%c", &a)){ > fclose(fp); > return(1); > } > > } while(a != '\005'); > > k = -1; > do{ > k++; > > if(EOF == fscanf(fp, "%c", buf + k)){ > fclose(fp); > return(1); > } > } while(buf[k] != '\005'); > > buf[k] = '\0'; > > all_edits[i].ins_string = strdup(buf); > if(! all_edits[i].ins_string){ > fclose(fp); > return(1); > } > > if(fscanf(fp, "%d%d", &(all_edits[i].ins_strlen), &j) < 2){ > fclose(fp); > return(1); > } > > all_edits[i].type = (char) j; > } > > fclose(fp); > > XmTextSetCursorPosition(text_edit, cpos); > XmTextSetInsertionPosition(text_edit, cpos); > > return(0); >} > >void >emergency_exit(int sigc) >{ > int i, len; > FILE *fp; > char buf[256]; > char *text; > > fprintf(stderr, "textedit panic: got signal %d !\n", sigc); > fprintf(stderr, "Trying to save text and edits, so that you can\n"); > fprintf(stderr, "recover everything with the command:\n\n%s\n\n", > recovercmd); > fprintf(stderr, "(You can cut & paste the line above).\n"); > fprintf(stderr, "Trying to dump the text as %s...\n", textdumpfile); > > text = XmTextGetString(text_edit); > len = XmTextGetLastPosition(text_edit); > fp = fopen(textdumpfile, "w"); > i = (fp != NULL) && (fwrite(text, sizeof(char), len, fp) == len); > fclose(fp); > XtFree(text); > > fprintf(stderr, ! i ? "failed.\n" : "succeeded.\n"); > fprintf(stderr, "Trying to dump your modifications as %s...\n", > editdumpfile); > i = dump_edits(); > fprintf(stderr, i ? "failed.\n" : "succeeded.\n"); > fprintf(stderr, "Trying to auto-recover...\n"); > system(recovercmd); > > exit(0); >} > >void >client_msg_handler( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > XmAnyCallbackStruct *cbs; > > cbs = (XmAnyCallbackStruct *) call_data; > > if(cbs->reason != XmCR_WM_PROTOCOLS) > return; > > maybe_exit(); >} > >void >set_wm_interactions() >{ > int i; > > wm_delete_window = XmInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", > False); > XmAddWMProtocolCallback(toplevel, wm_delete_window, client_msg_handler, > NULL); >} > >void >usage(char * progname) >{ > fprintf(stderr, "usage: %s [ +|-ai ] [ +|-ro ] [ +|-nb ] [ <filename> ]\n", > progname); > fprintf(stderr, " ai stands for auto-indentation,\n"); > fprintf(stderr, " nb stands for no backup (no *%%-file),\n"); > fprintf(stderr, " ro stands for read-only option.\n"); > > exit(0); >} > >void >termproc() >{ > get_options(); > > if(!recover && !toplevel && exitflag == OPENING_DISPLAY){ > char *altedit; > > altedit = getenv("ALTEDITOR"); > if(!altedit) > altedit = "vi"; > > execlp(altedit, altedit, act_filename, NULL); > } >} > >void >get_extras_menu() >{ > char *homeacc; > FILE *fp; > char *extras_file; > char linebuf[1000]; > char *cptr, *cptr2, *cptr3; > char quoted; > > homeacc = getenv("HOME"); > if(!homeacc) > return; > > extras_file = malloc(sizeof(char) * > (strlen(homeacc) + 2 + strlen(TEXT_EXTRAS_FILE))); > > if(!extras_file) > return; > > strcpy(extras_file, homeacc); > strcat(extras_file, "/"); > strcat(extras_file, TEXT_EXTRAS_FILE); > > fp = fopen(extras_file, "r"); > if(!fp) > return; > > for(;;){ > if(!fgets(linebuf, 999, fp)) > break; > > linebuf[999] = '\0'; > > while(linebuf[strlen(linebuf) - 1] == '\n') > linebuf[strlen(linebuf) - 1] = '\0'; > > if(!extras_cmds) > extras_cmds = malloc(sizeof(char*)); > else > extras_cmds = realloc(extras_cmds, > (num_extras + 1) * sizeof(char*)); > if(!extras_names) > extras_names = malloc(sizeof(char*)); > else > extras_names = realloc(extras_names, > (num_extras + 1) * sizeof(char*)); > > cptr = linebuf; > while(*cptr && isspace(*cptr)) > cptr++; > > if(!*cptr) > continue; > > cptr2 = cptr; > quoted = 0; > while(*cptr2 && (!isspace(*cptr2) || quoted)){ > if(*cptr2 == '\"'){ > quoted = !quoted; > for(cptr3 = cptr2; *cptr3; cptr3++) > *cptr3 = *(cptr3 + 1); > cptr2--; > } > cptr2++; > } > > if(!*cptr2){ > fprintf(stderr, "Line in %s has wrong format:\n%s\n", > TEXT_EXTRAS_FILE, linebuf); > continue; > } > > *cptr2 = '\0'; > extras_names[num_extras] = strdup(cptr); > > if(!extras_names[num_extras]){ > fprintf(stderr, "Error: cannot allocate memory for extras.\n"); > exit(1); > } > > cptr = cptr2 + 1; > while(*cptr && isspace(*cptr)) > cptr++; > > if(!*cptr){ > fprintf(stderr, "Line in %s has wrong format:\n%s\n", > TEXT_EXTRAS_FILE, linebuf); > continue; > } > > extras_cmds[num_extras] = strdup(cptr); > if(!extras_cmds[num_extras]){ > fprintf(stderr, "Error: cannot allocate memory for extras.\n"); > exit(1); > } > > num_extras++; > } > > fclose(fp); >} > >void >extras_proc( > Widget w, > XtPointer client_data, > XtPointer call_data) >{ > int idx, namp, selected, i, pipe_in; > FILE *pp; > char buf[1000], cmd[1050]; > char *text; > XmTextPosition first, last, cursorpos; > struct stat statb; > > idx = (int) client_data; > > if(extras_cmds[idx][0] == '|') > pipe_in = 1; > else > pipe_in = 0; > > if(!pipe_in){ > sprintf(cmd, "%s > ", extras_cmds[idx]); > namp = strlen(cmd); > tmpnam(cmd + namp); > } > else{ > strcpy(cmd, extras_cmds[idx] + 1); > } > pp = popen(cmd, "w"); > if(!pp){ > sprintf(buf, "Error: cannot execute command %s", extras_cmds[idx]); > XmTextSetString(text_output, buf); > return; > } > > first = last = 0; > selected = XmTextGetSelectionPosition(text_edit, &first, &last); > if(selected && first >= last) > selected = 0; > > cursorpos = XmTextGetInsertionPosition(text_edit); > > text = XmTextGetString(text_edit); > if(!selected){ > first = 0; > last = XmTextGetLastPosition(text_edit); > } > > fwrite(text + first, 1, last - first, pp); > > pclose(pp); > XtFree(text); > > if(pipe_in){ > unlink(cmd + namp); > return; > } > > i = stat(cmd + namp, &statb); > pp = fopen(cmd + namp, "r"); > if(i < 0 || !pp){ > if(pp) > fclose(pp); > sprintf(buf, "Error: cannot execute command %s", extras_cmds[idx]); > XmTextSetString(text_output, buf); > unlink(cmd + namp); > return; > } > > text = malloc(sizeof(char) * (statb.st_size + 1)); > if(!text){ > fprintf(stderr, "Error: cannot allocate memory.\n"); > unlink(cmd + namp); > exit(9); > } > > i = fread(text, 1, statb.st_size, pp); > text[statb.st_size] = '\0'; > > fclose(pp); > unlink(cmd + namp); > > if(i < statb.st_size){ > sprintf(buf, "Error: cannot execute command %s", extras_cmds[idx]); > XmTextSetString(text_output, buf); > XtFree(text); > return; > } > > XmTextSetInsertionPosition(text_edit, last); > XmTextSetCursorPosition(text_edit, last); > XmTextReplace(text_edit, first, last, text); > if(selected){ > XmTextSetInsertionPosition(text_edit, first + statb.st_size); > XmTextSetCursorPosition(text_edit, first + statb.st_size); > } > else{ > XmTextSetInsertionPosition(text_edit, cursorpos); > XmTextSetCursorPosition(text_edit, cursorpos); > } > > XtFree(text); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 834191
: 593372