[gtk+] broadway: Add win32 support



commit 53a9311e2c5580c483904a10d18a9f2350c1081b
Author: Tarnyko <tarnyko tarnyko net>
Date:   Thu Jun 13 19:35:43 2013 +0200

    broadway: Add win32 support

 gdk/broadway/Makefile.am          |    4 +
 gdk/broadway/broadway-server.c    |   91 +++++++++++++++++++++---
 gdk/broadway/gdkbroadway-server.c |  138 +++++++++++++++++++++++++++++--------
 3 files changed, 191 insertions(+), 42 deletions(-)
---
diff --git a/gdk/broadway/Makefile.am b/gdk/broadway/Makefile.am
index 1bbde7c..5d714ef 100644
--- a/gdk/broadway/Makefile.am
+++ b/gdk/broadway/Makefile.am
@@ -80,7 +80,11 @@ broadwayd_SOURCES = \
        broadway-output.h               \
        broadway-output.c
 
+if OS_WIN32
+broadwayd_LDADD = $(GDK_DEP_LIBS) -lcrypt -lws2_32
+else
 broadwayd_LDADD = $(GDK_DEP_LIBS) -lrt -lcrypt
+endif
 
 MAINTAINERCLEANFILES = $(broadway_built_sources)
 EXTRA_DIST += $(broadway_built_sources)
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index bc283cb..37135c5 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -20,9 +20,15 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/types.h>
+#ifdef G_OS_UNIX
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <string.h>
+#endif
 
 typedef struct BroadwayInput BroadwayInput;
 typedef struct BroadwayWindow BroadwayWindow;
@@ -861,6 +867,73 @@ broadway_server_block_for_input (BroadwayServer *server, char op,
   }
 }
 
+static void *
+map_named_shm (char *name, gsize size)
+{
+#ifdef G_OS_UNIX
+
+  int fd;
+  void *ptr;
+
+  fd = shm_open(name, O_RDONLY, 0600);
+  if (fd == -1)
+    {
+      perror ("Failed to shm_open");
+      return NULL;
+    }
+
+  ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
+
+  (void) close(fd);
+
+  shm_unlink (name);
+
+  return ptr;
+
+#elif defined(G_OS_WIN32)
+
+  int fd;
+  void *ptr;
+  char *shmpath;
+  void *map = ((void *)-1);
+
+  if (*name == '/')
+    ++name;
+  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
+
+  fd = open(shmpath, O_RDONLY, 0600);
+  if (fd == -1)
+    {
+      g_free (shmpath);
+      perror ("Failed to shm_open");
+      return NULL;
+    }
+
+  if (size == 0)
+    ptr = map;
+  else
+    {
+      HANDLE h, fm;
+      h = (HANDLE)_get_osfhandle (fd);
+      fm = CreateFileMapping (h, NULL, PAGE_READONLY, 0, (DWORD)size, NULL);
+      ptr = MapViewOfFile (fm, FILE_MAP_READ, 0, 0, (size_t)size);
+      CloseHandle (fm);
+    }
+
+  (void) close(fd);
+
+  remove (shmpath);
+  g_free (shmpath);
+
+  return ptr;
+
+#else
+#error "No shm mapping supported"
+
+  return NULL;
+#endif
+}
+
 static char *
 parse_line (char *line, char *key)
 {
@@ -877,6 +950,7 @@ parse_line (char *line, char *key)
     p++;
   return p;
 }
