]> Dogcows Code - chaz/openbox/commitdiff
ECKS EM ELL
authorDana Jansens <danakj@orodu.net>
Sat, 24 May 2003 15:35:26 +0000 (15:35 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 24 May 2003 15:35:26 +0000 (15:35 +0000)
19 files changed:
configure.ac
data/rc3
openbox/Makefile.am
openbox/config.c
openbox/openbox.c
openbox/parse.c
openbox/parse.h
openbox/parse.l [deleted file]
openbox/parse.y [deleted file]
plugins/Makefile.am
plugins/keyboard/Makefile.am
plugins/keyboard/keyboard.c
plugins/mouse/Makefile.am
plugins/mouse/mouse.c
plugins/placement/Makefile.am
plugins/placement/history.c
plugins/placement/history.h
plugins/placement/placement.c
plugins/resistance.c

index 811de5de5f989a61929310e8fd7c28dfd3d867b1..21fc5219d65fa7628e13fb7368d5f824746d3134 100644 (file)
@@ -53,6 +53,10 @@ PKG_CHECK_MODULES(XFT, [xft])
 AC_SUBST(XFT_CFLAGS)
 AC_SUBST(XFT_LIBS)
 
+PKG_CHECK_MODULES(XML, [libxml-2.0])
+AC_SUBST(XML_CFLAGS)
+AC_SUBST(XML_LIBS)
+
 PKG_CHECK_MODULES(LIBSN, [libstartup-notification-1.0],
   [
     AC_DEFINE(USE_LIBSN)
index 26affba415395803efc3ddddc1c909071fa42386..a159e65eb2ca4f1cf3a16c0f17b3387853e7e0ad 100644 (file)
--- a/data/rc3
+++ b/data/rc3
-[resistance]
-
-# amount of resistance to provide at edges
-#strength=10
-
-# resistance against other windows
-#windows=true
-
-[placement]
-
-# place windows where they were last
-#remember = yes
-
-[focus]
-
-# focus new windows when they appear
-#focusNew = yes
-
-# does focus follow the mouse pointer when it enters a window
-#followMouse = no
-
-# when no windows are left with focus, focus the last window on the desktop
-# to previously have focus
-#focusLast = yes
-
-# a special case of focusLast that applies when switching between desktops; if
-# set, the previously focused window on the desktop is focused when switching
-#focusLastOnDesktop = yes
-
-# shows a helpful dialog while cycling focus
-#cyclingDialog = yes
-
-[desktops]
-
-# The number of virtual desktops to use
-#number = 4
-
-# A list of names for the desktops
-names = ("one" "two" "three" "four")
-
-[moveresize]
-
-# When true windows are moved opaquely, when false just an outline is shown
-# while they are moved
-#opaque_move = yes
-
-# When true windows are resized opaquely, when false just an outline is shown
-# while they are resized
-#opaque_resize = yes
-
-[theme]
-
-# the theme to display
-#theme = "operation"
-
-[dock]
-# The position on the screen to place the dock. Options are:
-#   TopLeft, Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Left
-#     - the appropriate corner/edge of the screen
-#   Floating - uses the floatingX and floatingY options to position itself
-#position = "TopLeft"
-
-# When position is "Floating", this specifies the x-coordinate to place the
-# the dock at.
-#floatingX = 0
-
-# When position is "Floating", this specifies the y-coordinate to place the
-# the dock at.
-#floatingY = 0
-
-# The stacking layer that the dock will be in. Options are:
-#   Top - above all normal windows, same layer as panels
-#   Normal - can be above and below normal windows
-#   Bottom - below all normal windows
-#stacking = "Top"
-
-# When true, the dock will grow horizontally when dock apps are added to it,
-# otherwise it will grow vertically.
-#horizontal = no
-
-# When true, the dock will hide itself while the pointer is not over it, and
-# will show itself when the pointer is.
-#autoHide = no
-
-# The number of milliseconds to wait before hiding the dock when the pointer
-# leaves it, if the autoHide option is on.
-#hideTimeout = 3000
-
-[keyboard]
-
-#kbind (Key [Key...])  Action  [Parameter]
-
-kbind (F12)            execute "xterm"
-
-kbind (A-Left)         PreviousDesktopWrap
-kbind (A-Right)                NextDesktopWrap
-
-kbind (A-1)            Desktop 1
-kbind (A-2)            Desktop 2
-kbind (A-3)            Desktop 3
-kbind (A-4)            Desktop 4
-
-kbind (C-A-1)          SendToDesktop 1
-kbind (C-A-2)          SendToDesktop 2
-kbind (C-A-3)          SendToDesktop 3
-kbind (C-A-4)          SendToDesktop 4
-
-kbind (C-S-x x)                ToggleMaximizeFull
-kbind (C-S-x Up)       ToggleMaximizeVert
-kbind (C-S-x Right)    ToggleMaximizeHorz
-
-kbind (C-A-Left)       MoveRelativeHorz -3
-kbind (C-A-Right)      MoveRelativeHorz  3
-kbind (C-A-Up)         MoveRelativeVert -3
-kbind (C-A-Down)       MoveRelativeVert  3
-
-kbind (A-F4)           Close
-
-kbind (W-D)            ToggleDecorations
-
-kbind (A-Tab)           NextWindow
-kbind (S-A-Tab)         PreviousWindow
-
-[mouse]
-
-# the distance a drag must go before it is recognized
-#dragThreshold = 3
-
-# the amount of time in milliseconds in which two clicks must occur to cause a
-# doubleclick event
-#doubleClickTime = 200
-
-#mbind Context         Event           Button  Action [Parameter]
-
-mbind  Titlebar        Drag            Left    Move
-mbind  Handle          Drag            Left    Move
-mbind  Frame           Drag            A-Left  Move
-
-mbind  BLCorner        Drag            Left    Resize
-mbind  BRCorner        Drag            Left    Resize
-mbind  Frame           Drag            A-Middle Resize
-
-mbind  Titlebar        Click           Left    Raise
-mbind  Titlebar        Press           Middle  Lower
-mbind  Handle          Click           Left    Raise
-mbind  Handle          Press           Middle  Lower
-mbind  Frame           Click           A-Left  Raise
-mbind  Frame           Click           A-Middle Lower
-
-mbind  Titlebar        Press           Left    Focus
-mbind  Handle          Press           Left    Focus
-mbind  BLCorner        Press           Left    Focus
-mbind  BRCorner        Press           Left    Focus
-mbind  Maximize        Press           Left    Focus
-mbind  Maximize        Press           Middle  Focus
-mbind  Maximize        Press           Right   Focus
-mbind  Iconify         Press           Left    Focus
-mbind  Icon            Press           Left    Focus
-mbind  Close           Press           Left    Focus
-mbind  AllDesktops     Press           Left    Focus
-mbind  Shade           Press           Left    Focus
-mbind  Client          Press           Left    FocusRaise
-mbind  Client          Press           Middle  Focus
-mbind  Client          Press           Right   Focus
-mbind  Frame           Press           A-Left  Focus
-
-mbind  Titlebar        DoubleClick     Left    ToggleShade
-mbind  Titlebar        Click           Up      Shade
-mbind  Titlebar        Click           Down    UnShade
-
-mbind  Maximize        Click           Left    ToggleMaximizeFull
-mbind  Maximize        Click           Middle  ToggleMaximizeVert
-mbind  Maximize        Click           Right   ToggleMaximizeHorz
-mbind  Iconify         Click           Left    Iconify
-mbind  Icon            DoubleClick     Left    Close
-mbind  Close           Click           Left    Close
-mbind  Close           Click           Middle  Kill
-mbind  AllDesktops     Click           Left    ToggleOmnipresent
-mbind  Shade           Click           Left    ToggleShade
-
-mbind  Root            Click           Up      NextDesktopWrap
-mbind  Root            Click           Down    PreviousDesktopWrap
-mbind  Root            Click           A-Up    NextDesktopWrap
-mbind  Root            Click           A-Down  PreviousDesktopWrap
-mbind  Frame           Click           A-Up    NextDesktopWrap
-mbind  Frame           Click           A-Down  PreviousDesktopWrap
-mbind  Frame           Click           C-A-Up  SendToNextDesktopWrap
-mbind  Frame           Click           C-A-Down SendToPreviousDesktopWrap
-
-mbind  Root            Click           Right   ShowMenu "root"
-mbind   Frame           Click           Right   ShowMenu "client-menu"
+<?xml version="1.0"?>
+
+<!-- Do not edit this file, it will be overwritten on install. Edit the file
+     in $HOME/.openbox/ instead. -->
+
+<openbox_config>
+
+<resistance>
+  <strength>10</strength>
+  <windows>yes</windows>
+</resistance>
+
+<placement>
+  <remember>yes</remember>
+</placement>
+
+<focus>
+  <focusNew>yes</focusNew>
+  <followMouse>no</followMouse>
+  <focusLast>yes</focusLast>
+  <focusLastOnDesktop>yes</focusLastOnDesktop>
+  <cyclingDialog>yes</cyclingDialog>
+</focus>
+
+<theme>
+  <theme>operation</theme>
+</theme>
+
+<desktops>
+  <number>4</number>
+  <names>
+    <name>one</name>
+    <name>two</name>
+    <name>three</name>
+    <name>four</name>
+  </names>
+</desktops>
+
+<moveresize>
+  <opaqueMove>yes</opaqueMove>
+  <opaqueResize>yes</opaqueResize>
+</moveresize>
+
+<dock>
+  <position>topleft</position>
+  <stacking>top</stacking>
+  <direction>vertical</direction>
+  <floatingX>0</floatingX>
+  <floatingY>0</floatingY>
+  <autoHide>no</autoHide>
+  <hideTimeout>300</hideTimeout>
+</dock>
+
+<keyboard>
+  <keybind key="A-F10">
+    <action name="MaximizeFull"></action>
+  </keybind>
+  <keybind key="A-F5">
+    <action name="UnmaximizeFull"></action>
+  </keybind>
+  <keybind key="A-F12">
+    <action name="ToggleShaded"></action>
+  </keybind>
+  <keybind key="C-A-Left">
+    <action name="DesktopLeft"></action>
+  </keybind>
+  <keybind key="C-A-Right">
+    <action name="DesktopRight"></action>
+  </keybind>
+  <keybind key="C-A-Up">
+    <action name="DesktopUp"></action>
+  </keybind>
+  <keybind key="C-A-Down">
+    <action name="DesktopDown"></action>
+  </keybind>
+  <keybind key="S-A-Left">
+    <action name="SendToDesktopLeft"></action>
+  </keybind>
+  <keybind key="S-A-Right">
+    <action name="SendToDesktopRight"></action>
+  </keybind>
+  <keybind key="S-A-Up">
+    <action name="SendToDesktopUp"></action>
+  </keybind>
+  <keybind key="S-A-Down">
+    <action name="SendToDesktopDown"></action>
+  </keybind>
+  <keybind key="C-A-d">
+    <action name="ToggleShowDesktop"></action>
+  </keybind>
+  <keybind key="A-F4">
+    <action name="Close"></action>
+  </keybind>
+  <keybind key="A-Tab">
+    <action name="NextWindow"></action>
+  </keybind>
+  <keybind key="A-S-Tab">
+    <action name="PreviousWindow"></action>
+  </keybind>
+  <keybind key="A-F7">
+    <action name="KeyboardMove"></action>
+  </keybind>
+  <keybind key="A-F8">
+    <action name="KeyboardResize"></action>
+  </keybind>
+  <keybind key="A-F9">
+    <action name="Iconify"></action>
+  </keybind>
+</keyboard>
+
+<mouse>
+  <dragThreshold>3</dragThreshold>
+  <doubleClickTime>200</doubleClickTime>
+
+  <context name="frame">
+    <mousebind button="A-Left" action="drag">
+      <action name="move"/>
+    </mousebind>
+    <mousebind button="A-Left" action="click">
+      <action name="raise"/>
+    </mousebind>
+    <mousebind button="A-Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="A-Middle" action="drag">
+      <action name="resize"/>
+    </mousebind> 
+    <mousebind button="A-Middle" action="click">
+      <action name="lower"/>
+    </mousebind>
+    <mousebind button="A-Right" action="press">
+      <action name="showmenu"><menu>client-menu</menu></action>
+    </mousebind>
+    <mousebind button="A-Up" action="click">
+      <action name="desktopright"/>
+    </mousebind>
+    <mousebind button="A-Down" action="click">
+      <action name="desktopleft"/>
+    </mousebind>
+    <mousebind button="C-A-Up" action="click">
+      <action name="sendtodesktopright"/>
+    </mousebind>
+    <mousebind button="C-A-Down" action="click">
+      <action name="sendtodesktopleft"/>
+    </mousebind>
+  </context>
+  <context name="titlebar">
+    <mousebind button="Left" action="drag">
+      <action name="move"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="raise"/>
+    </mousebind>
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="doubleclick">
+      <action name="toggleshade"/>
+    </mousebind>
+    <mousebind button="Middle" action="press">
+      <action name="lower"/>
+    </mousebind>
+    <mousebind button="Up" action="click">
+      <action name="shade"/>
+    </mousebind>
+    <mousebind button="Down" action="click">
+      <action name="unshade"/>
+    </mousebind>
+    <mousebind button="Right" action="press">
+      <action name="showmenu"><menu>client-menu</menu></action>
+    </mousebind>
+  </context>
+  <context name="handle">
+    <mousebind button="Left" action="drag">
+      <action name="move"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="raise"/>
+    </mousebind>
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Middle" action="press">
+      <action name="lower"/>
+    </mousebind>
+  </context>
+  <context name="blcorner">
+    <mousebind button="Left" action="drag">
+      <action name="resize"/>
+    </mousebind>
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+  </context>
+  <context name="brcorner">
+    <mousebind button="Left" action="drag">
+      <action name="resize"/>
+    </mousebind>
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+  </context>
+  <context name="client">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Middle" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Right" action="press">
+      <action name="focus"/>
+    </mousebind>
+  </context>
+  <context name="icon">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="showmenu"><menu>client-menu</menu></action>
+    </mousebind>
+    <mousebind button="Left" action="doubleclick">
+      <action name="close"/>
+    </mousebind>
+  </context>
+  <context name="alldesktops">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="toggleomnipresent"/>
+    </mousebind>
+  </context>
+  <context name="shade">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="toggleshade"/>
+    </mousebind>
+  </context>
+  <context name="iconify">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="iconify"/>
+    </mousebind>
+  </context>
+  <context name="maximize">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Middle" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Right" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="togglemaximizefull"/>
+    </mousebind>
+    <mousebind button="Middle" action="click">
+      <action name="togglemaximizevert"/>
+    </mousebind>
+    <mousebind button="Right" action="click">
+      <action name="togglemaximizehorz"/>
+    </mousebind>
+  </context>
+  <context name="close">
+    <mousebind button="Left" action="press">
+      <action name="focus"/>
+    </mousebind>
+    <mousebind button="Left" action="click">
+      <action name="close"/>
+    </mousebind>
+  </context>
+  <context name="root">
+    <mousebind button="Up" action="click">
+      <action name="desktopright"/>
+    </mousebind>
+    <mousebind button="Down" action="click">
+      <action name="desktopleft"/>
+    </mousebind>
+    <mousebind button="A-Up" action="click">
+      <action name="desktopright"/>
+    </mousebind>
+    <mousebind button="A-Down" action="click">
+      <action name="desktopleft"/>
+    </mousebind>
+    <mousebind button="Middle" action="press">
+      <action name="showmenu"><menu>root</menu></action>
+    </mousebind>
+  </context>
+</mouse>
+
+</openbox_config>
index 4c83005ffacfd7c03ccd1f9ff8f66ec72228e5ea..ecb72969bd0438a6774c7ef110cf39b9cf9ae05d 100644 (file)
@@ -6,7 +6,7 @@ binary=openbox3
 url=http://icculus.org/openbox
 
 CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
-         $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+         $(LIBSN_CFLAGS) $(GL_CFLAGS) $(XML_CFLAGS) @CPPFLAGS@ \
          -DLOCALEDIR=\"$(localedir)\" \
          -DRCDIR=\"$(rcdir)\" \
          -DPLUGINDIR=\"$(plugindir)\" \
@@ -16,38 +16,25 @@ CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
 INCLUDES=-I..
 LIBS=$(X_LIBS) $(XFT_LIBS) $(XINERAMA_LIBS) $(XKB_LIBS) $(XRANDR_LIBS) \
        $(VIDMODE_LIBS) $(XSHAPE_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) \
-       $(LIBSN_LIBS) @LIBS@ @LIBINTL@
+       $(LIBSN_LIBS) $(XML_LIBS) @LIBS@ @LIBINTL@
 
 bin_PROGRAMS=$(binary)
 
 openbox3_LDADD=-lobrender -L../render
 openbox3_LDFLAGS=-export-dynamic
-openbox3_SOURCES=parse.tab.c parse.lex.c action.c client.c config.c \
+openbox3_SOURCES=action.c client.c config.c parse.c \
                  extensions.c focus.c frame.c grab.c menu.c menu_render.c \
-                 openbox.c framerender.c parse.c plugin.c prop.c screen.c \
+                 openbox.c framerender.c plugin.c prop.c screen.c \
                  stacking.c dispatch.c event.c group.c timer.c xerror.c \
                  moveresize.c startup.c popup.c dock.c window.c
 
 noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \
                focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \
-               menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \
+               menu.h openbox.h plugin.h prop.h screen.h \
                stacking.h timer.h xerror.h moveresize.h startup.h popup.h \
-               dock.h window.h
-
-# kill the implicit .c.y rule
-%.c: %.y
-       @
-
-%.lex.c: %.l
-       $(FLEX) -o$@ $<
-
-%.tab.c: %.y
-       $(BISON) -d -o $@ $<
+               dock.h window.h parse.h
 
 MAINTAINERCLEANFILES=Makefile.in
 
-clean-local:
-       $(RM) parse.lex.c parse.tab.c parse.tab.h
-
 distclean-local:
        $(RM) *\~ *.orig *.rej .\#*
index e751f32b6baa267e693899914e9354a8f24f41d8..c3fa786cce71c09b1a9f03e21388305cb43550cb 100644 (file)
@@ -23,182 +23,114 @@ gboolean     config_dock_horz;
 gboolean     config_dock_hide;
 guint        config_dock_hide_timeout;
 
-static void parse_focus(char *name, ParseToken *value)
+static void parse_focus(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "focusnew")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_focus_new = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "followmouse")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_focus_follow = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "focuslast")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_focus_last = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "focuslastondesktop")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_focus_last_on_desktop = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "cyclingdialog")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_focus_popup = value->data.bool;
-        }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("focusNew", node)))
+        config_focus_new = parse_bool(doc, n);
+    if ((n = parse_find_node("followMouse", node)))
+        config_focus_follow = parse_bool(doc, n);
+    if ((n = parse_find_node("focusLast", node)))
+        config_focus_last = parse_bool(doc, n);
+    if ((n = parse_find_node("focusLastOnDesktop", node)))
+        config_focus_last_on_desktop = parse_bool(doc, n);
+    if ((n = parse_find_node("cyclingDialog", node)))
+        config_focus_popup = parse_bool(doc, n);
 }
 
