shadow: improve subsystem structure
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 18 Sep 2014 19:43:11 +0000 (15:43 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 18 Sep 2014 19:43:11 +0000 (15:43 -0400)
include/freerdp/server/shadow.h
server/shadow/Mac/mac_shadow.c
server/shadow/Win/win_shadow.c
server/shadow/X11/x11_shadow.c
server/shadow/shadow_server.c
server/shadow/shadow_subsystem.c
server/shadow/shadow_subsystem.h

index f3b10c3..eee5643 100644 (file)
@@ -47,15 +47,19 @@ typedef struct rdp_shadow_encoder rdpShadowEncoder;
 typedef struct rdp_shadow_capture rdpShadowCapture;
 typedef struct rdp_shadow_subsystem rdpShadowSubsystem;
 
-typedef rdpShadowSubsystem* (*pfnShadowCreateSubsystem)(rdpShadowServer* server);
+typedef struct _RDP_SHADOW_ENTRY_POINTS RDP_SHADOW_ENTRY_POINTS;
+typedef int (*pfnShadowSubsystemEntry)(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
+
+typedef rdpShadowSubsystem* (*pfnShadowSubsystemNew)();
+typedef void (*pfnShadowSubsystemFree)(rdpShadowSubsystem* subsystem);
 
 typedef int (*pfnShadowSubsystemInit)(rdpShadowSubsystem* subsystem);
 typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem);
+
 typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem);
 typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
-typedef void (*pfnShadowSubsystemFree)(rdpShadowSubsystem* subsystem);
 
-typedef int (*pfnShadowEnumMonitors)(rdpShadowSubsystem* subsystem, MONITOR_DEF* monitors, int maxMonitors);
+typedef int (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, int maxMonitors);
 
 typedef int (*pfnShadowSurfaceCopy)(rdpShadowSubsystem* subsystem);
 typedef int (*pfnShadowSurfaceUpdate)(rdpShadowSubsystem* subsystem, REGION16* subRect);
@@ -112,7 +116,22 @@ struct rdp_shadow_server
        freerdp_listener* listener;
 };
 
+struct _RDP_SHADOW_ENTRY_POINTS
+{
+       pfnShadowSubsystemNew New;
+       pfnShadowSubsystemFree Free;
+
+       pfnShadowSubsystemInit Init;
+       pfnShadowSubsystemUninit Uninit;
+
+       pfnShadowSubsystemStart Start;
+       pfnShadowSubsystemStop Stop;
+
+       pfnShadowEnumMonitors EnumMonitors;
+};
+
 #define RDP_SHADOW_SUBSYSTEM_COMMON() \
+       RDP_SHADOW_ENTRY_POINTS ep; \
        HANDLE event; \
        int numMonitors; \
        int selectedMonitor; \
@@ -123,16 +142,6 @@ struct rdp_shadow_server
        wMessagePipe* MsgPipe; \
        SYNCHRONIZATION_BARRIER barrier; \
        \
-       pfnShadowSubsystemInit Init; \
-       pfnShadowSubsystemUninit Uninit; \
-       pfnShadowSubsystemStart Start; \
-       pfnShadowSubsystemStop Stop; \
-       pfnShadowSubsystemFree Free; \
-       \
-       pfnShadowEnumMonitors EnumMonitors; \
-       pfnShadowSurfaceCopy SurfaceCopy; \
-       pfnShadowSurfaceUpdate SurfaceUpdate; \
-       \
        pfnShadowSynchronizeEvent SynchronizeEvent; \
        pfnShadowKeyboardEvent KeyboardEvent; \
        pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \
@@ -159,7 +168,7 @@ FREERDP_API int shadow_server_stop(rdpShadowServer* server);
 FREERDP_API int shadow_server_init(rdpShadowServer* server);
 FREERDP_API int shadow_server_uninit(rdpShadowServer* server);
 
-FREERDP_API int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors, UINT32 flags);
+FREERDP_API int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors, const char* name);
 
 FREERDP_API rdpShadowServer* shadow_server_new();
 FREERDP_API void shadow_server_free(rdpShadowServer* server);
index ed1e09b..9132027 100644 (file)
@@ -538,7 +538,7 @@ void* mac_shadow_subsystem_thread(macShadowSubsystem* subsystem)
        return NULL;
 }
 