+
 static void
 send_error (HttpRequest *request,
            int error_code,
@@ -1835,7 +1909,11 @@ static void
 shm_data_unmap (void *_data)
 {
   ShmSurfaceData *data = _data;
+#ifdef G_OS_UNIX
   munmap (data->data, data->data_size);
+#elif defined(G_OS_WIN32)
+  UnmapViewOfFile (data->data);
+#endif
   g_free (data);
 }
 
@@ -1851,7 +1929,6 @@ broadway_server_open_surface (BroadwayServer *server,
   cairo_surface_t *surface;
   gsize size;
   void *ptr;
-  int fd;
 
   window = g_hash_table_lookup (server->id_ht,
                                GINT_TO_POINTER (id));
@@ -1864,17 +1941,7 @@ broadway_server_open_surface (BroadwayServer *server,
 
   size = width * height * sizeof (guint32);
 
-  fd = shm_open(name, O_RDONLY, 0600);
-  if (fd == -1)
-    {
-      perror ("Failed to shm_open");
-      return NULL;
-    }
-
-  ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
-  (void) close(fd);
-
-  shm_unlink (name);
+  ptr = map_named_shm (name, size);
 
   if (ptr == NULL)
     return NULL;
diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c
index 04565e0..7c1dc34 100644
--- a/gdk/broadway/gdkbroadway-server.c
+++ b/gdk/broadway/gdkbroadway-server.c
@@ -20,6 +20,9 @@
 #include <errno.h>
 #include <unistd.h>
 #include <sys/types.h>
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
 #include "gdkintl.h"
 
 typedef struct BroadwayInput BroadwayInput;
@@ -538,6 +541,85 @@ _gdk_broadway_server_window_translate (GdkBroadwayServer *server,
   return TRUE;
 }
 
+static void *
+map_named_shm (char *name, gsize size)
+{
+#ifdef G_OS_UNIX
+
+  int fd;
+  void *ptr;
+  int res;
+
+  fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
+  if (fd == -1)
+    {
+      if (errno != EEXIST)
+       g_error ("Unable to allocate shared mem for window");
+      return NULL;
+    }
+
+  res = ftruncate (fd, size);
+  g_assert (res != -1);
+
+  res = posix_fallocate (fd, 0, size);
+  if (res != 0)
+    {
+      shm_unlink (name);
+      g_error ("Not enough shared memory for window surface");
+    }
+  
+  ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+
+  (void) close(fd);
+
+  return ptr;
+
+#elif defined(G_OS_WIN32)
+
+  int fd;
+  void *ptr;
+  char *shmpath;
+  void *map = ((void *)-1);
+  int res;
+
+  if (*name == '/')
+    ++name;
+  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
+
+  fd = open(shmpath, O_RDWR|O_CREAT|O_EXCL, 0600);
+  g_free (shmpath);
+  if (fd == -1)
+    {
+      if (errno != EEXIST)
+       g_error ("Unable to allocate shared mem for window");
+      return NULL;
+    }
+
+  res = ftruncate (fd, size);
+  g_assert (res != -1);
+  
+  if (size == 0)
+    ptr = map;
+  else
+    {
+      HANDLE h, fm;
+      h = (HANDLE)_get_osfhandle (fd);
+      fm = CreateFileMapping (h, NULL, PAGE_READWRITE, 0, (DWORD)size, NULL);
+      ptr = MapViewOfFile (fm, FILE_MAP_WRITE, 0, 0, (size_t)size);
+      CloseHandle (fm);
+    }
+
+  (void) close(fd);
+
+  return ptr;
+
+#else
+#error "No shm mapping supported"
+
+  return NULL;
+#endif
+}
+
 static char
 make_valid_fs_char (char c)
 {
@@ -547,11 +629,12 @@ make_valid_fs_char (char c)
 }
 
 /* name must have at least space for 34 bytes */
-static int
-create_random_shm (char *name)
+static gpointer
+create_random_shm (char *name, gsize size)
 {
   guint32 r;
-  int i, o, fd;
+  int i, o;
+  gpointer ptr;
 
   while (TRUE)
     {
@@ -570,18 +653,11 @@ create_random_shm (char *name)
          name[o++] = make_valid_fs_char ((r >> 24) & 0xff);
        }
       name[o++] = 0;
-  
-      fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
-      if (fd >= 0)
-       return fd;
 
-      if (errno != EEXIST)
-       {
-         g_printerr ("Unable to allocate shared mem for window");
-         exit (1);
-       }
+      ptr = map_named_shm (name, size);
+      if (ptr)
+       return ptr;
     }
-
 }
 
 static const cairo_user_data_key_t gdk_broadway_shm_cairo_key;
@@ -597,8 +673,26 @@ shm_data_destroy (void *_data)
 {
   BroadwayShmSurfaceData *data = _data;
 
+#ifdef G_OS_UNIX
+
   munmap (data->data, data->data_size);
   shm_unlink (data->name);
+
+#elif defined(G_OS_WIN32)
+
+  char *name = data->name;
+  char *shmpath;
+
+  if (*name == '/')
+    ++name;
+
+  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
+  UnmapViewOfFile (data->data);
+  remove (shmpath);
+  g_free (shmpath);
+
+#endif
+
   g_free (data);
 }
 
@@ -608,26 +702,10 @@ _gdk_broadway_server_create_surface (int                 width,
 {
   BroadwayShmSurfaceData *data;
   cairo_surface_t *surface;
-  int res;
-  int fd;
 
   data = g_new (BroadwayShmSurfaceData, 1);
   data->data_size = width * height * sizeof (guint32);
-  
-  fd = create_random_shm (data->name);
-
-  res = ftruncate (fd, data->data_size);
-  g_assert (res != -1);
-
-  res = posix_fallocate (fd, 0, data->data_size);
-  if (res != 0)
-    {
-      shm_unlink (data->name);
-      g_error ("Not enough shared memory for window surface");
-    }
-
-  data->data = mmap(0, data->data_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
-  (void) close(fd);
+  data->data = create_random_shm (data->name, data->data_size);
 
   surface = cairo_image_surface_create_for_data ((guchar *)data->data,
                                                 CAIRO_FORMAT_RGB24, width, height, width * sizeof (guint32));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]