-static void parse_theme(char *name, ParseToken *value)
+static void parse_theme(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "theme")) {
-        if (value->type != TOKEN_STRING)
-            yyerror("invalid value");
-        else {
-            g_free(config_theme);
-            config_theme = g_strdup(value->data.string);
-        }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("theme", node))) {
+        g_free(config_theme);
+        config_theme = parse_string(doc, n);
+    }
 }
 
-static void parse_desktops(char *name, ParseToken *value)
+static void parse_desktops(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    GList *it;
-
-    if (!g_ascii_strcasecmp(name, "number")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            config_desktops_num = value->data.integer;
-        }
-    } else if (!g_ascii_strcasecmp(name, "names")) {
-        if (value->type == TOKEN_LIST) {
-            for (it = value->data.list; it; it = it->next)
-                if (((ParseToken*)it->data)->type != TOKEN_STRING) break;
-            if (it == NULL) {
-                /* build a string list */
-                g_free(config_desktops_names);
-                for (it = value->data.list; it; it = it->next)
-                    config_desktops_names =
-                        g_slist_append(config_desktops_names,
-                                       g_strdup
-                                       (((ParseToken*)it->data)->data.string));
-            } else {
-                yyerror("invalid string in names list");
-            }
-        } else {
-            yyerror("syntax error (expected list of strings)");
-        }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("number", node)))
+        config_desktops_num = parse_int(doc, n);
+    if ((n = parse_find_node("names", node))) {
+        GSList *it;
+        xmlNodePtr nname;
+
+        for (it = config_desktops_names; it; it = it->next)
+            g_free(it->data);
+        g_slist_free(config_desktops_names);
+        config_desktops_names = NULL;
+
+        nname = parse_find_node("name", n->xmlChildrenNode);
+        while (nname) {
+            config_desktops_names = g_slist_append(config_desktops_names,
+                                                   parse_string(doc, nname));
+            nname = parse_find_node("name", nname->next);
+        }
+    }
 }
 
-static void parse_moveresize(char *name, ParseToken *value)
+static void parse_moveresize(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "opaque_move")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_opaque_move = value->data.integer;
-        }
-    } else if (!g_ascii_strcasecmp(name, "opaque_resize")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_opaque_resize = value->data.integer;
-        }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("opaqueMove", node)))
+        config_opaque_move = parse_bool(doc, n);
+    if ((n = parse_find_node("opaqueResize", node)))
+        config_opaque_resize = parse_bool(doc, n);
 }
 
-static void parse_dock(char *name, ParseToken *value)
+static void parse_dock(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "stacking")) {
-        if (value->type != TOKEN_STRING)
-            yyerror("invalid value");
-        else {
-            if (!g_ascii_strcasecmp(value->data.string, "bottom"))
-                config_dock_layer = Layer_Below;
-            else if (!g_ascii_strcasecmp(value->data.string, "normal"))
-                config_dock_layer = Layer_Normal;
-            else if (!g_ascii_strcasecmp(value->data.string, "top"))
-                config_dock_layer = Layer_Top;
-            else
-                yyerror("invalid layer");
-        }
-    } else if (!g_ascii_strcasecmp(name, "position")) {
-        if (value->type != TOKEN_STRING)
-            yyerror("invalid value");
-        else {
-            if (!g_ascii_strcasecmp(value->data.string, "topleft"))
-                config_dock_pos = DockPos_TopLeft;
-            else if (!g_ascii_strcasecmp(value->data.string, "top"))
-                config_dock_pos = DockPos_Top;
-            else if (!g_ascii_strcasecmp(value->data.string, "topright"))
-                config_dock_pos = DockPos_TopRight;
-            else if (!g_ascii_strcasecmp(value->data.string, "right"))
-                config_dock_pos = DockPos_Right;
-            else if (!g_ascii_strcasecmp(value->data.string, "bottomright"))
-                config_dock_pos = DockPos_BottomRight;
-            else if (!g_ascii_strcasecmp(value->data.string, "bottom"))
-                config_dock_pos = DockPos_Bottom;
-            else if (!g_ascii_strcasecmp(value->data.string, "bottomleft"))
-                config_dock_pos = DockPos_BottomLeft;
-            else if (!g_ascii_strcasecmp(value->data.string, "left"))
-                config_dock_pos = DockPos_Left;
-            else if (!g_ascii_strcasecmp(value->data.string, "floating"))
-                config_dock_pos = DockPos_Floating;
-            else
-                yyerror("invalid position");
-        }
-    } else if (!g_ascii_strcasecmp(name, "floatingx")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            config_dock_x = value->data.integer;
-        }
-    } else if (!g_ascii_strcasecmp(name, "floatingy")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            config_dock_y = value->data.integer;
-        }
-    } else if (!g_ascii_strcasecmp(name, "horizontal")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_dock_horz = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "autohide")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else {
-            config_dock_hide = value->data.bool;
-        }
-    } else if (!g_ascii_strcasecmp(name, "hidetimeout")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            config_dock_hide_timeout = value->data.integer;
-        }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("position", node))) {
+        if (parse_contains("TopLeft", doc, n))
+            config_dock_pos = DockPos_TopLeft;
+        else if (parse_contains("Top", doc, n))
+            config_dock_pos = DockPos_Top;
+        else if (parse_contains("TopRight", doc, n))
+            config_dock_pos = DockPos_TopRight;
+        else if (parse_contains("Right", doc, n))
+            config_dock_pos = DockPos_Right;
+        else if (parse_contains("BottomRight", doc, n))
+            config_dock_pos = DockPos_BottomRight;
+        else if (parse_contains("Bottom", doc, n))
+            config_dock_pos = DockPos_Bottom;
+        else if (parse_contains("BottomLeft", doc, n))
+            config_dock_pos = DockPos_BottomLeft;
+        else if (parse_contains("Left", doc, n))
+            config_dock_pos = DockPos_Left;
+        else if (parse_contains("Floating", doc, n))
+            config_dock_pos = DockPos_Floating;
+    }
+    if (config_dock_pos == DockPos_Floating) {
+        if ((n = parse_find_node("floatingX", node)))
+            config_dock_x = parse_int(doc, n);
+        if ((n = parse_find_node("floatingY", node)))
+            config_dock_y = parse_int(doc, n);
+    }
+    if ((n = parse_find_node("stacking", node))) {
+        if (parse_contains("top", doc, n))
+            config_dock_layer = Layer_Top;
+        else if (parse_contains("normal", doc, n))
+            config_dock_layer = Layer_Normal;
+        else if (parse_contains("bottom", doc, n))
+            config_dock_layer = Layer_Below;
+    }
+    if ((n = parse_find_node("direction", node))) {
+        if (parse_contains("horizontal", doc, n))
+            config_dock_horz = TRUE;
+        else if (parse_contains("vertical", doc, n))
+            config_dock_horz = FALSE;
+    }
+    if ((n = parse_find_node("autoHide", node)))
+        config_dock_hide = parse_bool(doc, n);
+    if ((n = parse_find_node("hideTimeout", node)))
+        config_dock_hide_timeout = parse_int(doc, n);
 }
 
 void config_startup()
@@ -209,21 +141,21 @@ void config_startup()
     config_focus_last_on_desktop = TRUE;
     config_focus_popup = TRUE;
 
-    parse_reg_section("focus", NULL, parse_focus);
+    parse_register("focus", parse_focus, NULL);
 
     config_theme = NULL;
 
-    parse_reg_section("theme", NULL, parse_theme);
+    parse_register("theme", parse_theme, NULL);
 
     config_desktops_num = 4;
     config_desktops_names = NULL;
 
-    parse_reg_section("desktops", NULL, parse_desktops);
+    parse_register("desktops", parse_desktops, NULL);
 
     config_opaque_move = TRUE;
     config_opaque_resize = TRUE;
 
-    parse_reg_section("moveresize", NULL, parse_moveresize);
+    parse_register("moveresize", parse_moveresize, NULL);
 
     config_dock_layer = Layer_Top;
     config_dock_pos = DockPos_TopRight;
@@ -233,7 +165,7 @@ void config_startup()
     config_dock_hide = FALSE;
     config_dock_hide_timeout = 3000;
 
-    parse_reg_section("dock", NULL, parse_dock);
+    parse_register("dock", parse_dock, NULL);
 }
 
 void config_shutdown()
index 3b2a999111c8b7371da971091a5ab425ef755554..2b4dddced71679ae56163f53bcb2b0c0fd55bce8 100644 (file)
@@ -180,7 +180,7 @@ int main(int argc, char **argv)
         /* set up the kernel config shit */
         config_startup();
         /* parse/load user options */
-        parse_rc();
+        parse_config();
         /* we're done with parsing now, kill it */
         parse_shutdown();
 
index ffb72c031b7cbc6e7a89cb023abf349737260604..8f9c82fbc5a9aedf0a20c44946539654739d6b5b 100644 (file)
 #include "parse.h"
+#include <glib.h>
 
-static GHashTable     *reg = NULL;
+struct Callback {
+    char *tag;
+    ParseCallback func;
+    void *data;
+};
 
-struct Functions {
-    ParseFunc       f;
-    AssignParseFunc af;
-} *funcs;
+static GHashTable *callbacks;
+static xmlDocPtr doc_config = NULL;
 
-void destshit(gpointer shit) { g_free(shit); }
+static void destfunc(struct Callback *c)
+{
+    g_free(c->tag);
+    g_free(c);
+}
 
 void parse_startup()
 {
-    reg = g_hash_table_new_full(g_str_hash, g_str_equal, destshit, destshit);
-    funcs = NULL;
+    callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+                                      (GDestroyNotify)destfunc);
 }
 
 void parse_shutdown()
 {
-    g_hash_table_destroy(reg);
+    xmlFree(doc_config);
+    doc_config = NULL;
+
+    g_hash_table_destroy(callbacks);
 }
 
-void parse_reg_section(char *section, ParseFunc func, AssignParseFunc afunc)
+void parse_register(const char *tag, ParseCallback func, void *data)
 {
-    struct Functions *f = g_new(struct Functions, 1);
-    f->f = func;
-    f->af = afunc;
-    g_hash_table_insert(reg, g_ascii_strdown(section, -1), f);
+    struct Callback *c;
+
+    if ((c = g_hash_table_lookup(callbacks, tag))) {
+        g_warning("tag '%s' already registered", tag);
+        return;
+    }
+
+    c = g_new(struct Callback, 1);
+    c->tag = g_strdup(tag);
+    c->func = func;
+    c->data = data;
+    g_hash_table_insert(callbacks, c->tag, c);
 }
 
-void parse_free_token(ParseToken *token)
+void parse_config()
 {
-    GList *it;
-
-    switch (token->type) {
-    case TOKEN_STRING:
-        g_free(token->data.string);
-        break;
-    case TOKEN_IDENTIFIER:
-        g_free(token->data.identifier);
-        break;
-    case TOKEN_LIST:
-        for (it = token->data.list; it; it = it->next) {
-            parse_free_token(it->data);
-            g_free(it->data);
+    char *path;
+    xmlNodePtr node = NULL;
+
+    xmlLineNumbersDefault(1);
+
+    path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
+    if ((doc_config = xmlParseFile(path))) {
+        node = xmlDocGetRootElement(doc_config);
+        if (!node) {
+            xmlFreeDoc(doc_config);
+            doc_config = NULL;
+            g_warning("%s is an empty document", path);
+        } else {
+            if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_config")) {
+                xmlFreeDoc(doc_config);
+                doc_config = NULL;
+                g_warning("document %s is of wrong type. root node is "
+                          "not 'openbox_config'", path);
+            }
+        }
+    }
+    g_free(path);
+    if (!doc_config) {
+        path = g_build_filename(RCDIR, "rc3", NULL);
+        if ((doc_config = xmlParseFile(path))) {
+            node = xmlDocGetRootElement(doc_config);
+            if (!node) {
+                xmlFreeDoc(doc_config);
+                doc_config = NULL;
+                g_warning("%s is an empty document", path);
+            } else {
+                if (xmlStrcasecmp(node->name,
+                                  (const xmlChar*)"openbox_config")) {
+                    xmlFreeDoc(doc_config);
+                    doc_config = NULL;
+                    g_warning("document %s is of wrong type. root node is "
+                              "not 'openbox_config'", path);
+                }
+            }
         }
-        g_list_free(token->data.list);
-        break;
-    case TOKEN_REAL:
-    case TOKEN_INTEGER:
-    case TOKEN_BOOL:
-    case TOKEN_LBRACE:
-    case TOKEN_RBRACE:
-    case TOKEN_COMMA:
-    case TOKEN_NEWLINE:
-        break;
+        g_free(path);
     }
+    if (!doc_config) {
+        g_message("unable to find a valid config file, using defaults");
+    } else {
+        parse_tree(doc_config, node->xmlChildrenNode, NULL);
+    }
+}
+
+void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
+{
+    while (node) {
+        struct Callback *c = g_hash_table_lookup(callbacks, node->name);
+
+        if (c)
+            c->func(doc, node->xmlChildrenNode, c->data);
+
+        node = node->next;
+    }
+}
+
+char *parse_string(xmlDocPtr doc, xmlNodePtr node)
+{
+    xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+    char *s = g_strdup((char*)c);
+    xmlFree(c);
+    return s;
 }
 
-void parse_set_section(char *section)
+int parse_int(xmlDocPtr doc, xmlNodePtr node)
 {
-    char *sec;
-    sec = g_ascii_strdown(section, -1);
-    funcs = g_hash_table_lookup(reg, sec);
-    g_free(sec);
+    xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+    int i = atoi((char*)c);
+    xmlFree(c);
+    return i;
 }
 
-void parse_token(ParseToken *token)
+gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
 {
-    if (funcs) {
-        if (funcs->f)
-            funcs->f(token);
-        else if (token->type != TOKEN_NEWLINE)
-            yyerror("syntax error");
+    xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+    gboolean b = FALSE;
+    if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
+        b = TRUE;
+    else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
+        b = TRUE;
+    else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
+        b = TRUE;
+    xmlFree(c);
+    return b;
+}
+
+gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
+{
+    xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+    gboolean r;
+    r = !xmlStrcasecmp(c, (const xmlChar*) val);
+    xmlFree(c);
+    return r;
+}
+
+xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
+{
+    while (node) {
+        if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
+            return node;
+        node = node->next;
+    }
+    return NULL;
+}
+
+gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
+{
+    xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+    gboolean r = FALSE;
+    if (c) {
+        *value = atoi((char*)c);
+        r = TRUE;
     }
+    xmlFree(c);
+    return r;
 }
 
-void parse_assign(char *name, ParseToken *value)
+gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
 {
-    if (funcs) {
-        if (funcs->af)
-            funcs->af(name, value);
-        else
-            yyerror("syntax error");
+    xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+    gboolean r = FALSE;
+    if (c) {
+        *value = g_strdup((char*)c);
+        r = TRUE;
     }
+    xmlFree(c);
+    return r;
+}
+
+Action *parse_action(xmlDocPtr doc, xmlNodePtr node)
+{
+    char *actname;
+    Action *act = NULL;
+    xmlNodePtr n;
+
+    if (parse_attr_string("name", node, &actname)) {
+        if ((act = action_from_string(actname))) {
+            if (act->func == action_execute || act->func == action_restart) {
+                if ((n = parse_find_node("execute", node->xmlChildrenNode)))
+                    act->data.execute.path = parse_string(doc, n);
+            } else if (act->func == action_showmenu) {
+                if ((n = parse_find_node("menu", node->xmlChildrenNode)))
+                    act->data.showmenu.name = parse_string(doc, n);
+            } else if (act->func == action_desktop) {
+                if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+                    act->data.desktop.desk = parse_int(doc, n);
+                if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+            } else if (act->func == action_send_to_desktop) {
+                if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+                    act->data.sendto.desk = parse_int(doc, n);
+                if (act->data.sendto.desk > 0) act->data.sendto.desk--;
+            } else if (act->func == action_move_relative_horz ||
+                       act->func == action_move_relative_vert ||
+                       act->func == action_resize_relative_horz ||
+                       act->func == action_resize_relative_vert) {
+                if ((n = parse_find_node("delta", node->xmlChildrenNode)))
+                    act->data.relative.delta = parse_int(doc, n);
+            } else if (act->func == action_desktop_right ||
+                       act->func == action_desktop_left ||
+                       act->func == action_desktop_up ||
+                       act->func == action_desktop_down) {
+                if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
+                    g_message("WRAP %d", parse_bool(doc, n));
+                    act->data.desktopdir.wrap = parse_bool(doc, n);
+                }
+            } else if (act->func == action_send_to_desktop_right ||
+                       act->func == action_send_to_desktop_left ||
+                       act->func == action_send_to_desktop_up ||
+                       act->func == action_send_to_desktop_down) {
+                if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
+                    act->data.sendtodir.wrap = parse_bool(doc, n);
+                if ((n = parse_find_node("follow", node->xmlChildrenNode)))
+                    act->data.sendtodir.follow = parse_bool(doc, n);
+            }
+        }
+    }
+    return act;
+}
+
+gboolean parse_attr_contains(const char *val, xmlNodePtr node,
+                             const char *name)
+{
+    xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+    gboolean r;
+    r = !xmlStrcasecmp(c, (const xmlChar*) val);
+    xmlFree(c);
+    return r;
 }
index abd5bb2d7ef718c41ba9c1a72f6e05b639ed9e83..199e8104d7d1abd81e232a97a1d308ec12bb606e 100644 (file)
@@ -1,48 +1,38 @@
 #ifndef __parse_h
 #define __parse_h
 
+#include "action.h"
+
+#include <libxml/parser.h>
 #include <glib.h>
-#ifndef NO_TAB_H
-#include "parse.tab.h"
-#endif
 
-typedef enum {
-    TOKEN_REAL       = REAL,
-    TOKEN_INTEGER    = INTEGER,
-    TOKEN_STRING     = STRING,
-    TOKEN_IDENTIFIER = IDENTIFIER,
-    TOKEN_BOOL       = BOOLEAN,
-    TOKEN_LIST,
-    TOKEN_LBRACE     = '{',
-    TOKEN_RBRACE     = '}',
-    TOKEN_COMMA      = ',',
-    TOKEN_NEWLINE    = '\n'
-} ParseTokenType;
-
-typedef struct {
-    ParseTokenType type;
-    union ParseTokenData data;
-} ParseToken;
-
-typedef void (*ParseFunc)(ParseToken *token);
-typedef void (*AssignParseFunc)(char *name, ParseToken *value);
+typedef void (*ParseCallback)(xmlDocPtr doc, xmlNodePtr node, void *data);
 
 void parse_startup();
 void parse_shutdown();
 
-/* Parse the RC file
-   found in parse.yacc
-*/
-void parse_rc();
+void parse_register(const char *tag, ParseCallback func, void *data);
+
+void parse_config();
+
+void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing);
+
+
+/* helpers */
+
+xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node);
 
