home *** CD-ROM | disk | FTP | other *** search
- /* Xteddy - a cuddly bear to place on your desktop. */
- /* Copyright Stefan Gustavson, ISY-LiTH, 1994. */
- /* Internet email address: stefang@isy.liu.se */
-
- /* Xpm pixmap manipulation routines for color */
- /* and grayscale teddies are from the Xpm library */
- /* by Arnaud Le Hors, lehors@sophia.inria.fr, */
- /* Copyright 1990-93 GROUPE BULL */
-
- /* 1994-01-20: First working version (1.0). */
- /* Supports mono, grayscale and color displays. */
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xos.h>
- #include <X11/Xatom.h>
- #include <X11/keysym.h>
- #include <X11/extensions/shape.h>
- #include <X11/cursorfont.h>
-
- #if !defined(TRUE)
- #define TRUE 1
- #endif
-
- #ifndef NOXPM
- #include <xpm.h>
- #endif
-
- #include <stdio.h>
-
- #include "xteddy_icon.xbm"
- #include "xteddy_bw.xbm"
- #include "xteddy_mask.xbm"
-
- #ifndef NOXPM
- #include "xteddy_gray.xpm"
- #include "xteddy_color.xpm"
- #endif
-
- #include "patchlevel.h"
-
- static char *progname;
- Display *display;
- int screen_num;
-
- void main(argc, argv)
- int argc;
- char **argv;
- {
- /* Display, window and gc manipulation variables */
- Window win;
- GC gc;
- XSetWindowAttributes setwinattr;
- XGCValues gcvalues;
- unsigned long valuemask, gcvaluemask;
- unsigned int width, height;
- int x,y;
- unsigned int border_width = 0;
- unsigned int display_width, display_height, display_depth;
- char *window_name = "Xteddy";
- char *icon_name = "xteddy";
- Pixmap icon_pixmap, background_pixmap, shape_pixmap;
- XSizeHints size_hints;
- XIconSize *size_list;
- XWMHints wm_hints;
- XClassHint class_hints;
- XTextProperty windowName, iconName;
- int count;
- XEvent report;
- char *display_name = NULL;
- char buffer[20];
- int bufsize = 20;
- KeySym keysym;
- XComposeStatus compose;
- int charcount;
- Cursor cursor;
-
- #ifndef NOXPM
- /* Color allocation variables */
- Visual *default_visual;
- Colormap default_cmap;
- XpmAttributes xpmattributes;
- int visual_class;
- XVisualInfo visual_info;
- static char *visual_name[]={ "StaticGray", "GrayScale", "StaticColor",
- "PseudoColor", "TrueColor", "DirectColor" };
- #endif
-
- /* Window movement variables */
- XWindowChanges winchanges;
- Window root, child;
- int offs_x, offs_y, new_x, new_y, tmp_x, tmp_y;
- unsigned int tmp_mask;
-
- progname = argv[0];
-
- /* Connect to X server */
- if ( (display = XOpenDisplay(display_name)) == NULL )
- {
- (void) fprintf(stderr, "%s: Cannot connect to X server %s\n",
- progname, XDisplayName(display_name));
- exit(-1);
- }
-
- /* Set the window size to snugly fit the teddybear pixmap */
- width = xteddy_bw_width;
- height = xteddy_bw_height;
- /* Create the main window */
- x = y = 0;
- win = XCreateSimpleWindow(display, RootWindow(display,screen_num),
- x,y,width,height,border_width,
- BlackPixel(display,screen_num),
- WhitePixel(display,screen_num));
-
- /* Create a GC (Currently not used for any drawing) */
- gcvalues.foreground = BlackPixel(display,screen_num);
- gcvalues.background = WhitePixel(display,screen_num);
- gcvaluemask = GCForeground | GCBackground;
- gc = XCreateGC(display, win, gcvaluemask, &gcvalues);
-
- /* Get screen size and depth */
- screen_num = DefaultScreen(display);
- display_width = DisplayWidth(display, screen_num);
- display_height = DisplayHeight(display, screen_num);
- display_depth = DefaultDepth(display, screen_num);
-
- #ifndef NOXPM
- /* Get information about the default visual */
- default_visual = DefaultVisual(display, screen_num);
- default_cmap = DefaultColormap(display, screen_num);
- #endif
-
- #ifdef NOXPM
- /* Use b/w dithered bitmap no matter what */
- background_pixmap =
- XCreatePixmapFromBitmapData(display, win, xteddy_bw_bits,
- xteddy_bw_width, xteddy_bw_height,
- BlackPixel(display, screen_num),
- WhitePixel(display, screen_num),
- display_depth);
- #else
- /* Check which visual types are supported */
- visual_class = 5;
- while(!XMatchVisualInfo(display, screen_num, display_depth,
- visual_class--, &visual_info));
- visual_class++;
- #ifdef DEBUG
- printf("%s: found a %s class visual at default depth.\n",
- progname, visual_name[visual_class]);
- #endif
- if (visual_class == StaticGray)
- {
- /* Use b/w dithered bitmap */
- background_pixmap =
- XCreatePixmapFromBitmapData(display, win, xteddy_bw_bits,
- xteddy_bw_width, xteddy_bw_height,
- BlackPixel(display, screen_num),
- WhitePixel(display, screen_num),
- display_depth);
- }
- else if (visual_class == GrayScale)
- {
- /* Use grayscale pixmap */
- /* This creation of a grayscale pixmap requires the Xpm library */
- xpmattributes.visual = default_visual;
- xpmattributes.colormap = default_cmap;
- xpmattributes.depth = display_depth;
- xpmattributes.valuemask = XpmVisual | XpmColormap | XpmDepth;
- if (XpmCreatePixmapFromData(display, win, xteddy_gray,
- &background_pixmap, &shape_pixmap,
- &xpmattributes) < XpmSuccess)
- {
- printf("%s: Failed to allocate grays. Using black-and-white.\n",
- progname);
- background_pixmap =
- XCreatePixmapFromBitmapData(display, win, xteddy_bw_bits,
- xteddy_bw_width, xteddy_bw_height,
- BlackPixel(display, screen_num),
- WhitePixel(display, screen_num),
- display_depth);
- }
- }
- else /* At least StaticColor - use color pixmap */
- {
- #ifdef DEBUG
- if (visual_info.visual != default_visual)
- {
- printf("%s: %s class visual at default depth\n",
- progname, visual_name[visual_class]);
- printf("is not default visual. Continuing anyway...\n");
- }
- #endif
- /* This creation of a color pixmap requires the Xpm library */
- xpmattributes.visual = default_visual;
- xpmattributes.colormap = default_cmap;
- xpmattributes.depth = display_depth;
- xpmattributes.valuemask = XpmVisual | XpmColormap | XpmDepth;
- if (XpmCreatePixmapFromData(display, win, xteddy_color,
- &background_pixmap, &shape_pixmap,
- &xpmattributes) < XpmSuccess)
- {
- printf("%s: Failed to allocate colors. Using black-and-white.\n",
- progname);
- background_pixmap =
- XCreatePixmapFromBitmapData(display, win, xteddy_bw_bits,
- xteddy_bw_width, xteddy_bw_height,
- BlackPixel(display, screen_num),
- WhitePixel(display, screen_num),
- display_depth);
- }
- }
- #endif
- setwinattr.background_pixmap = background_pixmap;
- #ifdef USEWM
- setwinattr.override_redirect = FALSE;
- #else
- setwinattr.override_redirect = TRUE;
- #endif
- cursor = XCreateFontCursor(display, XC_heart);
- setwinattr.cursor = cursor;
- valuemask = CWBackPixmap | CWOverrideRedirect | CWCursor;
- XChangeWindowAttributes(display, win, valuemask, &setwinattr);
-
- /* Create and set the shape pixmap of the window - requires shape Xext */
- shape_pixmap = XCreateBitmapFromData(display,win, xteddy_mask_bits,
- xteddy_mask_width, xteddy_mask_height);
- XShapeCombineMask(display, win, ShapeBounding, 0, 0, shape_pixmap, ShapeSet);
-
- /* Get available icon sizes from window manager */
- /* (and then blatantly ignore the result) */
- if (XGetIconSizes(display, RootWindow(display,screen_num),
- &size_list, &count) == 0)
- {
- /* Window manager didn't set preferred icon sizes - use the default */
- icon_pixmap = XCreateBitmapFromData(display,win, xteddy_icon_bits,
- xteddy_icon_width, xteddy_icon_height);
- }
- else
- {
- /* Ignore the list and use the default size anyway */
- icon_pixmap = XCreateBitmapFromData(display,win, xteddy_icon_bits,
- xteddy_icon_width, xteddy_icon_height);
- }
- /* Report size hints and other stuff to the window manager */
- size_hints.min_width = width;
- size_hints.min_height = height;
- size_hints.max_width = width;
- size_hints.max_height = height;
- size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
- if (XStringListToTextProperty(&window_name, 1, &windowName) == 0)
- {
- (void) fprintf(stderr,
- "%s: structure allocation for windowName failed.\n",
- progname);
- exit(-1);
- }
- if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0)
- {
- (void) fprintf(stderr,
- "%s: structure allocation for iconName failed.\n",
- progname);
- exit(-1);
- }
- wm_hints.initial_state = NormalState;
- wm_hints.input = True;
- wm_hints.icon_pixmap = icon_pixmap;
- wm_hints.flags = StateHint | IconPixmapHint | InputHint;
-
- class_hints.res_name = progname;
- class_hints.res_class = "Xteddy";
-
- XSetWMProperties(display, win, &windowName, &iconName,
- argv, argc, &size_hints, &wm_hints, &class_hints);
-
- /* Select event types wanted */
- XSelectInput(display, win, ExposureMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask | StructureNotifyMask |
- ButtonMotionMask | PointerMotionHintMask |
- EnterWindowMask | LeaveWindowMask);
-
- /* Display window */
- XMapWindow(display,win);
-
- /* Get and process the events */
- while (1)
- {
- XNextEvent(display, &report);
- switch(report.type)
- {
- case Expose:
- if (report.xexpose.count != 0)
- break;
- else
- {
- /* No drawing needed - the background pixmap */
- /* is handled automatically by the X server */
- }
- break;
- case ConfigureNotify:
- /* Window has been resized */
- width = report.xconfigure.width;
- height = report.xconfigure.height;
- break;
- case EnterNotify:
- /* Grab the keyboard while the pointer is in the window */
- XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
- break;
- case LeaveNotify:
- /* Release the keyboard when the pointer leaves the window */
- XUngrabKeyboard(display, CurrentTime);
- break;
- case ButtonPress:
- /* Raise xteddy above sibling windows */
- XRaiseWindow(display, win);
- /* Remember where the mouse went down */
- XQueryPointer(display, win, &root, &child, &tmp_x, &tmp_y,
- &offs_x, &offs_y, &tmp_mask);
- break;
- case ButtonRelease:
- /* Place xteddy at the new position */
- XQueryPointer(display, win, &root, &child, &new_x, &new_y,
- &tmp_x, &tmp_y, &tmp_mask);
- winchanges.x = new_x - offs_x;
- winchanges.y = new_y - offs_y;
- XReconfigureWMWindow(display, win, screen_num,
- CWX | CWY, &winchanges);
- break;
- case MotionNotify:
- /* Move xteddy around with the mouse */
- while (XCheckMaskEvent(display, ButtonMotionMask, &report));
- if (!XQueryPointer(display, report.xmotion.window, &root, &child,
- &new_x, &new_y, &tmp_x, &tmp_y, &tmp_mask))
- break;
- winchanges.x = new_x - offs_x;
- winchanges.y = new_y - offs_y;
- XReconfigureWMWindow(display, win, screen_num,
- CWX | CWY, &winchanges);
- break;
- case KeyPress:
- /* Exit on "q" or "Q" */
- charcount = XLookupString(&report, buffer, bufsize,
- &keysym, &compose);
- if((keysym == XK_Q) || (keysym == XK_q))
- {
- XCloseDisplay(display);
- exit(1);
- }
- break;
- default:
- /* Throw away all other events */
- break;
- } /* end switch */
- } /* end while */
- }
-