/*
 * Explorer desktop support
 *
 * Copyright 2006 Alexandre Julliard
 * Copyright 2013 Hans Leidekker for CodeWeavers
 *
 * 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>

#define COBJMACROS
#define OEMRESOURCE
#include <windows.h>
#include <rpc.h>
#include <shlobj.h>
#include <shellapi.h>

#include "wine/unicode.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

#ifdef __APPLE__
static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0};
#else
static const WCHAR default_driver[] = {'x','1','1',0};
#endif

static BOOL using_root;

struct launcher
{
    WCHAR *path;
    HICON  icon;
    WCHAR *title;
};

static WCHAR *desktop_folder;
static WCHAR *desktop_folder_public;

static int icon_cx, icon_cy, icon_offset_cx, icon_offset_cy;
static int title_cx, title_cy, title_offset_cx, title_offset_cy;
static int desktop_width, launcher_size, launchers_per_row;

static struct launcher **launchers;
static unsigned int nb_launchers, nb_allocated;

static RECT get_icon_rect( unsigned int index )
{
    RECT rect;
    unsigned int row = index / launchers_per_row;
    unsigned int col = index % launchers_per_row;

    rect.left   = col * launcher_size + icon_offset_cx;
    rect.right  = rect.left + icon_cx;
    rect.top    = row * launcher_size + icon_offset_cy;
    rect.bottom = rect.top + icon_cy;
    return rect;
}

static RECT get_title_rect( unsigned int index )
{
    RECT rect;
    unsigned int row = index / launchers_per_row;
    unsigned int col = index % launchers_per_row;

    rect.left   = col * launcher_size + title_offset_cx;
    rect.right  = rect.left + title_cx;
    rect.top    = row * launcher_size + title_offset_cy;
    rect.bottom = rect.top + title_cy;
    return rect;
}

static const struct launcher *launcher_from_point( int x, int y )
{
    RECT icon, title;
    unsigned int index;

    if (!nb_launchers) return NULL;
    index = x / launcher_size + (y / launcher_size) * launchers_per_row;
    if (index >= nb_launchers) return NULL;

    icon = get_icon_rect( index );
    title = get_title_rect( index );
    if ((x < icon.left || x > icon.right || y < icon.top || y > icon.bottom) &&
        (x < title.left || x > title.right || y < title.top || y > title.bottom)) return NULL;
    return launchers[index];
}

static void draw_launchers( HDC hdc, RECT update_rect )
{
    COLORREF color = SetTextColor( hdc, RGB(255,255,255) ); /* FIXME: depends on background color */
    int mode = SetBkMode( hdc, TRANSPARENT );
    unsigned int i;
    LOGFONTW lf;
    HFONT font;

    SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
    font = SelectObject( hdc, CreateFontIndirectW( &lf ) );

    for (i = 0; i < nb_launchers; i++)
    {
        RECT dummy, icon = get_icon_rect( i ), title = get_title_rect( i );

        if (IntersectRect( &dummy, &icon, &update_rect ))
            DrawIconEx( hdc, icon.left, icon.top, launchers[i]->icon, icon_cx, icon_cy,
                        0, 0, DI_DEFAULTSIZE|DI_NORMAL );

        if (IntersectRect( &dummy, &title, &update_rect ))
            DrawTextW( hdc, launchers[i]->title, -1, &title,
                       DT_CENTER|DT_WORDBREAK|DT_EDITCONTROL|DT_END_ELLIPSIS );
    }

    SelectObject( hdc, font );
    SetTextColor( hdc, color );
    SetBkMode( hdc, mode );
}

static void do_launch( const struct launcher *launcher )
{
    static const WCHAR openW[] = {'o','p','e','n',0};
    ShellExecuteW( NULL, openW, launcher->path, NULL, NULL, 0 );
}

static WCHAR *append_path( const WCHAR *path, const WCHAR *filename, int len_filename )
{
    int len_path = strlenW( path );
    WCHAR *ret;

    if (len_filename == -1) len_filename = strlenW( filename );
    if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len_path + len_filename + 2) * sizeof(WCHAR) )))
        return NULL;
    memcpy( ret, path, len_path * sizeof(WCHAR) );
    ret[len_path] = '\\';
    memcpy( ret + len_path + 1, filename, len_filename * sizeof(WCHAR) );
    ret[len_path + 1 + len_filename] = 0;
    return ret;
}

