Logo Search packages:      
Sourcecode: nawm version File versions

builtins.c

/* builtins.c: the built-in commands */

/* 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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "nawm.h"
#include "lang.h"
#include "parser.h"
#include "builtins.h"
#include "cache.h"
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#include <X11/extensions/XTest.h>

/* commands */
function BEEP = { beep_cmd, 0, -1, 0 };
function CUT = { cut_cmd, 0, -1, 1, { T_STR } };
function DELETE = { delete_cmd, 0, -1, 1, { T_WIN } };
function DESTROY = { destroy_cmd, 0, -1, 1, { T_WIN } };
function DSIZE = { dsize_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function DSIZETO = { dsizeto_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function EXEC = { exec_cmd, 0, -1, 1, { T_STR } };
function EXIT = { exit_cmd, 0, -1, 0 };
function FIND = { find_cmd, 0, -1, 1, { T_WIN } };
function FREE = { free_cmd, 0, -1, 0 };
function GRAB = { grab_cmd, 0, -1, 0 };
function LOWER = { lower_cmd, 0, -1, 1, { T_WIN } };
function MAP = { map_cmd, 0, -1, 1, { T_WIN } };
function MOUSECLICK = { mouseclick_cmd, 0, -1, 3, { T_STR, T_INT, T_INT } };
function MOUSEPRESS = { mousepress_cmd, 0, -1, 1, { T_STR } };
function MOUSERELEASE = { mouserelease_cmd, 0, -1, 1, { T_STR } };
function MOVE = { move_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function MOVETO = { moveto_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function PUT = { put_cmd, 0, -1, 1, { T_STR } };
function RAISE = { raise_cmd, 0, -1, 1, { T_WIN } };
function REFRESH = { refresh_cmd, 0, -1, 0 };
function RESTART = { restart_cmd, 0, -1, 0 };
function SETLED = { setled_cmd, 0, -1, 2, { T_INT, T_INT } };
function SETMODE = { setmode_cmd, 0, -1, 1, { T_STR } };
function SETREPEAT = { setrepeat_cmd, 0, -1, 2, { T_STR, T_INT } };
function SIZE = { size_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function SIZETO = { sizeto_cmd, 0, -1, 3, { T_WIN, T_INT, T_INT } };
function SYNC = { sync_cmd, 0, -1, 0 };
function SYSTEM = { system_cmd, 0, -1, 1, { T_STR } };
function TYPE = { type_cmd, 0, -1, 1, { T_STR } };
function TYPEKEY = { typekey_cmd, 0, -1, 1, { T_STR } };
function UNFOCUS = { unfocus_cmd, 0, -1, 0 };
function UNGRAB = { ungrab_cmd, 0, -1, 0 };
function UNMAP = { unmap_cmd, 0, -1, 1, { T_WIN } };
function WARP = { warp_cmd, 0, -1, 2, { T_INT, T_INT } };
function WARPTO = { warpto_cmd, 0, -1, 2, { T_INT, T_INT } };
function WARPTOWINDOW = { warptowindow_cmd, 0, -1, 1, { T_WIN } };

/* functions */
function AT = { at_fun, T_WIN, -1, 2, { T_INT, T_INT } };
function ATOI = { atoi_fun, T_INT, -1, 1, { T_STR } };
function DHEIGHT = { dheight_fun, T_INT, -1, 1, { T_WIN } };
function DWIDTH = { dwidth_fun, T_INT, -1, 1, { T_WIN } };
function ENV = { env_fun, T_STR, -1, 1, { T_STR } };
function FOCUSWINDOW = { focuswindow_fun, T_WIN, -1, 0 };
function GETLED = { getled_fun, T_INT, -1, 1, { T_INT } };
function GETREPEAT = { getrepeat_fun, T_INT, -1, 1, { T_STR } };
function HASNAME = { hasname_fun, T_INT, -1, 2, { T_WIN, T_STR } };
function HEIGHT = { height_fun, T_INT, -1, 1, { T_WIN } };
function ITOA = { itoa_fun, T_STR, -1, 1, { T_INT } };
function MAPPED = { mapped_fun, T_INT, -1, 1, { T_WIN } };
function NAME = { name_fun, T_STR, -1, 1, { T_WIN } };
function PICK = { pick_fun, T_WIN, -1, 0 };
function POINTERWINDOW = { pointerwindow_fun, T_WIN, -1, 0 };
function PX = { px_fun, T_INT, -1, 0 };
function PY = { py_fun, T_INT, -1, 0 };
function STR2WIN = { str2win_fun, T_WIN, -1, 1, { T_STR } };
function WIDTH = { width_fun, T_INT, -1, 1, { T_WIN } };
/* type for WINDOWS will be filled in by initbuiltins */
function WINDOWS = { windows_fun, 0, -1, 0 };
function XLOC = { xloc_fun, T_INT, -1, 1, { T_WIN } };
function YLOC = { yloc_fun, T_INT, -1, 1, { T_WIN } };

/* variables */
variable CURRENTWINDOW = { T_WIN, -1, 0 };
variable ROOT = { T_WIN, -1, 0 };
variable SCREENHEIGHT = { T_INT, -1, 0 };
variable SCREENWIDTH = { T_INT, -1, 0 };

varbinding builtins[] = {
  { "at", FUN, &AT },
  { "atoi", FUN, &ATOI },
  { "beep", CMD, &BEEP },
  { "currentwindow", VAR, &CURRENTWINDOW },
  { "cut", CMD, &CUT },
  { "delete", CMD, &DELETE },
  { "destroy", CMD, &DESTROY },
  { "dheight", FUN, &DHEIGHT },
  { "dsize", CMD, &DSIZE },
  { "dsizeto", CMD, &DSIZETO },
  { "dwidth", FUN, &DWIDTH },
  { "env", FUN, &ENV },
  { "exec", CMD, &EXEC },
  { "exit", CMD, &EXIT },
  { "find", CMD, &FIND },
  { "focuswindow", FUN, &FOCUSWINDOW },
  { "free", CMD, &FREE },
  { "getled", FUN, &GETLED },
  { "getrepeat", FUN, &GETREPEAT },
  { "grab", CMD, &GRAB },
  { "hasname", FUN, &HASNAME },
  { "height", FUN, &HEIGHT },
  { "itoa", FUN, &ITOA },
  { "lower", CMD, &LOWER },
  { "map", CMD, &MAP },
  { "mapped", FUN, &MAPPED },
  { "mouseclick", CMD, &MOUSECLICK },
  { "mousepress", CMD, &MOUSEPRESS },
  { "mouserelease", CMD, &MOUSERELEASE },
  { "move", CMD, &MOVE },
  { "moveto", CMD, &MOVETO },
  { "name", FUN, &NAME },
  { "pick", FUN, &PICK },
  { "pointerwindow", FUN, &POINTERWINDOW },
  { "put", CMD, &PUT },
  { "px", FUN, &PX },
  { "py", FUN, &PY },
  { "raise", CMD, &RAISE },
  { "refresh", CMD, &REFRESH },
  { "restart", CMD, &RESTART },
  { "root", VAR, &ROOT },
  { "screenheight", VAR, &SCREENHEIGHT },
  { "screenwidth", VAR, &SCREENWIDTH },
  { "setled", CMD, &SETLED },
  { "setmode", CMD, &SETMODE },
  { "setrepeat", CMD, &SETREPEAT },
  { "size", CMD, &SIZE },
  { "sizeto", CMD, &SIZETO },
  { "sync", CMD, &SYNC },
  { "system", CMD, &SYSTEM },
  { "type", CMD, &TYPE },
  { "typekey", CMD, &TYPEKEY },
  { "unfocus", CMD, &UNFOCUS },
  { "ungrab", CMD, &UNGRAB },
  { "unmap", CMD, &UNMAP },
  { "warp", CMD, &WARP },
  { "warpto", CMD, &WARPTO },
  { "warptowindow", CMD, &WARPTOWINDOW },
  { "width", FUN, &WIDTH },
  { "win", FUN, &STR2WIN },
  { "windows", FUN, &WINDOWS },
  { "xloc", FUN, &XLOC },
  { "yloc", FUN, &YLOC },
};

int numbuiltins = sizeof(builtins)/sizeof(varbinding);

void *search_builtins(char *name, int *type)
{
  int hi = numbuiltins, lo = 0, mid, cmp;

  while (hi >= lo && lo < numbuiltins)
    {
      mid = (lo + hi) / 2;
      cmp = strcmp(name, builtins[mid].name);

      if (cmp == 0)
      {
        *type = builtins[mid].type;
        return builtins[mid].data;
      }
      else if (cmp < 0)
      {
        if (hi > mid)
          hi = mid;
        else
          hi = mid - 1;
      }
      else
      {
        if (lo < mid)
          lo = mid;
        else
          lo = mid + 1;
      }
    }

  return NULL;
}

char *nameof_builtin(void *data)
{
  int i;

  for (i = 0; i < numbuiltins; i++)
    {
      if (builtins[i].data == data)
      return builtins[i].name;
    }

  return NULL;
}

extern Window root;
extern int screenwidth, screenheight;
extern Display *dpy;
extern int screen;
extern int quit, window_manager;
extern cacheinfo *cachehead;
static Atom XA_WM_DELETE_WINDOW, XA_WM_PROTOCOLS;

void initbuiltins(void)
{
  XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  XA_WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
  WINDOWS.type = array_type(T_WIN, T_INT);
}

enum {SIZE_EXACT, SIZE_DELTA, SIZE_DISCRETE};
#define hcoord(x) ( (x) < 0 ? screenwidth + (x) : (x) )
#define vcoord(y) ( (y) < 0 ? screenheight + (y) : (y) )
void do_size(Window win, int w, int h, int mode);
void getsize(Window win, int *width, int *height, int *dwidth, int *dheight);
void querypointer(Window *pw, int *px, int *py);

void at_fun(int argc, nawmval *argv, nawmval *ret)
{
  cacheinfo ci;

  ci.x = hcoord(argv[0]);
  ci.y = vcoord(argv[1]);

  if (find_window(&ci, NAWM_CACHE_LOCATION))
    *ret = (nawmval)ci.win;
  else
    *ret = 0;
}

void atoi_fun(int argc, nawmval *argv, nawmval *ret)
{
  char *str = (char *)argv[0];

  *ret = atol(str);
}

void beep_cmd(int argc, nawmval *argv)
{
  XBell(dpy, 100);
}

void cut_cmd(int argc, nawmval *argv)
{

}

void delete_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  XClientMessageEvent ev;

  ev.type = ClientMessage;
  ev.window = win;
  ev.message_type = XA_WM_PROTOCOLS;
  ev.format = 32;
  ev.data.l[0] = XA_WM_DELETE_WINDOW;
  ev.data.l[1] = CurrentTime;
  XSendEvent(dpy, win, False, 0L, (XEvent *)&ev);
}

void destroy_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XDestroyWindow(dpy, win);
}

void dheight_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  int dh, dw, h, w;

  getsize(win, &w, &h, &dw, &dh);
  *ret = dh;
}

void dsize_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  int w = argv[1], h = argv[2];

  do_size(win, w, h, SIZE_DELTA | SIZE_DISCRETE);
}

void dsizeto_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  int w = argv[1], h = argv[2];

  do_size(win, w, h, SIZE_DISCRETE);
}

