[1/3] Make mac driver the default on OS X (try 2)

Josh DuBois duboisj at codeweavers.com
Fri Mar 15 13:22:32 CDT 2013


I'm re-submitting now that OpenGL and the clipboard stuff are in. I've 
shortened the error message in line with Ken's suggestion on wine-devel, 
and removed an extraneous return statement.

I'm basically just resubmitting because I offered to mod the error 
message, so I'm doing that.

Ken also noted that the error reporting could be simpler if it were in 
gdi instead of user32.  My impression, after having poked at it a while 
with Ken, is that it is in theory possible that an application which 
never tried to create a window would print less noise with the errors 
being reported as they are here than it would if the errors were 
reported directly from gdi, so that this may be superior because it is 
quieter.  However, I'm not an expert and if the rigamarole is not worth 
the extra lines, I'm sure Alexandre will indicate so by not applying this.

As to the question of whether it is time to make the switch, I am also 
agnostic.  Some people mentioned that having OpenGL and clipboard were 
prereqs, which is true, but those are in.  Virtual desktops are still 
missing, but there seems to be question as to whether they are necessary 
or desirable, and in any case they appear to be a good bit more work.  
I'm happy leaving those issues to others - my main goal was to prompt 
decisions about how the Mac Driver would be loaded and in what order vs 
X11, and at least that seems to be sorted out.  It seems good to turn it 
on eventually, but I'm happy to let others kibbitz about when.

(Ken noted that if I the patch which turns it on is mine, then any 
problems it creates will result in a bisect that points to me as the 
culprit.  So maybe I don't want this patch in after all.  On the other 
hand I certainly don't want to steal thunder from Ken (and Alexandre) 
for having done the work necessary to make it possible. But then, of 
people who enjoy the Mac Driver, I don't think all that many will do a 
bisect to find out when things _started_ being so great ;), so maybe 
that's not an issue.)

Cheers.

---
  dlls/gdi32/driver.c       |  100 
+++++++++++++++++++++++++++++++++++++++++++--
  dlls/gdi32/gdi32.spec     |    1 +
  dlls/gdi32/gdi_private.h  |    2 +
  dlls/user32/driver.c      |   27 ++++++------
  include/wine/gdi_driver.h |   11 +++++
  5 files changed, 123 insertions(+), 18 deletions(-)

-------------- next part --------------
>From 0729e938b62fcf77c9ed21c91a6972841b356e1b Mon Sep 17 00:00:00 2001
From: Josh DuBois <duboisj at CodeWeavers.com>
Date: Tue, 5 Mar 2013 15:30:03 -0600
Subject: Track and report multiple errors loading display drivers.

---
 dlls/gdi32/driver.c       |  100 +++++++++++++++++++++++++++++++++++++++++++--
 dlls/gdi32/gdi32.spec     |    1 +
 dlls/gdi32/gdi_private.h  |    2 +
 dlls/user32/driver.c      |   27 ++++++------
 include/wine/gdi_driver.h |   11 +++++
 5 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 70208fb..17d5e5e 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -48,7 +48,24 @@ struct graphics_driver
 
 static struct list drivers = LIST_INIT( drivers );
 static struct graphics_driver *display_driver;
-static DWORD display_driver_load_error;
+static DWORD last_display_driver_load_error;
+
+static display_driver_load_error display_driver_load_errors[] =
+{
+    {
+        "X11",
+        0,
+        0,
+        ""
+    },
+    {
+        "Mac",
+        0,
+        0,
+        ""
+    }
+    
+};
 
 const struct gdi_dc_funcs *font_driver = NULL;
 
@@ -119,11 +136,12 @@ static const struct gdi_dc_funcs *get_display_driver( HMODULE *module_ret )
 
         snprintf( libname, sizeof(libname), "wine%s.drv", name );
         if ((module = LoadLibraryA( libname )) != 0) break;
+
+        set_display_driver_load_error( name );
+
         name = next;
     }
 