static IShellLinkW *load_shelllink( const WCHAR *path )
{
    HRESULT hr;
    IShellLinkW *link;
    IPersistFile *file;

    hr = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW,
                           (void **)&link );
    if (FAILED( hr )) return NULL;

    hr = IShellLinkW_QueryInterface( link, &IID_IPersistFile, (void **)&file );
    if (FAILED( hr ))
    {
        IShellLinkW_Release( link );
        return NULL;
    }
    hr = IPersistFile_Load( file, path, 0 );
    IPersistFile_Release( file );
    if (FAILED( hr ))
    {
        IShellLinkW_Release( link );
        return NULL;
    }
    return link;
}

static HICON extract_icon( IShellLinkW *link )
{
    WCHAR tmp_path[MAX_PATH], icon_path[MAX_PATH], target_path[MAX_PATH];
    HICON icon = NULL;
    int index;

    tmp_path[0] = 0;
    IShellLinkW_GetIconLocation( link, tmp_path, MAX_PATH, &index );
    ExpandEnvironmentStringsW( tmp_path, icon_path, MAX_PATH );

    if (icon_path[0]) ExtractIconExW( icon_path, index, &icon, NULL, 1 );
    if (!icon)
    {
        tmp_path[0] = 0;
        IShellLinkW_GetPath( link, tmp_path, MAX_PATH, NULL, SLGP_RAWPATH );
        ExpandEnvironmentStringsW( tmp_path, target_path, MAX_PATH );
        ExtractIconExW( target_path, index, &icon, NULL, 1 );
    }
    return icon;
}

static WCHAR *build_title( const WCHAR *filename, int len )
{
    const WCHAR *p;
    WCHAR *ret;

    if (len == -1) len = strlenW( filename );
    for (p = filename + len - 1; p >= filename; p--)
    {
        if (*p == '.')
        {
            len = p - filename;
            break;
        }
    }
    if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return NULL;
    memcpy( ret, filename, len * sizeof(WCHAR) );
    ret[len] = 0;
    return ret;
}

static BOOL add_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
{
    struct launcher *launcher;
    IShellLinkW *link;

    if (nb_launchers == nb_allocated)
    {
        unsigned int count = nb_allocated * 2;
        struct launcher **tmp = HeapReAlloc( GetProcessHeap(), 0, launchers, count * sizeof(*tmp) );
        if (!tmp) return FALSE;
        launchers = tmp;
        nb_allocated = count;
    }

    if (!(launcher = HeapAlloc( GetProcessHeap(), 0, sizeof(*launcher) ))) return FALSE;
    if (!(launcher->path = append_path( folder, filename, len_filename ))) goto error;
    if (!(link = load_shelllink( launcher->path ))) goto error;

    launcher->icon = extract_icon( link );
    launcher->title = build_title( filename, len_filename );
    IShellLinkW_Release( link );
    if (launcher->icon && launcher->title)
    {
        launchers[nb_launchers++] = launcher;
        return TRUE;
    }
    HeapFree( GetProcessHeap(), 0, launcher->title );
    DestroyIcon( launcher->icon );

error:
    HeapFree( GetProcessHeap(), 0, launcher->path );
    HeapFree( GetProcessHeap(), 0, launcher );
    return FALSE;
}

static void free_launcher( struct launcher *launcher )
{
    DestroyIcon( launcher->icon );
    HeapFree( GetProcessHeap(), 0, launcher->path );
    HeapFree( GetProcessHeap(), 0, launcher->title );
    HeapFree( GetProcessHeap(), 0, launcher );
}

static BOOL remove_launcher( const WCHAR *folder, const WCHAR *filename, int len_filename )
{
    UINT i;
    WCHAR *path;
    BOOL ret = FALSE;

    if (!(path = append_path( folder, filename, len_filename ))) return FALSE;
    for (i = 0; i < nb_launchers; i++)
    {
        if (!strcmpiW( launchers[i]->path, path ))
        {
            free_launcher( launchers[i] );
            if (--nb_launchers)
                memmove( &launchers[i], &launchers[i + 1], sizeof(launchers[i]) * (nb_launchers - i) );
            ret = TRUE;
            break;
        }
    }
    HeapFree( GetProcessHeap(), 0, path );
    return ret;
}

