home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / jetedit / part03 < prev    next >
Encoding:
Text File  |  1993-04-27  |  52.5 KB  |  1,613 lines

  1. Newsgroups: comp.sources.x
  2. From: duane@blacks.jpl.nasa.gov (Duane Clark)
  3. Subject: v19i082:  Jetedit - A Motif text editor, Part03/04
  4. Message-ID: <1993Apr8.144500.20324@sparky.imd.sterling.com>
  5. X-Md4-Signature: f5ab1f656dcb443254cab600032e05fc
  6. Date: Thu, 8 Apr 1993 14:45:00 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: duane@blacks.jpl.nasa.gov (Duane Clark)
  10. Posting-number: Volume 19, Issue 82
  11. Archive-name: Jetedit/part03
  12. Environment: X11, OSF/Motif
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 3 (of 4)."
  21. # Contents:  xmedialg.c xmemisc.c
  22. # Wrapped by duane@blacks.jpl.nasa.gov on Sat Apr  3 20:04:06 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'xmedialg.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'xmedialg.c'\"
  26. else
  27. echo shar: Extracting \"'xmedialg.c'\" \(22684 characters\)
  28. sed "s/^X//" >'xmedialg.c' <<'END_OF_FILE'
  29. X/**---------------------------------------------------------------------
  30. X***     
  31. X***    file:        xmedialg.c
  32. X***
  33. X***    project:    jetedit - Motif Widgets text editor
  34. X***
  35. X***-------------------------------------------------------------------*/
  36. X
  37. X#include "xme.h"
  38. X
  39. X#define DIALOG_FSELECT        300
  40. X#define DIALOG_OWARNING        301
  41. X#define DIALOG_NWARNING        302
  42. X#define DIALOG_CWARNING        303
  43. X#define DIALOG_XWARNING        304
  44. X#define DIALOG_NEW        305
  45. X#define DIALOG_SAVE_AS        306
  46. X#define DIALOG_HELP        307
  47. X#define DIALOG_PRINT        308
  48. X#define DIALOG_GOTO        309
  49. X#define DIALOG_FIND        310
  50. X#define DIALOG_F_EXISTS        311
  51. X#define DIALOG_F_MODE        312
  52. X#define DIALOG_EXISTS_AS    313
  53. X#define DIALOG_PREF        314
  54. X
  55. Xextern char warningBits[];
  56. X
  57. Xchar    find_help_string[] = "\n\
  58. X     Regular Expressions Quick Reference\n\
  59. X**********************************************\n\
  60. X  RE refers to a regular expression.\n\
  61. X^RE$         Anchor the beginning and end of a line.\n\
  62. X.            Matches any character.\n\
  63. X[...]        Brackets match any characters they contain,\n\
  64. X             unless the first character is ^, in which\n\
  65. X             case they match characters NOT contained.\n\
  66. X[a-e]        Matches a,b,c,d or e.\n\
  67. XRE*          Matches zero or more occurences of RE.\n\
  68. XRE\\{m,n\\}    Matches a minimum m and maximum n occurrences\n\
  69. X             of RE.\n\
  70. X**********************************************\n\
  71. XTo enter a Tab into the Find or Replace strings, type the Tab into the editor's main window, then copy it into the dialog.\n\
  72. X";
  73. X
  74. X/*-------------------------------------------------------------
  75. X**    DialogAcceptCB
  76. X**        Process callback from Dialog "Ok" actions.
  77. X*/
  78. Xvoid DialogAcceptCB (w, client_data, call_data) 
  79. XWidget         w;        /*  widget id           */
  80. Xcaddr_t        client_data;    /*  data from application   */
  81. Xcaddr_t        call_data;    /*  data from widget class  */
  82. X{
  83. X    char    *command;    /* command used in printing */
  84. X    char    *goto_string=NULL;
  85. X    char    line_string[15];
  86. X    int        tfd;        /* temporary file descriptor */
  87. X    Arg        al[1];
  88. X    mode_t    mode_mask;
  89. X    struct stat statbuf;    /* Information on a file. */
  90. X    char    dir_string[120];
  91. X    int        i,j;
  92. X    switch ((int)client_data)
  93. X    {
  94. X    case DIALOG_FSELECT:
  95. X        /* open the file and read it into the text widget */
  96. X        thefile = NULL;
  97. X        {
  98. X        XmFileSelectionBoxCallbackStruct *fcb =
  99. X                (XmFileSelectionBoxCallbackStruct *) call_data;
  100. X
  101. X        /* get the thefile from the file selection box */
  102. X        XmStringGetLtoR(fcb->value, charset, &thefile);
  103. X        }
  104. X        /* Open file, print error if it does not exist. */
  105. X        if ((tfd = open(thefile, O_RDONLY)) == -1)  {
  106. X            XtUnmanageChild (open_dialog);
  107. X            XtManageChild (refused_dialog);
  108. X        }
  109. X        else {
  110. X            if (stat(thefile, &statbuf) == 0) {
  111. X                file_mode = statbuf.st_mode;
  112. X                if (S_ISDIR(file_mode)) {
  113. X                    /* This stuff allows directory traversal under Motif1.0 */
  114. X                    strcpy(dir_string, thefile);
  115. X                    i=strlen(dir_string);
  116. X                    if (dir_string[i-1]=='.') {
  117. X                        if (dir_string[i-2]=='.') {
  118. X                            j=i-4;
  119. X                            while (dir_string[j]!='/' && j>=0)
  120. X                                j--;
  121. X                            if (j>=0)
  122. X                                dir_string[j+1] = '\0';
  123. X                            else
  124. X                                dir_string[i-2] = '\0';
  125. X                        }
  126. X                        else dir_string[i-1] = '\0';
  127. X                    }
  128. X                    else 
  129. X                        strcat(dir_string, "/");
  130. X                    XmFileSelectionDoSearch(open_dialog,
  131. X                      XmStringCreateLtoR(dir_string, charset)); 
  132. X                }
  133. X                if (S_ISREG(file_mode)) {
  134. X                    XtUnmanageChild (open_dialog);
  135. X                    OpenFile(tfd);
  136. X                   /* close up the file */
  137. X                    if (close(tfd) != NULL) 
  138. X                        strcat (message_string, 
  139. X                        "  \7Warning: unable to close file.");
  140. X                }
  141. X            }
  142. X        }
  143. X        break;
  144. X
  145. X    case DIALOG_OWARNING:
  146. X        /* save the file */
  147. X        if (SaveFile()) {
  148. X            CloseFile(); /* close the file */
  149. X            file_saved = True; /* reset the default */
  150. X        }
  151. X        break;
  152. X
  153. X    case DIALOG_NEW:
  154. X        /* Open the file and read it into the text widget. */
  155. X        if (thefile != NULL) {
  156. X            oldfile = XtMalloc (strlen (thefile) + 1);
  157. X            strcpy (oldfile, thefile);
  158. X            thefile = NULL;
  159. X        }
  160. X        {
  161. X        XmSelectionBoxCallbackStruct *scb =
  162. X            (XmSelectionBoxCallbackStruct *) call_data;
  163. X
  164. X        /* get thefile string from the file name prompt box */
  165. X        XmStringGetLtoR(scb->value, charset, &thefile);
  166. X        }
  167. X        XtUnmanageChild (new_dialog);
  168. X        if ((tfd = open (thefile, O_RDONLY)) == -1) {
  169. X            XtFree (oldfile);
  170. X            no_undo = True;
  171. X            XmTextSetString (text, "");
  172. X            no_undo = False;
  173. X            file_saved = True;
  174. X            
  175. X            lines = 1;
  176. X            sprintf (line_string, " Line:  %4d", lines);
  177. X            XtSetArg(al[0], XmNlabelString, 
  178. X                XmStringCreateLtoR(line_string, charset));
  179. X            XtSetValues(line, al, 1);
  180. X            
  181. X            mode_mask = umask(0);
  182. X            umask(mode_mask);
  183. X            file_mode = ((S_IFREG | 0777) & ~mode_mask);
  184. X            file_user = UID_NO_CHANGE;
  185. X            file_group = GID_NO_CHANGE;
  186. X            
  187. X            XtSetSensitive(text, True);
  188. X            XtSetSensitive(cut_button, True);
  189. X            XtSetSensitive(copy_button, True);
  190. X            XtSetSensitive(paste_button, True);
  191. X            XtSetSensitive(find_button, True);
  192. X            XtSetSensitive(goto_button, True);
  193. X            InitUndoBuffer();
  194. X            
  195. X            sprintf (message_string, " Editing:  %s", thefile);
  196. X            XtSetArg(al[0], XmNlabelString, 
  197. X                XmStringCreateLtoR(message_string, charset));
  198. X            XtSetValues(message, al, 1);
  199. X        }
  200. X        else {
  201. X            close (tfd);
  202. X            XtManageChild (file_exists_dialog);
  203. X        }
  204. X        break;
  205. X
  206. X    case DIALOG_NWARNING:
  207. X        /* save the file */
  208. X        if (SaveFile()) {
  209. X            CloseFile(); /* close the file */
  210. X            file_saved = True; /* reset the default */
  211. X        }
  212. X        break;
  213. X
  214. X    case DIALOG_F_EXISTS:
  215. X        XtFree (oldfile);
  216. X        XmTextSetString (text, "");
  217. X        XtSetSensitive(text, True);
  218. X        XtSetSensitive(cut_button, True);
  219. X        XtSetSensitive(copy_button, True);
  220. X        XtSetSensitive(paste_button, True);
  221. X        XtSetSensitive(find_button, True);
  222. X        XtSetSensitive(goto_button, True);
  223. X        file_saved = True; /* reset the default */
  224. X        sprintf (message_string, " Editing:  %s", thefile);
  225. X        XtSetArg(al[0], XmNlabelString, 
  226. X            XmStringCreateLtoR(message_string, charset));
  227. X        XtSetValues(message, al, 1);
  228. X        break;
  229. X
  230. X    case DIALOG_CWARNING:
  231. X        /* save the file */
  232. X        if (SaveFile()) {
  233. X            CloseFile(); /* close the file */
  234. X            file_saved = True; /* reset the default */
  235. X            XtSetSensitive(text, False);
  236. X            XtSetSensitive(cut_button, False);
  237. X            XtSetSensitive(copy_button, False);
  238. X            XtSetSensitive(paste_button, False);
  239. X            XtSetSensitive(find_button, False);
  240. X            XtSetSensitive(goto_button, False);
  241. X            sprintf (message_string, " Editing:");
  242. X            XtSetArg(al[0], XmNlabelString, 
  243. X                XmStringCreateLtoR(message_string, charset));
  244. X            XtSetValues(message, al, 1);
  245. X        }
  246. X        break;
  247. X
  248. X    case DIALOG_XWARNING:
  249. X        /* save the file */
  250. X        if (SaveFile()) {
  251. X            CloseFile(); /* close the file */
  252. X            CloseUndoBuffer ();
  253. X            exit(0);
  254. X        }
  255. X        break;
  256. X
  257. X    case DIALOG_SAVE_AS:
  258. X        /* open the file and read it into the text widget */
  259. X        if (thefile != NULL) {
  260. X            oldfile = XtMalloc (strlen (thefile) + 1);
  261. X            strcpy (oldfile, thefile);
  262. X            thefile = NULL;
  263. X        }
  264. X        {
  265. X        XmSelectionBoxCallbackStruct *scb =
  266. X            (XmSelectionBoxCallbackStruct *) call_data;
  267. X
  268. X        /* get the thefile string from the file name prompt box */
  269. X        XmStringGetLtoR(scb->value, charset, &thefile);
  270. X        }
  271. X        XtUnmanageChild (save_as_dialog);
  272. X        if ((tfd = open (thefile, O_RDONLY)) == -1) {
  273. X            XtFree (oldfile);
  274. X            SaveFile();
  275. X        }
  276. X        else {
  277. X            close (tfd);
  278. X            XtManageChild (exists_as_dialog);
  279. X        }
  280. X        break;
  281. X
  282. X    case DIALOG_EXISTS_AS:
  283. X        XtFree (oldfile);
  284. X        SaveFile();
  285. X        break;  
  286. X    
  287. X    case DIALOG_F_MODE:
  288. X        break;
  289. X    
  290. X    case DIALOG_GOTO:
  291. X        {
  292. X        XmSelectionBoxCallbackStruct *scb =
  293. X                (XmSelectionBoxCallbackStruct *) call_data;
  294. X
  295. X        /* get the find string from the prompt box */
  296. X        XmStringGetLtoR(scb->value, charset, &goto_string);
  297. X        GotoString(goto_string);
  298. X        }
  299. X        break;
  300. X
  301. X    case DIALOG_HELP:
  302. X        /* no help at this time */
  303. X        break;
  304. X
  305. X    default:
  306. X        /* unknown callback type */
  307. X        fprintf (stderr, "\7Warning: in accept callback\n");
  308. X        break;
  309. X    }
  310. X}
  311. X
  312. X
  313. X
  314. X/*-------------------------------------------------------------
  315. X**    DialogApplyCB
  316. X**        Process callback from Dialog "Discard" actions.
  317. X*/
  318. Xvoid DialogApplyCB (w, client_data, call_data) 
  319. XWidget        w;        /*  widget id            */
  320. Xcaddr_t        client_data;    /*  data from application    */
  321. Xcaddr_t        call_data;    /*  data from widget class    */
  322. X{
  323. X    char *command;        /* command used in printing */
  324. X
  325. X    switch ((int)client_data)
  326. X    {
  327. X        case DIALOG_OWARNING:
  328. X            CloseFile();
  329. X            file_saved = True;
  330. X            XtUnmanageChild (open_warning);
  331. X            break;
  332. X
  333. X        case DIALOG_NWARNING:
  334. X            CloseFile();
  335. X            file_saved = True;
  336. X            XtUnmanageChild (new_warning);
  337. X            break;
  338. X
  339. X        case DIALOG_CWARNING:
  340. X            CloseFile();
  341. X            file_saved = True;
  342. X            XtUnmanageChild (close_warning);
  343. X            break;
  344. X
  345. X        case DIALOG_XWARNING:
  346. X            CloseFile();
  347. X            CloseUndoBuffer();
  348. X            XtUnmanageChild (exit_warning);
  349. X            exit();
  350. X            break;          
  351. X
  352. X        default:
  353. X            /* unknown client_data was recieved and
  354. X               there is no setup to handle this */
  355. X            fprintf (stderr, "\7Warning: in apply callback\n");
  356. X            break;
  357. X
  358. X    }
  359. X}
  360. X
  361. X
  362. X/*-------------------------------------------------------------
  363. X**    DialogCancelCB
  364. X**        Process callback from Dialog "Cancel" actions.
  365. X*/
  366. Xvoid DialogCancelCB (w, client_data, call_data) 
  367. XWidget        w;        /*  widget id           */
  368. Xcaddr_t        client_data;    /*  data from application   */
  369. Xcaddr_t        call_data;    /*  data from widget class  */
  370. X{
  371. X    int  theerror;
  372. X    
  373. X    switch ((int)client_data)
  374. X    {
  375. X        case DIALOG_FSELECT:
  376. X        case DIALOG_OWARNING:
  377. X            /* popdown the file selection box */
  378. X            XtUnmanageChild (open_dialog);
  379. X            break;
  380. X
  381. X        case DIALOG_NWARNING:
  382. X            /* popdown the file selection box */
  383. X            XtUnmanageChild (new_dialog);
  384. X            break;
  385. X        case DIALOG_F_EXISTS:
  386. X        case DIALOG_EXISTS_AS:
  387. X            strcpy (thefile, oldfile);
  388. X            XtFree (oldfile);
  389. X            break;
  390. X            
  391. X        case DIALOG_F_MODE:
  392. X            chmod (thefile, file_mode);
  393. X            CloseFile();
  394. X            file_saved = True;
  395. X            break;
  396. X        
  397. X        case DIALOG_GOTO:
  398. X            XtUnmanageChild (goto_dialog);
  399. X            break;
  400. X        
  401. X        case DIALOG_CWARNING:
  402. X        case DIALOG_XWARNING:
  403. X        case DIALOG_NEW:
  404. X        case DIALOG_SAVE_AS:
  405. X        case DIALOG_HELP:
  406. X            /* no action is necessary at this time */
  407. X            break;
  408. X
  409. X        default:
  410. X            /* a unknown client_data was recieved and
  411. X               there is no setup to handle this */
  412. X            fprintf (stderr, "\7Warning: in cancel callback\n");
  413. X            break;
  414. X    }
  415. X}
  416. X
  417. X
  418. X/*-------------------------------------------------------------
  419. X**    CreateMenuDialogs
  420. X**        Create the popup dialogs.
  421. X*/
  422. Xvoid CreateMenuDialogs (menu_bar)
  423. XWidget menu_bar;
  424. X{
  425. X    Arg        al[10];
  426. X    Cardinal    ac;
  427. X    XImage     *image;         /*  image for warning pixmap    */
  428. X    Widget    button;
  429. X
  430. X    image = CreateDefaultImage (warningBits, 32, 32);
  431. X    XmInstallImage (image, "warning_image");
  432. X                                        
  433. X    ac = 0;
  434. X    XtSetArg(al[ac], XmNdirMask, ""); ac++;
  435. X    XtSetArg(al[ac], XmNwidth, 220); ac++;
  436. X#ifdef HARDCODE
  437. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  438. X#endif
  439. X    XtSetArg (al[ac], XmNdialogTitle, 
  440. X        XmStringCreateLtoR("File Selection", charset));  ac++;
  441. X    open_dialog = XmCreateFileSelectionDialog(menu_bar,
  442. X            "file selection dialog", al, ac);
  443. X    XtAddCallback (open_dialog, XmNokCallback,
  444. X            DialogAcceptCB, DIALOG_FSELECT);
  445. X    XtAddCallback (open_dialog, XmNcancelCallback,
  446. X            DialogCancelCB, DIALOG_FSELECT);
  447. X    button = XmFileSelectionBoxGetChild (open_dialog, XmDIALOG_HELP_BUTTON);
  448. X    XtUnmanageChild (button);
  449. X
  450. X    ac = 0;
  451. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  452. X#ifdef HARDCODE
  453. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  454. X#endif
  455. X    XtSetArg (al[ac], XmNdialogTitle, 
  456. X        XmStringCreateLtoR("Open Warning", charset));  ac++;
  457. X    open_warning = CreateSpecialWarningDialog(menu_bar, "open warning",
  458. X            "warning_image", "Save Changes?", al, ac);
  459. X    XtAddCallback (open_warning, XmNapplyCallback,
  460. X            DialogApplyCB, DIALOG_OWARNING);
  461. X    XtAddCallback (open_warning, XmNokCallback,
  462. X            DialogAcceptCB, DIALOG_OWARNING);
  463. X    XtAddCallback (open_warning, XmNcancelCallback,
  464. X            DialogCancelCB, DIALOG_OWARNING);
  465. X
  466. X    ac = 0;
  467. X    XtSetArg(al[ac], XmNselectionLabelString, XmStringCreateLtoR
  468. X           ("Enter name of new file (including complete path).", charset));  ac++;
  469. X#ifdef HARDCODE
  470. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  471. X#endif
  472. X    XtSetArg (al[ac], XmNdialogTitle, 
  473. X        XmStringCreateLtoR("New File", charset));  ac++;
  474. X    new_dialog = XmCreatePromptDialog(menu_bar,
  475. X           "new file dialog", al, ac);
  476. X    XtAddCallback (new_dialog, XmNokCallback,
  477. X            DialogAcceptCB, DIALOG_NEW);
  478. X    XtAddCallback (new_dialog, XmNcancelCallback,
  479. X            DialogCancelCB, DIALOG_NEW);
  480. X    button = XmSelectionBoxGetChild (new_dialog, XmDIALOG_HELP_BUTTON);
  481. X    XtUnmanageChild (button);
  482. X
  483. X    ac = 0;
  484. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  485. X#ifdef HARDCODE
  486. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  487. X#endif
  488. X    XtSetArg (al[ac], XmNdialogTitle, 
  489. X        XmStringCreateLtoR("New Warning", charset));  ac++;
  490. X    new_warning = CreateSpecialWarningDialog(menu_bar, "new_warning",
  491. X           "warning_image", "Save Changes?", al, ac);
  492. X    XtAddCallback (new_warning, XmNapplyCallback,
  493. X           DialogApplyCB, DIALOG_NWARNING);
  494. X    XtAddCallback (new_warning, XmNokCallback,
  495. X           DialogAcceptCB, DIALOG_NWARNING);
  496. X    XtAddCallback (new_warning, XmNcancelCallback,
  497. X           DialogCancelCB, DIALOG_NWARNING);
  498. X
  499. X    ac = 0;
  500. X    XtSetArg(al[ac], XmNmessageString, XmStringCreateLtoR
  501. X           ("This file already exists.", charset));  ac++;
  502. X    XtSetArg(al[ac], XmNokLabelString,
  503. X         XmStringCreateLtoR("Overwrite", charset)); ac++;
  504. X    XtSetArg(al[ac], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);  ac++;
  505. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  506. X#ifdef HARDCODE
  507. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  508. X#endif
  509. X    XtSetArg (al[ac], XmNdialogTitle, 
  510. X        XmStringCreateLtoR("File Exists Warning", charset));  ac++;
  511. X    file_exists_dialog = XmCreateWarningDialog(menu_bar,
  512. X           "file exists dialog", al, ac);
  513. X    XtAddCallback (file_exists_dialog, XmNokCallback,
  514. X            DialogAcceptCB, DIALOG_F_EXISTS);
  515. X    XtAddCallback (file_exists_dialog, XmNcancelCallback,
  516. X            DialogCancelCB, DIALOG_F_EXISTS);
  517. X    button = XmMessageBoxGetChild (file_exists_dialog, XmDIALOG_HELP_BUTTON);
  518. X    XtUnmanageChild (button);
  519. X
  520. X    ac = 0;
  521. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  522. X#ifdef HARDCODE
  523. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  524. X#endif
  525. X    XtSetArg (al[ac], XmNdialogTitle, 
  526. X        XmStringCreateLtoR("Close Warning", charset));  ac++;
  527. X    close_warning = CreateSpecialWarningDialog(menu_bar, "close_warning",
  528. X           "warning_image", "Save Changes?", al, ac);
  529. X    XtAddCallback (close_warning, XmNapplyCallback,
  530. X           DialogApplyCB, DIALOG_CWARNING);
  531. X    XtAddCallback (close_warning, XmNokCallback,
  532. X           DialogAcceptCB, DIALOG_CWARNING);
  533. X    XtAddCallback (close_warning, XmNcancelCallback,
  534. X           DialogCancelCB, DIALOG_CWARNING);
  535. X
  536. X    ac = 0;
  537. X    XtSetArg(al[ac], XmNselectionLabelString, XmStringCreateLtoR
  538. X           ("Save As...", charset));  ac++;
  539. X    XtSetArg(al[ac], XmNtextString, XmStringCreateLtoR
  540. X           (thefile, charset));  ac++;
  541. X#ifdef HARDCODE
  542. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  543. X#endif
  544. X    XtSetArg (al[ac], XmNdialogTitle, 
  545. X        XmStringCreateLtoR("Save As", charset));  ac++;
  546. X    save_as_dialog = XmCreatePromptDialog(menu_bar, "save as dialog", al, ac);
  547. X    XtAddCallback (save_as_dialog, XmNokCallback,
  548. X           DialogAcceptCB, DIALOG_SAVE_AS);
  549. X    button = XmSelectionBoxGetChild (save_as_dialog, XmDIALOG_HELP_BUTTON);
  550. X    XtUnmanageChild (button);
  551. X
  552. X    ac = 0;
  553. X    XtSetArg(al[ac], XmNmessageString, XmStringCreateLtoR
  554. X           ("This file already exists.", charset));  ac++;
  555. X    XtSetArg(al[ac], XmNokLabelString,
  556. X         XmStringCreateLtoR("Overwrite", charset)); ac++;
  557. X    XtSetArg(al[ac], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);  ac++;
  558. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  559. X#ifdef HARDCODE
  560. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  561. X#endif
  562. X    XtSetArg (al[ac], XmNdialogTitle, 
  563. X        XmStringCreateLtoR("File Exists Warning", charset));  ac++;
  564. X    exists_as_dialog = XmCreateWarningDialog(menu_bar,
  565. X           "file exists as dialog", al, ac);
  566. X    XtAddCallback (exists_as_dialog, XmNokCallback,
  567. X            DialogAcceptCB, DIALOG_EXISTS_AS);
  568. X    XtAddCallback (exists_as_dialog, XmNcancelCallback,
  569. X            DialogCancelCB, DIALOG_EXISTS_AS);
  570. X    button = XmMessageBoxGetChild (exists_as_dialog, XmDIALOG_HELP_BUTTON);
  571. X    XtUnmanageChild (button);
  572. X
  573. X    ac = 0;
  574. X    XtSetArg(al[ac], XmNmessageString, XmStringCreateLtoR
  575. X           ("This file does not have write permission.", charset));  ac++;
  576. X    XtSetArg(al[ac], XmNokLabelString,
  577. X         XmStringCreateLtoR("Continue", charset)); ac++;
  578. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  579. X    XtSetArg (al[ac], XmNdialogTitle, 
  580. X        XmStringCreateLtoR("Permission Warning", charset));  ac++;
  581. X    file_mode_dialog = XmCreateWarningDialog(menu_bar,
  582. X           "file mode dialog", al, ac);
  583. X    XtAddCallback (file_mode_dialog, XmNokCallback,
  584. X            DialogAcceptCB, DIALOG_F_MODE);
  585. X    XtAddCallback (file_mode_dialog, XmNcancelCallback,
  586. X            DialogCancelCB, DIALOG_F_MODE);
  587. X    button = XmMessageBoxGetChild (file_mode_dialog, XmDIALOG_HELP_BUTTON);
  588. X    XtUnmanageChild (button);
  589. X
  590. X    ac = 0;
  591. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  592. X    XtSetArg(al[ac], XmNmessageString, XmStringCreateLtoR
  593. X           ("Access permission Denied.", charset));  ac++;
  594. X#ifdef HARDCODE
  595. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  596. X#endif
  597. X    XtSetArg (al[ac], XmNdialogTitle, 
  598. X        XmStringCreateLtoR("Refused Warning", charset));  ac++;
  599. X    refused_dialog = XmCreateMessageDialog(menu_bar, "refused", al, ac);
  600. X    button = XmMessageBoxGetChild (refused_dialog, XmDIALOG_CANCEL_BUTTON);
  601. X    XtUnmanageChild (button);
  602. X    button = XmMessageBoxGetChild (refused_dialog, XmDIALOG_HELP_BUTTON);
  603. X    XtUnmanageChild (button);
  604. X
  605. X    ac = 0;
  606. X    XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ac++;
  607. X#ifdef HARDCODE
  608. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  609. X#endif
  610. X    XtSetArg (al[ac], XmNdialogTitle, 
  611. X        XmStringCreateLtoR("Exit Warning", charset));  ac++;
  612. X    exit_warning = CreateSpecialWarningDialog(menu_bar, "exit_warning",
  613. X          "warning_image", "Save Changes?", al, ac);
  614. X    XtAddCallback (exit_warning, XmNapplyCallback,
  615. X        DialogApplyCB, DIALOG_XWARNING);
  616. X    XtAddCallback (exit_warning, XmNokCallback,
  617. X        DialogAcceptCB, DIALOG_XWARNING);
  618. X
  619. X    ac = 0;
  620. X#ifdef HARDCODE
  621. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  622. X    XtSetArg (al[ac], XmNautoUnmanage, False);  ac++;
  623. X#endif
  624. X    XtSetArg (al[ac], XmNdialogTitle, 
  625. X        XmStringCreateLtoR("Find/Replace", charset));  ac++;
  626. X    find_dialog = CreateSpecialFindDialog(menu_bar,
  627. X         "Find", al, ac);
  628. X
  629. X    ac = 0;
  630. X#ifdef HARDCODE
  631. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  632. X#endif
  633. X    XtSetArg (al[ac], XmNdialogTitle, 
  634. X        XmStringCreateLtoR("Find Help", charset));  ac++;
  635. X    find_help_dialog = CreateSpecialHelpDialog(menu_bar, &find_help_text,
  636. X         "find_help", al, ac);
  637. X    XmTextSetString(find_help_text, find_help_string);
  638. X
  639. X    ac = 0;
  640. X    XtSetArg(al[ac], XmNselectionLabelString,
  641. X        XmStringCreateLtoR ("Go to line:", charset));  ac++;
  642. X    XtSetArg(al[ac], XmNcancelLabelString,
  643. X        XmStringCreateLtoR ("Done", charset));  ac++;
  644. X#ifdef HARDCODE
  645. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  646. X    XtSetArg (al[ac], XmNautoUnmanage, False);  ac++;
  647. X#endif
  648. X    XtSetArg (al[ac], XmNdialogTitle, 
  649. X        XmStringCreateLtoR("GoTo", charset));  ac++;
  650. X    goto_dialog = XmCreatePromptDialog(menu_bar,
  651. X           "goto dialog", al, ac);
  652. X    XtAddCallback (goto_dialog, XmNokCallback,
  653. X            DialogAcceptCB, DIALOG_GOTO);
  654. X    XtAddCallback (goto_dialog, XmNcancelCallback,
  655. X            DialogCancelCB, DIALOG_GOTO);
  656. X    button = XmSelectionBoxGetChild (goto_dialog, XmDIALOG_HELP_BUTTON);
  657. X    XtUnmanageChild (button);
  658. X
  659. X    ac = 0;
  660. X#ifdef HARDCODE
  661. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  662. X#endif
  663. X    XtSetArg (al[ac], XmNdialogTitle, 
  664. X        XmStringCreateLtoR("Preferences", charset));  ac++;
  665. X    prefer_dialog = CreatePreferencesDialog(menu_bar,
  666. X         "preferences", al, ac);
  667. X
  668. X    ac = 0;
  669. X#ifdef HARDCODE
  670. X    XtSetArg (al[ac], XmNtextFontList, fontlist);  ac++;
  671. X#endif
  672. X    XtSetArg (al[ac], XmNdialogTitle, 
  673. X        XmStringCreateLtoR("Preferences Help", charset));  ac++;
  674. X    help_dialog = CreateSpecialHelpDialog(menu_bar, &help_text,
  675. X         "help", al, ac);
  676. X}
  677. X
  678. END_OF_FILE
  679. if test 22684 -ne `wc -c <'xmedialg.c'`; then
  680.     echo shar: \"'xmedialg.c'\" unpacked with wrong size!
  681. fi
  682. chmod +x 'xmedialg.c'
  683. # end of 'xmedialg.c'
  684. fi
  685. if test -f 'xmemisc.c' -a "${1}" != "-c" ; then 
  686.   echo shar: Will not clobber existing file \"'xmemisc.c'\"
  687. else
  688. echo shar: Extracting \"'xmemisc.c'\" \(27127 characters\)
  689. sed "s/^X//" >'xmemisc.c' <<'END_OF_FILE'
  690. X/**---------------------------------------------------------------------
  691. X***     
  692. X***    file:        xmemisc.c
  693. X***
  694. X***    project:    jetedit - Motif Widgets text editor
  695. X***
  696. X***-------------------------------------------------------------------*/
  697. X
  698. X#define  BUFFER  20    /* The number of commands that can be undone. */
  699. X#define  BUFSIZE 40    /* The default storage size for the undo data. */
  700. X#include "xme.h"
  701. X
  702. Xstruct UndoRecord {
  703. X    XmTextPosition  start_pos;
  704. X    XmTextPosition  end_pos;
  705. X    XmTextPosition  cursor_pos;
  706. X    char  *delete_string;
  707. X} UndoRecordPtr[BUFFER];
  708. X
  709. Xint    head, tail;
  710. X
  711. X/*--------------------------------------------------------------
  712. X**      OpenUndoBuffer
  713. X**              Initialize an array of UndoRecord structures.
  714. X*/
  715. Xvoid OpenUndoBuffer()
  716. X{
  717. X    int  i;
  718. X    
  719. X    for (i=0; i<BUFFER; i++) {
  720. X        UndoRecordPtr[i].delete_string = XtMalloc (BUFSIZE);
  721. X        (UndoRecordPtr[i].delete_string)[0] = '\0';
  722. X        UndoRecordPtr[i].start_pos = 0;
  723. X        UndoRecordPtr[i].end_pos = 0;
  724. X        UndoRecordPtr[i].cursor_pos = 0;
  725. X    }
  726. X    head = 0;
  727. X    tail = 0;
  728. X}
  729. X
  730. X
  731. X/*--------------------------------------------------------------
  732. X**      InitUndoBuffer
  733. X**              Reinitialize the array of UndoRecord structures.
  734. X*/
  735. Xvoid InitUndoBuffer()
  736. X{
  737. X    int  i;
  738. X    
  739. X    for (i=0; i<BUFFER; i++) {
  740. X        UndoRecordPtr[i].delete_string = 
  741. X              XtRealloc (UndoRecordPtr[i].delete_string, BUFSIZE);
  742. X        (UndoRecordPtr[i].delete_string)[0] = '\0';
  743. X        UndoRecordPtr[i].start_pos = 0;
  744. X        UndoRecordPtr[i].end_pos = 0;
  745. X        UndoRecordPtr[i].cursor_pos = 0;
  746. X    }
  747. X    head = 0;
  748. X    tail = 0;
  749. X}
  750. X
  751. X
  752. X/*--------------------------------------------------------------
  753. X**      CloseUndoBuffer
  754. X**              Deallocate the string arrays.
  755. X*/
  756. Xvoid CloseUndoBuffer()
  757. X{
  758. X    int  i;
  759. X    
  760. X    XtSetSensitive(undo_button, False);
  761. X    for (i=0; i<BUFFER; i++)
  762. X        XtFree (UndoRecordPtr[i].delete_string);
  763. X}
  764. X    
  765. X    
  766. X/*--------------------------------------------------------------
  767. X**      UndoStoreCB
  768. X**              Store an UndoRecord structure.
  769. X*/
  770. Xvoid UndoStoreCB (w, client_data, call_data)
  771. XWidget    w;
  772. Xcaddr_t    client_data;
  773. Xcaddr_t    call_data;
  774. X{
  775. X    XmTextVerifyCallbackStruct *cb = (XmTextVerifyCallbackStruct *) call_data;
  776. X    XmTextPosition    startpos, endpos;
  777. X    char    *deltext;    /* text being deleted */
  778. X    char    *thestring;    /* the complete text in the text widget */
  779. X    int        textl;        /* the length of the text to be inserted */
  780. X    long    i, j;
  781. X    Arg        al[1];
  782. X    int        newlines;
  783. X    
  784. X    if (no_undo) return;    /* a flag indicating to not store an undo record */
  785. X    
  786. X    if (file_saved) {
  787. X        file_saved = False;
  788. X        XtSetSensitive(save_button, True);
  789. X        sprintf (message_string, " Editing:  %s", thefile);
  790. X        XtSetArg(al[0], XmNlabelString, 
  791. X            XmStringCreateLtoR(message_string, charset));
  792. X        XtSetValues(message, al, 1);
  793. X    }
  794. X    XtSetSensitive(undo_button, True);
  795. X    head++;
  796. X    if (head >= BUFFER) 
  797. X        head = 0;
  798. X    if (head == tail) {
  799. X        tail++;
  800. X        if (tail >= BUFFER)
  801. X            tail = 0;
  802. X    }
  803. X    
  804. X    startpos = cb->startPos;
  805. X    endpos   = cb->endPos;
  806. X    textl  = cb->text->length;
  807. X    thestring = cb->text->ptr;
  808. X    deltext = UndoRecordPtr[head].delete_string;
  809. X    deltext[0] = '\0';
  810. X    UndoRecordPtr[head].cursor_pos = cb->currInsert;
  811. X    UndoRecordPtr[head].start_pos = startpos;
  812. X    UndoRecordPtr[head].end_pos = startpos + textl;
  813. X
  814. X    newlines = 0;
  815. X    if (textl) {     /* text is being inserted */
  816. X        for (i=0; i<textl; i++)
  817. X            if (thestring[i] == '\n')
  818. X                newlines++;
  819. X    }
  820. X    if (endpos != startpos) {      /* text is being deleted */
  821. X        if (endpos - startpos + 1 > BUFSIZE) {
  822. X            deltext = XtRealloc 
  823. X                  (UndoRecordPtr[head].delete_string, endpos - startpos +1);
  824. X            UndoRecordPtr[head].delete_string = deltext;
  825. X        }
  826. X        thestring = XmTextGetString(w);
  827. X        j=0;
  828. X        for (i=startpos; i<endpos; i++,j++) {
  829. X            deltext[j] = thestring[i];
  830. X            if (deltext[j] == '\n')
  831. X                newlines--;
  832. X        }
  833. X        deltext[j] = '\0';
  834. X        XtFree(thestring);
  835. X    }
  836. X    
  837. X    if (newlines) {
  838. X        /* update the line number message */
  839. X        lines += newlines;
  840. X        sprintf (message_string, " Line:  %4d", lines);
  841. X        XtSetArg(al[0], XmNlabelString, 
  842. X            XmStringCreateLtoR(message_string, charset));
  843. X        XtSetValues(line, al, 1);
  844. X    }
  845. X}
  846. X
  847. X
  848. X/*--------------------------------------------------------------
  849. X**      Undo
  850. X**              Restore previous condition from an UndoRecord Structure.
  851. X*/
  852. Xvoid Undo(event)
  853. XXKeyEvent *event;
  854. X{
  855. X    XmTextPosition startpos;
  856. X    XmTextPosition endpos;
  857. X    char    *thestring;
  858. X    int        length, j, newlines;
  859. X    char     *file_string;
  860. X    char    line_string[15];
  861. X    Arg        al[1];
  862. X    
  863. X    if (head == tail) return;
  864. X    no_undo = True;
  865. X    startpos = UndoRecordPtr[head].start_pos;
  866. X    endpos = UndoRecordPtr[head].end_pos;
  867. X    thestring = UndoRecordPtr[head].delete_string;
  868. X    length = strlen(thestring);
  869. X    
  870. X    XmTextReplace (text, startpos, endpos, thestring);
  871. X    if (length > 1)
  872. X        XmTextSetSelection(text, startpos, startpos+length, event->time+1);
  873. X    MoveTo(UndoRecordPtr[head].cursor_pos);
  874. X    
  875. X    file_string = (char *)XmTextGetString(text);
  876. X    newlines = 1;
  877. X    for (j=0; j<UndoRecordPtr[head].cursor_pos; j++)
  878. X        if(file_string[j] == '\n')
  879. X            newlines++;
  880. X    
  881. X    if (lines != newlines) {
  882. X        lines = newlines;
  883. X        /* update the line number message */
  884. X        sprintf (line_string, " Line:%5d", lines);
  885. X        XtSetArg(al[0], XmNlabelString, 
  886. X            XmStringCreateLtoR(line_string, charset));
  887. X        XtSetValues(line, al, 1);
  888. X    }
  889. X    XtFree (file_string);
  890. X    
  891. X    head--;
  892. X    if (head < 0)
  893. X        head = BUFFER - 1;
  894. X    if (head == tail)
  895. X        XtSetSensitive(undo_button, False);
  896. X    no_undo = False;
  897. X}
  898. X
  899. X
  900. X/*--------------------------------------------------------------
  901. X**      Indent
  902. X**              Insert tab stop or spaces as appropriate.
  903. X**        Return the number of characters inserted.
  904. X*/
  905. Xint Indent(file_string, cursorPos, fixCursor)
  906. Xchar    *file_string;
  907. XXmTextPosition cursorPos;
  908. XBoolean fixCursor;
  909. X{
  910. X    XmTextPosition linePos;
  911. X    int      i,j;
  912. X    char     theChar;
  913. X    int      numSpaces;
  914. X    char     insertionText[MAX_TAB_SPACES+1];
  915. X    Boolean    leading;    /* leading or trailing flag */
  916. X    
  917. X    /* if real tabs are selected, just insert and return */
  918. X    if (leading_tabs && trailing_tabs) {
  919. X        XmTextReplace(text, cursorPos, cursorPos, "\t");
  920. X        return(1);
  921. X    }
  922. X    
  923. X    /* FixCursor is a flag indicating this routine was called from
  924. X        the auto indenting routines in NewLine. NewLine sends only
  925. X        single lines of text in file_string rather than the entire
  926. X        file. */
  927. X    if (fixCursor)
  928. X        linePos = strlen (file_string);
  929. X    else linePos = cursorPos;
  930. X    
  931. X    /* We now figure out where to tab to. The first step is to move back
  932. X        to the first non-space character, counting spaces as we go. */
  933. X    numSpaces = 0;
  934. X    while (linePos-- > 0) {
  935. X        if (file_string[linePos] != ' ')
  936. X            break;
  937. X        numSpaces++;
  938. X    }
  939. X    
  940. X    /* If the first none space character is a newline, or we reach the 
  941. X        beginning of the string without finding anything but spaces,
  942. X        we are inserting a leading tab stop. */
  943. X    theChar = file_string[linePos];
  944. X    if ((theChar == '\n') || (linePos < 0))
  945. X        leading = True;
  946. X    
  947. X    /* else if the character was anything but '\t', we are 
  948. X        inserting a trailing tab. Determine the total number of
  949. X        characters on the line (stop counting if '\t' is encountered) */
  950. X    else if (theChar != '\t') {
  951. X        leading = False;
  952. X        numSpaces++;
  953. X        while (linePos-- > 0) {
  954. X            if ((file_string[linePos] == '\n') || (file_string[linePos] == '\t'))
  955. X                break;
  956. X            numSpaces++;
  957. X        }
  958. X    }
  959. X    
  960. X    /* else the character must have been '\t'. We check to see if there is anything
  961. X        but spaces or tabs back on the line. If there are, it's a trailing tab.
  962. X        If not, it's a leading tab. */
  963. X    else {
  964. X        while (linePos >= 0) {
  965. X            if ((file_string[linePos] != ' ') && (file_string[linePos] != '\t'))
  966. X                break;
  967. X            linePos--;
  968. X        }
  969. X        if ((file_string[linePos] == '\n') || (linePos < 0))
  970. X            leading = True;
  971. X        else leading = False;
  972. X    }
  973. X    
  974. X    if ((leading && leading_tabs) || (!leading && trailing_tabs)) {
  975. X        XmTextReplace(text, cursorPos, cursorPos, "\t");
  976. X        return(1);
  977. X    }
  978. X    
  979. X    /* Insert enough spaces to fill out to the next tab_spaces stop. */
  980. X    i = tab_spaces - (numSpaces % tab_spaces);
  981. X    for (j=0; j<i; j++)
  982. X        insertionText[j] = ' ';
  983. X    insertionText[i] = '\0';
  984. X    XmTextReplace(text, cursorPos, cursorPos, insertionText);
  985. X    return (i);
  986. X}
  987. X
  988. X
  989. X
  990. X/*--------------------------------------------------------------
  991. X**      Outdent
  992. X**              Delete to previous tab stop.
  993. X*/
  994. Xint Outdent(file_string, cursorPos, fixCursor)
  995. Xchar    *file_string;
  996. XXmTextPosition cursorPos;
  997. XBoolean fixCursor;
  998. X{
  999. X    XmTextPosition linePos;
  1000. X    int  i;
  1001. X    int  numSpaces;
  1002. X    int  numNotabs;
  1003. X    
  1004. X    numSpaces=0;
  1005. X    /* FixCursor is a flag indicating this routine was called from
  1006. X        the auto indenting routines in NewLine. NewLine sends only
  1007. X        single lines of text in file_string rather than the entire
  1008. X        file. */
  1009. X    if (fixCursor)
  1010. X        linePos = strlen (file_string);
  1011. X    else linePos = cursorPos;
  1012. X    /* find previous none space */
  1013. X    while (linePos > 0) {
  1014. X        linePos--;
  1015. X        if (file_string[linePos] != ' ')
  1016. X            break;
  1017. X        numSpaces++;
  1018. X    }
  1019. X    /* Now we determine the total number of characters in the line.
  1020. X       We stop counting if we find a '\n' or '\t'. */
  1021. X    numNotabs = numSpaces;
  1022. X    if (file_string[linePos] != ' ') {
  1023. X        while (linePos > 0) {
  1024. X            if ((file_string[linePos] == '\n') || (file_string[linePos] == '\t'))
  1025. X                break;
  1026. X            numNotabs++;
  1027. X            linePos--;        
  1028. X        }
  1029. X    }
  1030. X    
  1031. X    if (numNotabs) {
  1032. X        i = numNotabs % tab_spaces;
  1033. X        if (i == 0)
  1034. X            i = tab_spaces;
  1035. X        if (i > numSpaces)
  1036. X            i = numSpaces;
  1037. X    }
  1038. X    else {
  1039. X        if (file_string[linePos] == '\t')
  1040. X            i=1;
  1041. X        else i=0;
  1042. X    }
  1043. X
  1044. X    if (i)
  1045. X        XmTextReplace(text, cursorPos-i, cursorPos, "");
  1046. X    return (i);
  1047. X}
  1048. X
  1049. X
  1050. X/*--------------------------------------------------------------
  1051. X**      IndentText
  1052. X**              Indent each line in a block of selected text
  1053. X**        or at the cursor if no text selected.
  1054. X*/
  1055. Xvoid IndentText(w,event)
  1056. XWidget      w;
  1057. XXKeyEvent *event;
  1058. X{
  1059. X    XmTextPosition cursorPos;
  1060. X    XmTextPosition linePos;
  1061. X    XmTextPosition endPos;
  1062. X    XmTextPosition startPos;
  1063. X    Arg  al[2];
  1064. X    char *selString;            /* the selected block of text */
  1065. X    char *file_string;
  1066. X    int     i;
  1067. X    
  1068. X    /* get the text string */
  1069. X    file_string = (char *)XmTextGetString(text);
  1070. X    /* get cursor position */
  1071. X    XtSetArg(al[0], XmNcursorPosition, &cursorPos);
  1072. X    XtGetValues(text, al, 1);
  1073. X    
  1074. X    /* The cursor may be located at either the start or end of the
  1075. X       selected block of text. */
  1076. X    selString = NULL;
  1077. X    if ((selString = XmTextGetSelection (text)) && strlen(selString)) {
  1078. X        if (!strncmp (selString, file_string+cursorPos, strlen(selString))) {
  1079. X            startPos = cursorPos;
  1080. X            endPos = cursorPos + strlen (selString);
  1081. X        }
  1082. X        else {
  1083. X            startPos = cursorPos - strlen (selString);
  1084. X            endPos = cursorPos;
  1085. X        }
  1086. X        cursorPos = endPos;
  1087. X        
  1088. X        if (file_string[--cursorPos] == '\n')
  1089. X            cursorPos--;    /* if last character is newline,
  1090. X                                    move back one character */
  1091. X        while (cursorPos >= startPos) {
  1092. X            /* find start of line */
  1093. X            while (file_string[cursorPos] != '\n' && cursorPos >= startPos)
  1094. X                cursorPos--;
  1095. X            linePos = cursorPos + 1;
  1096. X            while (linePos < endPos) {
  1097. X                if ((file_string[linePos] != ' ') && (file_string[linePos] != '\t'))
  1098. X                    break;
  1099. X                linePos++;
  1100. X            }
  1101. X            i = Indent (file_string, linePos, False);
  1102. X            endPos += i;
  1103. X            cursorPos --;
  1104. X        }
  1105. X        /* the widget apparently clears the selection at event->time,
  1106. X           so we need to add one to get it to set a new selection */
  1107. X        XmTextSetSelection (text, startPos, endPos, event->time+1);
  1108. X        MoveTo(endPos);
  1109. X    }
  1110. X    else {
  1111. X        Indent(file_string, cursorPos, False);
  1112. X    }
  1113. X    
  1114. X    if (selString)
  1115. X        XtFree(selString);
  1116. X    XtFree (file_string);
  1117. X}
  1118. X
  1119. X
  1120. X/*--------------------------------------------------------------
  1121. X**      OutdentText
  1122. X**              Outdent each line in a block of selected text
  1123. X**        or at the cursor if no text selected.
  1124. X*/
  1125. Xvoid OutdentText(w,event)
  1126. XWidget      w;
  1127. XXKeyEvent *event;
  1128. X{
  1129. X    XmTextPosition cursorPos;        /* text cursor position    */
  1130. X    XmTextPosition endPos;
  1131. X    XmTextPosition startPos;
  1132. X    XmTextPosition oldPos;
  1133. X    Arg  al[2];
  1134. X    char *selString;            /* the selected block of text */
  1135. X    char *file_string;
  1136. X    char theChar;
  1137. X    
  1138. X    
  1139. X    /* get the text string */
  1140. X    file_string = (char *)XmTextGetString(text);
  1141. X    /* get cursor position */
  1142. X    XtSetArg(al[0], XmNcursorPosition, &cursorPos);
  1143. X    XtGetValues(text, al, 1);
  1144. X    
  1145. X    selString = NULL;
  1146. X    if ((selString = XmTextGetSelection (text)) && strlen(selString)) {
  1147. X        /*determine if cursor is at the beginning or end of selected block */
  1148. X        if (!strncmp (selString, file_string+cursorPos, strlen(selString))) {
  1149. X            startPos = cursorPos;
  1150. X            endPos = cursorPos + strlen (selString);
  1151. X        }
  1152. X        else {
  1153. X            startPos = cursorPos - strlen (selString);
  1154. X            endPos = cursorPos;
  1155. X        }
  1156. X        cursorPos = endPos;
  1157. X        
  1158. X        if (file_string[--cursorPos] == '\n')
  1159. X            cursorPos--;        /* if last character is \n, skip */
  1160. X        while (cursorPos >= startPos) {
  1161. X            /* find start of line */
  1162. X            while (file_string[cursorPos] != '\n' && cursorPos >= startPos)
  1163. X                cursorPos--;
  1164. X            /* find first non space or tab */
  1165. X            oldPos = cursorPos;
  1166. X            while ((theChar = file_string[++cursorPos]) == '\t' || theChar == ' ')
  1167. X                ;
  1168. X            endPos -= Outdent(file_string, cursorPos, False);
  1169. X            cursorPos = oldPos-1;
  1170. X        }
  1171. X        /* the widget apparently clears the selection at event->time,
  1172. X           so we need to add one to get it to set a new selection */
  1173. X        XmTextSetSelection (text, startPos, endPos, event->time+1);
  1174. X    }
  1175. X    else Outdent(file_string, cursorPos, False);
  1176. X    
  1177. X    if (selString)
  1178. X        XtFree(selString);
  1179. X    XtFree (file_string);
  1180. X}
  1181. X
  1182. X
  1183. X/*--------------------------------------------------------------
  1184. X**    GetPrevLine
  1185. X**        Get the previous line minus leading and trailing
  1186. X**        spaces and tabs.
  1187. X**
  1188. X**        This routine alters the contents of file_string.
  1189. X**        It returns a pointer to the
  1190. X**        position in file_string of the first non whitespace
  1191. X**        character of the first line before old_pos which is
  1192. X**        not a comment line. This can be the line containing
  1193. X**        old_pos. '\0's are put at the starting value of
  1194. X**        old_pos and at the end of the returned line but
  1195. X**        before trailing comments or whitespace.
  1196. X**
  1197. X**        On entry, old_pos points to the current insert point.
  1198. X**        On exit, it points to the '\n' immediately preceding
  1199. X**        the returned line. If there is no '\n', old_pos returns
  1200. X**        -1.
  1201. X**
  1202. X**        text_pos returns the offset from 
  1203. X**        the beginning of file_string of the beginning of
  1204. X**        the returned string.
  1205. X**
  1206. X**        spacetab will contain a '\n' followed by the leading
  1207. X**        whitespace and terminated with '\0'. This is for use
  1208. X**        in indenting the next line to the same position as the 
  1209. X**        previous one.
  1210. X*/
  1211. Xchar *GetPrevLine(file_string, old_pos, text_pos, spacetab)
  1212. Xchar *file_string;
  1213. Xlong *old_pos;
  1214. Xlong *text_pos;
  1215. Xchar *spacetab;
  1216. X{
  1217. X    char *trailing;
  1218. X    long  i;
  1219. X    char theChar;
  1220. X    char *theLine;
  1221. X    
  1222. X    /* the while loop eliminates lines of only tabs, spaces & comments */
  1223. X    i=0;
  1224. X    while (*old_pos > 0) {
  1225. X        /* get the line */
  1226. X        file_string[*old_pos] = '\0';
  1227. X        while (file_string[--(*old_pos)] != '\n') 
  1228. X            if (*old_pos < 0) break;
  1229. X        *text_pos = *old_pos;
  1230. X        (*text_pos)++;
  1231. X        /* save leading spaces and tabs */
  1232. X        i=0;
  1233. X        spacetab[i++] = '\n';
  1234. X        while ((file_string[*text_pos] == ' ') || (file_string[*text_pos] == '\t')) {
  1235. X            spacetab[i++] = file_string[*text_pos];
  1236. X            (*text_pos)++;
  1237. X        }
  1238. X        /* strip the returned line of leading tabs & spaces */
  1239. X        theLine = (char *)(file_string + *text_pos);
  1240. X        /* if the line contains any characters, check for a comment line */
  1241. X        if (theLine[0] != '\0') {
  1242. X            /* break if this line is not a comment */
  1243. X            if (theLine[0] != '*' && strncmp (theLine, "/*", 2))
  1244. X                break;
  1245. X        }
  1246. X    }
  1247. X    spacetab[i] = '\0';
  1248. X    spacetab[i+1] = '\0';    /* used by NewLine */
  1249. X
  1250. X    /* delete trailing comments */
  1251. X    if (trailing = strchr (theLine, '/'))
  1252. X        if (trailing[1] == '*')
  1253. X            trailing[0] = '\0';
  1254. X    
  1255. X    /* delete trailing spaces & tabs */
  1256. X    i = strlen (theLine);
  1257. X    while (((theChar = theLine[--i]) == ' ') || (theChar == '\t'))
  1258. X        ;
  1259. X    theLine[i+1] = '\0';
  1260. X    return (theLine);
  1261. X}
  1262. X
  1263. X/*--------------------------------------------------------------
  1264. X**      InSwitch
  1265. X**              Determine whether text_pos is in a switch.
  1266. X*/
  1267. XBoolean    InSwitch(file_string, text_pos)
  1268. Xchar    *file_string;
  1269. Xlong    text_pos;
  1270. X{
  1271. X    int     close_brackets;
  1272. X    char    *theLine;
  1273. X    
  1274. X    close_brackets = 0;
  1275. X    while (text_pos-- > 0) {
  1276. X        if (file_string[text_pos] == '}')
  1277. X            close_brackets++;
  1278. X        else if (file_string[text_pos] == '{') 
  1279. X            if (close_brackets >= 0)
  1280. X                close_brackets--;
  1281. X            else 
  1282. X                return False;
  1283. X        else if (file_string[text_pos] == 's') {
  1284. X            theLine = (char *)(file_string + text_pos);
  1285. X            if (!strncmp (theLine, "switch", 6))
  1286. X                return True;
  1287. X        }
  1288. X    }
  1289. X    return False;
  1290. X}
  1291. X                
  1292. X/*--------------------------------------------------------------
  1293. X**      NewLine
  1294. X**              Indent new line to appropriate syntax sensitive 
  1295. X**        position.
  1296. X*/
  1297. Xvoid NewLine(w,event)
  1298. XWidget      w;
  1299. XXKeyEvent *event;
  1300. X{
  1301. X    XmTextPosition cursorPos;       /* text cursor position    */
  1302. X    Arg      al[1];
  1303. X    char     *file_string;
  1304. X    long     textPos;
  1305. X    long     oldPos;
  1306. X    char     spacetab[100];
  1307. X    char     garbage[100];
  1308. X    char     *theLine;
  1309. X    char     *oldLine;
  1310. X    char     theChar;
  1311. X    int      i;
  1312. X    Boolean    inFlag;
  1313. X    char    line_string[15];
  1314. X    
  1315. X    /* get the cursor position */
  1316. X    XtSetArg(al[0], XmNcursorPosition, &cursorPos);
  1317. X    XtGetValues(text, al, 1);
  1318. X    
  1319. X    /* get the text string */
  1320. X    file_string = (char *)XmTextGetString(text);
  1321. X    if ((indent_style==NONE) || (file_string[cursorPos-1] == '\n') || (cursorPos == 0)) {
  1322. X        XmTextReplace(text, cursorPos, cursorPos, "\n");
  1323. X        MoveTo(cursorPos+1);
  1324. X        return;
  1325. X    }
  1326. X        
  1327. X    oldPos = (long)cursorPos;
  1328. X    theLine = GetPrevLine(file_string, &oldPos, &textPos, &spacetab[0]);
  1329. X
  1330. X    /* indent new line to position of previous line - smart indenting */
  1331. X    XmTextReplace(text, cursorPos, cursorPos, spacetab);
  1332. X    cursorPos += strlen (spacetab);
  1333. X    if (indent_style == SMART) {
  1334. X        MoveTo(cursorPos);
  1335. X        return;
  1336. X    }
  1337. X    
  1338. X    /* C syntax sensitive indenting. */
  1339. X    /* if theLine is not empty, check whether to indent or outdent */
  1340. X    if (i = strlen(theLine)) {
  1341. X        if (theLine[i-1] != ';') {
  1342. X            inFlag = False;
  1343. X            switch (theLine[0]) {
  1344. X            case 'c':
  1345. X                if (!strncmp (theLine, "case", 4))
  1346. X                    inFlag = True;
  1347. X                break;
  1348. X            case 'd':
  1349. X                if (!strncmp (theLine, "do", 2))
  1350. X                    inFlag = True;
  1351. X                break;
  1352. X            case 'e':
  1353. X                if (!strncmp (theLine, "else", 4))
  1354. X                    inFlag = True;
  1355. X                break;
  1356. X            case 'f':
  1357. X                if (!strncmp (theLine, "for", 3))
  1358. X                    inFlag = True;
  1359. X                break;
  1360. X            case 'i':
  1361. X                if (!strncmp (theLine, "if", 2))
  1362. X                    inFlag = True;
  1363. X                break;
  1364. X            case 's':
  1365. X                if (!strncmp (theLine, "struct", 6))
  1366. X                    inFlag = True;
  1367. X                else if (!strncmp (theLine, "static", 6))
  1368. X                    inFlag = True;
  1369. X                else if (!strncmp (theLine, "switch", 6))
  1370. X                    if (indent_case || open_brace != 2)
  1371. X                        inFlag = True;
  1372. X                break;
  1373. X            case 't':
  1374. X                if (!strncmp (theLine, "typedef", 7))
  1375. X                    inFlag = True;
  1376. X                break;
  1377. X            case 'w':
  1378. X                if (!strncmp (theLine, "while", 5))
  1379. X                    inFlag = True;
  1380. X                break;
  1381. X            case '{':
  1382. X                if (open_brace != 1 && theLine[1] == '\0') {
  1383. X                    if (oldPos>0) {
  1384. X                        theLine = GetPrevLine(file_string, &oldPos, &textPos, &garbage[0]);
  1385. X                        if (indent_case || strncmp(theLine, "switch", 6))
  1386. X                            inFlag = True;
  1387. X                    }
  1388. X                }
  1389. X                break;
  1390. X            case '}':
  1391. X                if (close_brace == 1)
  1392. X                    Outdent(spacetab, cursorPos, True);
  1393. X                break;
  1394. X            }
  1395. X            if (inFlag)
  1396. X                Indent (spacetab, cursorPos, True);
  1397. X        }
  1398. X        /* Else the previous line ends in a ';'. We need to check the line
  1399. X        ** before it to decide whether to outdent.
  1400. X        */
  1401. X        else {
  1402. X            /* outdent after a break when in a switch */
  1403. X            if (!strncmp (theLine, "break", 5)) {
  1404. X                if (InSwitch(file_string, oldPos))
  1405. X                    Outdent (spacetab, cursorPos, True);
  1406. X            }
  1407. X            else if (oldPos>0) {
  1408. X                theLine = GetPrevLine(file_string, &oldPos, &textPos, &garbage[0]);
  1409. X                if (i = strlen(theLine))
  1410. X                    switch (theLine[i-1]) {
  1411. X                    case ';':
  1412. X                    case ':':
  1413. X                    case '{':
  1414. X                    case '}':
  1415. X                        break;
  1416. X                    default:
  1417. X                        Outdent (spacetab, cursorPos, True);
  1418. X                        break;
  1419. X                    }
  1420. X            }
  1421. X        }
  1422. X    }
  1423. X    XtFree (file_string);
  1424. X}
  1425. X    
  1426. X/*--------------------------------------------------------------
  1427. X**      LeftBrace
  1428. X**              Outdent when a left brace is typed when using
  1429. X**        syntax sensitive indenting and open_brace==0.
  1430. X*/
  1431. Xvoid LeftBrace(w,event)
  1432. XWidget      w;
  1433. XXKeyEvent *event;
  1434. X{
  1435. X    XmTextPosition cursorPos;        /* text cursor position    */
  1436. X    XmTextPosition thePos;
  1437. X    long textPos;
  1438. X    Arg  al[10];
  1439. X    char *file_string;
  1440. X    char spacetab[100];
  1441. X    char *theLine;
  1442. X    char theChar;
  1443. X    
  1444. X    /* get the text string */
  1445. X    file_string = (char *)XmTextGetString(text);
  1446. X    /* get cursor position */
  1447. X    XtSetArg(al[0], XmNcursorPosition, &cursorPos);
  1448. X    XtGetValues(text, al, 1);
  1449. X    XmTextReplace(text, cursorPos, cursorPos, "{");
  1450. X    if ((indent_style==SYNTAX) && (open_brace == 0)) {
  1451. X        /* we need to make sure this is the first character on the line to
  1452. X            prevent outdenting { typed in comments */
  1453. X        thePos = cursorPos;
  1454. X        while (thePos > 0) {
  1455. X            thePos--;
  1456. X            if ((theChar = file_string[thePos]) == '\n') {
  1457. X                Outdent (file_string, cursorPos, False);
  1458. X                break;
  1459. X            }
  1460. X            else if (theChar != ' ' && theChar != '\t')
  1461. X                break;
  1462. X        }
  1463. X    }
  1464. X    XtFree (file_string);
  1465. X}
  1466. X
  1467. X/*--------------------------------------------------------------
  1468. X**      RightBrace
  1469. X**              Outdent when a right brace is typed when using
  1470. X**        syntax sensitive indenting and close_brace==0.
  1471. X**        It's a little more complex if the right brace follows
  1472. X**        a break.
  1473. X*/
  1474. Xvoid RightBrace(w,event)
  1475. XWidget      w;
  1476. XXKeyEvent *event;
  1477. X{
  1478. X    XmTextPosition cursorPos;        /* text cursor position    */
  1479. X    XmTextPosition thePos;
  1480. X    long textPos;
  1481. X    Arg  al[10];
  1482. X    char *file_string;
  1483. X    char spacetab[100];
  1484. X    char *theLine;
  1485. X    char theChar;
  1486. X    
  1487. X    /* get the text string */
  1488. X    file_string = (char *)XmTextGetString(text);
  1489. X    /* get cursor position */
  1490. X    XtSetArg(al[0], XmNcursorPosition, &cursorPos);
  1491. X    XtGetValues(text, al, 1);
  1492. X    XmTextReplace(text, cursorPos, cursorPos, "}");
  1493. X    if ((close_brace==0) && (indent_style==SYNTAX)) {
  1494. X        thePos = cursorPos;
  1495. X        while (thePos > 0) {
  1496. X            thePos--;
  1497. X            if ((theChar = file_string[thePos]) == '\n') {
  1498. X                thePos = cursorPos;
  1499. X                theLine = GetPrevLine(file_string, &thePos, &textPos, &spacetab[0]);
  1500. X                if (strncmp(theLine, "break", 5)) {
  1501. X                    XtFree (file_string);
  1502. X                    file_string = (char *)XmTextGetString(text);
  1503. X                    Outdent (file_string, cursorPos, False);
  1504. X                }
  1505. X                else {
  1506. X                    if (indent_case || !InSwitch(file_string, thePos)) {
  1507. X                        XtFree (file_string);
  1508. X                        file_string = (char *)XmTextGetString(text);
  1509. X                        Outdent (file_string, cursorPos, False);
  1510. X                    }
  1511. X                }
  1512. X                break;
  1513. X            }
  1514. X            else if (theChar != ' ' && theChar != '\t')
  1515. X                break;
  1516. X        }
  1517. X    }
  1518. X    XtFree (file_string);
  1519. X}
  1520. X
  1521. X/*-------------------------------------------------------------
  1522. X**      Goto Line
  1523. X*/
  1524. Xvoid GotoString(goto_string)
  1525. Xchar    *goto_string;
  1526. X{
  1527. X    char     *file_string;
  1528. X    XmTextPosition cursorPos;
  1529. X    Arg        al[1];
  1530. X    int        line_number;
  1531. X    int        i;
  1532. X    long    j;
  1533. X    long    string_length;
  1534. X
  1535. X    /* get the text string */
  1536. X    file_string = (char *)XmTextGetString(text);
  1537. X    j=0;
  1538. X    string_length = strlen (file_string);
  1539. X    sscanf (goto_string, "%d", &line_number);
  1540. X
  1541. X    for (i=0; i<(line_number-1); i++) {
  1542. X        while (file_string[j++] != '\n') {
  1543. X           if (j >= string_length) {
  1544. X               fprintf (stderr, "\7");    /* beep if at end of file */
  1545. X               break;
  1546. X            }
  1547. X        }
  1548. X        if (j >= string_length) break;
  1549. X    }
  1550. X
  1551. X    if (j < string_length) {
  1552. X        MoveTo((XmTextPosition)j);
  1553. X    }
  1554. X    XtFree (file_string);
  1555. X}
  1556. X
  1557. X/*-------------------------------------------------------------
  1558. X**      MoveTo
  1559. X**        We needed this function because Motif1.1 seems to
  1560. X**        have real problems with:
  1561. X**            XtSetArg (al[0], XmNcursorPosition, position);
  1562. X**            XtSetValues (text, al, 1);
  1563. X**        The function:
  1564. X**            XmTextSetCursorPosition(text, position);
  1565. X**        works fine, but is unavailable in Motif1.0
  1566. X*/
  1567. Xvoid MoveTo(position)
  1568. XXmTextPosition    position;
  1569. X{
  1570. X    Arg al[1];
  1571. X    
  1572. X#ifdef Motif1.0
  1573. X    XtSetArg (al[0], XmNcursorPosition, position);
  1574. X    XtSetValues (text, al, 1);
  1575. X#else
  1576. X    XmTextSetCursorPosition(text, position);
  1577. X#endif
  1578. X}
  1579. X
  1580. END_OF_FILE
  1581. if test 27127 -ne `wc -c <'xmemisc.c'`; then
  1582.     echo shar: \"'xmemisc.c'\" unpacked with wrong size!
  1583. fi
  1584. chmod +x 'xmemisc.c'
  1585. # end of 'xmemisc.c'
  1586. fi
  1587. echo shar: End of archive 3 \(of 4\).
  1588. cp /dev/null ark3isdone
  1589. MISSING=""
  1590. for I in 1 2 3 4 ; do
  1591.     if test ! -f ark${I}isdone ; then
  1592.     MISSING="${MISSING} ${I}"
  1593.     fi
  1594. done
  1595. if test "${MISSING}" = "" ; then
  1596.     echo You have unpacked all 4 archives.
  1597.     rm -f ark[1-9]isdone
  1598. else
  1599.     echo You still need to unpack the following archives:
  1600.     echo "        " ${MISSING}
  1601. fi
  1602. ##  End of shell archive.
  1603. exit 0
  1604.  
  1605. exit 0 # Just in case...
  1606. -- 
  1607.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  1608. \X/  Amiga - The only way to fly!      |
  1609.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  1610.   casual observer..."                  |
  1611.