This is xwin.c in view mode; [Download] [Up]
/* 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 ylong 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; ylong fgpixel, bgpixel; int l_width, l_style, l_cap, l_join, gcfunc; { ylong 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((XKeyEvent *) &report, buf, 512, NULL, NULL); my_input(win_user(report.xkeymap.window), 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() { char *xrmstr; 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 = NULL; XrmInitialize(); if((xrmstr = XResourceManagerString(display)) != NULL) db = XrmGetStringDatabase(xrmstr); else if((rfn = (char *)getenv("XENVIRONMENT")) != NULL && access(rfn, 0) == 0) db = XrmGetFileDatabase(rfn); else if((rfn = (char *)getenv("HOME")) != NULL) { sprintf(str, "%s/.Xdefaults", rfn); if(access(str, 0) == 0) db = XrmGetFileDatabase(str); } if(db == NULL) db = XrmGetStringDatabase(""); 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, (u_int *)&size.width, (u_int *)&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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.