static BOOL get_icon_text_metrics( HWND hwnd, TEXTMETRICW *tm )
{
    BOOL ret;
    HDC hdc;
    LOGFONTW lf;
    HFONT hfont;

    hdc = GetDC( hwnd );
    SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 );
    hfont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
    ret = GetTextMetricsW( hdc, tm );
    SelectObject( hdc, hfont );
    ReleaseDC( hwnd, hdc );
    return ret;
}

static BOOL process_changes( const WCHAR *folder, char *buf )
{
    FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *)buf;
    BOOL ret = FALSE;

    for (;;)
    {
        switch (info->Action)
        {
        case FILE_ACTION_ADDED:
        case FILE_ACTION_RENAMED_NEW_NAME:
            if (add_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
                ret = TRUE;
            break;

        case FILE_ACTION_REMOVED:
        case FILE_ACTION_RENAMED_OLD_NAME:
            if (remove_launcher( folder, info->FileName, info->FileNameLength / sizeof(WCHAR) ))
                ret = TRUE;
            break;

        default:
            WARN( "unexpected action %u\n", info->Action );
            break;
        }
        if (!info->NextEntryOffset) break;
        info = (FILE_NOTIFY_INFORMATION *)((char *)info + info->NextEntryOffset);
    }
    return ret;
}

