Bladeren bron

libraries plugins aktuelles 3.12 image mit qt 5.7

Reinhard Russinger 7 jaren geleden
bovenliggende
commit
12c69cb27a
55 gewijzigde bestanden met toevoegingen van 3452 en 727 verwijderingen
  1. 3 0
      Config.in
  2. 33 0
      GfA-buildroot-add-plugins-libraries-change-crosscompile-command.patch
  3. 1 0
      MakeBuildrootEnv.sh
  4. 1 1
      board/GfA/Display001/BUILD
  5. 59 25
      board/GfA/Display001/Display001.dts
  6. 1 1
      board/GfA/Display001/Display001_10.dts
  7. 1 1
      board/GfA/Display001/Display001_4.dts
  8. 1 1
      board/GfA/Display001/Display001_4_nopruss.dts
  9. 1 1
      board/GfA/Display001/Display001_7.dts
  10. 1 1
      board/GfA/Display001/Display001_7_bitbang.dts
  11. 1 1
      board/GfA/Display001/Display001_7_gain1.dts
  12. 1 1
      board/GfA/Display001/Display001_7_i2c2.dts
  13. 1 1
      board/GfA/Display001/Display001_rru.dts
  14. BIN
      board/GfA/Display001/rootfs/usr/lib/qt/plugins/platforminputcontexts/libFreeVirtualKeyboard.so
  15. BIN
      board/GfA/Display001/rootfs/usr/qml/ApplicationLauncher/libApplicationLauncher.so
  16. 0 3
      board/GfA/Display001/rootfs/usr/qml/ApplicationLauncher/qmldir
  17. BIN
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/FontAwesome.otf
  18. 0 263
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/InputPanel.qml
  19. 0 149
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyButton.qml
  20. 0 191
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyModel.qml
  21. 0 81
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyPopup.qml
  22. 0 2
      board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/qmldir
  23. BIN
      board/GfA/Display001/rootfs/usr/qml/gfa/plugins/qml/libSqlDatabase.so
  24. 0 4
      board/GfA/Display001/rootfs/usr/qml/gfa/plugins/qml/qmldir
  25. 6 0
      configs/Display001_3.12.30_defconfig
  26. 6 0
      package/libgfaipc/Config.in
  27. 24 0
      package/libgfaipc/libgfaipc.mk
  28. 55 0
      package/libgfaipc/src/Makefile
  29. 33 0
      package/libgfaipc/src/defines.h
  30. 36 0
      package/libgfaipc/src/gfaipc.h
  31. 333 0
      package/libgfaipc/src/ipcshm.cpp
  32. 87 0
      package/libgfaipc/src/locmtx.cpp
  33. 222 0
      package/libgfaipc/src/mutex.cpp
  34. 66 0
      package/libgfaipc/src/mutex.h
  35. 459 0
      package/libgfaipc/src/sema.cpp
  36. 113 0
      package/libgfaipc/src/sema.h
  37. 378 0
      package/libgfaipc/src/shm.cpp
  38. 73 0
      package/libgfaipc/src/shm.h
  39. 299 0
      package/libgfaipc/src/shmrot.cpp
  40. 99 0
      package/libgfaipc/src/shmrot.h
  41. 79 0
      package/libgfaipc/src/shmstrvar.cpp
  42. 69 0
      package/libgfaipc/src/uuid.c
  43. 49 0
      package/libgfaipc/src/uuid.h
  44. 6 0
      package/libgfatimer/Config.in
  45. 24 0
      package/libgfatimer/libgfatimer.mk
  46. 52 0
      package/libgfatimer/src/Makefile
  47. 69 0
      package/libgfatimer/src/gfatimer.cpp
  48. 77 0
      package/libgfatimer/src/gfatimer.h
  49. 66 0
      package/libgfatimer/src/mutex.h
  50. 421 0
      package/libgfatimer/src/timer.cpp
  51. 74 0
      package/libgfatimer/src/timer.h
  52. 49 0
      package/libgfatimer/src/uuid.h
  53. 4 0
      package/qmlplugins/Config.in
  54. BIN
      package/qmlplugins/GFAQMLPlugins.tar.gz
  55. 19 0
      package/qmlplugins/qmlplugins.mk

+ 3 - 0
Config.in

@@ -1,4 +1,7 @@
 source "$BR2_EXTERNAL_GFA_Display001_PATH/package/wt/Config.in"
 source "$BR2_EXTERNAL_GFA_Display001_PATH/package/network_interfaces_script/Config.in"
 source "$BR2_EXTERNAL_GFA_Display001_PATH/package/gfa_addons/Config.in"
+source "$BR2_EXTERNAL_GFA_Display001_PATH/package/libgfaipc/Config.in"
+source "$BR2_EXTERNAL_GFA_Display001_PATH/package/libgfatimer/Config.in"
+source "$BR2_EXTERNAL_GFA_Display001_PATH/package/qmlplugins/Config.in"
 

+ 33 - 0
GfA-buildroot-add-plugins-libraries-change-crosscompile-command.patch

@@ -0,0 +1,33 @@
+diff --git a/CrossCompile.sh b/CrossCompile.sh
+index a2feabcbee..0d659414b4 100755
+--- a/CrossCompile.sh
++++ b/CrossCompile.sh
+@@ -10,19 +10,19 @@ TOOLCHAIN=`grep BR2_HOST_DIR .config | awk -F\= -F\" '{print $2}'`
+ echo $TOOLCHAIN
+ 
+ if [[ $TOOLCHAIN = *\$\(BASE_DIR\)* ]]; then
+-	export SYSROOT=`readlink -f $CMDDIR`/output/host/usr/bin/
++	export SYSROOTBIN=`readlink -f $CMDDIR`/output/host/usr/bin/
+ else
+-	export SYSROOT=$TOOLCHAIN/usr/bin
++	export SYSROOTBIN=$TOOLCHAIN/usr/bin
+ fi
+ 
+-export PATH=$PATH:$SYSROOT
++export PATH=$PATH:$SYSROOTBIN
+ 
+ export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
+ export ARCH=arm
+ export KERNELDIR=`pwd`/output/build/linux-7f280334068b7c875ade51f8f3921ab311f0c824
+ export BB_KERNEL_SOURCES=$KERNELDIR
+-export SYSROOTARM=`grep BR2_HOST_DIR .config | awk -F\= -F\" '{print $2}'`/usr/arm-buildroot-linux-gnueabihf/sysroot
+-export CC_FULLPATH="${SYSROOT}${CROSS_COMPILE}"
++export SYSROOT=`grep BR2_HOST_DIR .config | awk -F\= -F\" '{print $2}'`/usr/arm-buildroot-linux-gnueabihf/sysroot
++export CC_FULLPATH="${SYSROOTBIN}${CROSS_COMPILE}"
+ #--- gnupru
+ export PASM=pasm
+ ##export PSYSROOT=/home/ru/pru/pru-gcc/bin
+diff --git a/package/qt5/qt5tools/qt5tools.hash b/package/qt5/qt5tools/qt5tools.hash__
+similarity index 100%
+rename from package/qt5/qt5tools/qt5tools.hash
+rename to package/qt5/qt5tools/qt5tools.hash__

+ 1 - 0
MakeBuildrootEnv.sh

@@ -19,6 +19,7 @@ patch -p1 < ../GfA/GfA-buildroot_qt57-qt5quickcontrols_mk.patch
 patch -p1 < ../GfA/GfA-buildroot_qt57-qt5quickcontrols2_mk.patch
 patch -p1 < ../GfA/GfA-buildroot_SetRightDisplayResolution_OnUpdate.patch
 patch -p1 < ../GfA/GfA-buildroot_SetRightDisplayResolution_OnUpdate_add5_7inch_display.patch
+patch -p1 < ../GfA/GfA-buildroot-add-plugins-libraries-change-crosscompile-command.patch
 #
 chmod a+x *.sh
 cp ../GfA/configs/* ./configs

+ 1 - 1
board/GfA/Display001/BUILD

@@ -1 +1 @@
-372
+377

+ 59 - 25
board/GfA/Display001/Display001.dts

@@ -111,6 +111,12 @@
                         >;
                 };
 
+                i2c_gpio_pins: pinmux_i2c_gpio_pins {
+                        pinctrl-single,pins = <
+                                0x150 (PIN_INPUT | MUX_MODE7)    /* spi0_sclk.i2c2_sda */
+                                0x154 (PIN_INPUT | MUX_MODE7)    /* spi0_d0.i2c2_scl */
+                        >;
+                };
 
                spi1_pins: pinmux_spi1_pins {
                         pinctrl-single,pins = <
@@ -177,8 +183,8 @@
 		profibus_pins_default: pinmux_profibus_pins_default {
                         pinctrl-single,pins = < 
                         0x158 (PIN_INPUT_PULLUP | MUX_MODE4)    /* spi0_d1.uart0_rxd */
-                        0x15c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* spi0_cs0.uart0_txd */ 
-			0x1a4 (PIN_OUTPUT | MUX_MODE7)		/* mcasp0_fsr.gpio3.19 */
+                        0x15c (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* spi0_cs0.uart0_txd */ 
+			0x1a4 (PIN_OUTPUT | MUX_MODE5)		/* mcasp0_fsr.gpio3.19 */
                 	>;
                 };
 };
@@ -196,7 +202,7 @@
 	};
 };
 
-
+/*
 &i2c2 {
     pinctrl-names = "default";
     pinctrl-0 = <&i2c2_pins>;
@@ -216,7 +222,35 @@
                 reset-gpios = <&gpio3 21 1>;
         };
 };
+*/
 