void dwidth_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  int dh, dw, h, w;

  getsize(win, &w, &h, &dw, &dh);
  *ret = dw;
}

void env_fun(int argc, nawmval *argv, nawmval *ret)
{
  char **val = (char **)ret;
  char *data;

  data = getenv((char *)argv[0]);
  if (!data)
    *val = gcstrdup("");
  else
    *val = gcstrdup(data);
}

void exec_cmd(int argc, nawmval *argv)
{

}

void exit_cmd(int argc, nawmval *argv)
{
  quit = 1;
}

void find_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  assign_var(&CURRENTWINDOW, (nawmval)win);
}

void focuswindow_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window *fw = (Window *)ret;
  int revert;

  XGetInputFocus(dpy, fw, &revert);
}

void free_cmd(int argc, nawmval *argv)
{
  XSetInputFocus(dpy, PointerRoot, None, CurrentTime);
}

void getled_fun(int argc, nawmval *argv, nawmval *ret)
{
  int led = argv[0];
  XKeyboardState state;

  XGetKeyboardControl(dpy, &state);
  *ret = (state.led_mask & (1 << (led - 1))) ? 1 : 0;
}

void getrepeat_fun(int argc, nawmval *argv, nawmval *ret)
{
  char *keyname = (char *)argv[0];
  KeyCode kc;
  XKeyboardState state;

  kc = parse_key(keyname);
  XGetKeyboardControl(dpy, &state);
  *ret = KEYSTATE(state.auto_repeats, kc) ? 1 : 0;
}