-void parse_reg_section(char *section, ParseFunc func, AssignParseFunc afunc);
+char *parse_string(xmlDocPtr doc, xmlNodePtr node);
+int parse_int(xmlDocPtr doc, xmlNodePtr node);
+gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node);
 
+gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node);
+gboolean parse_attr_contains(const char *val, xmlNodePtr node,
+                             const char *name);
 
-/* Free a parsed token's allocated memory */
-void parse_free_token(ParseToken *token);
+gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value);
+gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value);
 
-/* Display an error message while parsing.
-   found in parse.yacc */
-void yyerror(char *err);
+Action *parse_action(xmlDocPtr doc, xmlNodePtr node);
 
 #endif
diff --git a/openbox/parse.l b/openbox/parse.l
deleted file mode 100644 (file)
index a7cd6c6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-%{
-#include "parse.h"
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif
-
-extern int lineno;
-%}
-
-real [-0-9][0-9]*\.[0-9]+
-integer [-0-9][0-9]*
-string \"[^"\n]*\"
-identifier [a-zA-Z][-.a-zA-Z0-9_]*
-bool ([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][fF][fF])
-
-%%
-
-^[ \t]*#.*\n /* comment */ { ++lineno; }
-^[ \t]*#.*   /* comment */
-^[ \t]*\n    /* empty lines */ { ++lineno; }
-[ \t]        /* whitespace */
-{real}       { yylval.real = atof(yytext); return REAL; }
-{integer}    { yylval.integer = atoi(yytext); return INTEGER; }
-{string}     { yylval.string = g_strdup(yytext+1); /* drop the left quote */
-               if (yylval.string[yyleng-2] != '"')
-                   yyerror("improperly terminated string on line %d");
-               else
-                   yylval.string[yyleng-2] = '\0';
-               return STRING;
-             }
-{bool}       { yylval.bool = (!g_ascii_strcasecmp("true", yytext) ||
-                              !g_ascii_strcasecmp("yes", yytext) ||
-                              !g_ascii_strcasecmp("on", yytext));
-               return BOOLEAN;
-             }
-{identifier} { yylval.identifier = g_strdup(yytext); return IDENTIFIER; }
-[{}()\[\]=,] { yylval.character = *yytext; return *yytext; }
-\n           { yylval.character = *yytext; return *yytext; }
-.            { return INVALID; }
-
-%%
-
-int yywrap() {
-    return 1;
-}
diff --git a/openbox/parse.y b/openbox/parse.y
deleted file mode 100644 (file)
index 7e92efd..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-%{
-#include <glib.h>
-#ifdef HAVE_STDIO_H
-#  include <stdio.h>
-#endif
-
-%}
-
-%union ParseTokenData {
-    float real;
-    int integer;
-    char *string;
-    char *identifier;
-    gboolean bool;
-    char character;
-    GList *list;
-}
-
-%{
-#define NO_TAB_H
-#include "parse.h"
-#undef NO_TAB_H
-
-extern int yylex();
-extern int yyparse();
-void yyerror(char *err);
-
-extern int lineno;
-extern FILE *yyin;
-
-static char *path;
-static ParseToken t;
-
-/* in parse.c */
-void parse_token(ParseToken *token);
-void parse_assign(char *name, ParseToken *token);
-void parse_set_section(char *section);
-%}
-
-%token <real> REAL
-%token <integer> INTEGER
-%token <string> STRING
-%token <identifier> IDENTIFIER
-%token <bool> BOOLEAN
-%token <character> '('
-%token <character> ')'
-%token <character> '{'
-%token <character> '}'
-%token <character> '='
-%token <character> ','
-%token <character> '\n'
-%token INVALID
-
-%type <list> list
-%type <list> listtokens
-
-%%
-
-sections:
-  | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
-    { ++lineno; } lines
-  ;
-
-lines:
-  | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
-    { ++lineno; }
-  | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
-    { ++lineno; }
-  ;
-
-tokens:
-    tokens token { parse_token(&t); }
-  | token        { parse_token(&t); }
-  ;
-
-token:
-    REAL       { t.type = TOKEN_REAL; t.data.real = $1; }
-  | INTEGER    { t.type = TOKEN_INTEGER; t.data.integer = $1; }
-  | STRING     { t.type = TOKEN_STRING; t.data.string = $1; }
-  | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; }
-  | BOOLEAN    { t.type = TOKEN_BOOL; t.data.bool = $1; }
-  | list       { t.type = TOKEN_LIST; t.data.list = $1; }
-  | '{'        { t.type = $1; t.data.character = $1; }
-  | '}'        { t.type = $1; t.data.character = $1; }
-  | ','        { t.type = $1; t.data.character = $1; }
-  ;
-
-list:
-    '(' listtokens ')' { $$ = $2; }
-  ;
-
-listtokens:
-    listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1);
-                           nt->type = t.type;
-                           nt->data = t.data;
-                           $$ = g_list_append($1, nt);
-                         }
-  | listtoken            { ParseToken *nt = g_new(ParseToken, 1);
-                           nt->type = t.type;
-                           nt->data = t.data;
-                           $$ = g_list_append(NULL, nt);
-                         }
-  ;
-
-listtoken:
-    REAL       { t.type = TOKEN_REAL; t.data.real = $1; }
-  | INTEGER    { t.type = TOKEN_INTEGER; t.data.integer = $1; }
-  | STRING     { t.type = TOKEN_STRING; t.data.string = $1; }
-  | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; }
-  | BOOLEAN    { t.type = TOKEN_BOOL; t.data.bool = $1; }
-  | list       { t.type = TOKEN_LIST; t.data.list = $1; }
-  | '{'        { t.type = $1; t.data.character = $1; }
-  | '}'        { t.type = $1; t.data.character = $1; }
-  | ','        { t.type = $1; t.data.character = $1; }
-  ;
-
-
-%%
-
-int lineno;
-
-void yyerror(char *err) {
-    g_message("%s:%d: %s", path, lineno, err);
-}
-
-void parse_rc()
-{
-    /* try the user's rc */
-    path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
-    if ((yyin = fopen(path, "r")) == NULL) {
-        g_free(path);
-        /* try the system wide rc */
-        path = g_build_filename(RCDIR, "rc3", NULL);
-        if ((yyin = fopen(path, "r")) == NULL) {
-            g_warning("No rc2 file found!");
-            g_free(path);
-            return;
-        }
-    }
-
-    lineno = 1;
-
-    yyparse();
-
-    g_free(path);
-}
index 4796307ab40545d9f4c5c991fc45b1de7a2d48de..b23259d621993cb7ddaab1780ff4c94596de4005 100644 (file)
@@ -2,7 +2,8 @@ plugindir=$(libdir)/openbox/plugins
 
 SUBDIRS = keyboard mouse placement menu
 
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
+         $(XML_CFLAGS)  @CPPFLAGS@ \
 -DPLUGINDIR=\"$(plugindir)\"
 
 INCLUDES=-I..