-int mac_shadow_enum_monitors(macShadowSubsystem* subsystem, MONITOR_DEF* monitors, int maxMonitors)
+int mac_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
 {
        int index;
        size_t wide, high;
@@ -621,7 +621,7 @@ void mac_shadow_subsystem_free(macShadowSubsystem* subsystem)
        free(subsystem);
 }
 
-macShadowSubsystem* mac_shadow_subsystem_new(rdpShadowServer* server)
+macShadowSubsystem* mac_shadow_subsystem_new()
 {
        macShadowSubsystem* subsystem;
 
@@ -630,14 +630,6 @@ macShadowSubsystem* mac_shadow_subsystem_new(rdpShadowServer* server)
        if (!subsystem)
                return NULL;
 
-       subsystem->Init = (pfnShadowSubsystemInit) mac_shadow_subsystem_init;
-       subsystem->Uninit = (pfnShadowSubsystemInit) mac_shadow_subsystem_uninit;
-       subsystem->Start = (pfnShadowSubsystemStart) mac_shadow_subsystem_start;
-       subsystem->Stop = (pfnShadowSubsystemStop) mac_shadow_subsystem_stop;
-       subsystem->Free = (pfnShadowSubsystemFree) mac_shadow_subsystem_free;
-
-       subsystem->EnumMonitors = (pfnShadowEnumMonitors) mac_shadow_enum_monitors;
-
        subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) mac_shadow_input_synchronize_event;
        subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) mac_shadow_input_keyboard_event;
        subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) mac_shadow_input_unicode_keyboard_event;
@@ -647,7 +639,18 @@ macShadowSubsystem* mac_shadow_subsystem_new(rdpShadowServer* server)
        return subsystem;
 }
 
-rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server)
+int Mac_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
 {
-       return (rdpShadowSubsystem*) mac_shadow_subsystem_new(server);
+       pEntryPoints->New = (pfnShadowSubsystemNew) mac_shadow_subsystem_new;
+       pEntryPoints->Free = (pfnShadowSubsystemFree) mac_shadow_subsystem_free;
+
+       pEntryPoints->Init = (pfnShadowSubsystemInit) mac_shadow_subsystem_init;
+       pEntryPoints->Uninit = (pfnShadowSubsystemInit) mac_shadow_subsystem_uninit;
+
+       pEntryPoints->Start = (pfnShadowSubsystemStart) mac_shadow_subsystem_start;
+       pEntryPoints->Stop = (pfnShadowSubsystemStop) mac_shadow_subsystem_stop;
+
+       pEntryPoints->EnumMonitors = (pfnShadowEnumMonitors) mac_shadow_enum_monitors;
+
+       return 1;
 }
index 6574567..b70b61f 100644 (file)
@@ -399,7 +399,7 @@ void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem)
 
 #endif
 
-int win_shadow_enum_monitors(winShadowSubsystem* subsystem, MONITOR_DEF* monitors, int maxMonitors)
+int win_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
 {
        HDC hdc;
        int index;
@@ -440,25 +440,10 @@ int win_shadow_enum_monitors(winShadowSubsystem* subsystem, MONITOR_DEF* monitor
 
 int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
 {
-       HDC hdc;
        int status;
-       DWORD iDevNum = 0;
        MONITOR_DEF* virtualScreen;
-       DISPLAY_DEVICE DisplayDevice;
-
-       ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
-       DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
-
-       if (!EnumDisplayDevices(NULL, iDevNum, &DisplayDevice, 0))
-               return -1;
 
-       hdc = CreateDC(DisplayDevice.DeviceName, NULL, NULL, NULL);
-
-       subsystem->width = GetDeviceCaps(hdc, HORZRES);
-       subsystem->height = GetDeviceCaps(hdc, VERTRES);
-       subsystem->bpp = GetDeviceCaps(hdc, BITSPIXEL);
-
-       DeleteDC(hdc);
+       subsystem->numMonitors = win_shadow_enum_monitors(subsystem->monitors, 16);
 
 #if defined(WITH_WDS_API)
        status = win_shadow_wds_init(subsystem);
@@ -474,16 +459,6 @@ int win_shadow_subsystem_init(winShadowSubsystem* subsystem)
        virtualScreen->bottom = subsystem->height;
        virtualScreen->flags = 1;
 
-       if (subsystem->numMonitors < 1)
-       {
-               subsystem->numMonitors = 1;
-               subsystem->monitors[0].left = virtualScreen->left;
-               subsystem->monitors[0].top = virtualScreen->top;
-               subsystem->monitors[0].right = virtualScreen->right;
-               subsystem->monitors[0].bottom = virtualScreen->bottom;
-               subsystem->monitors[0].flags = 1;
-       }
-
        WLog_INFO(TAG, "width: %d height: %d", subsystem->width, subsystem->height);
 
        return 1;
@@ -535,7 +510,7 @@ void win_shadow_subsystem_free(winShadowSubsystem* subsystem)
        free(subsystem);
 }
 
-winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server)
+winShadowSubsystem* win_shadow_subsystem_new()
 {
        winShadowSubsystem* subsystem;
 
@@ -544,14 +519,6 @@ winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server)
        if (!subsystem)
                return NULL;
 
-       subsystem->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init;
-       subsystem->Uninit = (pfnShadowSubsystemInit) win_shadow_subsystem_uninit;
-       subsystem->Start = (pfnShadowSubsystemStart) win_shadow_subsystem_start;
-       subsystem->Stop = (pfnShadowSubsystemStop) win_shadow_subsystem_stop;
-       subsystem->Free = (pfnShadowSubsystemFree) win_shadow_subsystem_free;
-
-       subsystem->EnumMonitors = (pfnShadowEnumMonitors) win_shadow_enum_monitors;
-
        subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) win_shadow_input_synchronize_event;
        subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) win_shadow_input_keyboard_event;
        subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) win_shadow_input_unicode_keyboard_event;