void grab_cmd(int argc, nawmval *argv)
{
  XGrabServer(dpy);
}

void hasname_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  char *name = (char *)argv[1];

  *ret = hasname(win, name);
}

void height_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  int dw, dh, w, h;

  getsize(win, &w, &h, &dw, &dh);
  *ret = h;
}

void itoa_fun(int argc, nawmval *argv, nawmval *ret)
{
  long num = argv[0];
  char **str = (char **)ret;
  char buf[32];

  sprintf(buf, "%ld", num);
  *str = gcstrdup(buf);
}

void lower_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XLowerWindow(dpy, win);
}

void map_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XMapWindow(dpy, win);
}

void mapped_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  cacheinfo ci;

  ci.win = win;
  if (find_window(&ci, NAWM_CACHE_WINDOW | NAWM_CACHE_MAPPED))
    *ret = 1;
  else
    *ret = 0;
}

void mouseclick_cmd(int argc, nawmval *argv)
{
  char *but = (char *)argv[0];
  int x = (int)argv[1], y = (int)argv[2];
  Window rr, pr;
  int oldx, oldy, rx, ry, mods, button;
  unsigned int k;
  void *state;

  mods = parse_mods(&but);
  button = parse_button(but);

  XQueryPointer(dpy, root, &rr, &pr, &rx, &ry, &oldx, &oldy, &k);
  XTestFakeMotionEvent(dpy, screen, hcoord(x), vcoord(y), CurrentTime);
  state = set_modifier_state(mods);
  XTestFakeButtonEvent(dpy, button, True, CurrentTime);
  sleep(1);
  XTestFakeButtonEvent(dpy, button, False, CurrentTime);
  reset_modifier_state(state);
  XTestFakeMotionEvent(dpy, screen, oldx, oldy, CurrentTime);
}

