home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / EDITOR / NVI179B / NVI179B.ZIP / ip / ip_funcs.c next >
C/C++ Source or Header  |  1996-10-13  |  7KB  |  444 lines

  1. /*-
  2.  * Copyright (c) 1996
  3.  *    Keith Bostic.  All rights reserved.
  4.  *
  5.  * See the LICENSE file for redistribution information.
  6.  */
  7.  
  8. #include "config.h"
  9.  
  10. #ifndef lint
  11. static const char sccsid[] = "@(#)ip_funcs.c    8.4 (Berkeley) 10/13/96";
  12. #endif /* not lint */
  13.  
  14. #include <sys/types.h>
  15. #include <sys/queue.h>
  16. #include <sys/time.h>
  17.  
  18. #include <bitstring.h>
  19. #include <stdio.h>
  20.  
  21. #include "../common/common.h"
  22. #include "../vi/vi.h"
  23. #include "ip.h"
  24.  
  25. static int ip_send __P((SCR *, char *, IP_BUF *));
  26.  
  27. /*
  28.  * ip_addstr --
  29.  *    Add len bytes from the string at the cursor, advancing the cursor.
  30.  *
  31.  * PUBLIC: int ip_addstr __P((SCR *, const char *, size_t));
  32.  */
  33. int
  34. ip_addstr(sp, str, len)
  35.     SCR *sp;
  36.     const char *str;
  37.     size_t len;
  38. {
  39.     IP_BUF ipb;
  40.     IP_PRIVATE *ipp;
  41.     int iv, rval;
  42.  
  43.     ipp = IPP(sp);
  44.  
  45.     /*
  46.      * If ex isn't in control, it's the last line of the screen and
  47.      * it's a split screen, use inverse video.
  48.      */
  49.     iv = 0;
  50.     if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
  51.         ipp->row == LASTLINE(sp) && IS_SPLIT(sp)) {
  52.         iv = 1;
  53.         ip_attr(sp, SA_INVERSE, 1);
  54.     }
  55.     ipb.code = IPO_ADDSTR;
  56.     ipb.len = len;
  57.     ipb.str = str;
  58.     rval = ip_send(sp, "s", &ipb);
  59.  
  60.     if (iv)
  61.         ip_attr(sp, SA_INVERSE, 0);
  62.     return (rval);
  63. }
  64.  
  65. /*
  66.  * ip_attr --
  67.  *    Toggle a screen attribute on/off.
  68.  *
  69.  * PUBLIC: int ip_attr __P((SCR *, scr_attr_t, int));
  70.  */
  71. int
  72. ip_attr(sp, attribute, on)
  73.     SCR *sp;
  74.     scr_attr_t attribute;
  75.     int on;
  76. {
  77.     IP_BUF ipb;
  78.  
  79.     ipb.code = IPO_ATTRIBUTE;
  80.     ipb.val1 = attribute;
  81.     ipb.val2 = on;
  82.  
  83.     return (ip_send(sp, "12", &ipb));
  84. }
  85.  
  86. /*
  87.  * ip_baud --
  88.  *    Return the baud rate.
  89.  *
  90.  * PUBLIC: int ip_baud __P((SCR *, u_long *));
  91.  */
  92. int
  93. ip_baud(sp, ratep)
  94.     SCR *sp;
  95.     u_long *ratep;
  96. {
  97.     *ratep = 9600;        /* XXX: Translation: fast. */
  98.     return (0);
  99. }
  100.  
  101. /*
  102.  * ip_bell --
  103.  *    Ring the bell/flash the screen.
  104.  *
  105.  * PUBLIC: int ip_bell __P((SCR *));
  106.  */
  107. int
  108. ip_bell(sp)
  109.     SCR *sp;
  110. {
  111.     IP_BUF ipb;
  112.  
  113.     ipb.code = IPO_BELL;
  114.  
  115.     return (ip_send(sp, NULL, &ipb));
  116. }
  117.  
  118. /*
  119.  * ip_busy --
  120.  *    Display a busy message.
  121.  *
  122.  * PUBLIC: void ip_busy __P((SCR *, const char *, busy_t));
  123.  */
  124. void
  125. ip_busy(sp, str, bval)
  126.     SCR *sp;
  127.     const char *str;
  128.     busy_t bval;
  129. {
  130.     IP_BUF ipb;
  131.  
  132.     ipb.code = IPO_BUSY;
  133.     if (str == NULL) {
  134.         ipb.len = 0;
  135.         ipb.str = "";
  136.     } else {
  137.         ipb.len = strlen(str);
  138.         ipb.str = str;
  139.     }
  140.     ipb.val1 = bval;
  141.  
  142.     (void)ip_send(sp, "s1", &ipb);
  143. }
  144.  
  145. /*
  146.  * ip_clrtoeol --
  147.  *    Clear from the current cursor to the end of the line.
  148.  *
  149.  * PUBLIC: int ip_clrtoeol __P((SCR *));
  150.  */
  151. int
  152. ip_clrtoeol(sp)
  153.     SCR *sp;
  154. {
  155.     IP_BUF ipb;
  156.  
  157.     ipb.code = IPO_CLRTOEOL;
  158.  
  159.     return (ip_send(sp, NULL, &ipb));
  160. }
  161.  
  162. /*
  163.  * ip_cursor --
  164.  *    Return the current cursor position.
  165.  *
  166.  * PUBLIC: int ip_cursor __P((SCR *, size_t *, size_t *));
  167.  */
  168. int
  169. ip_cursor(sp, yp, xp)
  170.     SCR *sp;
  171.     size_t *yp, *xp;
  172. {
  173.     IP_PRIVATE *ipp;
  174.  
  175.     ipp = IPP(sp);
  176.     *yp = ipp->row;
  177.     *xp = ipp->col;
  178.     return (0);
  179. }
  180.  
  181. /*
  182.  * ip_deleteln --
  183.  *    Delete the current line, scrolling all lines below it.
  184.  *
  185.  * PUBLIC: int ip_deleteln __P((SCR *));
  186.  */
  187. int
  188. ip_deleteln(sp)
  189.     SCR *sp;
  190. {
  191.     IP_BUF ipb;
  192.  
  193.     /*
  194.      * This clause is required because the curses screen uses reverse
  195.      * video to delimit split screens.  If the screen does not do this,
  196.      * this code won't be necessary.
  197.      *
  198.      * If the bottom line was in reverse video, rewrite it in normal
  199.      * video before it's scrolled.
  200.      */
  201.     if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) {
  202.         ipb.code = IPO_REWRITE;
  203.         ipb.val1 = RLNO(sp, LASTLINE(sp));
  204.         if (ip_send(sp, "1", &ipb))
  205.             return (1);
  206.     }
  207.  
  208.     /*
  209.      * The bottom line is expected to be blank after this operation,
  210.      * and other screens must support that semantic.
  211.      */
  212.     ipb.code = IPO_DELETELN;
  213.     return (ip_send(sp, NULL, &ipb));
  214. }
  215.  
  216. /* 
  217.  * ip_ex_adjust --
  218.  *    Adjust the screen for ex.
  219.  *
  220.  * PUBLIC: int ip_ex_adjust __P((SCR *, exadj_t));
  221.  */
  222. int
  223. ip_ex_adjust(sp, action)
  224.     SCR *sp;
  225.     exadj_t action;
  226. {
  227.     abort();
  228.     /* NOTREACHED */
  229. }
  230.  
  231. /*
  232.  * ip_insertln --
  233.  *    Push down the current line, discarding the bottom line.
  234.  *
  235.  * PUBLIC: int ip_insertln __P((SCR *));
  236.  */
  237. int
  238. ip_insertln(sp)
  239.     SCR *sp;
  240. {
  241.     IP_BUF ipb;
  242.  
  243.     ipb.code = IPO_INSERTLN;
  244.  
  245.     return (ip_send(sp, NULL, &ipb));
  246. }
  247.  
  248. /*
  249.  * ip_keyval --
  250.  *    Return the value for a special key.
  251.  *
  252.  * PUBLIC: int ip_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *));
  253.  */
  254. int
  255. ip_keyval(sp, val, chp, dnep)
  256.     SCR *sp;
  257.     scr_keyval_t val;
  258.     CHAR_T *chp;
  259.     int *dnep;
  260. {
  261.     /*
  262.      * VEOF, VERASE and VKILL are required by POSIX 1003.1-1990,
  263.      * VWERASE is a 4BSD extension.
  264.      */
  265.     switch (val) {
  266.     case KEY_VEOF:
  267.         *dnep = '\004';        /* ^D */
  268.         break;
  269.     case KEY_VERASE:
  270.         *dnep = '\b';        /* ^H */
  271.         break;
  272.     case KEY_VKILL:
  273.         *dnep = '\025';        /* ^U */
  274.         break;
  275. #ifdef VWERASE
  276.     case KEY_VWERASE:
  277.         *dnep = '\027';        /* ^W */
  278.         break;
  279. #endif
  280.     default:
  281.         *dnep = 1;
  282.         break;
  283.     }
  284.     return (0);
  285. }
  286.  
  287. /*
  288.  * ip_move --
  289.  *    Move the cursor.
  290.  *
  291.  * PUBLIC: int ip_move __P((SCR *, size_t, size_t));
  292.  */
  293. int
  294. ip_move(sp, lno, cno)
  295.     SCR *sp;
  296.     size_t lno, cno;
  297. {
  298.     IP_PRIVATE *ipp;
  299.     IP_BUF ipb;
  300.  
  301.     ipp = IPP(sp);
  302.     ipp->row = lno;
  303.     ipp->col = cno;
  304.  
  305.     ipb.code = IPO_MOVE;
  306.     ipb.val1 = RLNO(sp, lno);
  307.     ipb.val2 = cno;
  308.     return (ip_send(sp, "12", &ipb));
  309. }
  310.  
  311. /*
  312.  * ip_refresh --
  313.  *    Refresh the screen.
  314.  *
  315.  * PUBLIC: int ip_refresh __P((SCR *, int));
  316.  */
  317. int
  318. ip_refresh(sp, repaint)
  319.     SCR *sp;
  320.     int repaint;
  321. {
  322.     IP_BUF ipb;
  323.  
  324.     ipb.code = repaint ? IPO_REDRAW : IPO_REFRESH;
  325.  
  326.     return (ip_send(sp, NULL, &ipb));
  327. }
  328.  
  329. /*
  330.  * ip_rename --
  331.  *    Rename the file.
  332.  *
  333.  * PUBLIC: int ip_rename __P((SCR *));
  334.  */
  335. int
  336. ip_rename(sp)
  337.     SCR *sp;
  338. {
  339.     IP_BUF ipb;
  340.  
  341.     ipb.code = IPO_RENAME;
  342.     ipb.len = strlen(sp->frp->name);
  343.     ipb.str = sp->frp->name;
  344.  
  345.     return (ip_send(sp, "s", &ipb));
  346. }
  347.  
  348. /*
  349.  * ip_suspend --
  350.  *    Suspend a screen.
  351.  *
  352.  * PUBLIC: int ip_suspend __P((SCR *, int *));
  353.  */
  354. int
  355. ip_suspend(sp, allowedp)
  356.     SCR *sp;
  357.     int *allowedp;
  358. {
  359.     *allowedp = 0;
  360.     return (0);
  361. }
  362.  
  363. /*      
  364.  * ip_usage --
  365.  *      Print out the ip usage messages.
  366.  *
  367.  * PUBLIC: void ip_usage __P((void));
  368.  */
  369. void    
  370. ip_usage()
  371. {       
  372. #define USAGE "\
  373. usage: vi [-eFlRrSv] [-c command] [-I ifd.ofd] [-t tag] [-w size] [file ...]\n"
  374.         (void)fprintf(stderr, "%s", USAGE);
  375. #undef  USAGE
  376. }
  377.  
  378. /*
  379.  * ip_send --
  380.  *    Construct and send an IP buffer.
  381.  */
  382. static int
  383. ip_send(sp, fmt, ipbp)
  384.     SCR *sp;
  385.     char *fmt;
  386.     IP_BUF *ipbp;
  387. {
  388.     IP_PRIVATE *ipp;
  389.     size_t blen, off;
  390.     u_int32_t ilen;
  391.     int nlen, n, nw, rval;
  392.     char *bp, *p;
  393.     
  394.     ipp = IPP(sp);
  395.  
  396.     GET_SPACE_RET(sp, bp, blen, 128);
  397.  
  398.     p = bp;
  399.     nlen = 0;
  400.     *p++ = ipbp->code;
  401.     nlen += IPO_CODE_LEN;
  402.  
  403.     if (fmt != NULL)
  404.         for (; *fmt != '\0'; ++fmt)
  405.             switch (*fmt) {
  406.             case '1':            /* Value 1. */
  407.                 ilen = htonl(ipbp->val1);
  408.                 goto value;
  409.             case '2':            /* Value 2. */
  410.                 ilen = htonl(ipbp->val2);
  411. value:                nlen += IPO_INT_LEN;
  412.                 off = p - bp;
  413.                 ADD_SPACE_RET(sp, bp, blen, nlen);
  414.                 p = bp + off;
  415.                 memmove(p, &ilen, IPO_INT_LEN);
  416.                 p += IPO_INT_LEN;
  417.                 break;
  418.             case 's':            /* String. */
  419.                 ilen = ipbp->len;    /* XXX: conversion. */
  420.                 ilen = htonl(ilen);
  421.                 nlen += IPO_INT_LEN + ipbp->len;
  422.                 off = p - bp;
  423.                 ADD_SPACE_RET(sp, bp, blen, nlen);
  424.                 p = bp + off;
  425.                 memmove(p, &ilen, IPO_INT_LEN);
  426.                 p += IPO_INT_LEN;
  427.                 memmove(p, ipbp->str, ipbp->len);
  428.                 p += ipbp->len;
  429.                 break;
  430.             }
  431.  
  432.  
  433.     rval = 0;
  434.     for (n = p - bp, p = bp; n > 0; n -= nw, p += nw)
  435.         if ((nw = write(ipp->o_fd, p, n)) < 0) {
  436.             rval = 1;
  437.             break;
  438.         }
  439.  
  440.     FREE_SPACE(sp, bp, blen);
  441.  
  442.     return (rval);
  443. }
  444.