home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1999 March / PCShareware-3-99.iso / IMPLE / DJGPP.RAR / DJGPP2 / XLIB-SR0.ZIP / SRC / XLIBEMU / TERM.C < prev    next >
Text File  |  1994-01-11  |  8KB  |  399 lines

  1. /* $Id: term.c 1.1 1994/01/12 04:38:25 ulrich Exp $ */
  2. /* 
  3.  * term.c 
  4.  *
  5.  * Simple terminal window code.
  6.  */
  7. #include <stdio.h>
  8. #include <malloc.h>
  9. #include <stdarg.h>
  10.  
  11. #include <X11/Xlib.h>
  12. #include <X11/Xutil.h>
  13. #include <X11/keysym.h>
  14.  
  15. typedef struct _Term {
  16.   int rows;
  17.   int cols;
  18.   int curr;
  19.   int curc;
  20.   int fw, fh;
  21.   char *text;
  22.   int *update;
  23.   Window window;
  24.   long event_mask;
  25.   GC normal_GC;
  26.   GC cursor_GC;
  27.   Display *display;
  28.   XFontStruct *font;
  29.   char *buffer;
  30.   int bufcount;
  31.   int bufsize;
  32. } _TermRec;
  33.  
  34. _TermRec *_xterm = NULL;
  35.  
  36.  
  37. _TermRec*
  38. TermCreate (Display *dpy)
  39. {
  40.   int width, height;
  41.   int background, foreground;
  42.   _TermRec *t;
  43.  
  44.   t = (_TermRec *) calloc (1, sizeof (_TermRec));
  45.   t->display = dpy;
  46.   t->font = XLoadQueryFont (dpy, "8x14");
  47.   t->cols = 80;
  48.   t->rows = 25;
  49.   t->text = (char *) malloc (t->cols * t->rows * sizeof(char));
  50.   memset (t->text, ' ', t->cols * t->rows);
  51.   t->update = (int *) malloc (t->rows * sizeof(int));
  52.   memset (t->update, 0, t->rows * sizeof(int));
  53.  
  54.   t->fw = t->font->max_bounds.width;
  55.   t->fh = (t->font->max_bounds.ascent + t->font->max_bounds.descent);
  56.   width = t->cols * t->fw;
  57.   height = t->rows * t->fh;
  58.   background = WhitePixel (dpy, DefaultScreen (dpy));
  59.   foreground = BlackPixel (dpy, DefaultScreen (dpy));
  60.   t->window =
  61.     XCreateSimpleWindow (dpy,
  62.              DefaultRootWindow (dpy),
  63.              50, 50, width, height, 4,
  64.              foreground, background);
  65.   t->event_mask = EnterWindowMask 
  66.     |LeaveWindowMask 
  67.     |ButtonPressMask
  68.     |KeyPressMask
  69.     |ExposureMask;
  70.  
  71.   XSelectInput (dpy, t->window, t->event_mask);
  72.   t->normal_GC = XCreateGC (dpy, (Drawable) t->window, 0, 0);
  73.   XSetFont (dpy, t->normal_GC, t->font->fid);
  74.   XSetBackground (dpy, t->normal_GC, background);
  75.   XSetForeground (dpy, t->normal_GC, foreground);
  76.   t->cursor_GC = XCreateGC (dpy, (Drawable) t->window, 0, 0);
  77.   XSetFont (dpy, t->cursor_GC, t->font->fid);
  78.   XSetBackground (dpy, t->cursor_GC, foreground);
  79.   XSetForeground (dpy, t->cursor_GC, background);
  80.   XStoreName (dpy, t->window, "xterm");
  81.   return t;
  82. }
  83.  
  84. void
  85. TermUpdate (_TermRec *t)
  86. {
  87.   int i;
  88.  
  89.   for (i = t->rows; --i >= 0;)
  90.     {
  91.       if (t->update[i])
  92.     {
  93.       XDrawImageString (t->display, t->window, t->normal_GC,
  94.                 0,  t->fh * (i + 1) - 1,
  95.                 t->text + t->cols * i, t->cols);
  96.       if (t->curr == i) {
  97.         XDrawImageString (t->display, t->window, t->cursor_GC,
  98.                   t->fw * t->curc, t->fh * (i + 1) - 1,
  99.                   t->text + t->cols * i + t->curc,
  100.                   1);
  101.       }
  102.       t->update[i] = 0;
  103.     }
  104.     }
  105. }
  106.  
  107. void
  108. TermScroll (_TermRec *t, int lines)
  109. {
  110.   if (lines > 0) {
  111.     if (lines >= t->rows) {
  112.       memset (t->text, ' ', t->cols * t->rows);
  113.       t->curr = 0;
  114.       t->curr = 1;
  115.     }
  116.     else {
  117.       char *src, *dst;
  118.       
  119.       dst = t->text;
  120.       src = t->text + t->cols * lines;
  121.       memcpy (dst, src, t->cols * (t->rows - lines));
  122.       dst += t->cols * (t->rows - lines);
  123.       memset (dst, ' ', t->cols * lines);
  124.       t->curr -= lines;
  125.     }
  126.     {
  127.       int i;
  128.       for (i = t->rows; --i >= 0;)
  129.     t->update[i] = 1;
  130.     }
  131.     return;
  132.   }
  133. }
  134.  
  135. void
  136. TermAddc (_TermRec *t, char c)
  137. {
  138.   if (t->buffer == NULL) {
  139.     t->bufsize = 1024;
  140.     t->buffer = (char *) malloc (t->bufsize);
  141.     t->bufcount = 0;
  142.   }
  143.   if (t->bufcount < t->bufsize) {
  144.     t->buffer[t->bufcount++] = c;
  145.   }
  146. }
  147.  
  148. void
  149. TermPutc (_TermRec *t, char c)
  150. {
  151.   switch (c) {
  152.   case '':
  153.     t->curc--;
  154.     if (t->curc < 0)
  155.       t->curc = 0;
  156.     t->update[t->curr] = 1;
  157.     break;
  158.   case '':
  159.     t->curc++;
  160.     if (t->curc >= t->cols)
  161.       t->curc = t->cols - 1;
  162.     t->update[t->curr] = 1;
  163.     break;
  164.   case '':
  165.     t->update[t->curr] = 1;
  166.     t->curr++;
  167.     if (t->curr >= t->rows)
  168.       t->curr = t->rows - 1;
  169.     t->update[t->curr] = 1;
  170.     break;
  171.   case '':
  172.     t->update[t->curr] = 1;
  173.     t->curr--;
  174.     if (t->curr < 0)
  175.       t->curr = 0;
  176.     t->update[t->curr] = 1;
  177.     break;
  178.   case '':
  179.     {
  180.       char *dst = t->text + t->cols * t->curr + t->curc;
  181.       memcpy (dst, dst + 1, t->cols - t->curc - 1);
  182.       dst[t->cols - t->curc - 1] = ' ';
  183.     }
  184.     t->update[t->curr] = 1;
  185.     break;
  186.   case '\b':
  187.     t->curc--;
  188.     if (t->curc < 0) {
  189.       t->curc = 0;
  190.     }
  191.     else {
  192.       char *dst = t->text + t->cols * t->curr + t->curc;
  193.       memcpy (dst, dst + 1, t->cols - t->curc - 1);
  194.       dst[t->cols - t->curc - 1] = ' ';
  195.     }
  196.     t->update[t->curr] = 1;
  197.     break;
  198.   case '\r':
  199.     t->curc = 0;
  200.     t->update[t->curr] = 1;
  201.     break;
  202.   case '\n':
  203.     t->update[t->curr] = 1;
  204.     t->curc = 0;
  205.     t->curr++;
  206.     if (t->curr >= t->rows) {
  207.       TermScroll (t, t->rows/2);
  208.     }
  209.     else {
  210.       t->update[t->curr] = 1;
  211.     }
  212.     break;
  213.   case '\t':
  214. #if 1
  215.     do {
  216.       TermPutc (t, ' ');
  217.     } while ((t->curc % 8) != 0);
  218. #else
  219.     t->curc = (t->curc + 8) % 8;
  220.     t->update[t->curr] = 1;
  221.     if (t->curc >= t->cols) {
  222.       t->curc = t->curc % 8;
  223.       t->curr++;
  224.       if (t->curr >= t->rows) {
  225.     TermScroll (t, t->rows/2);
  226.       }
  227.       else {
  228.     t->update[t->curr] = 1;
  229.       }
  230.     }
  231. #endif
  232.     break;
  233.   default:
  234.     t->text[t->cols * t->curr + t->curc] = c;
  235.     t->update[t->curr] = 1;
  236.     t->curc++;
  237.     if (t->curc >= t->cols) {
  238.       t->curc = 0;
  239.       t->curr++;
  240.       if (t->curr >= t->rows) {
  241.     TermScroll (t, t->rows/2);
  242.       }
  243.       else {
  244.     t->update[t->curr] = 1;
  245.       }
  246.     }
  247.   }
  248. }
  249.  
  250. void
  251. TermProc (_TermRec *t)
  252. {
  253.   char text[10];
  254.   KeySym keysym;
  255.   XComposeStatus cs;
  256.   int i, n, count;
  257.   XEvent ev;
  258.  
  259.   XNextEvent (t->display, &ev);
  260.     
  261.   switch (ev.type) {
  262.   case KeyPress:
  263.     count = XLookupString (&ev.xkey, text, 10, &keysym, &cs);
  264.     if (count == 1) {
  265.       if (text[0] == '\r') goto carrige_return;
  266.       TermPutc (t, text[0]);
  267.     }
  268.     else switch (keysym) {
  269.     case XK_Return:
  270.     carrige_return:
  271.       {
  272.     char *p;
  273.     p = t->text + t->cols * t->curr;
  274.     for (n = t->cols; --n >= 0; )
  275.       if (p[n] != ' ') break;
  276.     for (i = 1; i <= n; i++) {
  277.       TermAddc (t, p[i]);
  278.     }
  279.     TermAddc (t, '\n');
  280.       }
  281.       TermPutc (t, '\n');
  282.       break;
  283.     case XK_Tab:
  284.       TermPutc (t, '\t');
  285.       break;
  286.     case XK_BackSpace:
  287.       TermPutc (t, '\b');
  288.       break;
  289.     case XK_Delete:
  290.       TermPutc (t, '');
  291.       break;
  292.     case XK_Left:
  293.       TermPutc (t, '');
  294.       break;
  295.     case XK_Right:
  296.       TermPutc (t, '');
  297.       break;
  298.     case XK_Down:
  299.       TermPutc (t, '');
  300.       break;
  301.     case XK_Up:
  302.       TermPutc (t, '');
  303.       break;
  304.     }
  305.     TermUpdate (t);
  306.     break;
  307.   case Expose:
  308.     for (i = t->rows; --i >= 0;)
  309.       t->update[i] = 1;
  310.     TermUpdate (t);
  311.     break;
  312.   }
  313. }
  314.  
  315. int
  316. xread (char *buffer, int bufsize)
  317. {
  318.   int count = 0;
  319.  
  320.   if (_xterm->bufcount > 0) 
  321.     {
  322.       count = _xterm->bufcount;
  323.       if (count > bufsize) count = bufsize;
  324.       memcpy (buffer, _xterm->buffer, count);
  325.       _xterm->bufcount -= count;
  326.     }
  327.   return count;
  328. }
  329.  
  330. int
  331. xavail ()
  332. {
  333.   return _xterm->bufcount;
  334. }
  335.  
  336. int
  337. xputs (char *buffer)
  338. {
  339.   int i, count;
  340.   
  341.   count = strlen (buffer);
  342.   for (i = 0; i < count; i++)
  343.     TermPutc (_xterm, buffer[i]);
  344.   TermUpdate (_xterm);
  345.   return count;
  346. }
  347.  
  348. int
  349. xprintf (char *format, ...)
  350. {
  351.   char buffer[1024];
  352.   va_list ap;
  353.   va_start (ap, format);
  354.   vsprintf (buffer, format, ap);
  355.   va_end (ap);
  356.   return xputs (buffer);
  357. }
  358.  
  359.  
  360. term()
  361. {
  362.   int argc;
  363.   char *argv[2];
  364.   argc = 1;
  365.   argv[0] = "term";
  366.   argv[1] = NULL;
  367.  
  368.   return term_main (argc, argv);
  369. }
  370.  
  371. int
  372. term_main (int argc, char *argv[])
  373. {
  374.   Display *display;
  375.  
  376.   if (_xterm == NULL) {
  377.     display = XOpenDisplay ("");
  378.     if (display == NULL) {
  379.       fprintf (stderr, "Cannot open display\n");
  380.       exit (1);
  381.     }
  382.     _xterm = TermCreate (display);
  383.     XMapWindow (display, _xterm->window);
  384.   }
  385.   if (XPending (_xterm->display))
  386.     TermProc (_xterm);
  387.   return 1;
  388. }
  389.  
  390. #ifdef TEST
  391. main()
  392. {
  393.   while (term ());
  394. }
  395. #endif
  396.  
  397.  
  398.  
  399.