/*
 * Explorer desktop support
 *
 * Copyright 2006 Alexandre Julliard
 *
 * 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 <stdio.h>
#include "wine/unicode.h"

#define OEMRESOURCE

#include <windows.h>
#include <rpc.h>
#include <wine/debug.h>
#include "explorer_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(explorer);

#define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769))
#define DESKTOP_ALL_ACCESS 0x01ff

static BOOL using_root;

/* screen saver handler */
static BOOL start_screensaver( void )
{
    if (using_root)
    {
        const char *argv[3] = { "xdg-screensaver", "activate", NULL };
        int pid = spawnvp( _P_DETACH, argv[0], argv );
        if (pid > 0)
        {
            WINE_TRACE( "started process %d\n", pid );
            return TRUE;
        }
    }
    return FALSE;
}

/* window procedure for the desktop window */
static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPARAM lp )
{
    WINE_TRACE( "got msg %04x wp %lx lp %lx\n", message, wp, lp );

    switch(message)
    {
    case WM_SYSCOMMAND:
        switch(wp & 0xfff0)
        {
        case SC_CLOSE:
            ExitWindows( 0, 0 );
            break;
        case SC_SCREENSAVE:
            return start_screensaver();
        }
        return 0;

    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;

    case WM_SETCURSOR:
        return (LRESULT)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );

    case WM_NCHITTEST:
        return HTCLIENT;

    case WM_ERASEBKGND:
        if (!using_root) PaintDesktop( (HDC)wp );
        return TRUE;

    case WM_SETTINGCHANGE:
        if (wp == SPI_SETDESKWALLPAPER)
            SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
        return 0;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint( hwnd, &ps );
            if (!using_root && ps.fErase) PaintDesktop( ps.hdc );
            EndPaint( hwnd, &ps );
        }
        return 0;

    default:
        return DefWindowProcW( hwnd, message, wp, lp );
    }
}

/* create the desktop and the associated X11 window, and make it the current desktop */
static unsigned long create_desktop( const WCHAR *name, unsigned int width, unsigned int height )
{
    static const WCHAR rootW[] = {'r','o','o','t',0};
    HMODULE x11drv = GetModuleHandleA( "winex11.drv" );
    HDESK desktop;
    unsigned long xwin = 0;
    unsigned long (CDECL *create_desktop_func)(unsigned int, unsigned int);

    desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
    if (!desktop)
    {
        WINE_ERR( "failed to create desktop %s error %d\n", wine_dbgstr_w(name), GetLastError() );
        ExitProcess( 1 );
    }
    /* magic: desktop "root" means use the X11 root window */
    if (x11drv && strcmpiW( name, rootW ))
    {
        create_desktop_func = (void *)GetProcAddress( x11drv, "wine_create_desktop" );
        if (create_desktop_func) xwin = create_desktop_func( width, height );
    }
    SetThreadDesktop( desktop );
    return xwin;
}

/* parse the desktop size specification */
static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height )
{
    WCHAR *end;

    *width = strtoulW( size, &end, 10 );
    if (end == size) return FALSE;
    if (*end != 'x') return FALSE;
    size = end + 1;
    *height = strtoulW( size, &end, 10 );
    return !*end;
}

/* retrieve the desktop name to use if not specified on the command line */
static const WCHAR *get_default_desktop_name(void)
{
    static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
    static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0};
    static const WCHAR explorer_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
                                          'E','x','p','l','o','r','e','r',0};
    static WCHAR buffer[MAX_PATH];
    DWORD size = sizeof(buffer);
    HDESK desk = GetThreadDesktop( GetCurrentThreadId() );
    WCHAR *ret = NULL;
    HKEY hkey;

    if (desk && GetUserObjectInformationW( desk, UOI_NAME, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
    {
        if (strcmpiW( buffer, defaultW )) return buffer;
    }

    /* @@ Wine registry key: HKCU\Software\Wine\Explorer */
    if (!RegOpenKeyW( HKEY_CURRENT_USER, explorer_keyW, &hkey ))
    {
        if (!RegQueryValueExW( hkey, desktopW, 0, NULL, (LPBYTE)buffer, &size )) ret = buffer;
        RegCloseKey( hkey );
    }
    return ret;
}

/* retrieve the default desktop size from the registry */
static BOOL get_default_desktop_size( const WCHAR *name, unsigned int *width, unsigned int *height )
{
    static const WCHAR desktop_keyW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
                                         'E','x','p','l','o','r','e','r','\\',
                                         'D','e','s','k','t','o','p','s',0};
    HKEY hkey;
    WCHAR buffer[64];
    DWORD size = sizeof(buffer);
    BOOL found = FALSE;

    *width = 800;
    *height = 600;

    /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
    if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
    {
        if (!RegQueryValueExW( hkey, name, 0, NULL, (LPBYTE)buffer, &size ))
        {
            found = TRUE;
            if (!parse_size( buffer, width, height )) *width = *height = 0;
        }
        RegCloseKey( hkey );
    }
    return found;
}

