home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume27
/
ytalk-3.0
/
part01
/
xwin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-20
|
9KB
|
420 lines
/* xwin.c -- X Window Terminal Interface */
/* NOTICE
*
* Copyright (c) 1990,1992,1993 Britt Yenne. All rights reserved.
*
* This software is provided AS-IS. The author gives no warranty,
* real or assumed, and takes no responsibility whatsoever for any
* use or misuse of this software, or any damage created by its use
* or misuse.
*
* This software may be freely copied and distributed provided that
* no part of this NOTICE is deleted or edited in any manner.
*
*/
/* Mail comments or questions to ytalk@austin.eds.com */
#ifdef USE_X11
#include "header.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
static Display *display; /* display */
static Window rootwin; /* root window */
static int screen_num; /* screen number */
static XrmDatabase db; /* resource database */
static XFontStruct *text_font; /* font */
static GC textGC, /* text graphic context */
invertGC; /* graphic context for inverts */
static u_long whitepix, /* white pixel */
blackpix; /* black pixel */
static int font_width, /* font width */
font_height, /* font height */
font_ascent; /* font ascent */
#define YPOS(p) ((p) * font_height)
#define XPOS(p) ((p) * font_width)
/* ----- local functions ----- */
static XTextProperty *
strToTP(s)
char *s;
{
XTextProperty *tp = (XTextProperty *)get_mem(sizeof(XTextProperty));
XStringListToTextProperty(&s, 1, tp);
return tp;
}
static char *
getOption(o)
char *o;
{
XrmValue value;
char *type;
if(XrmGetResource(db, o, o, &type, &value))
{
if(value.addr == NULL)
return NULL;
if(strcmp(value.addr, "false") == 0)
return NULL;
if(strcmp(value.addr, "False") == 0)
return NULL;
return value.addr;
}
else
return (char *)NULL;
}
static void
load_font(name, font)
char *name;
XFontStruct **font;
{
if((*font = XLoadQueryFont(display, name)) == NULL)
{
sprintf(errstr, "Cannot load font %s", name);
show_error(errstr);
bail(YTE_ERROR);
}
}
static void
make_GC(gc, font, fgpixel, bgpixel, l_width, l_style, l_cap, l_join, gcfunc)
GC *gc;
XFontStruct *font;
u_long fgpixel, bgpixel;
int l_width, l_style, l_cap, l_join, gcfunc;
{
u_long mask = 0;
XGCValues values;
if(font != NULL)
{
values.font = font->fid;
mask |= GCFont;
}
values.foreground = fgpixel;
values.background = bgpixel;
values.line_width = l_width;
values.line_style = l_style;
values.cap_style = l_cap;
values.join_style = l_join;
mask |= GCForeground | GCBackground | GCLineWidth | GCLineStyle |
GCCapStyle | GCJoinStyle;
if(gcfunc != -1)
{
values.function = gcfunc;
mask |= GCFunction;
}
*gc = XCreateGC(display, rootwin, mask, &values);
}
/* Find the user who owns a given Window.
*/
static yuser *
win_user(win)
Window win;
{
register yuser *u;
for(u = user_list; u; u = u->unext)
if(u->win == win)
break;
return u;
}
#define TWIN report.xany.window
static void
process_event()
{
register int n;
register yuser *user;
static XEvent report;
static char buf[512];
while(XPending(display))
{
XNextEvent(display, &report);
switch(report.type)
{
case Expose:
if(report.xexpose.count)
break;
if((user = win_user(TWIN)) != NULL)
redraw_term(user, 0);
break;
case ConfigureNotify: /* RESIZED (or moved) */
if((user = win_user(TWIN)) != NULL)
{
int rows, cols;
rows = report.xconfigure.height / font_height;
cols = report.xconfigure.width / font_width;
resize_win(user, rows, cols);
}
break;
case KeyPress:
n = XLookupString(&report, buf, 512, NULL, NULL);
my_input(buf, n);
break;
}
}
}
static void
place_cursor(win, y, x)
Window win;
int y, x;
{
XFillRectangle(display, win, invertGC,
XPOS(x), YPOS(y),
font_width, font_height);
}
/* ----- global functions ----- */
/* Initialize X Windows.
*/
void
init_xwin()
{
extern char *getenv();
char *displayName;
char *rfn, str[256];
int xfd;
XGCValues values;
/* get and open the display */
displayName = getOption("YTalk.display");
if((display = XOpenDisplay(displayName)) == NULL)
{
show_error("Cannot open X display");
bail(YTE_ERROR);
}
rootwin = DefaultRootWindow(display);
screen_num = DefaultScreen(display);
/* read all options */
db = XrmGetStringDatabase(XResourceManagerString(display));
if((rfn = getenv("HOME")) != NULL)
{
sprintf(str, "%s/.Xdefaults", rfn);
if(access(str, 0) == 0)
XrmMergeDatabases(XrmGetFileDatabase(str), &db);
}
if((rfn = getenv("XENVIRONMENT")) != NULL)
if(access(rfn, 0) == 0)
XrmMergeDatabases(XrmGetFileDatabase(rfn), &db);
if(getOption("YTalk.reverse"))
{
whitepix = BlackPixel(display, screen_num);
blackpix = WhitePixel(display, screen_num);
}
else
{
blackpix = BlackPixel(display, screen_num);
whitepix = WhitePixel(display, screen_num);
}
/* load font and graphic context */
if((rfn = getOption("YTalk.font")) == NULL)
rfn = "9x15";
load_font(rfn, &text_font);
font_width = text_font->max_bounds.rbearing;
font_height = text_font->max_bounds.ascent + text_font->max_bounds.descent;
font_ascent = text_font->max_bounds.ascent;
make_GC(&textGC, text_font, blackpix, whitepix,
2, LineSolid, CapRound, JoinRound, -1);
make_GC(&invertGC, text_font, blackpix, whitepix,
2, LineSolid, CapRound, JoinRound, GXinvert);
values.plane_mask = blackpix ^ whitepix;
XChangeGC(display, invertGC, GCPlaneMask, &values);
/* set up event processing */
xfd = ConnectionNumber(display);
add_fd(xfd, process_event);
}
/* End X Windows.
*/
void
end_xwin()
{
XCloseDisplay(display);
}
/* Open a new window.
*/
int
open_xwin(user, title)
yuser *user;
char *title;
{
XWMHints WMhints;
XClassHint ClassHints;
XSizeHints size;
XTextProperty *name;
Window win;
int rows, cols;
size.x = 0;
size.y = 0;
size.width = 80;
size.height = 24;
size.min_width = 20;
size.min_height = 2;
size.width_inc = font_width;
size.height_inc = font_height;
size.flags = PSize | PMinSize | PResizeInc;
if(getOption("YTalk.geometry"))
{
XParseGeometry(getOption("YTalk.geometry"),
&size.x, &size.y, &size.width, &size.height);
/* don't set USPosition -- it confuses tvtwm */
}
rows = size.height;
cols = size.width;
size.width *= font_width;
size.height *= font_height;
size.min_width *= font_width;
size.min_height *= font_height;
win = XCreateSimpleWindow(display, rootwin, size.x, size.y,
size.width, size.height, 4, blackpix, whitepix);
if(win == (Window)0)
return -1;
WMhints.flags = InputHint;
WMhints.input = 1;
ClassHints.res_name = "ytalk";
ClassHints.res_class = "YTalk";
name = strToTP(title);
XSetWMProperties(display, win, name, name,
0, 0, &size, &WMhints, &ClassHints);
XSelectInput(display, win, ExposureMask | KeyPressMask
| StructureNotifyMask);
XMapRaised(display, win);
user->win = win;
user->ty = user->tx = 0;
place_cursor(win, 0, 0);
resize_win(user, rows, cols);
return 0;
}
void
close_xwin(user)
yuser *user;
{
XDestroyWindow(display, user->win);
user->win = (Window)0;
}
void
addch_xwin(user, ch)
yuser *user;
ychar ch;
{
XClearArea(display, user->win,
XPOS(user->tx), YPOS(user->ty),
font_width, font_height,
False);
XDrawString(display, user->win, textGC,
XPOS(user->tx), YPOS(user->ty) + font_ascent,
&ch, 1);
user->tx++;
if(user->tx >= user->t_cols)
user->tx--;
place_cursor(user->win, user->ty, user->tx);
}
void
move_xwin(user, y, x)
yuser *user;
int y, x;
{
place_cursor(user->win, user->ty, user->tx);
user->ty = y;
user->tx = x;
place_cursor(user->win, user->ty, user->tx);
}
void
clreol_xwin(user)
yuser *user;
{
XClearArea(display, user->win,
XPOS(user->tx), YPOS(user->ty),
0, font_height,
False);
place_cursor(user->win, user->ty, user->tx);
}
void
clreos_xwin(user)
yuser *user;
{
XClearArea(display, user->win,
XPOS(user->tx), YPOS(user->ty),
0, font_height,
False);
XClearArea(display, user->win,
0, YPOS(user->ty + 1),
0, 0,
False);
place_cursor(user->win, user->ty, user->tx);
}
void
scroll_xwin(user)
yuser *user;
{
place_cursor(user->win, user->ty, user->tx);
XCopyArea(display, user->win, user->win, textGC,
XPOS(0), YPOS(1),
XPOS(user->t_cols), YPOS(user->t_rows - 1),
XPOS(0), YPOS(0));
XClearArea(display, user->win,
0, YPOS(user->t_rows - 1),
0, font_height,
False);
place_cursor(user->win, user->ty, user->tx);
}
void
rev_scroll_xwin(user)
yuser *user;
{
place_cursor(user->win, user->ty, user->tx);
XCopyArea(display, user->win, user->win, textGC,
XPOS(0), YPOS(0),
XPOS(user->t_cols), YPOS(user->t_rows - 1),
XPOS(0), YPOS(1));
XClearArea(display, user->win,
XPOS(0), YPOS(0),
0, font_height,
False);
place_cursor(user->win, user->ty, user->tx);
}
void
flush_xwin(user)
yuser *user;
{
/* "user" is unused -- sorry, lint :-) */
XFlush(display);
}
#endif