home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3503 < prev    next >
Encoding:
Internet Message Format  |  1991-06-20  |  54.5 KB

  1. From: pgf@cayman.COM (Paul Fox)
  2. Newsgroups: alt.sources
  3. Subject: Vile 16/17 - vi feel-alike (multi-window)
  4. Message-ID: <4535@cayman.COM>
  5. Date: 7 Jun 91 22:10:23 GMT
  6.  
  7. #!/bin/sh
  8. # this is vileshar.16 (part 16 of Vile)
  9. # do not concatenate these parts, unpack them in order with /bin/sh
  10. # file vile.hlp continued
  11. #
  12. if test ! -r _shar_seq_.tmp; then
  13.     echo 'Please unpack part 1 first!'
  14.     exit 1
  15. fi
  16. (read Scheck
  17.  if test "$Scheck" != 16; then
  18.     echo Please unpack part "$Scheck" next!
  19.     exit 1
  20.  else
  21.     exit 0
  22.  fi
  23. ) < _shar_seq_.tmp || exit 1
  24. echo 'x - continuing file vile.hlp'
  25. sed 's/^X//' << 'SHAR_EOF' >> 'vile.hlp' &&
  26. X        single following digit.)  Note that since the buffer names
  27. X        are displayed in order of use, the list can quickly grow
  28. X        "stale" -- the numbers may be meaningless if buffer
  29. X        switching has been done since the last display of the list. 
  30. X
  31. X        The program version is also displayed with this command.
  32. X
  33. X    ^A-*    Always display a list of all buffers.  Useful for updating the
  34. X        list if it's already on the screen but may be out of date.
  35. X        Any argument will cause the list to include _all_ buffers,
  36. X        even those normally considered "invisible".  (For example,
  37. X        macros are stored in "invisible" buffers.)
  38. X
  39. Window manipulation commands:  
  40. -----------------------------
  41. X    ^T    Make Two windows.  Splits the current window in half. This
  42. X        is the usual way to create a new window.
  43. X    ^K    Get rid of (Kill) this window.
  44. X    ^O    Make this the Only window on the screen.
  45. X
  46. X        The emacs-style commands ^X-2, ^X-0, and ^X-1 are also 
  47. X        included, and are synonymous with ^T, ^K, and ^O.
  48. X
  49. X    ^N    Go to the next window on the screen.
  50. X    ^P    Go to the previous window on the screen.
  51. X
  52. X        These two commands may be disturbing to vi users who use
  53. X        ^N and ^P to move between lines.  See the examples under
  54. X        Key Rebinding for how to fix this.
  55. X
  56. X    v    Make the current window smaller.
  57. X    V    Make the current window larger.
  58. X
  59. X    ^A-^D    Scroll the next window down half a screen.
  60. X    ^A-^U    Scroll the next window up half a screen.
  61. X    ^A-^E    Scroll the next window up one line.
  62. X    ^A-^Y    Scroll the next window down one line.
  63. X    (The previous four commands are useful when comparing two buffers.
  64. X     Mnemonic -- think of them as affecting the "A"lternate window.)
  65. X
  66. X    zH zM zL  These are synonyms for vi's 'z+', 'z.', and 'z-', which 
  67. X        position the line holding the cursor at the top, middle, or
  68. X        bottom of the screen, respectively.
  69. X
  70. X    ^X-^R    Scroll the window right by 1/3 of a screen, or by the
  71. X        number of lines specifed.
  72. X    ^X-^L    Scroll the window left by 1/3 of a screen, or by the
  73. X        number of lines specifed.
  74. X
  75. X    If for some reason you can't get your screen set right via a
  76. X    TERM variable, try the ":screen-rows" or ":screen-columns"
  77. X    commands (which take their args (number of rows or columns
  78. X    respectively) before you type the ":").
  79. X
  80. File manipulation commands:  
  81. ---------------------------
  82. X    The usual :e, :r, :f, :w commands are available, though only
  83. X    ":e!" is available of the "!" options.  The :r command reads the
  84. X    named file in after the current line.  To read a file before the
  85. X    first line, use ":0r".
  86. X    
  87. X    As in vi, ranges of lines specified by line numbers (including '.',
  88. X    '$', and '%' shorthands) or marks may precede these commands.  
  89. X    Unlike vi, search patterns cannot be used as line specifiers.
  90. X
  91. X    In addition, two non-"colon" commands have been added:
  92. X
  93. X    ^R    Prompts for a filename, and then reads it in _above_ the
  94. X        current line.  If a register is specified (e.g. "a^R ), 
  95. X        the file is read into that named register, but not inserted 
  96. X        into the current buffer.
  97. X
  98. X    ^W    is a writing operator, which prompts for a filename, and 
  99. X        writes the specified region to that file.  Like all operators,
  100. X        it the command is repeated, as in ^W^W, then lines are 
  101. X        affected.  Use 10^W^W to write 10 lines.
  102. X
  103. X        If a register is specified (e.g. "a^W ) then the command 
  104. X        is _not_ an operator, but writes the specified register to 
  105. X        the named file.  
  106. X
  107. Shell Access
  108. ------------
  109. X    Anywhere a filename is valid, a command name is also
  110. X    valid, entered in the form "!shell-command".  The whole line is
  111. X    handed to the shell, and the read or write operation is done on
  112. X    the commands standard input or output, as appropriate.  Thus
  113. X    you can type ":e !date" to edit a copy of today's date.
  114. X
  115. X    The ": !cmd" shell escape works pretty much as it does in vi.
  116. X    The command ":!!" will rerun the previous such shell command.
  117. X
  118. X    The '!' operator works as expected.
  119. X    
  120. X    In addition, the ^X-! command runs a shell command and captures
  121. X    its output in a specific buffer, called "[Output]".  This is
  122. X    almost identical to ":e !cmd", except that in that case the buffer
  123. X    is named according to the command name.
  124. X
  125. X    These output capture commands are most useful in conjunction with
  126. X    the "error finder", described below.
  127. X
  128. X    On systems supporting job control, ^Z will suspend vile.
  129. X
  130. Text manipulation command:
  131. --------------------------
  132. X    Remember, these are only the new or different commands.  The 
  133. X    standard vi set should still work.
  134. X
  135. X    Undo ("u") and line-undo ("U") are available for all commands.
  136. X    They should be a little less capricious than their
  137. X    vi counterparts, since they do not share the default yank register
  138. X    for their operation.  Also, line-undo ("U") is available until
  139. X    the next change anywhere in the file, rather than until you leave
  140. X    the line.  Unfortunately, the cursor position after an undo may not 
  141. X    always be the same as it would be in vi.
  142. X
  143. X    The vi "global" command is present, in its non-interactive form
  144. X    only.  So is the "substitute" command.  These both look pretty
  145. X    different while they're being used than they do in vi, and since
  146. X    the searching is done right after the pattern is entered, there
  147. X    can be a long delay while you're trying to finish typing your
  148. X    complete command.  You can type commands just as you would have
  149. X    in vi, i.e. ":g/oldpat/s//newstring/" will work.  But you won't
  150. X    see any of the '/' characters.  Try it-- you'll get the idea.
  151. X    Line ranges are not possible on ":g", but they are on ":s".
  152. X
  153. X    The ":v" counterpart to ":g" is not implemented.
  154. X
  155. X    The ":g" command can be followed by any of l (list), p (print),
  156. X    < (left shift), > (right shift), r (read file), d (delete),
  157. X    L (lower case), U (upper case), ~ (flip case), put (append
  158. X    yanked text), Put (prepend yanked text), s (substitute),
  159. X    t (trim trailing whitespace).  For example, ":g/pattern/Put"
  160. X    will insert the contents of the default yank register just
  161. X    above every line containing "pattern". 
  162. X
  163. X    Operators
  164. X    ---------
  165. X    Vi has a class of commands known as "operators".  Operator
  166. X    commands are always immediately followed by a motion command. 
  167. X    The text affected by an operator is bounded by the initial
  168. X    position, and the cursor position after the motion is
  169. X    completed.  Thus the delete operator ('d') can be followed by
  170. X    the word motion command ('w'), causing the next word to be
  171. X    deleted.  The sequence "dG" will delete through the end of the
  172. X    file, and "d/junk" will delete to the next occurence of the
  173. X    string "junk".  Operators can all be "stuttered" to affect
  174. X    lines.  Thus "dd" deletes one line, "4dd" affects 4 lines,
  175. X    etc. 
  176. X
  177. X    Some operators in vile can be forced to affect whole lines,
  178. X    though the motion wouldn't normally imply it, by using the ^X
  179. X    form of the command.  For example, "d%" (assuming you are on a
  180. X    curly brace) will delete a C-style block of code.  "^X-d%"
  181. X    will delete that same area, plus anything else on the lines
  182. X    containing the curly- brace endpoints.
  183. X
  184. X    Note that some operators always affect whole lines, no matter
  185. X    how the motion is specified.  For instance, "!w" will always
  186. X    filter an entire line, and not just a single word. 
  187. X
  188. X    There are several new operator commands:
  189. X
  190. X    ^A-~    Is the operator form of the '~' command, so "^A-~~"
  191. X        changes the case of all characters on the current
  192. X        line, "^A-~w" does it to a word, "3^A-~}" does it for
  193. X        3 paragraphs, etc. 
  194. X    ^A-u    Like ^A-~, but converts the region to upper case.
  195. X    ^A-l    Like ^A-~, but converts the region to lower case.
  196. X
  197. X    ^A-f    Format the region based on the current fill column.  The
  198. X                initial indentation of both the first and second lines
  199. X                of the region are preserved, and all subsequent lines
  200. X                get the second line's indentation.  This makes indented/
  201. X        outdented paragraphs work correctly.  The usual use of
  202. X                this command is "^A-f}", which does it to the current
  203. X                paragraph.  (This is intentionally _not_ the same bevavior
  204. X        obtained by "!fmt", since that behavior is obviously 
  205. X        available elsewhere.)
  206. X
  207. X    ^X-d    Delete the region, including the lines it starts and ends on.
  208. X    ^X-c    Change the region, including the lines it starts and ends on.
  209. X    ^X-y    Yank the region, including the lines it starts and ends on.
  210. X
  211. X    Text insertion
  212. X    --------------
  213. X    ^X-p    Causes the previously yanked or deleted text, no matter
  214. X        how it was obtained, to be inserted after the current line.
  215. X        Usually text that did not consist of whole lines where it
  216. X        came from is inserted immediately following the cursor.
  217. X    ^X-P    As above, but the text is put before the current line.
  218. X        Thus "dw" followed by a "p" command does a normal insertion
  219. X        of the deleted word, whereas "^X-p" results in the word
  220. X        being inserted on a line by itself.
  221. X
  222. X    Searching
  223. X    ---------
  224. X    ^X-/    Does a forward search for the "word" located under the
  225. X        cursor.
  226. X    ^X-?    Does a reverse search for the "word" located under the
  227. X        cursor.
  228. X    ^A-/    Does not do a search, but sets the search pattern to the
  229. X        "word" under the cursor.  Useful for "picking up" a word
  230. X        from one buffer, and searching for it in another.
  231. X
  232. X    The following two commands may not always be present in vile,
  233. X        depeinding on how it was built:
  234. X    ^X-S    Incremental forward searching.  As you enter the search 
  235. X        string, the cursor is advanced to the next match with 
  236. X        what you've typed so far.  Use ^F and ^R to continue the
  237. X        search forward or in reverse, using the current pattern.
  238. X    ^X-R    As above, but in reverse.
  239. X
  240. X    Tags
  241. X    ----
  242. X    Vile supports vi-style "tags" files.
  243. X
  244. X    ":ta" or ":tag" allows you to enter a tagname to locate.  Changes
  245. X        to that file and location.
  246. X    ^]    Uses the identifier currently under the cursor as the 
  247. X        tagname.
  248. X    ^X-^]    "Un-tag" - pops to the file and location just previous to 
  249. X        the last tag command.  (Some versions of vi have this command
  250. X        attached to ^T)
  251. X
  252. X    When one of these commands is used, vile will look for a file named
  253. X    "tags" in the current directory, and load it into a hidden buffer
  254. X    for use during tag searches.  This buffer is editable if you wish
  255. X    (":e tags"), but will not appear in the buffer lists.  If a buffer
  256. X    named "tags" is already available when a tag is first requested, it
  257. X    will be used instead of a file called "tags", and of course will
  258. X    remain visible.
  259. X
  260. X    "Advanced" editing
  261. X    ------------------
  262. X    [ Eventually, these will be rewritten to become "operators", similar to
  263. X    those described above. ]
  264. X    ^A-<SPACE>    Convert tabs to spaces on the current line. An argument
  265. X        tells how many lines.
  266. X    ^A-<TAB>    Convert as many spaces to tabs as possible on the 
  267. X        current line.  Argument tells how many lines.
  268. X    ^A-o    Remove all but one blank line at the current spot.
  269. X
  270. Miscellaneous commands
  271. ----------------------
  272. X    ^X-^X    The "error finder".  Goes to the next file/line error pair 
  273. X        specified in the last buffer captured from a command's
  274. X        output.  This buffer is usually created with the ^X-! command.
  275. X        For example, "-!cc -c junk.c" puts all of the compiler output
  276. X        into the buffer named "[Output]".  Repeatedly hitting ^X-^X 
  277. X        will position the editor at each error in turn, and will
  278. X        eventually start over again at the top..
  279. X    ^X-t    Set or report on the tab-stop width.  Tab-stops may only be
  280. X        set to 2, 4, 8, or 16 column spacings.  To set, the spacing
  281. X        must precede the command, as in "4^X-t". The "set tabstop" 
  282. X        command described below does the same thing.
  283. X    ^X-f    Set the fill-column to be used with ^A-f and auto-wrap mode on
  284. X        insert.  The default value is 7/8's of the screen size, with
  285. X        a maximum of 70.  Since arguments come before commands, you
  286. X        type: 65^X-f.  The "set fillcol" command does the same thing.
  287. X    ^X-x    Set encryption key. (not well tested, but hopefully not broken)
  288. X        The CRYPT mode must be set for this to do anything.
  289. X    K    Count prefix.  The first time you type it, it is equivalent
  290. X        to an argument of 4 to the following command.  If you repeat 
  291. X        it, it becomes worth 16, the next time 64, etc...  
  292. X
  293. Editor modes
  294. ------------
  295. X    Modes are associated with buffers, and are inherited from a set of
  296. X    global modes.  To set a mode on a buffer, use ":set", to remove the
  297. X    mode, use ":unset", ":setno", or ":set" with the modename prefixed
  298. X    with "no".  To set and reset global modes, use ":setg", ":unsetg",
  299. X    ":setgno".  To display modes, use ":setall", ":modes", or
  300. X    ":setgall", ":gmodes".  (The modename "all" is also accepted as a
  301. X    dummy mode, which sets nothing, but display instead.  So vi's "set all"
  302. X    works as well.)  The possible modes are:
  303. X
  304. X    wrap    similar to vi's auto-wrap mode.  While inserting, words are
  305. X        moved to the next line if the current line gets too long.
  306. X        Unlike vi, wrapping is only attempted when a space is typed.
  307. X
  308. X    cmode    C-code mode..  Maintains current indentation level
  309. X        automatically during insert.  If a line ends with a '{',
  310. X        then the next line tabs in further.  If a line begins with
  311. X        a '}', it is lined up with its matching paired brace.  If a
  312. X        line starts with '#' it is started at the beginning of
  313. X        line.  If the global CMODE is set, then the buffer's mode
  314. X        is turned on automatically only for files ending in ".c" or
  315. X        ".h".  A common mistake is to put "set cmode" in a .vilerc
  316. X        file.  One almost always wants "setg cmode".
  317. X
  318. X    swrap    Scanwrap mode.  Text searches will continue from past the
  319. X        bottom of the file to the top, and vice-versa.
  320. X
  321. X    exact    Text searches must match the pattern exactly.  Otherwise,
  322. X        searches are case-insensitive.
  323. X
  324. X    view    View the file only.  No changes are permitted.  This is set
  325. X        automatically for the output of shell commands. 
  326. X
  327. X    magic    Allow meta-characters in search strings.  Otherwise,
  328. X        strings are taken literally.  Meta characters available are:
  329. X        ^ - matches beginning of line
  330. X        $ - matches end of line
  331. X        . - matches any single character
  332. X        * - matches any number of the previous character
  333. X        [...] - matches a character class
  334. X        \ - take the next character literally
  335. X
  336. X    asave    Automatic file saving.  Writes the file after every 256 
  337. X        characters of inserted text.  Other file changes are not 
  338. X        counted.
  339. X
  340. X    crypt    Causes files to be encrypted.  This is NOT compatible
  341. X        with the UNIX crypt(1) routines.
  342. X
  343. X    list    The buffer will be displayed with tabs and newlines made
  344. X        visible, instead of as whitespace.
  345. X
  346. X    dos    When writing the buffer, terminate lines with CR/LF pairs,
  347. X                rather than the usual single LF.  On input, if the global
  348. X        DOS mode is set, then incoming CR/LF pairs are taken as
  349. X        line terminators, and the local DOS mode is set on the
  350. X        buffer if the majority of lines ended that way.  If global
  351. X        DOS mode is _not_ set, then incoming CR characters will be
  352. X        visible on the screen. 
  353. X
  354. X    aindent Similar to C mode, above, but works for any buffer, and is
  355. X        not sensitive to {, }, or #.  Attempts to align new lines
  356. X        of text with previous lines.
  357. X
  358. X    lazy    If an attempt is made to edit a file (with ":e filename")
  359. X        which does not exist in the current directory, vile will
  360. X        try looking for a file of the same name (but in a different
  361. X        directory) which has been referenced in the tags file. 
  362. X        This mode is global to the editor, and is not "inherited"
  363. X        by buffers.  It's not very fast, either.
  364. X
  365. X    tabstop Will prompt for a new value for spacing of tabstops.  The
  366. X        only supported values are 2, 4, 8, and 16.  This value is,
  367. X        unfortunately, not settable on a per-buffer basis. 
  368. X
  369. X    fillcol Will prompt for a new value for the fill column, where
  370. X        auto-wrapping and region formatting will break lines.  This
  371. X        value is, unfortunately, not settable on a per-buffer
  372. X        basis. 
  373. X
  374. Special Character Expansion
  375. ---------------------------
  376. X
  377. X    As in vi, the % and # characters typed while responding to a prompt
  378. X    will expand to the current or "alternate" filename.  In addition,
  379. X    the colon character (":") expands to the identifier name under the
  380. X    cursor.  Expansion of ! to the last command run is not implemented.
  381. X
  382. Key Rebinding
  383. -------------
  384. X
  385. X    The vi "map", "map!", and "abbr" commands are not currently supported.
  386. X
  387. X    There is a key rebinding facility (if vile is built to include it),
  388. X    which is invoked as follows.  One must know the "english" name for the
  389. X    command being rebound.  Use ":describe-bindings" or ":apropos string"
  390. X    to find englishnames containing "string".  Then use the command:
  391. X        ":bind-key englishname keyseq"
  392. X    where keyseq is the exact keyboard sequence (i.e. single character,
  393. X    or ^X or ^A followed by a single character) to which the
  394. X    command should be bound.  In a ".vilerc" file, keyseq should be the
  395. X    printable representation of the sequence, e.g. M-a or ^X-S.
  396. X
  397. X    Examples:
  398. X     To cause the / and ? commands to perform incremental
  399. X      searches, use:
  400. X        bind-key incremental-search /
  401. X        bind-key reverse-incremental-search ?
  402. X     To change the default window-switching behavior of ^N and ^P, try
  403. X        bind-key next-line ^N
  404. X        bind-key previous-line ^P
  405. X     To cause the space bar to move forward by pages, as in them "more"
  406. X      command, use:
  407. X        bind-key next-page <sp>
  408. X
  409. X    (Space and tab can be represented with the strings: "<sp>" and 
  410. X    "<tab>".)  The englishname "rebind-key" is synonymous with "bind-key".
  411. X
  412. X    Note that even the ^A and ^X prefix characters can be rebound, using
  413. X    the dummy functions "cntl_a-prefix" and "cntl_x-prefix".  Even
  414. X    if they are rebound, however, the binding list and bind-key
  415. X    commands will refer to them as ^A and ^X.
  416. X
  417. Macros
  418. ------
  419. X
  420. X    The first type of macro in vile, is for temporary, quick macro
  421. X    usage, and lets you record a macro as you execute vile commands.
  422. X    You can then replay those keystrokes with a single key. 
  423. X
  424. X    ^X-(    Begin recording a keyboard macro.  The keystrokes you type
  425. X        are recorded, until you use ^X-).
  426. X    ^X-)    Finish recording a keyboard macro.
  427. X    ^X-&    Execute the keyboard macro.
  428. X
  429. X    Vile can also be extended (though I confess this has only been
  430. X    lightly used or tested) by defining macros and then binding
  431. X    execution of those macros to key sequences.  For example, if
  432. X    the following lines appear in a .vilerc file:
  433. X
  434. X        1 store-macro
  435. X        5 delete-til next-word
  436. X        endm
  437. X
  438. X        bind-key execute-macro-1 M-1
  439. X
  440. X    then when M-1 is executed, 5 words will be deleted.  The "-til"
  441. X    suffix on an englishname denotes that it is a vi operator style
  442. X    command, and expects to be followed by a motion command.
  443. X
  444. Differences
  445. ------------
  446. X    Of course, this really isn't vi.  Some of the following differences
  447. X    deserve changing, others do not.
  448. X
  449. X    The parser for the ':' commands is not very vi-like.  For instance,
  450. X    ":e" will prompt you for a file name.  Most commands remember their
  451. X    last argument, and will present it as the default reply to their
  452. X    prompt. 
  453. X
  454. X    The backspace, line kill, job control, etc. characters are not
  455. X    taken from the terminal settings on startup, but are hard-coded.
  456. X    The insert-mode command characters cannot even be rebound.
  457. X
  458. X    In insert mode there is no word kill (^W) or line kill (^U or @).
  459. X
  460. X    Repeated backspacing while in insert mode will move past the point
  461. X    where the insert began, until the beginning of line is reached.
  462. X
  463. X    There is no expansion of ! in filenames or shell escapes.  The
  464. X    command ":!!" does rerun the previous shell command.  Occurences of
  465. X    '#' and '%' are recognized and expanded to the previous or current
  466. X    filename.  Other punctuation (e.g.  '~') may be expanded by your
  467. X    shell (sh, csh), since it is handed filenames for expansion if they
  468. X    contain any of these characters: * ? ~ [ ] $ { }
  469. X
  470. X    Paragraph and section boundaries, for the {, }, [, and ] commands
  471. X    are not configurable, and do not exactly match those in vi.  The
  472. X    current set is:
  473. X      Paragraphs: blank lines, or lines beginning in .I .L .P .Q or .b
  474. X      Sections: lines beginning in {, formfeeds, or .S .H .N
  475. X    I think these will find more boundaries than vi, rather than fewer.
  476. X
  477. X    There is no special lisp support.  But then, when was the last time
  478. X    you heard of a lisp programmer that used vi?
  479. X
  480. X    Of course, ex and open mode aren't there.
  481. X
  482. X    There is no concept of shiftwidth.  ^D and ^T are aliased to backspace
  483. X    and tab for those whose fingers are too old for new tricks.
  484. X
  485. X    There are no "sentence" oriented motions. That is, "(" and ")" are
  486. X    missing.
  487. X
  488. X    Most, but not all, of the word-motion-with-operator and end-of-line 
  489. X    anomalies have been recreated.  One missing anomaly: In vile, "dw"
  490. X    on the last word of a line ending in whitespace deletes the
  491. X    trailing whitespace.  Vi does not delete the whitespace. 
  492. X
  493. Credits
  494. -------
  495. X    This code has been written by a _lot_ of people.  Names appearing
  496. X    within comments in the micro-Emacs source code are: Dave
  497. X    Conroy, Daniel Lawrence, John Gamble, Roger Ove, Dana Hoggatt,
  498. X    Jon Reid, Steve Wilhite, George Jones, Adam Fritz, D.R.Banks,
  499. X    Bob McNamara.  In addition, some of the "ex" code is by Steve
  500. X    Kirkendall, author of the vi clone called "elvis".  The
  501. X    changes to create vile from micro-Emacs were all done by Paul
  502. X    Fox, who can be reached at pgf@cayman.com.   (By the way, this is
  503. X    not the same Paul Fox who did the Crisp editor.)
  504. X
  505. X
  506. SHAR_EOF
  507. echo 'File vile.hlp is complete' &&
  508. chmod 0444 vile.hlp ||
  509. echo 'restore of vile.hlp failed'
  510. Wc_c="`wc -c < 'vile.hlp'`"
  511. test 24385 -eq "$Wc_c" ||
  512.     echo 'vile.hlp: original size 24385, current size' "$Wc_c"
  513. # ============= vmalloc.c ==============
  514. echo 'x - extracting vmalloc.c (Text)'
  515. sed 's/^X//' << 'SHAR_EOF' > 'vmalloc.c' &&
  516. #include "estruct.h"
  517. #include "edef.h"
  518. X
  519. /* these routines copied without permission from "The C User's Journal",
  520. X    issue of Feb. 1989.  I assume they are Copyright 1989 by them.
  521. X    They and the accompanying article were written by Eric White */
  522. X
  523. #if VMALLOC
  524. X
  525. #undef malloc
  526. #undef free
  527. #undef realloc
  528. #undef calloc
  529. #undef vverify
  530. X
  531. #include "stdio.h"
  532. #include "string.h"
  533. X
  534. char *malloc(), *calloc(), *realloc();
  535. X
  536. char *vmalloc();
  537. void vfree();
  538. void rvverify();
  539. char *vrealloc();
  540. char *vcalloc();
  541. void vdump();
  542. X
  543. typedef unsigned long ulong;
  544. X
  545. /* max buffers alloced but not yet freed */
  546. #define MAXMALLOCS 20000
  547. X
  548. /* known pattern, and how many of them */
  549. #define KP 0xaaaaaaaaL
  550. #define KPW (2*sizeof(unsigned long))
  551. X
  552. X
  553. static void trace();
  554. static void errout();
  555. X
  556. static int nummallocs = 0;
  557. struct mtype {
  558. X    unsigned char *addr;
  559. X    int size;
  560. };
  561. X
  562. static struct mtype m[MAXMALLOCS];
  563. X
  564. #define VMAL 1
  565. #define VFRE 2
  566. #define VREA 4
  567. int doverifys = VMAL|VREA;  /* |VFRE */
  568. X
  569. static void
  570. dumpbuf(x)
  571. int x;
  572. {
  573. X    unsigned char *c;
  574. X    char s [80];
  575. X    c = (unsigned char *)m[x].addr - 2;
  576. X    /* dump malloc buffer to the vmalloc file */
  577. X    while (c <= m[x].addr + m[x].size + KPW + KPW + 1) {
  578. X        sprintf(s, "%04.4lx : %02x ", (long)c, *c);
  579. X        if (c == m[x].addr)
  580. X            strcat(s," <= leading known pattern");
  581. X        if (c == m[x].addr + KPW)
  582. X            strcat(s," <= addr of malloc buffer");
  583. X        if (c == m[x].addr + m[x].size + KPW)
  584. X            strcat(s," <= trailing known pattern");
  585. X        strcat(s,"\n");
  586. X        trace(s);
  587. X        ++c;
  588. X    }
  589. }
  590. X        
  591. void
  592. rvverify(id,f,l)
  593. char *id;
  594. char *f;
  595. {
  596. X    char s[80];
  597. X    register int c;
  598. X    register struct mtype *mp;
  599. X
  600. X    
  601. X    /* verify entire malloc heap */
  602. X    for (mp = &m[nummallocs-1]; mp >= m; mp--) {
  603. X        if (mp->addr != NULL) {
  604. X            if (*(ulong *)mp->addr != KP || 
  605. X                *(ulong *)(mp->addr + sizeof (ulong)) != KP)
  606. X            {
  607. X                sprintf(s, 
  608. X        "ERROR: Malloc area corrupted (%s). %s %d\n",
  609. X                             id,f,l);
  610. X                fputs(s,stderr);
  611. X                trace(s);
  612. X                dumpbuf(mp - m);
  613. X                errout();
  614. X            }
  615. X        }
  616. X    }
  617. }        
  618. X
  619. char *
  620. vmalloc(size,f,l)
  621. char *f;
  622. {
  623. X    unsigned char *buffer;
  624. X    char *sp, s[80];
  625. X    register int c;
  626. X    register struct mtype *mp;
  627. X
  628. X    if (doverifys & VMAL)
  629. X        rvverify("vmalloc",f,l);
  630. X    if (( buffer = (unsigned char *)malloc(size + KPW + KPW)) == NULL) {
  631. X        sp = "ERROR: real malloc returned NULL\n";
  632. X        fprintf(stderr,sp);
  633. X        trace(sp);
  634. X        errout();
  635. X    }
  636. #ifdef VERBOSE
  637. X    sprintf(s,"%04.4lx:vmalloc size = %ld, %s %d\n",
  638. X        (long)buffer,(long)size,f,l);
  639. X    trace(s);
  640. #endif
  641. X    /* find a place for an entry in m */
  642. X    for (mp = m; mp < &m[MAXMALLOCS] && mp->addr != NULL; ++mp)
  643. X        ;
  644. X    if (mp == &m[MAXMALLOCS]) {
  645. X        sp = "ERROR: too many mallocs\n";
  646. X        fprintf(stderr,sp);
  647. X        trace(sp);
  648. X        errout();
  649. X    }
  650. X    mp->addr = buffer;
  651. X    mp->size = size;
  652. X    if (mp == &m[nummallocs])
  653. X        ++nummallocs;
  654. X    *(ulong *)(mp->addr) = KP;
  655. X    *(ulong *)(mp->addr + sizeof(ulong)) = KP;
  656. X    return (char *)(buffer + KPW);
  657. }
  658. X
  659. char *
  660. vcalloc(n,size,f,l)
  661. int n, size;
  662. char *f;
  663. {
  664. X    return vmalloc(n * size,f,l);
  665. }
  666. X
  667. void
  668. vfree(buffer,f,l)
  669. unsigned char *buffer;
  670. char *f;
  671. {
  672. X    unsigned char *b;
  673. X    char s[80], *sp;
  674. X    register struct mtype *mp;
  675. X
  676. X    b = buffer - KPW;
  677. X    if (doverifys & VFRE)
  678. X        rvverify("vfree",f,l);
  679. X    for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
  680. X        ;
  681. X    if (mp < m) {
  682. X        sprintf(s,"ERROR: location to free is not in list. %s %d\n",
  683. X                     f,l);
  684. X        fprintf(stderr,s);
  685. X        trace(s);
  686. X        errout();
  687. X    }
  688. #ifdef VERBOSE
  689. X    sprintf(s,"%04.4lx:vfree %s %d\n",(long)b,f,l);
  690. X    trace(s);
  691. #endif
  692. X    if (*(ulong *)mp->addr != KP || 
  693. X        *(ulong *)(mp->addr + sizeof (ulong)) != KP)
  694. X    {
  695. X        sprintf(s,"ERROR: corrupted freed block. %s %d\n", f,l);
  696. X        fprintf(stderr,s);
  697. X        trace(s);
  698. X        errout();
  699. X    }
  700. X    free(b);
  701. X    mp->addr = NULL;
  702. X    if (mp == &m[nummallocs-1])
  703. X        --nummallocs;
  704. }
  705. X
  706. char *
  707. vrealloc(buffer,size,f,l)
  708. unsigned char *buffer;
  709. int size;
  710. char *f;
  711. {
  712. X    unsigned char *b, *b2;
  713. X    char *sp, s[80];
  714. X    register int c;
  715. X    register struct mtype *mp;
  716. X
  717. X    b = buffer - KPW;
  718. X    if (doverifys & VREA)
  719. X        rvverify("vrealloc",f,l);
  720. X
  721. X    for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
  722. X        ;
  723. X    if (mp < m) {
  724. X        sprintf(s,"ERROR: location to realloc is not in list. %s %d\n",
  725. X                     sp,f,l);
  726. X        fprintf(stderr,s);
  727. X        trace(s);
  728. X        errout();
  729. X    }
  730. X
  731. #ifdef VERBOSE
  732. X    sprintf(s,"%04.4lx:vrealloc size = %ld, %s %d\n",
  733. X            (long)b,(long)size,f,l);
  734. X    trace(s);
  735. #endif
  736. X    *(ulong *)(mp->addr) = KP;
  737. X    *(ulong *)(mp->addr + sizeof (ulong)) = KP;
  738. X    b2 = (unsigned char *)realloc(b,size+KPW+KPW);
  739. X    *(ulong *)(mp->addr + mp->size + KPW) = KP;
  740. X    *(ulong *)(mp->addr + mp->size + KPW + sizeof (ulong)) = KP;
  741. X    return (char *)(b2 + KPW);
  742. }
  743. X
  744. void
  745. vdump(id)
  746. char *id;
  747. {
  748. X    char s[80];
  749. X    int x;
  750. X    sprintf(s,"=============Dump of malloc heap==========%s\n",id);
  751. X    trace(s);
  752. X    for (x = 0; x < nummallocs; ++x) {
  753. X        if (m[x].addr != NULL) {
  754. X            sprintf(s,"=========malloc buffer addr: %04.4lx\n",
  755. X                (long)m[x].addr);
  756. X            trace(s);
  757. X            sprintf(s,"=========malloc buffer size: %04x\n",
  758. X                (long)m[x].size + KPW + KPW);
  759. X            trace(s);
  760. X            dumpbuf(x);
  761. X        }
  762. X    }
  763. }
  764. X
  765. static void
  766. trace(s)
  767. char *s;
  768. {
  769. X    static FILE *out = NULL;
  770. X    if (out == NULL) {
  771. X        unlink("vmalloc.log");
  772. X        out = fopen("vmalloc.log", "w");
  773. X        setbuf(out,NULL);
  774. X    }
  775. X    fputs(s,out);
  776. }
  777. X    
  778. static void
  779. errout()
  780. {
  781. X    sleep(1);
  782. X    kill(getpid(),3);
  783. X    pause();
  784. }
  785. X
  786. setvmalloc(f,n)
  787. {
  788. X    register struct mtype *mp;
  789. X    int i,num,found;
  790. X    
  791. X    if (f)
  792. X        doverifys = n;
  793. X    rvverify("requested",__FILE__,__LINE__);
  794. X    for (mp = m, num = 0; mp < &m[MAXMALLOCS]; ++mp) {
  795. X        if (mp->addr != NULL)
  796. X            num++;
  797. X    }
  798. X    found = 0;
  799. X    { /* windows */
  800. X        register WINDOW *wp;
  801. X        for (wp=wheadp; wp != NULL; wp = wp->w_wndp)
  802. X            found++;
  803. X    }
  804. X    { /* buffers */
  805. X        register BUFFER *bp;
  806. X        for (bp=bheadp; bp != NULL; bp = bp->b_bufp) {
  807. X            LINE *lp;
  808. X            found++; /* for b_linep */
  809. X            for(lp = bp->b_linep; lp->l_fp != bp->b_linep;
  810. X                                lp = lp->l_fp)
  811. X                found++;
  812. X            if (bp->b_nmmarks)
  813. X                found++;
  814. X            if (bp->b_ulinep)
  815. X                found++;
  816. X            found++;  /* for the buffer itself */
  817. X            for (i = 0; i < 2; i++) {
  818. X                for (lp = bp->b_udstks[i]; lp != NULL;
  819. X                            lp = lp->l_nxtundo)
  820. X                    found++;
  821. X            }
  822. X        }
  823. X    }
  824. X    found += term.t_mrow+1;  /* vscreen and the rows */
  825. #if ! MEMMAP
  826. X    found += term.t_mrow+1;  /* pscreen and the rows */
  827. #endif
  828. X    if (fline)
  829. X        found++;
  830. #if ! SMALLER
  831. X    { /* user vars */
  832. X        extern UVAR uv[MAXVARS];
  833. X        for (i=0; i < MAXVARS; i++)
  834. X            if (uv[i].u_value) found++;
  835. X    }
  836. #endif
  837. #if    FILOCK
  838. X    need to count lock mallocs...
  839. #endif
  840. X    { /* searching */
  841. X        register MC    *mcptr;
  842. X
  843. X        if (patmatch)
  844. X            found++;
  845. X            
  846. X        mcptr = &mcpat[0];
  847. X        while (mcptr->mc_type != MCNIL)
  848. X        {
  849. X            if ((mcptr->mc_type & MASKCL) == CCL ||
  850. X                (mcptr->mc_type & MASKCL) == NCCL)
  851. X                if (mcptr->u.cclmap) found++;
  852. X            mcptr++;
  853. X        }
  854. X    }
  855. X    { /* kill registers */
  856. X        for (i = 0; i < NKREGS; i++) {
  857. X            KILL *kb;
  858. X            if ((kb = kbs[i].kbufh) != NULL) {
  859. X                while (kb) {
  860. X                    found++;
  861. X                    kb = kb->d_next;
  862. X                }
  863. X            }
  864. X        }
  865. X    }
  866. X    mlwrite("doverifys %s %d, outstanding mallocs: %d, %d accounted for.",
  867. X        f ? "set to":"is still", doverifys, num, found);
  868. X    return TRUE;
  869. }
  870. X
  871. #endif
  872. SHAR_EOF
  873. chmod 0444 vmalloc.c ||
  874. echo 'restore of vmalloc.c failed'
  875. Wc_c="`wc -c < 'vmalloc.c'`"
  876. test 6798 -eq "$Wc_c" ||
  877.     echo 'vmalloc.c: original size 6798, current size' "$Wc_c"
  878. # ============= vmsvt.c ==============
  879. echo 'x - extracting vmsvt.c (Text)'
  880. sed 's/^X//' << 'SHAR_EOF' > 'vmsvt.c' &&
  881. /*
  882. X *  Advanced VMS terminal driver
  883. X *
  884. X *  Knows about any terminal defined in SMGTERMS.TXT and TERMTABLE.TXT
  885. X *  located in SYS$SYSTEM.
  886. X *
  887. X *  Author:  Curtis Smith
  888. X *  Last Updated: 07/14/87
  889. X */
  890. X
  891. #include    <stdio.h>        /* Standard I/O package        */
  892. #include    "estruct.h"        /* Emacs' structures        */
  893. #include    "edef.h"        /* Emacs' definitions        */
  894. X
  895. #if    VMSVT
  896. X
  897. #include     <descrip.h>        /* Descriptor definitions    */
  898. X
  899. /*  These would normally come from iodef.h and ttdef.h  */
  900. #define IO$_SENSEMODE    0x27        /* Sense mode of terminal    */
  901. #define TT$_UNKNOWN    0x00        /* Unknown terminal        */
  902. X
  903. /** Forward references **/
  904. int vmsopen(), ttclose(), vmskopen(), vmskclose(), ttgetc(), ttputc();
  905. int ttflush(), vmsmove(), vmseeol(), vmseeop(), vmsbeep(), vmsrev();
  906. int vmscres();
  907. extern int eolexist, revexist;
  908. extern char sres[];
  909. X
  910. #if COLOR
  911. int vmsfcol(), vmsbcol();
  912. #endif
  913. X
  914. /** SMG stuff **/
  915. static char * begin_reverse, * end_reverse, * erase_to_end_line;
  916. static char * erase_whole_display;
  917. static int termtype;
  918. X
  919. #define SMG$K_BEGIN_REVERSE        0x1bf
  920. #define SMG$K_END_REVERSE        0x1d6
  921. #define SMG$K_SET_CURSOR_ABS        0x23a
  922. #define SMG$K_ERASE_WHOLE_DISPLAY    0x1da
  923. #define SMG$K_ERASE_TO_END_LINE        0x1d9
  924. X
  925. X
  926. /* Dispatch table. All hard fields just point into the terminal I/O code. */
  927. TERM    term    = {
  928. X    24 - 1,                /* Max number of rows allowable */
  929. X    /* Filled in */ - 1,        /* Current number of rows used    */
  930. X    132,                /* Max number of columns    */
  931. X    /* Filled in */ 0,        /* Current number of columns    */
  932. X    64,                /* Min margin for extended lines*/
  933. X    8,                /* Size of scroll region    */
  934. X    100,                /* # times thru update to pause */
  935. X    vmsopen,            /* Open terminal at the start    */
  936. X    ttclose,            /* Close terminal at end    */
  937. X    vmskopen,            /* Open keyboard        */
  938. X    vmskclose,            /* Close keyboard        */
  939. X    ttgetc,                /* Get character from keyboard    */
  940. X    ttputc,                /* Put character to display    */
  941. X    ttflush,            /* Flush output buffers        */
  942. X    vmsmove,            /* Move cursor, origin 0    */
  943. X    vmseeol,            /* Erase to end of line        */
  944. X    vmseeop,            /* Erase to end of page        */
  945. X    vmsbeep,            /* Beep                */
  946. X    vmsrev,                /* Set reverse video state    */
  947. X    vmscres                /* Change screen resolution    */
  948. #if    COLOR
  949. X    , vmsfcol,            /* Set forground color        */
  950. X    vmsbcol                /* Set background color        */
  951. #endif
  952. };
  953. X
  954. /***
  955. X *  ttputs  -  Send a string to ttputc
  956. X *
  957. X *  Nothing returned
  958. X ***/
  959. ttputs(string)
  960. char * string;                /* String to write        */
  961. {
  962. X    if (string)
  963. X        while (*string != '\0')
  964. X            ttputc(*string++);
  965. }
  966. X
  967. X
  968. /***
  969. X *  vmsmove  -  Move the cursor (0 origin)
  970. X *
  971. X *  Nothing returned
  972. X ***/
  973. vmsmove(row, col)
  974. int row;                /* Row position            */
  975. int col;                /* Column position        */
  976. {
  977. X    char buffer[32];
  978. X    int ret_length;
  979. X    static int request_code = SMG$K_SET_CURSOR_ABS;
  980. X    static int max_buffer_length = sizeof(buffer);
  981. X    static int arg_list[3] = { 2 };
  982. X    register char * cp;
  983. X    
  984. X    register int i;
  985. X
  986. X    /* Set the arguments into the arg_list array
  987. X     * SMG assumes the row/column positions are 1 based (boo!)
  988. X     */
  989. X    arg_list[1] = row + 1;
  990. X    arg_list[2] = col + 1;
  991. X
  992. X    if ((smg$get_term_data(        /* Get terminal data        */
  993. X        &termtype,        /* Terminal table address    */
  994. X        &request_code,        /* Request code            */
  995. X        &max_buffer_length,    /* Maximum buffer length    */
  996. X        &ret_length,        /* Return length        */
  997. X        buffer,            /* Capability data buffer    */
  998. X        arg_list)        /* Argument list array        */
  999. X
  1000. X    /* We'll know soon enough if this doesn't work        */
  1001. X            & 1) == 0) {
  1002. X                ttputs("OOPS");
  1003. X                return;
  1004. X            }
  1005. X
  1006. X    /* Send out resulting sequence                */
  1007. X    i = ret_length;
  1008. X    cp = buffer;
  1009. X    while (i-- > 0)
  1010. X        ttputc(*cp++);
  1011. }
  1012. X
  1013. X
  1014. /***
  1015. X *  vmsrev  -  Set the reverse video status
  1016. X *
  1017. X *  Nothing returned
  1018. X ***/
  1019. vmsrev(status)
  1020. int status;                /* TRUE if setting reverse    */
  1021. {
  1022. X    if (status)
  1023. X        ttputs(begin_reverse);
  1024. X    else 
  1025. X        ttputs(end_reverse);
  1026. }
  1027. X
  1028. /***
  1029. X *  vmscres  -  Change screen resolution (which it doesn't)
  1030. X *
  1031. X *  Nothing returned
  1032. X ***/
  1033. vmscres()
  1034. {
  1035. X    /* But it could.  For vt100/vt200s, one could switch from
  1036. X    80 and 132 columns modes */
  1037. }
  1038. X
  1039. X
  1040. #if    COLOR
  1041. /***
  1042. X *  vmsfcol  -  Set the forground color (not implimented)
  1043. X *
  1044. X *  Nothing returned
  1045. X ***/
  1046. vmsfcol()
  1047. {
  1048. }
  1049. X
  1050. /***
  1051. X *  vmsbcol  -  Set the background color (not implimented)
  1052. X *
  1053. X *  Nothing returned
  1054. X ***/
  1055. vmsbcol()
  1056. {
  1057. }
  1058. #endif
  1059. X
  1060. /***
  1061. X *  vmseeol  -  Erase to end of line
  1062. X *
  1063. X *  Nothing returned
  1064. X ***/
  1065. vmseeol()
  1066. {
  1067. X    ttputs(erase_to_end_line);
  1068. }
  1069. X
  1070. X
  1071. /***
  1072. X *  vmseeop  -  Erase to end of page (clear screen)
  1073. X *
  1074. X *  Nothing returned
  1075. X ***/
  1076. vmseeop()
  1077. {
  1078. X    ttputs(erase_whole_display);
  1079. }
  1080. X
  1081. X
  1082. /***
  1083. X *  vmsbeep  -  Ring the bell
  1084. X *
  1085. X *  Nothing returned
  1086. X ***/
  1087. vmsbeep()
  1088. {
  1089. X    ttputc('\007');
  1090. }
  1091. X
  1092. X
  1093. /***
  1094. X *  vmsgetstr  -  Get an SMG string capability by name
  1095. X *
  1096. X *  Returns:    Escape sequence
  1097. X *        NULL    No escape sequence available
  1098. X ***/ 
  1099. char * vmsgetstr(request_code)
  1100. int request_code;            /* Request code            */
  1101. {
  1102. X    register char * result;
  1103. X    static char seq_storage[1024];
  1104. X    static char * buffer = seq_storage;
  1105. X    static int arg_list[2] = { 1, 1 };
  1106. X    int max_buffer_length, ret_length;
  1107. X
  1108. X    /*  Precompute buffer length */
  1109. X    
  1110. X    max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
  1111. X
  1112. X    /* Get terminal commands sequence from master table */
  1113. X
  1114. X    if ((smg$get_term_data(    /* Get terminal data        */
  1115. X        &termtype,    /* Terminal table address    */
  1116. X        &request_code,    /* Request code            */
  1117. X        &max_buffer_length,/* Maximum buffer length    */
  1118. X        &ret_length,    /* Return length        */
  1119. X        buffer,        /* Capability data buffer    */
  1120. X        arg_list)    /* Argument list array        */
  1121. X
  1122. X    /* If this doesn't work, try again with no arguments */
  1123. X    
  1124. X        & 1) == 0 && 
  1125. X
  1126. X        (smg$get_term_data(    /* Get terminal data        */
  1127. X            &termtype,    /* Terminal table address    */
  1128. X            &request_code,    /* Request code            */
  1129. X            &max_buffer_length,/* Maximum buffer length    */
  1130. X            &ret_length,    /* Return length        */
  1131. X            buffer)        /* Capability data buffer    */
  1132. X
  1133. X    /* Return NULL pointer if capability is not available */
  1134. X    
  1135. X            & 1) == 0)
  1136. X                return NULL;
  1137. X
  1138. X    /* Check for empty result */
  1139. X    if (ret_length == 0)
  1140. X        return NULL;
  1141. X    
  1142. X    /* Save current position so we can return it to caller */
  1143. X
  1144. X    result = buffer;
  1145. X
  1146. X    /* NIL terminate the sequence for return */
  1147. X    
  1148. X    buffer[ret_length] = 0;
  1149. X
  1150. X    /* Advance buffer */
  1151. X
  1152. X    buffer += ret_length + 1;
  1153. X
  1154. X    /* Return capability to user */
  1155. X    return result;
  1156. }
  1157. X
  1158. X
  1159. /** I/O information block definitions **/
  1160. struct iosb {            /* I/O status block            */
  1161. X    short    i_cond;        /* Condition value            */
  1162. X    short    i_xfer;        /* Transfer count            */
  1163. X    long    i_info;        /* Device information            */
  1164. };
  1165. struct termchar {        /* Terminal characteristics        */
  1166. X    char    t_class;    /* Terminal class            */
  1167. X    char    t_type;        /* Terminal type            */
  1168. X    short    t_width;    /* Terminal width in characters        */
  1169. X    long    t_mandl;    /* Terminal's mode and length        */
  1170. X    long    t_extend;    /* Extended terminal characteristics    */
  1171. };
  1172. static struct termchar tc;    /* Terminal characteristics        */
  1173. X
  1174. /***
  1175. X *  vmsgtty - Get terminal type from system control block
  1176. X *
  1177. X *  Nothing returned
  1178. X ***/
  1179. vmsgtty()
  1180. {
  1181. X    short fd;
  1182. X    int status;
  1183. X    struct iosb iostatus;
  1184. X    $DESCRIPTOR(devnam, "SYS$INPUT");
  1185. X
  1186. X    /* Assign input to a channel */
  1187. X    status = sys$assign(&devnam, &fd, 0, 0);
  1188. X    if ((status & 1) == 0)
  1189. X        exit (status);
  1190. X
  1191. X    /* Get terminal characteristics */
  1192. X    status = sys$qiow(        /* Queue and wait        */
  1193. X        0,            /* Wait on event flag zero    */
  1194. X        fd,            /* Channel to input terminal    */
  1195. X        IO$_SENSEMODE,        /* Get current characteristic    */
  1196. X        &iostatus,        /* Status after operation    */
  1197. X        0, 0,            /* No AST service        */
  1198. X        &tc,            /* Terminal characteristics buf */
  1199. X        sizeof(tc),        /* Size of the buffer        */
  1200. X        0, 0, 0, 0);        /* P3-P6 unused            */
  1201. X
  1202. X    /* De-assign the input device */
  1203. X    if ((sys$dassgn(fd) & 1) == 0)
  1204. X        exit(status);
  1205. X
  1206. X    /* Jump out if bad status */
  1207. X    if ((status & 1) == 0)
  1208. X        exit(status);
  1209. X    if ((iostatus.i_cond & 1) == 0)
  1210. X        exit(iostatus.i_cond);
  1211. }
  1212. X
  1213. X
  1214. /***
  1215. X *  vmsopen  -  Get terminal type and open terminal
  1216. X *
  1217. X *  Nothing returned
  1218. X ***/
  1219. vmsopen()
  1220. {
  1221. X    /* Get terminal type */
  1222. X    vmsgtty();
  1223. X    if (tc.t_type == TT$_UNKNOWN) {
  1224. X        printf("Terminal type is unknown!\n");
  1225. X        printf("Try set your terminal type with SET TERMINAL/INQUIRE\n");
  1226. X        printf("Or get help on SET TERMINAL/DEVICE_TYPE\n");
  1227. X        exit(3);
  1228. X    }
  1229. X
  1230. X    /* Access the system terminal definition table for the        */
  1231. X    /* information of the terminal type returned by IO$_SENSEMODE    */
  1232. X    if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
  1233. X        return -1;
  1234. X        
  1235. X    /* Set sizes */
  1236. X    term.t_nrow = ((unsigned int) tc.t_mandl >> 24) - 1;
  1237. X    term.t_ncol = tc.t_width;
  1238. X
  1239. X    /* Get some capabilities */
  1240. X    begin_reverse = vmsgetstr(SMG$K_BEGIN_REVERSE);
  1241. X    end_reverse = vmsgetstr(SMG$K_END_REVERSE);
  1242. X    revexist = begin_reverse != NULL && end_reverse != NULL;
  1243. X    erase_to_end_line = vmsgetstr(SMG$K_ERASE_TO_END_LINE);
  1244. X    eolexist = erase_whole_display != NULL;
  1245. X    erase_whole_display = vmsgetstr(SMG$K_ERASE_WHOLE_DISPLAY);
  1246. X
  1247. X    /* Set resolution */
  1248. X    strcpy(sres, "NORMAL");
  1249. X
  1250. X    /* Open terminal I/O drivers */
  1251. X    ttopen();
  1252. }
  1253. X
  1254. X
  1255. /***
  1256. X *  vmskopen  -  Open keyboard (not used)
  1257. X *
  1258. X *  Nothing returned
  1259. X ***/
  1260. vmskopen()
  1261. {
  1262. }
  1263. X
  1264. X
  1265. /***
  1266. X *  vmskclose  -  Close keyboard (not used)
  1267. X *
  1268. X *  Nothing returned
  1269. X ***/
  1270. vmskclose()
  1271. {
  1272. }
  1273. X
  1274. X
  1275. /***
  1276. X *  fnclabel  -  Label function keys (not used)
  1277. X *
  1278. X *  Nothing returned
  1279. X ***/
  1280. #if    FLABEL
  1281. fnclabel(f, n)        /* label a function key */
  1282. int f,n;    /* default flag, numeric argument [unused] */
  1283. {
  1284. X    /* on machines with no function keys...don't bother */
  1285. X    return(TRUE);
  1286. }
  1287. #endif
  1288. X
  1289. X
  1290. /***
  1291. X *  spal  -  Set palette type  (Are you kidding?)
  1292. X *
  1293. X *  Nothing returned
  1294. X ***/
  1295. spal()
  1296. {
  1297. }
  1298. X
  1299. #else
  1300. X
  1301. /***
  1302. X *  hellovms  -  Avoid error because of empty module
  1303. X *
  1304. X *  Nothing returned
  1305. X ***/
  1306. hellovms()
  1307. {
  1308. }
  1309. X
  1310. #endif
  1311. SHAR_EOF
  1312. chmod 0444 vmsvt.c ||
  1313. echo 'restore of vmsvt.c failed'
  1314. Wc_c="`wc -c < 'vmsvt.c'`"
  1315. test 9271 -eq "$Wc_c" ||
  1316.     echo 'vmsvt.c: original size 9271, current size' "$Wc_c"
  1317. # ============= vt52.c ==============
  1318. echo 'x - extracting vt52.c (Text)'
  1319. sed 's/^X//' << 'SHAR_EOF' > 'vt52.c' &&
  1320. /*
  1321. X * The routines in this file
  1322. X * provide support for VT52 style terminals
  1323. X * over a serial line. The serial I/O services are
  1324. X * provided by routines in "termio.c". It compiles
  1325. X * into nothing if not a VT52 style device. The
  1326. X * bell on the VT52 is terrible, so the "beep"
  1327. X * routine is conditionalized on defining BEL.
  1328. X */
  1329. #define    termdef    1            /* don't define "term" external */
  1330. X
  1331. #include        <stdio.h>
  1332. #include        "estruct.h"
  1333. #include    "edef.h"
  1334. X
  1335. #if     VT52
  1336. X
  1337. #define NROW    24                      /* Screen size.                 */
  1338. #define NCOL    80                      /* Edit if you want to.         */
  1339. #define    MARGIN    8            /* size of minimim margin and    */
  1340. #define    SCRSIZ    64            /* scroll size for extended lines */
  1341. #define    NPAUSE    100            /* # times thru update to pause */
  1342. #define BIAS    0x20                    /* Origin 0 coordinate bias.    */
  1343. #define ESC     0x1B                    /* ESC character.               */
  1344. #define BEL     0x07                    /* ascii bell character         */
  1345. X
  1346. extern  int     ttopen();               /* Forward references.          */
  1347. extern  int     ttgetc();
  1348. extern  int     ttputc();
  1349. extern  int     ttflush();
  1350. extern  int     ttclose();
  1351. extern  int     vt52move();
  1352. extern  int     vt52eeol();
  1353. extern  int     vt52eeop();
  1354. extern  int     vt52beep();
  1355. extern  int     vt52open();
  1356. extern    int    vt52rev();
  1357. extern    int    vt52cres();
  1358. extern    int    vt52kopen();
  1359. extern    int    vt52kclose();
  1360. X
  1361. #if    COLOR
  1362. extern    int    vt52fcol();
  1363. extern    int    vt52bcol();
  1364. #endif
  1365. X
  1366. /*
  1367. X * Dispatch table. All the
  1368. X * hard fields just point into the
  1369. X * terminal I/O code.
  1370. X */
  1371. TERM    term    = {
  1372. X    NROW-1,
  1373. X        NROW-1,
  1374. X        NCOL,
  1375. X        NCOL,
  1376. X    MARGIN,
  1377. X    SCRSIZ,
  1378. X    NPAUSE,
  1379. X        &vt52open,
  1380. X        &ttclose,
  1381. X    &vt52kopen,
  1382. X    &vt52kclose,
  1383. X        &ttgetc,
  1384. X        &ttputc,
  1385. X        &ttflush,
  1386. X        &vt52move,
  1387. X        &vt52eeol,
  1388. X        &vt52eeop,
  1389. X        &vt52beep,
  1390. X        &vt52rev,
  1391. X        &vt52cres
  1392. #if    COLOR
  1393. X    , &vt52fcol,
  1394. X    &vt52bcol
  1395. #endif
  1396. };
  1397. X
  1398. vt52move(row, col)
  1399. {
  1400. X        ttputc(ESC);
  1401. X        ttputc('Y');
  1402. X        ttputc(row+BIAS);
  1403. X        ttputc(col+BIAS);
  1404. }
  1405. X
  1406. vt52eeol()
  1407. {
  1408. X        ttputc(ESC);
  1409. X        ttputc('K');
  1410. }
  1411. X
  1412. vt52eeop()
  1413. {
  1414. X        ttputc(ESC);
  1415. X        ttputc('J');
  1416. }
  1417. X
  1418. vt52rev(status)    /* set the reverse video state */
  1419. X
  1420. int status;    /* TRUE = reverse video, FALSE = normal video */
  1421. X
  1422. {
  1423. X    /* can't do this here, so we won't */
  1424. }
  1425. X
  1426. vt52cres()    /* change screen resolution - (not here though) */
  1427. X
  1428. {
  1429. X    return(TRUE);
  1430. }
  1431. X
  1432. spal()        /* change palette string */
  1433. X
  1434. {
  1435. X    /*    Does nothing here    */
  1436. }
  1437. X
  1438. #if    COLOR
  1439. vt52fcol()    /* set the forground color [NOT IMPLIMENTED] */
  1440. {
  1441. }
  1442. X
  1443. vt52bcol()    /* set the background color [NOT IMPLIMENTED] */
  1444. {
  1445. }
  1446. #endif
  1447. X
  1448. vt52beep()
  1449. {
  1450. #ifdef  BEL
  1451. X        ttputc(BEL);
  1452. X        ttflush();
  1453. #endif
  1454. }
  1455. X
  1456. vt52open()
  1457. {
  1458. #if     V7 | BSD
  1459. X        register char *cp;
  1460. X        char *getenv();
  1461. X
  1462. X        if ((cp = getenv("TERM")) == NULL) {
  1463. X                puts("Shell variable TERM not defined!");
  1464. X                exit(1);
  1465. X        }
  1466. X        if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
  1467. X                puts("Terminal type not 'vt52'or 'z19' !");
  1468. X                exit(1);
  1469. X        }
  1470. #endif
  1471. X        ttopen();
  1472. }
  1473. X
  1474. vt52kopen()
  1475. X
  1476. {
  1477. }
  1478. X
  1479. vt52kclose()
  1480. X
  1481. {
  1482. }
  1483. X
  1484. X
  1485. #if    FLABEL
  1486. fnclabel(f, n)        /* label a function key */
  1487. X
  1488. int f,n;    /* default flag, numeric argument [unused] */
  1489. X
  1490. {
  1491. X    /* on machines with no function keys...don't bother */
  1492. X    return(TRUE);
  1493. }
  1494. #endif
  1495. #else
  1496. X
  1497. vt52hello()
  1498. X
  1499. {
  1500. }
  1501. X
  1502. #endif
  1503. SHAR_EOF
  1504. chmod 0444 vt52.c ||
  1505. echo 'restore of vt52.c failed'
  1506. Wc_c="`wc -c < 'vt52.c'`"
  1507. test 3386 -eq "$Wc_c" ||
  1508.     echo 'vt52.c: original size 3386, current size' "$Wc_c"
  1509. # ============= window.c ==============
  1510. echo 'x - extracting window.c (Text)'
  1511. sed 's/^X//' << 'SHAR_EOF' > 'window.c' &&
  1512. /*
  1513. X * Window management. Some of the functions are internal, and some are
  1514. X * attached to keys that the user actually types.
  1515. X */
  1516. X
  1517. #include        <stdio.h>
  1518. #include        "estruct.h"
  1519. #include    "edef.h"
  1520. X
  1521. #if    MEGAMAX & ST520
  1522. overlay    "window"
  1523. #endif
  1524. X
  1525. /*
  1526. X * Reposition dot's line to line "n" of the window. If the argument is
  1527. X * positive, it is that line. If it is negative it is that line from the
  1528. X * bottom. If it is 0 the window is centered around dot (this is what 
  1529. X * the standard redisplay code does). Defaults to 0.
  1530. X */
  1531. reposition(f, n)
  1532. {
  1533. X    if (f == FALSE)    /* default to 0 to center screen */
  1534. X    n = 0;
  1535. X    curwp->w_force = n;
  1536. X    curwp->w_flag |= WFFORCE;
  1537. X    return (TRUE);
  1538. }
  1539. X
  1540. /*
  1541. X * Refresh the screen. With no argument, it just does the refresh. With an
  1542. X * argument it recenters "." in the current window.
  1543. X */
  1544. refresh(f, n)
  1545. {
  1546. #if    NeWS    /* see if the window has changed size */
  1547. X    newsrefresh() ;
  1548. #endif    
  1549. X
  1550. X    if (f == FALSE) {
  1551. X        sgarbf = TRUE;
  1552. X    } else {
  1553. X            curwp->w_force = 0;             /* Center dot. */
  1554. X            curwp->w_flag |= WFFORCE;
  1555. X    }
  1556. X
  1557. #if     NeWS
  1558. X    newsreportmodes() ;
  1559. #endif
  1560. X    return (TRUE);
  1561. }
  1562. X
  1563. /*
  1564. X * The command make the next window (next => down the screen) the current
  1565. X * window. There are no real errors, although the command does nothing if
  1566. X * there is only 1 window on the screen.
  1567. X *
  1568. X * with an argument this command finds the <n>th window from the top
  1569. X *
  1570. X */
  1571. nextwind(f, n)
  1572. int f, n;    /* default flag and numeric argument */
  1573. {
  1574. X    register WINDOW *wp;
  1575. X    register int nwindows;        /* total number of windows */
  1576. X
  1577. X    if (f) {
  1578. X
  1579. X        /* first count the # of windows */
  1580. X        wp = wheadp;
  1581. X        nwindows = 1;
  1582. X        while (wp->w_wndp != NULL) {
  1583. X            nwindows++;
  1584. X            wp = wp->w_wndp;
  1585. X        }
  1586. X
  1587. X        /* if the argument is negative, it is the nth window
  1588. X           from the bottom of the screen            */
  1589. X        if (n < 0)
  1590. X            n = nwindows + n + 1;
  1591. X
  1592. X        /* if an argument, give them that window from the top */
  1593. X        if (n > 0 && n <= nwindows) {
  1594. X            wp = wheadp;
  1595. X            while (--n)
  1596. X                wp = wp->w_wndp;
  1597. X        } else {
  1598. X            mlwrite("Window number out of range");
  1599. X            return(FALSE);
  1600. X        }
  1601. X    } else {
  1602. X        if ((wp = curwp->w_wndp) == NULL)
  1603. X            wp = wheadp;
  1604. X    }
  1605. X    curwp = wp;
  1606. X    make_current(curwp->w_bufp);
  1607. X    upmode();
  1608. X    return (TRUE);
  1609. }
  1610. X
  1611. poswind(f,n)
  1612. {
  1613. X    register int c;
  1614. X    register int rows;
  1615. X    int s;
  1616. X
  1617. X    c = kbd_key();
  1618. X    if (c == abortc)
  1619. X        return FALSE;
  1620. X
  1621. X    if (c == '+' || c == '\r' || c == 'H') {
  1622. X        rows = 1;
  1623. X    } else if (c == '.' || c == 'M') {
  1624. X        rows = 0;
  1625. X    } else if (c == '-' || c == 'L') {
  1626. X        rows = -1;
  1627. X    } else {
  1628. X        TTbeep();
  1629. X        return FALSE;
  1630. X    }
  1631. X
  1632. X    if (f == TRUE) {
  1633. X        s = gotoline(f,n);
  1634. X        if (s != TRUE)
  1635. X            return(s);
  1636. X    }
  1637. X    return(reposition(TRUE,rows));
  1638. }
  1639. X
  1640. /*
  1641. X * This command makes the previous window (previous => up the screen) the
  1642. X * current window. There arn't any errors, although the command does not do a
  1643. X * lot if there is 1 window.
  1644. X */
  1645. prevwind(f, n)
  1646. {
  1647. X    register WINDOW *wp1;
  1648. X    register WINDOW *wp2;
  1649. X
  1650. X    /* if we have an argument, we mean the nth window from the bottom */
  1651. X    if (f)
  1652. X        return(nextwind(f, -n));
  1653. X
  1654. X    wp1 = wheadp;
  1655. X    wp2 = curwp;
  1656. X
  1657. X    if (wp1 == wp2)
  1658. X        wp2 = NULL;
  1659. X
  1660. X    while (wp1->w_wndp != wp2)
  1661. X        wp1 = wp1->w_wndp;
  1662. X
  1663. X    curwp = wp1;
  1664. X    make_current(curwp->w_bufp);
  1665. X    upmode();
  1666. X    return (TRUE);
  1667. }
  1668. X
  1669. /*
  1670. X * This command moves the current window down by "arg" lines. Recompute the
  1671. X * top line in the window. The move up and move down code is almost completely
  1672. X * the same; most of the work has to do with reframing the window, and picking
  1673. X * a new dot. We share the code by having "move down" just be an interface to
  1674. X * "move up". Magic.
  1675. X */
  1676. mvdnwind(f, n)
  1677. int n;
  1678. {
  1679. X    return (mvupwind(f, -n));
  1680. }
  1681. X
  1682. /*
  1683. X * Move the current window up by "arg" lines. Recompute the new top line of
  1684. X * the window. Look to see if "." is still on the screen. If it is, you win.
  1685. X * If it isn't, then move "." to center it in the new framing of the window
  1686. X * (this command does not really move "." (except as above); it moves the 
  1687. X * frame).
  1688. X */
  1689. mvupwind(f, n)
  1690. int n;
  1691. {
  1692. X    register LINE *lp;
  1693. X    register int i;
  1694. X    int was_n = n;
  1695. X
  1696. X    lp = curwp->w_linep;
  1697. X
  1698. X    if (n < 0) {
  1699. X        while (n++ && lforw(lp) != curbp->b_linep)
  1700. X            lp = lforw(lp);
  1701. X    } else {
  1702. X        while (n-- && lback(lp)!=curbp->b_linep)
  1703. X            lp = lback(lp);
  1704. X    }
  1705. X
  1706. X    curwp->w_linep = lp;
  1707. X    curwp->w_flag |= WFHARD|WFMODE;
  1708. X
  1709. X    /* is it still in the window */
  1710. X    for (i = 0; i < curwp->w_ntrows; ++i) {
  1711. X        if (lp == curwp->w_dotp)
  1712. X            return (TRUE);
  1713. X        if (lforw(lp) == curbp->b_linep)
  1714. X            break;
  1715. X        lp = lforw(lp);
  1716. X    }
  1717. X    /* now lp is either just past the window bottom, or
  1718. X        it's the last line of the file */
  1719. X
  1720. X    /* preserve the current column */
  1721. X    if (curgoal < 0)
  1722. X        curgoal = getccol(FALSE);
  1723. X
  1724. X    if (was_n < 0)
  1725. X        curwp->w_dotp  = curwp->w_linep;
  1726. X    else
  1727. X        curwp->w_dotp  = lback(lp);
  1728. X    curwp->w_doto  = getgoal(curwp->w_dotp);
  1729. X    return (TRUE);
  1730. }
  1731. X
  1732. mvdnnxtwind(f, n)
  1733. {
  1734. X    nextwind(FALSE, 1);
  1735. X    mvdnwind(f, n);
  1736. X    prevwind(FALSE, 1);
  1737. }
  1738. X
  1739. mvupnxtwind(f, n)
  1740. {
  1741. X    nextwind(FALSE, 1);
  1742. X    mvupwind(f, n);
  1743. X    prevwind(FALSE, 1);
  1744. }
  1745. X
  1746. mvrightwind(f,n)
  1747. {
  1748. X    int move, col;
  1749. X
  1750. X    if (f)
  1751. X        move = n;
  1752. X    else
  1753. X        move = term.t_ncol/3;
  1754. X
  1755. X    if (curwp->w_sideways + move > (col = getccol(FALSE)) - 1) {
  1756. X        TTbeep();
  1757. X        return FALSE;
  1758. X    }
  1759. X
  1760. X    curwp->w_sideways += move;
  1761. X
  1762. X        curwp->w_flag  |= WFHARD|WFMOVE;
  1763. X
  1764. X    return TRUE;
  1765. }
  1766. X
  1767. mvleftwind(f,n)
  1768. {
  1769. X    if (f)
  1770. X        curwp->w_sideways -= n;
  1771. X    else
  1772. X        curwp->w_sideways -= term.t_ncol/3;
  1773. X
  1774. X    if (curwp->w_sideways < 0)
  1775. X        curwp->w_sideways = 0;
  1776. X
  1777. X        curwp->w_flag  |= WFHARD|WFMOVE;
  1778. X
  1779. X    return TRUE;
  1780. }
  1781. X
  1782. /*
  1783. X * This command makes the current window the only window on the screen.
  1784. X * Try to set the framing so that "." does not have to move on the
  1785. X * display. Some care has to be taken to keep the values of dot and mark in
  1786. X * the buffer structures right if the distruction of a window makes a buffer
  1787. X * become undisplayed.
  1788. X */
  1789. onlywind(f, n)
  1790. {
  1791. X        register WINDOW *wp;
  1792. X        register LINE   *lp;
  1793. X        register int    i;
  1794. X
  1795. X        wp = wheadp;
  1796. X        while (wp != NULL) {
  1797. X        register WINDOW *nwp;
  1798. X        nwp = wp->w_wndp;
  1799. X            if (wp != curwp) {
  1800. X                    if (--wp->w_bufp->b_nwnd == 0)
  1801. X                            undispbuff(wp->w_bufp,wp);
  1802. X                    free((char *) wp);
  1803. X            }
  1804. X                wp = nwp;
  1805. X        }
  1806. X        wheadp = curwp;
  1807. X        wheadp->w_wndp = NULL;
  1808. X        lp = curwp->w_linep;
  1809. X        i  = curwp->w_toprow;
  1810. X        while (i!=0 && lback(lp)!=curbp->b_linep) {
  1811. X                --i;
  1812. X                lp = lback(lp);
  1813. X        }
  1814. X        curwp->w_toprow = 0;
  1815. X        curwp->w_ntrows = term.t_nrow-1;
  1816. X        curwp->w_linep  = lp;
  1817. X        curwp->w_flag  |= WFMODE|WFHARD;
  1818. X        return (TRUE);
  1819. }
  1820. X
  1821. /*
  1822. X * Delete the current window, placing its space in the window above,
  1823. X * or, if it is the top window, the window below.
  1824. X */
  1825. X
  1826. delwind(f,n)
  1827. int f, n;    /* arguments are ignored for this command */
  1828. {
  1829. X    return delwp(curwp);
  1830. }
  1831. X
  1832. delwp(thewp)
  1833. WINDOW *thewp;
  1834. {
  1835. X    register WINDOW *wp;    /* window to recieve deleted space */
  1836. X    register LINE *lp;    /* line pointer */
  1837. X    register int i;
  1838. X
  1839. X    /* if there is only one window, don't delete it */
  1840. X    if (wheadp->w_wndp == NULL) {
  1841. X        mlwrite("Cannot delete the only window");
  1842. X        return(FALSE);
  1843. X    }
  1844. X
  1845. X    /* find recieving window and give up our space */
  1846. X    if (thewp == wheadp) { /* there's nothing before */
  1847. X        /* find the next window down */
  1848. X        wp = thewp->w_wndp;
  1849. X                lp = wp->w_linep;
  1850. X                /* the prev. window (thewp) has wp->w_toprow rows in it */
  1851. X                for (i = wp->w_toprow;
  1852. X                         i > 0 && lback(lp) != wp->w_bufp->b_linep; --i)
  1853. X                        lp = lback(lp);
  1854. X                wp->w_linep  = lp;
  1855. X        wp->w_ntrows += wp->w_toprow;  /* add in the new rows */
  1856. X        wp->w_toprow = 0;    /* and we're at the top of the screen */
  1857. X        wheadp = wp;    /* and at the top of the list as well */
  1858. X    } else {
  1859. X        /* find window before thewp in linked list */
  1860. X        for (wp = wheadp; wp->w_wndp != thewp; wp = wp->w_wndp)
  1861. X            ;
  1862. X        /* add thewp's rows to the next window up */
  1863. X        wp->w_ntrows += thewp->w_ntrows+1;
  1864. X        
  1865. X        wp->w_wndp = thewp->w_wndp; /* make their next window ours */
  1866. X    }
  1867. X
  1868. X    /* get rid of the current window */
  1869. X    if (--thewp->w_bufp->b_nwnd == 0)
  1870. X        undispbuff(thewp->w_bufp,thewp);
  1871. X    free((char *)thewp);
  1872. X    if (thewp == curwp) {
  1873. X        curwp = wp;
  1874. X        curwp->w_flag |= WFHARD;
  1875. X        make_current(curwp->w_bufp);
  1876. X    }
  1877. X    upmode();
  1878. X    return(TRUE);
  1879. }
  1880. X
  1881. /*
  1882. X    Split the current window.  A window smaller than 3 lines cannot be
  1883. X    split.  An argument of 1 forces the cursor into the upper window, an
  1884. X    argument of two forces the cursor to the lower window.  The only other
  1885. X    error that is possible is a "malloc" failure allocating the structure
  1886. X    for the new window.
  1887. X */
  1888. splitwind(f, n)
  1889. {
  1890. X        register WINDOW *wp;
  1891. X        register LINE   *lp;
  1892. X        register int    ntru;
  1893. X        register int    ntrl;
  1894. X        register int    ntrd;
  1895. X        register WINDOW *wp1;
  1896. X        register WINDOW *wp2;
  1897. X    register int i;
  1898. X
  1899. X        if (curwp->w_ntrows < 3) {
  1900. X                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  1901. X                return (FALSE);
  1902. X        }
  1903. X        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  1904. X                mlwrite("[OUT OF MEMORY]");
  1905. X                return (FALSE);
  1906. X        }
  1907. X        ++curbp->b_nwnd;                        /* Displayed twice.     */
  1908. X        wp->w_bufp  = curbp;
  1909. X        wp->w_dotp  = curwp->w_dotp;
  1910. X        wp->w_doto  = curwp->w_doto;
  1911. X        wp->w_mkp = curwp->w_mkp;
  1912. X        wp->w_mko = curwp->w_mko;
  1913. X        wp->w_linep = curwp->w_linep;
  1914. X        wp->w_ldmkp = curwp->w_ldmkp;
  1915. X        wp->w_ldmko = curwp->w_ldmko;
  1916. X        wp->w_sideways  = curwp->w_sideways;
  1917. X        wp->w_flag  = 0;
  1918. X        wp->w_force = 0;
  1919. #if    COLOR
  1920. X    /* set the colors of the new window */
  1921. X    wp->w_fcolor = gfcolor;
  1922. X    wp->w_bcolor = gbcolor;
  1923. #endif
  1924. X        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  1925. X        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  1926. X        lp = curwp->w_linep;
  1927. X        ntrd = 0;
  1928. X        while (lp != curwp->w_dotp) {
  1929. X                ++ntrd;
  1930. X                lp = lforw(lp);
  1931. X        }
  1932. X    /* ntrd is now the row containing dot */
  1933. X        if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  1934. X                /* Old is upper window. */
  1935. X            /* Adjust the top line if necessary */
  1936. X                if (ntrd == ntru)               /* Hit mode line.       */
  1937. X            if (ntrl > 1) {
  1938. X                ntru++;
  1939. X                ntrl--;
  1940. X            } else
  1941. X                            curwp->w_linep = lforw(curwp->w_linep);
  1942. X                curwp->w_ntrows = ntru; /* new size */
  1943. X        /* insert new window after curwp in window list */
  1944. X                wp->w_wndp = curwp->w_wndp;
  1945. X                curwp->w_wndp = wp;
  1946. X        /* set new window's position and size */
  1947. X                wp->w_toprow = curwp->w_toprow+ntru+1;
  1948. X                wp->w_ntrows = ntrl;
  1949. X        /* try to keep lower from reframing */
  1950. X        for (i = ntru+1; i > 0 &&
  1951. X                 wp->w_linep != wp->w_bufp->b_linep; i--) {
  1952. X            wp->w_linep = lforw(wp->w_linep);
  1953. X        }
  1954. X        wp->w_dotp = wp->w_linep;
  1955. X        wp->w_doto = 0;
  1956. X        } else {
  1957. X        /* Old is lower window  */
  1958. X                wp1 = NULL;
  1959. X                wp2 = wheadp;
  1960. X                while (wp2 != curwp) {
  1961. X                        wp1 = wp2;
  1962. X                        wp2 = wp2->w_wndp;
  1963. X                }
  1964. X                if (wp1 == NULL)
  1965. X                        wheadp = wp;
  1966. X                else
  1967. X                        wp1->w_wndp = wp;
  1968. X                wp->w_wndp   = curwp;
  1969. X                wp->w_toprow = curwp->w_toprow;
  1970. X                wp->w_ntrows = ntru;
  1971. X                ++ntru;                         /* Mode line.           */
  1972. X                curwp->w_toprow += ntru;
  1973. X                curwp->w_ntrows  = ntrl;
  1974. X        wp->w_dotp = wp->w_linep;
  1975. X        /* move upper window dot to bottom line of upper */
  1976. X        for (i = ntru-2; i > 0 && wp->w_dotp!=wp->w_bufp->b_linep; i--)
  1977. X            wp->w_dotp = lforw(wp->w_dotp);
  1978. X        wp->w_doto = 0;
  1979. X        /* adjust lower window topline */
  1980. X                while (ntru--)
  1981. X                        curwp->w_linep = lforw(curwp->w_linep);
  1982. X        }
  1983. X        curwp->w_flag |= WFMODE|WFHARD;
  1984. X        wp->w_flag |= WFMODE|WFHARD;
  1985. X        return (TRUE);
  1986. }
  1987. X
  1988. /*
  1989. X * Enlarge the current window. Find the window that loses space. Make sure it
  1990. X * is big enough. If so, hack the window descriptions, and ask redisplay to do
  1991. SHAR_EOF
  1992. true || echo 'restore of window.c failed'
  1993. echo 'End of Vile part 16'
  1994. echo 'File window.c is continued in part 17'
  1995. echo 17 > _shar_seq_.tmp
  1996. exit 0
  1997. -- 
  1998.         paul fox, pgf@cayman.com, (617)494-1999
  1999.         Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
  2000.