+/ {
+i2c@3 {
+        compatible = "i2c-gpio";
+        pinctrl-names = "default";
+        pinctrl-0 = <&i2c_gpio_pins>;
+        status = "okay";
+
+        gpios = <&gpio0 2 0 /* sda */
+                 &gpio0 3 0 /* scl */
+                >;
+        /*i2c-gpio,sda-open-drain;
+        i2c-gpio,scl-open-drain;*/ 
+        i2c-gpio,delay-us = <1>;        /* ~200 kHz */
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        polytouch: edt-ft5x06@38 {
+                        compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
+                        reg = <0x38>;
+                        pinctrl-names = "default";
+                        pinctrl-0 = <&edt_ft5x06_pins>;
+                        interrupt-parent = <&gpio2>;
+                        interrupts = <1 0>;
+                        reset-gpios = <&gpio3 21 1>;
+                };
+        };
+};
 
 &spi1 {
 	pinctrl-names = "default";
@@ -239,27 +273,27 @@
 
 
 &lcdc {
-        pinctrl-names = "default", "sleep";
-        pinctrl-0 = <&lcd_pins_default>;
-        pinctrl-1 = <&lcd_pins_sleep>;
-        status = "okay";
-        display-timings {
-                480x272 {
-                        hactive         = <480>;
-                        vactive         = <272>;
-                        hback-porch     = <2>;
-                        hfront-porch    = <2>;
-                        hsync-len       = <41>;
-                        vback-porch     = <2>;
-                        vfront-porch    = <2>;
-                        vsync-len       = <10>;
-                        clock-frequency = <9000000>;
-                        hsync-active    = <0>;
-                        vsync-active    = <0>;
-                        de-active       = <1>;
-                        pixelclk-active = <1>;
-                };
-        };
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&lcd_pins_default>;
+	pinctrl-1 = <&lcd_pins_sleep>;
+	status = "okay";
+	display-timings {
+		800x480 {
+			hactive         = <800>;
+			vactive         = <480>;
+			hback-porch     = <88>;
+			hfront-porch    = <40>;
+			hsync-len       = <128>;
+			vback-porch     = <33>;
+			vfront-porch    = <10>;
+			vsync-len       = <2>;
+			clock-frequency = <33000000>;
+			hsync-active    = <0>;
+			vsync-active    = <0>;
+			de-active	= <1>;
+			pixelclk-active = <0>;
+		};
+	};
 };
 
 /*
@@ -326,6 +360,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001.dts";
+		display_dtb = "Display001_7.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_10.dts

@@ -327,6 +327,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_10.dts";
+		display_dtb = "Display001_10.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_4.dts

@@ -326,6 +326,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_4.dts";
+		display_dtb = "Display001_4.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_4_nopruss.dts

@@ -326,6 +326,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_4_nopruss.dts";
+		display_dtb = "Display001_4_nopruss.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_7.dts

@@ -360,6 +360,6 @@ i2c@3 {
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_7.dts";
+		display_dtb = "Display001_7.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_7_bitbang.dts

@@ -360,6 +360,6 @@ i2c@3 {
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_7_bitbang.dts";
+		display_dtb = "Display001_7_bitbang.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_7_gain1.dts

@@ -361,6 +361,6 @@ i2c@3 {
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_7_gain1.dts";
+		display_dtb = "Display001_7_gain1.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_7_i2c2.dts

@@ -323,6 +323,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_7_i2c2.dts";
+		display_dtb = "Display001_7_i2c2.dtb";
 	};
 };

+ 1 - 1
board/GfA/Display001/Display001_rru.dts

@@ -475,6 +475,6 @@
 / {
 	vendorinfo { 
 		vendor_name = "GfA Display001";
-		display_dtb = "Display001_rru.dts";
+		display_dtb = "Display001_rru.dtb";
 	};
 };

BIN
board/GfA/Display001/rootfs/usr/lib/qt/plugins/platforminputcontexts/libFreeVirtualKeyboard.so


BIN
board/GfA/Display001/rootfs/usr/qml/ApplicationLauncher/libApplicationLauncher.so


+ 0 - 3
board/GfA/Display001/rootfs/usr/qml/ApplicationLauncher/qmldir

@@ -1,3 +0,0 @@
-module ApplicationLauncher
-plugin ApplicationLauncher
-

BIN
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/FontAwesome.otf


+ 0 - 263
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/InputPanel.qml

@@ -1,263 +0,0 @@
-import QtQuick 2.0
-import "."
-import FreeVirtualKeyboard 1.0
-
-/**
- * This is the QML input panel that provides the virtual keyboard UI
- * The code has been copied from
- * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
- */
-Item {
-    id:root
-    objectName: "inputPanel"
-    width: parent.width
-    height: width / 4
-
-    signal hideKeyPressed
-
-    // Report actual keyboard rectangle to input engine
-    onYChanged: InputEngine.setKeyboardRectangle(Qt.rect(x, y, width, height))
-
-    KeyModel {
-        id:keyModel
-        kbdLayout: settings.value("COMMON/KbdLayout") //"de"
-    }
-
-    FontLoader {
-        source: "FontAwesome.otf"
-    }
-    QtObject {
-        id:pimpl
-        property bool shiftModifier: false
-        property bool symbolModifier: false
-        property int verticalSpacing: keyboard.height / 40
-        property int horizontalSpacing: verticalSpacing
-        property int rowHeight: keyboard.height/24*5 - verticalSpacing
-        property int buttonWidth:  (keyboard.width-column.anchors.margins)/12 - horizontalSpacing
-    }
-
-    // The delegate that paints the key buttons
-    Component {
-        id: keyButtonDelegate
-        KeyButton {
-            id: button
-            width: pimpl.buttonWidth
-            height: pimpl.rowHeight
-            text: (pimpl.shiftModifier) ? letter.toUpperCase() : (pimpl.symbolModifier)?firstSymbol : letter
-            inputPanel: root
-        }
-    }
-
-    Component {
-        id: numberButtonDelegate
-        KeyButton {
-            id: button
-            width: pimpl.buttonWidth
-            height: pimpl.rowHeight  * 4 / 5
-            text: (pimpl.shiftModifier) ? letter.toUpperCase() : (pimpl.symbolModifier)?firstSymbol : letter
-            inputPanel: root
-            color: "grey"
-        }
-    }
-
-    Connections {
-        target: InputEngine
-        // Switch the keyboard layout to Numeric if the input mode of the InputEngine changes
-        onInputModeChanged: {
-            pimpl.symbolModifier = ((InputEngine.inputMode == InputEngine.Numeric)
-                                 || (InputEngine.inputMode == InputEngine.Dialable))
-            if (pimpl.symbolModifier) {
-                pimpl.shiftModifier = false
-            }
-        }
-    }
-
-    // This function shows the character preview popup for each key button
-    function showKeyPopup(keyButton)
-    {
-        // console.log("showKeyPopup");
-        keyPopup.popup(keyButton, root);
-    }
-
-    // The key popup for character preview
-    KeyPopup {
-        id: keyPopup
-        visible: false
-        z: 100
-    }
-
-    Rectangle {
-        id: background
-        color: "black"
-        width: keyboard.width
-        height: keyboard.height + 4 * pimpl.verticalSpacing
-    }
-
-    Rectangle {
-        id:keyboard
-        color: "black"
-        anchors.fill: parent;
-        MouseArea {
-            anchors.fill: parent
-        }
-
-        Column {
-            id:column
-            anchors.margins: 5
-            anchors.fill: parent
-            spacing: pimpl.verticalSpacing
-            Row {
-                height: pimpl.rowHeight
-                spacing: pimpl.horizontalSpacing
-                anchors.horizontalCenter:parent.horizontalCenter
-                Repeater {
-                    model: keyModel.numbersRowModel
-                    delegate: numberButtonDelegate
-                }
-            }
-
-            Row {
-                height: pimpl.rowHeight
-                spacing: pimpl.horizontalSpacing
-                anchors.horizontalCenter:parent.horizontalCenter
-                Repeater {
-                    model: keyModel.firstRowModel
-                    delegate: keyButtonDelegate
-                }
-            }
-            Row {
-                height: pimpl.rowHeight
-                spacing: pimpl.horizontalSpacing
-                anchors.horizontalCenter:parent.horizontalCenter
-                Repeater {
-                    model: keyModel.secondRowModel
-                    delegate: keyButtonDelegate
-                }
-            }
-            Item {
-                height: pimpl.rowHeight
-                width:parent.width
-                KeyButton {
-                    id: shiftKey
-                    color: (pimpl.shiftModifier)? "#1e6fa7": "#1e1b18"
-                    anchors.left: parent.left
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.family: "FontAwesome"
-                    font.bold: true
-                    text: "\u21ea" //"\uf062"
-                    functionKey: true
-                    onClicked: {
-                        if (pimpl.symbolModifier) {
-                            pimpl.symbolModifier = false
-                        }
-                        pimpl.shiftModifier = !pimpl.shiftModifier
-                    }
-                    inputPanel: root
-                }
-                Row {
-                    height: pimpl.rowHeight
-                    spacing: pimpl.horizontalSpacing
-                    anchors.horizontalCenter:parent.horizontalCenter
-                    Repeater {
-                        anchors.horizontalCenter: parent.horizontalCenter
-                        model: keyModel.thirdRowModel
-                        delegate: keyButtonDelegate
-                    }
-                }
-                KeyButton {
-                    id: backspaceKey
-                    font.family: "FontAwesome"
-                    color: "#1e1b18"
-                    anchors.right: parent.right
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    text: "\x7F"
-                    displayText: "\u27f5" //"\uf177"
-                    inputPanel: root
-                    repeat: true
-                }
-            }
-            Row {
-                height: pimpl.rowHeight
-                spacing: pimpl.horizontalSpacing
-                anchors.horizontalCenter:parent.horizontalCenter
-                KeyButton {
-                    id: hideKey
-                    color: "#1e1b18"
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.family: "FontAwesome"
-                    text: "\uf11c" //"\uf078"
-                    functionKey: true
-                    onClicked: {
-                        Qt.inputMethod.hide();
-                        hideKeyPressed();
-                    }
-                    inputPanel: root
-                    showPreview: false
-                }
-                KeyButton {
-                    color: "#1e1b18"
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.family: "FontAwesome"
-                    font.bold: true
-                    text:  (pimpl.shiftModifier) ? "\u21a4":"\u21a6"
-                    inputPanel: root
-                    //functionKey: true
-                }
-                KeyButton {
-                    color: "#1e1b18"
-                    width: pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.family: "FontAwesome"
-                    text: (pimpl.shiftModifier) ? "\u2191":"\u2190" //"\uf060" // arrow left
-                    //onClicked: InputEngine.sendKeyToFocusItem(text)
-                    inputPanel: root
-                }
-                KeyButton {
-                    id: spaceKey
-                    width: 3*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    text: " "
-                    inputPanel: root
-                    showPreview: false
-                }
-                KeyButton {
-                    color: "#1e1b18"
-                    width: pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.family: "FontAwesome"
-                    text: (pimpl.shiftModifier) ?"\u2193":"\u2192" //"\uf061"  //pimpl.symbolModifier ? ":" :"."
-                    inputPanel: root
-                }
-                KeyButton {
-                    id: symbolKey
-                    color: "#1e1b18"
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    text: (!pimpl.symbolModifier)? "12#" : "ABC"
-                    functionKey: true
-                    onClicked: {
-                        if (pimpl.shiftModifier) {
-                            pimpl.shiftModifier = false
-                        }
-                        pimpl.symbolModifier = !pimpl.symbolModifier
-                    }
-                    inputPanel: root
-                }
-                KeyButton {
-                    id: enterKey
-                    color: "#1e1b18"
-                    width: 1.25*pimpl.buttonWidth
-                    height: pimpl.rowHeight
-                    font.bold: true
-                    displayText: "\u23ce" //"Enter"
-                    text: "\n"
-                    inputPanel: root
-                }
-            }
-        }
-    }
-}

+ 0 - 149
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyButton.qml

@@ -1,149 +0,0 @@
-import QtQuick 2.0
-import FreeVirtualKeyboard 1.0
-
-/**
- * This is the type implements one single key button in the InputPanel
- * The code has been copied from
- * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
- */
-Item {
-    id:root
-
-    // The background color of this button
-    property color color: "#35322f"
-
-    // The key text to show in this button
-    property string text
-
-    // The font for rendering of text
-    property alias font: txt.font
-
-    // The color of the text in this button
-    property alias textColor: txt.color
-
-    // This property holds the pressed status of the key.
-    property alias isPressed: buttonMouseArea.pressed
-
-    // This property holds a reference to the input panel.
-    // A key can only show the charcter preview popup if this property contains
-    // a valid refernce to the input panel
-    property var inputPanel
-
-    // This property holds the highlighted status of the key
-    // The highlighted status is a little bit different from the pressed status
-    // If the user releases the key, it is not pressed anymore, but it is still
-    // highlighted for some milliseconds
-    property bool isHighlighted: false
-
-    // Sets the show preview attribute for the character preview key popup
-    property bool showPreview: true
-
-    // Sets the key repeat attribute.
-    // If the repeat is enabled, the key will repeat the input events while held down.
-    // The default is false.
-    property bool repeat: false
-
-    // Sets the key code for input method processing.
-    property int key
-
-    // Sets the display text - this string is rendered in the keyboard layout.
-    // The default value is the key text.
-    property alias displayText: txt.text
-
-    // Sets the function key attribute.
-    property bool functionKey: false
-
-    signal clicked()
-    signal pressed()
-    signal released()
-
-    Rectangle {
-        anchors.fill: parent
-        radius: height / 20
-        color: isHighlighted ? Qt.tint(root.color, "#801e6fa7") : root.color
-        Text {
-            id: txt
-            color: "white"
-            anchors.margins: parent.height / 6
-            anchors.fill: parent
-            fontSizeMode: Text.Fit
-            font.pixelSize: height
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-            text: root.text
-        }
-        MouseArea {
-            id: buttonMouseArea
-            anchors.fill: parent
-            onClicked: root.clicked()
-            onPressed: root.pressed()
-            onReleased: root.released()
-        }
-    }
-
-    Timer {
-        id: highlightTimer
-        interval: 100
-        running: !isPressed
-        repeat: false
-
-        onTriggered: {
-            isHighlighted = false;
-        }
-    }
-
-    Timer {
-        id: repeatTimer
-        interval: 500
-        repeat: true
-        running: root.repeat && root.isPressed
-
-        onTriggered: {
-            if (root.state == "")
-            {
-                root.state = "REPEATING"
-                console.log("switching to repeating");
-            }
-            else if (root.state == "REPEATING")
-            {
-                console.log("repeating");
-            }
-
-            if (!functionKey)
-            {
-                InputEngine.sendKeyToFocusItem(text)
-            }
-        }
-    }
-
-    onInputPanelChanged: {
-        console.log("onInputPanelChanged: " + inputPanel.objectName);
-    }
-
-    // If the InputPanel property has a valid InputPanel reference and if
-    // showPreview is true, then this function calls showKeyPopup() to
-    // show the character preview popup.
-    onPressed: {
-        if (inputPanel != null && showPreview)
-        {
-            inputPanel.showKeyPopup(root);
-        }
-        isHighlighted = true;
-    }
-
-    onReleased: {
-        state = ""
-        console.log("onReleased - functionKey = " + functionKey)
-        if (!functionKey)
-        {
-            InputEngine.sendKeyToFocusItem(text)
-        }
-    }
-
-    states: [
-        State {
-            name: "REPEATING"
-            PropertyChanges { target: repeatTimer; interval: 50}
-        }
-    ]
-}

+ 0 - 191
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyModel.qml

@@ -1,191 +0,0 @@
-import QtQuick 2.0
-
-/**
- * This is quick and dirty model for the keys of the InputPanel *
- * The code has been copied from
- * http://tolszak-dev.blogspot.de/2013/04/qplatforminputcontext-and-virtual.html
- */
-
-
-/********************************************************
-                English Keyboard Layout
- ********************************************************/
-
-
-Item {
-    property QtObject firstRowModel: first
-    property QtObject secondRowModel: second
-    property QtObject thirdRowModel: third
-    property QtObject numbersRowModel: numbers
-    property string kbdLayout: ""
-
-    ListModel {
-        id:numbers
-
-
-        Component.onCompleted: {
-
-            switch (kbdLayout){
-            default:
-            case "de":
-            append ({ letter: "1", firstSymbol: "1"});
-            append ({ letter: "2", firstSymbol: "2"});
-            append ({ letter: "3", firstSymbol: "3"});
-            append ({ letter: "4", firstSymbol: "4"});
-            append ({ letter: "5", firstSymbol: "5"});
-            append ({ letter: "6", firstSymbol: "6"});
-            append ({ letter: "7", firstSymbol: "7"});
-            append ({ letter: "8", firstSymbol: "8"});
-            append ({ letter: "9", firstSymbol: "9"});
-            append ({ letter: "0", firstSymbol: "0"});
-            append ({ letter: "@", firstSymbol: "€"});
-            break;
-
-            case "en":
-            append ({ letter: "1", firstSymbol: "1"});
-            append ({ letter: "2", firstSymbol: "2"});
-            append ({ letter: "3", firstSymbol: "3"});
-            append ({ letter: "4", firstSymbol: "4"});
-            append ({ letter: "5", firstSymbol: "5"});
-            append ({ letter: "6", firstSymbol: "6"});
-            append ({ letter: "7", firstSymbol: "7"});
-            append ({ letter: "8", firstSymbol: "8"});
-            append ({ letter: "9", firstSymbol: "9"});
-            append ({ letter: "0", firstSymbol: "0"});
-            append ({ letter: "$", firstSymbol: "$"});
-            break;
-
-            }
-
-        }
-
-//        ListElement { letter: "1"; firstSymbol: "1"}
-//        ListElement { letter: "2"; firstSymbol: "2"}
-//        ListElement { letter: "3"; firstSymbol: "3"}
-//        ListElement { letter: "4"; firstSymbol: "4"}
-//        ListElement { letter: "5"; firstSymbol: "5"}
-//        ListElement { letter: "6"; firstSymbol: "6"}
-//        ListElement { letter: "7"; firstSymbol: "7"}
-//        ListElement { letter: "8"; firstSymbol: "8"}
-//        ListElement { letter: "9"; firstSymbol: "9"}
-//        ListElement { letter: "0"; firstSymbol: "0"}
-//        ListElement { letter: "@"; firstSymbol: "@"}
-//        // ListElement { letter: "="; firstSymbol: "+"}
-    }
-
-    ListModel {
-        id:first
-        ListElement { letter: "q"; firstSymbol: "!"}
-        ListElement { letter: "w"; firstSymbol: "°"}
-        ListElement { letter: "e"; firstSymbol: "#"}
-        ListElement { letter: "r"; firstSymbol: "$"}
-        ListElement { letter: "t"; firstSymbol: "%"}
-        ListElement { letter: "y"; firstSymbol: "^"}
-        ListElement { letter: "u"; firstSymbol: "&"}
-        ListElement { letter: "i"; firstSymbol: "+"}
-        ListElement { letter: "o"; firstSymbol: "-"}
-        ListElement { letter: "p"; firstSymbol: "*"}
-        ListElement { letter: "("; firstSymbol: "/"}
-        ListElement { letter: ")"; firstSymbol: "="}
-    }
-    ListModel {
-        id:second
-        ListElement { letter: "a"; firstSymbol: "{"}
-        ListElement { letter: "s"; firstSymbol: "}"}
-        ListElement { letter: "d"; firstSymbol: "["}
-        ListElement { letter: "f"; firstSymbol: "]"}
-        ListElement { letter: "g"; firstSymbol: "("}
-        ListElement { letter: "h"; firstSymbol: ")"}
-        ListElement { letter: "j"; firstSymbol: ":"}
-        ListElement { letter: "k"; firstSymbol: "\""}
-        ListElement { letter: "l"; firstSymbol: "'"}
-        ListElement { letter: "'"; firstSymbol: "|"}
-        ListElement { letter: "/"; firstSymbol: "\\"}
-    }
-    ListModel {
-        id:third
-        ListElement { letter: "z"; firstSymbol: "<"}
-        ListElement { letter: "x"; firstSymbol: ">"}
-        ListElement { letter: "c"; firstSymbol: "€"}
-        ListElement { letter: "v"; firstSymbol: "µ"}
-        ListElement { letter: "b"; firstSymbol: "?"}
-        ListElement { letter: "n"; firstSymbol: ".com"}
-        ListElement { letter: "m"; firstSymbol: ";"}
-        ListElement { letter: ","; firstSymbol: ","}
-        ListElement { letter: "."; firstSymbol: "."}
-    }
-}
-
-
-
-/********************************************************
-                German Keyboard Layout
- ********************************************************/
-/*
-
-Item {
-    property QtObject firstRowModel: first
-    property QtObject secondRowModel: second
-    property QtObject thirdRowModel: third
-    property QtObject numbersRowModel: numbers
-
-    ListModel {
-        id:numbers
-        ListElement { letter: "1"; firstSymbol: "1"}
-        ListElement { letter: "2"; firstSymbol: "2"}
-        ListElement { letter: "3"; firstSymbol: "3"}
-        ListElement { letter: "4"; firstSymbol: "4"}
-        ListElement { letter: "5"; firstSymbol: "5"}
-        ListElement { letter: "6"; firstSymbol: "6"}
-        ListElement { letter: "7"; firstSymbol: "7"}
-        ListElement { letter: "8"; firstSymbol: "8"}
-        ListElement { letter: "9"; firstSymbol: "9"}
-        ListElement { letter: "0"; firstSymbol: "0"}
-        ListElement { letter: "ß"; firstSymbol: "@"}
-        // ListElement { letter: "="; firstSymbol: "+"}
-    }
-
-    ListModel {
-        id:first
-        ListElement { letter: "q"; firstSymbol: "!"}
-        ListElement { letter: "w"; firstSymbol: "°"}
-        ListElement { letter: "e"; firstSymbol: "#"}
-        ListElement { letter: "r"; firstSymbol: "$"}
-        ListElement { letter: "t"; firstSymbol: "%"}
-        ListElement { letter: "z"; firstSymbol: "^"}
-        ListElement { letter: "u"; firstSymbol: "&"}
-        ListElement { letter: "i"; firstSymbol: "+"}
-        ListElement { letter: "o"; firstSymbol: "-"}
-        ListElement { letter: "p"; firstSymbol: "*"}
-        ListElement { letter: "ü"; firstSymbol: "/"}
-        ListElement { letter: ""; firstSymbol: "="}
-    }
-    ListModel {
-        id:second
-        ListElement { letter: "a"; firstSymbol: "{"}
-        ListElement { letter: "s"; firstSymbol: "}"}
-        ListElement { letter: "d"; firstSymbol: "["}
-        ListElement { letter: "f"; firstSymbol: "]"}
-        ListElement { letter: "g"; firstSymbol: "("}
-        ListElement { letter: "h"; firstSymbol: ")"}
-        ListElement { letter: "j"; firstSymbol: ":"}
-        ListElement { letter: "k"; firstSymbol: "\""}
-        ListElement { letter: "l"; firstSymbol: "'"}
-        ListElement { letter: "ö"; firstSymbol: "|"}
-        ListElement { letter: "ä"; firstSymbol: "\\"}
-    }
-    ListModel {
-        id:third
-        ListElement { letter: "y"; firstSymbol: "<"}
-        ListElement { letter: "x"; firstSymbol: ">"}
-        ListElement { letter: "c"; firstSymbol: "€"}
-        ListElement { letter: "v"; firstSymbol: "µ"}
-        ListElement { letter: "b"; firstSymbol: "?"}
-        ListElement { letter: "n"; firstSymbol: ".de"}
-        ListElement { letter: "m"; firstSymbol: ";"}
-        ListElement { letter: ","; firstSymbol: ","}
-        ListElement { letter: "."; firstSymbol: "."}
-    }
-}
-
-*/

+ 0 - 81
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/KeyPopup.qml

@@ -1,81 +0,0 @@
-import QtQuick 2.0
-import QtGraphicalEffects 1.0
-
-/**
- * This is the key popup that shows a character preview above the
- * pressed key button like it is known from keyboards on phones.
- */
-
-Item {
-    id: root
-    property alias text: txt.text
-    property alias font: txt.font
-
-    width: 40
-    height: 40
-    visible: false
-
-    Rectangle {
-        id: popup
-        anchors.fill: parent
-        radius: Math.round(height / 30)
-        z: shadow.z + 1
-
-        gradient: Gradient {
-                 GradientStop { position: 0.0; color: Qt.lighter(Qt.lighter("#35322f"))}
-                 GradientStop { position: 1.0; color: Qt.lighter("#35322f")}
-
-        }
-
-        Text {
-            id: txt
-            color: "white"
-            anchors.fill: parent
-            fontSizeMode: Text.Fit
-            font.pixelSize: height
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-        }
-    }
-
-    Rectangle {
-        id: shadow
-        width: root.width
-        height: root.height
-        color: "#3F000000"
-        x: 4
-        y: 4
-    }
-
-    function popup(keybutton, inputPanel) {
-        // console.log("popup: " + inputPanel.objectName);
-        // console.log("keybutton.text: " + keybutton.text);
-        width = keybutton.width * 1.4;
-        height = keybutton.height * 1.4;
-        var KeyButtonGlobalLeft = keybutton.mapToItem(inputPanel, 0, 0).x;
-        var KeyButtonGlobalTop = keybutton.mapToItem(inputPanel, 0, 0).y;
-        var PopupGlobalLeft = KeyButtonGlobalLeft - (width - keybutton.width) / 2;
-        var PopupGlobalTop = KeyButtonGlobalTop - height - pimpl.verticalSpacing * 1.5;
-        // console.log("Popup position left: " + KeyButtonGlobalLeft);
-        var PopupLeft = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).x;
-        y = root.parent.mapFromItem(inputPanel, PopupGlobalLeft, PopupGlobalTop).y;
-        if (PopupGlobalLeft < 0)
-        {
-            x = 0;
-        }
-        else if ((PopupGlobalLeft + width) > inputPanel.width)
-        {
-            x = PopupLeft - (PopupGlobalLeft + width - inputPanel.width);
-        }
-        else
-        {
-            x = PopupLeft;
-        }
-
-        text = keybutton.displayText;
-        font.family = keybutton.font.family
-        visible = Qt.binding(function() {return keybutton.isHighlighted});
-    }
-}
-
-