static DWORD CALLBACK watch_desktop_folders( LPVOID param )
{
    HWND hwnd = param;
    HRESULT init = CoInitialize( NULL );
    HANDLE dir0, dir1, events[2];
    OVERLAPPED ovl0, ovl1;
    char *buf0 = NULL, *buf1 = NULL;
    DWORD count, size = 4096, error = ERROR_OUTOFMEMORY;
    BOOL ret, redraw;

    dir0 = CreateFileW( desktop_folder, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
    if (dir0 == INVALID_HANDLE_VALUE) return GetLastError();
    dir1 = CreateFileW( desktop_folder_public, FILE_LIST_DIRECTORY|SYNCHRONIZE, FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL );
    if (dir1 == INVALID_HANDLE_VALUE)
    {
        CloseHandle( dir0 );
        return GetLastError();
    }
    if (!(ovl0.hEvent = events[0] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
    if (!(ovl1.hEvent = events[1] = CreateEventW( NULL, FALSE, FALSE, NULL ))) goto error;
    if (!(buf0 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error;
    if (!(buf1 = HeapAlloc( GetProcessHeap(), 0, size ))) goto error;

    for (;;)
    {
        ret = ReadDirectoryChangesW( dir0, buf0, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl0, NULL );
        if (!ret)
        {
            error = GetLastError();
            goto error;
        }
        ret = ReadDirectoryChangesW( dir1, buf1, size, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ovl1, NULL );
        if (!ret)
        {
            error = GetLastError();
            goto error;
        }

        redraw = FALSE;
        switch ((error = WaitForMultipleObjects( 2, events, FALSE, INFINITE )))
        {
        case WAIT_OBJECT_0:
            if (!GetOverlappedResult( dir0, &ovl0, &count, FALSE ) || !count) break;
            if (process_changes( desktop_folder, buf0 )) redraw = TRUE;
            break;

        case WAIT_OBJECT_0 + 1:
            if (!GetOverlappedResult( dir1, &ovl1, &count, FALSE ) || !count) break;
            if (process_changes( desktop_folder_public, buf1 )) redraw = TRUE;
            break;

        default:
            goto error;
        }
        if (redraw) InvalidateRect( hwnd, NULL, TRUE );
    }

error:
    CloseHandle( dir0 );
    CloseHandle( dir1 );
    CloseHandle( events[0] );
    CloseHandle( events[1] );
    HeapFree( GetProcessHeap(), 0, buf0 );
    HeapFree( GetProcessHeap(), 0, buf1 );
    if (SUCCEEDED( init )) CoUninitialize();
    return error;
}

static void add_folder( const WCHAR *folder )
{
    static const WCHAR lnkW[] = {'\\','*','.','l','n','k',0};
    int len = strlenW( folder ) + strlenW( lnkW );
    WIN32_FIND_DATAW data;
    HANDLE handle;
    WCHAR *glob;

    if (!(glob = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return;
    strcpyW( glob, folder );
    strcatW( glob, lnkW );

    if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
    {
        do { add_launcher( folder, data.cFileName, -1 ); } while (FindNextFileW( handle, &data ));
        FindClose( handle );
    }
    HeapFree( GetProcessHeap(), 0, glob );
}

#define BORDER_SIZE  4
#define PADDING_SIZE 4
#define TITLE_CHARS  14

static void initialize_launchers( HWND hwnd )
{
    HRESULT hr, init;
    TEXTMETRICW tm;
    int icon_size;

    if (!(get_icon_text_metrics( hwnd, &tm ))) return;

    icon_cx = GetSystemMetrics( SM_CXICON );
    icon_cy = GetSystemMetrics( SM_CYICON );
    icon_size = max( icon_cx, icon_cy );
    title_cy = tm.tmHeight * 2;
    title_cx = max( tm.tmAveCharWidth * TITLE_CHARS, icon_size + PADDING_SIZE + title_cy );
    launcher_size = BORDER_SIZE + title_cx + BORDER_SIZE;
    icon_offset_cx = (launcher_size - icon_cx) / 2;
    icon_offset_cy = BORDER_SIZE + (icon_size - icon_cy) / 2;
    title_offset_cx = BORDER_SIZE;
    title_offset_cy = BORDER_SIZE + icon_size + PADDING_SIZE;
    desktop_width = GetSystemMetrics( SM_CXSCREEN );
    launchers_per_row = desktop_width / launcher_size;

    hr = SHGetKnownFolderPath( &FOLDERID_Desktop, KF_FLAG_CREATE, NULL, &desktop_folder );
    if (FAILED( hr ))
    {
        WINE_ERR("Could not get user desktop folder\n");
        return;
    }
    hr = SHGetKnownFolderPath( &FOLDERID_PublicDesktop, KF_FLAG_CREATE, NULL, &desktop_folder_public );
    if (FAILED( hr ))
    {
        WINE_ERR("Could not get public desktop folder\n");
        CoTaskMemFree( desktop_folder );
        return;
    }
    if ((launchers = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(launchers[0]) )))
    {
        nb_allocated = 2;

        init = CoInitialize( NULL );
        add_folder( desktop_folder );
        add_folder( desktop_folder_public );
        if (SUCCEEDED( init )) CoUninitialize();

        CreateThread( NULL, 0, watch_desktop_folders, hwnd, 0, NULL );
    }
}

/* 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_LBUTTONDBLCLK:
        if (!using_root)
        {
            const struct launcher *launcher = launcher_from_point( (short)LOWORD(lp), (short)HIWORD(lp) );
            if (launcher) do_launch( launcher );
        }
        return 0;

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

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

/* create the desktop and the associated driver window, and make it the current desktop */
static BOOL create_desktop( HMODULE driver, const WCHAR *name, unsigned int width, unsigned int height )
{
    static const WCHAR rootW[] = {'r','o','o','t',0};
    BOOL ret = FALSE;
    BOOL (CDECL *create_desktop_func)(unsigned int, unsigned int);

    /* magic: desktop "root" means use the root window */
    if (driver && strcmpiW( name, rootW ))
    {
        create_desktop_func = (void *)GetProcAddress( driver, "wine_create_desktop" );
        if (create_desktop_func) ret = create_desktop_func( width, height );
    }
    return ret;
}

/* 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 BOOL get_default_enable_shell( const WCHAR *name )
{
    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};
    static const WCHAR enable_shellW[] = {'E','n','a','b','l','e','S','h','e','l','l',0};
    static const WCHAR shellW[] = {'s','h','e','l','l',0};
    HKEY hkey;
    BOOL found = FALSE;
    BOOL result;
    DWORD size = sizeof(result);

    /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */
    if (!RegOpenKeyW( HKEY_CURRENT_USER, desktop_keyW, &hkey ))
    {
        if (!RegGetValueW( hkey, name, enable_shellW, RRF_RT_REG_DWORD, NULL, &result, &size ))
            found = TRUE;
        RegCloseKey( hkey );
    }
    /* Default off, except for the magic desktop name "shell" */
    if (!found)
        result = (lstrcmpiW( name, shellW ) == 0);
    return result;
}

static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
{
    static const WCHAR device_keyW[] = {
        'S','y','s','t','e','m','\\',
        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
        'C','o','n','t','r','o','l','\\',
        'V','i','d','e','o','\\',
        '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
        '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
        '%','0','2','x','%','0','2','x','%','0','2','x','}','\\','0','0','0','0',0};
    static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
    static const WCHAR driversW[] = {'S','o','f','t','w','a','r','e','\\',
                                     'W','i','n','e','\\','D','r','i','v','e','r','s',0};
    static const WCHAR graphicsW[] = {'G','r','a','p','h','i','c','s',0};
    static const WCHAR drv_formatW[] = {'w','i','n','e','%','s','.','d','r','v',0};

    WCHAR buffer[MAX_PATH], libname[32], *name, *next;
    WCHAR key[sizeof(device_keyW)/sizeof(WCHAR) + 39];
    HMODULE module = 0;
    HKEY hkey;
    char error[80];

    if (!driver)
    {
        strcpyW( buffer, default_driver );

        /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
        if (!RegOpenKeyW( HKEY_CURRENT_USER, driversW, &hkey ))
        {
            DWORD count = sizeof(buffer);
            RegQueryValueExW( hkey, graphicsW, 0, NULL, (LPBYTE)buffer, &count );
            RegCloseKey( hkey );
        }
    }
    else lstrcpynW( buffer, driver, sizeof(buffer)/sizeof(WCHAR) );

    name = buffer;
    while (name)
    {
        next = strchrW( name, ',' );
        if (next) *next++ = 0;

        snprintfW( libname, sizeof(libname)/sizeof(WCHAR), drv_formatW, name );
        if ((module = LoadLibraryW( libname )) != 0) break;
        switch (GetLastError())
        {
        case ERROR_MOD_NOT_FOUND:
            strcpy( error, "The graphics driver is missing. Check your build!" );
            break;
        case ERROR_DLL_INIT_FAILED:
            strcpy( error, "Make sure that your X server is running and that $DISPLAY is set correctly." );
            break;
        default:
            sprintf( error, "Unknown error (%u).", GetLastError() );
            break;
        }
        name = next;
    }

    if (module)
    {
        GetModuleFileNameW( module, buffer, MAX_PATH );
        TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) );
    }

    sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
              guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
              guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );

    if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
                          REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL  ))
    {
        if (module)
            RegSetValueExW( hkey, graphics_driverW, 0, REG_SZ,
                            (BYTE *)buffer, (strlenW(buffer) + 1) * sizeof(WCHAR) );
        else
            RegSetValueExA( hkey, "DriverError", 0, REG_SZ, (BYTE *)error, strlen(error) + 1 );
        RegCloseKey( hkey );
    }

    return module;
}

