home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xod / part01 < prev    next >
Encoding:
Text File  |  1993-04-27  |  66.4 KB  |  2,048 lines

  1. Newsgroups: comp.sources.x
  2. From: rfs@se28.wg2.waii.com (Robert Starr)
  3. Subject: v19i018:  Xod - Octal dump for Xwindows, Part01/04
  4. Message-ID: <csx-v19i018=Xod.150000@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 0f17f789e0b790275cc740a1cdd22a31
  6. Date: Tue, 9 Mar 1993 21:10:47 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: rfs@se28.wg2.waii.com (Robert Starr)
  10. Posting-number: Volume 19, Issue 18
  11. Archive-name: Xod/part01
  12. Environment: X11R4 X11R5 gcc
  13.  
  14. =================================== XOD =================================
  15.  
  16. Late news: if running OpenWindows, under X R4, it appears you will
  17. need to add the following line to helpdialog.c:
  18.  
  19.     #define XtNleftBitmap    "leftBitmap"
  20.  
  21. Please read this whole file before trying to make this program.  Some
  22. of what is said herein just may be important..... and you might not
  23. give up on it if you realize the minor caveats.  If nothing else,
  24. search for IMPORTANT in this document.
  25.  
  26.  Release
  27.  -------
  28. This is the first release of xod (xod 1.01).
  29.  
  30. Xod is an X-based "octal" dump program.  Like the Unix-supplied od(1),
  31. you are not limited to octal displays.  You can view your data in
  32. hex, octal, decimal, or ASCII as well.  Not only that (which isn't all
  33. that earth-shattering), you can click on a byte, and decode it and the
  34. bytes that follow in a variety of formats, search for strings, move
  35. backwards and forwards in the file, and lots more.
  36.  
  37. Like some mainframe data dumpers, you see your binary data in your
  38. selected format on one side of the screen, and in ASCII on the other.
  39. But with xod, you are a key (or mouse) stroke away from viewing your
  40. data in one of 4 formats (hex, octal, decimal, or ASCII).
  41.  
  42. xod uses the Athena widget set for portability.
  43. In a lot of ways, it is like running less, vi, or emacs on a binary file
  44. (except that you can't edit it).  But you can search for  strings,
  45. numbers, etc., decode any byte pointed to, and much other stuff.  See the
  46. man page for full details.
  47.  
  48. xod was developed on a 486 running Linux, and tested there and on a
  49. Sun.  Both were running X11R5, but is should run under R4.
  50.  
  51.  Building
  52.  --------
  53. Should be fairly easy:
  54.  
  55.     xmkmf
  56.     make
  57.  
  58. If this doesn't work, the files used by imake (run by xmkmf) may
  59. be wrong.  Have your sysadmin fix the appropriate files.
  60.  
  61. *IMPORTANT*
  62. To install, you need to install Xod.ad as Xod in your app-defaults
  63. area.  You may need a sysadmin to do this.  If you don't do this,
  64. xod will look stupid when it is run. And you will have to copy
  65. xod to your area for binaries (a sysadmin will probably have to do
  66. this as well).
  67.  
  68. *IMPORTANT*
  69. NOTE: this code is ANSI-C, so you may need to modify the CC line
  70. in the Imakefile before running xmkmf.  Use gcc if your company is too
  71. cheap to buy an ASNI compiler (in 1993?).  Otherwise, perhaps you
  72. can use one of the public domain de-prototypers.
  73.  
  74. *IMPORTANT*
  75. If keys don't work as advertized, some of the key mappings may be wrong
  76. (mainly PgUp, PgDn, Home, and End).  This has been tested on a Sun, and
  77. a 486 under Linux,  and there are proper key mappings for them.  Check
  78. out keys.h, and modify if required.  If you get proper mappings for other
  79. machines, please email them to me.
  80.  
  81.  Before running xod
  82.  ------------------
  83. Ensure that Xod.ad (included with this distribution) is installed in
  84. an app-defaults as Xod.  Otherwise, the screen display will be pretty
  85. funky.
  86.  
  87.  Author(s)
  88.  ---------
  89. xod was written by RF Starr (starr@wg2.waii.com).  It makes use of
  90. Paul Fox's wonderful CTW widget.  The CTW widget is a color terminal widget,
  91. allowing a text-like widget with multiple colors, and easy cursor manipulation.
  92. Much of the dialog box stuff was ripped out of the X11R5 bitmap program.
  93.  
  94.  Disclaimer
  95.  ----------
  96. This software is provided as-is.  There are no guarantees of any kind.
  97. Use at your own risk.  Don't smoke in bed.
  98.  
  99. This software is free, with no obligations whatsoever, except possibly
  100. those imposed by the authors of chunks of code used herein.
  101.  
  102. Please report bugs to the author, and please do not distribute hacked up
  103. versions of the source without my permission.  Suggest improvements to
  104. the author (especially minor mods to the keys.h file to get it to work on
  105. other machines).
  106.  
  107. ---- Cut Here and unpack ----
  108. #!/bin/sh
  109. # shar:    Shell Archiver  (v1.22)
  110. #
  111. # This is part 1 of a multipart archive                                    
  112. # do not concatenate these parts, unpack them in order with /bin/sh        
  113. #
  114. #    Run the following text with /bin/sh to create:
  115. #      Dialog.c
  116. #      Dialog.h
  117. #      Imakefile
  118. #      README
  119. #      Xod.ad
  120. #      buttonndx.h
  121. #      buttons.h
  122. #      byteaddress.c
  123. #      cmdline.c
  124. #      ctw.c
  125. #      ctw.h
  126. #      ctwP.h
  127. #      decode.c
  128. #      defines.h
  129. #      fileio.c
  130. #      frowny.xbm
  131. #      getres.c
  132. #      gvars.h
  133. #      gwidgets.h
  134. #      helpdialog.c
  135. #      keyhandler.c
  136. #      keys.h
  137. #      main.c
  138. #      mkwidgets.c
  139. #      rotate.c
  140. #      utils.c
  141. #      version.h
  142. #      xod.1
  143. #      xod.h
  144. #      xod.pt
  145. #      xutils.c
  146. #
  147. if test -r s2_seq_.tmp
  148. then echo "Must unpack archives in sequence!"
  149.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  150.      exit 1; fi
  151. echo "x - extracting Dialog.c (Text)"
  152. sed 's/^X//' << 'SHAR_EOF' > Dialog.c &&
  153. Xstatic char *RcsID = "$Id: Dialog.c,v 1.3 1993/02/23 18:21:42 rfs Exp $";
  154. X/*
  155. X * $Log: Dialog.c,v $
  156. X * Revision 1.3  1993/02/23  18:21:42  rfs
  157. X * Mad PositionPopup routine.
  158. X *
  159. X * Revision 1.2  1993/02/22  22:19:16  rfs
  160. X * *** empty log message ***
  161. X *
  162. X * Revision 1.1  1993/02/13  02:19:24  rfs
  163. X * Initial revision
  164. X *
  165. X*/
  166. X
  167. X/*
  168. X * $XConsortium: Dialog.c,v 1.10 91/07/24 15:46:20 converse Exp $
  169. X *
  170. X * Copyright 1989 Massachusetts Institute of Technology
  171. X *
  172. X * Permission to use, copy, modify, distribute, and sell this software and its
  173. X * documentation for any purpose is hereby granted without fee, provided that
  174. X * the above copyright notice appear in all copies and that both that
  175. X * copyright notice and this permission notice appear in supporting
  176. X * documentation, and that the name of M.I.T. not be used in advertising or
  177. X * publicity pertaining to distribution of the software without specific,
  178. X * written prior permission.  M.I.T. makes no representations about the
  179. X * suitability of this software for any purpose.  It is provided "as is"
  180. X * without express or implied warranty.
  181. X *
  182. X * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  183. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  184. X * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  185. X * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  186. X * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  187. X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  188. X *
  189. X * Author:  Davor Matic, MIT X Consortium
  190. X */
  191. X
  192. X#include <xod.h>
  193. X#include <X11/Xaw/Dialog.h>
  194. X#include <X11/Xaw/Command.h>
  195. X#include <X11/Xmu/CharSet.h>
  196. X#include <Dialog.h>
  197. X#include <xod.pt>
  198. X
  199. X#define min(x, y)                     (((x) < (y)) ? (x) : (y))
  200. X#define max(x, y)                     (((x) > (y)) ? (x) : (y))
  201. X
  202. Xvoid SetDialogButton();
  203. X
  204. Xstatic XtActionsRec actions_table[] = {
  205. X  {"set-dialog-button", SetDialogButton},
  206. X};
  207. X
  208. Xstatic DialogButton dialog_buttons[] = {
  209. X    {"yes", Yes},
  210. X    {"no", No},
  211. X    {"maybe", Maybe},
  212. X    {"okay", Okay},
  213. X    {"abort", Abort},
  214. X    {"cancel", Cancel},
  215. X    {"retry", Retry},
  216. X};
  217. X
  218. Xstatic unsigned long selected;
  219. X
  220. X/* ARGSUSED */
  221. Xvoid SetSelected(w, clientData, callData) /* ARGSUSED */
  222. X     Widget w;
  223. X     XtPointer clientData, callData;
  224. X{
  225. X    String name = (String)clientData;
  226. X    int i;
  227. X    
  228. X    for (i = 0; i < XtNumber(dialog_buttons); i++) 
  229. X    if (!strcmp(dialog_buttons[i].name, name)) 
  230. X        selected |= dialog_buttons[i].flag;
  231. X}
  232. X
  233. X/* ARGSUSED */
  234. Xvoid SetDialogButton(w, event, argv, argc)
  235. X     Widget w;         /* not used */
  236. X     XEvent *event;    /* not used */
  237. X     String *argv;
  238. X     Cardinal *argc;  
  239. X{
  240. X  char button_name[80];
  241. X  XtPointer dummy = NULL;
  242. X  int i;
  243. X
  244. X  for (i = 0; i < *argc; i++) {
  245. X    XmuCopyISOLatin1Lowered (button_name, argv[i]);
  246. X    SetSelected(w, button_name, dummy);
  247. X  }
  248. X}
  249. X
  250. Xstatic Boolean firstTime = True;
  251. X
  252. XDialog CreateDialog(top_widget, name, options)
  253. X     Widget top_widget;
  254. X     String name;
  255. X     unsigned long options;
  256. X{
  257. X    int i;
  258. X    Dialog popup;
  259. X
  260. X    popup = (Dialog) XtMalloc(sizeof(_Dialog));
  261. X
  262. X    if (popup) {
  263. X        if (firstTime) {
  264. X      XtAddActions(actions_table, XtNumber(actions_table));
  265. X      firstTime = False;
  266. X    }
  267. X    popup->top_widget = top_widget;
  268. X    popup->shell_widget = XtCreatePopupShell(name, 
  269. X                         transientShellWidgetClass, 
  270. X                         top_widget, NULL, 0);
  271. X    popup->dialog_widget = XtCreateManagedWidget("dialog", 
  272. X                             dialogWidgetClass,
  273. X                             popup->shell_widget, 
  274. X                             NULL, 0);
  275. X    for (i = 0; i < XtNumber(dialog_buttons); i++)
  276. X        if (options & dialog_buttons[i].flag)
  277. X        XawDialogAddButton(popup->dialog_widget, 
  278. X                   dialog_buttons[i].name, 
  279. X                   SetSelected, dialog_buttons[i].name);
  280. X    popup->options = options;
  281. X    return popup;
  282. X    }
  283. X    else
  284. X    return NULL;
  285. X}
  286. X
  287. Xvoid PopdownDialog(popup, answer)
  288. X    Dialog popup;
  289. X    String *answer;
  290. X{
  291. X    if (answer)
  292. X    *answer = XawDialogGetValueString(popup->dialog_widget);
  293. X    
  294. X    XtPopdown(popup->shell_widget);
  295. X}
  296. X
  297. Xunsigned long PopupDialog(popup, message, suggestion, answer, grab)
  298. X    Dialog popup;
  299. X    String message, suggestion, *answer;
  300. X    XtGrabKind grab;
  301. X{
  302. X  Position popup_x, popup_y, top_x, top_y;
  303. X  Dimension popup_width, popup_height, top_width, top_height, border_width;
  304. X  int n;
  305. X  Arg wargs[4];
  306. X
  307. X  n = 0;
  308. X  XtSetArg(wargs[n], XtNlabel, message); n++;
  309. X  XtSetArg(wargs[n], XtNvalue, suggestion); n++;
  310. X  XtSetValues(popup->dialog_widget, wargs, n);
  311. X
  312. X  XtRealizeWidget(popup->shell_widget);
  313. X  PositionPopupDialog(popup->top_widget, popup->shell_widget, &popup_width,
  314. X      &popup_height);
  315. X
  316. X  selected = None;
  317. X
  318. X  XtPopup(popup->shell_widget, grab);
  319. X  XWarpPointer(XtDisplay(popup->shell_widget), 
  320. X           XtWindow(popup->top_widget),
  321. X           XtWindow(popup->shell_widget), 
  322. X           0, 0, top_width, top_height,
  323. X           popup_width / 2, popup_height / 2);
  324. X
  325. X  while ((selected & popup->options) == None) {
  326. X      XEvent event;
  327. X      XtNextEvent(&event);
  328. X      XtDispatchEvent(&event);
  329. X  }
  330. X
  331. X  PopdownDialog(popup, answer);
  332. X
  333. X  return (selected & popup->options);
  334. X}
  335. X
  336. Xvoid
  337. XPositionPopup(Widget top, Widget popup) {
  338. X    Dimension w, h;
  339. X
  340. X    PositionPopupDialog(top, popup, &w, &h);
  341. X}
  342. X
  343. Xvoid
  344. XPositionPopupDialog(Widget top_widget, Widget shell_widget, Dimension *width,
  345. X  Dimension *height) {
  346. X  Position popup_x, popup_y, top_x, top_y;
  347. X  Dimension popup_width, popup_height, top_width, top_height, border_width;
  348. X  int n;
  349. X  Arg wargs[20];
  350. X
  351. X  n = 0;
  352. X  XtSetArg(wargs[n], XtNx, &top_x); n++;
  353. X  XtSetArg(wargs[n], XtNy, &top_y); n++;
  354. X  XtSetArg(wargs[n], XtNwidth, &top_width); n++;
  355. X  XtSetArg(wargs[n], XtNheight, &top_height); n++;
  356. X  XtGetValues(top_widget, wargs, n);
  357. X
  358. X  n = 0;
  359. X  XtSetArg(wargs[n], XtNwidth, &popup_width); n++;
  360. X  XtSetArg(wargs[n], XtNheight, &popup_height); n++;
  361. X  XtSetArg(wargs[n], XtNborderWidth, &border_width); n++;
  362. X  XtGetValues(shell_widget, wargs, n);
  363. X  *width = popup_width;
  364. X  *height = popup_height;
  365. X
  366. X  popup_x = max(0, 
  367. X    min(top_x + ((Position)top_width - (Position)popup_width) / 2, 
  368. X        (Position)DisplayWidth(XtDisplay(shell_widget), 
  369. X           DefaultScreen(XtDisplay(shell_widget))) -
  370. X        (Position)popup_width - 2 * (Position)border_width));
  371. X  popup_y = max(0, 
  372. X    min(top_y + ((Position)top_height - (Position)popup_height) / 2,
  373. X        (Position)DisplayHeight(XtDisplay(shell_widget), 
  374. X            DefaultScreen(XtDisplay(shell_widget))) -
  375. X        (Position)popup_height - 2 * (Position)border_width));
  376. X  n = 0;
  377. X  XtSetArg(wargs[n], XtNx, popup_x); n++;
  378. X  XtSetArg(wargs[n], XtNy, popup_y); n++;
  379. X  XtSetValues(shell_widget, wargs, n);
  380. X}
  381. SHAR_EOF
  382. chmod 0644 Dialog.c || echo "restore of Dialog.c fails"
  383. set `wc -c Dialog.c`;Sum=$1
  384. if test "$Sum" != "6532"
  385. then echo original size 6532, current size $Sum;fi
  386. echo "x - extracting Dialog.h (Text)"
  387. sed 's/^X//' << 'SHAR_EOF' > Dialog.h &&
  388. X/*
  389. X * $XConsortium: Dialog.h,v 1.5 91/02/22 18:20:14 converse Exp $
  390. X *
  391. X * Copyright 1989 Massachusetts Institute of Technology
  392. X *
  393. X * Permission to use, copy, modify, distribute, and sell this software and its
  394. X * documentation for any purpose is hereby granted without fee, provided that
  395. X * the above copyright notice appear in all copies and that both that
  396. X * copyright notice and this permission notice appear in supporting
  397. X * documentation, and that the name of M.I.T. not be used in advertising or
  398. X * publicity pertaining to distribution of the software without specific,
  399. X * written prior permission.  M.I.T. makes no representations about the
  400. X * suitability of this software for any purpose.  It is provided "as is"
  401. X * without express or implied warranty.
  402. X *
  403. X * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  404. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  405. X * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  406. X * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  407. X * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  408. X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  409. X *
  410. X * Author:  Davor Matic, MIT X Consortium
  411. X */
  412. X
  413. X
  414. X#ifndef _DIALOG_H
  415. X#define _DIALOG_H
  416. X
  417. X/*#define None   0*/
  418. X#define Yes    1<<1
  419. X#define No     1<<2
  420. X#define Maybe  1<<3  /* :-) */
  421. X#define Okay   1<<4
  422. X#define Abort  1<<5
  423. X#define Cancel 1<<6
  424. X#define Retry  1<<7
  425. X
  426. Xtypedef struct {
  427. X  Widget top_widget, shell_widget, dialog_widget;
  428. X  unsigned long options;
  429. X} _Dialog, *Dialog;
  430. X
  431. Xtypedef struct {
  432. X    String name;
  433. X    unsigned long flag;
  434. X} DialogButton;
  435. X#endif
  436. SHAR_EOF
  437. chmod 0644 Dialog.h || echo "restore of Dialog.h fails"
  438. set `wc -c Dialog.h`;Sum=$1
  439. if test "$Sum" != "1669"
  440. then echo original size 1669, current size $Sum;fi
  441. echo "x - extracting Imakefile (Text)"
  442. sed 's/^X//' << 'SHAR_EOF' > Imakefile &&
  443. X# $Id: Imakefile,v 1.5 1993/02/16 23:12:44 rfs Exp rfs $
  444. X#
  445. X# $Log: Imakefile,v $
  446. X# Revision 1.5  1993/02/16  23:12:44  rfs
  447. X# *** empty log message ***
  448. X#
  449. X# Revision 1.4  1993/02/14  01:14:04  rfs
  450. X# Added dependencies for headers
  451. X#
  452. X# Revision 1.3  1993/02/13  23:48:36  rfs
  453. X# Enhanced "tar" target.
  454. X#
  455. X# Revision 1.2  1993/02/13  14:33:11  rfs
  456. X# use shared libs
  457. X#
  458. X# Revision 1.1  1993/02/13  12:28:22  rfs
  459. X# Initial revision
  460. X#
  461. X#
  462. X# Makefile for xod
  463. X
  464. XLDOPTIONS = -lXaw -lXmu -lXext -lXt -lX11 -lm -lXext
  465. X
  466. XCC = gcc -pipe -I.
  467. XPROG = xod
  468. X
  469. XHEADERS    = ctw.h ctwP.h Dialog.h buttons.h defines.h gvars.h gwidgets.h \
  470. X    keys.h version.h xod.h buttonndx.h xod.pt
  471. XSRCS = main.c rotate.c ctw.c xutils.c \
  472. X    Dialog.c keyhandler.c helpdialog.c byteaddress.c decode.c \
  473. X    utils.c fileio.c cmdline.c mkwidgets.c getres.c
  474. XOBJS = main.o rotate.o ctw.o xutils.o \
  475. X    Dialog.o keyhandler.o helpdialog.o byteaddress.o decode.o \
  476. X    utils.o fileio.o cmdline.o mkwidgets.o getres.o
  477. X
  478. XAllTarget($(PROG))
  479. XComplexProgramTarget($(PROG))
  480. X
  481. Xctw.o: ctw.h
  482. Xcmdline.o: defines.h
  483. Xdecode.o: defines.h
  484. Xkeyhandler.o: defines.h
  485. Xmain.o: defines.h buttons.h version.h
  486. Xmkwidgets.o: buttons.h
  487. X
  488. Xproto:
  489. X    mkptypes -p _P_XOD $(SRCS) > xod.pt
  490. X
  491. Xbackup::
  492. X    cp *.c *.h Makefile backup
  493. X
  494. Xtar:
  495. X    -rm core
  496. X    $(MAKE) getapp-def
  497. X    (cd ..; tar cvf /dev/fd0H1440 xod)
  498. X
  499. X# install the app-defaults file
  500. Xapp-def:
  501. X    cp Xod.ad /usr/X386/lib/X11/app-defaults/Xod
  502. X
  503. Xshar::
  504. X    shar README frowny.xbm Imakefile xod.1 Xod.ad $(SRCS) $(HEADERS) > xod.shar
  505. SHAR_EOF
  506. chmod 0644 Imakefile || echo "restore of Imakefile fails"
  507. set `wc -c Imakefile`;Sum=$1
  508. if test "$Sum" != "1465"
  509. then echo original size 1465, current size $Sum;fi
  510. echo "x - extracting README (Text)"
  511. sed 's/^X//' << 'SHAR_EOF' > README &&
  512. X=================================== XOD =================================
  513. X
  514. XPlease read this whole file before trying to make this program.  Some
  515. Xof what is said herein just may be important..... and you might not
  516. Xgive up on it if you realize the minor caveats.  If nothing else,
  517. Xsearch for IMPORTANT in this document.
  518. X
  519. XRelease
  520. X-------
  521. XThis is the first release of xod (xod 1.01).
  522. X
  523. XXod is an X-based "octal" dump program.  Like the Unix-supplied od(1),
  524. Xyou are not limited to octal displays.  You can view your data in
  525. Xhex, octal, decimal, or ASCII as well.  Not only that (which isn't all
  526. Xthat earth-shattering), you can click on a byte, and decode it and the
  527. Xbytes that follow in a variety of formats, search for strings, move
  528. Xbackwards and forwards in the file, and lots more.
  529. X
  530. XLike some mainframe data dumpers, you see your binary data in your
  531. Xselected format on one side of the screen, and in ASCII on the other.
  532. XBut with xod, you are a key (or mouse) stroke away from viewing your
  533. Xdata in one of 4 formats (hex, octal, decimal, or ASCII).
  534. X
  535. Xxod uses the Athena widget set for portability.
  536. XIn a lot of ways, it is like running less, vi, or emacs on a binary file
  537. X(except that you can't edit it).  But you can search for  strings,
  538. Xnumbers, etc., decode any byte pointed to, and much other stuff.  See the
  539. Xman page for full details.
  540. X
  541. Xxod was developed on a 486 running Linux, and tested there and on a
  542. XSun.  Both were running X11R5, but is should run under R4.
  543. X
  544. XBuilding
  545. X--------
  546. XShould be fairly easy:
  547. X
  548. X    xmkmf
  549. X    make
  550. X
  551. XIf this doesn't work, the files used by imake (run by xmkmf) may
  552. Xbe wrong.  Have your sysadmin fix the appropriate files.
  553. X
  554. X*IMPORTANT*
  555. XTo install, you need to install Xod.ad as Xod in your app-defaults
  556. Xarea.  You may need a sysadmin to do this.  If you don't do this,
  557. Xxod will look stupid when it is run. And you will have to copy
  558. Xxod to your area for binaries (a sysadmin will probably have to do
  559. Xthis as well).
  560. X
  561. X*IMPORTANT*
  562. XNOTE: this code is ANSI-C, so you may need to modify the CC line
  563. Xin the Imakefile before running xmkmf.  Use gcc if your company is too
  564. Xcheap to buy an ASNI compiler (in 1993?).  Otherwise, perhaps you
  565. Xcan use one of the public domain de-prototypers.
  566. X
  567. X*IMPORTANT*
  568. XIf keys don't work as advertized, some of the key mappings may be wrong
  569. X(mainly PgUp, PgDn, Home, and End).  This has been tested on a Sun, and
  570. Xa 486 under Linux,  and there are proper key mappings for them.  Check
  571. Xout keys.h, and modify if required.  If you get proper mappings for other
  572. Xmachines, please email them to me.
  573. X
  574. XBefore running xod
  575. X------------------
  576. XEnsure that Xod.ad (included with this distribution) is installed in
  577. Xan app-defaults as Xod.  Otherwise, the screen display will be pretty
  578. Xfunky.
  579. X
  580. XAuthor(s)
  581. X---------
  582. Xxod was written by RF Starr (starr@wg2.waii.com).  It makes use of
  583. XPaul Fox's wonderful CTW widget.  The CTW widget is a color terminal widget,
  584. Xallowing a text-like widget with multiple colors, and easy cursor manipulation.
  585. XMuch of the dialog box stuff was ripped out of the X11R5 bitmap program.
  586. X
  587. XDisclaimer
  588. X----------
  589. XThis software is provided as-is.  There are no guarantees of any kind.
  590. XUse at your own risk.  Don't smoke in bed.
  591. X
  592. XThis software is free, with no obligations whatsoever, except possibly
  593. Xthose imposed by the authors of chunks of code used herein.
  594. X
  595. XPlease report bugs to the author, and please do not distribute hacked up
  596. Xversions of the source without my permission.  Suggest improvements to
  597. Xthe author (especially minor mods to the keys.h file to get it to work on
  598. Xother machines).
  599. SHAR_EOF
  600. chmod 0644 README || echo "restore of README fails"
  601. set `wc -c README`;Sum=$1
  602. if test "$Sum" != "3541"
  603. then echo original size 3541, current size $Sum;fi
  604. echo "x - extracting Xod.ad (Text)"
  605. sed 's/^X//' << 'SHAR_EOF' > Xod.ad &&
  606. X! You can muck with these
  607. X*font: -*-fixed-bold-*-*-*-14*
  608. X*MenuButton.background: blue
  609. X*MenuButton.foreground: white
  610. X*Label.background: yellow
  611. X*labelHelp.background: LightBlue
  612. X*Command.background: pink
  613. X*Form.background: Light Gray
  614. X*vt100.rows: 16
  615. X*vt100.columns: 84
  616. X*cursorFg: black
  617. X*cursorBg: green
  618. X*cursorColor: black
  619. X
  620. X!!!!!!!!!!!!!!!!!!!!! DON'T MESS WITH THESE !!!!!!!!!!!!!!!!!!!
  621. X! But you shouldn't change these!!!
  622. X*TransientShell.allowShellResize: True
  623. X*baseTranslations:#override\
  624. X            <Key>Return:    set-dialog-button(okay, yes, retry)
  625. X*shapeStyle: oval
  626. X*pane.orientation: horizontal
  627. X*helpOK*top: ChainTop
  628. X*helpOK*bottom: ChainTop
  629. X*helpOK*left: ChainLeft
  630. X*helpOK*right: ChainLeft
  631. X
  632. X*formy.status*top: ChainTop
  633. X*formy.status*bottom: ChainTop
  634. X*formy.status*left: ChainLeft
  635. X*formy.status*right: ChainRight
  636. X*formy*File*left: ChainLeft
  637. X*formy*menu*width: 40
  638. X*status.fromHoriz: File
  639. X*decode.fromHoriz: status
  640. X*byteoffset.fromHoriz: decode
  641. X*form*width: 80
  642. X*form*height: 15
  643. X
  644. X*File.top: ChainTop
  645. X*File.bottom: ChainTop
  646. X*File.left: ChainLeft
  647. X*File.right: ChainLeft
  648. X
  649. X*status*top: ChainTop
  650. X*status*bottom: ChainTop
  651. X*status*left: ChainLeft
  652. X*status*right: ChainLeft
  653. X
  654. X*byteoffset*top: ChainTop
  655. X*byteoffset*bottom: ChainTop
  656. X*byteoffset*left: ChainRight
  657. X*byteoffset*right: ChainRight
  658. X
  659. X*decode*top: ChainTop
  660. X*decode*bottom: ChainTop
  661. X*decode*left: ChainRight
  662. X*decode*right: ChainRight
  663. X*decode*label:
  664. X
  665. X*form.Octal.fromVert: Hex
  666. X*form.Decimal.fromVert: Octal
  667. X*form.ASCII.fromVert: Decimal
  668. X*form.Short.vertDistance: 15
  669. X*form.Short.fromVert: ASCII
  670. X*form.uShort.fromVert: Short
  671. X*form.Long.fromVert: uShort
  672. X*form.uLong.fromVert: Long
  673. X*form.Float.fromVert: uLong
  674. X*form.Double.fromVert: Float
  675. X! *form.HpR4.fromVert: Double
  676. X! *form.HpR6.fromVert: HpR4
  677. SHAR_EOF
  678. chmod 0644 Xod.ad || echo "restore of Xod.ad fails"
  679. set `wc -c Xod.ad`;Sum=$1
  680. if test "$Sum" != "1727"
  681. then echo original size 1727, current size $Sum;fi
  682. echo "x - extracting buttonndx.h (Text)"
  683. sed 's/^X//' << 'SHAR_EOF' > buttonndx.h &&
  684. X#define New 101
  685. X#define Quit 102
  686. X
  687. X#define Hex 0
  688. X#define Octal 1
  689. X#define Decimal 2
  690. X#define Ascii 3
  691. X
  692. X#define Short 5
  693. X#define uShort 6
  694. X#define Long 7
  695. X#define uLong 8
  696. X#define Float 9
  697. X#define Double 10
  698. X#define HPR4 11
  699. X#define HPR6 12
  700. SHAR_EOF
  701. chmod 0644 buttonndx.h || echo "restore of buttonndx.h fails"
  702. set `wc -c buttonndx.h`;Sum=$1
  703. if test "$Sum" != "229"
  704. then echo original size 229, current size $Sum;fi
  705. echo "x - extracting buttons.h (Text)"
  706. sed 's/^X//' << 'SHAR_EOF' > buttons.h &&
  707. X#include <buttonndx.h>
  708. X
  709. Xtypedef struct {
  710. X  int             id;
  711. X  String          name;
  712. X  Boolean         trap;
  713. X  Widget          widget;
  714. X} ButtonRec, *ButtonPtr;
  715. X
  716. X/* for the File menu */
  717. Xstatic ButtonRec file_menu[] = {
  718. X  {New, "new", True},
  719. X  {Quit, "quit", True},
  720. X};
  721. X
  722. Xstatic ButtonRec buttonsMode[] = {
  723. X  {Hex, "Hex", False},
  724. X  {Octal, "Octal", False},
  725. X  {Decimal, "Decimal", False},
  726. X  {Ascii, "ASCII", False},
  727. X};
  728. X
  729. Xstatic ButtonRec buttonsDecode[] = {
  730. X  {Short, "Short", False},
  731. X  {uShort, "uShort", False},
  732. X  {Long, "Long", False},
  733. X  {uLong, "uLong", False},
  734. X  {Float, "Float", False},
  735. X  {Double, "Double", False},
  736. X  {HPR4, "HpR4", False},
  737. X  {HPR6, "HpR6", False},
  738. X};
  739. SHAR_EOF
  740. chmod 0644 buttons.h || echo "restore of buttons.h fails"
  741. set `wc -c buttons.h`;Sum=$1
  742. if test "$Sum" != "671"
  743. then echo original size 671, current size $Sum;fi
  744. echo "x - extracting byteaddress.c (Text)"
  745. sed 's/^X//' << 'SHAR_EOF' > byteaddress.c &&
  746. Xstatic char *RcsId = "$Id: byteaddress.c,v 1.2 1993/02/13 18:43:58 rfs Exp rfs $";
  747. X
  748. X/*
  749. X * $Log: byteaddress.c,v $
  750. X * Revision 1.2  1993/02/13  18:43:58  rfs
  751. X * *** empty log message ***
  752. X *
  753. X * Revision 1.1  1993/02/13  02:20:18  rfs
  754. X * Initial revision
  755. X *
  756. X * Revision 1.1  1993/02/13  02:20:18  rfs
  757. X * Initial revision
  758. X *
  759. X*/
  760. X
  761. X#include "defines.h"
  762. X#include "gvars.h"
  763. X#include "gwidgets.h"
  764. X#include <stdio.h>
  765. X#include <malloc.h>
  766. X
  767. Xstatic char *fmts[] = {
  768. X    "%06x\n",
  769. X    "%06o\n",
  770. X    "%06d\n",
  771. X};
  772. Xstatic char *offsetbuf = NULL;
  773. X
  774. Xvoid
  775. XSetAddressMode(int mode) {
  776. X    OffsetMode = mode;
  777. X    OffsetFmt = fmts[mode];
  778. X}
  779. X
  780. Xchar *
  781. XFmtOffset(long addr) {
  782. X    static char buffer[MAXLEN];
  783. X
  784. X    sprintf(buffer, OffsetFmt, addr);
  785. X    return buffer;
  786. X}
  787. X
  788. Xvoid
  789. XShowByteAddress(long startaddr) {
  790. X    char buffer[128];
  791. X    int addr = startaddr;
  792. X    int i;
  793. X
  794. X    if (!offsetbuf) {
  795. X        offsetbuf = (char *)malloc(NumberRows*(6+2));
  796. X    }
  797. X    if (!OffsetFmt) {
  798. X        OffsetMode = 0;
  799. X        OffsetFmt = fmts[0];
  800. X    }
  801. X    *offsetbuf = (int)NULL;
  802. X    for (i=0; i < NumberRows; i++) {
  803. X        sprintf(buffer, OffsetFmt, addr);
  804. X        strcat(offsetbuf, buffer);
  805. X        addr += BytesHoriz;
  806. X    }
  807. X    SetWidgetLabel(ByteAddress, offsetbuf);
  808. X}
  809. SHAR_EOF
  810. chmod 0644 byteaddress.c || echo "restore of byteaddress.c fails"
  811. set `wc -c byteaddress.c`;Sum=$1
  812. if test "$Sum" != "1128"
  813. then echo original size 1128, current size $Sum;fi
  814. echo "x - extracting cmdline.c (Text)"
  815. sed 's/^X//' << 'SHAR_EOF' > cmdline.c &&
  816. Xstatic char *RcsID = "$Id: cmdline.c,v 1.3 1993/03/02 00:44:36 rfs Exp $";
  817. X
  818. X/*
  819. X * $Log: cmdline.c,v $
  820. X * Revision 1.3  1993/03/02  00:44:36  rfs
  821. X * Enhanced for release.
  822. X *
  823. X * Revision 1.2  1993/02/13  14:34:03  rfs
  824. X * *** empty log message ***
  825. X *
  826. X * Revision 1.1  1993/02/13  02:20:18  rfs
  827. X * Initial revision
  828. X *
  829. X * Revision 1.1  1993/02/13  02:20:18  rfs
  830. X * Initial revision
  831. X *
  832. X*/
  833. X
  834. X#include <xod.h>
  835. X#include <xod.pt>
  836. X
  837. Xstatic int offsetType = HEX;
  838. Xstatic int gotoOffset = 0;
  839. X
  840. Xvoid
  841. XCmdLineInit(void) {
  842. X    UpdateAll(offsetType, GetDataOffset());
  843. X    CursorToAbsByte(gotoOffset);
  844. X}
  845. X
  846. X/* print usage summary */
  847. Xstatic void
  848. XUsage() {
  849. X    fprintf(stderr, "Usage: xod [-options] filename\n");
  850. X}
  851. X
  852. X/* pares the command line */
  853. Xvoid
  854. XParseCommandLine(int argc, char **argv) {
  855. X    char *program, *title, *filename;
  856. X
  857. X    program = *argv;
  858. X    argv++;
  859. X    if (! *argv) {
  860. X        Usage();
  861. X        exit(1);
  862. X    }
  863. X    while (*argv) {
  864. X        char *arg = *argv;
  865. X        char *next;
  866. X        if (!strcmp(arg, "-v")) {
  867. X            printf("%s\n", XodVersion());
  868. X            exit(0);
  869. X        }
  870. X        else if (!strcmp(arg, "-x"))
  871. X            DataMode = HEX;
  872. X        else if (!strcmp(arg, "-o"))
  873. X            DataMode = OCTAL;
  874. X        else if (!strcmp(arg, "-d"))
  875. X            DataMode = DECIMAL;
  876. X        else if (!strcmp(arg, "-a"))
  877. X            DataMode = ASCII;
  878. X        /* change offset display format from hex default */
  879. X        else if (!strcmp(arg, "-odf")) {
  880. X            argv++;
  881. X            if (*(*argv) == 'o') {
  882. X                offsetType = OCTAL;
  883. X            }
  884. X            else if (*(*argv) == 'd') {
  885. X                offsetType = DECIMAL;
  886. X            }
  887. X            else if (*(*argv) == 'h') {
  888. X                offsetType = HEX;
  889. X            }
  890. X        }
  891. X        else if (!strcmp(arg, "-off")) {
  892. X            argv++;
  893. X            gotoOffset = AddressConvert(*argv);
  894. X        }
  895. X        else if (!strncmp(arg, "-", 1))
  896. X            ;
  897. X        else
  898. X            filename = arg;
  899. X        argv++;
  900. X    }
  901. X    if (!FileOpen(filename)) {
  902. X        fprintf(stderr, "Error trying to open %s for reading\n", filename);
  903. X        exit(1);
  904. X    }
  905. X}
  906. SHAR_EOF
  907. chmod 0644 cmdline.c || echo "restore of cmdline.c fails"
  908. set `wc -c cmdline.c`;Sum=$1
  909. if test "$Sum" != "1758"
  910. then echo original size 1758, current size $Sum;fi
  911. echo "x - extracting ctw.c (Text)"
  912. sed 's/^X//' << 'SHAR_EOF' > ctw.c &&
  913. Xstatic char *RcsID = "$Id: ctw.c,v 1.1 1993/02/13 18:39:38 rfs Exp rfs $";
  914. X/*
  915. X * $Log: ctw.c,v $
  916. X * Revision 1.1  1993/02/13  18:39:38  rfs
  917. X * Initial revision
  918. X *
  919. X *
  920. X*/
  921. X
  922. X/**********************************************************************/
  923. X/*                                                                    */
  924. X/*  File:          ctw.c                                              */
  925. X/*  Author:        P. D. Fox                                          */
  926. X/*  Created:       25 Nov 1991                                   */
  927. X/*                                                                    */
  928. X/*  Copyright (c) 1990, 1991, 1992 Paul Fox                           */
  929. X/*                All Rights Reserved.                                */
  930. X/*                                                                    */
  931. X/*                                                                    */
  932. X/*--------------------------------------------------------------------*/
  933. X/*  Description:  Color terminal widget.                              */
  934. X/*                                                                    */
  935. X/*   Sequences supported:                          */
  936. X/*                                         */
  937. X/*   ESC 7    Save cursor position                      */
  938. X/*   ESC 8    Restore cursor position                   */
  939. X/*   ESC c    Reset terminal                          */
  940. X/*   ESC D    Index (down cursor or scroll).                       */
  941. X/*   ESC M    Reverse index (up cursor or insline).             */
  942. X/*   ESC Z    Identify terminal.                        */
  943. X/*   ESC >    Numeric keypad                          */
  944. X/*   ESC =    Application keypad                        */
  945. X/*   ^H        Backspace                          */
  946. X/*   ^I        Tabs (fixed-width -- 8 chars wide).              */
  947. X/*   ^J        Line feed                          */
  948. X/*   ^L        Clear screen.                          */
  949. X/*   ^M     Carriage return                       */
  950. X/*   ESC ( 0      Graphics char set.                        */
  951. X/*   ESC ) 0      Graphics char set.                        */
  952. X/*   ESC ( B      Normal character set.                     */
  953. X/*   ESC [ 0m    Reset attributes.                                        */
  954. X/*   ESC [ 1m    Bold                                                     */
  955. X/*   ESC [ 4m    Underline                                                */
  956. X/*   ESC [ 7m    Reverse video.                                           */
  957. X/*   ESC [ 3Xm    Set foreground color.                                      */
  958. X/*   ESC [ 4Xm    Set background color.                                      */
  959. X/*   ESC [ n @    Insert characters.                        */
  960. X/*   ESC [ n A    Move cursor up                          */
  961. X/*   ESC [ n B    Move cursor down                      */
  962. X/*   ESC [ n C    Move cursor right                         */
  963. X/*   ESC [ n D    Move cursor left                      */
  964. X/*   ESC [ n ; m H                              */
  965. X/*        Move cursor to absolute position.              */
  966. X/*   ESC [ n L    Insert lines at current row                   */
  967. X/*   ESC [ n M    Delete lines at current row                   */
  968. X/*   ESC [ n ; m r    Set scrolling region.                  */
  969. X/*   ESC [ n P    Delete characters.                            */
  970. X/*   ESC [ S    Index (down cursor or scroll).                       */
  971. X/*   ESC [ T    Reverse index (up cursor or insline).             */
  972. X/*   ESC [ n X    Erase to blank (no cursor move)               */
  973. X/*   ESC [ n g    Print ASCII char 'n' (SCO mode only)              */
  974. X/*   ESC [n;m r    Set scrolling region to lines n..m.               */
  975. X/*   ESC [ n t    Shelltool/cmdtool compatable escape sequence          */
  976. X/*           ESC [1t    Open window.                      */
  977. X/*           ESC [2t    Iconise window.                      */
  978. X/*           ESC [3t    Move window.                      */
  979. X/*           ESC [4t    Change size (in pixels) window.              */
  980. X/*           ESC [5t    Raise window.                      */
  981. X/*           ESC [6t    Lower window.                      */
  982. X/*                                         */
  983. X/*   ESC [ ? 1 h    Application cursor keys                  */
  984. X/*   ESC [ ? 4 h    Set smooth scroll mode.                  */
  985. X/*   ESC [ ? 7 h    Set autowrap                             */
  986. X/*   ESC [ ? 47 h    Use alternate screen buffer.                     */
  987. X/*   ESC [ ? 1962 h    Turn on application mouse.                       */
  988. X/*                                         */
  989. X/*   ESC [ ? 1 l    Normal cursor keys                  */
  990. X/*   ESC [ ? 4 l    Set jump scroll mode.                  */
  991. X/*   ESC [ ? 7 l    Disable autowrap                         */
  992. X/*   ESC [ ? 47 l    Use normal screen buffer.                        */
  993. X/*   ESC [ ? 1962 l     Turn off application mouse.                      */
  994. X/*                                         */
  995. X/*   ESC [ ? r;c;h;w;n S Scroll rectangular region up or down n lines */
  996. X/*                                         */
  997. X/*                                         */
  998. X/*   Sequences reported:                          */
  999. X/*     ESC [ b; m; s; r; c M  Mouse position report                 */
  1000. X/*               b == Button being reported (1..3)          */
  1001. X/*               s == 0 button pressed                    */
  1002. X/*                 == 1 button released                   */
  1003. X/*                 == 2 button motion                     */
  1004. X/*                                         */
  1005. X/*               m == Modifier status as a set of bits         */
  1006. X/*                    0x01 Shift down                  */
  1007. X/*                    0x02 Ctrl down                   */
  1008. X/*                    0x04 Meta down                   */
  1009. X/*                                         */
  1010. X/*               r == current row (decimal 0..n)              */
  1011. X/*               c == current col (decimal 0..n)              */
  1012. X/*                                         */
  1013. X/**********************************************************************/
  1014. X
  1015. X/*static char sccs_id[] = "%Z% %M% %R%.%L%";*/
  1016. X
  1017. X/*# include     <X11/copyright.h>*/
  1018. X# include     <X11/IntrinsicP.h>
  1019. X# include     <X11/StringDefs.h>
  1020. X# include     <X11/Shell.h>
  1021. X# include    <X11/Xatom.h>
  1022. X# include    <signal.h>
  1023. X# include     "ctwP.h"
  1024. X/**********************************************************************/
  1025. X/*   Following  is  used  if  we  want  to  use my version of malloc  */
  1026. X/*   checking.                                  */
  1027. X/**********************************************************************/
  1028. X# if 0
  1029. X#     include    <chkalloc.h>
  1030. X# else
  1031. X#    define    chk_alloc    malloc
  1032. X#    define    chk_free    free
  1033. X# endif
  1034. X# include    <stdio.h>
  1035. X# include    <X11/keysym.h>
  1036. X# include    <ctype.h>
  1037. X# include    <memory.h>
  1038. X# include    <stdlib.h>
  1039. X# include    <string.h>
  1040. X
  1041. X# define    ROW_TO_PIXEL(w, r)    ((r) * w->ctw.font_height + w->ctw.fontp->ascent)
  1042. X# define    BLACK    0
  1043. X# define    WHITE    7
  1044. X
  1045. X# define    MAX_ARGS    32
  1046. X
  1047. X/**********************************************************************/
  1048. X/*   Default size of window if too small or not defined.          */
  1049. X/**********************************************************************/
  1050. X# define    DEFAULT_HEIGHT    (13 * 24)
  1051. X# define    DEFAULT_WIDTH    (7 * 80)
  1052. X# define    DEFAULT_FONT    XtDefaultFont
  1053. X
  1054. Xstatic int     default_rows = 24;
  1055. Xstatic int     default_columns = 80;
  1056. Xstatic int    default_max_lines = 512;
  1057. Xstatic Boolean    defaultFALSE = FALSE;
  1058. Xstatic int    default_flashrate = 500;
  1059. Xstatic int    default_multiClickTime = 250;
  1060. X
  1061. Xstatic XtResource resources[] = {
  1062. X#define offset(field) XtOffset(CtwWidget, ctw.field)
  1063. X    /* {name, class, type, size, offset, default_type, default_addr}, */
  1064. X    { XtNfont, XtCFont, XtRString, sizeof(char*),
  1065. X      offset(font), XtRString, "7x13bold"},
  1066. X    { XtNgeometry, XtCGeometry, XtRString, sizeof(char*),
  1067. X      offset(geometry), XtRString, ""},
  1068. X    { XtNcursorColor, XtCCursorColor, XtRPixel, sizeof(unsigned long),
  1069. X      offset(cursor_color), XtRString, "red"},
  1070. X    { XtNhiliteBackground, XtCHiliteBackground, XtRPixel, sizeof(unsigned long),
  1071. X      offset(hilite_bg), XtRString, "CadetBlue"},
  1072. X    { XtNhiliteForeground, XtCHiliteForeground, XtRPixel, sizeof(unsigned long),
  1073. X      offset(hilite_fg), XtRString, "yellow"},
  1074. X    { XtNrows, XtCRows, XtRInt, sizeof(int),
  1075. X      offset(rows), XtRInt, (char *) &default_rows},
  1076. X    { XtNcolumns, XtCColumns, XtRInt, sizeof(int),
  1077. X      offset(columns), XtRInt, (char *) &default_columns},
  1078. X    { XtNkbdCallback, XtCKbdCallback, XtRCallback, sizeof(caddr_t),
  1079. X      offset(kbd_callback), XtRCallback, (caddr_t) NULL},
  1080. X    { XtNresizeCallback, XtCResizeCallback, XtRCallback, sizeof(caddr_t),
  1081. X      offset(resize_callback), XtRCallback, (caddr_t) NULL},
  1082. X    { XtNtopCallback, XtCTopCallback, XtRCallback, sizeof(caddr_t),
  1083. X      offset(top_callback), XtRCallback, (caddr_t) NULL},
  1084. X    { XtNmouseCallback, XtCMouseCallback, XtRCallback, sizeof(caddr_t),
  1085. X      offset(mouse_callback), XtRCallback, (caddr_t) NULL},
  1086. X    { XtNapplCallback, XtCApplCallback, XtRCallback, sizeof(caddr_t),
  1087. X      offset(appl_callback), XtRCallback, (caddr_t) NULL},
  1088. X    { XtNtranslations, XtCTranslations, XtRTranslationTable, sizeof(char*),
  1089. X      offset(table), XtRString, ""},
  1090. X    { XtNsunFunctionKeys, XtCSunFunctionKeys, XtRBoolean, sizeof(Boolean),
  1091. X      offset(sun_function_keys), XtRBoolean, &defaultFALSE},
  1092. X    { XtNsaveLines, XtCSaveLines, XtRInt, sizeof(int),
  1093. X      offset(max_lines), XtRInt, (char *) &default_max_lines},
  1094. X    { XtNflashrate, XtCFlashrate, XtRInt, sizeof(int),
  1095. X      offset(flashrate), XtRInt, (char *) &default_flashrate},
  1096. X    { XtNfont1, XtCFont1, XtRString, sizeof(char *),
  1097. X      offset(font1), XtRString, "5x8"},
  1098. X    { XtNfont2, XtCFont2, XtRString, sizeof(char *),
  1099. X      offset(font2), XtRString, "6x9"},
  1100. X    { XtNfont3, XtCFont3, XtRString, sizeof(char *),
  1101. X      offset(font3), XtRString, "6x10"},
  1102. X    { XtNfont4, XtCFont4, XtRString, sizeof(char *),
  1103. X      offset(font4), XtRString, "6x13"},
  1104. X    { XtNfont5, XtCFont5, XtRString, sizeof(char *),
  1105. X      offset(font5), XtRString, "7x13bold"},
  1106. X    { XtNfont6, XtCFont6, XtRString, sizeof(char *),
  1107. X      offset(font6), XtRString, "8x13bold"},
  1108. X    { XtNmultiClickTime, XtCMultiClickTime, XtRInt, sizeof(int),
  1109. X      offset(multiClickTime), XtRInt, (char *) &default_multiClickTime},
  1110. X#undef offset
  1111. X};
  1112. X
  1113. Xstatic void    initialize();
  1114. Xstatic void    realize();
  1115. Xstatic void    Destroy();
  1116. Xstatic void    Resize();
  1117. Xstatic void    redisplay();
  1118. Xstatic Boolean    Set_values();
  1119. Xvoid    HandleFocusChange();
  1120. X
  1121. Xstatic void CtwInput(/* Widget, XEvent*, String*, Cardinal* */);
  1122. Xstatic void CtwSelectStart(/* Widget, XEvent*, String*, Cardinal* */);
  1123. Xstatic void CtwSelectExtend(/* Widget, XEvent*, String*, Cardinal* */);
  1124. Xstatic void CtwSelectEnd(/* Widget, XEvent*, String*, Cardinal* */);
  1125. Xstatic void CtwString(/* Widget, XEvent*, String*, Cardinal* */);
  1126. Xstatic void CtwExpose(/* Widget, XEvent*, String*, Cardinal* */);
  1127. Xstatic void CtwButtonDown(/* Widget, XEvent*, String*, Cardinal* */);
  1128. Xstatic void CtwButtonUp(/* Widget, XEvent*, String*, Cardinal* */);
  1129. Xstatic void CtwButtonMotion(/* Widget, XEvent*, String*, Cardinal* */);
  1130. Xstatic void CtwInsertSelection(/* Widget, XEvent*, String*, Cardinal* */);
  1131. X
  1132. Xstatic void    application_mouse PROTO((CtwWidget, int, int, XEvent *, int, int));
  1133. Xstatic void    ctw_add_string2 PROTO((CtwWidget, char *, int));
  1134. Xstatic int    compute_length PROTO((CtwWidget, int, int, int));
  1135. Xstatic void    cursor_flash_proc();
  1136. Xstatic void    convert_click PROTO((CtwWidget));
  1137. Xstatic void    reset_screen PROTO((CtwWidget));
  1138. Xstatic void    alloc_screen PROTO((CtwWidget, int));
  1139. Xstatic int    setup_x11_colors PROTO((Display *));
  1140. Xstatic void    exposed_region PROTO((CtwWidget, int, int, int, int));
  1141. Xstatic void    update_region PROTO((CtwWidget, int, int, int, int));
  1142. Xstatic void    print_string PROTO((CtwWidget, int, int, int, vbyte_t *));
  1143. Xstatic void    show_cursor PROTO((CtwWidget));
  1144. Xstatic void    draw_string PROTO((CtwWidget, int, int, char *, int, Pixel, Pixel, int));
  1145. Xstatic void    draw_line PROTO((CtwWidget, int, int, unsigned char *, int, Pixel, Pixel, int));
  1146. Xstatic int    reset_font PROTO((CtwWidget, int));
  1147. Xstatic void    get_xy PROTO((CtwWidget, int *, int *, int, int));
  1148. Xstatic int    sunfuncvalue PROTO((int));
  1149. Xstatic int    funcvalue PROTO((int));
  1150. Xstatic char    *handle_escape PROTO((CtwWidget, char *, char *));
  1151. Xstatic void    do_rev_index PROTO((CtwWidget));
  1152. Xstatic void    do_index PROTO((CtwWidget));
  1153. Xstatic void    scroll_up PROTO((CtwWidget, int));
  1154. Xstatic void    scroll_rectangle PROTO((CtwWidget, int, int, int, int, int));
  1155. Xstatic void    scroll_up_local  PROTO((CtwWidget, int, int));
  1156. Xstatic void    blank_line PROTO((CtwWidget, vbyte_t *));
  1157. Xstatic void    clear_lines PROTO((CtwWidget, int, int));
  1158. Xstatic void    delete_line PROTO((CtwWidget, int, int));
  1159. Xstatic void    insert_line PROTO((CtwWidget, int, int, int));
  1160. Xstatic void    wait_for_exposure PROTO((CtwWidget));
  1161. Xstatic int    process_escape PROTO((CtwWidget));
  1162. Xstatic void    send_input PROTO((CtwWidget, char *, int));
  1163. Xstatic void    scroll_down PROTO((CtwWidget, int, int));
  1164. Xstatic void    turn_off_cursor PROTO((CtwWidget));
  1165. Xstatic void    turn_on_cursor PROTO((CtwWidget));
  1166. Xstatic void    toggle_cursor();
  1167. Xstatic void    send_str PROTO((CtwWidget, char *, int));
  1168. Xstatic int    do_quest PROTO((CtwWidget, int, int, int *));
  1169. Xstatic int    do_escequ PROTO((CtwWidget, int, int, int *));
  1170. Xstatic int    do_text_parms PROTO((Widget, char *));
  1171. Xstatic void    down_line PROTO((CtwWidget, char *));
  1172. Xstatic void    clear_to_eol PROTO((CtwWidget));
  1173. Xstatic void    clear_from_beginning PROTO((CtwWidget));
  1174. Xstatic void    clear_screen PROTO((CtwWidget));
  1175. Xstatic void    hilite PROTO((CtwWidget, int, int, int, int, int));
  1176. Xstatic Boolean convert_proc();
  1177. Xstatic Atom     FetchAtom();
  1178. Xstatic void lose_selection();
  1179. Xstatic void    requestor_callback();
  1180. X
  1181. X
  1182. Xstatic XtActionsRec actions[] = {
  1183. X  /* {name, procedure}, */
  1184. X    {"input",        CtwInput},
  1185. X    {"expose",        CtwExpose},
  1186. X    {"string",        CtwString},
  1187. X/* not good or cool for xod
  1188. X    {"select-start",    CtwSelectStart},
  1189. X    {"select-extend",    CtwSelectExtend},
  1190. X    {"select-end",    CtwSelectEnd},
  1191. X    {"insert-selection",CtwInsertSelection},
  1192. X*/
  1193. X    {"button_motion",    CtwButtonMotion},
  1194. X    {"button_down",    CtwButtonDown},
  1195. X    {"button_up",    CtwButtonUp},
  1196. X};
  1197. X/*
  1198. X<Btn1Down>:        select-start()\n\
  1199. X<Btn1Motion>:        select-extend()\n\
  1200. X<Btn1Up>:        select-end(PRIMARY, CUT_BUFFER0)\n\
  1201. X*/
  1202. Xstatic char translations[] =
  1203. X"\
  1204. X<KeyPress>:        input()\n\
  1205. X<Expose>:        expose()\n\
  1206. X<GraphicsExpose>:    expose()\n\
  1207. X<Btn1Down>:        button_down()\n\
  1208. X<Btn1Up>:        button_up()\n\
  1209. X<Btn2Up>:        button_up()\n\
  1210. X<Btn2Down>:        button_down()\n\
  1211. X<Btn3Up>:        button_up()\n\
  1212. X<Btn3Down>:        button_down()\n\
  1213. X<BtnMotion>:        button_motion()\n";
  1214. X
  1215. XCtwClassRec ctwClassRec = {
  1216. X  { /* core fields */
  1217. X    /* superclass        */    (WidgetClass) &widgetClassRec,
  1218. X    /* class_name        */    "Ctw",
  1219. X    /* widget_size        */    sizeof(CtwRec),
  1220. X    /* class_initialize        */    NULL,
  1221. X    /* class_part_initialize    */    NULL,
  1222. X    /* class_inited        */    FALSE,
  1223. X    /* initialize        */    initialize,
  1224. X    /* initialize_hook        */    NULL,
  1225. X    /* realize            */    realize,
  1226. X    /* actions            */    actions,
  1227. X    /* num_actions        */    XtNumber(actions),
  1228. X    /* resources        */    resources,
  1229. X    /* num_resources        */    XtNumber(resources),
  1230. X    /* xrm_class        */    NULLQUARK,
  1231. X    /* compress_motion        */    TRUE,
  1232. X    /* compress_exposure    */    FALSE,
  1233. X    /* compress_enterleave    */    TRUE,
  1234. X    /* visible_interest        */    FALSE,
  1235. X    /* destroy            */    Destroy,
  1236. X    /* resize            */    Resize,
  1237. X    /* expose            */    redisplay,
  1238. X    /* set_values        */    Set_values,
  1239. X    /* set_values_hook        */    NULL,
  1240. X    /* set_values_almost    */    XtInheritSetValuesAlmost,
  1241. X    /* get_values_hook        */    NULL,
  1242. X    /* accept_focus        */    XtInheritAcceptFocus,
  1243. X    /* version            */    XtVersion,
  1244. X    /* callback_private        */    NULL,
  1245. X    /* tm_table            */    translations,
  1246. X    /* query_geometry        */    XtInheritQueryGeometry,
  1247. X    /* display_accelerator    */    XtInheritDisplayAccelerator,
  1248. X    /* extension        */    NULL
  1249. X  },
  1250. X  { /* ctw fields */
  1251. X    /* empty            */    0
  1252. X  }
  1253. X};
  1254. X
  1255. XWidgetClass ctwWidgetClass = (WidgetClass)&ctwClassRec;
  1256. X
  1257. X/**********************************************************************/
  1258. X/*   Array of colors corresponding to the ANSI.                  */
  1259. X/**********************************************************************/
  1260. Xstatic Pixel x11_colors[16];
  1261. X
  1262. X/**********************************************************************/
  1263. X/*   Array  of  characters  used  to  map  from  PC character set to  */
  1264. X/*   line-drawing character set.                      */
  1265. X/**********************************************************************/
  1266. Xstatic char pc_chars[256];
  1267. X
  1268. X/**********************************************************************/
  1269. X/*   Index  array  by  char  value  to  see  whether we need special  */
  1270. X/*   processing.                              */
  1271. X/**********************************************************************/
  1272. Xstatic unsigned char    parse_tbl[256];
  1273. X
  1274. X/* ARGSUSED */
  1275. Xstatic void
  1276. Xinitialize(Widget treq, Widget tnew) {
  1277. X    CtwWidget    new = (CtwWidget) tnew;
  1278. X    Display    *dpy = XtDisplay(new);
  1279. X
  1280. X    /***********************************************/
  1281. X    /*   Initialise the parse table.           */
  1282. X    /***********************************************/
  1283. X    parse_tbl['\0'] = 1;
  1284. X    parse_tbl[BEL] = 1;
  1285. X    parse_tbl['\b'] = 1;
  1286. X    parse_tbl['\t'] = 1;
  1287. X    parse_tbl['\r'] = 1;
  1288. X    parse_tbl['\n'] = 1;
  1289. X    parse_tbl['n' & 0x1f] = 1;
  1290. X    parse_tbl['o' & 0x1f] = 1;
  1291. X    parse_tbl[ESC] = 1;
  1292. X    parse_tbl[XON] = 1;
  1293. X    parse_tbl[XOFF] = 1;
  1294. X
  1295. X    if (setup_x11_colors(dpy) == FALSE) {
  1296. X        /***********************************************/
  1297. X        /*   Monochrome screen.                   */
  1298. X        /***********************************************/
  1299. X        new->ctw.cursor_color = x11_colors[7];
  1300. X        }
  1301. X
  1302. X    /***********************************************/
  1303. X    /*   Set  up  the  PC  charcter  set  mapping  */
  1304. X    /*   matrix.                       */
  1305. X    /***********************************************/
  1306. X    pc_chars[213] = 'l';
  1307. X    pc_chars[184] = 'k';
  1308. X    pc_chars[212] = 'm';
  1309. X    pc_chars[190] = 'j';
  1310. X    pc_chars[179] = 'x';
  1311. X    pc_chars[0xcd] = 'q';
  1312. X    pc_chars[0xd1] = 'w';
  1313. X    pc_chars[0xcf] = 'v';
  1314. X    pc_chars[0xd8] = 'n';
  1315. X    pc_chars[0xb5] = 'u';
  1316. X    pc_chars[0xc6] = 't';
  1317. X
  1318. X    if (new->core.height < 10)
  1319. X        new->core.height = DEFAULT_HEIGHT;
  1320. X    if (new->core.width < 10)
  1321. X        new->core.width = DEFAULT_WIDTH;
  1322. X    new->ctw.win_height_allocated = new->core.height;
  1323. X    new->ctw.win_width_allocated = new->core.width;
  1324. X    /***********************************************/
  1325. X    /*   Set   initial   position  and  state  of  */
  1326. X    /*   cursor.                       */
  1327. X    /***********************************************/
  1328. X    new->ctw.x = new->ctw.y = 0;
  1329. X    new->ctw.cursor_visible = TRUE;    
  1330. X
  1331. X    if ((new->ctw.fontp = XLoadQueryFont(XtDisplay(new), new->ctw.font)) != NULL) {
  1332. X        new->ctw.font_height = new->ctw.fontp->ascent + 
  1333. X                 new->ctw.fontp->descent;
  1334. X        new->ctw.font_width = XTextWidth(new->ctw.fontp, "A", 1);
  1335. X        new->core.height = new->ctw.rows * new->ctw.font_height;
  1336. X        new->core.width = new->ctw.columns * new->ctw.font_width;
  1337. X        new->ctw.win_height_allocated = new->core.height;
  1338. X        new->ctw.win_width_allocated = new->core.width;
  1339. X        }
  1340. X    /***********************************************/
  1341. X    /*   Look  for  focus  related  events on the  */
  1342. X    /*   parent     widget.     We     want    to  */
  1343. X    /*   enable/disable      flashing      cursor  */
  1344. X    /*   depending   on   whether   we  have  the  */
  1345. X    /*   keyboard focus or not.               */
  1346. X    /***********************************************/
  1347. X    XtAddEventHandler(XtParent(new), FocusChangeMask, FALSE,
  1348. X        HandleFocusChange, new);
  1349. X}
  1350. X/**********************************************************************/
  1351. X/*   Try  and  keep  track of whether we have the focus or not so we  */
  1352. X/*   can avoid flashing cursor when its not our responsibility.          */
  1353. X/**********************************************************************/
  1354. Xvoid
  1355. XHandleFocusChange(Widget widget, CtwWidget w, XFocusChangeEvent *event) {
  1356. X    if (event->type == FocusIn) {
  1357. X        w->ctw.have_focus = TRUE;
  1358. X        /***********************************************/
  1359. X        /*   If timer isn't running then restart it.   */
  1360. X        /***********************************************/
  1361. X        if (w->ctw.cursor_timer == 0 && w->ctw.flashrate)
  1362. X            cursor_flash_proc(w, (XtIntervalId *) NULL);
  1363. X        }
  1364. X    else {
  1365. X        w->ctw.have_focus = FALSE;
  1366. X        if (w->ctw.cursor_timer && w->ctw.flashrate) {
  1367. X            XtRemoveTimeOut(w->ctw.cursor_timer);
  1368. X            w->ctw.cursor_timer = 0;
  1369. X            turn_on_cursor(w);
  1370. X            }
  1371. X        }
  1372. X}
  1373. X# define    superclass    (&widgetClassRec)
  1374. Xstatic void
  1375. Xrealize(Widget w, XtValueMask *valueMask, XSetWindowAttributes *attributes) {
  1376. X    CtwWidget    new = (CtwWidget) w;
  1377. X    XGCValues    values;
  1378. X    Arg    args[10];
  1379. X    int    n;
  1380. X    XSetWindowAttributes    win_attr;
  1381. X
  1382. X    (*superclass->core_class.realize)(w, valueMask, attributes);
  1383. X    /***********************************************/
  1384. X    /*   Need  graphics  exposure  events because  */
  1385. X    /*   we  support  the  insert and delete line  */
  1386. X    /*   functionality, which uses XCopyArea.      */
  1387. X    /***********************************************/
  1388. X    values.graphics_exposures = TRUE;
  1389. X    values.background = x11_colors[0];
  1390. X    new->ctw.gc = XCreateGC(XtDisplay(new), XtWindow(new), 
  1391. X        GCBackground | GCGraphicsExposures, &values);
  1392. X    XSetWindowBackground(XtDisplay(w), XtWindow(w), x11_colors[0]);
  1393. X    values.graphics_exposures = FALSE;
  1394. X    values.background = new->ctw.cursor_color;
  1395. X    new->ctw.cursor_gc = XCreateGC(XtDisplay(new), XtWindow(new), 
  1396. X        GCBackground | GCGraphicsExposures, &values);
  1397. X    new->ctw.line_gc = XCreateGC(XtDisplay(new), XtWindow(new), GCGraphicsExposures, &values);
  1398. X
  1399. X    /***********************************************/
  1400. X    /*   Make sure we have a sane window size.     */
  1401. X    /***********************************************/
  1402. X    if (new->ctw.rows < 0)
  1403. X        new->ctw.rows = 1;
  1404. X    if (new->ctw.columns < 0)
  1405. X        new->ctw.columns = 1;
  1406. X    reset_font((CtwWidget)w, FALSE);
  1407. X
  1408. X    XSetFont(XtDisplay(new), new->ctw.gc, new->ctw.fontp->fid);
  1409. X    XSetFont(XtDisplay(new), new->ctw.cursor_gc, new->ctw.fontp->fid);
  1410. X
  1411. X    win_attr.bit_gravity = NorthWestGravity;
  1412. X    XChangeWindowAttributes(XtDisplay(w), XtWindow(w),
  1413. X        CWBitGravity, &win_attr);
  1414. X    
  1415. X    n = 0;
  1416. X    XtSetArg(args[n], XtNinput, 1); n++;
  1417. X    XtSetValues(w, args, n);
  1418. X
  1419. X    n = 0;
  1420. X    XtSetArg(args[n], XtNwidthInc, new->ctw.font_width); n++;
  1421. X    XtSetArg(args[n], XtNheightInc, new->ctw.font_height); n++;
  1422. X    XtSetValues(XtParent(w), args, n);
  1423. X
  1424. X    new->ctw.old_top_line = -1;
  1425. X    new->ctw.sel_string = (char *) NULL;
  1426. X    alloc_screen(new, TRUE);
  1427. X
  1428. X    new->ctw.flags[CTW_ERASE_BLACK] = TRUE;
  1429. X    new->ctw.flags[CTW_CUT_NEWLINES] = TRUE;
  1430. X
  1431. X    reset_screen(new);
  1432. X    /***********************************************/
  1433. X    /*   Timer for the flashing cursor.           */
  1434. X    /***********************************************/
  1435. X    new->ctw.cursor_timer = 0;
  1436. X    if (new->ctw.flashrate)
  1437. X        new->ctw.cursor_timer = XtAppAddTimeOut(
  1438. X            XtWidgetToApplicationContext((Widget)new),
  1439. X            (long) new->ctw.flashrate, cursor_flash_proc, new);
  1440. X}
  1441. X/**********************************************************************/
  1442. X/*   Function called when widget is destroyed.                  */
  1443. X/**********************************************************************/
  1444. Xstatic void
  1445. XDestroy(CtwWidget w) {
  1446. X    Display *dpy;
  1447. X
  1448. X    dpy = XtDisplay(w);
  1449. X    if (w->ctw.memory)
  1450. X        chk_free((void *) w->ctw.memory);
  1451. X    if (w->ctw.lines)
  1452. X        chk_free((void *) w->ctw.lines);
  1453. X    if (w->ctw.sel_string)
  1454. X        chk_free((void *) w->ctw.sel_string);
  1455. X    XFreeGC(dpy, w->ctw.gc);
  1456. X    XFreeGC(dpy, w->ctw.cursor_gc);
  1457. X    XFreeGC(dpy, w->ctw.line_gc);
  1458. X    XtRemoveTimeOut(w->ctw.cursor_timer);
  1459. X
  1460. X    XtRemoveEventHandler(XtParent(w), FocusChangeMask, FALSE,
  1461. X        (XtEventHandler)HandleFocusChange, w);
  1462. X
  1463. X}
  1464. X/* ARGSUSED */
  1465. Xstatic void
  1466. XResize(CtwWidget w) {
  1467. X    int    x, y;
  1468. X
  1469. X    if (!XtIsRealized((Widget)w))
  1470. X        return;
  1471. X    /***********************************************/
  1472. X    /*   Stop   get_xy()   from  stopping  window  */
  1473. X    /*   from getting bigger.               */
  1474. X    /***********************************************/
  1475. X    w->ctw.rows = 32767;
  1476. X    w->ctw.columns = 32767;
  1477. X    get_xy(w, &y, &x, w->core.width, w->core.height);
  1478. X    if (y < 1)
  1479. X        y = 1;
  1480. X    if (x < 1)
  1481. X        x = 1;
  1482. X    w->ctw.rows = y;
  1483. X    w->ctw.columns = x;
  1484. X    w->ctw.scroll_top = 0;
  1485. X    w->ctw.scroll_bot = y;
  1486. X
  1487. X    alloc_screen(w, FALSE);
  1488. X}
  1489. X/**********************************************************************/
  1490. X/*   Method   called  when  application  wants  to  change  resource  */
  1491. X/*   values. Intercept font change.                      */
  1492. X/**********************************************************************/
  1493. Xstatic Boolean
  1494. XSet_values(CtwWidget cur, CtwWidget req, CtwWidget new, ArgList args, 
  1495. X    Cardinal *num_args) {
  1496. X    int    refresh_needed = FALSE;
  1497. X    XFontStruct    *fp;
  1498. X    Dimension    req_width, req_height;
  1499. X
  1500. X    if (cur->ctw.font != new->ctw.font && 
  1501. X        strcmp(cur->ctw.font, new->ctw.font) != 0) {
  1502. X        if ((fp = XLoadQueryFont(XtDisplay(new), new->ctw.font)) != NULL) {
  1503. X            new->ctw.fontp = fp;
  1504. X            reset_font(new, FALSE);
  1505. X            XSetFont(XtDisplay(new), new->ctw.gc, fp->fid);
  1506. X            XSetFont(XtDisplay(new), new->ctw.cursor_gc, fp->fid);
  1507. X            refresh_needed = TRUE;
  1508. X            /***********************************************/
  1509. X            /*   Try and resize our window.               */
  1510. X            /***********************************************/
  1511. X            req_width = new->ctw.columns * new->ctw.font_width;
  1512. X            req_height = new->ctw.rows * new->ctw.font_height;
  1513. X            }
  1514. X        }
  1515. X    return refresh_needed;
  1516. X}
  1517. X/**********************************************************************/
  1518. X/*   Xterm compatable string action routine.                  */
  1519. X/**********************************************************************/
  1520. Xstatic void 
  1521. XCtwString(Widget w, XEvent *event, String *x, Cardinal *y) {
  1522. X    register int    i;
  1523. X    register char    *cp;
  1524. X    ctw_callback_t    reason;
  1525. X
  1526. X    reason.reason = CTW_INPUT;
  1527. X    for (i = 0; i < *y; i++) {
  1528. X        cp = x[i];
  1529. X        reason.ptr = cp;
  1530. X        reason.len = strlen(cp);
  1531. X        XtCallCallbacks((Widget)w, XtNkbdCallback, (caddr_t) &reason);
  1532. X        }
  1533. X}
  1534. X/**********************************************************************/
  1535. X/*   Xterm compatable routine for making a selection.              */
  1536. X/**********************************************************************/
  1537. Xstatic void 
  1538. XCtwSelectStart(CtwWidget w, XEvent *event, String *x, Cardinal *y) {
  1539. X    int    r, c;
  1540. X    ctw_callback_t    reason;
  1541. X
  1542. X    if ((unsigned long) ((long) event->xbutton.time - w->ctw.timestamp) >
  1543. X        w->ctw.multiClickTime)
  1544. X        w->ctw.num_clicks = 0;
  1545. X    else
  1546. X        w->ctw.num_clicks = (w->ctw.num_clicks + 1) & 3;
  1547. X    w->ctw.timestamp = event->xbutton.time;
  1548. X
  1549. X    /***********************************************/
  1550. X    /*   Unhilite  any  previous selection before  */
  1551. X    /*   starting the new one.               */
  1552. X    /***********************************************/
  1553. X    if (w->ctw.sel_string) {
  1554. X        if (w->ctw.sel_start_y >= 0)
  1555. X            hilite(w, w->ctw.sel_start_x, w->ctw.sel_start_y,
  1556. X                w->ctw.sel_cur_x, w->ctw.sel_cur_y, FALSE);
  1557. X        chk_free((void *) w->ctw.sel_string);
  1558. X        w->ctw.sel_string = (char *) NULL;
  1559. X        }
  1560. X
  1561. X    get_xy(w, &r, &c, event->xbutton.x, event->xbutton.y);
  1562. X
  1563. X    w->ctw.sel_start_x = c;
  1564. X    w->ctw.sel_start_y = w->ctw.top_line + r;
  1565. X
  1566. X    w->ctw.sel_cur_x = w->ctw.sel_start_x;
  1567. X    w->ctw.sel_cur_y = w->ctw.sel_start_y;
  1568. X
  1569. X    convert_click(w);
  1570. X
  1571. X    /***********************************************/
  1572. X    /*   Turn  off  cursor  and stop the flashing  */
  1573. X    /*   code from turning it back on.           */
  1574. X    /***********************************************/
  1575. X    turn_off_cursor(w);
  1576. X    w->ctw.cursor_state = CURSOR_HIDDEN;
  1577. X
  1578. X    /***********************************************/
  1579. X    /*   Tell  user  that we're doing a selection  */
  1580. X    /*   so  its  best not to keep adding text to  */
  1581. X    /*   the window to avoid scrolling problems.   */
  1582. X    /***********************************************/
  1583. X    reason.reason = CTW_SELECTION;
  1584. X    XtCallCallbacks((Widget)w, XtNmouseCallback, (caddr_t) &reason);
  1585. X}
  1586. X/**********************************************************************/
  1587. X/*   Routine   to  convert  co-ordinates  got  via  a  button  click  */
  1588. X/*   depending on how many clicks were typed.                  */
  1589. X/**********************************************************************/
  1590. Xstatic void
  1591. Xconvert_click(CtwWidget w) {
  1592. X    if (w->ctw.num_clicks == CLICK_LINE) {
  1593. X        w->ctw.sel_start_x = 0;
  1594. X        w->ctw.sel_cur_x = w->ctw.columns;
  1595. X        hilite(w, 
  1596. X            w->ctw.sel_start_x, w->ctw.sel_start_y,
  1597. X            w->ctw.sel_cur_x, w->ctw.sel_cur_y, FALSE);
  1598. X        }
  1599. X}
  1600. X/**********************************************************************/
  1601. X/*   Xterm compatable routine for making a selection.              */
  1602. X/**********************************************************************/
  1603. Xstatic void 
  1604. XCtwSelectExtend(CtwWidget w, XEvent *event, String *str, Cardinal *num) {
  1605. X    int    x, y;
  1606. X    int    start, cur, here;
  1607. X
  1608. X    get_xy(w, &y, &x, event->xbutton.x, event->xbutton.y);
  1609. X    y += w->ctw.top_line;
  1610. X    if (w->ctw.num_clicks == CLICK_LINE) {
  1611. X        x = w->ctw.columns;
  1612. X        }
  1613. X
  1614. X    start = w->ctw.sel_start_y * w->ctw.columns + w->ctw.sel_start_x;
  1615. X    cur = w->ctw.sel_cur_y * w->ctw.columns + w->ctw.sel_cur_x;
  1616. X    here = y * w->ctw.columns + x;
  1617. X    /***********************************************/
  1618. X    /*   Work   out  which  regions  need  to  be  */
  1619. X    /*   hilighted  and  make  the  display  look  */
  1620. X    /*   correct.                       */
  1621. X    /***********************************************/
  1622. X    if (cur < start) {
  1623. X        if (here < cur) {
  1624. X            hilite(w, x, y, w->ctw.sel_cur_x, w->ctw.sel_cur_y, TRUE);
  1625. X            }
  1626. X        else if (here < start) {
  1627. X            hilite(w, w->ctw.sel_cur_x, w->ctw.sel_cur_y, x, y, FALSE);
  1628. X            }
  1629. X        else {
  1630. X            hilite(w, w->ctw.sel_cur_x, w->ctw.sel_cur_y, 
  1631. X                w->ctw.sel_start_x, w->ctw.sel_start_y, FALSE);
  1632. X            hilite(w, w->ctw.sel_start_x, w->ctw.sel_start_y, x, y, TRUE);
  1633. X            }
  1634. X        }
  1635. X    else if (here >= cur) {
  1636. X        if (cur < start)
  1637. X            hilite(w, w->ctw.sel_cur_x, w->ctw.sel_cur_y, 
  1638. X                w->ctw.sel_start_x, w->ctw.sel_start_y, FALSE);
  1639. X        hilite(w, w->ctw.sel_cur_x, w->ctw.sel_cur_y, x, y, TRUE);
  1640. X        }
  1641. X    else if (here >= start && here < cur) {
  1642. X        hilite(w, x, y, w->ctw.sel_cur_x, w->ctw.sel_cur_y, FALSE);
  1643. X        }
  1644. X    else if (here < start) {
  1645. X        hilite(w, w->ctw.sel_start_x, w->ctw.sel_start_y, 
  1646. X            w->ctw.sel_cur_x, w->ctw.sel_cur_y, FALSE);
  1647. X        hilite(w, x, y, w->ctw.sel_start_x, w->ctw.sel_start_y, TRUE);
  1648. X        }
  1649. X    w->ctw.sel_cur_x = x;
  1650. X    w->ctw.sel_cur_y = y;
  1651. X}
  1652. X/**********************************************************************/
  1653. X/*   Routine to hilite a marked area.                      */
  1654. X/**********************************************************************/
  1655. Xstatic void
  1656. Xhilite(CtwWidget w, int x1, int y1, int x2, int y2, int set_flag) {
  1657. X    int    start_x = x1;
  1658. X    int    end_x, x;
  1659. X    int    y = y1;
  1660. X    vbyte_t    *vp;
  1661. X
  1662. X    if (y < 0)
  1663. X        return;
  1664. X
  1665. X    while (y <= y2) {
  1666. X        if (y == y2)
  1667. X            end_x = x2;
  1668. X        else
  1669. X            end_x = w->ctw.columns;
  1670. X        vp = &w->ctw.lines[y][start_x];
  1671. X        x = start_x;
  1672. X        if (set_flag) {
  1673. X            while (start_x++ < end_x) {
  1674. X                vp->vb_attr |= VB_SELECT;
  1675. X                vp++;
  1676. X                }
  1677. X            }
  1678. X        else {
  1679. X            while (start_x++ < end_x) {
  1680. X                vp->vb_attr &= ~VB_SELECT;
  1681. X                vp++;
  1682. X                }
  1683. X            }
  1684. X        update_region(w, y - w->ctw.top_line, x, 
  1685. X            y+1 - w->ctw.top_line, end_x+1);
  1686. X        start_x = 0;
  1687. X        y++;
  1688. X        }
  1689. X}
  1690. X/**********************************************************************/
  1691. X/*   Function  to  compute  the  length  of text in a line ready for  */
  1692. X/*   cutting.                                  */
  1693. X/**********************************************************************/
  1694. Xstatic int
  1695. Xcompute_length(CtwWidget w, int row, int start_col, int end_col) {
  1696. X    vbyte_t    *vp;
  1697. X    vbyte_t    *svp;
  1698. X
  1699. X    vp = w->ctw.lines[row] + end_col;
  1700. X    svp = w->ctw.lines[row] + start_col;
  1701. X    while (vp > svp) {
  1702. X        if (vp->vb_byte != ' ')
  1703. X            break;
  1704. X        vp--;
  1705. X        }
  1706. X    return (vp - svp) + 1;
  1707. X}
  1708. X/**********************************************************************/
  1709. X/*   Xterm compatable routine for making a selection.              */
  1710. X/**********************************************************************/
  1711. Xstatic void 
  1712. XCtwSelectEnd(CtwWidget w, XEvent *event, String *str, Cardinal *num) {
  1713. X    int    r, t, len;
  1714. X    int    y, x, end_x;
  1715. X    vbyte_t    *vp;
  1716. X    int    cur;
  1717. X    int    start;
  1718. X    char    *cp;
  1719. X    int    nl;
  1720. X    Atom    atom;
  1721. X
  1722. X    start = w->ctw.sel_start_y * w->ctw.columns + w->ctw.sel_start_x;
  1723. X    cur = w->ctw.sel_cur_y * w->ctw.columns + w->ctw.sel_cur_x;
  1724. X    if (cur < start) {
  1725. X        t = w->ctw.sel_start_x;
  1726. X        w->ctw.sel_start_x = w->ctw.sel_cur_x;
  1727. X        w->ctw.sel_cur_x = t;
  1728. X
  1729. X        t = w->ctw.sel_start_y;
  1730. X        w->ctw.sel_start_y = w->ctw.sel_cur_y;
  1731. X        w->ctw.sel_cur_y = t;
  1732. X
  1733. X        start = w->ctw.sel_start_y * w->ctw.columns + w->ctw.sel_start_x;
  1734. X        cur = w->ctw.sel_cur_y * w->ctw.columns + w->ctw.sel_cur_x;
  1735. X        }
  1736. X
  1737. X    /***********************************************/
  1738. X    /*   Free up any previous selection.           */
  1739. X    /***********************************************/
  1740. X    if (w->ctw.sel_string) {
  1741. X        chk_free((void *) w->ctw.sel_string);
  1742. X        }
  1743. X    /***********************************************/
  1744. X    /*   Work  out  how  much  room is needed for  */
  1745. X    /*   copy.  We  may  allocate  too  much  but  */
  1746. X    /*   thats better than too little.           */
  1747. X    /***********************************************/
  1748. X    if (w->ctw.sel_start_y == w->ctw.sel_cur_y) {
  1749. X        len = compute_length(w, w->ctw.sel_start_y, w->ctw.sel_start_x, w->ctw.sel_cur_x);
  1750. X        }
  1751. X    else {
  1752. X        len = compute_length(w, w->ctw.sel_start_y, w->ctw.sel_start_x, w->ctw.columns);
  1753. X        for (r = w->ctw.sel_start_y + 1; r < w->ctw.sel_cur_y; r++)
  1754. X            len += compute_length(w, r, 0, w->ctw.columns);
  1755. X        len += compute_length(w, 0, w->ctw.sel_cur_x, w->ctw.columns);
  1756. X        }
  1757. X    w->ctw.sel_length = len;
  1758. X    w->ctw.sel_string = (char *) chk_alloc(len);
  1759. X    cp = w->ctw.sel_string;
  1760. X    y = w->ctw.sel_start_y;
  1761. X    x = w->ctw.sel_start_x;
  1762. X    nl = '\0';
  1763. X    while (y <= w->ctw.sel_cur_y) {
  1764. X        if (y == w->ctw.sel_cur_y)
  1765. X            end_x = w->ctw.sel_cur_x - 1;
  1766. X        else {
  1767. X            end_x = w->ctw.columns - 1;
  1768. X            }
  1769. X        vp = &w->ctw.lines[y][x];
  1770. X        /***********************************************/
  1771. X        /*   Remove trailing spaces.               */
  1772. X        /***********************************************/
  1773. X        len = compute_length(w, y, x, end_x);
  1774. X        if (len != end_x - x + 1)
  1775. X            nl = '\n';
  1776. X        end_x = x + len - 1;
  1777. X        while (x++ <= end_x) {
  1778. X            *cp++ = vp->vb_byte;
  1779. X            vp++;
  1780. X            }
  1781. X        if (nl)
  1782. X            *cp++ = nl;
  1783. X        y++;
  1784. X        x = 0;
  1785. X        if (w->ctw.flags[CTW_CUT_NEWLINES])
  1786. X            nl = '\n';
  1787. X        }
  1788. X    *cp = '\0';
  1789. X    /***********************************************/
  1790. X    /*   Turn cursor back on.               */
  1791. X    /***********************************************/
  1792. X    w->ctw.cursor_state = CURSOR_OFF;
  1793. X    turn_on_cursor(w);
  1794. X
  1795. X    /***********************************************/
  1796. X    /*   Try and grab ownership of selection.      */
  1797. X    /***********************************************/
  1798. X    atom = XA_PRIMARY;
  1799. X    if (*num > 0 && strcmp(*str, "SECONDARY") == 0)
  1800. X        atom = XA_SECONDARY;
  1801. X    if (XtOwnSelection((Widget)w, atom, event->xbutton.time,
  1802. X        convert_proc, lose_selection, NULL) == FALSE) {
  1803. X        XBell(XtDisplay(w), 100);
  1804. X        }
  1805. X}
  1806. Xstatic Atom
  1807. XFetchAtom(Widget w, String name) {
  1808. X    Atom    a;
  1809. X    XrmValue    source, dest;
  1810. X
  1811. X    source.size = strlen(name) + 1;
  1812. X    source.addr = name;
  1813. X    dest.size = sizeof(Atom);
  1814. X    dest.addr = (caddr_t) &a;
  1815. X
  1816. X    XtConvertAndStore(w, XtRString, &source, XtRAtom, &dest);
  1817. X    return a;
  1818. X}
  1819. X/**********************************************************************/
  1820. X/*   Function   called   when   some  other  application  wants  the  */
  1821. X/*   selection.                                  */
  1822. X/**********************************************************************/
  1823. Xstatic Boolean
  1824. Xconvert_proc(CtwWidget w, Atom *selection, Atom *target, Atom *type, 
  1825. X    XtPointer *value, unsigned long *length, int *format) {
  1826. X    static Atom    targets = 0;
  1827. X
  1828. X    if (w->ctw.sel_string == (char *) NULL)
  1829. X        return FALSE;
  1830. X
  1831. X    if (targets == 0) {
  1832. X        targets = FetchAtom((Widget)w, "TARGETS");
  1833. X        }
  1834. X
  1835. X    if (*target == targets) {
  1836. X        *type = XA_ATOM;
  1837. X        *value = (XtPointer) XtNew(Atom);
  1838. X        *(Atom *) *value = XA_STRING;
  1839. X        *length = 1;
  1840. X        *format = 32;
  1841. X        return TRUE;
  1842. X        }
  1843. X
  1844. X    if (*target == XA_STRING) {
  1845. X        *type = XA_STRING;
  1846. X        *value = (XtPointer) XtNewString(w->ctw.sel_string);
  1847. X        *length = strlen(*value);
  1848. X        *format = 8;
  1849. X        return TRUE;
  1850. X        }
  1851. X    return FALSE;
  1852. X}
  1853. X/**********************************************************************/
  1854. X/*   Function  called  when  we lose the selection. Just free up the  */
  1855. X/*   allocated memory.                              */
  1856. X/**********************************************************************/
  1857. Xstatic void
  1858. Xlose_selection(CtwWidget w, Atom *selection) {
  1859. X    if (w->ctw.sel_string) {
  1860. X        chk_free((void *) w->ctw.sel_string);
  1861. X        w->ctw.sel_string = (char *) NULL;
  1862. X        hilite(w, w->ctw.sel_start_x, w->ctw.sel_start_y,
  1863. X            w->ctw.sel_cur_x, w->ctw.sel_cur_y, FALSE);
  1864. X        w->ctw.sel_start_x = -1;
  1865. X        }
  1866. X}
  1867. X/**********************************************************************/
  1868. X/*   Function  to  grab  contents  of  selection  and give to owning  */
  1869. X/*   application.                              */
  1870. X/**********************************************************************/
  1871. Xstatic void 
  1872. XCtwInsertSelection(Widget w, XEvent *event, String *x, Cardinal *y) {
  1873. X    XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, requestor_callback, 
  1874. X        NULL, event->xbutton.time);
  1875. X}
  1876. X/* ARGSUSED */
  1877. Xstatic void
  1878. Xrequestor_callback(Widget w, XtPointer client_data, Atom *selection, 
  1879. X    Atom *type, XtPointer *value, unsigned long *length, int *format) {
  1880. X    ctw_callback_t    reason;
  1881. X
  1882. X    reason.reason = CTW_PASTE;
  1883. X
  1884. X    if (value == NULL || (*value == NULL && *length == 0)) {
  1885. X        return;
  1886. X        }
  1887. X    reason.ptr = (char *) value;
  1888. X    reason.len = (int) *length;
  1889. X    XtCallCallbacks((Widget)w, XtNkbdCallback, (caddr_t) &reason);
  1890. X
  1891. X    /***********************************************/
  1892. X    /*   Free it.                       */
  1893. X    /***********************************************/
  1894. X    XtFree((char *)value);
  1895. X}
  1896. X/**********************************************************************/
  1897. X/*   Convert mouse button presses into pseudo keystrokes.          */
  1898. X/**********************************************************************/
  1899. Xstatic void 
  1900. XCtwButtonDown(CtwWidget w, XEvent *event, String *x, Cardinal *y) {
  1901. X    ctw_callback_t reason;
  1902. X
  1903. X    if (w->ctw.flags[CTW_APPL_MOUSE]) {
  1904. X        application_mouse(w, event->xbutton.state, 0, event, 
  1905. X            event->xbutton.x,
  1906. X            event->xbutton.y);
  1907. X        return;
  1908. X        }
  1909. X    w->ctw.timestamp = event->xbutton.time;
  1910. X
  1911. X    reason.reason = CTW_BUTTON_DOWN;
  1912. X    reason.event = event;
  1913. X    XtCallCallbacks((Widget)w, XtNmouseCallback, (caddr_t) &reason);
  1914. X}
  1915. X/**********************************************************************/
  1916. X/*   Function to handle the application mouse mode.              */
  1917. X/**********************************************************************/
  1918. Xstatic void
  1919. Xapplication_mouse(CtwWidget w, int state, int flag, XEvent *event, 
  1920. X    int x, int y) {
  1921. X    ctw_callback_t    reason;
  1922. X    char    buf[64];
  1923. X    int    r, c;
  1924. X    int    m = 0;
  1925. X
  1926. X    get_xy(w, &r, &c, x, y);
  1927. X    /***********************************************/
  1928. X    /*   Calculate modifer byte value.           */
  1929. X    /***********************************************/
  1930. X    if (state & ShiftMask)
  1931. X        m |= 0x01;
  1932. X    if (state & ControlMask)
  1933. X        m |= 0x02;
  1934. X    if (state & (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask))
  1935. X        m |= 0x04;
  1936. X
  1937. X    sprintf(buf, "\033[%d;%d;%d;%d;%dM", 
  1938. X        event->xbutton.button, 
  1939. X        flag,
  1940. X        m, r, c);
  1941. X    reason.reason = CTW_INPUT;
  1942. X    reason.ptr = buf;
  1943. X    reason.len = strlen(buf);
  1944. X    XtCallCallbacks((Widget)w, XtNkbdCallback, (caddr_t) &reason);
  1945. X}
  1946. X/**********************************************************************/
  1947. X/*   Event  handler  to  handle  the mouse moving whilst a button is  */
  1948. X/*   held down.                                  */
  1949. X/**********************************************************************/
  1950. Xstatic void 
  1951. XCtwButtonMotion(CtwWidget w, XEvent *event, String *x, Cardinal *y) {
  1952. X    ctw_callback_t reason;
  1953. X
  1954. X    if (w->ctw.flags[CTW_APPL_MOUSE]) {
  1955. X        application_mouse(w, 
  1956. X            event->xmotion.state & Button1Mask ? Button1 : 
  1957. X            event->xmotion.state & Button2Mask ? Button2 : 
  1958. X            event->xmotion.state & Button3Mask ? Button3 : 
  1959. X            event->xmotion.state & Button4Mask ? Button4 : 
  1960. X                           Button5,
  1961. X            2, event,
  1962. X            event->xmotion.x,
  1963. X            event->xmotion.y);
  1964. X        return;
  1965. X        }
  1966. X    reason.reason = CTW_BUTTON_MOTION;
  1967. X    reason.event = event;
  1968. X    XtCallCallbacks((Widget)w, XtNmouseCallback, (caddr_t) &reason);
  1969. X}
  1970. X/**********************************************************************/
  1971. X/*   Convert mouse button presses into pseudo keystrokes.          */
  1972. X/**********************************************************************/
  1973. Xstatic void 
  1974. XCtwButtonUp(CtwWidget w, XEvent *event, String *x, Cardinal *y) {
  1975. X    ctw_callback_t reason;
  1976. X
  1977. X    if (w->ctw.flags[CTW_APPL_MOUSE]) {
  1978. X        application_mouse(w, event->xbutton.state, 1, event,
  1979. X            event->xbutton.x,
  1980. X            event->xbutton.y);
  1981. X        return;
  1982. X        }
  1983. X    w->ctw.timestamp = event->xbutton.time;
  1984. X    reason.reason = CTW_BUTTON_UP;
  1985. X    reason.event = event;
  1986. X    XtCallCallbacks((Widget)w, XtNmouseCallback, (caddr_t) &reason);
  1987. X}
  1988. X/**********************************************************************/
  1989. X/*   Come here on a keypress event.                      */
  1990. X/**********************************************************************/
  1991. Xstatic void 
  1992. XCtwInput(Widget w, XEvent *event, String *x, Cardinal *y) {
  1993. X    CtwWidget    cw = (CtwWidget) w;
  1994. X    char    buf[BUFSIZ];
  1995. X    char    reply[BUFSIZ];
  1996. X    char    *rp = reply;
  1997. X    static XComposeStatus compose_status;
  1998. X    KeySym    keysym;
  1999. X    int    nbytes;
  2000. X    ctw_callback_t    reason;
  2001. Xstatic char *kypd_num = " XXXXXXXX\tXXX\rXXXxxxxXXXXXXXXXXXXXXXXXXXXX*+,-.\\0123456789XXX=";
  2002. Xstatic char *kypd_apl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ??????abcdefghijklmnopqrstuvwxyzXXX";
  2003. Xstatic char *cur = "DACB";
  2004. X
  2005. X    reason.reason = CTW_INPUT;
  2006. X    reason.len = 0;
  2007. X    reason.ptr = reply;
  2008. X
  2009. X    nbytes = XLookupString((XKeyEvent *) event, buf, sizeof buf,
  2010. X        &keysym, &compose_status);
  2011. X    if (IsPFKey(keysym)) {
  2012. X        *rp++ = ESC;
  2013. X        *rp++ = 'O';
  2014. X        *rp = keysym - XK_KP_F1 + 'P';
  2015. X        reason.len = 3;
  2016. X        }
  2017. X    else if (IsKeypadKey(keysym)) {
  2018. X        if (cw->ctw.flags[CTW_APPL_KEYPAD]) {
  2019. X            *rp++ = ESC;
  2020. X            *rp++ = 'O';
  2021. X            *rp = kypd_apl[keysym - XK_KP_Space];
  2022. X            reason.len = 3;
  2023. X            }
  2024. X        else  {
  2025. X            *rp = kypd_num[keysym - XK_KP_Space];
  2026. X            reason.len = 1;
  2027. X            }
  2028. X        }
  2029. X    else if (IsCursorKey(keysym) && keysym != XK_Prior && keysym != XK_Next) {
  2030. X        *rp++ = ESC;
  2031. X        if (cw->ctw.flags[CTW_CURSOR_KEYPAD])
  2032. X            *rp++ = 'O';
  2033. X        else
  2034. X            *rp++ = '[';
  2035. X        *rp = cur[keysym - XK_Left];
  2036. SHAR_EOF
  2037. echo "End of part 1"
  2038. echo "File ctw.c is continued in part 2"
  2039. echo "2" > s2_seq_.tmp
  2040. exit 0
  2041.  
  2042. exit 0 # Just in case...
  2043. -- 
  2044.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  2045. \X/  Amiga - The only way to fly!      |
  2046.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  2047.   casual observer..."                  |
  2048.