void mousepress_cmd(int argc, nawmval *argv)
{
  char *but = (char *)argv[0];
  int mods, button;
  void *state;

  mods = parse_mods(&but);
  button = parse_button(but);

  state = set_modifier_state(mods);
  XTestFakeButtonEvent(dpy, button, True, CurrentTime);
  reset_modifier_state(state);
}

void mouserelease_cmd(int argc, nawmval *argv)
{
  char *but = (char *)argv[0];
  int mods, button;
  void *state;

  mods = parse_mods(&but);
  button = parse_button(but);

  state = set_modifier_state(mods);
  XTestFakeButtonEvent(dpy, button, False, CurrentTime);
  reset_modifier_state(state);
}

void move_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  XWindowAttributes attr;

  XGetWindowAttributes(dpy, manager_window(win), &attr);
  argv[1] += attr.x;
  argv[2] += attr.y;
  moveto_cmd(argc, argv);
}

void moveto_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  int x = argv[1], y = argv[2];

  XWindowAttributes attr;

  if (window_manager == NAWM_WM_VTWM_GAMMA)
    {
      XWindowChanges xwc;

      XGetWindowAttributes(dpy, win, &attr);
      xwc.width = attr.width;
      xwc.height = attr.height;
      win = manager_window(win);
      XGetWindowAttributes(dpy, win, &attr);
      xwc.x = x;
      xwc.y = y;
      XConfigureWindow(dpy, win, CWX | CWY | CWWidth | CWHeight |
                   CWBorderWidth, &xwc);
    }
  else
    {
      win = manager_window(win);
      XGetWindowAttributes(dpy, win, &attr);
      XMoveWindow(dpy, win, attr.border_width + x, attr.border_width + y);
    }
}

void name_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  char **name = (char **)ret;
  unsigned long items, left;
  Atom type;
  int format;
  Window cwin = client_window(win);
  unsigned char *nm;

  if (XGetWindowProperty(dpy, cwin, XA_WM_NAME, 0, 1000, False,
                   AnyPropertyType, &type, &format, &items, &left,
                   &nm) != 0)
    *name = gcstrdup("");
  else
    {
      *name = gcstrdup((char *)nm);
      XFree(nm);
    }
}

void pick_fun(int argc, nawmval *argv, nawmval *ret)
{
  Cursor cursor;
  int status, buttons = 0;
  XEvent event;
  Window *w = (Window *)ret;

  *w = None;
  cursor = XCreateFontCursor(dpy, XC_crosshair);
  status = XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask,
                  GrabModeSync, GrabModeAsync, root, cursor,
                  CurrentTime);
  if (status != GrabSuccess)
    {
      XBell(dpy, 100);
      return;
    }

  while (*w == None || buttons)
    {
      XAllowEvents(dpy, SyncPointer, CurrentTime);
      XWindowEvent(dpy, root, ButtonPressMask | ButtonReleaseMask, &event);
      switch (event.type)
      {
      case ButtonPress:
        if (*w == None)
          {
            if (event.xbutton.subwindow != None)
            *w = event.xbutton.subwindow;
            else
            *w = root;
          }
        buttons++;
        break;

      case ButtonRelease:
        if (buttons)
          buttons--;
        break;
      }
    }
  assign_var(&CURRENTWINDOW, (nawmval)*w);
}

