From ab49a5e887a121f9ab5e58756eda46e880be3332 Mon Sep 17 00:00:00 2001
From: Cloudef <mailRoxas@gmail.com>
Date: Thu, 6 Oct 2011 22:04:46 +0300
Subject: [PATCH] fakedisp interface

---
 dlls/winex11.drv/Makefile.in   |    3 +-
 dlls/winex11.drv/fakedisp.c    |  123 ++++++++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/fakedisp.h    |   29 +++++++++
 dlls/winex11.drv/x11drv.h      |    1 +
 dlls/winex11.drv/x11drv_main.c |    5 ++
 5 files changed, 160 insertions(+), 1 deletions(-)
 create mode 100644 dlls/winex11.drv/fakedisp.c
 create mode 100644 dlls/winex11.drv/fakedisp.h

diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in
index 9af183c..01158ef 100644
--- a/dlls/winex11.drv/Makefile.in
+++ b/dlls/winex11.drv/Makefile.in
@@ -37,7 +37,8 @@ C_SRCS = \
 	xinerama.c \
 	xrandr.c \
 	xrender.c \
-	xvidmode.c
+	xvidmode.c \
+	fakedisp.c
 
 RC_SRCS = version.rc
 
diff --git a/dlls/winex11.drv/fakedisp.c b/dlls/winex11.drv/fakedisp.c
new file mode 100644
index 0000000..2e28b3c
--- /dev/null
+++ b/dlls/winex11.drv/fakedisp.c
@@ -0,0 +1,123 @@
+/*
+ * Wine X11drv fakedisp interface
+ *
+ * Copyright 2011 Jari Vetoniemi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "x11drv.h"
+#include "winreg.h"
+#include "fakedisp.h"
+
+#define X11DRV_FAKEDISP_MODE_SEPERATOR ";"
+static int current_mode = 0;
+extern char fakedisp_resolution[1024];
+
+/* **** STRING SPLITTING **** */
+
+static int strsplit(char ***dst, char *str, const char *token)
+{
+   char *saveptr, *ptr, *start;
+   int32_t t_len, i;
+
+   if (!(saveptr=strdup(str)))
+      return 0;
+
+   *dst=NULL;
+   t_len=strlen(token);
+   i=0;
+
+   for (start=saveptr,ptr=start;;ptr++) {
+      if (!strncmp(ptr,token,t_len) || !*ptr) {
+         while (!strncmp(ptr,token,t_len)) {
+            *ptr=0;
+            ptr+=t_len;
+         }
+
+         if (!((*dst)=realloc(*dst,(i+2)*sizeof(char*))))
+            return 0;
+         (*dst)[i]=start;
+         (*dst)[i+1]=NULL;
+         i++;
+
+         if (!*ptr)
+            break;
+         start=ptr;
+      }
+   }
+   return i;
+}
+
+static void strsplit_clear(char ***dst)
+{
+   if ((*dst)[0])
+      free((*dst)[0]);
+   free((*dst));
+}
+
+/* **** END OF STRING SPLITTING **** */
+
+
+static int X11DRV_FakeDisp_GetCurrentMode(void)
+{
+    return current_mode;
+}
+
+static LONG X11DRV_FakeDisp_SetCurrentMode(int mode)
+{
+   current_mode = mode;
+   return DISP_CHANGE_SUCCESSFUL;
+}
+
+void X11DRV_FakeDisp_Init(void)
+{
+    char *fakedisp_env, **modes;
+    int width, height, freq, c, nmodes, i;
+
+    fakedisp_env = getenv( "WINE_FAKEDISP" );
+    if(!fakedisp_env)
+    {
+       if(!strlen(fakedisp_resolution)) return; /* no env variable nor registry key */
+       fakedisp_env = fakedisp_resolution;
+    }
+    nmodes = strsplit( &modes, fakedisp_env, X11DRV_FAKEDISP_MODE_SEPERATOR );
+
+    X11DRV_Settings_SetHandlers("FakeDisp",
+                                X11DRV_FakeDisp_GetCurrentMode,
+                                X11DRV_FakeDisp_SetCurrentMode,
+                                nmodes, 1);
+
+    i = 0;
+    for(; i != nmodes; ++i)
+    {
+        c = sscanf(modes[i], "%dx%d_%d", &width, &height, &freq);
+        if(c<1) width  = 0;
+        if(c<2) height = 0;
+        if(c<3) freq   = 0;
+
+        X11DRV_Settings_AddOneMode(width, height, 0, freq);
+    }
+
+    strsplit_clear(&modes);
+    X11DRV_Settings_AddDepthModes();
+}
+
diff --git a/dlls/winex11.drv/fakedisp.h b/dlls/winex11.drv/fakedisp.h
new file mode 100644
index 0000000..beccd11
--- /dev/null
+++ b/dlls/winex11.drv/fakedisp.h
@@ -0,0 +1,29 @@
+/*
+ * Wine X11drv fakedisp interface
+ *
+ * Copyright 2011 Jari Vetoniemi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __WINE_FAKEDISP_H
+#define __WINE_FAKEDISP_H
+
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
+void X11DRV_FakeDisp_Init(void) DECLSPEC_HIDDEN;
+
+#endif /* __WINE_FAKEDISP_H */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98b1ab1..b4022a7 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -616,6 +616,7 @@ extern int copy_default_colors DECLSPEC_HIDDEN;
 extern int alloc_system_colors DECLSPEC_HIDDEN;
 extern int xrender_error_base DECLSPEC_HIDDEN;
 extern HMODULE x11drv_module DECLSPEC_HIDDEN;
+extern char fakedisp_resolution[1024] DECLSPEC_HIDDEN;
 
 /* atoms */
 
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 8e2082d..4f9ecac 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -99,6 +99,7 @@ int alloc_system_colors = 256;
 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
 int xrender_error_base = 0;
 HMODULE x11drv_module = 0;
+char fakedisp_resolution[1024];
 
 static x11drv_error_callback err_callback;   /* current callback for error */
 static Display *err_callback_display;        /* display callback is set for */
@@ -452,6 +453,8 @@ static void setup_options(void)
 
     get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
 
+    get_config_key( hkey, appkey, "FakeDispResolution", fakedisp_resolution, sizeof(fakedisp_resolution) );
+
     if (appkey) RegCloseKey( appkey );
     if (hkey) RegCloseKey( hkey );
 }
@@ -578,6 +581,8 @@ static BOOL process_attach(void)
     xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
     X11DRV_Settings_Init();
 
+    /* initialize FakeDisp */
+    X11DRV_FakeDisp_Init();
 #ifdef SONAME_LIBXXF86VM
     /* initialize XVidMode */
     X11DRV_XF86VM_Init();
-- 
1.7.7