index ffcd104b90d37f9cf985db773bb42c8b52a8f03a..4b1e850acd172e3057a86f6ab619359e44914732 100644 (file)
@@ -1,6 +1,7 @@
 plugindir=$(libdir)/openbox/plugins
 
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
+         $(XML_CFLAGS) @CPPFLAGS@ \
          -DG_LOG_DOMAIN=\"Plugin-Keyboard\"
 
 INCLUDES=-I../..
@@ -8,7 +9,7 @@ INCLUDES=-I../..
 plugin_LTLIBRARIES=keyboard.la
 
 keyboard_la_LDFLAGS=-module -avoid-version
-keyboard_la_SOURCES=keyboard.c keyparse.c translate.c tree.c
+keyboard_la_SOURCES=keyboard.c translate.c tree.c
 
 noinst_HEADERS=keyboard.h keyparse.h translate.h tree.h
 
index 5991606adc52e8514179589653214f896b87cb0a..d1d93241a77e5422ace3440325179aa475f3b341 100644 (file)
@@ -4,17 +4,74 @@
 #include "kernel/event.h"
 #include "kernel/grab.h"
 #include "kernel/action.h"
+#include "kernel/prop.h"
 #include "kernel/parse.h"
 #include "kernel/timer.h"
 #include "tree.h"
 #include "keyboard.h"
-#include "keyparse.h"
 #include "translate.h"
 #include <glib.h>
 
+/*
+
+<keybind key="C-x">
+  <action name="ChangeDesktop">
+    <desktop>3</desktop>
+  </action>
+</keybind>
+
+*/
+
+static void parse_key(xmlDocPtr doc, xmlNodePtr node, GList *keylist)
+{
+    char *key;
+    Action *action;
+    xmlNodePtr n, nact;
+    GList *it;
+
+    n = parse_find_node("keybind", node);
+    while (n) {
+        if (parse_attr_string("key", n, &key)) {
+            keylist = g_list_append(keylist, key);
+
+            parse_key(doc, n->xmlChildrenNode, keylist);
+
+            it = g_list_last(keylist);
+            g_free(it->data);
+            keylist = g_list_delete_link(keylist, it);
+        }
+        n = parse_find_node("keybind", n->next);
+    }
+    if (keylist) {
+        nact = parse_find_node("action", node);
+        while (nact) {
+            if ((action = parse_action(doc, nact))) {
+                /* validate that its okay for a key binding */
+                if (action->func == action_moveresize &&
+                    action->data.moveresize.corner !=
+                    prop_atoms.net_wm_moveresize_move_keyboard &&
+                    action->data.moveresize.corner !=
+                    prop_atoms.net_wm_moveresize_size_keyboard) {
+                    action_free(action);
+                    action = NULL;
+                }
+
+                if (action)
+                    kbind(keylist, action);
+            }
+            nact = parse_find_node("action", nact->next);
+        }
+    }
+}
+
+static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d)
+{
+    parse_key(doc, node, NULL);
+}
+
 void plugin_setup_config()
 {
-    parse_reg_section("keyboard", keyparse, NULL);
+    parse_register("keyboard", parse_xml, NULL);
 }
 
 KeyBindingTree *firstnode = NULL;
@@ -160,6 +217,7 @@ static void event(ObEvent *e, void *foo)
                                 act->data.cycle.cancel = FALSE;
                             }
 
+                            act->data.any.c = focus_client;
                             act->func(&act->data);
 
                             if (act->func == action_cycle_windows &&
index e4c897d53d30fcdfd3890e965541d7fd940e589a..3d4d6b9edd8657b3c736603378a6c832e8c3810a 100644 (file)
@@ -1,6 +1,7 @@
 plugindir=$(libdir)/openbox/plugins
 
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
+         $(XML_CFLAGS)  @CPPFLAGS@ \
          -DG_LOG_DOMAIN=\"Plugin-Mouse\"
 
 INCLUDES=-I../..
@@ -8,9 +9,9 @@ INCLUDES=-I../..
 plugin_LTLIBRARIES=mouse.la
 
 mouse_la_LDFLAGS=-module -avoid-version
-mouse_la_SOURCES=mouse.c mouseparse.c translate.c
+mouse_la_SOURCES=mouse.c translate.c
 
-noinst_HEADERS=mouse.h mouseparse.h translate.h
+noinst_HEADERS=mouse.h translate.h
 
 MAINTAINERCLEANFILES=Makefile.in
 
index e39720cbb022961b448d0bbf8e74ce4b00ec1c18..0bfe602c7cb936647785a9a78d98b70b1356097c 100644 (file)
@@ -9,38 +9,97 @@
 #include "kernel/frame.h"
 #include "translate.h"
 #include "mouse.h"
-#include "mouseparse.h"
 #include <glib.h>
 
 static int threshold;
 static int dclicktime;
 
-static void parse_assign(char *name, ParseToken *value)
+/*
+
+<context name="Titlebar"> 
+  <mousebind button="Left" action="Press">
+    <action name="Raise"></action>
+  </mousebind>
+</context>
+
+*/
+
+static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "dragthreshold")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            if (value->data.integer >= 0)
-                threshold = value->data.integer;
-        }
-    } else if (!g_ascii_strcasecmp(name, "doubleclicktime")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            if (value->data.integer >= 0)
-                dclicktime = value->data.integer;
+    xmlNodePtr n, nbut, nact;
+    char *buttonstr;
+    char *contextstr;
+    MouseAction mact;
+    Action *action;
+
+    if ((n = parse_find_node("dragThreshold", node)))
+        threshold = parse_int(doc, n);
+    if ((n = parse_find_node("doubleClickTime", node)))
+        dclicktime = parse_int(doc, n);
+
+    n = parse_find_node("context", node);
+    while (n) {
+        if (!parse_attr_string("name", n, &contextstr))
+            goto next_n;
+        nbut = parse_find_node("mousebind", n->xmlChildrenNode);
+        while (nbut) {
+            if (!parse_attr_string("button", nbut, &buttonstr))
+                goto next_nbut;
+            if (parse_attr_contains("press", nbut, "action"))
+                mact = MouseAction_Press;
+            else if (parse_attr_contains("release", nbut, "action"))
+                mact = MouseAction_Release;
+            else if (parse_attr_contains("click", nbut, "action"))
+                mact = MouseAction_Click;
+            else if (parse_attr_contains("doubleclick", nbut,"action"))
+                mact = MouseAction_DClick;
+            else if (parse_attr_contains("drag", nbut, "action"))
+                mact = MouseAction_Motion;
+            else
+                goto next_nbut;
+            nact = parse_find_node("action", nbut->xmlChildrenNode);
+            while (nact) {
+                if ((action = parse_action(doc, nact))) {
+                    /* validate that its okay for a mouse binding*/
+                    if (mact == MouseAction_Motion) {
+                        if (action->func != action_moveresize ||
+                            action->data.moveresize.corner ==
+                            prop_atoms.net_wm_moveresize_move_keyboard ||
+                            action->data.moveresize.corner ==
+                            prop_atoms.net_wm_moveresize_size_keyboard) {
+                            action_free(action);
+                            action = NULL;
+                        }
+                    } else {
+                        if (action->func == action_moveresize &&
+                            action->data.moveresize.corner !=
+                            prop_atoms.net_wm_moveresize_move_keyboard &&
+                            action->data.moveresize.corner !=
+                            prop_atoms.net_wm_moveresize_size_keyboard) {
+                            action_free(action);
+                            action = NULL;
+                        }
+                    }
+                    if (action)
+                        mbind(buttonstr, contextstr, mact, action);
+                }
+                nact = parse_find_node("action", nact->next);
+            }
+            g_free(buttonstr);
+        next_nbut:
+            nbut = parse_find_node("mousebind", nbut->next);
         }
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+        g_free(contextstr);
+    next_n:
+        n = parse_find_node("context", n->next);
+    }
 }
 
 void plugin_setup_config()
 {
     threshold = 3;
     dclicktime = 200;
-    parse_reg_section("mouse", mouseparse, parse_assign);
+    parse_register("mouse", parse_xml, NULL);
 }
 
 /* Array of GSList*s of PointerBinding*s. */
