xfreerdp: fix fullscreen mode
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 10 Feb 2015 20:15:30 +0000 (15:15 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 10 Feb 2015 20:15:30 +0000 (15:15 -0500)
client/X11/xf_client.c
client/X11/xf_monitor.c
client/X11/xf_monitor.h
client/X11/xf_window.c
client/X11/xfreerdp.h
client/common/cmdline.c
libfreerdp/core/settings.c

index 0e6693d..f479f98 100644 (file)
@@ -495,23 +495,22 @@ BOOL xf_process_x_events(freerdp* instance)
 
 BOOL xf_create_window(xfContext* xfc)
 {
-       freerdp* instance = xfc->instance;
-       rdpSettings* settings = instance->settings;
+       XGCValues gcv;
        XEvent xevent;
        int width, height;
        char* windowTitle;
-       XGCValues gcv;
-
-       xf_keyboard_init(xfc);
-  xfc->fullscreen = settings->Fullscreen;
-       xfc->grab_keyboard = settings->GrabKeyboard;
-       xfc->fullscreen_toggle = settings->ToggleFullscreen;
-       xf_detect_monitors(xfc, settings);
+       rdpSettings* settings = xfc->settings;
 
        ZeroMemory(&xevent, sizeof(xevent));
+
+       xf_detect_monitors(xfc);
+
        width = xfc->width;
        height = xfc->height;
 
+       if (!xfc->hdc)
+               xfc->hdc = gdi_CreateDC(CLRBUF_32BPP, xfc->bpp);
+
        if (!xfc->remote_app)
        {
                xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen);
@@ -521,56 +520,58 @@ BOOL xf_create_window(xfContext* xfc)
                xfc->attribs.colormap = xfc->colormap;
                xfc->attribs.bit_gravity = NorthWestGravity;
                xfc->attribs.win_gravity = NorthWestGravity;
+
 #ifdef WITH_XRENDER
                xfc->offset_x = 0;
                xfc->offset_y = 0;
 #endif
 
-               if (xfc->settings->WindowTitle)
+               if (settings->WindowTitle)
                {
-                       windowTitle = _strdup(xfc->settings->WindowTitle);
+                       windowTitle = _strdup(settings->WindowTitle);
                }
-               else if (xfc->settings->ServerPort == 3389)
+               else if (settings->ServerPort == 3389)
                {
-                       windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->settings->ServerHostname));
-                       sprintf(windowTitle, "FreeRDP: %s", xfc->settings->ServerHostname);
+                       windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(settings->ServerHostname));
+                       sprintf(windowTitle, "FreeRDP: %s", settings->ServerHostname);
                }
                else
                {
-                       windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->settings->ServerHostname) + sizeof(":00000"));
-                       sprintf(windowTitle, "FreeRDP: %s:%i", xfc->settings->ServerHostname, xfc->settings->ServerPort);
+                       windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(settings->ServerHostname) + sizeof(":00000"));
+                       sprintf(windowTitle, "FreeRDP: %s:%i", settings->ServerHostname, settings->ServerPort);
                }
 
                if (xfc->fullscreen)
                {
-                       width = WidthOfScreen(xfc->screen);
-                       height = HeightOfScreen(xfc->screen);
+                       width = xfc->desktopWidth;
+                       height = xfc->desktopHeight;
                }
 
 #ifdef WITH_XRENDER
-               if (xfc->settings->SmartSizing)
+               if (settings->SmartSizing)
                {
                        if (xfc->fullscreen)
                        {
                                if (xfc->window)
                                {
-                                       xfc->settings->SmartSizingWidth = xfc->window->width;
-                                       xfc->settings->SmartSizingHeight = xfc->window->height;
+                                       settings->SmartSizingWidth = xfc->window->width;
+                                       settings->SmartSizingHeight = xfc->window->height;
                                }
                        }
                        else
                        {
-                               if (xfc->settings->SmartSizingWidth)
-                                       width = xfc->settings->SmartSizingWidth;
-                               if (xfc->settings->SmartSizingHeight)
-                                       height = xfc->settings->SmartSizingHeight;
+                               if (settings->SmartSizingWidth)
+                                       width = settings->SmartSizingWidth;
+                               if (settings->SmartSizingHeight)
+                                       height = settings->SmartSizingHeight;
                        }
+
                        xfc->scaledWidth = width;
                        xfc->scaledHeight = height;
                }
 #endif
-               assert(!xfc->window);
-               xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->settings->Decorations);
+
+               xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->decorations);
 
                free(windowTitle);
 
@@ -607,22 +608,98 @@ BOOL xf_create_window(xfContext* xfc)
        XFillRectangle(xfc->display, xfc->primary, xfc->gc, 0, 0, xfc->width, xfc->height);
        XFlush(xfc->display);
        assert(!xfc->image);