@@ -561,7 +528,18 @@ winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server)
        return subsystem;
 }
 
-rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server)
+int Win_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
 {
-       return (rdpShadowSubsystem*) win_shadow_subsystem_new(server);
+       pEntryPoints->New = (pfnShadowSubsystemNew) win_shadow_subsystem_new;
+       pEntryPoints->Free = (pfnShadowSubsystemFree) win_shadow_subsystem_free;
+
+       pEntryPoints->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init;
+       pEntryPoints->Uninit = (pfnShadowSubsystemInit) win_shadow_subsystem_uninit;
+
+       pEntryPoints->Start = (pfnShadowSubsystemStart) win_shadow_subsystem_start;
+       pEntryPoints->Stop = (pfnShadowSubsystemStop) win_shadow_subsystem_stop;
+
+       pEntryPoints->EnumMonitors = (pfnShadowEnumMonitors) win_shadow_enum_monitors;
+
+       return 1;
 }
index d25176e..1c0b5e8 100644 (file)
@@ -781,39 +781,62 @@ int x11_shadow_xshm_init(x11ShadowSubsystem* subsystem)
        return 1;
 }
 
-int x11_shadow_enum_monitors(x11ShadowSubsystem* subsystem, MONITOR_DEF* monitors, int maxMonitors)
+int x11_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
 {
        int index;
+       Display* display;
+       int displayWidth;
+       int displayHeight;
        int numMonitors = 0;
        MONITOR_DEF* monitor;
 
+       if (!getenv("DISPLAY"))
+               setenv("DISPLAY", ":0", 1);
+
+       display = XOpenDisplay(NULL);
+
+       if (!display)
+       {
+               WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL));
+               return -1;
+       }
+
+       displayWidth = WidthOfScreen(DefaultScreenOfDisplay(display));
+       displayHeight = HeightOfScreen(DefaultScreenOfDisplay(display));
+
 #ifdef WITH_XINERAMA
-       if (x11_shadow_xinerama_init(subsystem) > 0)
        {
+               int major, minor;
+               int xinerama_event;
+               int xinerama_error;
                XineramaScreenInfo* screen;
                XineramaScreenInfo* screens;
 
-               screens = XineramaQueryScreens(subsystem->display, &numMonitors);
+               if (XineramaQueryExtension(display, &xinerama_event, &xinerama_error) &&
+                               XDamageQueryVersion(display, &major, &minor) && XineramaIsActive(display))
+               {
+                       screens = XineramaQueryScreens(display, &numMonitors);
 
-               if (numMonitors > maxMonitors)
-                       numMonitors = maxMonitors;
+                       if (numMonitors > maxMonitors)
+                               numMonitors = maxMonitors;
 
-               if (screens && (numMonitors > 0))
-               {
-                       for (index = 0; index < numMonitors; index++)
+                       if (screens && (numMonitors > 0))
                        {
-                               screen = &screens[index];
-                               monitor = &monitors[index];
-
-                               monitor->left = screen->x_org;
-                               monitor->top = screen->y_org;
-                               monitor->right = monitor->left + screen->width;
-                               monitor->bottom = monitor->top + screen->height;
-                               monitor->flags = (index == 0) ? 1 : 0;
+                               for (index = 0; index < numMonitors; index++)
+                               {
+                                       screen = &screens[index];
+                                       monitor = &monitors[index];
+
+                                       monitor->left = screen->x_org;
+                                       monitor->top = screen->y_org;
+                                       monitor->right = monitor->left + screen->width;
+                                       monitor->bottom = monitor->top + screen->height;
+                                       monitor->flags = (index == 0) ? 1 : 0;
+                               }
                        }
-               }
 
-               XFree(screens);
+                       XFree(screens);
+               }
        }
 #endif
 