@@ -240,11 +299,11 @@ static void event(ObEvent *e, void *foo)
                                 e->data.x.e->xbutton.window);
         if (e->data.x.e->xbutton.button == button) {
             /* clicks are only valid if its released over the window */
-            int junk;
+            int junk1, junk2;
             Window wjunk;
             guint ujunk, b, w, h;
             XGetGeometry(ob_display, e->data.x.e->xbutton.window,
-                         &wjunk, &junk, &junk, &w, &h, &b, &ujunk);
+                         &wjunk, &junk1, &junk2, &w, &h, &b, &ujunk);
             if (e->data.x.e->xbutton.x >= (signed)-b &&
                 e->data.x.e->xbutton.y >= (signed)-b &&
                 e->data.x.e->xbutton.x < (signed)(w+b) &&
index 6b32800873a0cd69186b4739225b4dc6fe3b7cf3..762f5af809a0be1d5926a5ddb3dbfe2a98208317 100644 (file)
@@ -1,6 +1,7 @@
 plugindir=$(libdir)/openbox/plugins
 
-CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \
+CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) $(GL_CFLAGS) \
+         $(XML_CFLAGS) @CPPFLAGS@ \
          -DG_LOG_DOMAIN=\"Plugin-Placement\"
 
 INCLUDES=-I../..
index ea3d60dfb5cf9a7b2d2d0b7d7b438390946dd543..9d932b9edfbe7e0ca292738f298f91ae0d6782ce 100644 (file)
@@ -3,41 +3,47 @@
 #include "kernel/frame.h"
 #include "kernel/client.h"
 #include "kernel/screen.h"
+#include "kernel/parse.h"
+#include "history.h"
 #include <glib.h>
 #include <string.h>
 #ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
 #endif
 
+#define PLACED        (1 << 0)
+
+#define HAVE_POSITION (1 << 1)
+#define HAVE_SIZE     (1 << 2)
+#define HAVE_DESKTOP  (1 << 3)
+
 struct HistoryItem {
     char *name;
     char *class;
     char *role;
-    int x;
-    int y;
-    gboolean placed;
+
+    int flags;
+
+    int x, y;
+    int w, h;
+    guint desk;
 };
 
-static GSList *history = NULL;
+static GSList *history_list = NULL;
 static char *history_path = NULL;
 
-static struct HistoryItem *find_history(Client *c)
+static struct HistoryItem *history_find(const char *name, const char *class,
+                                 const char *role)
 {
     GSList *it;
     struct HistoryItem *hi = NULL;
 
     /* find the client */
-    for (it = history; it != NULL; it = it->next) {
+    for (it = history_list; it != NULL; it = it->next) {
         hi = it->data;
-        g_assert(hi->name != NULL);
-        g_assert(hi->class != NULL);
-        g_assert(hi->role != NULL);
-        g_assert(c->name != NULL);
-        g_assert(c->class != NULL);
-        g_assert(c->role != NULL);
-        if (!strcmp(hi->name, c->name) &&
-            !strcmp(hi->class, c->class) &&
-            !strcmp(hi->role, c->role))
+        if (!g_utf8_collate(hi->name, name) &&
+            !g_utf8_collate(hi->class, class) &&
+            !g_utf8_collate(hi->role, role))
             return hi;
     }
     return NULL;
@@ -46,57 +52,65 @@ static struct HistoryItem *find_history(Client *c)
 gboolean place_history(Client *c)
 {
     struct HistoryItem *hi;
-    int x, y;
+    int x, y, w, h;
 
-    hi = find_history(c);
+    hi = history_find(c->name, c->class, c->role);
 
-    if (hi != NULL && !hi->placed) {
-        hi->placed = TRUE;
+    if (hi && !(hi->flags & PLACED)) {
+        hi->flags |= PLACED;
         if (ob_state != State_Starting) {
-            x = hi->x;
-            y = hi->y;
-
-            frame_frame_gravity(c->frame, &x, &y); /* get where the client
-                                                      should be */
-            client_configure(c, Corner_TopLeft, x, y,
-                             c->area.width, c->area.height,
-                             TRUE, TRUE);
+            if (hi->flags & HAVE_POSITION ||
+                hi->flags & HAVE_SIZE) {
+                if (hi->flags & HAVE_POSITION) {
+                    x = hi->x;
+                    y = hi->y;
+                    /* get where the client should be */
+                    frame_frame_gravity(c->frame, &x, &y);
+                } else {
+                    x = c->area.x;
+                    y = c->area.y;
+                }
+                if (hi->flags & HAVE_SIZE) {
+                    w = hi->w * c->size_inc.width;
+                    h = hi->h * c->size_inc.height;
+                } else {
+                    w = c->area.width;
+                    h = c->area.height;
+                }
+                client_configure(c, Corner_TopLeft, x, y, w, h,
+                                 TRUE, TRUE);
+            }
+            if (hi->flags & HAVE_DESKTOP) {
+                client_set_desktop(c, hi->desk, FALSE);
+            }
         }
-        return TRUE;
+        return hi->flags & HAVE_POSITION;
     }
 
     return FALSE;
 }
 
-static void strip_tabs(char *s)
-{
-    while (*s != '\0') {
-        if (*s == '\t')
-            *s = ' ';
-        ++s;
-    }
-}
-
 static void set_history(Client *c)
 {
     struct HistoryItem *hi;
 
-    hi = find_history(c);
+    hi = history_find(c->name, c->class, c->role);
 
     if (hi == NULL) {
         hi = g_new(struct HistoryItem, 1);
-        history = g_slist_append(history, hi);
+        history_list = g_slist_append(history_list, hi);
         hi->name = g_strdup(c->name);
-        strip_tabs(hi->name);
         hi->class = g_strdup(c->class);
-        strip_tabs(hi->class);
         hi->role = g_strdup(c->role);
-        strip_tabs(hi->role);
+        hi->flags = HAVE_POSITION;
+    }
+
+    if (hi->flags & HAVE_POSITION) {
+        hi->x = c->frame->area.x;
+        hi->y = c->frame->area.y;
     }
 
-    hi->x = c->frame->area.x;
-    hi->y = c->frame->area.y;
-    hi->placed = FALSE;
+    hi->flags &= ~PLACED;
 }
 
 static void event(ObEvent *e, void *foo)
@@ -106,104 +120,140 @@ static void event(ObEvent *e, void *foo)
     set_history(e->data.c.client);
 }
 
+/*
+
+<entry name="name" class="class" role="role">
+  <x>0</x>
+  <y>0</y>
+  <width>300</width>
+  <height>200</height>
+  <desktop>1</desktop>
+</entry>
+
+*/
+
 static void save_history()
 {
-    GError *err = NULL;
-    GIOChannel *io;
-    GString *buf;
+    xmlDocPtr doc;
+    xmlNodePtr root, node;
+    char *s;
     GSList *it;
-    struct HistoryItem *hi;
-    gsize ret;
-
-    io = g_io_channel_new_file(history_path, "w", &err);
-    if (io != NULL) {
-        for (it = history; it != NULL; it = it->next) {
-            hi = it->data;
-            buf = g_string_sized_new(0);
-            buf=g_string_append(buf, hi->name);
-            g_string_append_c(buf, '\t');
-            buf=g_string_append(buf, hi->class);
-            g_string_append_c(buf, '\t');
-            buf=g_string_append(buf, hi->role);
-            g_string_append_c(buf, '\t');
-            g_string_append_printf(buf, "%d", hi->x);
-            buf=g_string_append_c(buf, '\t');
-            g_string_append_printf(buf, "%d", hi->y);
-            buf=g_string_append_c(buf, '\n');
-            if (g_io_channel_write_chars(io, buf->str, buf->len, &ret, &err) !=
-                G_IO_STATUS_NORMAL)
-                break;
-            g_string_free(buf, TRUE);
+
+    doc = xmlNewDoc(NULL);
+    root = xmlNewNode(NULL, (const xmlChar*) "openbox_history");
+    xmlDocSetRootElement(doc, root);
+
+    for (it = history_list; it; it = g_slist_next(it)) {
+        struct HistoryItem *hi = it->data;
+        g_message("adding %s", hi->name);
+        node = xmlNewChild(root, NULL, (const xmlChar*) "entry", NULL);
+        xmlNewProp(node, (const xmlChar*) "name", (const xmlChar*) hi->name);
+        xmlNewProp(node, (const xmlChar*) "class", (const xmlChar*) hi->class);
+        xmlNewProp(node, (const xmlChar*) "role", (const xmlChar*) hi->role);
+        if (hi->flags & HAVE_POSITION) {
+            s = g_strdup_printf("%d", hi->x);
+            xmlNewTextChild(node, NULL,
+                            (const xmlChar*) "x", (const xmlChar*) s);
+            g_free(s);
+            s = g_strdup_printf("%d", hi->y);
+            xmlNewTextChild(node, NULL,
+                            (const xmlChar*) "y", (const xmlChar*) s);
+            g_free(s);
+        }
+        if (hi->flags & HAVE_SIZE) {
+            s = g_strdup_printf("%d", hi->w);
+            xmlNewTextChild(node, NULL,
+                            (const xmlChar*) "width", (const xmlChar*) s);
+            g_free(s);
+            s = g_strdup_printf("%d", hi->h);
+            xmlNewTextChild(node, NULL,
+                            (const xmlChar*) "height", (const xmlChar*) s);
+            g_free(s);
+        }
+        if (hi->flags & HAVE_DESKTOP) {
+            s = g_strdup_printf("%d", hi->desk < 0 ? hi->desk : hi->desk + 1);
+            xmlNewTextChild(node, NULL,
+                            (const xmlChar*) "desktop", (const xmlChar*) s);
+            g_free(s);
         }
-        g_io_channel_unref(io);
     }
+
+    xmlIndentTreeOutput = 1;
+    xmlSaveFormatFile(history_path, doc, 1);
+
+    xmlFree(doc);
 }
 
 static void load_history()
 {
-    GError *err = NULL;
-    GIOChannel *io;
-    char *buf = NULL;
-    char *b, *c;
-    struct HistoryItem *hi = NULL;
-
-    io = g_io_channel_new_file(history_path, "r", &err);
-    if (io != NULL) {
-        while (g_io_channel_read_line(io, &buf, NULL, NULL, &err) ==
-               G_IO_STATUS_NORMAL) {
-            hi = g_new0(struct HistoryItem, 1);
-
-            b = buf;
-            if ((c = strchr(b, '\t')) == NULL) break;
-            *c = '\0';
-            hi->name = g_strdup(b);
-
-            b = c + 1;
-            if ((c = strchr(b, '\t')) == NULL) break;
-            *c = '\0';
-            hi->class = g_strdup(b);
-
-            b = c + 1;
-            if ((c = strchr(b, '\t')) == NULL) break;
-            *c = '\0';
-            hi->role = g_strdup(b);
-
-            b = c + 1;
-            if ((c = strchr(b, '\t')) == NULL) break;
-            *c = '\0';
-            hi->x = atoi(b);
-
-            b = c + 1;
-            if ((c = strchr(b, '\n')) == NULL) break;
-            *c = '\0';
-            hi->y = atoi(b);
-
-            hi->placed = FALSE;
-
-            g_free(buf);
-            buf = NULL;
+    xmlDocPtr doc;
+    xmlNodePtr node, n;
+    char *name;
+    char *class;
+    char *role;
+    struct HistoryItem *hi;
 
-            history = g_slist_append(history, hi);
-            hi = NULL;
-        }
-        g_io_channel_unref(io);
+    if (!(doc = xmlParseFile(history_path)))
+        return;
+    if (!(node = xmlDocGetRootElement(doc))) {
+        xmlFreeDoc(doc);
+        doc = NULL;
+        return;
+    }
+    if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_history")) {
+        xmlFreeDoc(doc);
+        doc = NULL;
+        return;
     }
-        
-    g_free(buf);
 
-    if (hi != NULL) {
-        g_free(hi->name);
-        g_free(hi->class);
-        g_free(hi->role);
+    node = parse_find_node("entry", node->xmlChildrenNode);
+    while (node) {
+        name = class = role = NULL;
+        if (parse_attr_string("name", node, &name) &&
+            parse_attr_string("class", node, &class) &&
+            parse_attr_string("role", node, &role)) {
+
+            hi = history_find(name, class, role);
+            if (!hi) {
+                hi = g_new(struct HistoryItem, 1);
+                hi->name = g_strdup(name);
+                hi->class = g_strdup(class);
+                hi->role = g_strdup(role);
+                hi->flags = 0;
+            }
+            if ((n = parse_find_node("x", node->xmlChildrenNode))) {
+                hi->x = parse_int(doc, n);
+                if ((n = parse_find_node("y", node->xmlChildrenNode))) {
+                    hi->y = parse_int(doc, n);
+                    hi->flags |= HAVE_POSITION;
+                }
+            }
+            if ((n = parse_find_node("width", node->xmlChildrenNode))) {
+                hi->w = parse_int(doc, n);
+                if ((n = parse_find_node("height", node->xmlChildrenNode))) {
+                    hi->h = parse_int(doc, n);
+                    hi->flags |= HAVE_SIZE;
+                }
+            }
+            if ((n = parse_find_node("desktop", node->xmlChildrenNode))) {
+                hi->desk = parse_int(doc, n);
+                if (hi->desk > 0) --hi->desk;
+                hi->flags |= HAVE_DESKTOP;
+            }
+
+            history_list = g_slist_append(history_list, hi);
+        }
+        g_free(name); g_free(class); g_free(role);
+        node = parse_find_node("entry", node->next);
     }
-    g_free(hi);
+    xmlFree(doc);
 }
 
 void history_startup()
 {
     char *path;
 
-    history = NULL;
+    history_list = NULL;
 
     path = g_build_filename(g_get_home_dir(), ".openbox", "history", NULL);
     history_path = g_strdup_printf("%s.%d", path, ob_screen);
@@ -219,9 +269,14 @@ void history_shutdown()
     GSList *it;
 
     save_history(); /* save to the historydb file */
-    for (it = history; it != NULL; it = it->next)
-        g_free(it->data);
-    g_slist_free(history);
+    for (it = history_list; it != NULL; it = it->next) {
+        struct HistoryItem *hi = it->data;
+        g_free(hi->name);
+        g_free(hi->class);
+        g_free(hi->role);
+        g_free(hi);
+    }
+    g_slist_free(history_list);
 
     dispatch_register(0, (EventHandler)event, NULL);
 
index 48a29c3e9bd93962a0c3e5b1fcc899a625d2f9b8..385717696e49db4b3cf4c62c4a4fc0951af5a47c 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __plugin_placement_history_h
 #define __plugin_placement_history_h
 
-#include "../../kernel/client.h"
+#include "kernel/client.h"
 #include <glib.h>
 
 void history_startup();
index 23ffbb5d9a47929b6280df8c3030f9e130c8da4e..dd818970b0fef6b498be005a507bbb549607fe90 100644 (file)
@@ -9,23 +9,19 @@
 
 static gboolean history;
 
-static void parse_assign(char *name, ParseToken *value)
+static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if  (!g_ascii_strcasecmp(name, "remember")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else
-            history = value->data.bool;
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("remember", node)))
+        history = parse_bool(doc, n);
 }
 
 void plugin_setup_config()
 {
     history = TRUE;
 
-    parse_reg_section("placement", NULL, parse_assign);
+    parse_register("placement", parse_xml, NULL);
 }
 
 static void place_random(Client *c)
index bafd362c0ec8c62a5cf77a204898d0ff6874b1de..ee6f6e1e6c5794ce5b9d1f1d555dcbae17ed7a65 100644 (file)
@@ -9,23 +9,14 @@
 static int resistance;
 static gboolean resist_windows;
 
-static void parse_assign(char *name, ParseToken *value)
+static void parse_xml(xmlDocPtr doc, xmlNodePtr node, void *d)
 {
-    if (!g_ascii_strcasecmp(name, "strength")) {
-        if (value->type != TOKEN_INTEGER)
-            yyerror("invalid value");
-        else {
-            if (value->data.integer >= 0)
-                resistance = value->data.integer;
-        }
-    } else if  (!g_ascii_strcasecmp(name, "windows")) {
-        if (value->type != TOKEN_BOOL)
-            yyerror("invalid value");
-        else
-            resist_windows = value->data.bool;
-    } else
-        yyerror("invalid option");
-    parse_free_token(value);
+    xmlNodePtr n;
+
+    if ((n = parse_find_node("strength", node)))
+        resistance = parse_int(doc, n);
+    if ((n = parse_find_node("windows", node)))
+        resist_windows = parse_bool(doc, n);
 }
 
 void plugin_setup_config()
@@ -33,7 +24,7 @@ void plugin_setup_config()
     resistance = 10;
     resist_windows = TRUE;
 
-    parse_reg_section("resistance", NULL, parse_assign);
+    parse_register("resistance", parse_xml, NULL);
 }
 
 static void resist_move(Client *c, int *x, int *y)
This page took 0.079899 seconds and 4 git commands to generate.