Skip to content

Instantly share code, notes, and snippets.

@Cloudef
Created October 6, 2011 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cloudef/1268382 to your computer and use it in GitHub Desktop.
Save Cloudef/1268382 to your computer and use it in GitHub Desktop.
FakeDisp interface for wine
From ce8506d5fb32fc2ecd0edfb9b29057edb1cba367 Mon Sep 17 00:00:00 2001
From: Jari Vetoniemi <mailroxas@gmail.com>
Date: Fri, 27 Jul 2012 23:57:38 +0300
Subject: [PATCH] Fake display interface.
Sends fake resolution information to applications and,
fakes succesful display resolution changes to applications.
Useful if one does not want resolution switches and applications
don't work if they don't get any resolution information.
Also may help with dualhead setups.
Example use from terminal:
WINE_FAKEDISP="1440x900;1024x768;800x600" wine application.exe
You can also specify resolutions in registry in the same format:
HKEY_CURRENT_USER/Software/Wine/X11 Driver/FakeDispResolution
If both env variable and registry key is empty, fakedisp isn't used.
---
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 deletion(-)
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 2bc49f5..3d5e935 100644
--- a/dlls/winex11.drv/Makefile.in
+++ b/dlls/winex11.drv/Makefile.in
@@ -29,7 +29,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..1998707
--- /dev/null
+++ b/dlls/winex11.drv/fakedisp.c
@@ -0,0 +1,123 @@
+/*
+ * Wine X11drv fakedisp interface
+ *
+ * Copyright 2012 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[MAX_PATH+10];
+
+/* **** 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..b560d97
--- /dev/null
+++ b/dlls/winex11.drv/fakedisp.h
@@ -0,0 +1,29 @@
+/*
+ * Wine X11drv fakedisp interface
+ *
+ * Copyright 2012 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 32d7772..a688d15 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -391,6 +391,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[MAX_PATH+10] DECLSPEC_HIDDEN;
/* atoms */
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 8012df3..48484f0 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -96,6 +96,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[MAX_PATH+10];
static x11drv_error_callback err_callback; /* current callback for error */
static Display *err_callback_display; /* display callback is set for */
@@ -446,6 +447,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 );
}
@@ -573,6 +576,8 @@ static BOOL process_attach(void)
xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
X11DRV_Settings_Init();
+ /* initialize FakeDisp */
+ X11DRV_FakeDisp_Init();
/* initialize XVidMode */
X11DRV_XF86VM_Init();
/* initialize XRandR */
--
1.7.11.3
@Cloudef
Copy link
Author

Cloudef commented Oct 6, 2011

http://www.winehq.org/pipermail/wine-devel/2011-September/092034.html
For more information.

UPDATE:
Uses only one registry key called "FakeDispResolution" now, if that or WINE_FAKEDISP env variable is empty, fakedisp isn't used.
Also multiple resolutions are supported. Both registry key and env variable have same syntax WIDTHxHEIGHT_FREQ, resolutions have to be seperated by semicolon (;).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment