home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / EDITOR / NVI179B / NVI179B.ZIP / common / screen.c < prev    next >
C/C++ Source or Header  |  1996-09-15  |  5KB  |  234 lines

  1. /*-
  2.  * Copyright (c) 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  * Copyright (c) 1993, 1994, 1995, 1996
  5.  *    Keith Bostic.  All rights reserved.
  6.  *
  7.  * See the LICENSE file for redistribution information.
  8.  */
  9.  
  10. #include "config.h"
  11.  
  12. #ifndef lint
  13. static const char sccsid[] = "@(#)screen.c    10.15 (Berkeley) 9/15/96";
  14. #endif /* not lint */
  15.  
  16. #include <sys/types.h>
  17. #include <sys/queue.h>
  18. #include <sys/time.h>
  19.  
  20. #include <bitstring.h>
  21. #include <errno.h>
  22. #include <limits.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27.  
  28. #include "common.h"
  29. #include "../vi/vi.h"
  30.  
  31. /*
  32.  * screen_init --
  33.  *    Do the default initialization of an SCR structure.
  34.  *
  35.  * PUBLIC: int screen_init __P((GS *, SCR *, SCR **));
  36.  */
  37. int
  38. screen_init(gp, orig, spp)
  39.     GS *gp;
  40.     SCR *orig, **spp;
  41. {
  42.     SCR *sp;
  43.     size_t len;
  44.  
  45.     *spp = NULL;
  46.     CALLOC_RET(orig, sp, SCR *, 1, sizeof(SCR));
  47.     *spp = sp;
  48.  
  49. /* INITIALIZED AT SCREEN CREATE. */
  50.     sp->id = ++gp->id;
  51.     sp->refcnt = 1;
  52.  
  53.     sp->gp = gp;                /* All ref the GS structure. */
  54.  
  55.     sp->ccnt = 2;                /* Anything > 1 */
  56.  
  57.     /*
  58.      * XXX
  59.      * sp->defscroll is initialized by the opts_init() code because
  60.      * we don't have the option information yet.
  61.      */
  62.  
  63.     CIRCLEQ_INIT(&sp->tiq);
  64.  
  65. /* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
  66.     if (orig == NULL) {
  67.         sp->searchdir = NOTSET;
  68.     } else {
  69.         /* Alternate file name. */
  70.         if (orig->alt_name != NULL &&
  71.             (sp->alt_name = strdup(orig->alt_name)) == NULL)
  72.             goto mem;
  73.  
  74.         /* Last executed at buffer. */
  75.         if (F_ISSET(orig, SC_AT_SET)) {
  76.             F_SET(sp, SC_AT_SET);
  77.             sp->at_lbuf = orig->at_lbuf;
  78.         }
  79.  
  80.         /* Retain searching/substitution information. */
  81.         sp->searchdir = orig->searchdir == NOTSET ? NOTSET : FORWARD;
  82.         if (orig->re != NULL && (sp->re =
  83.             v_strdup(sp, orig->re, orig->re_len)) == NULL)
  84.             goto mem;
  85.         sp->re_len = orig->re_len;
  86.         if (orig->subre != NULL && (sp->subre =
  87.             v_strdup(sp, orig->subre, orig->subre_len)) == NULL)
  88.             goto mem;
  89.         sp->subre_len = orig->subre_len;
  90.         if (orig->repl != NULL && (sp->repl =
  91.             v_strdup(sp, orig->repl, orig->repl_len)) == NULL)
  92.             goto mem;
  93.         sp->repl_len = orig->repl_len;
  94.         if (orig->newl_len) {
  95.             len = orig->newl_len * sizeof(size_t);
  96.             MALLOC(sp, sp->newl, size_t *, len);
  97.             if (sp->newl == NULL) {
  98. mem:                msgq(orig, M_SYSERR, NULL);
  99.                 goto err;
  100.             }
  101.             sp->newl_len = orig->newl_len;
  102.             sp->newl_cnt = orig->newl_cnt;
  103.             memcpy(sp->newl, orig->newl, len);
  104.         }
  105.  
  106.         if (opts_copy(orig, sp))
  107.             goto err;
  108.  
  109.         F_SET(sp, F_ISSET(orig, SC_EX | SC_VI));
  110.     }
  111.  
  112.     if (ex_screen_copy(orig, sp))        /* Ex. */
  113.         goto err;
  114.     if (v_screen_copy(orig, sp))        /* Vi. */
  115.         goto err;
  116.  
  117.     *spp = sp;
  118.     return (0);
  119.  
  120. err:    screen_end(sp);
  121.     return (1);
  122. }
  123.  
  124. /*
  125.  * screen_end --
  126.  *    Release a screen, no matter what had (and had not) been
  127.  *    initialized.
  128.  *
  129.  * PUBLIC: int screen_end __P((SCR *));
  130.  */
  131. int
  132. screen_end(sp)
  133.     SCR *sp;
  134. {
  135.     int rval;
  136.  
  137.     /* If multiply referenced, just decrement the count and return. */
  138.      if (--sp->refcnt != 0)
  139.          return (0);
  140.  
  141.     /*
  142.      * Remove the screen from the displayed queue.
  143.      *
  144.      * If a created screen failed during initialization, it may not
  145.      * be linked into the chain.
  146.      */
  147.     if (sp->q.cqe_next != NULL)
  148.         CIRCLEQ_REMOVE(&sp->gp->dq, sp, q);
  149.  
  150.     /* The screen is no longer real. */
  151.     F_CLR(sp, SC_SCR_EX | SC_SCR_VI);
  152.  
  153.     rval = 0;
  154. #ifdef HAVE_PERL_INTERP
  155.     if (perl_screen_end(sp))        /* End perl. */
  156.         rval = 1;
  157. #endif
  158.     if (v_screen_end(sp))            /* End vi. */
  159.         rval = 1;
  160.     if (ex_screen_end(sp))            /* End ex. */
  161.         rval = 1;
  162.  
  163.     /* Free file names. */
  164.     { char **ap;
  165.         if (!F_ISSET(sp, SC_ARGNOFREE) && sp->argv != NULL) {
  166.             for (ap = sp->argv; *ap != NULL; ++ap)
  167.                 free(*ap);
  168.             free(sp->argv);
  169.         }
  170.     }
  171.  
  172.     /* Free any text input. */
  173.     if (sp->tiq.cqh_first != NULL)
  174.         text_lfree(&sp->tiq);
  175.  
  176.     /* Free alternate file name. */
  177.     if (sp->alt_name != NULL)
  178.         free(sp->alt_name);
  179.  
  180.     /* Free up search information. */
  181.     if (sp->re != NULL)
  182.         free(sp->re);
  183.     if (F_ISSET(sp, SC_RE_SEARCH))
  184.         regfree(&sp->re_c);
  185.     if (sp->subre != NULL)
  186.         free(sp->subre);
  187.     if (F_ISSET(sp, SC_RE_SUBST))
  188.         regfree(&sp->subre_c);
  189.     if (sp->repl != NULL)
  190.         free(sp->repl);
  191.     if (sp->newl != NULL)
  192.         free(sp->newl);
  193.  
  194.     /* Free all the options */
  195.     opts_free(sp);
  196.  
  197.     /* Free the screen itself. */
  198.     free(sp);
  199.  
  200.     return (rval);
  201. }
  202.  
  203. /*
  204.  * screen_next --
  205.  *    Return the next screen in the queue.
  206.  *
  207.  * PUBLIC: SCR *screen_next __P((SCR *));
  208.  */
  209. SCR *
  210. screen_next(sp)
  211.     SCR *sp;
  212. {
  213.     GS *gp;
  214.     SCR *next;
  215.  
  216.     /* Try the display queue, without returning the current screen. */
  217.     gp = sp->gp;
  218.     for (next = gp->dq.cqh_first;
  219.         next != (void *)&gp->dq; next = next->q.cqe_next)
  220.         if (next != sp)
  221.             break;
  222.     if (next != (void *)&gp->dq)
  223.         return (next);
  224.  
  225.     /* Try the hidden queue; if found, move screen to the display queue. */
  226.     if (gp->hq.cqh_first != (void *)&gp->hq) {
  227.         next = gp->hq.cqh_first;
  228.         CIRCLEQ_REMOVE(&gp->hq, next, q);
  229.         CIRCLEQ_INSERT_HEAD(&gp->dq, next, q);
  230.         return (next);
  231.     }
  232.     return (NULL);
  233. }
  234.