Category : C Source Code
Archive   : POPI.ZIP
Filename : X11.C

 
Output of file : X11.C contained in archive : POPI.ZIP
/*LINTLIBRARY*/

/* @(#)x11.c 1.9 89/12/11
*
* X11 dependent graphics routines used by popi.
* written by Rich Burridge - Sun Microsystems.
*
* Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
* This version is based on the code in his Prentice Hall book,
* "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
* which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
*
* Permission is given to distribute these extensions, as long as these
* introductory messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if reported
* (see README file) then an attempt will be made to fix them.
*/

#include "popi.h"
#include "graphics.h"
#include
#include
#include
#include

#define BOLD_FONT "helvetica-bold-14"
#define DEFFONT "fixed"
#define NORMAL_FONT "8x13"

#define POPI_BORDER_WIDTH 2

#define FRAME_MASK (KeyPressMask | KeyReleaseMask | ExposureMask)

short icon_image[] = {
#include "popi.icon"
} ;

Atom protocol_atom, kill_atom ;
Cursor busy_cursor, main_cursor ;
Display *dpy ;
GC gc, pix_gc ;
Pixmap mpr, popi_icon, load_icon() ;
Visual *visual ;
Window frame, frame_icon ;
XColor current_col ;
XEvent event ;
XFontStruct *bfont, *font, *nfont ;
XGCValues gc_val ;
XSetWindowAttributes attributes ;
XSizeHints size ;
XVisualInfo vinfo ;
XWMHints wm_hints ;

unsigned long gc_mask ;
int screen ;
unsigned int scr_depth ;
unsigned long backgnd, foregnd ;
unsigned long palette[CMAPLEN] ;

/* 256-byte table for quickly reversing the bits in an unsigned 8-bit char,
* used to convert between MSBFirst and LSBFirst image formats.
*/

char revtable[256] = {
0, -128, 64, -64, 32, -96, 96, -32,
16, -112, 80, -48, 48, -80, 112, -16,
8, -120, 72, -56, 40, -88, 104, -24,
24, -104, 88, -40, 56, -72, 120, -8,
4, -124, 68, -60, 36, -92, 100, -28,
20, -108, 84, -44, 52, -76, 116, -12,
12, -116, 76, -52, 44, -84, 108, -20,
28, -100, 92, -36, 60, -68, 124, -4,
2, -126, 66, -62, 34, -94, 98, -30,
18, -110, 82, -46, 50, -78, 114, -14,
10, -118, 74, -54, 42, -86, 106, -22,
26, -102, 90, -38, 58, -70, 122, -6,
6, -122, 70, -58, 38, -90, 102, -26,
22, -106, 86, -42, 54, -74, 118, -10,
14, -114, 78, -50, 46, -82, 110, -18,
30, -98, 94, -34, 62, -66, 126, -2,
1, -127, 65, -63, 33, -95, 97, -31,
17, -111, 81, -47, 49, -79, 113, -15,
9, -119, 73, -55, 41, -87, 105, -23,
25, -103, 89, -39, 57, -71, 121, -7,
5, -123, 69, -59, 37, -91, 101, -27,
21, -107, 85, -43, 53, -75, 117, -11,
13, -115, 77, -51, 45, -83, 109, -19,
29, -99, 93, -35, 61, -67, 125, -3,
3, -125, 67, -61, 35, -93, 99, -29,
19, -109, 83, -45, 51, -77, 115, -13,
11, -117, 75, -53, 43, -85, 107, -21,
27, -101, 91, -37, 59, -69, 123, -5,
7, -121, 71, -57, 39, -89, 103, -25,
23, -105, 87, -41, 55, -73, 119, -9,
15, -113, 79, -49, 47, -81, 111, -17,
31, -97, 95, -33, 63, -65, 127, -1,
} ;

cleanup() /* Null routine for the X11 version. */
{
}


/* This routine needs to be dramatically improved. It should be possible
* to avoid copying the data to a separate buffer and creating a pixmap,
* and send it direct to the popi frame.
*/

