home *** CD-ROM | disk | FTP | other *** search
- /*
- Here are some routines I wrote which implement +d option on
- unix computers running X-windows. For now, only black
- and white output is supported. If I get access to a computer
- with a color monitor, I'll probably add support for colors to
- my routines.
-
- In future I'll probably add some more dithering methods.
- I have tested these routines on SUN 3 and SUN 4. I'm using
- the tvtwm window manager.
-
- If you have some suggestions to my source code or if you change
- anything, please let me know. I can be reached at the following
- address: Marek Rzewuski, Avstikkeren 11, 1156 Oslo 11, Norway or
- marekr@ifi.uio.no on Internet.
- */
-
- #include <stdio.h>
- #include <X11/Xlib.h> /* some Xlib stuff */
- #include <X11/Xutil.h>
- #include "theIcon"
-
- #include "frame.h"
- #include "dkbproto.h"
-
- #define BORDER_WIDTH 2
- #define EV_MASK (ButtonPressMask | \
- KeyPressMask | \
- ExposureMask | \
- StructureNotifyMask)
-
- Display *theDisplay;
- int theScreen;
- int theDepth;
- unsigned long theBlackPixel;
- unsigned long theWhitePixel;
- XEvent theEvent;
- Window theWindow, openWindow();
- GC theGC;
- unsigned char *bitmap; /* pointer to our picture bitmap */
- unsigned char *bitmapPos; /* position to the last drawn pixel in our bitmap */
-
-
- /* global DKBTrace variables */
-
- extern FRAME Frame;
- extern unsigned int Options;
- extern char DisplayFormat;
- extern int First_Line;
-
- enum pixval { BLACK, WHITE };
-
- /* an dither matrix used to produce some dithering when using black/white screen */
- int dither_matrix[8][8] = {
- { 2, 60, 16, 56, 3, 57, 13, 53 },
- { 34, 18, 48, 32, 35, 19, 45, 29 },
- { 10, 50, 6, 64, 11, 51, 7, 61 },
- { 42, 26, 38, 22, 43, 27, 39, 23 },
- { 4, 58, 14, 54, 1, 59, 15, 55 },
- { 36, 20, 46, 30, 33, 17, 47, 31 },
- { 44, 28, 40, 24, 41, 25, 37, 21 },
- { 2, 60, 16, 56, 3, 57, 13, 53 }};
-
- void unix_init_dkb_trace PARAMS ((void))
- {
- }
-
- enum pixval
- dither(r, g, b, x, y)
- int r, g, b, x, y;
- {
- int greyval;
-
- /* They say those numbers are the best, don't ask me why... */
- greyval = (0.299*r + 0.587*g + 0.114*b) * 64. / 255.;
- return (greyval < dither_matrix[x%8][y%8]) ? BLACK : WHITE;
- }
-
-
-
-
- /* Sets up a connection to the X server and stores informations about the enviroment */
-
- initX()
- {
- theDisplay = XOpenDisplay(NULL);
- if (theDisplay == NULL) {
- fprintf(stderr,"ERROR: Cannot establish a connection to the X server %s\n",
- XDisplayName(NULL));
- exit(1);
- }
- theScreen = DefaultScreen(theDisplay);
- theDepth = DefaultDepth(theDisplay, theScreen);
- theWhitePixel = WhitePixel(theDisplay, theScreen);
- theBlackPixel = BlackPixel(theDisplay, theScreen);
- }
-
- /* This procedure will do the following things:
- 1) Set up attributes desired for the window
- 2) Set up an icon to our window.
- 3) Send hints to the window manager.
- 4) Open a window on the display
- 5) Tell the X to place the window on the screen
- 6) Flush out all the queued up X requests to the X server */
-
- Window openWindow(x,y,width,height,flag,theNewGC)
- int x,y;
- int width,height;
- int flag;
- GC *theNewGC;
- {
- XSetWindowAttributes theWindowAttributes;
- XSizeHints theSizeHints;
- unsigned long theWindowMask;
- Window theNewWindow;
- Pixmap theIconPixmap;
- XWMHints theWMHints;
-
-
- /* Set up some attributes for the window. Override_redirect tells
- the window manager to deal width the window or leave it alone */
-
- theWindowAttributes.border_pixel = theBlackPixel;
- theWindowAttributes.background_pixel = theWhitePixel;
- theWindowAttributes.override_redirect = False;
- theWindowMask = CWBackPixel | CWBorderPixel | CWOverrideRedirect;
-
- /* Now, open out window */
-
- theNewWindow = XCreateWindow(theDisplay,
- RootWindow(theDisplay,theScreen),
- x,y,
- width, height,
- BORDER_WIDTH,
- theDepth,
- InputOutput,
- CopyFromParent,
- theWindowMask,
- &theWindowAttributes);
-
- /* Create one iconbitmap */
-
- theIconPixmap = XCreateBitmapFromData(theDisplay,
- theNewWindow,
- theIcon_bits,
- theIcon_width,
- theIcon_height);
-
- /* Now tell the window manager where on screen we should place our
- window. */
-
- theWMHints.icon_pixmap = theIconPixmap;
- theWMHints.initial_state = NormalState; /* we don't want an iconized window when it's created */
- theWMHints.flags = IconPixmapHint | StateHint;
-
- XSetWMHints(theDisplay,theNewWindow,&theWMHints);
-
- theSizeHints.flags = PPosition | PSize;
- theSizeHints.x = x;
- theSizeHints.y = y;
- theSizeHints.width = width;
- theSizeHints.height = height;
- /* theSizeHints.min_width = width;
- theSizeHints.min_height = height;
- theSizeHints.max_width = width;
- theSizeHints.max_height = height; */
-
- XSetNormalHints(theDisplay,theNewWindow,&theSizeHints);
-
-
- if (createGC(theNewWindow, theNewGC) == 0) {
- XDestroyWindow(theDisplay, theNewWindow);
- return((Window) 0);
- }
-
- /* make a name for our window */
-
- XStoreName(theDisplay, theNewWindow, "DKBTrace v2.10\0");
-
- /* Now, could we please see the window on the screen?
- Until now, we have dealed with a window which has been created
- but noe appeared on the screen. Maping the window places it visibly
- on the screen */
-
- XMapWindow(theDisplay,theNewWindow);
- XFlush(theDisplay);
- return(theNewWindow);
- }
-
- refreshWindow(theExposedWindow)
- Window theExposedWindow;
- {
- int i, x, y;
- unsigned char *dummy;
- dummy = bitmap;
- i = 0; x= 0; y = First_Line;
- do {
- if (*dummy)
- XDrawPoint(theDisplay, theWindow, theGC,x,y);
- if (x == Frame.Screen_Width) {
- x = 0;
- y++;
- } else {
- dummy++;
- x++;
- i++;
- }
- } while(dummy != bitmapPos); /* until dummy = the last drawn pixel in our window */
- XFlush(theDisplay);
- }
-
- /* Creates a new graphics context */
-
- createGC(theNewWindow, theNewGC)
- Window theNewWindow;
- GC *theNewGC;
- {
- XGCValues theGCValues;
- *theNewGC = XCreateGC(theDisplay,
- theNewWindow,
- (unsigned long) 0,
- &theGCValues);
-
- if (*theNewGC == 0) {
- return(0); /*error*/
- } else { /* set foreground and background defaults for the new GC */
- XSetForeground(theDisplay,
- *theNewGC,
- theBlackPixel);
-
- XSetBackground(theDisplay,
- *theNewGC,
- theWhitePixel);
-
- return(1); /* OK */
- }
- }
-
- initEvents(theWindow)
- Window theWindow;
- {
- XSelectInput(theDisplay,
- theWindow,
- EV_MASK);
- }
-
- void display_finished ()
- {
-
- }
-
-
- void display_init ()
- {
- int i;
-
- /* set some room for a bitmap for our picture. I've got to "remember" the whole
- picture bacuse of resising of the window, overlaping etc. Then I've got to
- refresh the picture. This should be easy to convert to an "color version" in
- future */
-
- bitmap = (unsigned char *) malloc(sizeof(unsigned char) * (Frame.Screen_Width * Frame.Screen_Height));
- bitmapPos = bitmap;
- if (bitmap == NULL)
- printf("ERROR: Can not allocate the buffer..\n");
-
- for (i = 0; i < (Frame.Screen_Width*Frame.Screen_Height); i++) {
- *bitmapPos++ = 0;
- }
- bitmapPos = bitmap;
- initX();
- theWindow = openWindow(0,0,Frame.Screen_Width,Frame.Screen_Height,0,&theGC);
- initEvents(theWindow);
- XFlush(theDisplay);
- XNextEvent(theDisplay,&theEvent);
- XFlush(theDisplay);
- } /* end of display initilazation */
-
- void display_close ()
- {
- sleep(10); /* an simple delay. 10 seconds. */
- XDestroyWindow(theDisplay,theWindow);
- XFlush(theDisplay);
- XCloseDisplay(theDisplay);
- free(bitmap);
- }
-
- void display_plot (x, y, Red, Green, Blue)
- int x, y;
- unsigned char Red, Green, Blue;
- {
- unsigned char color;
- int numEvents;
- /* lets find if there are some events waiting for us */
-
- numEvents = XPending(theDisplay);
- if (numEvents > 0) { /* now deal with the events.. */
- XNextEvent(theDisplay,&theEvent);
-
- switch (theEvent.type) {
- case Expose:
- /*printf("Window is exposed.\n");*/
- refreshWindow(theEvent.xany.window);
- break;
-
- case MapNotify:
- /*printf("The window is mapped.\n");*/
- refreshWindow(theEvent.xany.window);
- break;
-
- case ButtonPress:
- /*printf("A mouse button was pressed.\n");*/
- break;
-
- case ConfigureNotify:
- /*printf("The window configuration has been changed\n");*/
- refreshWindow(theEvent.xany.window);
- break;
- }
- }
- color = (!dither(Red, Green, Blue, x, y));
-
- *bitmapPos = color;
- if (color)
- XDrawPoint(theDisplay, theWindow, theGC,x,y);
- bitmapPos++;
- /*XFlush(theDisplay); Let's be nice to the network, OK? */
- }
-
-