Index: /code/branches/ggz/cmake/FindGGZ.cmake
===================================================================
--- /code/branches/ggz/cmake/FindGGZ.cmake	(revision 2889)
+++ /code/branches/ggz/cmake/FindGGZ.cmake	(revision 2889)
@@ -0,0 +1,16 @@
+# Find GGZ
+
+FIND_PATH(GGZ_INCLUDE_DIR ggzmod.h)
+
+FIND_LIBRARY(GGZMOD_LIBRARY NAMES ggzmod)
+
+# handle the QUIETLY and REQUIRED arguments and set GGZ_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GGZMOD DEFAULT_MSG GGZMOD_LIBRARY GGZ_INCLUDE_DIR)
+
+IF(GGZMOD_FOUND)
+  SET(GGZMOD_LIBRARIES ${GGZMOD_LIBRARY})
+ENDIF(GGZMOD_FOUND)
+
+MARK_AS_ADVANCED(GGZMOD_LIBRARY GGZMOD_LIBRARIES GGZ_INCLUDE_DIR)
Index: /code/branches/ggz/cmake/LibraryConfig.cmake
===================================================================
--- /code/branches/ggz/cmake/LibraryConfig.cmake	(revision 2888)
+++ /code/branches/ggz/cmake/LibraryConfig.cmake	(revision 2889)
@@ -115,4 +115,5 @@
 FIND_PACKAGE(ALUT            REQUIRED)
 FIND_PACKAGE(ZLIB            REQUIRED)
+FIND_PACKAGE(GGZ                     )
 IF(WIN32)
   FIND_PACKAGE(DirectX       REQUIRED)