draw_scanline(line, y) /* Display image scanline on the screen. */
unsigned char *line ;
int y ;
{
XImage *image ;
int i ;

if (iscolor)
{
mptr = (unsigned char *) Emalloc(Xsize) ;
for (i = 0; i < Xsize; i++) mptr[i] = palette[255 - line[i]] ;
image = XCreateImage(dpy, DefaultVisual(dpy, screen),
scr_depth, ZPixmap, 0, mptr, Xsize, 1, 8, Xsize) ;
mpr = XCreatePixmap(dpy, RootWindow(dpy, screen),
(unsigned) image->width,
(unsigned) image->height, scr_depth) ;
XPutImage(dpy, mpr, pix_gc, image, 0, 0, 0, 0,
(unsigned) image->width, (unsigned) image->height) ;
XDestroyImage(image) ;
}
else
{
mptr = (unsigned char *) Emalloc((Xsize / 8) + 1) ;
halftone(line, y) ;
for (i = 0; i < (Xsize / 8) + 1; i++) mptr[i] = revtable[mptr[i]] ;
mpr = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), mptr,
Xsize, 1, foregnd, backgnd, scr_depth) ; free(mptr) ;
}
XCopyArea(dpy, mpr, frame, gc, 0, 0, Xsize, 1, 0, y+100) ;
XFreePixmap(dpy, mpr) ;
}


drawarea(x, y, width, height, op)
int x, y, width, height ;
enum op_type op ;
{
gc_val.function = ops[(int) op] ;
XChangeGC(dpy, gc, GCFunction, &gc_val) ;
XFillRectangle(dpy, frame, gc, x, y,
(unsigned int) width, (unsigned int) height) ;
XSync(dpy, 0) ;
}


drawline(x1, y1, x2, y2)
int x1, y1, x2, y2 ;
{
gc_val.foreground = foregnd ;
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
XDrawLine(dpy, frame, gc, x1, y1, x2, y2) ;
}


drawtext(x, y, fontno, str)
enum font_type fontno ;
int x, y ;
char *str ;
{
if (fontno == NFONT) font = nfont ;
else if (fontno == BFONT) font = bfont ;
gc_val.font = font->fid ;
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCFont | GCFunction, &gc_val) ;
XDrawString(dpy, frame, gc, x, y, str, strlen(str)) ;
}


XFontStruct *
get_font(name)
char *name ;
{
XFontStruct *font ;

if (!(font = XLoadQueryFont(dpy, name)))
if (!(font = XLoadQueryFont(dpy, DEFFONT)))
{
perror("couldn't get the default font.") ;
exit(1) ;
}
return(font) ;
}


get_next_char(c)
char *c ;
{
XClientMessageEvent *ev ;
XKeyPressedEvent *key_event ;
KeySym keysym ;
char chs[2] ;

for (;;)
{
if (!XCheckMaskEvent(dpy, ExposureMask, &event))
XNextEvent(dpy, &event) ;

switch (event.type)
{
case ClientMessage : /* Catch ICCCM kill from WM. */

ev = (XClientMessageEvent *) &event ;
if (ev->message_type == protocol_atom &&
ev->data.l[0] == kill_atom)
exit(0) ;
break ;

case Expose : process_expose(&event) ;
break ;

case KeyPress : key_event = (XKeyPressedEvent *) &event ;
(void) XLookupString(key_event, chs, 1,
&keysym,
(XComposeStatus *) NULL) ;
if (keysym == XK_Shift_L ||
keysym == XK_Shift_R) break ;
*c = chs[0] ;
return ;
}
}
/*NOTREACHED*/
}


init_fonts()
{
bfont = get_font(BOLD_FONT) ;
nfont = get_font(NORMAL_FONT) ;
nfont_width = 8 ;
}


init_ws_type()
{
if ((dpy = XOpenDisplay(x11_display)) == NULL)
{
FPRINTF(stderr,"%s: Couldn't open display %s\n", ProgName,
(getenv ("DISPLAY") ? getenv("DISPLAY") : x11_display)) ;
exit(1) ;
}

screen = DefaultScreen(dpy) ;

if (!geometry)
STRCPY(geometry, XGetDefault(dpy, ProgName, "Geometry")) ;

foregnd = BlackPixel(dpy, screen) ;
backgnd = WhitePixel(dpy, screen) ;
scr_depth = DefaultDepth(dpy, screen) ;

ops[(int) GCLR] = GXclear ;
ops[(int) GSET] = GXset ;
return 0 ;
}


/*ARGSUSED*/
static Bool
is_exposed(dpy, ev, window) /* Return True if window is being exposed */
Display *dpy ;
XEvent *ev ;
char *window ;
{
if (ev->type == Expose && *((Window *) window) == ev->xkey.window)
return True ;
return False ;
}


