Sweden-Number/dlls/x11drv/desktop.c

178 lines
5.5 KiB
C

/*
* X11DRV desktop window handling
*
* Copyright 2001 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <X11/cursorfont.h>
#include "ts_xlib.h"
#include "wine/winuser16.h"
#include "win.h"
#include "x11drv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
/* desktop window procedure */
static LRESULT WINAPI desktop_winproc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch(message)
{
case WM_ERASEBKGND:
PaintDesktop( (HDC)wParam );
ValidateRect( hwnd, NULL );
break;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_CLOSE) ExitWindows( 0, 0 );
break;
case WM_SETCURSOR:
return (LRESULT)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
case WM_NCHITTEST:
return HTCLIENT;
}
return 0;
}
/* desktop window manager thread */
static DWORD CALLBACK desktop_thread( LPVOID driver_data )
{
Display *display;
MSG msg;
HWND hwnd;
WND *win;
NtCurrentTeb()->driver_data = driver_data;
display = thread_display();
hwnd = GetDesktopWindow();
/* patch the desktop window queue to point to our queue */
win = WIN_GetPtr( hwnd );
win->tid = GetCurrentThreadId();
win->hmemTaskQ = InitThreadInput16( 0, 0 );
X11DRV_register_window( display, hwnd, win->pDriverData );
WIN_ReleasePtr( win );
SetWindowLongW( hwnd, GWL_WNDPROC, (LONG)desktop_winproc );
wine_tsx11_lock();
XSetWMProtocols( display, root_window, &wmDeleteWindow, 1 );
XMapWindow( display, root_window );
wine_tsx11_unlock();
while (GetMessageW( &msg, hwnd, 0, 0 )) DispatchMessageW( &msg );
return 0;
}
/***********************************************************************
* X11DRV_create_desktop_thread
*
* Create the thread that manages the desktop window
*/
void X11DRV_create_desktop_thread(void)
{
HANDLE handle = CreateThread( NULL, 0, desktop_thread, NtCurrentTeb()->driver_data, 0, NULL );
if (!handle)
{
MESSAGE( "Could not create desktop thread\n" );
ExitProcess(1);
}
/* we transferred our driver data to the new thread */
NtCurrentTeb()->driver_data = NULL;
CloseHandle( handle );
}
/***********************************************************************
* X11DRV_create_desktop
*
* Create the X11 desktop window for the desktop mode.
*/
Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry )
{
int x = 0, y = 0, flags;
unsigned int width = 640, height = 480; /* Default size = 640x480 */
char *name = GetCommandLineA();
XSizeHints *size_hints;
XWMHints *wm_hints;
XClassHint *class_hints;
XSetWindowAttributes win_attr;
XTextProperty window_name;
Window win;
Display *display = thread_display();
wine_tsx11_lock();
flags = XParseGeometry( geometry, &x, &y, &width, &height );
screen_width = width;
screen_height = height;
/* Create window */
win_attr.background_pixel = BlackPixel(display, 0);
win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
if (desktop_vi)
win_attr.colormap = XCreateColormap( display, DefaultRootWindow(display),
visual, AllocNone );
else
win_attr.colormap = None;
win = XCreateWindow( display, DefaultRootWindow(display),
x, y, width, height, 0, screen_depth, InputOutput, visual,
CWBackPixel | CWEventMask | CWCursor | CWColormap, &win_attr );
/* Set window manager properties */
size_hints = XAllocSizeHints();
wm_hints = XAllocWMHints();
class_hints = XAllocClassHint();
if (!size_hints || !wm_hints || !class_hints)
{
MESSAGE("Not enough memory for window manager hints.\n" );
ExitProcess(1);
}
size_hints->min_width = size_hints->max_width = width;
size_hints->min_height = size_hints->max_height = height;
size_hints->flags = PMinSize | PMaxSize;
if (flags & (XValue | YValue)) size_hints->flags |= USPosition;
if (flags & (WidthValue | HeightValue)) size_hints->flags |= USSize;
else size_hints->flags |= PSize;
wm_hints->flags = InputHint | StateHint;
wm_hints->input = True;
wm_hints->initial_state = NormalState;
class_hints->res_name = "wine";
class_hints->res_class = "Wine";
XStringListToTextProperty( &name, 1, &window_name );
XSetWMProperties( display, win, &window_name, &window_name,
NULL, 0, size_hints, wm_hints, class_hints );
XFree( size_hints );
XFree( wm_hints );
XFree( class_hints );
XFlush( display );
wine_tsx11_unlock();
return win;
}