예제 #1
0
파일: panel.c 프로젝트: guns/subtle
SubPanel *
subPanelNew(int type)
{
    SubPanel *p = NULL;

    /* Create new panel */
    p = PANEL(subSharedMemoryAlloc(1, sizeof(SubPanel)));
    p->flags = (SUB_TYPE_PANEL|type);

    /* Handle panel item type */
    switch(p->flags & (SUB_PANEL_ICON|SUB_PANEL_SUBLET|SUB_PANEL_VIEWS))
    {
    case SUB_PANEL_ICON: /* {{{ */
        p->icon = ICON(subSharedMemoryAlloc(1, sizeof(SubIcon)));
        break; /* }}} */
    case SUB_PANEL_SUBLET: /* {{{ */
        p->sublet = SUBLET(subSharedMemoryAlloc(1, sizeof(SubSublet)));

        /* Sublet specific */
        p->sublet->time   = subSubtleTime();
        p->sublet->text   = subSharedTextNew();
        p->sublet->style  = -1;
        break; /* }}} */
    case SUB_PANEL_VIEWS: /* {{{ */
        p->flags |= SUB_PANEL_DOWN;
        break; /* }}} */
    }

    subSharedLogDebugSubtle("new=panel, type=%s\n",
                            SUB_PANEL_VIEWS == type ? "views" : "title");

    return p;
} /* }}} */
예제 #2
0
파일: screen.c 프로젝트: guns/subtle
/* ScreenPublish {{{ */
static void
ScreenPublish(void)
{
  int i;
  long *workareas = NULL, *panels = NULL, *viewports = NULL;

  assert(subtle);

  /* EWMH: Workarea and screen panels */
  workareas = (long *)subSharedMemoryAlloc(4 * subtle->screens->ndata,
    sizeof(long));
  panels = (long *)subSharedMemoryAlloc(2 * subtle->screens->ndata,
    sizeof(long));

  /* Collect data*/
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);

      /* Set workareas */
      workareas[i * 4 + 0] = s->geom.x;
      workareas[i * 4 + 1] = s->geom.y;
      workareas[i * 4 + 2] = s->geom.width;
      workareas[i * 4 + 3] = s->geom.height;

      /* Set panels */
      panels[i * 2 + 0] = s->flags & SUB_SCREEN_PANEL1 ? subtle->ph : 0;
      panels[i * 2 + 1] = s->flags & SUB_SCREEN_PANEL2 ? subtle->ph : 0;
    }

  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_WORKAREA, workareas,
    4 * subtle->screens->ndata);
  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_SCREEN_PANELS, panels,
    2 * subtle->screens->ndata);

  /* EWMH: Desktop viewport */
  viewports = (long *)subSharedMemoryAlloc(2 * subtle->screens->ndata,
    sizeof(long)); ///< Calloc inits with zero - great

  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_DESKTOP_VIEWPORT, viewports,
    2 * subtle->screens->ndata);

  free(workareas);
  free(panels);
  free(viewports);

  XSync(subtle->dpy, False); ///< Sync all changes

  subSharedLogDebugSubtle("publish=screen, screens=%d\n",
    subtle->screens->ndata);
} /* }}} */
예제 #3
0
파일: screen.c 프로젝트: guns/subtle
void
subScreenPublish(void)
{
  int i;
  long *views = NULL;

  assert(subtle);

  /* EWMH: Views per screen */
  views = (long *)subSharedMemoryAlloc(subtle->screens->ndata,
    sizeof(long));

  /* Collect views */
  for(i = 0; i < subtle->screens->ndata; i++)
    views[i] = SCREEN(subtle->screens->data[i])->vid;

  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_SCREEN_VIEWS,
    views, subtle->screens->ndata);

  free(views);

  XSync(subtle->dpy, False); ///< Sync all changes

  subSharedLogDebugSubtle("publish=screen, screens=%d\n",
    subtle->screens->ndata);
} /* }}} */
예제 #4
0
파일: tray.c 프로젝트: guns/subtle
SubTray *
subTrayNew(Window win)
{
  SubTray *t = NULL;

  assert(win);

  /* Create new tray */
  t = TRAY(subSharedMemoryAlloc(1, sizeof(SubTray)));
  t->flags = SUB_TYPE_TRAY;
  t->win   = win;
  t->width = subtle->ph; ///< Default width

  /* Update tray properties */
  subSharedPropertyName(subtle->dpy, win, &t->name, PKG_NAME);
  subEwmhSetWMState(t->win, WithdrawnState);
  XSelectInput(subtle->dpy, t->win, TRAYMASK);
  XReparentWindow(subtle->dpy, t->win, subtle->windows.tray, 0, 0);
  XAddToSaveSet(subtle->dpy, t->win);
  XSaveContext(subtle->dpy, t->win, TRAYID, (void *)t);

  /* Start embedding life cycle */
  subEwmhMessage(t->win, SUB_EWMH_XEMBED, 0xFFFFFF, CurrentTime,
    XEMBED_EMBEDDED_NOTIFY, 0, subtle->windows.tray, 0);

  subSharedLogDebugSubtle("new=tray, name=%s, win=%#lx\n", t->name, win);

  return t;
} /* }}} */
예제 #5
0
파일: icon.c 프로젝트: guns/subtle
VALUE
subIconAlloc(VALUE self)
{
  SubtlextIcon *i = NULL;

  /* Create icon */
  i = (SubtlextIcon *)subSharedMemoryAlloc(1, sizeof(SubtlextIcon));
  i->instance = Data_Wrap_Struct(self, IconMark, IconSweep, (void *)i);

  return i->instance;
} /* }}} */
예제 #6
0
파일: gravity.c 프로젝트: guns/subtle
/* GravityFindId {{{ */
static int
GravityFindId(char *match,
  char **name,
  XRectangle *geometry)
{
  int ret = -1, ngravities = 0;
  char **gravities = NULL;
  regex_t *preg = NULL;

  assert(match);

  /* Find gravity id */
  if((preg = subSharedRegexNew(match)) &&
      (gravities = subSharedPropertyGetStrings(display, DefaultRootWindow(display),
      XInternAtom(display, "SUBTLE_GRAVITY_LIST", False), &ngravities)))
    {
      int i;
      XRectangle geom = { 0 };
      char buf[30] = { 0 };

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

          /* Check id and name */
          if((isdigit(match[0]) && atoi(match) == i) ||
              (!isdigit(match[0]) && subSharedRegexMatch(preg, buf)))
            {
              subSharedLogDebugSubtlext("Found: type=gravity, name=%s, id=%d\n", buf, i);

              if(geometry) *geometry = geom;
              if(name)
                {
                  *name = (char *)subSharedMemoryAlloc(strlen(buf) + 1, sizeof(char));
                  strncpy(*name, buf, strlen(buf));
                }

              ret = i;
              break;
           }
       }
    }
  else subSharedLogDebugSubtlext("Failed finding gravity `%s'\n", name);

  if(preg)       subSharedRegexKill(preg);
  if(gravities) XFreeStringList(gravities);

  return ret;
} /* }}} */
예제 #7
0
파일: style.c 프로젝트: guns/subtle
SubStyle *
subStyleNew(void)
{
  SubStyle *s = NULL;

  /* Create new style */
  s = STYLE(subSharedMemoryAlloc(1, sizeof(SubStyle)));
  s->flags |= SUB_TYPE_STYLE;

  /* Init style values */
  subStyleReset(s, -1);

  subSharedLogDebugSubtle("new=style\n");

  return s;
} /* }}} */
예제 #8
0
파일: hook.c 프로젝트: MinasMazar/subtle
SubHook *
subHookNew(int type,
  unsigned long proc)
{
  SubHook *h = NULL;

  assert(proc);

  /* Create new hook */
  h = HOOK(subSharedMemoryAlloc(1, sizeof(SubHook)));
  h->flags = (SUB_TYPE_HOOK|type);
  h->proc  = proc;

  subSubtleLogDebugSubtle("new=hook, type=%d, proc=%ld\n", type, proc);

  return h;
} /* }}} */
예제 #9
0
파일: tray.c 프로젝트: guns/subtle
void
subTrayPublish(void)
{
  int i;
  Window *wins = (Window *)subSharedMemoryAlloc(subtle->trays->ndata, sizeof(Window));

  for(i = 0; i < subtle->trays->ndata; i++)
    wins[i] = TRAY(subtle->trays->data[i])->win;

  /* EWMH: Client list and client list stacking */
  subEwmhSetWindows(ROOT, SUB_EWMH_SUBTLE_TRAY_LIST, wins, subtle->trays->ndata);

  XSync(subtle->dpy, False); ///< Sync all changes

  free(wins);

  subSharedLogDebugSubtle("publish=tray, trays=%d\n", subtle->trays->ndata);
} /* }}} */
예제 #10
0
파일: screen.c 프로젝트: guns/subtle
SubScreen *
subScreenNew(int x,
  int y,
  unsigned int width,
  unsigned int height)
{
  SubScreen *s = NULL;
  XSetWindowAttributes sattrs;
  unsigned long mask = 0;

  /* Create screen */
  s = SCREEN(subSharedMemoryAlloc(1, sizeof(SubScreen)));
  s->flags       = SUB_TYPE_SCREEN;
  s->geom.x      = x;
  s->geom.y      = y;
  s->geom.width  = width;
  s->geom.height = height;
  s->base        = s->geom; ///< Backup size
  s->vid         = subtle->screens->ndata; ///< Init

  /* Create panel windows */
  sattrs.event_mask        = ButtonPressMask|EnterWindowMask|
    LeaveWindowMask|ExposureMask;
  sattrs.override_redirect = True;
  sattrs.background_pixmap = ParentRelative;
  mask                     = CWEventMask|CWOverrideRedirect|CWBackPixmap;

  s->panel1 = XCreateWindow(subtle->dpy, ROOT, 0, 1, 1, 1, 0,
    CopyFromParent, InputOutput, CopyFromParent, mask, &sattrs);
  s->panel2 = XCreateWindow(subtle->dpy, ROOT, 0, 0, 1, 1, 0,
    CopyFromParent, InputOutput, CopyFromParent, mask, &sattrs);

  XSaveContext(subtle->dpy, s->panel1, SCREENID, (void *)s);
  XSaveContext(subtle->dpy, s->panel2, SCREENID, (void *)s);

  subSharedLogDebugSubtle("new=screen, x=%d, y=%d, width=%u, height=%u\n",
    s->geom.x, s->geom.y, s->geom.width, s->geom.height);

  return s;
} /* }}} */
예제 #11
0
파일: panel.c 프로젝트: guns/subtle
void
subPanelPublish(void)
{
    int i = 0, j = 0, idx = 0;
    char **names = NULL;

    /* Alloc space */
    names = (char **)subSharedMemoryAlloc(subtle->sublets->ndata,
                                          sizeof(char *));

    /* Find sublet in panels */
    for(i = 0; i < subtle->screens->ndata; i++)
    {
        SubScreen *s = SCREEN(subtle->screens->data[i]);

        if(s->panels)
        {
            for(j = 0; j < s->panels->ndata; j++)
            {
                SubPanel *p = PANEL(s->panels->data[j]);

                /* Include sublets, exclude shallow copies */
                if(p->flags & SUB_PANEL_SUBLET && !(p->flags & SUB_PANEL_COPY))
                    names[idx++] = p->sublet->name;
            }
        }
    }

    /* EWMH: Sublet list and windows */
    subSharedPropertySetStrings(subtle->dpy, ROOT,
                                subEwmhGet(SUB_EWMH_SUBTLE_SUBLET_LIST), names, subtle->sublets->ndata);

    subSharedLogDebugSubtle("publish=panel, n=%d\n", subtle->sublets->ndata);

    XSync(subtle->dpy, False); ///< Sync all changes

    free(names);
} /* }}} */
예제 #12
0
파일: subtle.c 프로젝트: guns/subtle
/* main {{{ */
int
main(int argc,
     char *argv[])
{
    int c;
    char *display = NULL;
    struct sigaction sa;
    const struct option long_options[] =
    {
        { "config",   required_argument, 0, 'c' },
        { "display",  required_argument, 0, 'd' },
        { "help",     no_argument,       0, 'h' },
        { "check",    no_argument,       0, 'k' },
        { "no-randr", no_argument,       0, 'n' },
        { "replace",  no_argument,       0, 'r' },
        { "sublets",  required_argument, 0, 's' },
        { "version",  no_argument,       0, 'v' },
#ifdef DEBUG
        { "level",    required_argument, 0, 'l' },
        { "debug",    no_argument,       0, 'D' },
#endif /* DEBUG */
        { 0, 0, 0, 0}
    };

    /* Create subtle */
    subtle = (SubSubtle *)(subSharedMemoryAlloc(1, sizeof(SubSubtle)));
    subtle->flags |= (SUB_SUBTLE_XRANDR|SUB_SUBTLE_XINERAMA);

    /* Parse arguments */
    while(-1 != (c = getopt_long(argc, argv, "c:d:hknrs:vl:D", long_options, NULL)))
    {
        switch(c)
        {
        case 'c':
            subtle->paths.config = optarg;
            break;
        case 'd':
            display = optarg;
            break;
        case 'h':
            SubtleUsage();
            return 0;
        case 'k':
            subtle->flags |= SUB_SUBTLE_CHECK;
            break;
        case 'n':
            subtle->flags &= ~SUB_SUBTLE_XRANDR;
            break;
        case 'r':
            subtle->flags |= SUB_SUBTLE_REPLACE;
            break;
        case 's':
            subtle->paths.sublets = optarg;
            break;
        case 'v':
            SubtleVersion();
            return 0;
#ifdef DEBUG
        case 'l':
            subSharedLogLevel(SubtleLevel(optarg));
            break;
        case 'D':
            subtle->flags |= SUB_SUBTLE_DEBUG;
            subSharedLogLevel(DEFAULT_LOGLEVEL|DEBUG_LOGLEVEL);
            break;
#else /* DEBUG */
        case 'l':
        case 'D':
            printf("Please recompile %s with `debug=yes'\n", PKG_NAME);
            return 0;
#endif /* DEBUG */
        case '?':
            printf("Try `%s --help' for more information\n", PKG_NAME);
            return -1;
        }
    }

    /* Signal handler */
    sa.sa_handler = SubtleSignal;
    sa.sa_flags   = 0;
    memset(&sa.sa_mask, 0, sizeof(sigset_t)); ///< Avoid uninitialized values
    sigemptyset(&sa.sa_mask);

    sigaction(SIGHUP,  &sa, NULL);
    sigaction(SIGINT,  &sa, NULL);
    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGCHLD, &sa, NULL);

    /* Load and check config only */
    if(subtle->flags & SUB_SUBTLE_CHECK)
    {
        int ret = 0;

        subRubyInit();

        if((ret = subRubyLoadConfig()))
            printf("Syntax OK\n");

        subRubyFinish();

        free(subtle);

        return !ret;
    }

    /* Alloc arrays */
    subtle->clients   = subArrayNew();
    subtle->grabs     = subArrayNew();
    subtle->gravities = subArrayNew();
    subtle->hooks     = subArrayNew();
    subtle->screens   = subArrayNew();
    subtle->sublets   = subArrayNew();
    subtle->tags      = subArrayNew();
    subtle->trays     = subArrayNew();
    subtle->views     = subArrayNew();

    /* Init */
    SubtleVersion();
    subDisplayInit(display);
    subEwmhInit();
    subScreenInit();
    subRubyInit();
    subGrabInit();

    /* Load */
    subRubyLoadConfig();
    subRubyLoadSublets();
    subRubyLoadPanels();

    /* Display */
    subDisplayConfigure();
    subDisplayScan();

    subEventLoop();

    /* Restart if necessary */
    if(subtle->flags & SUB_SUBTLE_RESTART)
    {
        subSubtleFinish();

        printf("Restarting\n");

        execvp(argv[0], argv);
    }
    else subSubtleFinish();

    printf("Exit\n");

    return 0;
} /* }}} */
예제 #13
0
파일: ewmh.c 프로젝트: guns/subtle
void
subEwmhInit(void)
{
  int len = 0;
  long data[2] = { 0, 0 }, pid = (long)getpid();
  char *selection = NULL, *names[] =
  {
    /* ICCCM */
    "WM_NAME", "WM_CLASS", "WM_STATE", "WM_PROTOCOLS", "WM_TAKE_FOCUS",
    "WM_DELETE_WINDOW", "WM_NORMAL_HINTS", "WM_SIZE_HINTS", "WM_HINTS",
    "WM_WINDOW_ROLE", "WM_CLIENT_LEADER",

    /* EWMH */
    "_NET_SUPPORTED", "_NET_CLIENT_LIST", "_NET_CLIENT_LIST_STACKING",
    "_NET_NUMBER_OF_DESKTOPS", "_NET_DESKTOP_NAMES", "_NET_DESKTOP_GEOMETRY",
    "_NET_DESKTOP_VIEWPORT", "_NET_CURRENT_DESKTOP", "_NET_ACTIVE_WINDOW",
    "_NET_WORKAREA", "_NET_SUPPORTING_WM_CHECK", "_NET_WM_FULL_PLACEMENT",
    "_NET_FRAME_EXTENTS",

    /* Client */
    "_NET_CLOSE_WINDOW", "_NET_RESTACK_WINDOW", "_NET_MOVERESIZE_WINDOW",
    "_NET_WM_NAME", "_NET_WM_PID", "_NET_WM_DESKTOP", "_NET_WM_STRUT",

    /* Types */
    "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_DOCK",
    "_NET_WM_WINDOW_TYPE_DESKTOP", "_NET_WM_WINDOW_TYPE_TOOLBAR",
    "_NET_WM_WINDOW_TYPE_SPLASH", "_NET_WM_WINDOW_TYPE_DIALOG",

    /* States */
    "_NET_WM_STATE", "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE",
    "_NET_WM_STATE_STICKY", "_NET_WM_STATE_DEMANDS_ATTENTION",

    /* Tray */
    "_NET_SYSTEM_TRAY_OPCODE", "_NET_SYSTEM_TRAY_MESSAGE_DATA",
    "_NET_SYSTEM_TRAY_S",

    /* Misc */
    "UTF8_STRING", "MANAGER", "_MOTIF_WM_HINTS",

    /* XEmbed */
    "_XEMBED", "_XEMBED_INFO",

    /* subtle */
    "SUBTLE_CLIENT_TAGS", "SUBTLE_CLIENT_RETAG",
    "SUBTLE_CLIENT_GRAVITY", "SUBTLE_CLIENT_SCREEN", "SUBTLE_CLIENT_FLAGS",
    "SUBTLE_GRAVITY_NEW", "SUBTLE_GRAVITY_LIST", "SUBTLE_GRAVITY_KILL",
    "SUBTLE_TAG_NEW", "SUBTLE_TAG_LIST", "SUBTLE_TAG_KILL", "SUBTLE_TRAY_LIST",
    "SUBTLE_VIEW_NEW", "SUBTLE_VIEW_TAGS", "SUBTLE_VIEW_STYLE",
    "SUBTLE_VIEW_ICONS", "SUBTLE_VIEW_KILL",
    "SUBTLE_SUBLET_NEW", "SUBTLE_SUBLET_UPDATE", "SUBTLE_SUBLET_DATA",
    "SUBTLE_SUBLET_STYLE", "SUBTLE_SUBLET_FLAGS", "SUBTLE_SUBLET_LIST",
    "SUBTLE_SUBLET_KILL",
    "SUBTLE_SCREEN_PANELS", "SUBTLE_SCREEN_VIEWS", "SUBTLE_SCREEN_JUMP",
    "SUBTLE_VISIBLE_TAGS", "SUBTLE_VISIBLE_VIEWS",
    "SUBTLE_RENDER", "SUBTLE_RELOAD", "SUBTLE_RESTART", "SUBTLE_QUIT",
    "SUBTLE_COLORS", "SUBTLE_FONT", "SUBTLE_DATA"
  };

  assert(SUB_EWMH_TOTAL == LENGTH(names));

  /* Update tray selection name for current screen */
  len       = strlen(names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION]) + 5; ///< For high screen counts
  selection = (char *)subSharedMemoryAlloc(len, sizeof(char));

  snprintf(selection, len, "%s%u", names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION], SCRN);
  subSharedLogDebug("Selection: len=%d, name=%s\n", len, selection);
  names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION] = selection;

  /* Register atoms */
  XInternAtoms(subtle->dpy, names, SUB_EWMH_TOTAL, 0, atoms);
  subtle->flags |= SUB_SUBTLE_EWMH; ///< Set EWMH flag

  free(selection);

  /* EWMH: Supported hints */
  XChangeProperty(subtle->dpy, ROOT, atoms[SUB_EWMH_NET_SUPPORTED], XA_ATOM,
    32, PropModeReplace, (unsigned char *)&atoms, SUB_EWMH_TOTAL);

  /* EWMH: Window manager information */
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_SUPPORTING_WM_CHECK,
    &subtle->windows.support, 1);
  subEwmhSetString(subtle->windows.support, SUB_EWMH_NET_WM_NAME, PKG_NAME);
  subEwmhSetString(subtle->windows.support, SUB_EWMH_WM_CLASS, PKG_NAME);
  subEwmhSetCardinals(subtle->windows.support, SUB_EWMH_NET_WM_PID, &pid, 1);

  /* EWMH: Desktop geometry */
  data[0] = subtle->width;
  data[1] = subtle->height;
  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_DESKTOP_GEOMETRY, (long *)&data, 2);

  /* EWMH: Client list and client list stacking */
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_CLIENT_LIST, NULL, 0);
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_CLIENT_LIST_STACKING, NULL, 0);

  subSharedLogDebugSubtle("init=ewmh\n");
} /* }}} */