load_colors() /* Create and load popi color map. */
{
u_char red[CMAPLEN], green[CMAPLEN], blue[CMAPLEN] ;
int i, numcolors ;

iscolor = 0 ;
if (DisplayCells(dpy, screen) > 2)
{
iscolor = 1 ;
numcolors = 0 ;
for (i = 0; i < CMAPLEN; i++)
{
current_col.flags = DoRed | DoGreen | DoBlue ;
current_col.red = current_col.green =
current_col.blue = (unsigned short) ((255 - i) << 8) ;
if (XAllocColor(dpy, DefaultColormap(dpy, screen), ¤t_col) == True)
palette[numcolors++] = current_col.pixel ;
}
if (numcolors < 2)
{
FPRINTF(stderr, "%s: cannot allocate colors.\n", ProgName) ;
exit(1) ;
}
}
}


Pixmap
load_icon(sbuf)
short sbuf[] ;
{
char cbuf[512] ;
int i ;

for (i = 0; i < 256; i++)
{
cbuf[i*2+0] = revtable[(sbuf[i] >> 8) & 0xFF] ;
cbuf[i*2+1] = revtable[sbuf[i] & 0xFF] ;
}
return(XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, screen), cbuf,
64, 64, foregnd, backgnd, scr_depth)) ;
}


make_items(argc, argv) /* Create icon, frame, canvas etc.. */
int argc ;
char *argv[] ;
{
unsigned int h, w ; /* Window dimensions. */
int flags ;
int x, y ; /* Window position. */

load_colors() ;
popi_icon = load_icon(icon_image) ;

size.flags = PMinSize | PMaxSize | PPosition | PSize ;
size.x = 0 ;
size.y = 0 ;
size.max_width = size.min_width = size.width = TWIDTH ;
size.max_height = size.min_height = size.height = THEIGHT ;

if (strlen(geometry))
{
flags = XParseGeometry(geometry, &x, &y, &w, &h) ;
if (XValue & flags)
{
if (XNegative & flags)
x = DisplayWidth(dpy, screen) + x - size.width ;
size.flags |= USPosition ;
size.x = x ;
}
if (YValue & flags)
{
if (YNegative & flags)
y = DisplayHeight(dpy, screen) + y - size.height ;
size.flags |= USPosition ;
size.y = y ;
}
}

frame = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
size.x, size.y, size.width, size.height,
POPI_BORDER_WIDTH, foregnd, backgnd) ;

protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False) ;
kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False) ;

XSetStandardProperties(dpy, frame, "popi", NULL, popi_icon,
argv, argc, &size) ;

wm_hints.icon_x = ix ;
wm_hints.icon_y = iy ;
wm_hints.input = True ;
wm_hints.icon_pixmap = popi_icon ;
wm_hints.flags = IconPositionHint | InputHint | IconPixmapHint ;
if (iconic)
{
wm_hints.initial_state = IconicState ;
wm_hints.flags |= StateHint ;
}
XSetWMHints(dpy, frame, &wm_hints) ;

gc_mask = GCFont | GCForeground | GCBackground | GCGraphicsExposures ;
gc_val.font = nfont->fid ;
gc_val.foreground = foregnd ;
gc_val.background = backgnd ;
gc_val.graphics_exposures = False ;
gc = XCreateGC(dpy, RootWindow(dpy, screen), gc_mask, &gc_val) ;
XSetFunction(dpy, gc, GXcopy) ;
pix_gc = DefaultGC(dpy, screen) ;

main_cursor = XCreateFontCursor(dpy, XC_top_left_arrow) ;
busy_cursor = XCreateFontCursor(dpy, XC_coffee_mug) ;
}


process_expose(event)
XExposeEvent *event ;
{
int doframe ;

doframe = 0 ;
do
{
if (event->count == 0)
if (event->window == frame) doframe++ ;
}
while (XCheckMaskEvent(dpy, ExposureMask, event)) ;

if (doframe) paint_canvas() ;
}


set_cursor(type)
enum cur_type type ;
{
switch (type)
{
case BUSY_CUR : XDefineCursor(dpy, frame, busy_cursor) ;
break ;
case NORMAL_CUR : XDefineCursor(dpy, frame, main_cursor) ;
}
}


start_tool()
{
XSelectInput(dpy, frame, FRAME_MASK) ;
XMapWindow(dpy, frame) ;
}


  3 Responses to “Category : C Source Code
Archive   : POPI.ZIP
Filename : X11.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/