@@ -822,14 +845,12 @@ int x11_shadow_enum_monitors(x11ShadowSubsystem* subsystem, MONITOR_DEF* monitor
                index = 0;
                numMonitors = 1;
 
-               x11_shadow_subsystem_base_init(subsystem);
-
                monitor = &monitors[index];
 
                monitor->left = 0;
                monitor->top = 0;
-               monitor->right = subsystem->width;
-               monitor->bottom = subsystem->height;
+               monitor->right = displayWidth;
+               monitor->bottom = displayHeight;
                monitor->flags = 1;
        }
 
@@ -850,9 +871,9 @@ int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem)
        XPixmapFormatValues* pfs;
        MONITOR_DEF* virtualScreen;
 
-       x11_shadow_subsystem_base_init(subsystem);
+       subsystem->numMonitors = x11_shadow_enum_monitors(subsystem->monitors, 16);
 
-       subsystem->numMonitors = x11_shadow_enum_monitors(subsystem, subsystem->monitors, 16);
+       x11_shadow_subsystem_base_init(subsystem);
 
        extensions = XListExtensions(subsystem->display, &nextensions);
 
@@ -960,16 +981,6 @@ int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem)
        virtualScreen->bottom = subsystem->height;
        virtualScreen->flags = 1;
 
-       if (subsystem->numMonitors < 1)
-       {
-               subsystem->numMonitors = 1;
-               subsystem->monitors[0].left = virtualScreen->left;
-               subsystem->monitors[0].top = virtualScreen->top;
-               subsystem->monitors[0].right = virtualScreen->right;
-               subsystem->monitors[0].bottom = virtualScreen->bottom;
-               subsystem->monitors[0].flags = 1;
-       }
-
        WLog_INFO(TAG, "X11 Extensions: XFixes: %d Xinerama: %d XDamage: %d XShm: %d",
                        subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage, subsystem->use_xshm);
 
@@ -1034,7 +1045,7 @@ void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem)
        free(subsystem);
 }
 
-x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
+x11ShadowSubsystem* x11_shadow_subsystem_new()
 {
        x11ShadowSubsystem* subsystem;
 
@@ -1043,14 +1054,6 @@ x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
        if (!subsystem)
                return NULL;
 
-       subsystem->Init = (pfnShadowSubsystemInit) x11_shadow_subsystem_init;
-       subsystem->Uninit = (pfnShadowSubsystemInit) x11_shadow_subsystem_uninit;
-       subsystem->Start = (pfnShadowSubsystemStart) x11_shadow_subsystem_start;
-       subsystem->Stop = (pfnShadowSubsystemStop) x11_shadow_subsystem_stop;
-       subsystem->Free = (pfnShadowSubsystemFree) x11_shadow_subsystem_free;
-
-       subsystem->EnumMonitors = (pfnShadowEnumMonitors) x11_shadow_enum_monitors;
-
        subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) x11_shadow_input_synchronize_event;
        subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) x11_shadow_input_keyboard_event;
        subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) x11_shadow_input_unicode_keyboard_event;
@@ -1066,7 +1069,18 @@ x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server)
        return subsystem;
 }
 
-rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server)
+int X11_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
 {
-       return (rdpShadowSubsystem*) x11_shadow_subsystem_new(server);
+       pEntryPoints->New = (pfnShadowSubsystemNew) x11_shadow_subsystem_new;
+       pEntryPoints->Free = (pfnShadowSubsystemFree) x11_shadow_subsystem_free;
+
+       pEntryPoints->Init = (pfnShadowSubsystemInit) x11_shadow_subsystem_init;
+       pEntryPoints->Uninit = (pfnShadowSubsystemInit) x11_shadow_subsystem_uninit;
+
+       pEntryPoints->Start = (pfnShadowSubsystemStart) x11_shadow_subsystem_start;
+       pEntryPoints->Stop = (pfnShadowSubsystemStop) x11_shadow_subsystem_stop;
+
+       pEntryPoints->EnumMonitors = (pfnShadowEnumMonitors) x11_shadow_enum_monitors;
+
+       return 1;
 }