static void initialize_display_settings(void)
{
    DEVMODEW dmW;

    /* 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};
    HDESK desktop = 0;
    GUID guid;
    MSG msg;
    HWND hwnd;
    HMODULE graphics_driver;
    unsigned int width, height;
    WCHAR *cmdline = NULL, *driver = NULL;
    WCHAR *p = arg;
    const WCHAR *name = NULL;
    BOOL enable_shell = FALSE;

    /* 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[,driver]] */
    if (*arg == '=' || *arg == ',')
    {
        arg++;
        name = arg;
        if ((p = strchrW( arg, ',' )))
        {
            *p++ = 0;
            if ((driver = strchrW( p, ',' ))) *driver++ = 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)
        enable_shell = get_default_enable_shell( name );

    if (name && width && height)
    {
        if (!(desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL )))
        {
            WINE_ERR( "failed to create desktop %s error %d\n", wine_dbgstr_w(name), GetLastError() );
            ExitProcess( 1 );
        }
        SetThreadDesktop( desktop );
    }

    UuidCreate( &guid );
    TRACE( "display guid %s\n", debugstr_guid(&guid) );
    graphics_driver = load_graphics_driver( driver, &guid );

    /* create the desktop window */
    hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL,
                            WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid );

    if (hwnd)
    {
        /* create the HWND_MESSAGE parent */
        CreateWindowExW( 0, messageW, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                         0, 0, 100, 100, 0, 0, 0, NULL );

        using_root = !desktop || !create_desktop( graphics_driver, name, width, height );
        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 );
        SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
                      GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN),
                      SWP_SHOWWINDOW );
        SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE );
        ClipCursor( NULL );
        initialize_display_settings();
        initialize_appbar();

        if (graphics_driver)
        {
            HMODULE shell32;
            void (WINAPI *pShellDDEInit)( BOOL );

            if (using_root) enable_shell = FALSE;

            initialize_systray( graphics_driver, using_root, enable_shell );
            if (!using_root) initialize_launchers( hwnd );

            if ((shell32 = LoadLibraryA( "shell32.dll" )) &&
                (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188)))
            {
                pShellDDEInit( TRUE );
            }
        }
    }

    /* 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 );
}