-    if (!module) display_driver_load_error = GetLastError();
-
     if (!(driver = create_driver( module )))
     {
         MESSAGE( "Could not create graphics driver '%s'\n", buffer );
@@ -143,6 +161,80 @@ done:
 
 
 /**********************************************************************
+ *	     __wine_get_display_driver_load_errors
+ *
+ * Retrive user-readable information re: why display drivers failed to load.
+ */
+void CDECL __wine_get_display_driver_load_errors( display_driver_load_error **load_errs,
+                                                 int *num_known_drivers )
+{
+    int n = sizeof(display_driver_load_errors) /
+        sizeof(display_driver_load_errors[0]);
+
+    if (load_errs) *load_errs = display_driver_load_errors;
+    if (num_known_drivers) *num_known_drivers = n;
+}
+
+
+/**********************************************************************
+ *	     set_display_driver_load_error
+ *
+ * Set error information after failure to load a display driver.
+ */
+void set_display_driver_load_error( const char *name )
+{
+    display_driver_load_error *load_err = NULL;
+    int n = sizeof(display_driver_load_errors) /
+        sizeof(display_driver_load_errors[0]);
+    int j;
+
+    last_display_driver_load_error = GetLastError();
+
+    for (j = 0; j < n; j++)
+        if (!strcasecmp( display_driver_load_errors[j].name, name ))
+            load_err = &display_driver_load_errors[j];
+
+    if (!load_err)
+    {
+        ERR( "Attempted to load unknown display driver '%s' failed with %d\n",
+             name, last_display_driver_load_error );
+        return;
+    }
+    
+    load_err->load_failed = 1;
+    load_err->err = last_display_driver_load_error;
+
+    if (!strcasecmp( name, "X11" ))
+    {
+        switch (load_err->err)
+        {
+        case ERROR_MOD_NOT_FOUND:
+            load_err->err_msg = "The X11 driver is missing. Check your build!";
+            break;
+        case ERROR_DLL_INIT_FAILED:
+            load_err->err_msg = "Make sure that your X server is running \nand that $DISPLAY is set correctly.";
+            break;
+        default:
+            load_err->err_msg = "Unknown error loding X11 driver.";
+        }
+    } else if (!strcasecmp( name, "Mac" ))
+    {
+        switch (load_err->err)
+        {
+        case ERROR_MOD_NOT_FOUND:
+            load_err->err_msg = "The Mac driver is missing. Check your build!";
+            break;
+        case ERROR_DLL_INIT_FAILED:
+            load_err->err_msg = "The Mac driver cannot run in a non-GUI \nsession (such as a remote login).";
+            break;
+        default:
+            load_err->err_msg = "Unknown error loding Mac driver.";
+        }
+    } 
+}
+
+
+/**********************************************************************
  *	     DRIVER_load_driver
  */
 const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name, HMODULE *module_ret )
@@ -210,7 +302,7 @@ HMODULE CDECL __wine_get_driver_module( HDC hdc )
     {
         ret = dc->module;
         release_dc_ptr( dc );
-        if (!ret) SetLastError( display_driver_load_error );
+        if (!ret) SetLastError( last_display_driver_load_error );
     }
     else SetLastError( ERROR_INVALID_HANDLE );
     return ret;
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 65f1d0c..a67a41f 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -515,6 +515,7 @@
 
 # Graphics drivers
 @ cdecl __wine_get_driver_module(long)
+@ cdecl __wine_get_display_driver_load_errors(ptr ptr)
 
 # OpenGL
 @ cdecl __wine_get_wgl_driver(long long)
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index edd4bf6..ebec942 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -526,4 +526,6 @@ extern void free_heap_bits( struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
 
 extern HMODULE gdi32_module DECLSPEC_HIDDEN;
 
+void set_display_driver_load_error( const char *name );
+
 #endif /* __WINE_GDI_PRIVATE_H */
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 1c12134..6c66717 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -32,7 +32,6 @@
 static USER_DRIVER null_driver, lazy_load_driver;
 
 const USER_DRIVER *USER_Driver = &lazy_load_driver;
-static DWORD driver_load_error;
 
 /* load the graphics driver */
 static const USER_DRIVER *load_driver(void)
@@ -109,7 +108,6 @@ static const USER_DRIVER *load_driver(void)
         GET_USER_FUNC(SystemParametersInfo);
 #undef GET_USER_FUNC
     }
-    else driver_load_error = GetLastError();
 
     prev = InterlockedCompareExchangePointer( (void **)&USER_Driver, driver, &lazy_load_driver );
     if (prev != &lazy_load_driver)
@@ -299,23 +297,24 @@ static BOOL CDECL nulldrv_CreateDesktopWindow( HWND hwnd )
 static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
 {
     static int warned;
+    display_driver_load_error *load_errs;
+    int known_drivers;
+    int j;
 
     /* HWND_MESSAGE windows don't need a graphics driver */
     if (GetAncestor( hwnd, GA_PARENT ) == get_user_thread_info()->msg_window) return TRUE;
     if (warned++) return FALSE;
 
-    MESSAGE( "Application tried to create a window, but no driver could be loaded.\n");
-    switch (driver_load_error)
-    {
-    case ERROR_MOD_NOT_FOUND:
-        MESSAGE( "The graphics driver is missing. Check your build!\n" );
-        break;
-    case ERROR_DLL_INIT_FAILED:
-        MESSAGE( "Make sure that your X server is running and that $DISPLAY is set correctly.\n" );
-        break;
-    default:
-        MESSAGE( "Unknown error (%d).\n", driver_load_error );
-    }
+    MESSAGE( "Application tried to create a window, but no display driver could be loaded.\n" );
+
+    __wine_get_display_driver_load_errors( &load_errs, &known_drivers );
+
+    for (j = 0; j < known_drivers; j++)
+        if (load_errs[j].load_failed)
+            MESSAGE( "The %s display driver failed to load: %s (err: %d)\n",
+                    load_errs[j].name, 
+                    load_errs[j].err_msg,
+                    load_errs[j].err );
 
     return FALSE;
 }
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index fffbad0..4ab58fc 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -279,4 +279,15 @@ extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis
 extern HMODULE CDECL __wine_get_driver_module( HDC hdc );
 extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version );
 
+typedef struct display_driver_load_error_t
+{
+    const char *name;
+    int load_failed;
+    DWORD err;
+    const char *err_msg;
+} display_driver_load_error;
+
+void CDECL __wine_get_display_driver_load_errors( display_driver_load_error **load_errs, 
+                                                  int *num_known_drivers );
+
 #endif /* __WINE_WINE_GDI_DRIVER_H */
-- 
1.7.7.4



More information about the wine-patches mailing list