+ 0 - 2
board/GfA/Display001/rootfs/usr/qml/QtQuick/FreeVirtualKeyboard/qmldir

@@ -1,2 +0,0 @@
-module QtQuick.FreeVirtualKeyboard
-InputPanel 1.0 InputPanel.qml

BIN
board/GfA/Display001/rootfs/usr/qml/gfa/plugins/qml/libSqlDatabase.so


+ 0 - 4
board/GfA/Display001/rootfs/usr/qml/gfa/plugins/qml/qmldir

@@ -1,4 +0,0 @@
-module gfa.plugins.qml
-plugin SqlDatabase
-classname SqlDatabase
-typeinfo plugins.qmltypes

+ 6 - 0
configs/Display001_3.12.30_defconfig

@@ -94,6 +94,7 @@ BR2_PACKAGE_FLASHBENCH=y
 BR2_PACKAGE_MAKEDEVS=y
 BR2_PACKAGE_MMC_UTILS=y
 BR2_PACKAGE_DEJAVU=y
+BR2_PACKAGE_FONT_AWESOME=y
 BR2_PACKAGE_DIRECTFB=y
 BR2_PACKAGE_DIRECTFB_DIVINE=y
 BR2_PACKAGE_DIRECTFB_SAWMAN=y
@@ -138,6 +139,7 @@ BR2_PACKAGE_QT5BASE_SQLITE_SYSTEM=y
 BR2_PACKAGE_QT5BASE_OPENGL_LIB=y
 BR2_PACKAGE_QT5BASE_LINUXFB=y
 BR2_PACKAGE_QT5BASE_EGLFS=y
+BR2_PACKAGE_QT5BASE_FONTCONFIG=y
 BR2_PACKAGE_QT5BASE_GIF=y
 BR2_PACKAGE_QT5BASE_JPEG=y
 BR2_PACKAGE_QT5BASE_PNG=y
@@ -153,6 +155,9 @@ BR2_PACKAGE_QT5QUICKCONTROLS=y
 BR2_PACKAGE_QT5SENSORS=y
 BR2_PACKAGE_QT5SERIALBUS=y
 BR2_PACKAGE_QT5SVG=y
+BR2_PACKAGE_QT5TOOLS=y
+BR2_PACKAGE_QT5TOOLS_QTPATHS=y
+BR2_PACKAGE_QT5TOOLS_QTPLUGININFO=y
 BR2_PACKAGE_QT5WEBENGINE=y
 BR2_PACKAGE_QT5VIRTUALKEYBOARD=y
 BR2_PACKAGE_QT5CHARTS=y
@@ -425,3 +430,4 @@ BR2_PACKAGE_HOST_MTOOLS=y
 BR2_PACKAGE_WT=y
 BR2_PACKAGE_NETWORK_INTERFACES_SCRIPT=y
 BR2_PACKAGE_GFA_ADDONS=y
+BR2_PACKAGE_QMLPLUGINS=y

+ 6 - 0
package/libgfaipc/Config.in

@@ -0,0 +1,6 @@
+config BR2_PACKAGE_LIBGFAIPC
+	bool "libgfaipc"
+	default y
+	help
+		libgfaipc component.config BR2_PACKAGE_LIBGFAIPC
+

+ 24 - 0
package/libgfaipc/libgfaipc.mk

@@ -0,0 +1,24 @@
+LIBGFAIPC_VERSION = 1.1.0
+LIBGFAIPC_SITE = ../GfA/package/libgfaipc/src
+LIBGFAIPC_SITE_METHOD = local
+LIBGFAIPC_INSTALL_STAGING = YES
+LIBGFAIPC_INSTALL_TARGET = YES
+
+define LIBGFAIPC_BUILD_CMDS
+	$(MAKE) CC="$(TARGET_CC)" CXX="$(TARGET_CXX)" LD="$(TARGET_LD)" -C $(@D) all
+endef
+
+define LIBGFAIPC_INSTALL_STAGING_CMDS
+	$(INSTALL) -D -m 0755 $(@D)/libgfaipc.so.1.1.0 $(STAGING_DIR)/usr/lib/libgfaipc.so.1.1.0
+	$(INSTALL) -D -m 0755 $(@D)/gfaipc.h $(STAGING_DIR)/usr/include/gfaipc.h
+	ln -sfn libgfaipc.so.1.1.0 $(STAGING_DIR)/usr/lib/libgfaipc.so.1
+	ln -sfn libgfaipc.so.1 $(STAGING_DIR)/usr/lib/libgfaipc.so
+endef
+
+define LIBGFAIPC_INSTALL_TARGET_CMDS
+	$(INSTALL) -D -m 0755 $(@D)/libgfaipc.so.1.1.0 $(TARGET_DIR)/usr/lib/libgfaipc.so.1.1.0
+	ln -sfn libgfaipc.so.1.1.0 $(TARGET_DIR)/usr/lib/libgfaipc.so.1
+	ln -sfn libgfaipc.so.1 $(TARGET_DIR)/usr/lib/libgfaipc.so
+endef
+
+$(eval $(generic-package))

+ 55 - 0
package/libgfaipc/src/Makefile

@@ -0,0 +1,55 @@
+# Change these if necessary
+DEBUG ?= 0
+        
+_LIBBASENAME=gfaipc
+LIBFILENAME=lib$(LIBBASENAME).so.1.1.0
+
+#CC = $(CROSS_COMPILE)gcc
+#CXX = $(CROSS_COMPILE)c++ 
+CFLAGS = -pthread -fPIC -Wall -Wno-unused -Wno-unused-label -Wformat -Wuninitialized -Wundef -Wcast-qual -Wwrite-strings -fabi-version=2 -fno-omit-frame-pointer
+CXXFLAGS = -pthread -fPIC -Wall -Wno-unused -Wno-unused-label -Wformat -Wuninitialized -Wundef -Wcast-qual -Wwrite-strings -std=c++11 -fabi-version=2 -fno-omit-frame-pointer
+LDFLAGS = -fPIC -shared -L. -lc -pthread
+
+ifeq ($(DEBUG), 1)
+	CFLAGS += -g
+	CXXFLAGS += -g
+	LDFLAGS += -g
+	LIBBASENAME = $(_LIBBASENAME)d
+else
+	CFLAGS += -O3
+	CXXFLAGS += -O3
+	LDFLAGS += -O3
+	LIBBASENAME = $(_LIBBASENAME)
+endif
+
+
+
+
+RM = rm -f  # rm command
+TARGET_LIB = $(LIBFILENAME) # target lib
+
+CSRCS = uuid.c  # source files
+CXXSRCS = sema.cpp mutex.cpp locmtx.cpp shm.cpp shmrot.cpp ipcshm.cpp # source files
+COBJS = $(CSRCS:.c=.o)
+CXXOBJS = $(CXXSRCS:.cpp=.o)
+
+.PHONY: all
+all: ${TARGET_LIB}
+
+$(TARGET_LIB): $(COBJS) $(CXXOBJS)
+	$(CC) ${LDFLAGS} -o $@ $^
+
+$(CSRCS:.c=.d):%.d:%.c
+	$(CC) $(CFLAGS) -MM $< >$@
+
+$(CXXSRCS:.cpp=.dpp):%.dpp:%.cpp
+	$(CXX) $(CXXFLAGS) -MM $< >$@
+
+include $(CSRCS:.c=.d) $(CXXSRCS:.cpp=.dpp)
+
+.PHONY: clean
+clean:
+	$(RM) $(TARGET_LIB) 
+	$(RM) *.o
+	$(RM) *.d
+	$(RM) *.dpp

+ 33 - 0
package/libgfaipc/src/defines.h

@@ -0,0 +1,33 @@
+// defines.h :
+//
+
+#if !defined(AGD_DEFINES_H__CBCFEAE4_7504_435D_BD29_909BA80D72CD__INCLUDED_)
+#define AGD_DEFINES_H__CBCFEAE4_7504_435D_BD29_909BA80D72CD__INCLUDED_
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// defines.h - Declarations:
+
+#ifdef _WIN32
+#endif	//	_WIN32
+
+#ifdef __linux__
+#endif	//	__linux__
+
+#define _INVALID_ID							-1
+#define _NUMBER_OF_THE_BEAST				0666
+
+#ifdef _DEBUG
+#define TRACE								printf
+#else	//	_DEBUG
+#define TRACE(...)
+#endif	//	_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_DEFINES_H__CBCFEAE4_7504_435D_BD29_909BA80D72CD__INCLUDED_)

+ 36 - 0
package/libgfaipc/src/gfaipc.h

@@ -0,0 +1,36 @@
+// gfaipc.h :
+//
+
+#if !defined(AGD_GFAIPC_H__6126047E_C1B1_4ACE_BD49_8780C7E5E068__INCLUDED_)
+#define AGD_GFAIPC_H__6126047E_C1B1_4ACE_BD49_8780C7E5E068__INCLUDED_
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// gfaipc.h - Declarations:
+
+typedef void				*HSHM;
+
+HSHM	GfaIpcAcquireSHM	(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName);
+void	GfaIpcReleaseSHM	(HSHM hShm);
+void*	GfaIpcAcquirePointer(HSHM hShm);
+void	GfaIpcReleasePointer(HSHM hShm, const void *p);
+void	GfaIpcLockSHM		(HSHM hShm);
+void	GfaIpcUnlockSHM		(HSHM hShm);
+void	GfaIpcDumpSHMROT	(void);
+
+long	GfaIpcInterlockedIncrement(HSHM hShm, volatile long *pl);
+long	GfaIpcInterlockedDecrement(HSHM hShm, volatile long *pl);
+long	GfaIpcInterlockedCompare(HSHM hShm, volatile long *pl, long comparand);
+long	GfaIpcInterlockedSet(HSHM hShm, volatile long *pl, long val);
+long	GfaIpcInterlockedClear(HSHM hShm, volatile long *pl);
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_GFAIPC_H__6126047E_C1B1_4ACE_BD49_8780C7E5E068__INCLUDED_)

+ 333 - 0
package/libgfaipc/src/ipcshm.cpp