index 4300633..792102f 100644 (file)
@@ -304,10 +304,7 @@ void* shadow_server_thread(rdpShadowServer* server)
        StopEvent = server->StopEvent;
        subsystem = server->subsystem;
 
-       if (subsystem->Start)
-       {
-               subsystem->Start(subsystem);
-       }
+       shadow_subsystem_start(server->subsystem);
 
        while (1)
        {
@@ -341,10 +338,7 @@ void* shadow_server_thread(rdpShadowServer* server)
 
        listener->Close(listener);
 
-       if (subsystem->Stop)
-       {
-               subsystem->Stop(subsystem);
-       }
+       shadow_subsystem_stop(server->subsystem);
 
        ExitThread(0);
 
@@ -560,7 +554,7 @@ int shadow_server_init(rdpShadowServer* server)
        server->listener->info = (void*) server;
        server->listener->PeerAccepted = shadow_client_accepted;
 
-       server->subsystem = shadow_subsystem_new(0);
+       server->subsystem = shadow_subsystem_new(NULL);
 
        if (!server->subsystem)
                return -1;
@@ -580,12 +574,6 @@ int shadow_server_uninit(rdpShadowServer* server)
                server->listener = NULL;
        }
 
-       if (server->subsystem)
-       {
-               server->subsystem->Free(server->subsystem);
-               server->subsystem = NULL;
-       }
-
        if (server->CertificateFile)
        {
                free(server->CertificateFile);
@@ -609,26 +597,6 @@ int shadow_server_uninit(rdpShadowServer* server)
        return 1;
 }
 
-int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors, UINT32 flags)
-{
-       int numMonitors = 0;
-       rdpShadowSubsystem* subsystem;
-
-       subsystem = shadow_subsystem_new(flags);
-
-       if (!subsystem)
-               return -1;
-
-       if (!subsystem->EnumMonitors)
-               return -1;
-
-       numMonitors = subsystem->EnumMonitors(subsystem, monitors, maxMonitors);
-
-       shadow_subsystem_free(subsystem);
-
-       return numMonitors;
-}
-
 rdpShadowServer* shadow_server_new()
 {
        rdpShadowServer* server;
@@ -658,7 +626,7 @@ void shadow_server_free(rdpShadowServer* server)
                server->clients = NULL;
        }
 
-       shadow_server_uninit(server);
+       shadow_subsystem_free(server->subsystem);
 
        free(server);
 }
index 4221137..9d41a8f 100644 (file)
 
 #include "shadow_subsystem.h"
 
+struct _RDP_SHADOW_SUBSYSTEM
+{
+       const char* name;
+       pfnShadowSubsystemEntry entry;
+};
+typedef struct _RDP_SHADOW_SUBSYSTEM RDP_SHADOW_SUBSYSTEM;
+
+
 #ifdef WITH_SHADOW_X11
-extern rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server);
+extern int X11_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
 #endif
 
 #ifdef WITH_SHADOW_MAC
-extern rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server);
+extern int Mac_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
 #endif
 
 #ifdef WITH_SHADOW_WIN
-extern rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server);
+extern int Win_ShadowSubsystemEntry(RDP_SHADOW_ENTRY_POINTS* pEntryPoints);
 #endif
 