void pointerwindow_fun(int argc, nawmval *argv, nawmval *ret)
{
  int px, py;
  Window *pw = (Window *)ret;

  querypointer(pw, &px, &py);
  if (*pw)
    *pw = client_window(*pw);
}

void px_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window pw;
  int py, px;

  querypointer(&pw, &px, &py);
  *ret = px;
}

void py_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window pw;
  int px, py;

  querypointer(&pw, &px, &py);
  *ret = py;
}

void querypointer(Window *pw, int *px, int *py)
{
  Window rr;
  int x, y;
  unsigned int k;

  XQueryPointer(dpy, root, &rr, pw, px, py, &x, &y, &k);
}

void put_cmd(int argc, nawmval *argv)
{
  puts((char *)argv[0]);
}

void raise_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XRaiseWindow(dpy, win);
}

void refresh_cmd(int argc, nawmval *argv)
{
  XSetWindowAttributes attributes;
  unsigned long valuemask;
  Window w;

  valuemask = CWBackPixel | CWBackingStore | CWSaveUnder | CWOverrideRedirect;
  attributes.background_pixel = BlackPixel(dpy, screen);
  attributes.backing_store = NotUseful;
  attributes.save_under = False;
  attributes.override_redirect = True;
  w = XCreateWindow(dpy, root, 0, 0, screenwidth, screenheight, 0,
                 CopyFromParent, CopyFromParent,
                 (Visual *) CopyFromParent, valuemask,
                 &attributes);
  XMapWindow(dpy, w);
  XDestroyWindow(dpy, w);
  XFlush(dpy);
}

void restart_cmd(int argc, nawmval *argv)
{
  extern char **Argv;

  XSync(dpy, 0);
  execvp(Argv[0], Argv);
}

void setled_cmd(int argc, nawmval *argv)
{
  int led = argv[0], val = argv[1];
  XKeyboardControl ctl;

  ctl.led = led;
  ctl.led_mode = val ? LedModeOn : LedModeOff;
  XChangeKeyboardControl(dpy, KBLed | KBLedMode, &ctl);
}

void setmode_cmd(int argc, nawmval *argv)
{
  set_mode((char *)argv[0]);
}

void setrepeat_cmd(int argc, nawmval *argv)
{
  char *keyname = (char *)argv[0];
  int state = argv[1];
  KeyCode kc;
  XKeyboardControl ctl;

  kc = parse_key(keyname);

  ctl.key = kc;
  ctl.auto_repeat_mode = state ? AutoRepeatModeOn : AutoRepeatModeOff;
  XChangeKeyboardControl(dpy, KBKey | KBAutoRepeatMode, &ctl);
}

void size_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  int w = argv[1], h = argv[2];

  do_size(win, w, h, SIZE_DELTA);
}

void sizeto_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];
  int w = argv[1], h = argv[2];

  do_size(win, w, h, SIZE_EXACT);
}

void str2win_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window *ans = (Window *)ret;
  cacheinfo ci;

  ci.names[0] = (char *)argv[0];
  if (find_window(&ci, NAWM_CACHE_NAME | NAWM_CACHE_MAPPED))
    *ret = (nawmval)ci.win;
  else if (find_window(&ci, NAWM_CACHE_NAME))
    *ret = (nawmval)ci.win;
  else
    *ret = 0;
}

void sync_cmd(int argc, nawmval *argv)
{
  XSync(dpy, False);
}

void system_cmd(int argc, nawmval *argv)
{
  char *str = (char *)argv[0];
  char *exec_argv[4] = { "sh", "-c", NULL, NULL };

  exec_argv[2] = str;
  switch (fork())
    {
    case 0:
      execvp("/bin/sh", exec_argv);
      _exit(1);

    case -1:
      XBell(dpy, 100);
      break;
    }
}

void type_cmd(int argc, nawmval *argv)
{
  char *str = (char *)argv[0];
  void *state;

  state = set_modifier_state(0);
  for (; *str; str++)
    typechar(*str);
  reset_modifier_state(state);
}

void typekey_cmd(int argc, nawmval *argv)
{
  char *keyname = (char *)argv[0];
  int mods;
  KeyCode kc;
  void *state;

  mods = parse_mods(&keyname);
  kc = parse_key(keyname);

  state = set_modifier_state(mods);
  XTestFakeKeyEvent(dpy, kc, True, CurrentTime);
  XTestFakeKeyEvent(dpy, kc, False, CurrentTime);
  reset_modifier_state(state);
}