@@ -0,0 +1,333 @@
+// gfaipc.cpp
+//
+
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#include <windows.h>
+#endif	//	_WIN32
+
+#include <stdio.h>
+#include <string.h>
+#include "defines.h"
+#include "uuid.h"
+#include "shmrot.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+CShmHandleMap::CShmHandleMap(void)
+{
+	memset(m_handles, 0, sizeof(m_handles));
+}
+
+CShmHandleMap::~CShmHandleMap(void)
+{
+	for(size_t i = 0; i < _IPCSHM_MAX_HANDLES; i++)
+	{
+	}
+}
+
+HSHM CShmHandleMap::AcquireHandle(CShm *pShm)
+{
+	HSHM hShm = NULL;
+
+	for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++)
+	{
+		if(!m_handles[i].pShm)
+		{
+			m_handles[i].pShm = pShm;
+			hShm = &m_handles[i];
+			break;
+		}
+	}
+
+	return hShm;
+}
+
+void CShmHandleMap::ReleaseHandle(HSHM hShm)
+{
+	for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++)
+	{
+		if(&m_handles[i] == hShm)
+		{
+			m_handles[i].pShm = NULL;
+			break;
+		}
+	}
+}
+
+CShm* CShmHandleMap::LookupShm(const uuid_t &uuid)
+{
+	for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++)
+	{
+		if(m_handles[i].pShm)
+		{
+			const uuid_t &uuid2 = m_handles[i].pShm->Uuid();
+
+			if(!_uuid_compare(&uuid, &uuid2))
+				return m_handles[i].pShm;
+		}
+	}
+
+	return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static CShmROT g_shmRot;
+static CShmHandleMap g_shmHandleMap;
+
+/////////////////////////////////////////////////////////////////////////////
+
+HSHM GfaIpcAcquireSHM(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName)
+{
+	HSHM hShm = NULL;
+
+	if(!g_shmRot.Created())
+	{
+		if(!g_shmRot.Create())
+		{
+			TRACE("GfaIpcAcquireSHM: Failed to create ROT!\n");
+			return NULL;
+		}
+	}
+
+	g_shmRot.Lock();
+	CShm *pShm = g_shmRot.AcquireShm(pszUuid, nSizeElement, nCntElements, pszDescName);
+
+	if(pShm)
+	{
+		hShm = g_shmHandleMap.AcquireHandle(pShm);
+
+		if(!hShm)
+		{
+			TRACE("GfaIpcAcquireSHM: Failed to acquire handle!\n");
+			g_shmRot.ReleaseShm(pShm);
+		}
+	}
+
+	g_shmRot.Unlock();
+	return hShm;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void GfaIpcReleaseSHM(HSHM hShm)
+{
+	if(hShm)
+	{
+		LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+		if(!ph->pShm)
+		{
+			TRACE("GfaIpcReleaseSHM: Invalid Handle!\n");
+			return;
+		}
+		g_shmRot.Lock();
+		g_shmRot.ReleaseShm(ph->pShm);
+		g_shmHandleMap.ReleaseHandle(hShm);
+		g_shmRot.Unlock();
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void* GfaIpcAcquirePointer(HSHM hShm)
+{
+	if(hShm)
+	{
+		LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+		if(!ph->pShm)
+		{
+			TRACE("GfaIpcAcquirePointer: Invalid Handle!\n");
+			return NULL;
+		}
+
+		return ph->pShm->Attach();
+	}
+
+	TRACE("GfaIpcAcquirePointer: Invalid Handle!\n");
+	return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void GfaIpcReleasePointer(HSHM hShm, const void *p)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	ph->pShm->Detach(p);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void GfaIpcLockSHM(HSHM hShm)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	ph->pShm->Lock();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void GfaIpcUnlockSHM(HSHM hShm)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		return;
+	}
+
+	ph->pShm->Unlock();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void GfaIpcDumpSHMROT(void)
+{
+	if(!g_shmRot.Created())
+	{
+		if(!g_shmRot.Create())
+		{
+			TRACE("GfaIpcDumpSHMROT: Failed to create ROT!\n");
+			return;
+		}
+	}
+
+	g_shmRot.DumpEntries(g_shmHandleMap);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+long GfaIpcInterlockedIncrement(HSHM hShm, volatile long *pl)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcInterlockedIncrement: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcInterlockedIncrement: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->InterlockedIncrement(pl);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+long GfaIpcInterlockedDecrement(HSHM hShm, volatile long *pl)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcInterlockedDecrement: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcInterlockedDecrement: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->InterlockedDecrement(pl);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+long GfaIpcInterlockedCompare(HSHM hShm, volatile long *pl, long comparand)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcInterlockedCompare: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcInterlockedCompare: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->InterlockedCompare(pl, comparand);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+long GfaIpcInterlockedSet(HSHM hShm, volatile long *pl, long val)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcInterlockedSet: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcInterlockedSet: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->InterlockedSet(pl, val);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+long GfaIpcInterlockedClear(HSHM hShm, volatile long *pl)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcInterlockedSet: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcInterlockedClear: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->InterlockedClear(pl);
+}

+ 87 - 0
package/libgfaipc/src/locmtx.cpp

@@ -0,0 +1,87 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <windows.h>
+#include <io.h>
+#include "../Win32/w32def.h"
+#endif	//	_WIN32
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/file.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <linux/limits.h>
+#include <sys/shm.h>
+#endif	//	__linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "mutex.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _IS_VALID_SHMID(id)				((id) >= 0)
+
+/////////////////////////////////////////////////////////////////////////////
+
+CLocalMutex::CLocalMutex(void) : m_bInit(false)
+{
+	memset(&m_mutex, 0, sizeof(m_mutex));
+	memset(&m_mutexAttr, 0, sizeof(m_mutexAttr));
+	::pthread_mutexattr_init(&m_mutexAttr);
+	::pthread_mutexattr_settype(&m_mutexAttr, PTHREAD_MUTEX_RECURSIVE);
+}
+
+CLocalMutex::~CLocalMutex(void)
+{
+	Release();
+	::pthread_mutexattr_destroy(&m_mutexAttr);
+}
+
+bool CLocalMutex::Create(bool bRecursive)
+{
+	if(!m_bInit)
+	{
+		if(!::pthread_mutex_init(&m_mutex, bRecursive ? &m_mutexAttr : NULL))
+		{
+			TRACE("CLocalMutex::Create: Created Mutex (recursive=%s)\n", bRecursive ? "true" : "false");
+			m_bInit = true;
+		}
+		else
+		{
+			TRACE("CLocalMutex::Create failed!\n");
+		}
+	}
+	
+	return m_bInit;
+}
+
+void CLocalMutex::Release(void)
+{
+	if(m_bInit)
+	{
+		::pthread_mutex_destroy(&m_mutex);
+		m_bInit = false;
+		TRACE("CLocalMutex::Release: Mutex released.\n");
+	}
+}
+
+bool CLocalMutex::Lock(void)
+{
+	return !::pthread_mutex_lock(&m_mutex);
+}
+
+bool CLocalMutex::TryLock(void)
+{
+	return !::pthread_mutex_trylock(&m_mutex);
+}
+
+bool CLocalMutex::Unlock(void)
+{
+	return !::pthread_mutex_unlock(&m_mutex);
+}

+ 222 - 0
package/libgfaipc/src/mutex.cpp

@@ -0,0 +1,222 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <windows.h>
+#include <io.h>
+#include "../Win32/w32def.h"
+#endif	//	_WIN32
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/file.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <linux/limits.h>
+#include <sys/shm.h>
+#endif	//	__linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "mutex.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _IS_VALID_SHMID(id)				((id) >= 0)
+
+/////////////////////////////////////////////////////////////////////////////
+
+CGlobalMutex::CGlobalMutex(void) :	m_nShmID(_INVALID_ID), m_pMutex(NULL)
+{
+	memset(&m_mutexAttr, 0, sizeof(m_mutexAttr));
+	::pthread_mutexattr_init(&m_mutexAttr);
+	::pthread_mutexattr_setpshared(&m_mutexAttr, PTHREAD_PROCESS_SHARED);
+	::pthread_mutexattr_settype(&m_mutexAttr, PTHREAD_MUTEX_RECURSIVE);
+	::pthread_mutexattr_setrobust(&m_mutexAttr, PTHREAD_MUTEX_ROBUST);
+}
+
+CGlobalMutex::~CGlobalMutex(void)
+{
+	Release();
+}
+
+int CGlobalMutex::Create(const uuid_t &ruuid, const char *pszDir)
+{
+	if(!pszDir)
+		pszDir = "";
+
+	size_t nLenReq = strlen(pszDir) + _UUID_STRING_LEN + 2;
+
+	if(nLenReq > PATH_MAX)
+	{
+		TRACE("CGlobalMutex::Create: directory name too long\n");
+		errno = EINVAL;
+		return -1;
+	}
+
+	int nRet = -1;
+	char szUuid[_UUID_STRING_LEN + 1];
+	char szShm[PATH_MAX];
+	_uuid_unparse(&ruuid, szUuid, sizeof(szUuid));
+	sprintf(szShm, "%s/%s.mtx", pszDir, szUuid);
+
+	int nFdShm;
+
+	if((nFdShm = ::open(szShm, O_RDWR | O_CREAT | O_TRUNC, _NUMBER_OF_THE_BEAST)) >= 0)
+	{
+		key_t shmKey;
+
+		if((shmKey = ::ftok(szShm, 'R')) >= 0)
+		{
+			if((m_nShmID = ::shmget(shmKey, sizeof(pthread_mutex_t), IPC_CREAT | _NUMBER_OF_THE_BEAST)) >= 0)
+			{
+				struct shmid_ds sds;
+				memset(&sds, 0, sizeof(sds));
+
+				if(!::shmctl(m_nShmID, IPC_STAT, (struct shmid_ds*)&sds))
+				{
+					m_pMutex = (pthread_mutex_t*)::shmat(m_nShmID, NULL, 0);
+
+					if(!sds.shm_atime)
+					{
+						if(!(nRet = ::pthread_mutex_init(m_pMutex, &m_mutexAttr)))
+						{
+							TRACE("CGlobalMutex::Create: Created new Mutex\n");
+							nRet = 1;
+						}
+						else
+						{
+							TRACE("CGlobalMutex::Create failed! Code: %d\n", nRet);
+							nRet = -1;
+						}
+					}
+					else
+					{
+						TRACE("CGlobalMutex::Create: Opened existing Mutex\n");
+						nRet = 0;
+					}
+				}
+				else
+				{
+					TRACE("CGlobalMutex::Create: IPC_STAT failed - errno: %d!\n", errno);
+				}
+			}
+			else
+			{
+				TRACE("CGlobalMutex::Create: Failed to create SHM on Key: 0x%08X - errno: %d!\n", shmKey, errno);
+			}
+		}
+		else
+		{
+			TRACE("CGlobalMutex::Create: Failed to create shmKey - errno: %d!\n", errno);
+		}
+
+		close(nFdShm);
+	}
+	else
+	{
+		TRACE("CGlobalMutex::Create: Failed to open '%s' - errno: %d!\n", szShm, errno);
+	}
+
+	return nRet;
+}
+	
+long CGlobalMutex::Release(void)
+{
+	struct shmid_ds sds;
+	sds.shm_nattch = (shmatt_t)-1;
+
+	if(_IS_VALID_SHMID(m_nShmID) && m_pMutex)
+	{
+		if(!::shmctl(m_nShmID, IPC_STAT, (struct shmid_ds*)&sds))
+		{
+			if((long)sds.shm_nattch > 1)
+			{
+				::pthread_mutexattr_destroy(&m_mutexAttr);
+				::shmdt(m_pMutex);
+				::shmctl(m_nShmID, IPC_STAT, (struct shmid_ds*)&sds);
+				TRACE("CGlobalMutex::Release: Still attached: %ld!\n", (long)(sds.shm_nattch));
+			}
+			else if((long)sds.shm_nattch == 1)
+			{
+				::pthread_mutex_destroy(m_pMutex);
+				::pthread_mutexattr_destroy(&m_mutexAttr);
+				::shmdt(m_pMutex);
+				::shmctl(m_nShmID, IPC_RMID, NULL);
+				sds.shm_nattch = 0;
+				TRACE("CGlobalMutex::Release: Mutex removed!\n");
+			}
+		}
+		else
+		{
+			sds.shm_nattch = (shmatt_t)-1;
+			TRACE("CGlobalMutex::Release: IPC_STAT failed!\n");
+		}
+
+		m_pMutex = NULL;
+		m_nShmID = _INVALID_ID;
+	}
+
+	return (long)sds.shm_nattch;
+}
+
+bool CGlobalMutex::Lock(void)
+{
+	if(m_pMutex)
+	{
+		int nRet = ::pthread_mutex_lock(m_pMutex);
+		if(nRet == EOWNERDEAD)
+		{
+			TRACE("CGlobalMutex::Lock: Former owner process has died - gained ownership!\n");
+			::pthread_mutex_consistent(m_pMutex);
+			nRet = 0;
+		}
+//		TRACE("CGlobalMutex::Lock: Locked: %d.\n", m_nShmID);
+		return !nRet;
+	}
+	else
+	{
+		TRACE("CGlobalMutex::Lock: Invalid Mutex: %p!\n", m_pMutex);
+		errno = EINVAL;
+		return false;
+	}
+}
+
+bool CGlobalMutex::TryLock(void)
+{
+	if(m_pMutex)
+	{
+		int nRet = ::pthread_mutex_trylock(m_pMutex);
+		if(nRet == EOWNERDEAD)
+		{
+			TRACE("CGlobalMutex::TryLock: Former owner process has died - gained ownership!\n");
+			::pthread_mutex_consistent(m_pMutex);
+			nRet = 0;
+		}
+		return !nRet;
+	}
+	else
+	{
+		TRACE("CGlobalMutex::TryLock: Invalid Mutex: %p!\n", m_pMutex);
+		errno = EINVAL;
+		return false;
+	}
+}
+
+bool CGlobalMutex::Unlock(void)
+{
+	if(m_pMutex)
+	{
+//		TRACE("CGlobalMutex::Unlock: Unlocked: %d.\n", m_nShmID);
+		return !::pthread_mutex_unlock(m_pMutex);
+	}
+	else
+	{
+		TRACE("CGlobalMutex::Unlock: Invalid Mutex: %p!\n", m_pMutex);
+		errno = EINVAL;
+		return false;
+	}
+}

+ 66 - 0
package/libgfaipc/src/mutex.h

@@ -0,0 +1,66 @@
+// mutex.h :
+//
+
+#if !defined(AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_)
+#define AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "uuid.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// mutex.h - Declarations:
+
+#ifdef _WIN32
+#define _DEF_MUTEX_DIR						"."
+#endif	//	_WIN32
+
+#ifdef __linux__
+#define _DEF_MUTEX_DIR						"/tmp"
+#endif	//	__linux__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CGlobalMutex
+{
+public:
+	CGlobalMutex(void);
+	virtual ~CGlobalMutex(void);
+
+	int Create(const uuid_t &ruuid, const char *pszDir = _DEF_MUTEX_DIR);
+	long Release(void);
+
+	bool Lock(void);
+	bool TryLock(void);
+	bool Unlock(void);
+
+private:
+	int m_nShmID;
+	pthread_mutexattr_t m_mutexAttr;
+	pthread_mutex_t *m_pMutex;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CLocalMutex
+{
+public:
+	CLocalMutex(void);
+	virtual ~CLocalMutex(void);
+
+	bool Create(bool bRecursive = false);
+	void Release(void);
+
+	bool Lock(void);
+	bool TryLock(void);
+	bool Unlock(void);
+
+private:
+	bool m_bInit;
+	pthread_mutexattr_t m_mutexAttr;
+	pthread_mutex_t m_mutex;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_)

+ 459 - 0
package/libgfaipc/src/sema.cpp

@@ -0,0 +1,459 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <windows.h>
+#include <io.h>
+#include "../Win32/w32def.h"
+#endif	//	_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/file.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <linux/limits.h>
+#endif	//	__linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "sema.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _IS_VALID_SEMID(id)				((id) >= 0)
+
+/////////////////////////////////////////////////////////////////////////////
+
+CSemaphore::CSemaphore(void) :	m_nSemID(_INVALID_ID)
+{
+}
+
+CSemaphore::~CSemaphore(void)
+{
+	Release();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::Create(const char *pszFilename, int nsems, unsigned short *pInitArr)
+{
+	int nFdSema, nRet = -1;
+
+	if((nFdSema = ::open(pszFilename, O_RDWR | O_CREAT | O_TRUNC, _NUMBER_OF_THE_BEAST)) >= 0)
+	{
+		if(!::flock(nFdSema, LOCK_EX))
+		{
+			key_t semKey;
+
+			if((semKey = ::ftok(pszFilename, 'R')) >= 0)
+			{
+				if((m_nSemID = ::semget(semKey, nsems, IPC_CREAT | _NUMBER_OF_THE_BEAST)) >= 0)
+				{
+					struct semid_ds sds;
+					::memset(&sds, 0, sizeof(sds));
+
+					if(!IpcStat(&sds))
+					{
+						if(!sds.sem_otime)
+						{
+							bool fCreateArr = !pInitArr;
+
+							if(fCreateArr)
+							{
+								pInitArr = new unsigned short[sds.sem_nsems];
+
+								for(unsigned long i = 0; i < sds.sem_nsems; i++)
+								{
+									pInitArr[i] = 0;
+								}
+							}
+
+							SetAll(pInitArr);
+
+							if(fCreateArr)
+								delete [] pInitArr;
+
+							struct sembuf sb[2] = {{0, 1, IPC_NOWAIT}, {0, -1, IPC_NOWAIT}};
+							Op(sb, 2);
+
+							TRACE("CSemaphore::Create: Created new Semaphore!\n");
+							nRet = 1;
+						}
+						else
+						{
+							TRACE("CSemaphore::Create: Opened existing Semaphore!\n");
+							nRet = 0;
+						}
+					}
+					else
+					{
+						TRACE("CSemaphore::Create: IpcStat failed - errno: %d!\n", errno);
+					}
+				}
+				else
+				{
+					TRACE("CSemaphore::Create: Failed to create Semaphore - errno: %d!\n", errno);
+				}
+			}
+			else
+			{
+				TRACE("CSemaphore::Create: Failed to create semKey - errno: %d!\n", errno);
+			}
+
+			::flock(nFdSema, LOCK_UN);
+		}
+		else
+		{
+			TRACE("CSemaphore::Create: Failed to create Lock on '%s' - errno: %d!\n", pszFilename, errno);
+		}
+
+		::close(nFdSema);
+	}
+	else
+	{
+		TRACE("CSemaphore::Create: Failed to create '%s' - errno: %d!\n", pszFilename, errno);
+	}
+
+	return nRet;
+}
+
+void CSemaphore::Release(void)
+{
+	if(_IS_VALID_SEMID(m_nSemID))
+	{
+		m_nSemID = _INVALID_ID;
+		TRACE("CSemaphore::Release\n");
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::Ctl(int cmd)
+{
+	union semun su;
+	su.val = 0;
+	return Ctl(0, cmd, su);
+}
+
+int CSemaphore::Ctl(int semnum, int cmd)
+{
+	union semun su;
+	su.val = 0;
+	return Ctl(semnum, cmd, su);
+}
+
+int CSemaphore::Ctl(int semnum, int cmd, int val)
+{
+	union semun su;
+	su.val = val;
+	return Ctl(semnum, cmd, su);
+}
+
+int CSemaphore::Ctl(int cmd, struct semid_ds *buf)
+{
+	union semun su;
+	su.buf = buf;
+	return Ctl(0, cmd, su);
+}
+
+int CSemaphore::Ctl(int cmd, unsigned short  *arr)
+{
+	union semun su;
+	su.array = arr;
+	return Ctl(0, cmd, su);
+}
+
+int CSemaphore::Ctl(int cmd, struct seminfo *si)
+{
+	union semun su;
+	su.__buf = si;
+	return Ctl(0, cmd, su);
+}
+
+int CSemaphore::Ctl(int semnum, int cmd, union semun su)
+{
+	if(!_IS_VALID_SEMID(m_nSemID))
+	{
+//		TRACE("CSemaphore::Ctl: Invalid SemID: %d!\n", m_nSemID);
+		errno = EINVAL;
+		return -1;
+	}
+
+	return ::semctl(m_nSemID, semnum, cmd, su);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::IpcStat(struct semid_ds *buf)
+{
+	return Ctl(IPC_STAT, buf);
+}
+
+int CSemaphore::IpcSet(struct semid_ds *buf)
+{
+	return Ctl(IPC_SET, buf);
+}
+
+int CSemaphore::IpcRmID(void)
+{
+	int nRet = Ctl(IPC_RMID);
+	Release();
+	return nRet;
+}
+
+int CSemaphore::IpcInfo(struct seminfo *si)
+{
+	return Ctl(IPC_INFO, si);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::SemStat(int index, struct semid_ds *buf)
+{
+	union semun su;
+	su.buf = buf;
+	return ::semctl(index, 0, SEM_STAT, su);
+}
+
+int CSemaphore::SemInfo(struct seminfo *si)
+{
+	return Ctl(SEM_INFO, si);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::GetVal(int semnum)
+{
+	return Ctl(semnum, GETVAL);
+}
+
+int CSemaphore::SetVal(int semnum, int val)
+{
+	return Ctl(semnum, SETVAL, val);
+}
+
+int CSemaphore::GetAll(unsigned short *arr)
+{
+	return Ctl(GETALL, arr);
+}
+
+int CSemaphore::SetAll(unsigned short *arr)
+{
+	return Ctl(SETALL, arr);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CSemaphore::GetPid(int semnum)
+{
+	return Ctl(semnum, GETPID);
+}
+
+int CSemaphore::GetNCnt(int semnum)
+{
+	return Ctl(semnum, GETNCNT);
+}
+
+int CSemaphore::GetZCnt(int semnum)
+{
+	return Ctl(semnum, GETZCNT);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+bool CSemaphore::Op(struct sembuf *sops, size_t nsops)
+{
+	if(!_IS_VALID_SEMID(m_nSemID))
+	{
+//		TRACE("CSemaphore::Op: Invalid SemID: %d!\n", m_nSemID);
+		errno = EINVAL;
+		return false;
+	}
+
+	return !::semop(m_nSemID, sops, nsops);
+}
+
+bool CSemaphore::TimedOp(struct sembuf *sops, size_t nsops, const struct timespec *timeout)
+{
+	if(!_IS_VALID_SEMID(m_nSemID))
+	{
+		TRACE("CSemaphore::TimedOp: Invalid SemID: %d!\n", m_nSemID);
+		errno = EINVAL;
+		return false;
+	}
+
+	return !::semtimedop(m_nSemID, sops, nsops, timeout);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool CSemaphore::Lock(int semnum)
+{
+	struct sembuf sb;
+	sb.sem_num	= (unsigned short)semnum;
+	sb.sem_op	= -1;
+	sb.sem_flg	= SEM_UNDO;
+	return Op(&sb, 1);
+}
+
+bool CSemaphore::LockTimeout(const struct timespec *timeout, int semnum)
+{
+	struct sembuf sb;
+	sb.sem_num	= (unsigned short)semnum;
+	sb.sem_op	= -1;
+	sb.sem_flg	= SEM_UNDO;
+	return TimedOp(&sb, 1, timeout);
+}
+
+bool CSemaphore::LockTimeout(unsigned long msec, int semnum)
+{
+	struct timespec to;
+	to.tv_sec	= msec / 1000;
+	to.tv_nsec	= (msec % 1000) * 1000000;
+	return LockTimeout(&to, semnum);
+}
+
+bool CSemaphore::Unlock(int semnum)
+{
+	struct sembuf sb;
+	sb.sem_num	= (unsigned short)semnum;
+	sb.sem_op	= 1;
+	sb.sem_flg	= SEM_UNDO;
+	return Op(&sb, 1);
+}
+
+bool CSemaphore::WaitZero(int semnum)
+{
+	struct sembuf sb;
+	sb.sem_num	= (unsigned short)semnum;
+	sb.sem_op	= 0;
+	sb.sem_flg	= SEM_UNDO;
+	return Op(&sb, 1);
+}
+
+bool CSemaphore::WaitZeroTimeout(const struct timespec *timeout, int semnum)
+{
+	struct sembuf sb;
+	sb.sem_num	= (unsigned short)semnum;
+	sb.sem_op	= 0;
+	sb.sem_flg	= SEM_UNDO;
+	return TimedOp(&sb, 1, timeout);
+}
+
+bool CSemaphore::WaitZeroTimeout(unsigned long msec, int semnum)
+{
+	struct timespec to;
+	to.tv_sec	= msec / 1000;
+	to.tv_nsec	= (msec % 1000) * 1000000;
+	return WaitZeroTimeout(&to, semnum);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CSemaphore::DumpIpcPerm(struct ipc_perm *ip)
+{
+	printf("__key: 0x%X\n", ip->__key);
+	printf("uid:   %d\n", ip->uid);
+	printf("gid:   %d\n", ip->gid);
+	printf("cuid:  %d\n", ip->cuid);
+	printf("cgid:  %d\n", ip->cgid);
+	printf("mode:  %hu\n", ip->mode);
+	printf("__seq: %hu\n", ip->__seq);
+}
+
+void CSemaphore::DumpSemidDs(struct semid_ds *sid)
+{
+	CSemaphore::DumpIpcPerm(&sid->sem_perm);
+	printf("sem_otime: %lu\n", sid->sem_otime);
+	printf("sem_ctime: %lu\n", sid->sem_ctime);
+	printf("sem_nsems: %lu\n", sid->sem_nsems);
+}
+
+void CSemaphore::DumpSeminfo(struct seminfo *psi)
+{
+	printf("semmap: %d\n", psi->semmap);
+	printf("semmni: %d\n", psi->semmni);
+	printf("semmns: %d\n", psi->semmns);
+	printf("semmnu: %d\n", psi->semmnu);
+	printf("semmsl: %d\n", psi->semmsl);
+	printf("semopm: %d\n", psi->semopm);
+	printf("semume: %d\n", psi->semume);
+	printf("semusz: %d\n", psi->semusz);
+	printf("semvmx: %d\n", psi->semvmx);
+	printf("semaem: %d\n\n", psi->semaem);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+CShmSemaphore::CShmSemaphore(void)
+{
+}
+
+CShmSemaphore::~CShmSemaphore(void)
+{
+	Release();
+}
+
+int CShmSemaphore::Create(const char *pszFilename)
+{
+	int nRet;
+	unsigned short nVals[2] = {1, 0};
+	if((nRet = CSemaphore::Create(pszFilename, 2, nVals)) < 0)
+		return nRet;
+	Unlock(1);
+	TRACE("CShmSemaphore::Create\n");
+	return nRet;
+}
+
+int CShmSemaphore::Create(const uuid_t &ruuid, const char *pszDir)
+{
+	if(!pszDir)
+		pszDir = "";
+
+	size_t nLenReq = strlen(pszDir) + _UUID_STRING_LEN + 2;
+
+	if(nLenReq > PATH_MAX)
+	{
+		TRACE("CShmSemaphore::Create: directory name too long\n");
+		errno = EINVAL;
+		return -1;
+	}
+
+	char szUuid[_UUID_STRING_LEN + 1];
+	char szSema[PATH_MAX];
+	_uuid_unparse(&ruuid, szUuid, sizeof(szUuid));
+	sprintf(szSema, "%s/%s.sem", pszDir, szUuid);
+	return Create(szSema);
+}
+
+void CShmSemaphore::Release(void)
+{
+	if(_IS_VALID_SEMID(m_nSemID))
+	{
+		int nRefs = GetVal(1);
+
+		if(nRefs > 1)
+		{
+			TRACE("CShmSemaphore::Release: remaining References: %d\n", nRefs - 1);
+			Lock(1);
+		}
+		else if(nRefs == 1)
+		{
+			TRACE("CShmSemaphore::Release: remaining References: %d - Semaphore removed!\n", nRefs - 1);
+			IpcRmID();
+		}
+
+		CSemaphore::Release();
+	}
+}

+ 113 - 0
package/libgfaipc/src/sema.h

@@ -0,0 +1,113 @@
+// sema.h :
+//
+
+#if !defined(AGD_SEMA_H__EA777512_58F6_495A_A36F_1272222A4749__INCLUDED_)
+#define AGD_SEMA_H__EA777512_58F6_495A_A36F_1272222A4749__INCLUDED_
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include "uuid.h"
+
+#define _SHM_SEMA_RECURSIVE				1
+
+/////////////////////////////////////////////////////////////////////////////
+// sema.h - Declarations:
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+union semun
+{
+	int              val;    // Value for SETVAL
+	struct semid_ds *buf;    // Buffer for IPC_STAT, IPC_SET
+	unsigned short  *array;  // Array for GETALL, SETALL
+	struct seminfo  *__buf;  // Buffer for IPC_INFO	(Linux-specific)
+};
+
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+class CSemaphore
+{
+public:
+	CSemaphore(void);
+	virtual ~CSemaphore(void);
+
+	virtual int Create(const char *pszFilename, int nsems, unsigned short *pInitArr = NULL);
+	virtual void Release(void);
+
+	int Ctl(int cmd);
+	int Ctl(int semnum, int cmd);
+	int Ctl(int semnum, int cmd, int val);
+	int Ctl(int cmd, struct semid_ds *buf);
+	int Ctl(int cmd, unsigned short *arr);
+	int Ctl(int cmd, struct seminfo *si);
+
+	int IpcStat(struct semid_ds *buf);
+	int IpcInfo(struct seminfo *si);
+	int IpcSet(struct semid_ds *buf);
+	int IpcRmID(void);
+	int SemStat(int index, struct semid_ds *buf);
+	int SemInfo(struct seminfo *si);
+	int GetVal(int semnum = 0);
+	int SetVal(int semnum, int val);
+	int GetAll(unsigned short *arr);
+	int SetAll(unsigned short *arr);
+	int GetPid(int semnum = 0);
+	int GetNCnt(int semnum = 0);
+	int GetZCnt(int semnum = 0);
+
+	bool Op(struct sembuf *sops, size_t nsops);
+	bool TimedOp(struct sembuf *sops, size_t nsops, const struct timespec *timeout);
+
+	bool Lock(int semnum = 0);
+	bool LockTimeout(const struct timespec *timeout, int semnum = 0);
+	bool LockTimeout(unsigned long msec, int semnum = 0);
+	bool Unlock(int semnum = 0);
+	bool WaitZero(int semnum = 0);
+	bool WaitZeroTimeout(const struct timespec *timeout, int semnum = 0);
+	bool WaitZeroTimeout(unsigned long msec, int semnum = 0);
+
+	static void DumpIpcPerm(struct ipc_perm *ip);
+	static void DumpSemidDs(struct semid_ds *sid);
+	static void DumpSeminfo(struct seminfo *psi);
+
+protected:
+	int Ctl(int semnum, int cmd, union semun su);
+
+protected:
+	int m_nSemID;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN32
+#define _DEF_SEMA_DIR						"."
+#endif	//	_WIN32
+
+#ifdef __linux__
+#define _DEF_SEMA_DIR						"/tmp"
+#endif	//	__linux__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CShmSemaphore : public CSemaphore
+{
+public:
+	CShmSemaphore(void);
+	virtual ~CShmSemaphore(void);
+
+	virtual int Create(const char *pszFilename);
+	virtual int Create(const uuid_t &ruuid, const char *pszDir = _DEF_SEMA_DIR);
+	virtual void Release(void);
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_SEMA_H__EA777512_58F6_495A_A36F_1272222A4749__INCLUDED_)

+ 378 - 0
package/libgfaipc/src/shm.cpp

@@ -0,0 +1,378 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <windows.h>
+#include <io.h>
+#include "../Win32/w32def.h"
+#endif	//	_WIN32
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/file.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <linux/limits.h>
+#include <sys/shm.h>
+#endif	//	__linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "shm.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _IS_VALID_SHMID(id)				((id) >= 0)
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CShmLocker
+{
+public:
+	CShmLocker(CGlobalMutex &rMutex) :	m_bLocked(false),
+										m_rMutex(rMutex)
+	{
+		m_bLocked = m_rMutex.Lock();
+	}
+
+	~CShmLocker(void)
+	{
+		if(m_bLocked)
+			m_bLocked = !m_rMutex.Unlock();
+	}
+
+private:
+	bool m_bLocked;
+	CGlobalMutex &m_rMutex;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+CShm::CShm(void) :	m_nShmID(_INVALID_ID)
+{
+	memset(&m_uuid, 0, sizeof(m_uuid));
+}
+
+CShm::~CShm(void)
+{
+	Release();
+}
+
+int CShm::Create(const uuid_t &ruuid, size_t nCbShm, const char *pszDir)
+{
+	if(!pszDir)
+		pszDir = "";
+
+	size_t nLenReq = strlen(pszDir) + _UUID_STRING_LEN + 2;
+
+	if(nLenReq > PATH_MAX)
+	{
+		TRACE("CShm::Create: directory name too long\n");
+		errno = EINVAL;
+		return -1;
+	}
+
+	int nRet = -1;
+	char szUuid[_UUID_STRING_LEN + 1];
+	char szShm[PATH_MAX];
+	_uuid_unparse(&ruuid, szUuid, sizeof(szUuid));
+	sprintf(szShm, "%s/%s.shm", pszDir, szUuid);
+
+	if(m_mutex.Create(ruuid, pszDir) < 0)
+		return -1;
+
+	int nFdShm;
+//	CShmLocker locker(m_mutex);
+
+	if((nFdShm = ::open(szShm, O_RDWR | O_CREAT | O_TRUNC, _NUMBER_OF_THE_BEAST)) >= 0)
+	{
+		key_t shmKey;
+
+		if((shmKey = ::ftok(szShm, 'R')) >= 0)
+		{
+			if((m_nShmID = ::shmget(shmKey, nCbShm, IPC_CREAT | _NUMBER_OF_THE_BEAST)) >= 0)
+			{
+				struct shmid_ds sds;
+				memset(&sds, 0, sizeof(sds));
+
+				if(!IpcStat(&sds))
+				{
+					if(!sds.shm_atime)
+					{
+						void *p = ::shmat(m_nShmID, NULL, 0);
+						::shmdt(p);
+						TRACE("CShm::Create: Created new SHM: ID: %d, Size: %zu\n", m_nShmID, nCbShm);
+						nRet = 1;
+					}
+					else
+					{
+						TRACE("CShm::Create: Opened existing SHM: ID: %d, Size: %zu\n", m_nShmID, nCbShm);
+						nRet = 0;
+					}
+
+					_uuid_copy(&m_uuid, &ruuid);
+				}
+				else
+				{
+					TRACE("CShm::Create: IpcStat failed - errno: %d!\n", errno);
+				}
+			}
+			else
+			{
+				TRACE("CShm::Create: Failed to create SHM on Key: 0x%08X - errno: %d!\n", shmKey, errno);
+			}
+		}
+		else
+		{
+			TRACE("CShm::Create: Failed to create shmKey - errno: %d!\n", errno);
+		}
+
+		close(nFdShm);
+	}
+	else
+	{
+		TRACE("CShm::Create: Failed to open '%s' - errno: %d!\n", szShm, errno);
+	}
+
+	return nRet;
+}
+
+long CShm::Release(void)
+{
+	long att = -1;
+	CShmLocker locker(m_mutex);
+
+	if(_IS_VALID_SHMID(m_nShmID))
+	{
+		att = GetNumAttached();
+
+		if(att == 0)
+		{
+			TRACE("CShm::Release: attached: %ld - SHM removed!\n", att);
+			IpcRmID();
+		}
+		else if(att > 0)
+		{
+			TRACE("CShm::Release: Still attached: %ld!\n", att);
+		}
+
+		m_nShmID = _INVALID_ID;
+	}
+
+	return att;
+}
+
+void* CShm::Attach(const void *pAddr, int shmflg)
+{
+	CShmLocker locker(m_mutex);
+
+	if(!_IS_VALID_SHMID(m_nShmID))
+	{
+		TRACE("CShm::Attach: Invalid ShmID: %d!\n", m_nShmID);
+		errno = EINVAL;
+		return NULL;
+	}
+
+	void *p = ::shmat(m_nShmID, pAddr, shmflg);
+
+	if(p == (void*)-1)
+	{
+		TRACE("CShm::Attach: Failed to attach memory - errno: %d!\n", errno);
+		p = NULL;
+	}
+	else
+	{
+		TRACE("CShm::Attach: %p!\n", p);
+	}
+
+	return p;
+}
+
+void CShm::Detach(const void *pAddr)
+{
+	if(pAddr)
+	{
+		TRACE("CShm::Detach: %p!\n", pAddr);
+		CShmLocker locker(m_mutex);
+		::shmdt(pAddr);
+	}
+}
+
+long CShm::GetNumAttached(void)
+{
+	long att = -1;
+	struct shmid_ds sds;
+	if(!IpcStat(&sds))
+		att = (long)sds.shm_nattch;
+	return att;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CShm::Ctl(int cmd, struct shmid_ds *pshd)
+{
+	if(!_IS_VALID_SHMID(m_nShmID))
+	{
+		TRACE("CShm::Ctl: Invalid ShmID: %d!\n", m_nShmID);
+		errno = EINVAL;
+		return -1;
+	}
+
+	return ::shmctl(m_nShmID, cmd, pshd);
+}
+
+int CShm::Ctl(int cmd)
+{
+	return Ctl(cmd, (struct shmid_ds*)NULL);
+}
+
+int CShm::Ctl(int cmd, struct shminfo *pinfo)
+{
+	return Ctl(cmd, (struct shmid_ds*)pinfo);
+}
+
+int CShm::Ctl(int cmd, struct shm_info *pinfo)
+{
+	return Ctl(cmd, (struct shmid_ds*)pinfo);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CShm::IpcStat(struct shmid_ds *buf)
+{
+	return Ctl(IPC_STAT, buf);
+}
+
+int CShm::IpcInfo(struct shminfo *si)
+{
+	return Ctl(IPC_INFO, si);
+}
+
+int CShm::IpcSet(struct shmid_ds *buf)
+{
+	return Ctl(IPC_SET, buf);
+}
+
+int CShm::IpcRmID(void)
+{
+	return Ctl(IPC_RMID);
+}
+
+int CShm::ShmStat(int index, struct shmid_ds *buf)
+{
+	return ::shmctl(index, SHM_STAT, buf);
+}
+
+int CShm::ShmInfo(struct shm_info *pinfo)
+{
+	return Ctl(SHM_INFO, pinfo);
+}
+
+int CShm::Lock(void)
+{
+	return m_mutex.Lock();
+}
+
+int CShm::Unlock(void)
+{
+	return m_mutex.Unlock();
+}
+
+long CShm::InterlockedIncrement(volatile long *pl)
+{
+	if(!pl)
+	{
+		TRACE("CShm::InterlockedIncrement: Invalid Argument!\n");
+		return 0;
+	}
+
+	long l;
+	m_mutex.Lock();
+	l = ++(*pl);
+	m_mutex.Unlock();
+	return l;
+}
+
+long CShm::InterlockedDecrement(volatile long *pl)
+{
+	if(!pl)
+	{
+		TRACE("CShm::InterlockedDecrement: Invalid Argument!\n");
+		return 0;
+	}
+
+	long l;
+	m_mutex.Lock();
+	l = --(*pl);
+	m_mutex.Unlock();
+	return l;
+}
+
+long CShm::InterlockedCompare(volatile long *pl, long comparand)
+{
+	if(!pl)
+	{
+		TRACE("CShm::InterlockedCompare: Invalid Argument!\n");
+		return 0;
+	}
+
+	long l;
+	m_mutex.Lock();
+	l = *pl - comparand;
+	m_mutex.Unlock();
+	return l;
+}
+
+long CShm::InterlockedSet(volatile long *pl, long val)
+{
+	if(!pl)
+	{
+		TRACE("CShm::InterlockedSet: Invalid Argument!\n");
+		return 0;
+	}
+
+	long l;
+	m_mutex.Lock();
+	l = *pl;
+	*pl = val;
+	m_mutex.Unlock();
+	return l;
+}
+
+long CShm::InterlockedClear(volatile long *pl)
+{
+	if(!pl)
+	{
+		TRACE("CShm::InterlockedClear: Invalid Argument!\n");
+		return 0;
+	}
+
+	long l;
+	m_mutex.Lock();
+	l = *pl;
+	*pl = 0;
+	m_mutex.Unlock();
+	return l;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CShm::DumpIpcPerm(struct ipc_perm *ip)
+{
+	CSemaphore::DumpIpcPerm(ip);
+}
+
+void CShm::DumpShmidDs(struct shmid_ds *sid)
+{
+	CShm::DumpIpcPerm(&sid->shm_perm);
+	printf("shm_segsz:  %zu\n", sid->shm_segsz);
+	printf("shm_atime:  %lu\n", sid->shm_atime);
+	printf("shm_dtime:  %lu\n", sid->shm_dtime);
+	printf("shm_ctime:  %lu\n", sid->shm_ctime);
+	printf("shm_cpid:  %hd\n", sid->shm_cpid);
+	printf("shm_lpid:   %hd\n", sid->shm_lpid);
+	printf("shm_nattch: %lu\n", sid->shm_nattch);
+}

+ 73 - 0
package/libgfaipc/src/shm.h

@@ -0,0 +1,73 @@
+// shm.h :
+//
+
+#if !defined(AGD_SHM_H__AD9FF941_0114_4585_8EF1_0A4ACA7DC0AD__INCLUDED_)
+#define AGD_SHM_H__AD9FF941_0114_4585_8EF1_0A4ACA7DC0AD__INCLUDED_
+
+#include "mutex.h"
+#include "sema.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// shm.h - Declarations:
+
+#ifdef _WIN32
+#define _DEF_SHM_DIR						"."
+#endif	//	_WIN32
+
+#ifdef __linux__
+#define _DEF_SHM_DIR						"/tmp"
+#endif	//	__linux__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CShm
+{
+public:
+	CShm(void);
+	virtual ~CShm(void);
+
+	int Create(const uuid_t &ruuid, size_t nCbShm, const char *pszDir = _DEF_SHM_DIR);
+	long Release(void);
+
+	void* Attach(const void *pAddr = NULL, int shmflg = 0);
+	void Detach(const void *pAddr);
+	long GetNumAttached(void);
+
+	int Ctl(int cmd);
+	int Ctl(int cmd, struct shmid_ds *pshd);
+	int Ctl(int cmd, struct shminfo *pinfo);
+	int Ctl(int cmd, struct shm_info *pinfo);
+
+	int IpcStat(struct shmid_ds *buf);
+	int IpcInfo(struct shminfo *si);
+	int IpcSet(struct shmid_ds *buf);
+	int IpcRmID(void);
+
+	int ShmStat(int index, struct shmid_ds *buf);
+	int ShmInfo(struct shm_info *pinfo);
+
+	int Lock(void);
+	int Unlock(void);
+
+	const uuid_t& Uuid() const {
+		return m_uuid;}
+
+	long InterlockedIncrement(volatile long *pl);
+	long InterlockedDecrement(volatile long *pl);
+	long InterlockedCompare(volatile long *pl, long comparand);
+	long InterlockedSet(volatile long *pl, long val);
+	long InterlockedClear(volatile long *pl);
+
+	static void DumpIpcPerm(struct ipc_perm *ip);
+	static void DumpShmidDs(struct shmid_ds *sid);
+
+private:
+
+private:
+	int m_nShmID;
+	CGlobalMutex m_mutex;
+	uuid_t m_uuid;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_SHM_H__AD9FF941_0114_4585_8EF1_0A4ACA7DC0AD__INCLUDED_)

+ 299 - 0
package/libgfaipc/src/shmrot.cpp

@@ -0,0 +1,299 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS
+#include <windows.h>
+#include <io.h>
+#include "../Win32/w32def.h"
+#endif	//	_WIN32
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/file.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <linux/limits.h>
+#include <sys/shm.h>
+#endif	//	__linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "defines.h"
+#include "shmrot.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _FILES_DIRECTORY				"/tmp"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _SHMROT_ENTRY_FLAG_VALID		0x00000001
+
+/////////////////////////////////////////////////////////////////////////////
+
+// {99df2b86-f904-425d-9fcc-c83c329d0937}
+DEFINE_UUID(GUID_SHMROT, 0x99df2b86, 0xf904, 0x425d, 0x9f, 0xcc, 0xc8, 0x3c, 0x32, 0x9d, 0x09, 0x37);
+
+/////////////////////////////////////////////////////////////////////////////
+
+CShmROT::CShmROT(void)	: m_pTable(NULL)
+{
+}
+
+CShmROT::~CShmROT(void)
+{
+	Release();
+}
+
+bool CShmROT::Create(void)
+{
+	TRACE("CShmROT::Create!\n");
+
+	int nRet = m_shmRot.Create(GUID_SHMROT, sizeof(SHMROT));
+
+	if(	nRet >= 0 &&
+		(m_pTable = (LPSHMROT)m_shmRot.Attach()))
+	{
+		if(nRet == 1)
+		{
+			m_pTable->version		= _ROT_CURRENT_VERSION;
+			m_pTable->maxEntries	= _ROT_MAX_TABLE_ENTRIES;
+			m_pTable->entrySize		= (uint32_t)sizeof(SHMROT_ENTRY);
+
+		}
+		else if(nRet == 0)
+		{
+			if(m_pTable->version != _ROT_CURRENT_VERSION)
+			{
+				// ...
+			}
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
+void CShmROT::Release(void)
+{
+	if(m_pTable)
+	{
+		TRACE("CShmROT::Release!\n");
+		m_shmRot.Detach(m_pTable);
+		m_shmRot.Release();
+		m_pTable = NULL;
+	}
+}
+
+CShm* CShmROT::AcquireShm(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName)
+{
+	if(!m_pTable)
+	{
+		TRACE("CShmROT::AcquireShm: ROT not initialized!\n");
+		return NULL;
+	}
+
+	uuid_t uuid;
+	CShm *pShm = NULL;
+
+	if(!_uuid_parse(pszUuid, &uuid))
+	{
+		TRACE("CShmROT::AcquireShm: invalid uuid!\n");
+		return NULL;
+	}
+
+	int nIndexFound			= -1;
+	int nFirstUnusedIndex	= -1;
+
+	for(int i = 0; i < (int)m_pTable->maxEntries; i++)
+	{
+		SHMROT_ENTRY &re = m_pTable->rot[i];
+
+		if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
+		{
+			if(!_uuid_compare(&re.uuid, &uuid))
+			{
+				nIndexFound = i;
+				break;
+			}
+		}
+		else if(nFirstUnusedIndex == -1)
+		{
+			nFirstUnusedIndex = i;
+		}
+	}
+
+	if(nIndexFound >= 0) // found existing entry
+	{
+		SHMROT_ENTRY &re = m_pTable->rot[nIndexFound];
+		bool bMatch = (re.nSizeElement == nSizeElement) && (re.nCntElements == nCntElements);
+
+		if(bMatch)
+		{
+			TRACE("CShmROT::AcquireShm: Found matching SHM entry!\n");
+
+			if((pShm = new CShm))
+			{
+				if(pShm->Create(uuid, nSizeElement * nCntElements) < 0)
+				{
+					pShm->Release();
+					delete pShm;
+					pShm = NULL;
+					TRACE("CShmROT::AcquireShm: Failed to create new CShm!\n");
+				}
+				else
+				{
+					re.nCntHandles++;
+				}
+			}
+			else
+			{
+				TRACE("CShmROT::AcquireShm: Failed to allocate new CShm!\n");
+			}
+		}
+		else
+		{
+			TRACE("CShmROT::AcquireShm: SHM uuid exists, but size does not match!\n");
+		}
+	}
+	else if(nFirstUnusedIndex >= 0) // next free slot
+	{
+		TRACE("CShmROT::AcquireShm: Create new SHM entry!\n");
+
+		SHMROT_ENTRY &re = m_pTable->rot[nFirstUnusedIndex];
+
+		if((pShm = new CShm))
+		{
+			if(pShm->Create(uuid, nSizeElement * nCntElements) < 0)
+			{
+				pShm->Release();
+				delete pShm;
+				pShm = NULL;
+				TRACE("CShmROT::AcquireShm: Failed to create new CShm!\n");
+			}
+			else
+			{
+				re.flags		= _SHMROT_ENTRY_FLAG_VALID;
+				re.nSizeElement	= (uint32_t)nSizeElement;
+				re.nCntElements	= (uint32_t)nCntElements;
+				re.nCntHandles	= 1;
+				_uuid_copy(&re.uuid, &uuid);
+				memset(re.szDescName, 0, sizeof(re.szDescName));
+
+				if(pszDescName)
+				{
+					size_t nLen = strlen(pszDescName);
+
+					if(nLen > 0)
+					{
+						if(nLen >= _ROT_MAX_ENTRY_NAME)
+							nLen = _ROT_MAX_ENTRY_NAME - 1;
+						memcpy(re.szDescName, pszDescName, nLen);
+						re.szDescName[nLen] = '\0';
+					}
+				}
+			}
+		}
+		else
+		{
+			TRACE("CShmROT::AcquireShm: Failed to allocate new CShm!\n");
+		}
+	}
+	else
+	{
+		TRACE("CShmROT::AcquireShm: SHM uuid not found and no slot available!\n");
+	}
+
+	return pShm;
+}
+
+void CShmROT::ReleaseShm(CShm *pShm)
+{
+	if(pShm)
+	{
+		const uuid_t &ruuid = pShm->Uuid();
+
+		for(int i = 0; i < (int)m_pTable->maxEntries; i++)
+		{
+			SHMROT_ENTRY &re = m_pTable->rot[i];
+
+			if(!_uuid_compare(&re.uuid, &ruuid))
+			{
+				if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
+				{
+					if(re.nCntHandles > 0)
+						--re.nCntHandles;
+						
+					if(re.nCntHandles == 0)
+						re.flags &= ~_SHMROT_ENTRY_FLAG_VALID;
+				}
+
+				break;
+			}
+		}
+
+		pShm->Release();
+		delete pShm;
+	}
+}
+
+int CShmROT::Lock(void)
+{
+	return m_shmRot.Lock();
+}
+
+int CShmROT::Unlock(void)
+{
+	return m_shmRot.Unlock();
+}
+
+void CShmROT::DumpEntries(CShmHandleMap &map)
+{
+	if(!m_pTable)
+	{
+		printf("CShmROT::DumpEntries: ROT not initialized!\n");
+		return;
+	}
+
+	char szUuid[_UUID_STRING_LEN + 1];
+
+	Lock();
+
+	for(int i = 0; i < (int)m_pTable->maxEntries; i++)
+	{
+		SHMROT_ENTRY &re = m_pTable->rot[i];
+
+		if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
+		{
+			unsigned long nAttached = 0;
+			_uuid_unparse(&re.uuid, szUuid, sizeof(szUuid));
+
+			if(re.nCntHandles > 0)
+			{
+				CShm *pShm = map.LookupShm(re.uuid);
+				if(pShm)
+					nAttached = pShm->GetNumAttached();
+			}
+
+			printf(	"uuid: '%s',\n"						\
+					"    flags:              0x%08x,\n"	\
+					"    size of element:    %u,\n"		\
+					"    number of elements: %u,\n"		\
+					"    name:               '%s',\n"	\
+					"    number of handles:  %u,\n"		\
+					"    number of pointers: %lu\n",
+					szUuid,
+					re.flags,
+					re.nSizeElement,
+					re.nCntElements,
+					re.szDescName,
+					re.nCntHandles,
+					nAttached);
+		}
+	}
+
+	Unlock();
+}

+ 99 - 0
package/libgfaipc/src/shmrot.h

@@ -0,0 +1,99 @@
+// shmrot.h :
+//
+
+#if !defined(AGD_SHMROT_H__58C9857B_4E4E_4AE1_B093_DFECBB85F652__INCLUDED_)
+#define AGD_SHMROT_H__58C9857B_4E4E_4AE1_B093_DFECBB85F652__INCLUDED_
+
+#include "gfaipc.h"
+#include "shm.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// shmrot.h - Declarations:
+
+typedef struct _SHM_HANDLE
+{
+	CShm *pShm;
+}SHM_HANDLE, *LPSHM_HANDLE;
+typedef const SHM_HANDLE *LPCSHM_HANDLE;
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _IPCSHM_MAX_HANDLES			32
+
+class CShmHandleMap
+{
+public:
+	CShmHandleMap(void);
+	~CShmHandleMap(void);
+
+	HSHM AcquireHandle(CShm *pShm);
+	void ReleaseHandle(HSHM hShm);
+	CShm* LookupShm(const uuid_t &uuid);
+
+private:
+	SHM_HANDLE m_handles[_IPCSHM_MAX_HANDLES];
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _ROT_MAX_TABLE_ENTRIES			32
+#define _ROT_MAX_ENTRY_NAME				128
+
+#define _ROT_MAKE_VERSION(ma, mi)		(((ma) << 16) | (mi))
+#define _ROT_VERSION_MAJOR(ver)			(((ver) >> 16) & 0x0000FFFF)
+#define _ROT_VERSION_MINOR(ver)			((ver) & 0x0000FFFF)
+#define _ROT_CURRENT_VERSION			_ROT_MAKE_VERSION(1, 0)
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct _SHMROT_ENTRY
+{
+	uuid_t uuid;
+	uint32_t flags;
+	uint32_t nSizeElement;
+	uint32_t nCntElements;
+	uint32_t nCntHandles;
+	uint32_t reserved[4];
+	char szDescName[_ROT_MAX_ENTRY_NAME];
+}SHMROT_ENTRY, *LPSHMROT_ENTRY;
+typedef const SHMROT_ENTRY *LPCSHMROT_ENTRY;
+
+typedef struct _SHMROT
+{
+	uint32_t version;		// major << 16, minor version
+	uint32_t maxEntries;	// sollte _ROT_MAX_TABLE_ENTRIES sein
+	uint32_t entrySize;
+	uint32_t reserved[5];
+	SHMROT_ENTRY rot[_ROT_MAX_TABLE_ENTRIES];
+}SHMROT, *LPSHMROT;
+typedef const SHMROT *LPCSHMROT;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CShmROT
+{
+public:
+	CShmROT(void);
+	virtual ~CShmROT(void);
+
+	bool Create(void);
+	void Release(void);
+
+	CShm* AcquireShm(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName);
+	void ReleaseShm(CShm *pShm);
+
+	int Lock(void);
+	int Unlock(void);
+
+	bool Created(void) const {
+		return !!m_pTable;}
+
+	void DumpEntries(CShmHandleMap &map);
+
+private:
+	CShm m_shmRot;
+	LPSHMROT m_pTable;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_SHMROT_H__58C9857B_4E4E_4AE1_B093_DFECBB85F652__INCLUDED_)

+ 79 - 0
package/libgfaipc/src/shmstrvar.cpp

@@ -0,0 +1,79 @@
+#include "shmvar.h"
+#include <QDebug>
+
+#define _IS_VALID_VT(vt)		((vt > CShmStringVariable::VT_Invalid) && (vt < CShmStringVariable::VT_Last))
+
+CShmStringVariable::CShmStringVariable(void *pData, size_t nCChData, VT vt, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, QObject *pParent)
+{
+	if(!pData || !hShm || !nCChData || !_IS_VALID_VT(vt))
+	{
+		Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Invalid parameter!");
+		return;
+	}
+
+    m_data.pVoid = pData;
+    m_hShm = hShm;
+    setObjectName(QStringLiteral("CShmVariable"));
+    if((m_nIndex = nIndex) >= 0)
+	{
+		m_varName += QString("%1%2%3").arg('[').arg(nIndex).arg(']');
+	}
+
+    if((rti == typeid(signed char)) || (rti == typeid(unsigned char)))
+    {
+    }
+    else if(rti == typeid(wchar_t))
+	{
+	}
+    else
+	{
+		Q_ASSERT_X(false, "CShmStringVariable::CShmStringVariable", "Unknown data type!");
+	}
+}
+
+CShmStringVariable::~CShmStringVariable(void)
+{
+}
+
+void CShmStringVariable::valRaw(QString &v)
+{
+}
+
+QString CShmStringVariable::val(void)
+{
+}
+
+void CShmStringVariable::setVal(const QString &val)
+{
+}
+
+unsigned long long CShmStringVariable::CheckUpdateShm(bool fLock)
+{
+	return 0;
+}
+
+
+void CShmStringVariable::Lock(void)
+{
+	::GfaIpcLockSHM(m_hShm);
+//	qDebug() << "CShmStringVariable::Lock";
+}
+
+void CShmStringVariable::Unlock(void)
+{
+//	qDebug() << "CShmStringVariable::Unlock";
+	::GfaIpcUnlockSHM(m_hShm);
+}
+
+void CShmStringVariable::emitChanged(bool fLock)
+{
+//    qDebug() << "CShmStringVariable: val changed!";
+	if(fLock)
+	    emit valChanged(val());
+	else
+	{
+	    QString v;
+	    valRaw(v);
+	    emit valChanged(v);
+	}
+}

+ 69 - 0
package/libgfaipc/src/uuid.c

@@ -0,0 +1,69 @@
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#include <windows.h>
+#endif	//	_WIN32
+
+#include "uuid.h"
+#include <stdio.h>
+#include <string.h>
+
+DEFINE_UUID(UUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+int _uuid_parse(const char *pszIn, uuid_t *uuid)
+{
+	int i, nRet = 0;
+
+	if(pszIn && uuid && strlen(pszIn) == _UUID_STRING_LEN)
+	{
+		int n[8];
+
+		nRet = sscanf(pszIn,
+				"%08x-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x",
+				&uuid->Data1,
+				&uuid->Data2,
+				&uuid->Data3,
+				&n[0], &n[1],
+				&n[2], &n[3], &n[4], &n[5], &n[6], &n[7]);
+
+		if(nRet == 11)
+		{
+			for(i = 0; i < 8; i++)
+			{
+				uuid->Data4[i] = (unsigned char)n[i];
+			}
+		}
+	}
+
+	return nRet == 11;
+}
+
+int _uuid_unparse(const uuid_t *uuid, char *pszOut, size_t nCChOut)
+{
+	if(!uuid || !pszOut || nCChOut <= _UUID_STRING_LEN)
+		return 0;
+
+	return sprintf(pszOut, "%08x-%04hx-%04hx-%02hx%02hx-%02hx%02hx%02hx%02hx%02hx%02hx",
+				uuid->Data1,
+				uuid->Data2,
+				uuid->Data3,
+				uuid->Data4[0], uuid->Data4[1],
+				uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
+}
+
+int _uuid_compare(const uuid_t *uuid1, const uuid_t *uuid2)
+{
+	if(uuid1 && uuid2)
+		return memcmp(uuid1, uuid2, sizeof(uuid_t));
+	return 0;
+}
+
+void _uuid_copy(uuid_t *uuDest, const uuid_t *uuSrc)
+{
+	if(uuDest && uuSrc)
+		memcpy(uuDest, uuSrc, sizeof(uuid_t));
+}
+
+int _uuid_is_null(const uuid_t *uuid)
+{
+	return !_uuid_compare(uuid, &UUID_NULL);
+}

+ 49 - 0
package/libgfaipc/src/uuid.h

@@ -0,0 +1,49 @@
+// uuid.h :
+//
+
+#if !defined(AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_)
+#define AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// uuid.h - Declarations:
+
+#ifdef __linux__
+typedef struct _UUID
+{
+    uint32_t Data1;
+    uint16_t Data2;
+    uint16_t Data3;
+    uint8_t  Data4[8];
+}UUID;
+#define uuid_t UUID
+#endif	//	__linux__
+
+#define DEFINE_UUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+											const uuid_t name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
+
+#define _UUID_STRING_LEN					36
+
+/////////////////////////////////////////////////////////////////////////////
+
+extern const uuid_t UUID_NULL;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int		_uuid_parse		(const char *pszIn, uuid_t *uuid);
+int		_uuid_unparse	(const uuid_t *uuid, char *pszOut, size_t nCChOut);
+int		_uuid_compare	(const uuid_t *uuid1, const uuid_t *uuid2);
+void	_uuid_copy		(uuid_t *uuDest, const uuid_t *uuSrc);
+int		_uuid_is_null	(const uuid_t *uuid);
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_)

+ 6 - 0
package/libgfatimer/Config.in

@@ -0,0 +1,6 @@
+config BR2_PACKAGE_LIBGFATIMER
+	bool "libgfatimer"
+	default y
+	help
+		libgfatimer component.config BR2_PACKAGE_LIBGFATIMER
+

+ 24 - 0
package/libgfatimer/libgfatimer.mk

@@ -0,0 +1,24 @@
+LIBGFATIMER_VERSION = 1.0.0
+LIBGFATIMER_SITE = ../GfA/package/libgfatimer/src
+LIBGFATIMER_SITE_METHOD = local
+LIBGFATIMER_INSTALL_STAGING = YES
+LIBGFATIMER_INSTALL_TARGET = YES
+
+define LIBGFATIMER_BUILD_CMDS
+	$(MAKE) CC="$(TARGET_CC)" CXX="$(TARGET_CXX)" LD="$(TARGET_LD)" -C $(@D) all
+endef
+
+define LIBGFATIMER_INSTALL_STAGING_CMDS
+	$(INSTALL) -D -m 0755 $(@D)/libgfatimer.so.1.0.0 $(STAGING_DIR)/usr/lib/libgfatimer.so.1.0.0
+	$(INSTALL) -D -m 0755 $(@D)/gfatimer.h $(STAGING_DIR)/usr/include/gfatimer.h
+	ln -sfn libgfatimer.so.1.0.0 $(STAGING_DIR)/usr/lib/libgfatimer.so.1
+	ln -sfn libgfatimer.so.1 $(STAGING_DIR)/usr/lib/libgfatimer.so
+endef
+
+define LIBGFATIMER_INSTALL_TARGET_CMDS
+	$(INSTALL) -D -m 0755 $(@D)/libgfatimer.so.1.0.0 $(TARGET_DIR)/usr/lib/libgfatimer.so.1.0.0
+	ln -sfn libgfatimer.so.1.0.0 $(TARGET_DIR)/usr/lib/libgfatimer.so.1
+	ln -sfn libgfatimer.so.1 $(TARGET_DIR)/usr/lib/libgfatimer.so
+endef
+
+$(eval $(generic-package))

+ 52 - 0
package/libgfatimer/src/Makefile

@@ -0,0 +1,52 @@
+# Change these if necessary
+DEBUG ?= 0
+        
+_LIBBASENAME=gfatimer
+LIBFILENAME=lib$(LIBBASENAME).so.1.0.0
+
+#CC = $(CROSS_COMPILE)gcc
+#CXX = $(CROSS_COMPILE)c++ 
+CFLAGS = -pthread -fPIC -Wall -Wno-unused -Wno-unused-label -Wformat -Wuninitialized -Wundef -Wcast-qual -Wwrite-strings -fabi-version=2 -fno-omit-frame-pointer
+CXXFLAGS = -pthread -fPIC -Wall -Wno-unused -Wno-unused-label -Wformat -Wuninitialized -Wundef -Wcast-qual -Wwrite-strings -std=c++11 -fabi-version=2 -fno-omit-frame-pointer
+LDFLAGS = -fPIC -shared -L. -lc -pthread
+
+ifeq ($(DEBUG), 1)
+	CFLAGS += -g
+	CXXFLAGS += -g
+	LDFLAGS += -g
+	LIBBASENAME = $(_LIBBASENAME)d
+else
+	CFLAGS += -O3
+	CXXFLAGS += -O3
+	LDFLAGS += -O3
+	LIBBASENAME = $(_LIBBASENAME)
+endif
+
+RM = rm -f  # rm command
+TARGET_LIB = $(LIBFILENAME) # target lib
+
+CSRCS =  # source files
+CXXSRCS = timer.cpp gfatimer.cpp # source files
+COBJS = $(CSRCS:.c=.o)
+CXXOBJS = $(CXXSRCS:.cpp=.o)
+
+.PHONY: all
+all: ${TARGET_LIB}
+
+$(TARGET_LIB): $(COBJS) $(CXXOBJS)
+	$(CC) ${LDFLAGS} -o $@ $^
+
+$(CSRCS:.c=.d):%.d:%.c
+	$(CC) $(CFLAGS) -MM $< >$@
+
+$(CXXSRCS:.cpp=.dpp):%.dpp:%.cpp
+	$(CXX) $(CXXFLAGS) -MM $< >$@
+
+include $(CSRCS:.c=.d) $(CXXSRCS:.cpp=.dpp)
+
+.PHONY: clean
+clean:
+	$(RM) $(TARGET_LIB) 
+	$(RM) *.o
+	$(RM) *.d
+	$(RM) *.dpp

+ 69 - 0
package/libgfatimer/src/gfatimer.cpp

@@ -0,0 +1,69 @@
+#include "gfatimer.h"
+#include "timer.h"
+
+static CGfaTimer g_gfaTimer;
+
+int GfaTimerInit(int nTimerCount, GfaTimerResolution res)
+{
+	return g_gfaTimer.Initialize(nTimerCount, res);
+}
+
+void GfaTimerRelease(void)
+{
+	g_gfaTimer.Release();
+}
+
+void GfaRegisterTimerCallback(int tnum, pfnTIMERCALLBACK pfnCallback, void *pContext)
+{
+	g_gfaTimer.RegisterTimerCallback(tnum, pfnCallback, pContext);
+}
+
+void GfaRegisterClockPulseCallback(GfaTimerClockPulse cp, pfnPULSECALLBACK pfnCallback, void *pContext)
+{
+	g_gfaTimer.RegisterClockPulseCallback(cp, pfnCallback, pContext);
+}
+
+void GfaUnregisterTimerCallback(int tnum)
+{
+	g_gfaTimer.RegisterTimerCallback(tnum, NULL, NULL);
+}
+
+void GfaUnregisterClockPulseCallback(GfaTimerClockPulse cp)
+{
+	g_gfaTimer.RegisterClockPulseCallback(cp, NULL, NULL);
+}
+
+int tf_test(int tnum)
+{
+	return g_gfaTimer.tf_test(tnum);
+}
+
+void tf_set(int tnum)
+{
+	g_gfaTimer.tf_set(tnum);
+}
+
+void tf_clear(int tnum)
+{
+	g_gfaTimer.tf_clear(tnum);
+}
+
+void tf_store(int tnum, int fset)
+{
+	g_gfaTimer.tf_store(tnum, fset);
+}
+
+unsigned long tw_read(int tnum)
+{
+	return g_gfaTimer.tw_read(tnum);
+}
+
+void tw_set(int tnum, unsigned long val)
+{
+	g_gfaTimer.tw_set(tnum, val);
+}
+
+int cp_test(GfaTimerClockPulse cp)
+{
+	return g_gfaTimer.cp_test(cp);
+}

+ 77 - 0
package/libgfatimer/src/gfatimer.h

@@ -0,0 +1,77 @@
+// gfatimer.h :
+//
+
+#if !defined(AGD_GFATIMER_H__60DC793C_D443_45EB_AD2F_D947862C2060__INCLUDED_)
+#define AGD_GFATIMER_H__60DC793C_D443_45EB_AD2F_D947862C2060__INCLUDED_
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// gfatimer.h - Declarations:
+
+typedef enum GfaTimerResolution
+{
+	GTR_Invalid,
+	GTR_10ms,
+	GTR_25ms,
+	GTR_50ms,
+	GTR_Last
+	
+}GfaTimerResolution;
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef enum GfaTimerClockPulse
+{
+	GTCP_Invalid = -1,
+	GTCP_250ms,
+	GTCP_500ms,
+	GTCP_750ms,
+	GTCP_1000ms,
+	GTCP_1500ms,
+	GTCP_2000ms,
+	GTCP_5000ms,
+	GTCP_10000ms,
+	GTCP_Last
+}GfaTimerClockPulse;
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef void (*pfnTIMERCALLBACK)(int, void*);
+typedef void (*pfnPULSECALLBACK)(GfaTimerClockPulse, int, void*);
+
+/////////////////////////////////////////////////////////////////////////////
+// initialization (if GfaTimerRelease is not called explicitly, clean up will
+// be done internally, if the process exits gracefully)
+
+int				GfaTimerInit(int nTimerCount, GfaTimerResolution res);
+void			GfaTimerRelease(void);
+
+void			GfaRegisterTimerCallback(int tnum, pfnTIMERCALLBACK pfnCallback, void *pContext);
+void			GfaUnregisterTimerCallback(int tnum);
+
+void			GfaRegisterClockPulseCallback(GfaTimerClockPulse cp, pfnPULSECALLBACK pfnCallback, void *pContext);
+void			GfaUnregisterClockPulseCallback(GfaTimerClockPulse cp);
+
+/////////////////////////////////////////////////////////////////////////////
+// mondial legacy timer API
+
+int				tf_test(int tnum);
+void			tf_set(int tnum);
+void			tf_clear(int tnum);
+void			tf_store(int tnum, int fset);
+unsigned long	tw_read(int tnum);
+void			tw_set(int tnum, unsigned long val); // val in milliseconds
+
+/////////////////////////////////////////////////////////////////////////////
+// test clock pulse (see GfaTimerClockPulse enumeration for possible values)
+
+int				cp_test(GfaTimerClockPulse cp);
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_GFATIMER_H__60DC793C_D443_45EB_AD2F_D947862C2060__INCLUDED_)

+ 66 - 0
package/libgfatimer/src/mutex.h

@@ -0,0 +1,66 @@
+// mutex.h :
+//
+
+#if !defined(AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_)
+#define AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "uuid.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// mutex.h - Declarations:
+
+#ifdef _WIN32
+#define _DEF_MUTEX_DIR						"."
+#endif	//	_WIN32
+
+#ifdef __linux__
+#define _DEF_MUTEX_DIR						"/tmp"
+#endif	//	__linux__
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CGlobalMutex
+{
+public:
+	CGlobalMutex(void);
+	virtual ~CGlobalMutex(void);
+
+	int Create(const uuid_t &ruuid, const char *pszDir = _DEF_MUTEX_DIR);
+	long Release(void);
+
+	bool Lock(void);
+	bool TryLock(void);
+	bool Unlock(void);
+
+private:
+	int m_nShmID;
+	pthread_mutexattr_t m_mutexAttr;
+	pthread_mutex_t *m_pMutex;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CLocalMutex
+{
+public:
+	CLocalMutex(void);
+	virtual ~CLocalMutex(void);
+
+	bool Create(bool bRecursive = false);
+	void Release(void);
+
+	bool Lock(void);
+	bool TryLock(void);
+	bool Unlock(void);
+
+private:
+	bool m_bInit;
+	pthread_mutexattr_t m_mutexAttr;
+	pthread_mutex_t m_mutex;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_MUTEX_H__307A751D_EF2D_45D6_BBA8_2EB4B79B548D__INCLUDED_)

+ 421 - 0
package/libgfatimer/src/timer.cpp

@@ -0,0 +1,421 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+
+#include <time.h>
+#include <errno.h>
+#include "timer.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef _DEBUG
+#define _VALIDATE_TIMER_RET(tnum, ret)		if(!ValidateTimer(tnum, __FUNCTION__)) return (ret)
+#define _VALIDATE_TIMER_VOID(tnum)			if(!ValidateTimer(tnum, __FUNCTION__)) return
+#define TRACE								printf
+#else	//	_DEBUG
+#define _VALIDATE_TIMER_RET(tnum, ret)
+#define _VALIDATE_TIMER_VOID(tnum)
+#define TRACE(...)
+#endif	//	_DEBUG
+
+#define _GFA_DEFAULT_TIMER_COUNT			32
+#define _GFA_MAX_TIMER_COUNT				256
+#define _COUNTOF(a)							(sizeof(a) / sizeof(*a))
+#define _INVALID_THREAD_ID					0
+#define _NANOSECS_PER_SEC					1000000000
+
+/////////////////////////////////////////////////////////////////////////////
+
+const int CGfaTimer::m_nPulseFreq[GTCP_Last] = {250, 500, 750, 1000, 1500, 2000, 5000, 10000};
+
+/////////////////////////////////////////////////////////////////////////////
+
+CGfaTimer::CGfaTimer(void) : m_pTimer(NULL), m_nTimerCount(0), m_nTimerIncrement(0), m_nClockCount(0), m_nClockPulse(0), m_threadID(_INVALID_THREAD_ID), m_bProcessTimers(false)
+{
+	memset(&m_timInterval, 0, sizeof(m_timInterval));
+	memset(m_ClkPulseCallbackTable, 0, sizeof(m_ClkPulseCallbackTable));
+
+	if(!m_mutex.Create(true))
+	{
+		TRACE("CGfaTimer::CGfaTimer: failed to create mutex!\n");
+		throw -1;
+	}
+}
+
+CGfaTimer::~CGfaTimer(void)
+{
+	Release();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CGfaTimer::Initialize(int nTimerCount, GfaTimerResolution res)
+{
+	if(!m_pTimer)
+	{
+		if(nTimerCount == 0)
+			nTimerCount = _GFA_DEFAULT_TIMER_COUNT;
+		else if(nTimerCount < 0)
+		{
+			TRACE("CGfaTimer::Initialize: invalid timer count: %d!\n", nTimerCount);
+			return 0;
+		}
+		else if(nTimerCount > _GFA_MAX_TIMER_COUNT)
+			nTimerCount = _GFA_MAX_TIMER_COUNT;
+
+		switch(res)
+		{
+		case GTR_10ms:
+			m_timInterval.tv_sec	= 0;
+			m_timInterval.tv_nsec	= 10000000;
+			m_nTimerIncrement		= 10;
+			break;
+		case GTR_25ms:
+			m_timInterval.tv_sec	= 0;
+			m_timInterval.tv_nsec	= 25000000;
+			m_nTimerIncrement		= 25;
+			break;
+		case GTR_50ms:
+			m_timInterval.tv_sec	= 0;
+			m_timInterval.tv_nsec	= 50000000;
+			m_nTimerIncrement		= 50;
+			break;
+		default:
+			TRACE("CGfaTimer::Initialize: invalid timer resolution: %d!\n", (int)res);
+			return 0;
+		}
+
+		m_pTimer = new GFA_TIMER[nTimerCount];
+		memset(m_pTimer, 0, sizeof(GFA_TIMER) * nTimerCount);
+		m_nTimerCount = nTimerCount;
+		m_bProcessTimers = true;
+
+		if(::pthread_create(&m_threadID, NULL, &CGfaTimer::LordOfTheTimers, reinterpret_cast<void*>(this)))
+		{
+			TRACE("CGfaTimer::Initialize: Failed to create timer thread!\n");
+			Release();
+		}
+
+		TRACE("CGfaTimer::Initialize: Success!\n");
+	}
+	else
+	{
+		TRACE("CGfaTimer::Initialize: Already initialized!\n");
+	}
+
+	return m_nTimerCount;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::Release(void)
+{
+	if(m_pTimer)
+	{
+		m_mutex.Lock();
+		if(m_threadID != _INVALID_THREAD_ID)
+		{
+			m_bProcessTimers = false;
+			m_mutex.Unlock();
+			::pthread_join(m_threadID, NULL);
+			m_mutex.Lock();
+			m_threadID = _INVALID_THREAD_ID;
+		}
+
+		m_nTimerCount = m_nTimerIncrement = m_nClockCount = m_nClockPulse = 0;
+		delete [] m_pTimer;
+		m_pTimer = NULL;
+		m_mutex.Unlock();
+		TRACE("CGfaTimer::Release: Timer released.\n");
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::RegisterTimerCallback(int tnum, pfnTIMERCALLBACK pfnCallback, void *pContext)
+{
+	_VALIDATE_TIMER_VOID(tnum);
+	if(pfnCallback)
+	{
+		m_mutex.Lock();
+	    m_pTimer[tnum].pfnCallback		= pfnCallback;
+    	m_pTimer[tnum].pContext			= pContext;
+    	m_pTimer[tnum].bCallScheduled	= false;
+		m_mutex.Unlock();
+		TRACE("CGfaTimer::RegisterTimerCallback: Timer %d - callback: %p, context: %p.\n", tnum, pfnCallback, pContext);
+    }
+    else
+	{
+		m_mutex.Lock();
+	    m_pTimer[tnum].pfnCallback		= NULL;
+    	m_pTimer[tnum].pContext			= NULL;
+    	m_pTimer[tnum].bCallScheduled	= false;
+		m_mutex.Unlock();
+		TRACE("CGfaTimer::RegisterTimerCallback: Timer %d - Unregister callback.\n", tnum);
+	}
+}
+
+void CGfaTimer::RegisterClockPulseCallback(GfaTimerClockPulse cp, pfnPULSECALLBACK pfnCallback, void *pContext)
+{
+	if(cp <= GTCP_Invalid || cp >= GTCP_Last)
+	{
+		TRACE("CGfaTimer::RegisterClockPulseCallback: invalid clock pulse %d!\n", cp);
+		return;
+	}
+	
+	if(pfnCallback)
+	{
+		m_mutex.Lock();
+		m_ClkPulseCallbackTable[cp].pfnCallback	= pfnCallback;
+		m_ClkPulseCallbackTable[cp].pContext	= pContext;
+		m_mutex.Unlock();
+		TRACE("CGfaTimer::RegisterClockPulseCallback:  Clock pulse %dms: Register callback: %p, context: %p.\n", CGfaTimer::m_nPulseFreq[cp], pfnCallback, pContext);
+	}
+	else
+	{
+		m_mutex.Lock();
+		m_ClkPulseCallbackTable[cp].pfnCallback	= NULL;
+		m_ClkPulseCallbackTable[cp].pContext	= NULL;
+		m_mutex.Unlock();
+		TRACE("CGfaTimer::RegisterClockPulseCallback: Clock pulse %dms: Unregister callback.\n", CGfaTimer::m_nPulseFreq[cp]);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool CGfaTimer::ValidateTimer(int tnum, const char *pszCaller)
+{
+	if(!m_pTimer)
+	{
+		TRACE("%s: Timer not initialized!\n", pszCaller);
+		return false;
+	}
+
+	if((tnum < 0) || (tnum >= m_nTimerCount))
+	{
+		TRACE("%s: Invalid Timer number: %d\n", pszCaller, tnum);
+		return false;
+	}
+
+	return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CGfaTimer::tf_test(int tnum)
+{
+	_VALIDATE_TIMER_RET(tnum, 0);
+	m_mutex.Lock();
+    int nRet = m_pTimer[tnum].tf;
+	m_mutex.Unlock();
+	return nRet;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::tf_set(int tnum)
+{
+	_VALIDATE_TIMER_VOID(tnum);
+	m_mutex.Lock();
+	m_pTimer[tnum].tf = 1;
+	m_mutex.Unlock();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::tf_clear(int tnum)
+{
+	_VALIDATE_TIMER_VOID(tnum);
+	m_mutex.Lock();
+	m_pTimer[tnum].tf = 0;
+	m_mutex.Unlock();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::tf_store(int tnum, int fset)
+{
+	_VALIDATE_TIMER_VOID(tnum);
+	if(fset)
+	{
+		m_mutex.Lock();
+		m_pTimer[tnum].tf = 1;
+		m_mutex.Unlock();
+	}
+	else
+	{
+		m_mutex.Lock();
+		m_pTimer[tnum].tf = 0;
+		m_mutex.Unlock();
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+unsigned long CGfaTimer::tw_read(int tnum)
+{
+	_VALIDATE_TIMER_RET(tnum, 0);
+	m_mutex.Lock();
+    unsigned long nRet = m_pTimer[tnum].tw;
+	m_mutex.Unlock();
+	return nRet;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::tw_set(int tnum, unsigned long val)
+{
+	_VALIDATE_TIMER_VOID(tnum);
+	m_mutex.Lock();
+    m_pTimer[tnum].tw = val;
+	m_mutex.Unlock();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int CGfaTimer::cp_test(GfaTimerClockPulse cp)
+{
+	if(cp > GTCP_Invalid && cp < GTCP_Last)
+	{
+		return !!(m_nClockPulse & (0x00000001 << cp));
+	}
+
+	TRACE("CGfaTimer::cp_test: Invalid clock pulse: %d.\n", (int)cp);
+	return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void CGfaTimer::AddTimeSpecs(const struct timespec &ts1, const struct timespec &ts2, struct timespec &tsResult)
+{
+	long ns = ts1.tv_nsec + ts2.tv_nsec;
+	tsResult.tv_sec = ts1.tv_sec + ts2.tv_sec + (time_t)ns / _NANOSECS_PER_SEC;
+	tsResult.tv_nsec = ns % _NANOSECS_PER_SEC;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void* CGfaTimer::LordOfTheTimers(void *pParam)
+{
+	int nRet;
+	struct timespec tsDueTime;
+	CGfaTimer* pSelf = reinterpret_cast<CGfaTimer*>(pParam);
+	TRACE("CGfaTimer::LordOfTheTimers: thread enter.\n");
+
+	::clock_gettime(CLOCK_MONOTONIC, &tsDueTime);
+
+	/////////////////////////////////////////////////////////////////////////
+	// enter loop
+
+	do
+	{
+		/////////////////////////////////////////////////////////////////////
+
+		CGfaTimer::AddTimeSpecs(tsDueTime, pSelf->m_timInterval, tsDueTime);
+
+		if((nRet = ::clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tsDueTime, NULL)))
+		{
+			while(nRet && (errno == EINTR))
+			{
+				errno = 0;
+				nRet = ::clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tsDueTime, NULL);
+			}
+		}
+		/////////////////////////////////////////////////////////////////////
+
+		for(int i = 0; i < pSelf->m_nTimerCount; i++)
+		{
+			GFA_TIMER &rt = pSelf->m_pTimer[i];
+
+			pSelf->m_mutex.Lock();
+            if(rt.tf)
+            {
+                if(rt.tw > pSelf->m_nTimerIncrement)
+                	rt.tw -= pSelf->m_nTimerIncrement;
+                else if(rt.tw)
+                {
+                	rt.tw = 0;
+                	if(rt.pfnCallback)
+                		rt.bCallScheduled = true;
+                }
+            }
+            else if(rt.tw)
+            {
+                rt.tw = 0;
+            }
+			pSelf->m_mutex.Unlock();
+		}
+
+		/////////////////////////////////////////////////////////////////////
+		// process clock pulses
+
+		pSelf->m_mutex.Lock();
+		bool bDoCallbacks = false;
+		unsigned long nPrevClockPulse = pSelf->m_nClockPulse;
+		unsigned long nScheduled;
+		pSelf->m_nClockCount += pSelf->m_nTimerIncrement;
+
+		if(!(pSelf->m_nClockCount % CGfaTimer::m_nPulseFreq[0]))
+		{
+			unsigned long nPulseMask = 1;
+			pSelf->m_nClockPulse ^= nPulseMask;
+
+			for(int i = 1; i < GTCP_Last; i++)
+			{
+				nPulseMask <<= 1;
+
+				if(!(pSelf->m_nClockCount % CGfaTimer::m_nPulseFreq[i]))
+				{
+					pSelf->m_nClockPulse ^= nPulseMask;
+				}
+			}
+
+			bDoCallbacks	= true;
+			nScheduled		= pSelf->m_nClockPulse ^ nPrevClockPulse;
+		}
+
+		pSelf->m_mutex.Unlock();
+
+		/////////////////////////////////////////////////////////////////////
+		// call clock pulse callbacks
+		
+		if(bDoCallbacks)
+		{
+			unsigned long nPulseMask	= 1;
+
+			for(int i = GTCP_250ms; i < GTCP_Last; i++, nPulseMask <<= 1)
+			{
+				pSelf->m_mutex.Lock();
+				pfnPULSECALLBACK pfnCallback = pSelf->m_ClkPulseCallbackTable[i].pfnCallback;
+				void *pContext = pSelf->m_ClkPulseCallbackTable[i].pContext;
+				int nState = !!(pSelf->m_nClockPulse & nPulseMask);
+				pSelf->m_mutex.Unlock();
+				
+				if(pfnCallback && (nScheduled & nPulseMask))
+				{
+					(*pfnCallback)((GfaTimerClockPulse)i, nState, pContext);
+				}
+			}
+		}
+
+		/////////////////////////////////////////////////////////////////////
+		// process timer callbacks
+
+		for(int i = 0; i < pSelf->m_nTimerCount; i++)
+		{
+			GFA_TIMER &rt = pSelf->m_pTimer[i];
+
+			pSelf->m_mutex.Lock();
+            if(rt.pfnCallback && rt.tf && rt.bCallScheduled && !rt.tw)
+            {
+            	rt.bCallScheduled = false;
+				(*rt.pfnCallback)(i, rt.pContext);
+            }
+			pSelf->m_mutex.Unlock();
+		}
+	}
+	while(pSelf->m_bProcessTimers);
+
+	TRACE("CGfaTimer::LordOfTheTimers: thread exit.\n");
+	return NULL;
+}

+ 74 - 0
package/libgfatimer/src/timer.h

@@ -0,0 +1,74 @@
+// timer.h :
+//
+
+#if !defined(AGD_TIMER_H__039EAF1D_4D42_44F5_9CAD_437128DA1BA9__INCLUDED_)
+#define AGD_TIMER_H__039EAF1D_4D42_44F5_9CAD_437128DA1BA9__INCLUDED_
+
+#include <stdio.h>
+#include <string.h>
+#include "mutex.h"
+#include "gfatimer.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// timer.h - Declarations:
+
+typedef struct _GFA_TIMER
+{
+    int tf;
+    unsigned long tw;
+    pfnTIMERCALLBACK pfnCallback;
+    void *pContext;
+    bool bCallScheduled;
+}GFA_TIMER, *LPGFA_TIMER;
+typedef const GFA_TIMER *LPCGFA_TIMER;
+
+typedef struct _GFA_TIMER_PULSE_CALLBACK
+{
+    pfnPULSECALLBACK pfnCallback;
+    void *pContext;
+}GFA_TIMER_PULSE_CALLBACK, *LPGFA_TIMER_PULSE_CALLBACK;
+typedef const GFA_TIMER_PULSE_CALLBACK *LPCGFA_TIMER_PULSE_CALLBACK;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CGfaTimer
+{
+public:
+	CGfaTimer(void);
+	~CGfaTimer(void);
+
+	int Initialize(int nTimerCount, GfaTimerResolution res);
+	void Release(void);
+	void RegisterTimerCallback(int tnum, pfnTIMERCALLBACK pfnCallback, void *pContext);
+	void RegisterClockPulseCallback(GfaTimerClockPulse cp, pfnPULSECALLBACK pfnCallback, void *pContext);
+
+	int tf_test(int tnum);
+	void tf_set(int tnum);
+	void tf_clear(int tnum);
+	void tf_store(int tnum, int fset);
+	unsigned long tw_read(int tnum);
+	void tw_set(int tnum, unsigned long val);
+
+	int cp_test(GfaTimerClockPulse cp);
+
+private:
+	bool ValidateTimer(int tnum, const char *pszCaller);
+	static void* LordOfTheTimers(void *pParam);
+	static void AddTimeSpecs(const struct timespec &ts1, const struct timespec &ts2, struct timespec &tsResult);
+
+private:
+	LPGFA_TIMER m_pTimer;
+	int m_nTimerCount;
+	unsigned long m_nTimerIncrement;
+	unsigned long long m_nClockCount;
+	unsigned long m_nClockPulse;
+	CLocalMutex m_mutex;
+    pthread_t m_threadID;
+    struct timespec m_timInterval;
+    bool m_bProcessTimers;
+    static const int m_nPulseFreq[];
+    GFA_TIMER_PULSE_CALLBACK m_ClkPulseCallbackTable[GTCP_Last];
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_TIMER_H__039EAF1D_4D42_44F5_9CAD_437128DA1BA9__INCLUDED_)

+ 49 - 0
package/libgfatimer/src/uuid.h

@@ -0,0 +1,49 @@
+// uuid.h :
+//
+
+#if !defined(AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_)
+#define AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif	//	__cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// uuid.h - Declarations:
+
+#ifdef __linux__
+typedef struct _UUID
+{
+    uint32_t Data1;
+    uint16_t Data2;
+    uint16_t Data3;
+    uint8_t  Data4[8];
+}UUID;
+#define uuid_t UUID
+#endif	//	__linux__
+
+#define DEFINE_UUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+											const uuid_t name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}
+
+#define _UUID_STRING_LEN					36
+
+/////////////////////////////////////////////////////////////////////////////
+
+extern const uuid_t UUID_NULL;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int		_uuid_parse		(const char *pszIn, uuid_t *uuid);
+int		_uuid_unparse	(const uuid_t *uuid, char *pszOut, size_t nCChOut);
+int		_uuid_compare	(const uuid_t *uuid1, const uuid_t *uuid2);
+void	_uuid_copy		(uuid_t *uuDest, const uuid_t *uuSrc);
+int		_uuid_is_null	(const uuid_t *uuid);
+
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+}
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_UUID_H__E2CBFDC3_1EA5_4220_8D44_D0C26219B529__INCLUDED_)

+ 4 - 0
package/qmlplugins/Config.in

@@ -0,0 +1,4 @@
+config BR2_PACKAGE_QMLPLUGINS
+	bool "qmlplugins"
+	help
+		qmlplugins GfA QML Plugins 

BIN
package/qmlplugins/GFAQMLPlugins.tar.gz


+ 19 - 0
package/qmlplugins/qmlplugins.mk

@@ -0,0 +1,19 @@
+QMLPLUGINS_VERSION = 1.0.0
+QMLPLUGINS_SITE = ../GfA/package/qmlplugins
+QMLPLUGINS_SITE_METHOD = local
+QMLPLUGINS_INSTALL_STAGING = YES
+QMLPLUGINS_INSTALL_TARGET = YES
+
+define QMLPLUGINS_BUILD_CMDS
+	echo "GfA plugins installer"
+endef
+
+define QMLPLUGINS_INSTALL_STAGING_CMDS
+	tar -C $(STAGING_DIR) -xzvf $(@D)/GFAQMLPlugins.tar.gz
+endef
+
+define QMLPLUGINS_INSTALL_TARGET_CMDS
+	tar -C $(TARGET_DIR) -xzvf $(@D)/GFAQMLPlugins.tar.gz
+endef
+
+$(eval $(generic-package))