dlopen libncurses.so in wineconsole (take 3)

Mike McCormack mike at codeweavers.com
Thu Aug 14 21:00:03 CDT 2003



Eric Pouech wrote:

> yes, way better. Latest point, I think you shouldn't protect the 
> MAKE_FUNCPTR with #ifdef. If you do so, and one of the symbol is not 
> defined, your LOAD_FUNCPTR will not compile because the global variable 
> to hold the function pointer will not be defined.
> So, either you protect MAKE_FUNCPTR and LOAD_FUNCPTR with a #ifdef (and 
> you can even remove the needed arg to LOAD_FUNCPTR), or you don't 
> protect at all both MAKE_FUNCPTR and LOAD_FUNCPTR.
> 
> A+

OK, I have removed the boolean, and just #ifdef'ed the LOAD_FUNCPTR 
macros. The problem is that if initscr is a macro, typeof(initscr) may 
not do what we want, so we can't use MAKE_FUNCPTR(initscr).

I also made a define for the name of the library, so the error messages
say the "curses" not "ncurses" if curses is used.

Mike


ChangeLog
* dlopen libncurses.so in wineconsole

-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.171
diff -u -r1.171 configure.ac
--- configure.ac	13 Aug 2003 01:27:48 -0000	1.171
+++ configure.ac	15 Aug 2003 01:37:12 -0000
@@ -919,6 +919,8 @@
   WINE_GET_SONAME(jack,jack_client_new)
   WINE_GET_SONAME(ssl,SSL_library_init)
   WINE_GET_SONAME(crypto,BIO_new_socket)
+  WINE_GET_SONAME(ncurses,waddch)
+  WINE_GET_SONAME(curses,waddch)
 fi
 
 
Index: include/config.h.in
===================================================================
RCS file: /home/wine/wine/include/config.h.in,v
retrieving revision 1.157
diff -u -r1.157 config.h.in
--- include/config.h.in	20 Jun 2003 23:26:56 -0000	1.157
+++ include/config.h.in	15 Aug 2003 01:37:12 -0000
@@ -791,6 +791,12 @@
 /* Define to the soname of the libXrender library. */
 #undef SONAME_LIBXRENDER
 
+/* Define to the soname of the libncurses library. */
+#undef SONAME_LIBNCURSES
+
+/* Define to the soname of the libncurses library. */
+#undef SONAME_LIBCURSES
+
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be
    automatically deduced at run-time.
Index: programs/wineconsole/Makefile.in
===================================================================
RCS file: /home/wine/wine/programs/wineconsole/Makefile.in,v
retrieving revision 1.7
diff -u -r1.7 Makefile.in
--- programs/wineconsole/Makefile.in	13 Dec 2002 23:37:06 -0000	1.7
+++ programs/wineconsole/Makefile.in	15 Aug 2003 01:37:12 -0000
@@ -4,7 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = wineconsole.exe
-EXTRALIBS = @CURSESLIBS@
+EXTRALIBS = 
 APPMODE   = gui
 IMPORTS   = advapi32 kernel32 ntdll
 DELAYIMPORTS = comctl32 user32 gdi32
Index: programs/wineconsole/curses.c
===================================================================
RCS file: /home/wine/wine/programs/wineconsole/curses.c,v
retrieving revision 1.10
diff -u -r1.10 curses.c
--- programs/wineconsole/curses.c	14 Jun 2003 01:34:53 -0000	1.10
+++ programs/wineconsole/curses.c	15 Aug 2003 01:37:13 -0000
@@ -44,6 +44,8 @@
 #include <winnls.h>
 #include "winecon_private.h"
 
+#include "wine/library.h"
+#include "wine/port.h"
 #include "wine/server.h"
 #include "wine/debug.h"
 
@@ -53,6 +55,12 @@
 
 #if defined(HAVE_CURSES_H) || defined(HAVE_NCURSES_H)
 
+#ifdef HAVE_NCURSES_H
+ #define CURSES_NAME "ncurses"
+#else
+ #define CURSES_NAME "curses"
+#endif
+
 struct inner_data_curse 
 {
     mmask_t             initial_mouse_mask;
@@ -63,6 +71,146 @@
 };
 
 