+
        xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
-                                                         (char*) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0);
+                       (char*) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0);
+
        return TRUE;
 }
 
+void xf_window_free(xfContext* xfc)
+{
+       if (xfc->gc_mono)
+       {
+               XFreeGC(xfc->display, xfc->gc_mono);
+               xfc->gc_mono = 0;
+       }
+
+       if (xfc->window)
+       {
+               xf_DestroyDesktopWindow(xfc, xfc->window);
+               xfc->window = NULL;
+       }
+
+       if (xfc->hdc)
+       {
+               gdi_DeleteDC(xfc->hdc);
+               xfc->hdc = NULL;
+       }
+
+       if (xfc->xv_context)
+       {
+               xf_tsmf_uninit(xfc, NULL);
+               xfc->xv_context = NULL;
+       }
+
+       if (xfc->bitmap_buffer)
+       {
+               _aligned_free(xfc->bitmap_buffer);
+               xfc->bitmap_buffer = NULL;
+               xfc->bitmap_size = 0;
+       }
+
+       if (xfc->image)
+       {
+               xfc->image->data = NULL;
+               XDestroyImage(xfc->image);
+               xfc->image = NULL;
+       }
+
+       if (xfc->bitmap_mono)
+       {
+               XFreePixmap(xfc->display, xfc->bitmap_mono);
+               xfc->bitmap_mono = 0;
+       }
+
+       if (xfc->primary)
+       {
+               XFreePixmap(xfc->display, xfc->primary);
+               xfc->primary = 0;
+       }
+
+       if (xfc->gc)
+       {
+               XFreeGC(xfc->display, xfc->gc);
+               xfc->gc = 0;
+       }
+
+       if (xfc->modifierMap)
+       {
+               XFreeModifiermap(xfc->modifierMap);
+               xfc->modifierMap = NULL;
+       }
+}
+
 void xf_toggle_fullscreen(xfContext* xfc)
 {
        WindowStateChangeEventArgs e;
+       rdpContext* context = (rdpContext*) xfc;
+       rdpSettings* settings = context->settings;
+
        xf_lock_x11(xfc, TRUE);
+
        xf_window_free(xfc);
+
        xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
+       xfc->decorations = (xfc->fullscreen) ? FALSE : settings->Decorations;
+
        xf_create_window(xfc);
+
        xf_unlock_x11(xfc, TRUE);
+
        EventArgsInit(&e, "xfreerdp");
        e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
-       PubSub_OnWindowStateChange(((rdpContext*) xfc)->pubSub, xfc, &e);
+       PubSub_OnWindowStateChange(context->pubSub, context, &e);
 }
 
 void xf_toggle_control(xfContext* xfc)
@@ -818,28 +895,6 @@ int _xf_error_handler(Display* d, XErrorEvent* ev)
        return xf_error_handler(d, ev);
 }
 
