Logo Search packages:      
Sourcecode: nawm version File versions  Download package

icon.c

/* icon.c: old nawm icon command compatibility. */

/* Copyright (C) 1999 by the Massachusetts Institute of Technology.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */

#include "nawmmod.h"

#include <string.h>

#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>

int nawm_modrev = NAWM_MODREV;

typedef struct _icon {
  char *name;
  Window w, iconw;
  int x, y;
  struct _icon *next;
} icon;

static icon *icon_list;
static int numicons;

static void iconify_fun(int argc, nawmval *argv, nawmval *ret);
static void deiconify_cmd(int argc, nawmval *argv);
static void icon_event_handler(XEvent *ev);
static void deiconify(icon *icn);
static void nuke_icon(icon *icn);

static GC icon_gc;
static XFontStruct *icon_font;
static Cursor icon_cursor;
extern Display *dpy;
extern Window root;

void modinit(void)
{
  icon_list = NULL;
  numicons = 0;
  icon_gc = XCreateGC(dpy, root, 0, 0);
  icon_font = XLoadQueryFont(dpy, "fixed");
  XSetFont(dpy, icon_gc, icon_font->fid);
  XSetForeground(dpy, icon_gc, BlackPixel(dpy, 0));
  icon_cursor = XCreateFontCursor(dpy, XC_top_left_arrow);

  module_define_procedure("iconify", T_WIN, iconify_fun, 1, T_WIN);
  module_define_procedure("deiconify", 0, deiconify_cmd, 1, T_WIN);
  module_define_event_handler(icon_event_handler, ExposureMask);
}

static void iconify_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  icon *icn;
  int w;
  Atom type;
  int format;
  unsigned long items, left;
  long hret;
  unsigned char *prop;
  XWindowAttributes attr;
  XSizeHints hints;

  if (win == root)
    {
      XBell(dpy, 100);
      return;
    }
  for (icn = icon_list; icn; icn = icn->next)
    {
      if (icn->w == win)
      {
        XBell(dpy, 100);
        return;
      }
    }

  XGetWindowAttributes(dpy, manager_window(win), &attr);  

  icn = xmalloc(sizeof(icon));
  icn->w = win;
  icn->x = attr.x;
  icn->y = attr.y; 
  if (XGetWindowProperty(dpy, win, XA_WM_NAME, 0, 1000, False, AnyPropertyType,
                   &type, &format, &items, &left, &prop) == Success)
    icn->name = xstrdup((char *)prop);
  else
    icn->name = xstrdup("");

  w = XTextWidth(icon_font, icn->name, strlen(icn->name));  
  w += 20;
  icn->iconw = XCreateSimpleWindow(dpy, root, attr.x, attr.y, w, 20,
                           2, BlackPixel(dpy, 0), WhitePixel(dpy, 0));
  XGrabButton(dpy, 1, 0, icn->iconw, False, ButtonPressMask,
            GrabModeAsync, GrabModeAsync, None, None);
  XSetTransientForHint(dpy, icn->iconw, root);
  XSelectInput(dpy, icn->iconw, ExposureMask | ButtonPressMask |
             SubstructureNotifyMask);
  XDefineCursor(dpy, icn->iconw, icon_cursor);
  XMapWindow(dpy, icn->iconw);

  /* Set USPosition on win so user's wm won't ask to reposition it
   * again when we deiconify it.
   */
  XGetWMNormalHints(dpy, icn->w, &hints, &hret);
  hints.flags |= USPosition;
  XSetWMNormalHints(dpy, icn->w, &hints);
  XUnmapWindow(dpy, icn->w);

  icn->next = icon_list;
  icon_list = icn;

  *ret = (nawmval)icn->iconw;
}

static void icon_event_handler(XEvent *ev)
{
  icon *icn;

  for (icn = icon_list; icn; icn = icn->next)
    {
      if (icn->iconw == ev->xany.window)
      {
        switch(ev->type) {
        case ButtonPress:
          deiconify(icn);
          break;

        case Expose:
          XDrawString(dpy, icn->iconw, icon_gc, 10, 15,
                  icn->name, strlen(icn->name));
          break;

        case DestroyNotify:
          nuke_icon(icn);
          break;
        }
      }
    }
}

static void deiconify_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  icon *icn;

  for (icn = icon_list; icn; icn = icn->next)
    {
      if (icn->iconw == win || icn->w == win)
      {
        deiconify(icn);
        return;
      }
    }
}

static void deiconify(icon *icn)
{
  XMapWindow(dpy, icn->w);
  nuke_icon(icn);
}

static void nuke_icon(icon *icn)
{
  icon *prev = NULL, *i;
  
  XDestroyWindow(dpy, icn->iconw);
  free(icn->name);

  for (i = icon_list; i; i = i->next)
    {
      if (i == icn)
      break;
      prev = i;
    }
  if (!i)
    return;

  if (!prev)
    icon_list = icn->next;
  else
    prev->next = icn->next;

  free(icn);
}


Generated by  Doxygen 1.6.0   Back to index