void unfocus_cmd(int argc, nawmval *argv)
{
  XSetInputFocus(dpy, PointerRoot, None, CurrentTime);
}

void ungrab_cmd(int argc, nawmval *argv)
{
  XUngrabServer(dpy);
}

void unmap_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XUnmapWindow(dpy, win);
}

void warp_cmd(int argc, nawmval *argv)
{
  int x = argv[0], y = argv[1];

  XWarpPointer(dpy, None, None, 0, 0, 0, 0, x, y);
}

void warpto_cmd(int argc, nawmval *argv)
{
  int x = argv[0], y = argv[1];

  XWarpPointer(dpy, None, root, 0, 0, 0, 0, hcoord(x), vcoord(y));
}

void warptowindow_cmd(int argc, nawmval *argv)
{
  Window win = (Window)argv[0];

  XWindowAttributes attr;

  if (!XGetWindowAttributes(dpy, win, &attr))
    return;
  XWarpPointer(dpy, None, win, 0, 0, 0, 0, attr.width / 2, attr.height / 2);
  assign_var(&CURRENTWINDOW, (nawmval)win);
}

void width_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  int dw, dh, w, h;

  getsize(win, &w, &h, &dw, &dh);
  *ret = w;
}

void windows_fun(int argc, nawmval *argv, nawmval *ret)
{
  cacheinfo *ci;
  array *ans;
  int n;

  ans = create_array(array_type(T_WIN, T_INT), 10);
  for (n = 0, ci = cachehead; ci; ci = ci->next)
    array_insert(ans, n++, ci->win);

  *ret = (nawmval)ans;
}

void xloc_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  XWindowAttributes attr;

  if (!XGetWindowAttributes(dpy, win, &attr))
    *ret = 0;
  else
    *ret = attr.x;
}

void yloc_fun(int argc, nawmval *argv, nawmval *ret)
{
  Window win = (Window)argv[0];
  XWindowAttributes attr;

  if (!XGetWindowAttributes(dpy, win, &attr))
    *ret = 0;
  else
    *ret = attr.y;
}


void do_size(Window win, int w, int h, int mode)
{
  XWindowAttributes attr;
  XSizeHints hints;
  long data;

  XGetWMNormalHints(dpy, win, &hints, &data);
  XGetWindowAttributes(dpy, win, &attr);

  if ((mode & SIZE_DISCRETE) && (hints.flags & PResizeInc))
    {
      w *= hints.width_inc;
      h *= hints.height_inc;
    }

  /* If we're doing a relative resize, add in the current height and width */
  if (mode & SIZE_DELTA)
    {
      w += attr.width;
      h += attr.height;
    }
  /* Otherwise, add in the base size */
  else if (hints.flags & PBaseSize)
    {
      w += hints.base_width;
      h += hints.base_height;
    }
#if 0
  /* If base size isn't specified, it defaults to equal the min size */
  else if (hints.flags & PMinSize)
    {
      w += hints.min_width;
      h += hints.min_height;
    }
#endif

  /* check limits */
  if ((((w < hints.min_width) || (h < hints.min_height)) &&
       hints.flags & PMinSize) ||
      (((w > hints.max_width) ||  (h > hints.max_height)) &&
       hints.flags & PMaxSize))
    return;

  XResizeWindow(dpy, win, w, h);
}

void getsize(Window win, int *width, int *height, int *dwidth, int *dheight)
{
  XWindowAttributes attr;
  XSizeHints hints;
  long data;

  if (!XGetWindowAttributes(dpy, win, &attr))
    {
      *width = *height = *dwidth = *dheight = 0;
      return;
    }
  *width = *dwidth = attr.width;
  *height = *dheight = attr.height;

  if (!XGetWMNormalHints(dpy, win, &hints, &data))
    return;

  if (hints.flags & PBaseSize)
    {
      *width = *dwidth = attr.width - hints.base_width;
      *height = *dheight = attr.height - hints.base_height;
    }
  else if (hints.flags & PMinSize)
    {
      *width = *dwidth = attr.width - hints.min_width;
      *height = *dheight = attr.height - hints.min_height;
    }

  if (hints.flags & PResizeInc)
    {
      *dwidth /= hints.width_inc;
      *dheight /= hints.height_inc;
    }
}

Generated by  Doxygen 1.6.0   Back to index