-static void xf_post_disconnect(freerdp* instance)
-{
-       xfContext* xfc;
-
-       if (!instance || !instance->context || !instance->settings)
-               return;
-
-       xfc = (xfContext*) instance->context;
-
-       xf_monitors_free(xfc, instance->settings);
-       gdi_free(instance);
-
-       if (xfc->clipboard)
-       {
-               xf_clipboard_free(xfc->clipboard);
-               xfc->clipboard = NULL;
-       }
-
-       xf_window_free(xfc);
-       freerdp_channels_disconnect(instance->context->channels, instance);
-}
-
 static void xf_play_sound(rdpContext* context, PLAY_SOUND_UPDATE* play_sound)
 {
        xfContext* xfc = (xfContext*) context;
@@ -886,14 +941,15 @@ BOOL xf_pre_connect(freerdp* instance)
 {
        rdpChannels* channels;
        rdpSettings* settings;
+       rdpContext* context = instance->context;
        xfContext* xfc = (xfContext*) instance->context;
 
-       xfc->codecs = instance->context->codecs;
+       xfc->codecs = context->codecs;
        xfc->settings = instance->settings;
        xfc->instance = instance;
 
        settings = instance->settings;
-       channels = instance->context->channels;
+       channels = context->channels;
 
        settings->OsMajorType = OSMAJORTYPE_UNIX;
        settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;
@@ -923,10 +979,12 @@ BOOL xf_pre_connect(freerdp* instance)
        settings->OrderSupport[NEG_POLYGON_CB_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
        settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
        settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
+
        PubSub_SubscribeChannelConnected(instance->context->pubSub,
-                                                                        (pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler);
+                       (pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler);
        PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
-                                                                               (pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler);
+                       (pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler);
+
        freerdp_client_load_addins(channels, instance->settings);
        freerdp_channels_pre_connect(channels, instance);
 
@@ -953,7 +1011,20 @@ BOOL xf_pre_connect(freerdp* instance)
                WLog_INFO(TAG, "Authentication only. Don't connect to X.");
        }
 
-       instance->context->cache = cache_new(instance->settings);
+       if (!context->cache)
+               context->cache = cache_new(settings);
+
+       xf_keyboard_init(xfc);
+
+       xf_detect_monitors(xfc);
+       settings->DesktopWidth = xfc->desktopWidth;
+       settings->DesktopHeight = xfc->desktopHeight;
+
+       xfc->fullscreen = settings->Fullscreen;
+       xfc->decorations = settings->Decorations;
+       xfc->grab_keyboard = settings->GrabKeyboard;
+       xfc->fullscreen_toggle = settings->ToggleFullscreen;
+
        return TRUE;
 }
 
@@ -966,15 +1037,20 @@ BOOL xf_post_connect(freerdp* instance)
 {
        UINT32 flags;
        rdpCache* cache;
+       rdpUpdate* update;
+       rdpContext* context;
        rdpChannels* channels;
        rdpSettings* settings;
        ResizeWindowEventArgs e;
        xfContext* xfc = (xfContext*) instance->context;
 
-       cache = instance->context->cache;
-       channels = instance->context->channels;
+       context = instance->context;
+       cache = context->cache;
+       channels = context->channels;
        settings = instance->settings;
-       xf_register_graphics(instance->context->graphics);
+       update = context->update;
+
+       xf_register_graphics(context->graphics);
 
        flags = CLRCONV_ALPHA;
 
@@ -989,14 +1065,13 @@ BOOL xf_post_connect(freerdp* instance)
 
                gdi_init(instance, flags, NULL);
 
-               gdi = instance->context->gdi;
+               gdi = context->gdi;
                xfc->primary_buffer = gdi->primary_buffer;
        }
        else
        {
                xfc->srcBpp = settings->ColorDepth;
-               xf_gdi_register_update_callbacks(instance->update);
-               xfc->hdc = gdi_CreateDC(flags, xfc->bpp);
+               xf_gdi_register_update_callbacks(update);
        }
 
        xfc->width = settings->DesktopWidth;
@@ -1031,31 +1106,31 @@ BOOL xf_post_connect(freerdp* instance)
 
        if (settings->SoftwareGdi)
        {
-               instance->update->BeginPaint = xf_sw_begin_paint;
-               instance->update->EndPaint = xf_sw_end_paint;
-               instance->update->DesktopResize = xf_sw_desktop_resize;
+               update->BeginPaint = xf_sw_begin_paint;
+               update->EndPaint = xf_sw_end_paint;
+               update->DesktopResize = xf_sw_desktop_resize;
        }
        else
        {
-               instance->update->BeginPaint = xf_hw_begin_paint;
-               instance->update->EndPaint = xf_hw_end_paint;
-               instance->update->DesktopResize = xf_hw_desktop_resize;
+               update->BeginPaint = xf_hw_begin_paint;
+               update->EndPaint = xf_hw_end_paint;
+               update->DesktopResize = xf_hw_desktop_resize;
        }
 
-       pointer_cache_register_callbacks(instance->update);
+       pointer_cache_register_callbacks(update);
 
        if (!settings->SoftwareGdi)
        {
-               glyph_cache_register_callbacks(instance->update);
-               brush_cache_register_callbacks(instance->update);
-               bitmap_cache_register_callbacks(instance->update);
-               offscreen_cache_register_callbacks(instance->update);
-               palette_cache_register_callbacks(instance->update);
-               instance->update->BitmapUpdate = xf_gdi_bitmap_update;
+               glyph_cache_register_callbacks(update);
+               brush_cache_register_callbacks(update);
+               bitmap_cache_register_callbacks(update);
+               offscreen_cache_register_callbacks(update);
+               palette_cache_register_callbacks(update);
+               update->BitmapUpdate = xf_gdi_bitmap_update;
        }
 
-       instance->update->PlaySound = xf_play_sound;
-       instance->update->SetKeyboardIndicators = xf_keyboard_set_indicators;
+       update->PlaySound = xf_play_sound;
+       update->SetKeyboardIndicators = xf_keyboard_set_indicators;
 
        xfc->clipboard = xf_clipboard_new(xfc);
        freerdp_channels_post_connect(channels, instance);
@@ -1063,10 +1138,43 @@ BOOL xf_post_connect(freerdp* instance)
        EventArgsInit(&e, "xfreerdp");
        e.width = settings->DesktopWidth;
        e.height = settings->DesktopHeight;
-       PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
+       PubSub_OnResizeWindow(context->pubSub, xfc, &e);
+
        return TRUE;
 }
 
+static void xf_post_disconnect(freerdp* instance)
+{
+       xfContext* xfc;
+       rdpContext* context;
+
+       if (!instance || !instance->context)
+               return;
+
+       context = instance->context;
+       xfc = (xfContext*) context;
+
+       gdi_free(instance);
+
+       if (xfc->clipboard)
+       {
+               xf_clipboard_free(xfc->clipboard);
+               xfc->clipboard = NULL;
+       }
+
+       xf_window_free(xfc);
+
+       if (context->cache)
+       {
+               cache_free(context->cache);
+               context->cache = NULL;
+       }
+
+       xf_keyboard_free(xfc);
+
+       freerdp_channels_disconnect(context->channels, instance);
+}
+
 /** Callback set in the rdp_freerdp structure, and used to get the user's password,
  *  if required to establish the connection.
  *  This function is actually called in credssp_ntlmssp_client_init()
@@ -1149,80 +1257,6 @@ int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
        return 1;
 }
 
-void xf_window_free(xfContext* xfc)
-{
-       rdpContext* context = (rdpContext*) xfc;
-
-       xf_keyboard_free(xfc);
-
-       if (xfc->gc_mono)
-       {
-               XFreeGC(xfc->display, xfc->gc_mono);
-               xfc->gc_mono = 0;
-       }
-
-       if (xfc->window)
-       {
-               xf_DestroyDesktopWindow(xfc, xfc->window);
-               xfc->window = NULL;
-       }
-
-       if (context->cache)
-       {
-               cache_free(context->cache);
-               context->cache = NULL;
-       }
-
-       if (xfc->hdc)
-       {
-               gdi_DeleteDC(xfc->hdc);
-       }
-
-       if (xfc->xv_context)
-       {
-               xf_tsmf_uninit(xfc, NULL);
-               xfc->xv_context = NULL;
-       }
-
-       if (xfc->bitmap_buffer)
-       {
-               _aligned_free(xfc->bitmap_buffer);
-               xfc->bitmap_buffer = NULL;
-    xfc->bitmap_size = 0;
-       }
-
-       if (xfc->image)
-       {
-               xfc->image->data = NULL;
-               XDestroyImage(xfc->image);
-               xfc->image = NULL;
-       }
-
-       if (xfc->bitmap_mono)
-       {
-               XFreePixmap(xfc->display, xfc->bitmap_mono);
-               xfc->bitmap_mono = 0;
-       }
-
-       if (xfc->primary)
-       {
-               XFreePixmap(xfc->display, xfc->primary);
-               xfc->primary = 0;
-       }
-
-       if (xfc->gc)
-       {
-               XFreeGC(xfc->display, xfc->gc);
-               xfc->gc = 0;
-       }
-
-       if (xfc->modifierMap)
-       {
-               XFreeModifiermap(xfc->modifierMap);
-               xfc->modifierMap = NULL;
-       }
-}
-
 void* xf_input_thread(void* arg)
 {
        DWORD status;
@@ -1378,8 +1412,8 @@ void* xf_client_thread(void* param)
                ExitThread(exit_code);
        }
 
-       channels = instance->context->channels;
-       settings = instance->context->settings;
+       channels = context->channels;
+       settings = context->settings;
 
        if (!settings->AsyncInput)
        {
@@ -1605,10 +1639,8 @@ static int xfreerdp_client_stop(rdpContext* context)
 
 static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
 {
-       xfContext* xfc;
        rdpSettings* settings;
-
-       xfc = (xfContext*) instance->context;
+       xfContext* xfc = (xfContext*) instance->context;
 
        instance->PreConnect = xf_pre_connect;
        instance->PostConnect = xf_post_connect;
@@ -1647,7 +1679,7 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
        {
                WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL));
                WLog_ERR(TAG, "Please check that the $DISPLAY environment variable is properly set.");
-               return FALSE;
+               return -1;
        }
 
        assert(!xfc->mutex);
@@ -1656,7 +1688,7 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
        if (!xfc->mutex)
        {
                WLog_ERR(TAG, "Could not create mutex!");
-               return FALSE;
+               return -1;
        }
 
        xfc->_NET_WM_ICON = XInternAtom(xfc->display, "_NET_WM_ICON", False);
@@ -1687,7 +1719,7 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
        xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE;
        xfc->complex_regions = TRUE;
 
-  assert(!xfc->x11event);
+       assert(!xfc->x11event);
        xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
        xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number);
        xfc->format = PIXEL_FORMAT_XRGB32;
@@ -1713,7 +1745,12 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
        xf_check_extensions(xfc);
 
        if (!xf_get_pixmap_info(xfc))
-               return FALSE;
+               return -1;
+
+       xfc->vscreen.monitors = calloc(16, sizeof(MONITOR_INFO));
+
+       if (!xfc->vscreen.monitors)
+               return -1;
 
        return 0;
 }
@@ -1750,6 +1787,12 @@ static void xfreerdp_client_free(freerdp* instance, rdpContext* context)
                CloseHandle(xfc->mutex);
                xfc->mutex = NULL;
        }
+
+       if (xfc->vscreen.monitors)
+       {
+               free(xfc->vscreen.monitors);
+               xfc->vscreen.monitors = NULL;
+       }
 }
 
 int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
index 59fa850..65689e1 100644 (file)
@@ -45,18 +45,19 @@ int xf_list_monitors(xfContext* xfc)
 {
 #ifdef WITH_XINERAMA
        Display* display;
+       int major, minor;
        int i, nmonitors = 0;
-       int ignored, ignored2;
        XineramaScreenInfo* screen = NULL;
 
        display = XOpenDisplay(NULL);
+
        if (!display)
        {
                WLog_ERR(TAG, "failed to open X display");
                return -1;
        }
 
-       if (XineramaQueryExtension(display, &ignored, &ignored2))
+       if (XineramaQueryExtension(display, &major, &minor))
        {
                if (XineramaIsActive(display))
                {
@@ -64,7 +65,7 @@ int xf_list_monitors(xfContext* xfc)
 
                        for (i = 0; i < nmonitors; i++)
                        {
-                               WLog_DBG(TAG, "      %s [%d] %dx%d\t+%d+%d",
+                               printf("      %s [%d] %dx%d\t+%d+%d\n",
                                                 (i == 0) ? "*" : " ", i,
                                                 screen[i].width, screen[i].height,
                                                 screen[i].x_org, screen[i].y_org);
@@ -81,63 +82,83 @@ int xf_list_monitors(xfContext* xfc)
 
        display = XOpenDisplay(NULL);
 
-       if(!display)
+       if (!display)
        {
                WLog_ERR(TAG, "failed to open X display");
                return -1;
        }
+
        screen = ScreenOfDisplay(display, DefaultScreen(display));
-       WLog_DBG(TAG, "      * [0] %dx%d\t+%d+%d", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0);
+
+       printf("      * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0);
+
        XCloseDisplay(display);
 #endif
 
        return 0;
 }
 
-BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
+BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
 {
-       int i, j;
+       int index;
+       rdpSettings* settings = xfc->settings;
+
+       if (!settings->NumMonitorIds)
+               return TRUE;
+
+       for (index = 0; index < settings->NumMonitorIds; index++)
+       {
+               if (settings->MonitorIds[index] == id)
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
+BOOL xf_detect_monitors(xfContext* xfc)
+{
+       int i;
        int nmonitors;
        int primaryMonitor;
        int vWidth, vHeight;
        int maxWidth, maxHeight;
        VIRTUAL_SCREEN* vscreen;
+       rdpSettings* settings = xfc->settings;
 
 #ifdef WITH_XINERAMA
-       int ignored, ignored2;
-       XineramaScreenInfo* screen_info = NULL;
+       int major, minor;
+       XineramaScreenInfo* screenInfo = NULL;
 #endif
 
        vscreen = &xfc->vscreen;
+       xfc->desktopWidth = settings->DesktopWidth;
+       xfc->desktopHeight = settings->DesktopHeight;
 
 #ifdef WITH_XINERAMA
-       if (XineramaQueryExtension(xfc->display, &ignored, &ignored2))
+       if (XineramaQueryExtension(xfc->display, &major, &minor))
        {
                if (XineramaIsActive(xfc->display))
                {
-                       screen_info = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
+                       screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
 
                        if (vscreen->nmonitors > 16)
                                vscreen->nmonitors = 0;
 
-                       vscreen->monitors = malloc(sizeof(MONITOR_INFO) * vscreen->nmonitors);
-                       ZeroMemory(vscreen->monitors, sizeof(MONITOR_INFO) * vscreen->nmonitors);
-
                        if (vscreen->nmonitors)
                        {
                                for (i = 0; i < vscreen->nmonitors; i++)
                                {
-                                       vscreen->monitors[i].area.left = screen_info[i].x_org;
-                                       vscreen->monitors[i].area.top = screen_info[i].y_org;
-                                       vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1;
-                                       vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1;
+                                       vscreen->monitors[i].area.left = screenInfo[i].x_org;
+                                       vscreen->monitors[i].area.top = screenInfo[i].y_org;
+                                       vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
+                                       vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
 
-                                       if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0))
+                                       if ((screenInfo[i].x_org == 0) && (screenInfo[i].y_org == 0))
                                                vscreen->monitors[i].primary = TRUE;
                                }
                        }
 
-                       XFree(screen_info);
+                       XFree(screenInfo);
                }
        }
 #endif
@@ -152,24 +173,24 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
 
        if (settings->Fullscreen)
        {
-               settings->DesktopWidth = WidthOfScreen(xfc->screen);
-               settings->DesktopHeight = HeightOfScreen(xfc->screen);
-               maxWidth = settings->DesktopWidth;
-               maxHeight = settings->DesktopHeight;
+               xfc->desktopWidth = WidthOfScreen(xfc->screen);
+               xfc->desktopHeight = HeightOfScreen(xfc->screen);
+               maxWidth = xfc->desktopWidth;
+               maxHeight = xfc->desktopHeight;
        }
        else if (settings->Workarea)
        {
-               settings->DesktopWidth = xfc->workArea.width;
-               settings->DesktopHeight = xfc->workArea.height;
-               maxWidth = settings->DesktopWidth;
-               maxHeight = settings->DesktopHeight;
+               xfc->desktopWidth = xfc->workArea.width;
+               xfc->desktopHeight = xfc->workArea.height;
+               maxWidth = xfc->desktopWidth;
+               maxHeight = xfc->desktopHeight;
        }
        else if (settings->PercentScreen)
        {
-               settings->DesktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100;
-               settings->DesktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100;
-               maxWidth = settings->DesktopWidth;
-               maxHeight = settings->DesktopHeight;
+               xfc->desktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100;
+               xfc->desktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100;
+               maxWidth = xfc->desktopWidth;
+               maxHeight = xfc->desktopHeight;
        }
        else
        {
@@ -188,7 +209,6 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
                if (settings->NumMonitorIds != 1)
                {
                        settings->NumMonitorIds = 1;
-                       settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds);
                        settings->MonitorIds[0] = 0;
 
                        for (i = 0; i < vscreen->nmonitors; i++)
@@ -207,24 +227,13 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
 
        for (i = 0; i < vscreen->nmonitors; i++)
        {
-               if (settings->NumMonitorIds)
-               {
-                       BOOL found = FALSE;
-
-                       for (j = 0; j < settings->NumMonitorIds; j++)
-                       {
-                               if (settings->MonitorIds[j] == i)
-                                       found = TRUE;
-                       }
-
-                       if (!found)
-                               continue;
-               }
+               if (!xf_is_monitor_id_active(xfc, i))
+                       continue;
 
                settings->MonitorDefArray[nmonitors].x = vscreen->monitors[i].area.left;
                settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top;
-               settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, settings->DesktopWidth);
-               settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, settings->DesktopHeight);
+               settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, xfc->desktopWidth);
+               settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, xfc->desktopHeight);
                settings->MonitorDefArray[nmonitors].is_primary = vscreen->monitors[i].primary;
 
                primaryMonitor |= vscreen->monitors[i].primary;
@@ -259,31 +268,12 @@ BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
 
        if (nmonitors && !primaryMonitor)
                settings->MonitorDefArray[0].is_primary = TRUE;
-       
+
        if (settings->MonitorCount)
        {
-               settings->DesktopWidth = vscreen->area.right - vscreen->area.left + 1;
-               settings->DesktopHeight = vscreen->area.bottom - vscreen->area.top + 1;
+               xfc->desktopWidth = vscreen->area.right - vscreen->area.left + 1;
+               xfc->desktopHeight = vscreen->area.bottom - vscreen->area.top + 1;
        }
 
        return TRUE;
 }
-
-/** Clean up all resources allocated by functions in this file.
- */
-void xf_monitors_free(xfContext *xfc, rdpSettings *settings)
-{
-#ifdef WITH_XINERAMA
-       if (xfc->vscreen.monitors)
-       {
-               free(xfc->vscreen.monitors);
-               xfc->vscreen.monitors = NULL;
-       }
-#endif
-
-       if (settings->MonitorIds)
-       {
-               free(settings->MonitorIds);
-               settings->MonitorIds = NULL;
-       }
-}
index b3d4c6a..6acbe64 100644 (file)
@@ -44,7 +44,7 @@ typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN;
 #include "xfreerdp.h"
 
 FREERDP_API int xf_list_monitors(xfContext* xfc);
-FREERDP_API BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings);
-FREERDP_API void xf_monitors_free(xfContext *xfc, rdpSettings *settings);
+FREERDP_API BOOL xf_detect_monitors(xfContext* xfc);
+FREERDP_API void xf_monitors_free(xfContext* xfc);
 
 #endif /* __XF_MONITOR_H */