Index: /code/branches/ggz/src/orxonox/CMakeLists.txt
===================================================================
--- /code/branches/ggz/src/orxonox/CMakeLists.txt	(revision 2888)
+++ /code/branches/ggz/src/orxonox/CMakeLists.txt	(revision 2889)
@@ -20,4 +20,5 @@
 SET_SOURCE_FILES(ORXONOX_SRC_FILES
   CameraManager.cc
+  GGZClient.cc
   GraphicsEngine.cc
   LevelManager.cc
@@ -51,4 +52,5 @@
   ${CEGUILUA_LIBRARY}
   ${Boost_SYSTEM_LIBRARY}
+  ${GGZMOD_LIBRARIES}
   ogreceguirenderer_orxonox
   tinyxml++_orxonox
Index: /code/branches/ggz/src/orxonox/GGZClient.cc
===================================================================
--- /code/branches/ggz/src/orxonox/GGZClient.cc	(revision 2889)
+++ /code/branches/ggz/src/orxonox/GGZClient.cc	(revision 2889)
@@ -0,0 +1,77 @@
+#include "GGZClient.h"
+
+#include <cassert>
+
+namespace orxonox
+{
+    GGZClient* GGZClient::singletonRef_s = 0;
+
+    GGZClient::GGZClient()
+    {
+        assert(singletonRef_s == 0);
+        singletonRef_s = this;
+
+        active = ggzmod_is_ggz_mode();
+        if (active) {
+            initGGZ();
+        }
+    }
+
+    GGZClient::~GGZClient()
+    {
+        if (active) {
+            deinitGGZ();
+        }
+
+        assert(singletonRef_s);
+        singletonRef_s = 0;
+    }
+
+    GGZClient& GGZClient::getInstance()
+    {
+        assert(singletonRef_s);
+        return *singletonRef_s;
+    }
+
+    void GGZClient::initGGZ()
+    {
+        ggzmod = ggzmod_new(GGZMOD_GAME);
+        ggzmod_set_handler(ggzmod, GGZMOD_EVENT_SERVER,
+                &orxonox::GGZClient::handleGGZModServer);
+        if (ggzmod_connect(ggzmod) < 0) {
+            /* TODO: Error */
+        }
+        int ggzSocket = ggzmod_get_fd(ggzmod);
+        if (ggzSocket < 0) {
+            /* TODO: Error */
+        }
+        sockets.add(ggzSocket, &orxonox::GGZClient::handleGGZ);
+    }
+
+    void GGZClient::deinitGGZ()
+    {
+        ggzmod_disconnect(ggzmod);
+        ggzmod_free(ggzmod);
+    }
+
+    /* Got data from game server */
+    void handleGame(int fd)
+    {
+        /* TODO: read from fd */
+    }
+
+    /* Got data from GGZ */
+    void GGZClient::handleGGZ(int fd)
+    {
+        ggzmod_dispatch(getInstance().ggzmod);
+    }
+
+    /* Connection to game server established */
+    void GGZClient::handleGGZModServer(GGZMod * ggzmod, GGZModEvent e,
+            const void *data)
+    {
+        ggzmod_set_state(ggzmod, GGZMOD_STATE_PLAYING);
+        int gameSocket = *(int*)data;
+        getInstance().sockets.add(gameSocket, &orxonox::GGZClient::handleGGZ);
+    }
+}
Index: /code/branches/ggz/src/orxonox/GGZClient.h
===================================================================
--- /code/branches/ggz/src/orxonox/GGZClient.h	(revision 2889)
+++ /code/branches/ggz/src/orxonox/GGZClient.h	(revision 2889)
@@ -0,0 +1,35 @@
+#ifndef _GGZClient_H__
+#define _GGZClient_H__
+
+#include "OrxonoxPrereqs.h"
+#include "objects/FDWatcher.h"
+
+#include <ggzmod.h>
+
+namespace orxonox
+{
+    class _OrxonoxExport GGZClient
+    {
+        public:
+            GGZClient();
+            ~GGZClient();
+
+            static GGZClient& getInstance();
+
+        private:
+            static GGZClient* singletonRef_s;
+
+            bool active;
+            GGZMod *ggzmod;
+            FDWatcher sockets;
+
+            void initGGZ();
+            void deinitGGZ();
+            static void handleGame(int fd);
+            static void handleGGZ(int fd);
+            static void handleGGZModServer(GGZMod * ggzmod, GGZModEvent e,
+                    const void *data);
+    };
+}
+
+#endif /* _GGZClient_H__ */
Index: /code/branches/ggz/src/orxonox/objects/CMakeLists.txt
===================================================================
--- /code/branches/ggz/src/orxonox/objects/CMakeLists.txt	(revision 2888)
+++ /code/branches/ggz/src/orxonox/objects/CMakeLists.txt	(revision 2889)
@@ -3,4 +3,5 @@
   EventDispatcher.cc
   EventTarget.cc
+  FDWatcher.cc
   GlobalShader.cc
   Level.cc
Index: /code/branches/ggz/src/orxonox/objects/FDWatcher.cc
===================================================================
--- /code/branches/ggz/src/orxonox/objects/FDWatcher.cc	(revision 2889)
+++ /code/branches/ggz/src/orxonox/objects/FDWatcher.cc	(revision 2889)
@@ -0,0 +1,67 @@
+#include "FDWatcher.h"
+
+namespace orxonox
+{
+    FDWatcher::FDWatcher()
+    {
+        pollfds = 0;
+        npollfds = 0;
+    }
+
+    FDWatcher::~FDWatcher()
+    {
+        if (pollfds) {
+            delete [] pollfds;
+        }
+    }
+
+    void FDWatcher::tick(const float dt)
+    {
+        int ret = poll(pollfds, npollfds, 0);
+        if (ret < 0) {
+            // TODO error
+        }
+        for (int i=0; ret>0; i++, ret--) {
+            if (pollfds[i].revents & POLLIN) {
+                (*watches[pollfds[i].fd])(pollfds[i].fd);
+            }
+            if (pollfds[i].revents & !POLLIN) {
+                // TODO error
+            }
+        }
+    }
+
+    void FDWatcher::add(const int fd, intfunction cb)
+    {
+        watches[fd] = cb;
+        npollfds++;
+        rebuild();
+    }
+
+    void FDWatcher::remove(const int fd)
+    {
+        watches.erase(fd);
+        npollfds--;
+        rebuild();
+    }
+
+    void FDWatcher::rebuild()
+    {
+        if (pollfds) {
+            delete [] pollfds;
+        }
+        if (npollfds) {
+            pollfds = new struct pollfd[npollfds];
+        }
+        else {
+            pollfds = 0;
+        }
+        int i=0;
+        for (std::map<int, intfunction>::iterator it=watches.begin();
+                it!=watches.end(); it++, i++)
+        {
+            pollfds[i].fd = it->first;
+            pollfds[i].events = POLLIN;
+        }
+    }
+}
Index: /code/branches/ggz/src/orxonox/objects/FDWatcher.h
===================================================================
--- /code/branches/ggz/src/orxonox/objects/FDWatcher.h	(revision 2889)
+++ /code/branches/ggz/src/orxonox/objects/FDWatcher.h	(revision 2889)
@@ -0,0 +1,33 @@
+#ifndef _FDWATCHER_H__
+#define _FDWATCHER_H__
+
+#include "objects/Tickable.h"
+
+#include <map>
+#include <poll.h>
+
+namespace orxonox
+{
+    class _OrxonoxExport FDWatcher : public Tickable
+    {
+        typedef void (*intfunction) (int fd);
+
+        public:
+            FDWatcher();
+            ~FDWatcher();
+
+            virtual void tick(const float dt);
+
+            void add(const int fd, intfunction cb);
+            void remove(const int fd);
+
+        private:
+            std::map<int, intfunction> watches;
+            pollfd * pollfds;
+            int npollfds;
+
+            void rebuild();
+    };
+}
+
+#endif /* _FDWATCHER_H__ */