-rdpShadowSubsystem* shadow_subsystem_new(UINT32 flags)
+
+static RDP_SHADOW_SUBSYSTEM g_Subsystems[] =
 {
-       rdpShadowSubsystem* subsystem = NULL;
-       pfnShadowCreateSubsystem CreateSubsystem = NULL;
 
 #ifdef WITH_SHADOW_X11
-       CreateSubsystem = X11_ShadowCreateSubsystem;
+       { "X11", X11_ShadowSubsystemEntry },
 #endif
 
 #ifdef WITH_SHADOW_MAC
-       CreateSubsystem = Mac_ShadowCreateSubsystem;
+       { "Mac", Mac_ShadowSubsystemEntry },
 #endif
 
 #ifdef WITH_SHADOW_WIN
-       CreateSubsystem = Win_ShadowCreateSubsystem;
+       { "Win", Win_ShadowSubsystemEntry },
 #endif
 
-       if (CreateSubsystem)
-               subsystem = CreateSubsystem(NULL);
+       { "", NULL }
+};
+
+static int g_SubsystemCount = (sizeof(g_Subsystems) / sizeof(g_Subsystems[0]));
+
+pfnShadowSubsystemEntry shadow_subsystem_load_static_entry(const char* name)
+{
+       int index;
+
+       if (!name)
+       {
+               for (index = 0; index < g_SubsystemCount; index++)
+               {
+                       if (g_Subsystems[index].name)
+                               return g_Subsystems[index].entry;
+               }
+       }
+
+       for (index = 0; index < g_SubsystemCount; index++)
+       {
+               if (strcmp(name, g_Subsystems[index].name) == 0)
+                       return g_Subsystems[index].entry;
+       }
+
+       return NULL;
+}
+
+int shadow_subsystem_load_entry_points(RDP_SHADOW_ENTRY_POINTS* pEntryPoints, const char* name)
+{
+       pfnShadowSubsystemEntry entry;
+
+       entry = shadow_subsystem_load_static_entry(name);
+
+       if (!entry)
+               return -1;
+
+       ZeroMemory(pEntryPoints, sizeof(RDP_SHADOW_ENTRY_POINTS));
+
+       if (entry(pEntryPoints) < 0)
+               return -1;
+
+       return 1;
+}
+
+rdpShadowSubsystem* shadow_subsystem_new(const char* name)
+{
+       RDP_SHADOW_ENTRY_POINTS ep;
+       rdpShadowSubsystem* subsystem = NULL;
+
+       shadow_subsystem_load_entry_points(&ep, name);
+
+       if (!ep.New)
+               return NULL;
+
+       subsystem = ep.New();
+
+       if (!subsystem)
+               return NULL;
+
+       CopyMemory(&(subsystem->ep), &ep, sizeof(RDP_SHADOW_ENTRY_POINTS));
 
        return subsystem;
 }
 
 void shadow_subsystem_free(rdpShadowSubsystem* subsystem)
 {
-       if (subsystem->Free)
-               subsystem->Free(subsystem);
+       if (subsystem->ep.Free)
+               subsystem->ep.Free(subsystem);
 }
 
 int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server)
@@ -76,19 +141,19 @@ int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server
        subsystem->MsgPipe = MessagePipe_New();
        region16_init(&(subsystem->invalidRegion));
 
-       if (!subsystem->Init)
+       if (!subsystem->ep.Init)
                return -1;
 
-       if (subsystem->Init)
-               status = subsystem->Init(subsystem);
+       if (subsystem->ep.Init)
+               status = subsystem->ep.Init(subsystem);
 
        return status;
 }
 
 void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
 {
-       if (subsystem->Uninit)
-               subsystem->Uninit(subsystem);
+       if (subsystem->ep.Uninit)
+               subsystem->ep.Uninit(subsystem);
 
        if (subsystem->updateEvent)
        {
@@ -107,3 +172,40 @@ void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
                region16_uninit(&(subsystem->invalidRegion));
        }
 }
+
+int shadow_subsystem_start(rdpShadowSubsystem* subsystem)
+{
+       int status;
+
+       if (!subsystem->ep.Start)
+               return -1;
+
+       status = subsystem->ep.Start(subsystem);
+
+       return status;
+}
+
+int shadow_subsystem_stop(rdpShadowSubsystem* subsystem)
+{
+       int status;
+
+       if (!subsystem->ep.Stop)
+               return -1;
+
+       status = subsystem->ep.Stop(subsystem);
+
+       return status;
+}
+
+int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors, const char* name)
+{
+       int numMonitors = 0;
+       RDP_SHADOW_ENTRY_POINTS ep;
+
+       if (shadow_subsystem_load_entry_points(&ep, name) < 0)
+               return -1;
+
+       numMonitors = ep.EnumMonitors(monitors, maxMonitors);
+
+       return numMonitors;
+}
index e22b545..9e61d6c 100644 (file)
 extern "C" {
 #endif
 
-rdpShadowSubsystem* shadow_subsystem_new(UINT32 flags);
+rdpShadowSubsystem* shadow_subsystem_new(const char* name);
 void shadow_subsystem_free(rdpShadowSubsystem* subsystem);
 
 int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server);
 void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem);
 
+int shadow_subsystem_start(rdpShadowSubsystem* subsystem);
+int shadow_subsystem_stop(rdpShadowSubsystem* subsystem);
+
 #ifdef __cplusplus
 }
 #endif