home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / ytalk-3.0.1 / xwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-27  |  9.2 KB  |  425 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 ylong        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.   ylong fgpixel, bgpixel;
  92.   int l_width, l_style, l_cap, l_join, gcfunc;
  93. {
  94.     ylong 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((XKeyEvent *) &report, buf, 512, NULL, NULL);
  164.         my_input(win_user(report.xkeymap.window), 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.     char    *xrmstr;
  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 = NULL;
  207.     XrmInitialize();
  208.     if((xrmstr = XResourceManagerString(display)) != NULL)
  209.     db = XrmGetStringDatabase(xrmstr);
  210.     else if((rfn = (char *)getenv("XENVIRONMENT")) != NULL
  211.         && access(rfn, 0) == 0)
  212.     db = XrmGetFileDatabase(rfn);
  213.     else if((rfn = (char *)getenv("HOME")) != NULL)
  214.     {
  215.     sprintf(str, "%s/.Xdefaults", rfn);
  216.     if(access(str, 0) == 0)
  217.         db = XrmGetFileDatabase(str);
  218.     }
  219.     if(db == NULL)
  220.     db = XrmGetStringDatabase("");
  221.     if(getOption("YTalk.reverse"))
  222.     {
  223.     whitepix = BlackPixel(display, screen_num);
  224.     blackpix = WhitePixel(display, screen_num);
  225.     }
  226.     else
  227.     {
  228.     blackpix = BlackPixel(display, screen_num);
  229.     whitepix = WhitePixel(display, screen_num);
  230.     }
  231.  
  232.     /* load font and graphic context */
  233.  
  234.     if((rfn = getOption("YTalk.font")) == NULL)
  235.     rfn = "9x15";
  236.     load_font(rfn, &text_font);
  237.     font_width = text_font->max_bounds.rbearing;
  238.     font_height = text_font->max_bounds.ascent + text_font->max_bounds.descent;
  239.     font_ascent = text_font->max_bounds.ascent;
  240.     make_GC(&textGC, text_font, blackpix, whitepix,
  241.         2, LineSolid, CapRound, JoinRound, -1);
  242.     make_GC(&invertGC, text_font, blackpix, whitepix,
  243.         2, LineSolid, CapRound, JoinRound, GXinvert);
  244.     values.plane_mask = blackpix ^ whitepix;
  245.     XChangeGC(display, invertGC, GCPlaneMask, &values);
  246.  
  247.     /* set up event processing */
  248.  
  249.     xfd = ConnectionNumber(display);
  250.     add_fd(xfd, process_event);
  251. }
  252.  
  253. /* End X Windows.
  254.  */
  255. void
  256. end_xwin()
  257. {
  258.     XCloseDisplay(display);
  259. }
  260.  
  261. /* Open a new window.
  262.  */
  263. int
  264. open_xwin(user, title)
  265.   yuser *user;
  266.   char *title;
  267. {
  268.     XWMHints    WMhints;
  269.     XClassHint    ClassHints;
  270.     XSizeHints    size;
  271.     XTextProperty *name;
  272.     Window    win;
  273.     int        rows, cols;
  274.  
  275.     size.x = 0;
  276.     size.y = 0;
  277.     size.width = 80;
  278.     size.height = 24;
  279.     size.min_width = 20;
  280.     size.min_height = 2;
  281.     size.width_inc = font_width;
  282.     size.height_inc = font_height;
  283.     size.flags = PSize | PMinSize | PResizeInc;
  284.     if(getOption("YTalk.geometry"))
  285.     {
  286.     XParseGeometry(getOption("YTalk.geometry"),
  287.         &size.x, &size.y, (u_int *)&size.width, (u_int *)&size.height);
  288.  
  289.     /* don't set USPosition -- it confuses tvtwm */
  290.     }
  291.     rows = size.height;
  292.     cols = size.width;
  293.     size.width *= font_width;
  294.     size.height *= font_height;
  295.     size.min_width *= font_width;
  296.     size.min_height *= font_height;
  297.     win = XCreateSimpleWindow(display, rootwin, size.x, size.y,
  298.     size.width, size.height, 4, blackpix, whitepix);
  299.     if(win == (Window)0)
  300.     return -1;
  301.  
  302.     WMhints.flags = InputHint;
  303.     WMhints.input = 1;
  304.     ClassHints.res_name = "ytalk";
  305.     ClassHints.res_class = "YTalk";
  306.     name = strToTP(title);
  307.     XSetWMProperties(display, win, name, name,
  308.     0, 0, &size, &WMhints, &ClassHints);
  309.  
  310.     XSelectInput(display, win, ExposureMask | KeyPressMask
  311.     | StructureNotifyMask);
  312.     XMapRaised(display, win);
  313.  
  314.     user->win = win;
  315.     user->ty = user->tx = 0;
  316.     place_cursor(win, 0, 0);
  317.     resize_win(user, rows, cols);
  318.     return 0;
  319. }
  320.  
  321. void
  322. close_xwin(user)
  323.   yuser *user;
  324. {
  325.     XDestroyWindow(display, user->win);
  326.     user->win = (Window)0;
  327. }
  328.  
  329. void
  330. addch_xwin(user, ch)
  331.   yuser *user;
  332.   ychar ch;
  333. {
  334.     XClearArea(display, user->win,
  335.     XPOS(user->tx), YPOS(user->ty),
  336.     font_width, font_height,
  337.     False);
  338.     XDrawString(display, user->win, textGC,
  339.     XPOS(user->tx), YPOS(user->ty) + font_ascent,
  340.     &ch, 1);
  341.     user->tx++;
  342.     if(user->tx >= user->t_cols)
  343.     user->tx--;
  344.     place_cursor(user->win, user->ty, user->tx);
  345. }
  346.  
  347. void
  348. move_xwin(user, y, x)
  349.   yuser *user;
  350.   int y, x;
  351. {
  352.     place_cursor(user->win, user->ty, user->tx);
  353.     user->ty = y;
  354.     user->tx = x;
  355.     place_cursor(user->win, user->ty, user->tx);
  356. }
  357.  
  358. void
  359. clreol_xwin(user)
  360.   yuser *user;
  361. {
  362.     XClearArea(display, user->win,
  363.     XPOS(user->tx), YPOS(user->ty),
  364.     0, font_height,
  365.     False);
  366.     place_cursor(user->win, user->ty, user->tx);
  367. }
  368.  
  369. void
  370. clreos_xwin(user)
  371.   yuser *user;
  372. {
  373.     XClearArea(display, user->win,
  374.     XPOS(user->tx), YPOS(user->ty),
  375.     0, font_height,
  376.     False);
  377.     XClearArea(display, user->win,
  378.     0, YPOS(user->ty + 1),
  379.     0, 0,
  380.     False);
  381.     place_cursor(user->win, user->ty, user->tx);
  382. }
  383.  
  384. void
  385. scroll_xwin(user)
  386.   yuser *user;
  387. {
  388.     place_cursor(user->win, user->ty, user->tx);
  389.     XCopyArea(display, user->win, user->win, textGC,
  390.     XPOS(0), YPOS(1),
  391.     XPOS(user->t_cols), YPOS(user->t_rows - 1),
  392.     XPOS(0), YPOS(0));
  393.     XClearArea(display, user->win,
  394.     0, YPOS(user->t_rows - 1),
  395.     0, font_height,
  396.     False);
  397.     place_cursor(user->win, user->ty, user->tx);
  398. }
  399.  
  400. void
  401. rev_scroll_xwin(user)
  402.   yuser *user;
  403. {
  404.     place_cursor(user->win, user->ty, user->tx);
  405.     XCopyArea(display, user->win, user->win, textGC,
  406.     XPOS(0), YPOS(0),
  407.     XPOS(user->t_cols), YPOS(user->t_rows - 1),
  408.     XPOS(0), YPOS(1));
  409.     XClearArea(display, user->win,
  410.     XPOS(0), YPOS(0),
  411.     0, font_height,
  412.     False);
  413.     place_cursor(user->win, user->ty, user->tx);
  414. }
  415.  
  416. void
  417. flush_xwin(user)
  418.   yuser *user;
  419. {
  420.     /* "user" is unused -- sorry, lint  :-) */
  421.     XFlush(display);
  422. }
  423.  
  424. #endif
  425.