static void initialize_display_settings( HWND desktop )
{
    static const WCHAR display_device_guid_propW[] = {
        '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
        'd','e','v','i','c','e','_','g','u','i','d',0 };
    GUID guid;
    RPC_CSTR guid_str;
    ATOM guid_atom;
    DEVMODEW dmW;

    UuidCreate( &guid );
    UuidToStringA( &guid, &guid_str );
    WINE_TRACE( "display guid %s\n", guid_str );

    guid_atom = GlobalAddAtomA( (LPCSTR)guid_str );
    SetPropW( desktop, display_device_guid_propW, ULongToHandle(guid_atom) );

    RpcStringFreeA( &guid_str );

    /* Store current display mode in the registry */
    if (EnumDisplaySettingsExW( NULL, ENUM_CURRENT_SETTINGS, &dmW, 0 ))
    {
        WINE_TRACE( "Current display mode %ux%u %u bpp %u Hz\n", dmW.dmPelsWidth,
                    dmW.dmPelsHeight, dmW.dmBitsPerPel, dmW.dmDisplayFrequency );
        ChangeDisplaySettingsExW( NULL, &dmW, 0,
                                  CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY,
                                  NULL );
    }
}

static void set_desktop_window_title( HWND hwnd, const WCHAR *name )
{
    static const WCHAR desktop_nameW[] = {'W','i','n','e',' ','d','e','s','k','t','o','p',0};
    static const WCHAR desktop_name_separatorW[] = {' ', '-', ' ', 0};
    WCHAR *window_titleW = NULL;
    int window_title_len;

    if (!name[0])
    {
        SetWindowTextW( hwnd, desktop_nameW );
        return;
    }

    window_title_len = strlenW(name) * sizeof(WCHAR)
                     + sizeof(desktop_name_separatorW)
                     + sizeof(desktop_nameW);
    window_titleW = HeapAlloc( GetProcessHeap(), 0, window_title_len );
    if (!window_titleW)
    {
        SetWindowTextW( hwnd, desktop_nameW );
        return;
    }

    strcpyW( window_titleW, name );
    strcatW( window_titleW, desktop_name_separatorW );
    strcatW( window_titleW, desktop_nameW );

    SetWindowTextW( hwnd, window_titleW );
    HeapFree( GetProcessHeap(), 0, window_titleW );
}

/* main desktop management function */
void manage_desktop( WCHAR *arg )
{
    static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0};
    MSG msg;
    HWND hwnd, msg_hwnd;
    unsigned long xwin = 0;
    unsigned int width, height;
    WCHAR *cmdline = NULL;
    WCHAR *p = arg;
    const WCHAR *name = NULL;

    /* get the rest of the command line (if any) */
    while (*p && !isspace(*p)) p++;
    if (*p)
    {
        *p++ = 0;
        while (*p && isspace(*p)) p++;
        if (*p) cmdline = p;
    }

    /* parse the desktop option */
    /* the option is of the form /desktop=name[,widthxheight] */
    if (*arg == '=' || *arg == ',')
    {
        arg++;
        name = arg;
        if ((p = strchrW( arg, ',' ))) *p++ = 0;
        if (!p || !parse_size( p, &width, &height ))
            get_default_desktop_size( name, &width, &height );
    }
    else if ((name = get_default_desktop_name()))
    {
        if (!get_default_desktop_size( name, &width, &height )) width = height = 0;
    }

    if (name && width && height) xwin = create_desktop( name, width, height );

    if (!xwin) using_root = TRUE; /* using the root window */

    /* create the desktop window */
    hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
                            WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                            GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
                            GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN),
                            0, 0, 0, NULL );

    /* create the HWND_MESSAGE parent */
    msg_hwnd = CreateWindowExW( 0, messageW, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                0, 0, 100, 100, 0, 0, 0, NULL );

    if (hwnd == GetDesktopWindow())
    {
        HMODULE shell32;
        void (WINAPI *pShellDDEInit)( BOOL );

        SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)desktop_wnd_proc );
        SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO)));
        if (name) set_desktop_window_title( hwnd, name );
        SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
        ClipCursor( NULL );
        initialize_display_settings( hwnd );
        initialize_appbar();
        initialize_systray( using_root );

        if ((shell32 = LoadLibraryA( "shell32.dll" )) &&
            (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188)))
        {
            pShellDDEInit( TRUE );
        }
    }
    else
    {
        DestroyWindow( hwnd );  /* someone beat us to it */
        hwnd = 0;
    }

    if (GetAncestor( msg_hwnd, GA_PARENT )) DestroyWindow( msg_hwnd );  /* someone beat us to it */

    /* if we have a command line, execute it */
    if (cmdline)
    {
        STARTUPINFOW si;
        PROCESS_INFORMATION pi;

        memset( &si, 0, sizeof(si) );
        si.cb = sizeof(si);
        WINE_TRACE( "starting %s\n", wine_dbgstr_w(cmdline) );
        if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
        {
            CloseHandle( pi.hThread );
            CloseHandle( pi.hProcess );
        }
    }

    /* run the desktop message loop */
    if (hwnd)
    {
        WINE_TRACE( "desktop message loop starting on hwnd %p\n", hwnd );
        while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
        WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
    }

    ExitProcess( 0 );
}