index de82ab7..38c32fa 100644 (file)
@@ -283,123 +283,124 @@ static const char* get_shm_id()
        return shm_id;
 }
 
-xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char *name, int width, int height, BOOL decorations)
+xfWindow* xf_CreateDesktopWindow(xfContext* xfc, charname, int width, int height, BOOL decorations)
 {
        XEvent xevent;
+       int input_mask;
        xfWindow* window;
+       Window parentWindow;
+       XClassHint* classHints;
        rdpSettings* settings;
 
        window = (xfWindow*) calloc(1, sizeof(xfWindow));
 
+       if (!window)
+               return NULL;
+
        settings = xfc->instance->settings;
+       parentWindow = (Window) xfc->settings->ParentWindowId;
 
-       if (window)
-       {
-               int input_mask;
-               XClassHint* class_hints;
+       window->width = width;
+       window->height = height;
+       window->fullscreen = FALSE;
+       window->decorations = decorations;
+       window->is_mapped = FALSE;
+       window->is_transient = FALSE;
+
+       window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
+                       xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
+                       0, xfc->depth, InputOutput, xfc->visual,
+                       CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
+                       CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
+
+       window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
 
-               window->width = width;
-               window->height = height;
-               window->fullscreen = FALSE;
-               window->decorations = decorations;
-               window->is_mapped = FALSE;
-               window->is_transient = FALSE;
+       if (window->shmid < 0)
+       {
+               DEBUG_X11("xf_CreateDesktopWindow: failed to get access to shared memory - shmget()\n");
+       }
+       else
+       {
+               void* mem;
 
-               window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
-                               xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
-                               0, xfc->depth, InputOutput, xfc->visual,
-                               CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
-                               CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
+               ftruncate(window->shmid, sizeof(window->handle));
 
-               window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
+               mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
 
-               if (window->shmid < 0)
+               if (mem == ((int*) -1))
                {
-                       DEBUG_X11("xf_CreateDesktopWindow: failed to get access to shared memory - shmget()\n");
+                       DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
                }
                else
                {
-                       void* mem;
-
-                       ftruncate(window->shmid, sizeof(window->handle));
-
-                       mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
-
-                       if (mem == ((int*) -1))
-                       {
-                               DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
-                       }
-                       else
-                       {
-                               window->xfwin = mem;
-                               *window->xfwin = window->handle;
-                       }
+                       window->xfwin = mem;
+                       *window->xfwin = window->handle;
                }
+       }
 
-               class_hints = XAllocClassHint();
-
-               if (class_hints)
-               {
-                       class_hints->res_name = "xfreerdp";
+       classHints = XAllocClassHint();
 
-                       if (xfc->settings->WmClass)
-                               class_hints->res_class = xfc->settings->WmClass;
-                       else
-                               class_hints->res_class = "xfreerdp";
+       if (classHints)
+       {
+               classHints->res_name = "xfreerdp";
 
-                       XSetClassHint(xfc->display, window->handle, class_hints);
-                       XFree(class_hints);
-               }
+               if (xfc->settings->WmClass)
+                       classHints->res_class = xfc->settings->WmClass;
+               else
+                       classHints->res_class = "xfreerdp";
 
-               xf_ResizeDesktopWindow(xfc, window, width, height);
-               xf_SetWindowDecorations(xfc, window->handle, decorations);
-               xf_SetWindowPID(xfc, window->handle, 0);
+               XSetClassHint(xfc->display, window->handle, classHints);
+               XFree(classHints);
+       }
 
-               input_mask =
-                       KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
-                       VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
-                       PointerMotionMask | ExposureMask | PropertyChangeMask;
+       xf_ResizeDesktopWindow(xfc, window, width, height);
+       xf_SetWindowDecorations(xfc, window->handle, decorations);
+       xf_SetWindowPID(xfc, window->handle, 0);
 
-               if (xfc->grab_keyboard)
-                       input_mask |= EnterWindowMask | LeaveWindowMask;
+       input_mask =
+               KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
+               VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
+               PointerMotionMask | ExposureMask | PropertyChangeMask;
 
-               XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
-                                       PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
+       if (xfc->grab_keyboard)
+               input_mask |= EnterWindowMask | LeaveWindowMask;
 
-               if (xfc->settings->ParentWindowId)
-                       XReparentWindow(xfc->display, window->handle, (Window) xfc->settings->ParentWindowId, 0, 0);
+       XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
+                               PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
 
-               XSelectInput(xfc->display, window->handle, input_mask);
-               XClearWindow(xfc->display, window->handle);
-               XMapWindow(xfc->display, window->handle);
+       if (parentWindow)
+               XReparentWindow(xfc->display, window->handle, parentWindow, 0, 0);
 
-               xf_input_init(xfc, window->handle);
+       XSelectInput(xfc->display, window->handle, input_mask);
+       XClearWindow(xfc->display, window->handle);
+       XMapWindow(xfc->display, window->handle);
 
-               /*
-                * NOTE: This must be done here to handle reparenting the window,
-                * so that we don't miss the event and hang waiting for the next one
-                */
-               do
-               {
-                       XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
-               }
-               while (xevent.type != VisibilityNotify);
-               /*
-                * The XCreateWindow call will start the window in the upper-left corner of our current
-                * monitor instead of the upper-left monitor for remote app mode (which uses all monitors).
-                * This extra call after the window is mapped will position the login window correctly
-                */
-               if (xfc->settings->RemoteApplicationMode)
-               {
-                       XMoveWindow(xfc->display, window->handle, 0, 0);
-               }
-               else if (settings->DesktopPosX || settings->DesktopPosY)
-               {
-                       XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
-               }
+       xf_input_init(xfc, window->handle);
 
-               XStoreName(xfc->display, window->handle, name);
+       /*
+        * NOTE: This must be done here to handle reparenting the window,
+        * so that we don't miss the event and hang waiting for the next one
+        */
+       do
+       {
+               XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
        }
+       while (xevent.type != VisibilityNotify);
+       /*
+        * The XCreateWindow call will start the window in the upper-left corner of our current
+        * monitor instead of the upper-left monitor for remote app mode (which uses all monitors).
+        * This extra call after the window is mapped will position the login window correctly
+        */
+       if (xfc->settings->RemoteApplicationMode)
+       {
+               XMoveWindow(xfc->display, window->handle, 0, 0);
+       }
+       else if (settings->DesktopPosX || settings->DesktopPosY)
+       {
+               XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
+       }
+
+       XStoreName(xfc->display, window->handle, name);
 
        return window;
 }
index 0f487d9..7397e48 100644 (file)
@@ -102,6 +102,7 @@ struct xf_context
        int scanline_pad;
        BOOL big_endian;
        BOOL fullscreen;
+       BOOL decorations;
        BOOL grab_keyboard;
        BOOL unobscured;
        BOOL debug;
@@ -161,6 +162,8 @@ struct xf_context
        wArrayList* xevents;
        char* actionScript;
 
+       UINT32 desktopWidth;
+       UINT32 desktopHeight;
        XSetWindowAttributes attribs;
        BOOL complex_regions;
        VIRTUAL_SCREEN vscreen;
index ab2d823..22dc460 100644 (file)
@@ -1322,8 +1322,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
 
                                p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
 
+                               if (count > 16)
+                                       count = 16;
+
                                settings->NumMonitorIds = (UINT32) count;
-                               settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds);
 
                                for (i = 0; i < settings->NumMonitorIds; i++)
                                {
index 35e9ad7..82c0ea1 100644 (file)
@@ -268,13 +268,13 @@ rdpSettings* freerdp_settings_new(DWORD flags)
 
                settings->ChannelCount = 0;
                settings->ChannelDefArraySize = 32;
-               settings->ChannelDefArray = (CHANNEL_DEF*) malloc(sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
-               ZeroMemory(settings->ChannelDefArray, sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
+               settings->ChannelDefArray = (CHANNEL_DEF*) calloc(settings->ChannelDefArraySize, sizeof(CHANNEL_DEF));
 
                settings->MonitorCount = 0;
                settings->MonitorDefArraySize = 32;
-               settings->MonitorDefArray = (rdpMonitor*) malloc(sizeof(rdpMonitor) * settings->MonitorDefArraySize);
-               ZeroMemory(settings->MonitorDefArray, sizeof(rdpMonitor) * settings->MonitorDefArraySize);
+               settings->MonitorDefArray = (rdpMonitor*) calloc(settings->MonitorDefArraySize, sizeof(rdpMonitor));
+
+               settings->MonitorIds = (UINT32*) calloc(16, sizeof(UINT32));
 
                settings_get_computer_name(settings);
 
@@ -568,6 +568,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
                _settings->MonitorDefArray = (rdpMonitor*) malloc(sizeof(rdpMonitor) * settings->MonitorDefArraySize);
                CopyMemory(_settings->MonitorDefArray, settings->MonitorDefArray, sizeof(rdpMonitor) * settings->MonitorDefArraySize);
 
+               _settings->MonitorIds = (UINT32*) calloc(16, sizeof(UINT32));
+               CopyMemory(_settings->MonitorIds, settings->MonitorIds, 16 * sizeof(UINT32));
+
                _settings->ReceivedCapabilities = malloc(32);
                _settings->OrderSupport = malloc(32);
                CopyMemory(_settings->ReceivedCapabilities, settings->ReceivedCapabilities, 32);
@@ -653,6 +656,7 @@ void freerdp_settings_free(rdpSettings* settings)
                free(settings->ComputerName);
                free(settings->ChannelDefArray);
                free(settings->MonitorDefArray);
+               free(settings->MonitorIds);
                free(settings->ClientAddress);
                free(settings->ClientDir);
                free(settings->AllowedTlsCiphers);