Ejemplo n.º 1
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingAskRunning(VALUE self)
{
  char *prop = NULL;
  Window *support = NULL;
  VALUE running = Qfalse;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Get supporting window */
  if((support = (Window *)subSharedPropertyGet(display,
      DefaultRootWindow(display), XA_WINDOW, XInternAtom(display,
      "_NET_SUPPORTING_WM_CHECK", False), NULL)))
    {
      subSharedLogDebugSubtlext("Support: win=%#lx\n", *support);

      /* Get property */
      if((prop = subSharedPropertyGet(display, *support, XInternAtom(display,
          "UTF8_STRING", False), XInternAtom(display, "_NET_WM_NAME", False),
          NULL)))
        {
          if(!strncmp(prop, PKG_NAME, strlen(prop))) running = Qtrue;
          subSharedLogDebugSubtlext("Running: wmname=%s\n", prop);

          free(prop);
        }

      free(support);
    }

  return running;
} /* }}} */
Ejemplo n.º 2
0
/* ViewFind {{{ */
static VALUE
ViewFind(VALUE value,
  int first)
{
  int flags = 0;
  VALUE parsed = Qnil;
  char buf[50] = { 0 };

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Check object type */
  switch(rb_type(parsed = subSubtlextParse(
      value, buf, sizeof(buf), &flags)))
    {
      case T_SYMBOL:
        if(CHAR2SYM("visible") == parsed)
          return subViewSingVisible(Qnil);
        else if(CHAR2SYM("all") == parsed)
          return subViewSingList(Qnil);
        else if(CHAR2SYM("current") == parsed)
          return subViewSingCurrent(Qnil);
        break;
      case T_OBJECT:
        if(rb_obj_is_instance_of(value, rb_const_get(mod, rb_intern("View"))))
          return parsed;
    }

  return subSubtlextFindObjects("_NET_DESKTOP_NAMES", "View",
    buf, flags, first);
} /* }}} */
Ejemplo n.º 3
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingDisplayReader(VALUE self)
{
  subSubtlextConnect(NULL); ///< Implicit open connection

  return rb_str_new2(DisplayString(display));
} /* }}} */
Ejemplo n.º 4
0
VALUE
subViewIcon(VALUE self)
{
  unsigned long nicons = 0;
  VALUE id = Qnil, ret = Qnil;
  unsigned long *icons = NULL;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Check results */
  if((icons = (unsigned long *)subSharedPropertyGet(display,
      DefaultRootWindow(display), XA_CARDINAL,
      XInternAtom(display, "SUBTLE_VIEW_ICONS", False), &nicons)))
    {
      int iid = FIX2INT(id);

      /* Check if id is in range and icon available */
      if(0 <= iid && iid < nicons && -1 != icons[iid])
        {
          /* Create new icon */
          ret = rb_funcall(rb_const_get(mod, rb_intern("Icon")),
            rb_intern("new"), 1, LONG2NUM(icons[iid]));
        }

      free(icons);
    }

  return ret;
} /* }}} */
Ejemplo n.º 5
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingSpawn(VALUE self,
  VALUE cmd)
{
  VALUE ret = Qnil;

  /* Check object type */
  if(T_STRING == rb_type(cmd))
    {
      pid_t pid = 0;

      subSubtlextConnect(NULL); ///< Implicit open connection

      /* Create client with empty window id since we cannot
       * know the real window id at this point (race) */
      if(0 < (pid = subSharedSpawn(RSTRING_PTR(cmd))))
        {
          ret = subClientInstantiate((int)pid);
          rb_iv_set(ret, "@pid", INT2FIX((int)pid));
        }
    }
  else rb_raise(rb_eArgError, "Unexpected value-type `%s'",
    rb_obj_classname(cmd));

  return ret;
} /* }}} */
Ejemplo n.º 6
0
VALUE
subViewUpdate(VALUE self)
{
  long *tags = NULL, ntags = 0;
  VALUE id = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch tags */
  if((tags = (long *)subSharedPropertyGet(display, ROOT, XA_CARDINAL,
      XInternAtom(display, "SUBTLE_VIEW_TAGS", False), (unsigned long *)&ntags)))
    {
      int idx = FIX2INT(id);

      rb_iv_set(self, "@tags", LONG2NUM(idx < ntags ? tags[idx] : 0));

      free(tags);
    }

  return self;
} /* }}} */
Ejemplo n.º 7
0
VALUE
subViewSingCurrent(VALUE self)
{
  int nnames = 0;
  char **names = NULL;
  unsigned long *cur_view = NULL;
  VALUE view = Qnil;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  names    = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
    XInternAtom(display, "_NET_DESKTOP_NAMES", False), &nnames);
  cur_view = (unsigned long *)subSharedPropertyGet(display,
    DefaultRootWindow(display), XA_CARDINAL,
    XInternAtom(display, "_NET_CURRENT_DESKTOP", False), NULL);

  /* Check results */
  if(names && cur_view)
    {
      /* Create instance */
      view = subViewInstantiate(names[*cur_view]);
      rb_iv_set(view, "@id",  INT2FIX(*cur_view));
    }

  if(names)    XFreeStringList(names);
  if(cur_view) free(cur_view);

  return view;
} /* }}} */
Ejemplo n.º 8
0
Archivo: sublet.c Proyecto: guns/subtle
VALUE
subSubletSingAll(VALUE self)
{
  int i, nsublets = 0;
  char **sublets = NULL;
  VALUE meth = Qnil, klass = Qnil, array = Qnil;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  meth   = rb_intern("new");
  klass  = rb_const_get(mod, rb_intern("Sublet"));
  array  = rb_ary_new();

  /* Check results */
  if((sublets = subSharedPropertyGetStrings(display,
      DefaultRootWindow(display), XInternAtom(display, "SUBTLE_SUBLET_LIST",
      False), &nsublets)))
    {
      for(i = 0; i < nsublets; i++)
        {
          VALUE s = rb_funcall(klass, meth, 1, rb_str_new2(sublets[i]));

          rb_iv_set(s, "@id", INT2FIX(i));
          rb_ary_push(array, s);
        }

      XFreeStringList(sublets);
    }

  return array;
} /* }}} */
Ejemplo n.º 9
0
Archivo: sublet.c Proyecto: guns/subtle
VALUE
subSubletSingFind(VALUE self,
  VALUE value)
{
  int flags = 0;
  VALUE parsed = Qnil;
  char buf[50] = { 0 };

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Check object type */
  switch(rb_type(parsed = subSubtlextParse(
      value, buf, sizeof(buf), &flags)))
    {
      case T_SYMBOL:
        if(CHAR2SYM("all") == parsed)
          return subSubletSingAll(Qnil);
        break;
      case T_OBJECT:
        if(rb_obj_is_instance_of(value, rb_const_get(mod, rb_intern("Sublet"))))
          return parsed;
    }

  return subSubtlextFindObjects("SUBTLE_SUBLET_LIST", "Sublet", buf, flags);
} /* }}} */
Ejemplo n.º 10
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingDisplayWriter(VALUE self,
  VALUE display_string)
{
  /* Explicit open connection */
  subSubtlextConnect(T_STRING == rb_type(display_string) ?
    RSTRING_PTR(display_string) : NULL);

  return Qnil;
} /* }}} */
Ejemplo n.º 11
0
Archivo: subtle.c Proyecto: guns/subtle
/* SubtleSend {{{ */
static VALUE
SubtleSend(char *message)
{
  SubMessageData data = { { 0, 0, 0, 0, 0 } };

  subSubtlextConnect(NULL); ///< Implicit open connection

  subSharedMessage(display, DefaultRootWindow(display),
    message, data, 32, True);

  return Qnil;
} /* }}} */
Ejemplo n.º 12
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingColors(VALUE self)
{
  int i;
  unsigned long ncolors = 0, *colors = NULL;
  VALUE meth = Qnil, klass = Qnil, hash = Qnil;
  const char *names[] = {
    "title_fg",            "title_bg",             "title_bo_top",
    "title_bo_right",      "title_bo_bottom",      "title_bo_left",
    "view_fg",             "view_bg",              "view_bo_top",
    "view_bo_right",       "view_bo_bottom",       "view_bo_left",
    "focus_fg",            "focus_bg",             "focus_bo_top",
    "focus_bo_right",      "focus_bo_bottom",      "focus_bo_left",
    "urgent_fg",           "urgent_bg",            "urgent_bo_top",
    "urgent_bo_right",     "urgent_bo_bottom",     "urgent_bo_left",
    "occupied_fg",         "occupied_bg",          "occupied_bo_top",
    "occupied_bo_right",   "occupied_bo_bottom",   "occupied_bo_left",
    "unoccupied_fg",       "unoccupied_bg",        "unoccupied_bo_top",
    "unoccupied_bo_right", "unoccupied_bo_bottom", "unoccupied_bo_left",
    "sublets_fg",         "sublets_bg",            "sublets_bo_top",
    "sublets_bo_right",   "sublets_bo_bottom",     "sublets_bo_left",
    "separator_fg",       "separator_bg",          "separator_bo_top",
    "separator_bo_right", "separator_bo_bottom",   "separator_bo_left",
    "client_active",      "client_inactive",
    "panel_top",          "panel_bottom",
    "stipple",            "background"
  };

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  meth  = rb_intern("new");
  klass = rb_const_get(mod, rb_intern("Color"));
  hash  = rb_hash_new();

  /* Check result */
  if((colors = (unsigned long *)subSharedPropertyGet(display,
      DefaultRootWindow(display), XA_CARDINAL,
      XInternAtom(display, "SUBTLE_COLORS", False), &ncolors)))
    {
      for(i = 0; i < ncolors && i < LENGTH(names); i++)
        {
          VALUE c = rb_funcall(klass, meth, 1, LONG2NUM(colors[i]));

          rb_hash_aset(hash, CHAR2SYM(names[i]), c);
        }

      free(colors);
    }

  return hash;
} /* }}} */
Ejemplo n.º 13
0
VALUE
subGravityClients(VALUE self)
{
  int i, nclients = 0;
  Window *clients = NULL;
  VALUE id = Qnil, klass = Qnil, meth = Qnil, array = Qnil, c = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  klass   = rb_const_get(mod, rb_intern("Client"));
  meth    = rb_intern("new");
  array   = rb_ary_new();
  clients = subSubtlextWindowList("_NET_CLIENT_LIST", &nclients);

  /* Check results */
  if(clients)
    {
      for(i = 0; i < nclients; i++)
        {
          unsigned long *gravity = NULL;

          /* Get window gravity */
          gravity = (unsigned long *)subSharedPropertyGet(display,
            clients[i], XA_CARDINAL, XInternAtom(display,
            "SUBTLE_CLIENT_GRAVITY", False), NULL);

          /* Check if there are common tags or window is stick */
          if(gravity && FIX2INT(id) == *gravity &&
              !NIL_P(c = rb_funcall(klass, meth, 1, INT2FIX(i))))
            {
              rb_iv_set(c, "@win", LONG2NUM(clients[i]));

              subClientUpdate(c);

              rb_ary_push(array, c);
            }

          if(gravity) free(gravity);
        }

      free(clients);
    }

  return array;
} /* }}} */
Ejemplo n.º 14
0
Archivo: sublet.c Proyecto: guns/subtle
VALUE
subSubletInit(VALUE self,
  VALUE name)
{
  if(T_STRING != rb_type(name))
    rb_raise(rb_eArgError, "Unexpected value-type `%s'",
      rb_obj_classname(name));

  /* Init object */
  rb_iv_set(self, "@id",   Qnil);
  rb_iv_set(self, "@name", name);

  subSubtlextConnect(NULL); ///< Implicit open connection

  return self;
} /* }}} */
Ejemplo n.º 15
0
VALUE
subViewSave(VALUE self)
{
  int id = -1;
  VALUE name = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@name", name);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Create view if needed */
  if(-1 == (id = subSubtlextFindString("_NET_DESKTOP_NAMES",
      RSTRING_PTR(name), NULL, SUB_MATCH_EXACT)))
    {
      SubMessageData data = { { 0, 0, 0, 0, 0 } };

      snprintf(data.b, sizeof(data.b), "%s", RSTRING_PTR(name));
      subSharedMessage(display, DefaultRootWindow(display),
        "SUBTLE_VIEW_NEW", data, 8, True);

      id = subSubtlextFindString("_NET_DESKTOP_NAMES",
        RSTRING_PTR(name), NULL, SUB_MATCH_EXACT);
    }

  /* Guess view id */
  if(-1 == id)
    {
      int nnames = 0;
      char **names = NULL;

      /* Get names of views */
      if((names = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
          XInternAtom(display, "_NET_DESKTOP_NAMES", False), &nnames)))
        {
          id = nnames; ///< New id should be last

          if(names) XFreeStringList(names);
        }
    }

  /* Set properties */
  rb_iv_set(self, "@id", INT2FIX(id));

  return self;
} /* }}} */
Ejemplo n.º 16
0
VALUE
subViewSingVisible(VALUE self)
{
  int i, nnames = 0, *tags = NULL;
  char **names = NULL;
  unsigned long *visible = NULL;
  VALUE meth = Qnil, klass = Qnil, array = Qnil, v = Qnil;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  meth  = rb_intern("new");
  klass = rb_const_get(mod, rb_intern("View"));
  array = rb_ary_new();
  names = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
    XInternAtom(display, "_NET_DESKTOP_NAMES", False), &nnames);
  visible = (unsigned long *)subSharedPropertyGet(display,
    DefaultRootWindow(display), XA_CARDINAL, XInternAtom(display,
    "SUBTLE_VISIBLE_VIEWS", False), NULL);
  tags  = (int *)subSharedPropertyGet(display, ROOT, XA_CARDINAL,
      XInternAtom(display, "SUBTLE_VIEW_TAGS", False), NULL);

  /* Check results */
  if(names && visible && tags)
    {
      for(i = 0; i < nnames; i++)
        {
          /* Create view on match */
          if(*visible & (1L << (i + 1)) &&
              !NIL_P(v = rb_funcall(klass, meth, 1, rb_str_new2(names[i]))))
            {
              rb_iv_set(v, "@id",   INT2FIX(i));
              rb_iv_set(v, "@tags", INT2FIX(tags[i]));

              rb_ary_push(array, v);
            }
        }
    }

  if(names)   XFreeStringList(names);
  if(visible) free(visible);
  if(tags)    free(tags);

  return array;
} /* }}} */
Ejemplo n.º 17
0
VALUE
subViewJump(VALUE self)
{
  VALUE id = Qnil;
  SubMessageData data = { { 0, 0, 0, 0, 0 } };

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Send message */
  data.l[0] = FIX2INT(id);
  data.l[2] = -1;

  subSharedMessage(display, DefaultRootWindow(display),
    "_NET_CURRENT_DESKTOP", data, 32, True);

  return self;
} /* }}} */
Ejemplo n.º 18
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingFont(VALUE self)
{
  char *prop = NULL;
  VALUE font = Qnil;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Get results */
  if((prop = subSharedPropertyGet(display, DefaultRootWindow(display),
      XInternAtom(display, "UTF8_STRING", False),
      XInternAtom(display, "SUBTLE_FONT", False),
      NULL)))
    {
      font = rb_str_new2(prop);

      free(prop);
    }

  return font;
} /* }}} */
Ejemplo n.º 19
0
VALUE
subGravityInit(int argc,
  VALUE *argv,
  VALUE self)
{
  VALUE data[2] = { Qnil };

  rb_scan_args(argc, argv, "02", &data[0], &data[1]);

  if(T_STRING != rb_type(data[0]))
    rb_raise(rb_eArgError, "Invalid value type");

  /* Init object */
  rb_iv_set(self, "@id",       Qnil);
  rb_iv_set(self, "@name",     data[0]);
  rb_iv_set(self, "@geometry", data[1]);

  subSubtlextConnect(NULL); ///< Implicit open connection

  return self;
} /* }}} */
Ejemplo n.º 20
0
/* ViewSelect {{{ */
static VALUE
ViewSelect(VALUE self,
  int dir)
{
  int nnames = 0;
  char **names = NULL;
  VALUE id = Qnil, ret = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  if((names = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
    XInternAtom(display, "_NET_DESKTOP_NAMES", False), &nnames)))
    {
      int vid = FIX2INT(id);

      /* Select view */
      if(SUB_VIEW_NEXT == dir && vid < (nnames - 1))
        {
          vid++;
        }
      else if(SUB_VIEW_PREV == dir && 0 < vid)
        {
          vid--;
        }

      /* Create view */
      ret = subViewInstantiate(names[vid]);
      subViewUpdate(ret);

      XFreeStringList(names);
    }

  return ret;
} /* }}} */
Ejemplo n.º 21
0
VALUE
subViewKill(VALUE self)
{
  VALUE id = Qnil;
  SubMessageData data = { { 0, 0, 0, 0, 0 } };

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Send message */
  data.l[0] = FIX2INT(id);

  subSharedMessage(display, DefaultRootWindow(display),
    "SUBTLE_VIEW_KILL", data, 32, True);

  rb_obj_freeze(self); ///< Freeze object

  return Qnil;
} /* }}} */
Ejemplo n.º 22
0
VALUE
subColorInit(int argc,
  VALUE *argv,
  VALUE self)
{
  VALUE data[3] = { Qnil };
  XColor xcolor = { 0 };

  rb_scan_args(argc, argv, "12", &data[0], &data[1], &data[2]);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Get color values */
  subColorPixel(data[0], data[1], data[2], &xcolor);

  /* Set values */
  rb_iv_set(self, "@red",   INT2FIX(xcolor.red));
  rb_iv_set(self, "@green", INT2FIX(xcolor.green));
  rb_iv_set(self, "@blue",  INT2FIX(xcolor.blue));
  rb_iv_set(self, "@pixel", LONG2NUM(xcolor.pixel));

  return self;
} /* }}} */
Ejemplo n.º 23
0
VALUE
subViewClients(VALUE self)
{
  int i, nclients = 0;
  Window *clients = NULL;
  VALUE id = Qnil, klass = Qnil, meth = Qnil, array = Qnil, client = Qnil;
  unsigned long *view_tags = NULL;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@id", id);

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Fetch data */
  klass     = rb_const_get(mod, rb_intern("Client"));
  meth      = rb_intern("new");
  array     = rb_ary_new();
  clients   = subSubtlextWindowList("_NET_CLIENT_LIST", &nclients);
  view_tags = (unsigned long *)subSharedPropertyGet(display,
    DefaultRootWindow(display), XA_CARDINAL,
    XInternAtom(display, "SUBTLE_VIEW_TAGS", False), NULL);

  /* Check results */
  if(clients && view_tags)
    {
      for(i = 0; i < nclients; i++)
        {
          unsigned long *client_tags = NULL, *flags = NULL;

          /* Fetch window data */
          client_tags = (unsigned long *)subSharedPropertyGet(display,
            clients[i], XA_CARDINAL,
            XInternAtom(display, "SUBTLE_CLIENT_TAGS", False), NULL);
          flags       = (unsigned long *)subSharedPropertyGet(display,
            clients[i], XA_CARDINAL,
            XInternAtom(display, "SUBTLE_CLIENT_FLAGS", False), NULL);

          /* Check if there are common tags or window is stick */
          if((client_tags && view_tags[FIX2INT(id)] & *client_tags) ||
              (flags && *flags & SUB_EWMH_STICK))
            {
              if(RTEST(client = rb_funcall(klass, meth,
                  1, LONG2NUM(clients[i]))))
                {
                  subClientUpdate(client);

                  rb_ary_push(array, client);
                }
            }

          if(client_tags) free(client_tags);
          if(flags)       free(flags);
        }
    }

  if(clients)   free(clients);
  if(view_tags) free(view_tags);

  return array;
} /* }}} */
Ejemplo n.º 24
0
Archivo: subtle.c Proyecto: guns/subtle
VALUE
subSubtleSingSelect(VALUE self)
{
  int i, format = 0, buttons = 0;
  unsigned int nwins = 0;
  unsigned long nitems = 0, bytes = 0;
  unsigned char *data = NULL;
  XEvent event;
  Window win = None;
  Atom type = None, rtype = None;
  Window wroot = None, parent = None, root = None, *wins = NULL;
  Cursor cursor = None;

  subSubtlextConnect(NULL); ///< Implicit open connection

  root   = DefaultRootWindow(display);
  cursor = XCreateFontCursor(display, XC_cross);
  type   = XInternAtom(display, "WM_STATE", True);

  /* Grab pointer */
  if(XGrabPointer(display, root, False, ButtonPressMask|ButtonReleaseMask,
      GrabModeSync, GrabModeAsync, root, cursor, CurrentTime))
    {
      XFreeCursor(display, cursor);

      return Qnil;
    }

  /* Select a window */
  while(None == win || 0 != buttons)
    {
      XAllowEvents(display, SyncPointer, CurrentTime);
      XWindowEvent(display, root, ButtonPressMask|ButtonReleaseMask, &event);

      switch(event.type)
        {
          case ButtonPress:
            if(None == win)
              win = event.xbutton.subwindow ? event.xbutton.subwindow : root; ///< Sanitize
            buttons++;
            break;
          case ButtonRelease:
            if(0 < buttons) buttons--;
            break;
        }
      }

  /* Find children with WM_STATE atom */
  XQueryTree(display, win, &wroot, &parent, &wins, &nwins);

  for(i = 0; i < nwins; i++)
    {
      if(Success == XGetWindowProperty(display, wins[i], type, 0, 0, False,
          AnyPropertyType, &rtype, &format, &nitems, &bytes, &data))
        {
          if(data)
            {
              XFree(data);
              data = NULL;
            }

          if(type == rtype)
            {
              win = wins[i];

              break;
            }
        }
    }

  if(wins) XFree(wins);
  XFreeCursor(display, cursor);
  XUngrabPointer(display, CurrentTime);

  XSync(display, False); ///< Sync all changes

  return None != win ? LONG2NUM(win) : Qnil;
} /* }}} */
Ejemplo n.º 25
0
Archivo: icon.c Proyecto: guns/subtle
VALUE
subIconInit(int argc,
  VALUE *argv,
  VALUE self)
{
  SubtlextIcon *i = NULL;

  Data_Get_Struct(self, SubtlextIcon, i);
  if(i)
    {
      VALUE data[3] = { Qnil };

      rb_scan_args(argc, argv, "12", &data[0], &data[1], &data[2]);

      subSubtlextConnect(NULL); ///< Implicit open connection

      /* Find or create icon */
      if(T_STRING == rb_type(data[0])) ///< Icon path
        {
          int hotx = 0, hoty = 0;
          char buf[100] = { 0 };

#ifdef HAVE_WORDEXP_H
          /* Expand tildes in path */
          wordexp_t we;

          if(0 == wordexp(RSTRING_PTR(data[0]), &we, 0))
            {
              snprintf(buf, sizeof(buf), "%s", we.we_wordv[0]);

              wordfree(&we);
            }
          else
#endif /* HAVE_WORDEXP_H */
          snprintf(buf, sizeof(buf), "%s", RSTRING_PTR(data[0]));

          /* Find file */
          if(-1 == access(buf, R_OK))
            {
              char *home = NULL;

              /* Combine paths */
              if((home = getenv("XDG_DATA_HOME")))
                {
                  snprintf(buf, sizeof(buf), "%s/subtle/icons/%s",
                    home, RSTRING_PTR(data[0]));
                }
              else
                {
                  snprintf(buf, sizeof(buf), "%s/.local/share/subtle/icons/%s",
                   getenv("HOME"), RSTRING_PTR(data[0]));
                }

              if(-1 == access(buf, R_OK))
                rb_raise(rb_eStandardError, "Icon not found `%s'",
                  RSTRING_PTR(data[0]));
            }

          /* Reading bitmap or pixmap icon file */
          if(BitmapSuccess != XReadBitmapFile(display,
              DefaultRootWindow(display), buf, &i->width, &i->height,
              &i->pixmap, &hotx, &hoty))
            {
#ifdef HAVE_X11_XPM_H
              XpmAttributes attrs;

              /* We could define a color to use on transparent areas, but
               * this can be done on init only, so we just ignore it and
               * expect pixmaps to have no transparent areas at all */

              /* Init attributes */
              attrs.colormap  = DefaultColormap(display, DefaultScreen(display));
              attrs.depth     = DefaultDepth(display, DefaultScreen(display));
              attrs.visual    = DefaultVisual(display, DefaultScreen(display));
              attrs.valuemask = XpmColormap|XpmDepth|XpmVisual;

              if(XpmSuccess == XpmReadFileToPixmap(display,
                  DefaultRootWindow(display), buf, &i->pixmap, NULL, &attrs))
                {
                  i->flags  |= ICON_PIXMAP;
                  i->width   = attrs.width;
                  i->height  = attrs.height;
                }
              else
#endif /* HAVE_X11_XPM_H */
                {
                  rb_raise(rb_eStandardError, "Malormed icon");

                  return Qnil;
               }
            }
          else i->flags |= ICON_BITMAP;
        }
      else if(FIXNUM_P(data[0]) && FIXNUM_P(data[1])) ///< Icon dimensions
        {
          int depth = 1;

          /* Create pixmap or bitmap */
          if(Qtrue == data[2])
            {
              i->flags |= ICON_PIXMAP;
              depth     = XDefaultDepth(display, DefaultScreen(display));
            }
          else i->flags |= ICON_BITMAP;

          /* Create empty pixmap */
          i->width  = FIX2INT(data[0]);
          i->height = FIX2INT(data[1]);
          i->pixmap = XCreatePixmap(display, DefaultRootWindow(display),
            i->width, i->height, depth);
        }
      else if(FIXNUM_P(data[0]))
        {
          XRectangle geom = { 0 };

          i->flags  |= (ICON_BITMAP|ICON_FOREIGN);
          i->pixmap  = NUM2LONG(data[0]);

          subSharedPropertyGeometry(display, i->pixmap, &geom);

          i->width  = geom.width;
          i->height = geom.height;
        }
      else rb_raise(rb_eArgError, "Unexpected value-types");

      /* Update object */
      rb_iv_set(i->instance, "@width",  INT2FIX(i->width));
      rb_iv_set(i->instance, "@height", INT2FIX(i->height));
      rb_iv_set(i->instance, "@pixmap", LONG2NUM(i->pixmap));

      XSync(display, False); ///< Sync all changes

      subSharedLogDebugSubtlext("new=icon, width=%03d, height=%03d\n",
        i->width, i->height);
    }

  return Qnil;
} /* }}} */
Ejemplo n.º 26
0
/* GravityFind {{{ */
static VALUE
GravityFind(char *source,
  int flags)
{
  int ngravities = 0;
  char **gravities = NULL;
  VALUE ret = Qnil;

  subSubtlextConnect(NULL); ///< Implicit open connection

  /* Get gravity list */
  if((gravities = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
      XInternAtom(display, "SUBTLE_GRAVITY_LIST", False), &ngravities)))
    {
      int i, selid = -1;
      XRectangle geometry = { 0 };
      char buf[30] = { 0 };
      VALUE klass_grav = Qnil, klass_geom = Qnil, meth = Qnil;
      VALUE gravity = Qnil, geom = Qnil;
      regex_t *preg = NULL;

      /* Fetch data */
      klass_grav = rb_const_get(mod, rb_intern("Gravity"));
      klass_geom = rb_const_get(mod, rb_intern("Geometry"));
      meth       = rb_intern("new");

      /* Create if source is given */
      if(source)
        {
          if(isdigit(source[0])) selid = atoi(source);
          preg = subSharedRegexNew(source);
        }

      /* Create gravity list */
      for(i = 0; i < ngravities; i++)
        {
          sscanf(gravities[i], "%hdx%hd+%hd+%hd#%s", &geometry.x, &geometry.y,
            &geometry.width, &geometry.height, buf);

          /* Check if gravity matches */
          if(!source || (source && (selid == i || (-1 == selid &&
              ((flags & SUB_MATCH_EXACT && 0 == strcmp(source, buf)) ||
              (preg && !(flags & SUB_MATCH_EXACT) &&
                subSharedRegexMatch(preg, buf)))))))
            {
              /* Create new gravity */
              gravity = rb_funcall(klass_grav, meth, 1, rb_str_new2(buf));
              geom    = rb_funcall(klass_geom, meth, 4, INT2FIX(geometry.x),
                INT2FIX(geometry.y), INT2FIX(geometry.width),
                INT2FIX(geometry.height));

              rb_iv_set(gravity, "@id",       INT2FIX(i));
              rb_iv_set(gravity, "@geometry", geom);

              ret = subSubtlextOneOrMany(gravity, ret);
            }
        }

      if(preg)    subSharedRegexKill(preg);
      XFreeStringList(gravities);
    }
  else rb_raise(rb_eStandardError, "Failed getting gravity list");

  return NIL_P(ret) ? rb_ary_new() : ret;
} /* }}} */