home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / ytalk-3.0 / part01 / xwin.c < prev    next >
C/C++ Source or Header  |  1993-08-20  |  9KB  |  420 lines

  1. /* xwin.c -- X Window Terminal Interface */
  2.  
  3. /*               NOTICE
  4.  *
  5.  * Copyright (c) 1990,1992,1993 Britt Yenne.  All rights reserved.
  6.  * 
  7.  * This software is provided AS-IS.  The author gives no warranty,
  8.  * real or assumed, and takes no responsibility whatsoever for any 
  9.  * use or misuse of this software, or any damage created by its use
  10.  * or misuse.
  11.  * 
  12.  * This software may be freely copied and distributed provided that
  13.  * no part of this NOTICE is deleted or edited in any manner.
  14.  * 
  15.  */
  16.  
  17. /* Mail comments or questions to ytalk@austin.eds.com */
  18.  
  19. #ifdef USE_X11
  20.  
  21. #include "header.h"
  22. #include <X11/Xlib.h>
  23. #include <X11/Xutil.h>
  24. #include <X11/Xresource.h>
  25.  
  26. static Display           *display;    /* display */
  27. static Window        rootwin;    /* root window */
  28. static int        screen_num;    /* screen number */
  29. static XrmDatabase    db;        /* resource database */
  30. static XFontStruct     *text_font;    /* font */
  31. static GC        textGC,        /* text graphic context */
  32.             invertGC;    /* graphic context for inverts */
  33. static u_long        whitepix,    /* white pixel */
  34.             blackpix;    /* black pixel */
  35. static int        font_width,    /* font width */
  36.             font_height,    /* font height */
  37.             font_ascent;    /* font ascent */
  38.  
  39. #define YPOS(p) ((p) * font_height)
  40. #define XPOS(p) ((p) * font_width)
  41.  
  42. /* ----- local functions ----- */
  43.  
  44. static XTextProperty *
  45. strToTP(s)
  46.   char *s;
  47. {
  48.     XTextProperty *tp = (XTextProperty *)get_mem(sizeof(XTextProperty));
  49.     XStringListToTextProperty(&s, 1, tp);
  50.     return tp;
  51. }
  52.  
  53. static char *
  54. getOption(o)
  55.   char *o;
  56. {
  57.     XrmValue value;
  58.     char *type;
  59.  
  60.     if(XrmGetResource(db, o, o, &type, &value))
  61.     {
  62.     if(value.addr == NULL)
  63.         return NULL;
  64.     if(strcmp(value.addr, "false") == 0)
  65.         return NULL;
  66.     if(strcmp(value.addr, "False") == 0)
  67.         return NULL;
  68.     return value.addr;
  69.     }
  70.     else
  71.     return (char *)NULL;
  72. }
  73.  
  74. static void
  75. load_font(name, font)
  76.   char *name;
  77.   XFontStruct **font;
  78. {
  79.     if((*font = XLoadQueryFont(display, name)) == NULL)
  80.     {
  81.     sprintf(errstr, "Cannot load font %s", name);
  82.     show_error(errstr);
  83.     bail(YTE_ERROR);
  84.     }
  85. }
  86.  
  87. static void
  88. make_GC(gc, font, fgpixel, bgpixel, l_width, l_style, l_cap, l_join, gcfunc)
  89.   GC *gc;
  90.   XFontStruct *font;
  91.   u_long fgpixel, bgpixel;
  92.   int l_width, l_style, l_cap, l_join, gcfunc;
  93. {
  94.     u_long mask = 0;
  95.     XGCValues values;
  96.  
  97.     if(font != NULL)
  98.     {
  99.     values.font = font->fid;
  100.     mask |= GCFont;
  101.     }
  102.     values.foreground = fgpixel;
  103.     values.background = bgpixel;
  104.     values.line_width = l_width;
  105.     values.line_style = l_style;
  106.     values.cap_style = l_cap;
  107.     values.join_style = l_join;
  108.     mask |= GCForeground | GCBackground | GCLineWidth | GCLineStyle | 
  109.         GCCapStyle | GCJoinStyle;
  110.     if(gcfunc != -1)
  111.     {
  112.     values.function = gcfunc;
  113.     mask |= GCFunction;
  114.     }
  115.     *gc = XCreateGC(display, rootwin, mask, &values);
  116. }
  117.  
  118. /* Find the user who owns a given Window.
  119.  */
  120. static yuser *
  121. win_user(win)
  122.   Window win;
  123. {
  124.     register yuser *u;
  125.  
  126.     for(u = user_list; u; u = u->unext)
  127.     if(u->win == win)
  128.         break;
  129.     return u;
  130. }
  131.  
  132. #define TWIN    report.xany.window
  133.  
  134. static void
  135. process_event()
  136. {
  137.     register int n;
  138.     register yuser *user;
  139.     static XEvent report;
  140.     static char buf[512];
  141.  
  142.     while(XPending(display))
  143.     {
  144.     XNextEvent(display, &report);
  145.     switch(report.type)
  146.     {
  147.         case Expose:
  148.         if(report.xexpose.count)
  149.             break;
  150.         if((user = win_user(TWIN)) != NULL)
  151.             redraw_term(user, 0);
  152.         break;
  153.         case ConfigureNotify: /* RESIZED (or moved) */
  154.         if((user = win_user(TWIN)) != NULL)
  155.         {
  156.             int rows, cols;
  157.             rows = report.xconfigure.height / font_height;
  158.             cols = report.xconfigure.width / font_width;
  159.             resize_win(user, rows, cols);
  160.         }
  161.         break;
  162.         case KeyPress:
  163.         n = XLookupString(&report, buf, 512, NULL, NULL);
  164.         my_input(buf, n);
  165.         break;
  166.     }
  167.     }
  168. }
  169.  
  170. static void
  171. place_cursor(win, y, x)
  172.   Window win;
  173.   int y, x;
  174. {
  175.     XFillRectangle(display, win, invertGC,
  176.     XPOS(x), YPOS(y),
  177.     font_width, font_height);
  178. }
  179.  
  180. /* ----- global functions ----- */
  181.  
  182. /* Initialize X Windows.
  183.  */
  184. void
  185. init_xwin()
  186. {
  187.     extern char *getenv();
  188.     char    *displayName;
  189.     char    *rfn, str[256];
  190.     int        xfd;
  191.     XGCValues   values;
  192.  
  193.     /* get and open the display */
  194.  
  195.     displayName = getOption("YTalk.display");
  196.     if((display = XOpenDisplay(displayName)) == NULL)
  197.     {
  198.     show_error("Cannot open X display");
  199.     bail(YTE_ERROR);
  200.     }
  201.     rootwin = DefaultRootWindow(display);
  202.     screen_num = DefaultScreen(display);
  203.  
  204.     /* read all options */
  205.  
  206.     db = XrmGetStringDatabase(XResourceManagerString(display));
  207.     if((rfn = getenv("HOME")) != NULL)
  208.     {
  209.     sprintf(str, "%s/.Xdefaults", rfn);
  210.     if(access(str, 0) == 0)
  211.         XrmMergeDatabases(XrmGetFileDatabase(str), &db);
  212.     }
  213.     if((rfn = getenv("XENVIRONMENT")) != NULL)
  214.     if(access(rfn, 0) == 0)
  215.         XrmMergeDatabases(XrmGetFileDatabase(rfn), &db);
  216.     if(getOption("YTalk.reverse"))
  217.     {
  218.     whitepix = BlackPixel(display, screen_num);
  219.     blackpix = WhitePixel(display, screen_num);
  220.     }
  221.     else
  222.     {
  223.     blackpix = BlackPixel(display, screen_num);
  224.     whitepix = WhitePixel(display, screen_num);
  225.     }
  226.  
  227.     /* load font and graphic context */
  228.  
  229.     if((rfn = getOption("YTalk.font")) == NULL)
  230.     rfn = "9x15";
  231.     load_font(rfn, &text_font);
  232.     font_width = text_font->max_bounds.rbearing;
  233.     font_height = text_font->max_bounds.ascent + text_font->max_bounds.descent;
  234.     font_ascent = text_font->max_bounds.ascent;
  235.     make_GC(&textGC, text_font, blackpix, whitepix,
  236.         2, LineSolid, CapRound, JoinRound, -1);
  237.     make_GC(&invertGC, text_font, blackpix, whitepix,
  238.         2, LineSolid, CapRound, JoinRound, GXinvert);
  239.     values.plane_mask = blackpix ^ whitepix;
  240.     XChangeGC(display, invertGC, GCPlaneMask, &values);
  241.  
  242.     /* set up event processing */
  243.  
  244.     xfd = ConnectionNumber(display);
  245.     add_fd(xfd, process_event);
  246. }
  247.  
  248. /* End X Windows.
  249.  */
  250. void
  251. end_xwin()
  252. {
  253.     XCloseDisplay(display);
  254. }
  255.  
  256. /* Open a new window.
  257.  */
  258. int
  259. open_xwin(user, title)
  260.   yuser *user;
  261.   char *title;
  262. {
  263.     XWMHints    WMhints;
  264.     XClassHint    ClassHints;
  265.     XSizeHints    size;
  266.     XTextProperty *name;
  267.     Window    win;
  268.     int        rows, cols;
  269.  
  270.     size.x = 0;
  271.     size.y = 0;
  272.     size.width = 80;
  273.     size.height = 24;
  274.     size.min_width = 20;
  275.     size.min_height = 2;
  276.     size.width_inc = font_width;
  277.     size.height_inc = font_height;
  278.     size.flags = PSize | PMinSize | PResizeInc;
  279.     if(getOption("YTalk.geometry"))
  280.     {
  281.     XParseGeometry(getOption("YTalk.geometry"),
  282.         &size.x, &size.y, &size.width, &size.height);
  283.  
  284.     /* don't set USPosition -- it confuses tvtwm */
  285.     }
  286.     rows = size.height;
  287.     cols = size.width;
  288.     size.width *= font_width;
  289.     size.height *= font_height;
  290.     size.min_width *= font_width;
  291.     size.min_height *= font_height;
  292.     win = XCreateSimpleWindow(display, rootwin, size.x, size.y,
  293.     size.width, size.height, 4, blackpix, whitepix);
  294.     if(win == (Window)0)
  295.     return -1;
  296.  
  297.     WMhints.flags = InputHint;
  298.     WMhints.input = 1;
  299.     ClassHints.res_name = "ytalk";
  300.     ClassHints.res_class = "YTalk";
  301.     name = strToTP(title);
  302.     XSetWMProperties(display, win, name, name,
  303.     0, 0, &size, &WMhints, &ClassHints);
  304.  
  305.     XSelectInput(display, win, ExposureMask | KeyPressMask
  306.     | StructureNotifyMask);
  307.     XMapRaised(display, win);
  308.  
  309.     user->win = win;
  310.     user->ty = user->tx = 0;
  311.     place_cursor(win, 0, 0);
  312.     resize_win(user, rows, cols);
  313.     return 0;
  314. }
  315.  
  316. void
  317. close_xwin(user)
  318.   yuser *user;
  319. {
  320.     XDestroyWindow(display, user->win);
  321.     user->win = (Window)0;
  322. }
  323.  
  324. void
  325. addch_xwin(user, ch)
  326.   yuser *user;
  327.   ychar ch;
  328. {
  329.     XClearArea(display, user->win,
  330.     XPOS(user->tx), YPOS(user->ty),
  331.     font_width, font_height,
  332.     False);
  333.     XDrawString(display, user->win, textGC,
  334.     XPOS(user->tx), YPOS(user->ty) + font_ascent,
  335.     &ch, 1);
  336.     user->tx++;
  337.     if(user->tx >= user->t_cols)
  338.     user->tx--;
  339.     place_cursor(user->win, user->ty, user->tx);
  340. }
  341.  
  342. void
  343. move_xwin(user, y, x)
  344.   yuser *user;
  345.   int y, x;
  346. {
  347.     place_cursor(user->win, user->ty, user->tx);
  348.     user->ty = y;
  349.     user->tx = x;
  350.     place_cursor(user->win, user->ty, user->tx);
  351. }
  352.  
  353. void
  354. clreol_xwin(user)
  355.   yuser *user;
  356. {
  357.     XClearArea(display, user->win,
  358.     XPOS(user->tx), YPOS(user->ty),
  359.     0, font_height,
  360.     False);
  361.     place_cursor(user->win, user->ty, user->tx);
  362. }
  363.  
  364. void
  365. clreos_xwin(user)
  366.   yuser *user;
  367. {
  368.     XClearArea(display, user->win,
  369.     XPOS(user->tx), YPOS(user->ty),
  370.     0, font_height,
  371.     False);
  372.     XClearArea(display, user->win,
  373.     0, YPOS(user->ty + 1),
  374.     0, 0,
  375.     False);
  376.     place_cursor(user->win, user->ty, user->tx);
  377. }
  378.  
  379. void
  380. scroll_xwin(user)
  381.   yuser *user;
  382. {
  383.     place_cursor(user->win, user->ty, user->tx);
  384.     XCopyArea(display, user->win, user->win, textGC,
  385.     XPOS(0), YPOS(1),
  386.     XPOS(user->t_cols), YPOS(user->t_rows - 1),
  387.     XPOS(0), YPOS(0));
  388.     XClearArea(display, user->win,
  389.     0, YPOS(user->t_rows - 1),
  390.     0, font_height,
  391.     False);
  392.     place_cursor(user->win, user->ty, user->tx);
  393. }
  394.  
  395. void
  396. rev_scroll_xwin(user)
  397.   yuser *user;
  398. {
  399.     place_cursor(user->win, user->ty, user->tx);
  400.     XCopyArea(display, user->win, user->win, textGC,
  401.     XPOS(0), YPOS(0),
  402.     XPOS(user->t_cols), YPOS(user->t_rows - 1),
  403.     XPOS(0), YPOS(1));
  404.     XClearArea(display, user->win,
  405.     XPOS(0), YPOS(0),
  406.     0, font_height,
  407.     False);
  408.     place_cursor(user->win, user->ty, user->tx);
  409. }
  410.  
  411. void
  412. flush_xwin(user)
  413.   yuser *user;
  414. {
  415.     /* "user" is unused -- sorry, lint  :-) */
  416.     XFlush(display);
  417. }
  418.  
  419. #endif
  420.