aboutsummaryrefslogtreecommitdiff
path: root/src/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/group.c')
-rw-r--r--src/group.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/group.c b/src/group.c
new file mode 100644
index 0000000..cd3aba4
--- /dev/null
+++ b/src/group.c
@@ -0,0 +1,299 @@
+/****************************************************************************
+ * Functions for handling window groups.
+ * Copyright (C) 2004 Joe Wingbermuehle
+ ****************************************************************************/
+
+#include "jwm.h"
+#include "group.h"
+#include "client.h"
+#include "icon.h"
+#include "error.h"
+#include "match.h"
+#include "desktop.h"
+#include "main.h"
+#include "misc.h"
+
+typedef enum {
+ MATCH_NAME,
+ MATCH_CLASS
+} MatchType;
+
+typedef struct PatternListType {
+ char *pattern;
+ MatchType match;
+ struct PatternListType *next;
+} PatternListType;
+
+typedef struct OptionListType {
+ OptionType option;
+ char *value;
+ struct OptionListType *next;
+} OptionListType;
+
+typedef struct GroupType {
+ PatternListType *patterns;
+ OptionListType *options;
+ struct GroupType *next;
+} GroupType;
+
+static GroupType *groups = NULL;
+
+static void ReleasePatternList(PatternListType *lp);
+static void ReleaseOptionList(OptionListType *lp);
+static void AddPattern(PatternListType **lp, const char *pattern,
+ MatchType match);
+static void ApplyGroup(const GroupType *gp, ClientNode *np);
+
+/****************************************************************************
+ ****************************************************************************/
+void InitializeGroups() {
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void StartupGroups() {
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void ShutdownGroups() {
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void DestroyGroups() {
+
+ GroupType *gp;
+
+ while(groups) {
+ gp = groups->next;
+ ReleasePatternList(groups->patterns);
+ ReleaseOptionList(groups->options);
+ Release(groups);
+ groups = gp;
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void ReleasePatternList(PatternListType *lp) {
+
+ PatternListType *tp;
+
+ while(lp) {
+ tp = lp->next;
+ Release(lp->pattern);
+ Release(lp);
+ lp = tp;
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void ReleaseOptionList(OptionListType *lp) {
+
+ OptionListType *tp;
+
+ while(lp) {
+ tp = lp->next;
+ if(lp->value) {
+ Release(lp->value);
+ }
+ Release(lp);
+ lp = tp;
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+GroupType *CreateGroup() {
+ GroupType *tp;
+
+ tp = Allocate(sizeof(GroupType));
+ tp->patterns = NULL;
+ tp->options = NULL;
+ tp->next = groups;
+ groups = tp;
+
+ return tp;
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void AddGroupClass(GroupType *gp, const char *pattern) {
+
+ Assert(gp);
+
+ if(pattern) {
+ AddPattern(&gp->patterns, pattern, MATCH_CLASS);
+ } else {
+ Warning("invalid group class");
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void AddGroupName(GroupType *gp, const char *pattern) {
+
+ Assert(gp);
+
+ if(pattern) {
+ AddPattern(&gp->patterns, pattern, MATCH_NAME);
+ } else {
+ Warning("invalid group name");
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void AddPattern(PatternListType **lp, const char *pattern, MatchType match) {
+
+ PatternListType *tp;
+
+ Assert(lp);
+ Assert(pattern);
+
+ tp = Allocate(sizeof(PatternListType));
+ tp->next = *lp;
+ *lp = tp;
+
+ tp->pattern = CopyString(pattern);
+ tp->match = match;
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void AddGroupOption(GroupType *gp, OptionType option) {
+
+ OptionListType *lp;
+
+ lp = Allocate(sizeof(OptionListType));
+ lp->option = option;
+ lp->value = NULL;
+ lp->next = gp->options;
+ gp->options = lp;
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void AddGroupOptionValue(GroupType *gp, OptionType option,
+ const char *value) {
+
+ OptionListType *lp;
+
+ Assert(value);
+
+ lp = Allocate(sizeof(OptionListType));
+ lp->option = option;
+ lp->value = CopyString(value);
+ lp->next = gp->options;
+ gp->options = lp;
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void ApplyGroups(ClientNode *np) {
+
+ PatternListType *lp;
+ GroupType *gp;
+
+ Assert(np);
+
+ for(gp = groups; gp; gp = gp->next) {
+ for(lp = gp->patterns; lp; lp = lp->next) {
+ if(lp->match == MATCH_CLASS) {
+ if(Match(lp->pattern, np->className)) {
+ ApplyGroup(gp, np);
+ break;
+ }
+ } else if(lp->match == MATCH_NAME) {
+ if(Match(lp->pattern, np->name)) {
+ ApplyGroup(gp, np);
+ break;
+ }
+ } else {
+ Debug("invalid match in ApplyGroups: %d", lp->match);
+ }
+ }
+ }
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
+void ApplyGroup(const GroupType *gp, ClientNode *np) {
+
+ OptionListType *lp;
+ unsigned int temp;
+
+ Assert(gp);
+ Assert(np);
+
+ for(lp = gp->options; lp; lp = lp->next) {
+ switch(lp->option) {
+ case OPTION_STICKY:
+ np->state.status |= STAT_STICKY;
+ break;
+ case OPTION_NOLIST:
+ np->state.status |= STAT_NOLIST;
+ break;
+ case OPTION_BORDER:
+ np->state.border |= BORDER_OUTLINE;
+ break;
+ case OPTION_NOBORDER:
+ np->state.border &= ~BORDER_OUTLINE;
+ break;
+ case OPTION_TITLE:
+ np->state.border |= BORDER_TITLE;
+ break;
+ case OPTION_NOTITLE:
+ np->state.border &= ~BORDER_TITLE;
+ break;
+ case OPTION_LAYER:
+ temp = atoi(lp->value);
+ if(temp <= LAYER_COUNT) {
+ SetClientLayer(np, temp);
+ } else {
+ Warning("invalid group layer: %s", lp->value);
+ }
+ break;
+ case OPTION_DESKTOP:
+ temp = atoi(lp->value);
+ if(temp >= 1 && temp <= desktopCount) {
+ np->state.desktop = temp - 1;
+ } else {
+ Warning("invalid group desktop: %s", lp->value);
+ }
+ break;
+ case OPTION_ICON:
+ DestroyIcon(np->icon);
+ np->icon = LoadNamedIcon(lp->value);
+ break;
+ case OPTION_PIGNORE:
+ np->state.status |= STAT_PIGNORE;
+ break;
+ case OPTION_MAXIMIZED:
+ np->state.status |= STAT_MAXIMIZED;
+ break;
+ case OPTION_MINIMIZED:
+ np->state.status |= STAT_MINIMIZED;
+ break;
+ case OPTION_SHADED:
+ np->state.status |= STAT_SHADED;
+ break;
+ default:
+ Debug("invalid option: %d", lp->option);
+ break;
+ }
+ }
+
+}
+