+static void *nc_handle = NULL;
+
+#define MAKE_FUNCPTR(f) typeof(f) * p_##f = NULL;
+
+MAKE_FUNCPTR(curs_set)
+MAKE_FUNCPTR(delwin)
+MAKE_FUNCPTR(endwin)
+MAKE_FUNCPTR(getmouse)
+MAKE_FUNCPTR(has_colors)
+MAKE_FUNCPTR(init_pair)
+#ifndef initscr
+MAKE_FUNCPTR(initscr)
+#endif
+#ifndef intrflush
+MAKE_FUNCPTR(intrflush)
+#endif
+MAKE_FUNCPTR(keypad)
+MAKE_FUNCPTR(mouseinterval)
+MAKE_FUNCPTR(mousemask)
+MAKE_FUNCPTR(newpad)
+#ifndef nodelay
+MAKE_FUNCPTR(nodelay)
+#endif
+#ifndef noecho
+MAKE_FUNCPTR(noecho)
+#endif
+MAKE_FUNCPTR(prefresh)
+MAKE_FUNCPTR(raw)
+MAKE_FUNCPTR(start_color)
+MAKE_FUNCPTR(stdscr)
+MAKE_FUNCPTR(waddchnstr)
+MAKE_FUNCPTR(wmove)
+MAKE_FUNCPTR(wgetch)
+
+#undef MAKE_FUNCPTR
+
+/**********************************************************************/
+
+typedef struct {
+    LPVOID lpCallback;
+    LPVOID lpContext;
+} DirectDrawEnumerateProcData;
+
+static BOOL WCCURSES_bind_libcurses()
+{
+#ifdef HAVE_NCURSES_H
+    char *ncname = SONAME_LIBNCURSES;
+#else
+    char *ncname = SONAME_LIBCURSES;
+#endif
+
+    nc_handle = wine_dlopen(ncname, RTLD_NOW, NULL, 0);
+    if(!nc_handle)
+    {
+        WINE_MESSAGE("Wine cannot find the " CURSES_NAME " library (%s).\n",
+                     ncname);
+        return FALSE;
+    }
+
+#define LOAD_FUNCPTR(f)                                      \
+    if((p_##f = wine_dlsym(nc_handle, #f, NULL, 0)) == NULL) \
+    {                                                        \
+        WINE_WARN("Can't find symbol %s\n", #f);             \
+        goto sym_not_found;                                  \
+    }
+
+    LOAD_FUNCPTR(curs_set)
+    LOAD_FUNCPTR(delwin)
+    LOAD_FUNCPTR(endwin)
+    LOAD_FUNCPTR(getmouse)
+    LOAD_FUNCPTR(has_colors)
+    LOAD_FUNCPTR(init_pair)
+#ifndef initscr
+    LOAD_FUNCPTR(initscr)
+#endif
+#ifndef intrflush
+    LOAD_FUNCPTR(intrflush)
+#endif
+    LOAD_FUNCPTR(keypad)
+    LOAD_FUNCPTR(mouseinterval)
+    LOAD_FUNCPTR(mousemask)
+    LOAD_FUNCPTR(newpad)
+#ifndef nodelay
+    LOAD_FUNCPTR(nodelay)
+#endif
+#ifndef noecho
+    LOAD_FUNCPTR(noecho)
+#endif
+    LOAD_FUNCPTR(prefresh)
+    LOAD_FUNCPTR(raw)
+    LOAD_FUNCPTR(start_color)
+    LOAD_FUNCPTR(stdscr)
+    LOAD_FUNCPTR(waddchnstr)
+    LOAD_FUNCPTR(wmove)
+    LOAD_FUNCPTR(wgetch)
+
+#undef LOAD_FUNCPTR
+
+    return TRUE;
+
+sym_not_found:
+    WINE_MESSAGE(
+      "Wine cannot find certain functions that it needs inside the "
+       CURSES_NAME "\nlibrary.  To enable Wine to use " CURSES_NAME 
+      " please upgrade your " CURSES_NAME "\nlibraries\n");
+    wine_dlclose(nc_handle, NULL, 0);
+    nc_handle = NULL;
+    return FALSE;
+}
+
+#define curs_set p_curs_set
+#define delwin p_delwin
+#define endwin p_endwin
+#define getmouse p_getmouse
+#define has_colors p_has_colors
+#define init_pair p_init_pair
+#ifndef initscr
+#define initscr p_initscr
+#endif
+#ifndef intrflush
+#define intrflush p_intrflush
+#endif
+#define keypad p_keypad
+#define mouseinterval p_mouseinterval
+#define mousemask p_mousemask
+#define newpad p_newpad
+#ifndef nodelay
+#define nodelay p_nodelay
+#endif
+#ifndef noecho
+#define noecho p_noecho
+#endif
+#define prefresh p_prefresh
+#define raw p_raw
+#define start_color p_start_color
+#define stdscr (*p_stdscr)
+#define waddchnstr p_waddchnstr
+#define wmove p_wmove
+#define wgetch p_wgetch
+
 /******************************************************************
  *		WCCURSES_ResizeScreenBuffer
  *
@@ -719,6 +867,9 @@
  */
 enum init_return WCCURSES_InitBackend(struct inner_data* data)
 {
+    if( !WCCURSES_bind_libcurses() )
+        return init_failed;
+
     data->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct inner_data_curse));
     if (!data->private) return init_failed;
 


More information about the wine-patches mailing list