Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1642fbcb
Commit
1642fbcb
authored
Feb 25, 2008
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Moved the DCE support from winex11 back to user32.
Window and class DCEs are now allocated lazily.
parent
4273a8ab
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
705 additions
and
769 deletions
+705
-769
class.c
dlls/user32/class.c
+22
-0
controls.h
dlls/user32/controls.h
+2
-0
driver.c
dlls/user32/driver.c
+11
-24
painting.c
dlls/user32/painting.c
+582
-8
dce.c
dlls/user32/tests/dce.c
+0
-1
user32.spec
dlls/user32/user32.spec
+1
-0
user_private.h
dlls/user32/user_private.h
+6
-3
win.c
dlls/user32/win.c
+7
-1
winpos.c
dlls/user32/winpos.c
+11
-1
Makefile.in
dlls/winex11.drv/Makefile.in
+0
-1
dce.c
dlls/winex11.drv/dce.c
+0
-655
opengl.c
dlls/winex11.drv/opengl.c
+0
-2
window.c
dlls/winex11.drv/window.c
+57
-38
winex11.drv.spec
dlls/winex11.drv/winex11.drv.spec
+2
-3
winpos.c
dlls/winex11.drv/winpos.c
+3
-18
x11drv.h
dlls/winex11.drv/x11drv.h
+0
-14
win.h
include/win.h
+1
-0
No files found.
dlls/user32/class.c
View file @
1642fbcb
...
...
@@ -52,6 +52,7 @@ typedef struct tagCLASS
INT
cbClsExtra
;
/* Class extra bytes */
INT
cbWndExtra
;
/* Window extra bytes */
LPWSTR
menuName
;
/* Default menu name (Unicode followed by ASCII) */
struct
dce
*
dce
;
/* Opaque pointer to class DCE */
HINSTANCE
hInstance
;
/* Module that created the task */
HICON
hIcon
;
/* Default icon */
HICON
hIconSm
;
/* Default small icon */
...
...
@@ -243,6 +244,7 @@ static void CLASS_FreeClass( CLASS *classPtr )
USER_Lock
();
if
(
classPtr
->
dce
)
free_dce
(
classPtr
->
dce
,
0
);
list_remove
(
&
classPtr
->
entry
);
if
(
classPtr
->
hbrBackground
>
(
HBRUSH
)(
COLOR_GRADIENTINACTIVECAPTION
+
1
))
DeleteObject
(
classPtr
->
hbrBackground
);
...
...
@@ -442,6 +444,26 @@ WNDPROC get_class_winproc( CLASS *class )
/***********************************************************************
* get_class_dce
*/
struct
dce
*
get_class_dce
(
CLASS
*
class
)
{
return
class
->
dce
;
}
/***********************************************************************
* set_class_dce
*/
struct
dce
*
set_class_dce
(
CLASS
*
class
,
struct
dce
*
dce
)
{
if
(
class
->
dce
)
return
class
->
dce
;
/* already set, don't change it */
class
->
dce
=
dce
;
return
dce
;
}
/***********************************************************************
* RegisterClassA (USER32.@)
*
* Register a window class.
...
...
dlls/user32/controls.h
View file @
1642fbcb
...
...
@@ -64,6 +64,8 @@ struct tagWND;
extern
ATOM
get_int_atom_value
(
LPCWSTR
name
)
DECLSPEC_HIDDEN
;
extern
void
CLASS_RegisterBuiltinClasses
(
void
)
DECLSPEC_HIDDEN
;
extern
WNDPROC
get_class_winproc
(
struct
tagCLASS
*
class
)
DECLSPEC_HIDDEN
;
extern
struct
dce
*
get_class_dce
(
struct
tagCLASS
*
class
)
DECLSPEC_HIDDEN
;
extern
struct
dce
*
set_class_dce
(
struct
tagCLASS
*
class
,
struct
dce
*
dce
)
DECLSPEC_HIDDEN
;
extern
void
CLASS_FreeModuleClasses
(
HMODULE16
hModule
)
DECLSPEC_HIDDEN
;
/* defwnd proc */
...
...
dlls/user32/driver.c
View file @
1642fbcb
...
...
@@ -108,7 +108,7 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC
(
CreateDesktopWindow
);
GET_USER_FUNC
(
CreateWindow
);
GET_USER_FUNC
(
DestroyWindow
);
GET_USER_FUNC
(
GetDC
Ex
);
GET_USER_FUNC
(
GetDC
);
GET_USER_FUNC
(
MsgWaitForMultipleObjectsEx
);
GET_USER_FUNC
(
ReleaseDC
);
GET_USER_FUNC
(
ScrollDC
);
...
...
@@ -121,7 +121,6 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC
(
SetWindowText
);
GET_USER_FUNC
(
ShowWindow
);
GET_USER_FUNC
(
SysCommandSizeMove
);
GET_USER_FUNC
(
WindowFromDC
);
GET_USER_FUNC
(
WindowMessage
);
#undef GET_USER_FUNC
}
...
...
@@ -344,9 +343,9 @@ static void nulldrv_DestroyWindow( HWND hwnd )
{
}
static
HDC
nulldrv_GetDCEx
(
HWND
hwnd
,
HRGN
hrgn
,
DWORD
flags
)
static
void
nulldrv_GetDC
(
HDC
hdc
,
HWND
hwnd
,
HWND
top_win
,
const
RECT
*
win_rect
,
const
RECT
*
top_rect
,
DWORD
flags
)
{
return
0
;
}
static
DWORD
nulldrv_MsgWaitForMultipleObjectsEx
(
DWORD
count
,
const
HANDLE
*
handles
,
DWORD
timeout
,
...
...
@@ -356,9 +355,8 @@ static DWORD nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *han
timeout
,
flags
&
MWMO_ALERTABLE
);
}
static
INT
nulldrv_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
,
BOOL
end_paint
)
static
void
nulldrv_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
)
{
return
0
;
}
static
BOOL
nulldrv_ScrollDC
(
HDC
hdc
,
INT
dx
,
INT
dy
,
const
RECT
*
scroll
,
const
RECT
*
clip
,
...
...
@@ -407,11 +405,6 @@ static void nulldrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
{
}
static
HWND
nulldrv_WindowFromDC
(
HDC
hdc
)
{
return
0
;
}
static
LRESULT
nulldrv_WindowMessage
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
return
0
;
...
...
@@ -461,7 +454,7 @@ static const USER_DRIVER null_driver =
nulldrv_CreateDesktopWindow
,
nulldrv_CreateWindow
,
nulldrv_DestroyWindow
,
nulldrv_GetDC
Ex
,
nulldrv_GetDC
,
nulldrv_MsgWaitForMultipleObjectsEx
,
nulldrv_ReleaseDC
,
nulldrv_ScrollDC
,
...
...
@@ -474,7 +467,6 @@ static const USER_DRIVER null_driver =
nulldrv_SetWindowText
,
nulldrv_ShowWindow
,
nulldrv_SysCommandSizeMove
,
nulldrv_WindowFromDC
,
nulldrv_WindowMessage
};
...
...
@@ -668,9 +660,10 @@ static void loaderdrv_DestroyWindow( HWND hwnd )
load_driver
()
->
pDestroyWindow
(
hwnd
);
}
static
HDC
loaderdrv_GetDCEx
(
HWND
hwnd
,
HRGN
hrgn
,
DWORD
flags
)
static
void
loaderdrv_GetDC
(
HDC
hdc
,
HWND
hwnd
,
HWND
top_win
,
const
RECT
*
win_rect
,
const
RECT
*
top_rect
,
DWORD
flags
)
{
return
load_driver
()
->
pGetDCEx
(
hwnd
,
hrgn
,
flags
);
load_driver
()
->
pGetDC
(
hdc
,
hwnd
,
top_win
,
win_rect
,
top_rect
,
flags
);
}
static
DWORD
loaderdrv_MsgWaitForMultipleObjectsEx
(
DWORD
count
,
const
HANDLE
*
handles
,
DWORD
timeout
,
...
...
@@ -679,9 +672,9 @@ static DWORD loaderdrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *h
return
load_driver
()
->
pMsgWaitForMultipleObjectsEx
(
count
,
handles
,
timeout
,
mask
,
flags
);
}
static
INT
loaderdrv_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
,
BOOL
end_paint
)
static
void
loaderdrv_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
)
{
return
load_driver
()
->
pReleaseDC
(
hwnd
,
hdc
,
end_paint
);
load_driver
()
->
pReleaseDC
(
hwnd
,
hdc
);
}
static
BOOL
loaderdrv_ScrollDC
(
HDC
hdc
,
INT
dx
,
INT
dy
,
const
RECT
*
scroll
,
const
RECT
*
clip
,
...
...
@@ -738,11 +731,6 @@ static void loaderdrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
load_driver
()
->
pSysCommandSizeMove
(
hwnd
,
wparam
);
}
static
HWND
loaderdrv_WindowFromDC
(
HDC
hdc
)
{
return
load_driver
()
->
pWindowFromDC
(
hdc
);
}
static
LRESULT
loaderdrv_WindowMessage
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wparam
,
LPARAM
lparam
)
{
return
load_driver
()
->
pWindowMessage
(
hwnd
,
msg
,
wparam
,
lparam
);
...
...
@@ -792,7 +780,7 @@ static const USER_DRIVER lazy_load_driver =
loaderdrv_CreateDesktopWindow
,
loaderdrv_CreateWindow
,
loaderdrv_DestroyWindow
,
loaderdrv_GetDC
Ex
,
loaderdrv_GetDC
,
loaderdrv_MsgWaitForMultipleObjectsEx
,
loaderdrv_ReleaseDC
,
loaderdrv_ScrollDC
,
...
...
@@ -805,6 +793,5 @@ static const USER_DRIVER lazy_load_driver =
loaderdrv_SetWindowText
,
loaderdrv_ShowWindow
,
loaderdrv_SysCommandSizeMove
,
loaderdrv_WindowFromDC
,
loaderdrv_WindowMessage
};
dlls/user32/painting.c
View file @
1642fbcb
/*
* Window painting functions
*
* Copyright 1993, 1994, 1995, 2001, 2004 Alexandre Julliard
* Copyright 1999 Alex Korobka
* Copyright 1993, 1994, 1995, 2001, 2004
, 2005, 2008
Alexandre Julliard
* Copyright 199
6, 1997, 199
9 Alex Korobka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -22,6 +22,7 @@
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
...
...
@@ -34,11 +35,31 @@
#include "wine/server.h"
#include "win.h"
#include "user_private.h"
#include "controls.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
win
);
struct
dce
{
struct
list
entry
;
/* entry in global DCE list */
HDC
hdc
;
HWND
hwnd
;
HRGN
clip_rgn
;
DWORD
flags
;
LONG
count
;
/* usage count; 0 or 1 for cache DCEs, always 1 for window DCEs,
always >= 1 for class DCEs */
};
static
struct
list
dce_list
=
LIST_INIT
(
dce_list
);
static
BOOL
CALLBACK
dc_hook
(
HDC
hDC
,
WORD
code
,
DWORD_PTR
data
,
LPARAM
lParam
);
static
const
WCHAR
displayW
[]
=
{
'D'
,
'I'
,
'S'
,
'P'
,
'L'
,
'A'
,
'Y'
,
0
};
/***********************************************************************
* dump_rdw_flags
*/
...
...
@@ -79,6 +100,420 @@ static void dump_rdw_flags(UINT flags)
/***********************************************************************
* update_visible_region
*
* Set the visible region and X11 drawable for the DC associated to
* a given window.
*/
static
void
update_visible_region
(
struct
dce
*
dce
)
{
NTSTATUS
status
;
HRGN
vis_rgn
=
0
;
HWND
top_win
=
0
;
DWORD
flags
=
dce
->
flags
;
size_t
size
=
256
;
RECT
win_rect
,
top_rect
;
/* don't clip siblings if using parent clip region */
if
(
flags
&
DCX_PARENTCLIP
)
flags
&=
~
DCX_CLIPSIBLINGS
;
/* fetch the visible region from the server */
do
{
RGNDATA
*
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
)
+
size
-
1
);
if
(
!
data
)
return
;
SERVER_START_REQ
(
get_visible_region
)
{
req
->
window
=
dce
->
hwnd
;
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
data
->
Buffer
,
size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
{
size_t
reply_size
=
wine_server_reply_size
(
reply
);
data
->
rdh
.
dwSize
=
sizeof
(
data
->
rdh
);
data
->
rdh
.
iType
=
RDH_RECTANGLES
;
data
->
rdh
.
nCount
=
reply_size
/
sizeof
(
RECT
);
data
->
rdh
.
nRgnSize
=
reply_size
;
vis_rgn
=
ExtCreateRegion
(
NULL
,
size
,
data
);
top_win
=
reply
->
top_win
;
win_rect
.
left
=
reply
->
win_rect
.
left
;
win_rect
.
top
=
reply
->
win_rect
.
top
;
win_rect
.
right
=
reply
->
win_rect
.
right
;
win_rect
.
bottom
=
reply
->
win_rect
.
bottom
;
top_rect
.
left
=
reply
->
top_rect
.
left
;
top_rect
.
top
=
reply
->
top_rect
.
top
;
top_rect
.
right
=
reply
->
top_rect
.
right
;
top_rect
.
bottom
=
reply
->
top_rect
.
bottom
;
}
else
size
=
reply
->
total_size
;
}
SERVER_END_REQ
;
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
while
(
status
==
STATUS_BUFFER_OVERFLOW
);
if
(
status
||
!
vis_rgn
)
return
;
USER_Driver
->
pGetDC
(
dce
->
hdc
,
dce
->
hwnd
,
top_win
,
&
win_rect
,
&
top_rect
,
flags
);
if
(
dce
->
clip_rgn
)
CombineRgn
(
vis_rgn
,
vis_rgn
,
dce
->
clip_rgn
,
(
flags
&
DCX_INTERSECTRGN
)
?
RGN_AND
:
RGN_DIFF
);
/* map region to DC coordinates */
OffsetRgn
(
vis_rgn
,
-
win_rect
.
left
,
-
win_rect
.
top
);
SelectVisRgn
(
dce
->
hdc
,
vis_rgn
);
DeleteObject
(
vis_rgn
);
}
/***********************************************************************
* release_dce
*/
static
void
release_dce
(
struct
dce
*
dce
)
{
if
(
!
dce
->
hwnd
)
return
;
/* already released */
USER_Driver
->
pReleaseDC
(
dce
->
hwnd
,
dce
->
hdc
);
if
(
dce
->
clip_rgn
)
DeleteObject
(
dce
->
clip_rgn
);
dce
->
clip_rgn
=
0
;
dce
->
hwnd
=
0
;
dce
->
flags
&=
DCX_CACHE
;
}
/***********************************************************************
* delete_clip_rgn
*/
static
void
delete_clip_rgn
(
struct
dce
*
dce
)
{
if
(
!
dce
->
clip_rgn
)
return
;
/* nothing to do */
dce
->
flags
&=
~
(
DCX_EXCLUDERGN
|
DCX_INTERSECTRGN
);
DeleteObject
(
dce
->
clip_rgn
);
dce
->
clip_rgn
=
0
;
/* make it dirty so that the vis rgn gets recomputed next time */
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
}
/***********************************************************************
* alloc_dce
*
* Allocate a new DCE.
*/
static
struct
dce
*
alloc_dce
(
void
)
{
struct
dce
*
dce
;
if
(
!
(
dce
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
dce
)
)))
return
NULL
;
if
(
!
(
dce
->
hdc
=
CreateDCW
(
displayW
,
NULL
,
NULL
,
NULL
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
return
0
;
}
SaveDC
(
dce
->
hdc
);
dce
->
hwnd
=
0
;
dce
->
clip_rgn
=
0
;
dce
->
flags
=
0
;
dce
->
count
=
1
;
/* store DCE handle in DC hook data field */
SetDCHook
(
dce
->
hdc
,
dc_hook
,
(
DWORD_PTR
)
dce
);
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
return
dce
;
}
/***********************************************************************
* get_window_dce
*/
static
struct
dce
*
get_window_dce
(
HWND
hwnd
)
{
struct
dce
*
dce
;
WND
*
win
=
WIN_GetPtr
(
hwnd
);
if
(
!
win
||
win
==
WND_OTHER_PROCESS
||
win
==
WND_DESKTOP
)
return
NULL
;
dce
=
win
->
dce
;
if
(
!
dce
&&
(
dce
=
get_class_dce
(
win
->
class
)))
{
win
->
dce
=
dce
;
dce
->
count
++
;
}
WIN_ReleasePtr
(
win
);
if
(
!
dce
)
/* try to allocate one */
{
struct
dce
*
dce_to_free
=
NULL
;
LONG
class_style
=
GetClassLongW
(
hwnd
,
GCL_STYLE
);
if
(
class_style
&
CS_CLASSDC
)
{
if
(
!
(
dce
=
alloc_dce
()))
return
NULL
;
win
=
WIN_GetPtr
(
hwnd
);
if
(
win
&&
win
!=
WND_OTHER_PROCESS
&&
win
!=
WND_DESKTOP
)
{
if
(
win
->
dce
)
/* another thread beat us to it */
{
dce_to_free
=
dce
;
dce
=
win
->
dce
;
}
else
if
((
win
->
dce
=
set_class_dce
(
win
->
class
,
dce
))
!=
dce
)
{
dce_to_free
=
dce
;
dce
=
win
->
dce
;
dce
->
count
++
;
}
else
{
dce
->
count
++
;
list_add_tail
(
&
dce_list
,
&
dce
->
entry
);
}
WIN_ReleasePtr
(
win
);
}
else
dce_to_free
=
dce
;
}
else
if
(
class_style
&
CS_OWNDC
)
{
if
(
!
(
dce
=
alloc_dce
()))
return
NULL
;
win
=
WIN_GetPtr
(
hwnd
);
if
(
win
&&
win
!=
WND_OTHER_PROCESS
&&
win
!=
WND_DESKTOP
)
{
if
(
win
->
dwStyle
&
WS_CLIPCHILDREN
)
dce
->
flags
|=
DCX_CLIPCHILDREN
;
if
(
win
->
dwStyle
&
WS_CLIPSIBLINGS
)
dce
->
flags
|=
DCX_CLIPSIBLINGS
;
if
(
win
->
dce
)
/* another thread beat us to it */
{
dce_to_free
=
dce
;
dce
=
win
->
dce
;
}
else
{
win
->
dce
=
dce
;
dce
->
hwnd
=
hwnd
;
list_add_tail
(
&
dce_list
,
&
dce
->
entry
);
}
WIN_ReleasePtr
(
win
);
}
else
dce_to_free
=
dce
;
}
if
(
dce_to_free
)
{
SetDCHook
(
dce
->
hdc
,
NULL
,
0
);
DeleteDC
(
dce
->
hdc
);
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
}
}
return
dce
;
}
/***********************************************************************
* free_dce
*
* Free a class or window DCE.
*/
void
free_dce
(
struct
dce
*
dce
,
HWND
hwnd
)
{
USER_Lock
();
if
(
dce
)
{
if
(
!--
dce
->
count
)
{
/* turn it into a cache entry */
release_dce
(
dce
);
dce
->
flags
|=
DCX_CACHE
;
}
else
if
(
dce
->
hwnd
==
hwnd
)
{
release_dce
(
dce
);
}
}
/* now check for cache DCEs */
if
(
hwnd
)
{
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
(
dce
->
hwnd
!=
hwnd
)
continue
;
if
(
!
(
dce
->
flags
&
DCX_CACHE
))
continue
;
if
(
dce
->
count
)
WARN
(
"GetDC() without ReleaseDC() for window %p
\n
"
,
hwnd
);
dce
->
count
=
0
;
release_dce
(
dce
);
}
}
USER_Unlock
();
}
/***********************************************************************
* make_dc_dirty
*
* Mark the associated DC as dirty to force a refresh of the visible region
*/
static
void
make_dc_dirty
(
struct
dce
*
dce
)
{
if
(
!
dce
->
count
)
{
/* Don't bother with visible regions of unused DCEs */
TRACE
(
"
\t
purged %p dce [%p]
\n
"
,
dce
,
dce
->
hwnd
);
release_dce
(
dce
);
}
else
{
/* Set dirty bits in the hDC and DCE structs */
TRACE
(
"
\t
fixed up %p dce [%p]
\n
"
,
dce
,
dce
->
hwnd
);
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
}
}
/***********************************************************************
* invalidate_dce
*
* It is called from SetWindowPos() - we have to
* mark as dirty all busy DCEs for windows that have pWnd->parent as
* an ancestor and whose client rect intersects with specified update
* rectangle. In addition, pWnd->parent DCEs may need to be updated if
* DCX_CLIPCHILDREN flag is set.
*/
void
invalidate_dce
(
HWND
hwnd
,
const
RECT
*
rect
)
{
RECT
window_rect
,
extra_rect
;
struct
dce
*
dce
;
HWND
hwndScope
=
GetAncestor
(
hwnd
,
GA_PARENT
);
if
(
!
hwndScope
)
return
;
GetWindowRect
(
hwnd
,
&
window_rect
);
if
(
rect
)
{
extra_rect
=
*
rect
;
MapWindowPoints
(
hwndScope
,
0
,
(
POINT
*
)
&
extra_rect
,
2
);
}
TRACE
(
"%p scope hwnd = %p %s (%s)
\n
"
,
hwnd
,
hwndScope
,
wine_dbgstr_rect
(
&
window_rect
),
wine_dbgstr_rect
(
rect
)
);
/* walk all DCEs and fixup non-empty entries */
USER_Lock
();
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
TRACE
(
"%p: hwnd %p dcx %08x %s %s
\n
"
,
dce
,
dce
->
hwnd
,
dce
->
flags
,
(
dce
->
flags
&
DCX_CACHE
)
?
"Cache"
:
"Owned"
,
dce
->
count
?
"InUse"
:
""
);
if
(
!
dce
->
hwnd
)
continue
;
if
((
dce
->
hwnd
==
hwndScope
)
&&
!
(
dce
->
flags
&
DCX_CLIPCHILDREN
))
continue
;
/* child window positions don't bother us */
/* if DCE window is a child of hwnd, it has to be invalidated */
if
(
dce
->
hwnd
==
hwnd
||
IsChild
(
hwnd
,
dce
->
hwnd
))
{
make_dc_dirty
(
dce
);
}
else
/* otherwise check if the window rectangle intersects this DCE window */
{
if
(
hwndScope
==
GetDesktopWindow
()
||
hwndScope
==
dce
->
hwnd
||
IsChild
(
hwndScope
,
dce
->
hwnd
))
{
RECT
dce_rect
,
tmp
;
GetWindowRect
(
dce
->
hwnd
,
&
dce_rect
);
if
(
IntersectRect
(
&
tmp
,
&
dce_rect
,
&
window_rect
)
||
(
rect
&&
IntersectRect
(
&
tmp
,
&
dce_rect
,
&
extra_rect
)))
make_dc_dirty
(
dce
);
}
}
}
USER_Unlock
();
}
/***********************************************************************
* release_dc
*
* Implementation of ReleaseDC.
*/
static
INT
release_dc
(
HWND
hwnd
,
HDC
hdc
,
BOOL
end_paint
)
{
struct
dce
*
dce
;
BOOL
ret
=
FALSE
;
TRACE
(
"%p %p
\n
"
,
hwnd
,
hdc
);
USER_Lock
();
dce
=
(
struct
dce
*
)
GetDCHook
(
hdc
,
NULL
);
if
(
dce
&&
dce
->
count
)
{
if
(
end_paint
||
(
dce
->
flags
&
DCX_CACHE
))
delete_clip_rgn
(
dce
);
if
(
dce
->
flags
&
DCX_CACHE
)
dce
->
count
=
0
;
ret
=
TRUE
;
}
USER_Unlock
();
return
ret
;
}
/***********************************************************************
* dc_hook
*
* See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
*/
static
BOOL
CALLBACK
dc_hook
(
HDC
hDC
,
WORD
code
,
DWORD_PTR
data
,
LPARAM
lParam
)
{
BOOL
retv
=
TRUE
;
struct
dce
*
dce
=
(
struct
dce
*
)
data
;
TRACE
(
"hDC = %p, %u
\n
"
,
hDC
,
code
);
if
(
!
dce
)
return
0
;
assert
(
dce
->
hdc
==
hDC
);
switch
(
code
)
{
case
DCHC_INVALIDVISRGN
:
/* GDI code calls this when it detects that the
* DC is dirty (usually after SetHookFlags()). This
* means that we have to recompute the visible region.
*/
if
(
dce
->
count
)
update_visible_region
(
dce
);
else
/* non-fatal but shouldn't happen */
WARN
(
"DC is not in use!
\n
"
);
break
;
case
DCHC_DELETEDC
:
/*
* Windows will not let you delete a DC that is busy
* (between GetDC and ReleaseDC)
*/
USER_Lock
();
if
(
dce
->
count
)
{
WARN
(
"Application trying to delete a busy DC %p
\n
"
,
dce
->
hdc
);
retv
=
FALSE
;
}
else
{
list_remove
(
&
dce
->
entry
);
if
(
dce
->
clip_rgn
)
DeleteObject
(
dce
->
clip_rgn
);
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
}
USER_Unlock
();
break
;
}
return
retv
;
}
/***********************************************************************
* get_update_region
*
* Return update region (in screen coordinates) for a window.
...
...
@@ -263,7 +698,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
if
(
type
!=
NULLREGION
)
need_erase
=
!
SendMessageW
(
hwnd
,
WM_ERASEBKGND
,
(
WPARAM
)
hdc
,
0
);
}
if
(
!
hdc_ret
)
USER_Driver
->
pReleaseDC
(
hwnd
,
hdc
,
TRUE
);
if
(
!
hdc_ret
)
release_dc
(
hwnd
,
hdc
,
TRUE
);
}
if
(
hdc_ret
)
*
hdc_ret
=
hdc
;
...
...
@@ -457,7 +892,7 @@ HDC WINAPI BeginPaint( HWND hwnd, PAINTSTRUCT *lps )
BOOL
WINAPI
EndPaint
(
HWND
hwnd
,
const
PAINTSTRUCT
*
lps
)
{
if
(
!
lps
)
return
FALSE
;
USER_Driver
->
pReleaseDC
(
hwnd
,
lps
->
hdc
,
TRUE
);
release_dc
(
hwnd
,
lps
->
hdc
,
TRUE
);
ShowCaret
(
hwnd
);
return
TRUE
;
}
...
...
@@ -468,10 +903,142 @@ BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps )
*/
HDC
WINAPI
GetDCEx
(
HWND
hwnd
,
HRGN
hrgnClip
,
DWORD
flags
)
{
static
const
DWORD
clip_flags
=
DCX_PARENTCLIP
|
DCX_CLIPSIBLINGS
|
DCX_CLIPCHILDREN
|
DCX_WINDOW
;
struct
dce
*
dce
;
BOOL
bUpdateVisRgn
=
TRUE
;
HWND
parent
;
LONG
window_style
=
GetWindowLongW
(
hwnd
,
GWL_STYLE
);
if
(
!
hwnd
)
hwnd
=
GetDesktopWindow
();
else
hwnd
=
WIN_GetFullHandle
(
hwnd
);
return
USER_Driver
->
pGetDCEx
(
hwnd
,
hrgnClip
,
flags
);
TRACE
(
"hwnd %p, hrgnClip %p, flags %08x
\n
"
,
hwnd
,
hrgnClip
,
flags
);
/* fixup flags */
if
(
flags
&
(
DCX_WINDOW
|
DCX_PARENTCLIP
))
flags
|=
DCX_CACHE
;
if
(
flags
&
DCX_USESTYLE
)
{
flags
&=
~
(
DCX_CLIPCHILDREN
|
DCX_CLIPSIBLINGS
|
DCX_PARENTCLIP
);
if
(
window_style
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
if
(
!
(
flags
&
DCX_WINDOW
))
{
if
(
GetClassLongW
(
hwnd
,
GCL_STYLE
)
&
CS_PARENTDC
)
flags
|=
DCX_PARENTCLIP
;
if
(
window_style
&
WS_CLIPCHILDREN
&&
!
(
window_style
&
WS_MINIMIZE
))
flags
|=
DCX_CLIPCHILDREN
;
}
}
if
(
flags
&
DCX_WINDOW
)
flags
&=
~
DCX_CLIPCHILDREN
;
parent
=
GetAncestor
(
hwnd
,
GA_PARENT
);
if
(
!
parent
||
(
parent
==
GetDesktopWindow
()))
flags
=
(
flags
&
~
DCX_PARENTCLIP
)
|
DCX_CLIPSIBLINGS
;
/* it seems parent clip is ignored when clipping siblings or children */
if
(
flags
&
(
DCX_CLIPSIBLINGS
|
DCX_CLIPCHILDREN
))
flags
&=
~
DCX_PARENTCLIP
;
if
(
flags
&
DCX_PARENTCLIP
)
{
LONG
parent_style
=
GetWindowLongW
(
parent
,
GWL_STYLE
);
if
(
(
window_style
&
WS_VISIBLE
)
&&
(
parent_style
&
WS_VISIBLE
)
)
{
flags
&=
~
DCX_CLIPCHILDREN
;
if
(
parent_style
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
}
}
/* find a suitable DCE */
if
((
flags
&
DCX_CACHE
)
||
!
(
dce
=
get_window_dce
(
hwnd
)))
{
struct
dce
*
dceEmpty
=
NULL
,
*
dceUnused
=
NULL
;
/* Strategy: First, we attempt to find a non-empty but unused DCE with
* compatible flags. Next, we look for an empty entry. If the cache is
* full we have to purge one of the unused entries.
*/
USER_Lock
();
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
((
dce
->
flags
&
DCX_CACHE
)
&&
!
dce
->
count
)
{
dceUnused
=
dce
;
if
(
!
dce
->
hwnd
)
dceEmpty
=
dce
;
else
if
((
dce
->
hwnd
==
hwnd
)
&&
!
((
dce
->
flags
^
flags
)
&
clip_flags
))
{
TRACE
(
"
\t
found valid %p dce [%p], flags %08x
\n
"
,
dce
,
hwnd
,
dce
->
flags
);
bUpdateVisRgn
=
FALSE
;
break
;
}
}
}
if
(
&
dce
->
entry
==
&
dce_list
)
/* nothing found */
dce
=
dceEmpty
?
dceEmpty
:
dceUnused
;
if
(
dce
)
dce
->
count
=
1
;
USER_Unlock
();
/* if there's no dce empty or unused, allocate a new one */
if
(
!
dce
)
{
if
(
!
(
dce
=
alloc_dce
()))
return
0
;
dce
->
flags
=
DCX_CACHE
;
USER_Lock
();
list_add_head
(
&
dce_list
,
&
dce
->
entry
);
USER_Unlock
();
}
}
else
{
flags
|=
DCX_NORESETATTRS
;
if
(
dce
->
hwnd
==
hwnd
)
{
TRACE
(
"
\t
skipping hVisRgn update
\n
"
);
bUpdateVisRgn
=
FALSE
;
/* updated automatically, via DCHook() */
}
else
{
/* we should free dce->clip_rgn here, but Windows apparently doesn't */
dce
->
flags
&=
~
(
DCX_EXCLUDERGN
|
DCX_INTERSECTRGN
);
dce
->
clip_rgn
=
0
;
}
}
if
(
flags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
))
{
/* if the extra clip region has changed, get rid of the old one */
if
(
dce
->
clip_rgn
!=
hrgnClip
||
((
flags
^
dce
->
flags
)
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
)))
delete_clip_rgn
(
dce
);
dce
->
clip_rgn
=
hrgnClip
;
if
(
!
dce
->
clip_rgn
)
dce
->
clip_rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
dce
->
flags
|=
flags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
);
bUpdateVisRgn
=
TRUE
;
}
dce
->
hwnd
=
hwnd
;
dce
->
flags
=
(
dce
->
flags
&
~
clip_flags
)
|
(
flags
&
clip_flags
);
if
(
SetHookFlags
(
dce
->
hdc
,
DCHF_VALIDATEVISRGN
))
bUpdateVisRgn
=
TRUE
;
/* DC was dirty */
if
(
bUpdateVisRgn
)
update_visible_region
(
dce
);
if
(
!
(
flags
&
DCX_NORESETATTRS
))
{
RestoreDC
(
dce
->
hdc
,
1
);
/* initial save level is always 1 */
SaveDC
(
dce
->
hdc
);
/* save the state again for next time */
}
TRACE
(
"(%p,%p,0x%x): returning %p
\n
"
,
hwnd
,
hrgnClip
,
flags
,
dce
->
hdc
);
return
dce
->
hdc
;
}
...
...
@@ -511,16 +1078,23 @@ HDC WINAPI GetWindowDC( HWND hwnd )
*/
INT
WINAPI
ReleaseDC
(
HWND
hwnd
,
HDC
hdc
)
{
return
USER_Driver
->
pReleaseDC
(
hwnd
,
hdc
,
FALSE
);
return
release_dc
(
hwnd
,
hdc
,
FALSE
);
}
/**********************************************************************
* WindowFromDC (USER32.@)
*/
HWND
WINAPI
WindowFromDC
(
HDC
h
DC
)
HWND
WINAPI
WindowFromDC
(
HDC
h
dc
)
{
return
USER_Driver
->
pWindowFromDC
(
hDC
);
struct
dce
*
dce
;
HWND
hwnd
=
0
;
USER_Lock
();
dce
=
(
struct
dce
*
)
GetDCHook
(
hdc
,
NULL
);
if
(
dce
)
hwnd
=
dce
->
hwnd
;
USER_Unlock
();
return
hwnd
;
}
...
...
dlls/user32/tests/dce.c
View file @
1642fbcb
...
...
@@ -385,7 +385,6 @@ static void test_invisible_create(void)
dc1
=
GetDC
(
hwnd_owndc
);
dc2
=
GetDC
(
hwnd_owndc
);
todo_wine
ok
(
dc1
==
dc2
,
"expected owndc dcs to match
\n
"
);
ReleaseDC
(
hwnd_owndc
,
dc2
);
...
...
dlls/user32/user32.spec
View file @
1642fbcb
...
...
@@ -794,3 +794,4 @@
@ cdecl WINPOS_ShowIconTitle(long long)
@ cdecl WIN_GetPtr(long)
@ cdecl WIN_SetStyle(long long long)
@ cdecl WIN_invalidate_dce(long ptr) invalidate_dce
dlls/user32/user_private.h
View file @
1642fbcb
...
...
@@ -144,9 +144,9 @@ typedef struct tagUSER_DRIVER {
BOOL
(
*
pCreateDesktopWindow
)(
HWND
);
BOOL
(
*
pCreateWindow
)(
HWND
);
void
(
*
pDestroyWindow
)(
HWND
);
HDC
(
*
pGetDCEx
)(
HWND
,
HRGN
,
DWORD
);
void
(
*
pGetDC
)(
HDC
,
HWND
,
HWND
,
const
RECT
*
,
const
RECT
*
,
DWORD
);
DWORD
(
*
pMsgWaitForMultipleObjectsEx
)(
DWORD
,
const
HANDLE
*
,
DWORD
,
DWORD
,
DWORD
);
INT
(
*
pReleaseDC
)(
HWND
,
HDC
,
BOOL
);
void
(
*
pReleaseDC
)(
HWND
,
HDC
);
BOOL
(
*
pScrollDC
)(
HDC
,
INT
,
INT
,
const
RECT
*
,
const
RECT
*
,
HRGN
,
LPRECT
);
void
(
*
pSetFocus
)(
HWND
);
void
(
*
pSetParent
)(
HWND
,
HWND
,
HWND
);
...
...
@@ -157,7 +157,6 @@ typedef struct tagUSER_DRIVER {
void
(
*
pSetWindowText
)(
HWND
,
LPCWSTR
);
BOOL
(
*
pShowWindow
)(
HWND
,
INT
);
void
(
*
pSysCommandSizeMove
)(
HWND
,
WPARAM
);
HWND
(
*
pWindowFromDC
)(
HDC
);
LRESULT
(
*
pWindowMessage
)(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
}
USER_DRIVER
;
...
...
@@ -231,9 +230,13 @@ extern HMODULE user32_module DECLSPEC_HIDDEN;
extern
DWORD
USER16_AlertableWait
DECLSPEC_HIDDEN
;
extern
HBRUSH
SYSCOLOR_55AABrush
DECLSPEC_HIDDEN
;
struct
dce
;
extern
BOOL
CLIPBOARD_ReleaseOwner
(
void
)
DECLSPEC_HIDDEN
;
extern
BOOL
FOCUS_MouseActivate
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
BOOL
HOOK_IsHooked
(
INT
id
)
DECLSPEC_HIDDEN
;
extern
void
free_dce
(
struct
dce
*
dce
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
invalidate_dce
(
HWND
hwnd
,
const
RECT
*
rect
)
DECLSPEC_HIDDEN
;
extern
void
erase_now
(
HWND
hwnd
,
UINT
rdw_flags
)
DECLSPEC_HIDDEN
;
extern
void
*
get_hook_proc
(
void
*
proc
,
const
WCHAR
*
module
);
extern
LRESULT
call_current_hook
(
HHOOK
hhook
,
INT
code
,
WPARAM
wparam
,
LPARAM
lparam
)
DECLSPEC_HIDDEN
;
...
...
dlls/user32/win.c
View file @
1642fbcb
...
...
@@ -522,7 +522,11 @@ ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
}
SERVER_END_REQ
;
WIN_ReleasePtr
(
win
);
if
(
ok
)
USER_Driver
->
pSetWindowStyle
(
hwnd
,
old_style
);
if
(
ok
)
{
USER_Driver
->
pSetWindowStyle
(
hwnd
,
old_style
);
if
((
old_style
^
new_style
)
&
WS_VISIBLE
)
invalidate_dce
(
hwnd
,
NULL
);
}
return
old_style
;
}
...
...
@@ -631,6 +635,8 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
if
((
wndPtr
->
dwStyle
&
(
WS_CHILD
|
WS_POPUP
))
!=
WS_CHILD
)
menu
=
(
HMENU
)
wndPtr
->
wIDmenu
;
sys_menu
=
wndPtr
->
hSysMenu
;
free_dce
(
wndPtr
->
dce
,
hwnd
);
wndPtr
->
dce
=
NULL
;
WIN_ReleasePtr
(
wndPtr
);
if
(
menu
)
DestroyMenu
(
menu
);
...
...
dlls/user32/winpos.c
View file @
1642fbcb
...
...
@@ -276,6 +276,7 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
UINT
swp_flags
=
SWP_NOSIZE
|
SWP_NOMOVE
|
SWP_NOZORDER
|
SWP_NOACTIVATE
|
SWP_FRAMECHANGED
|
SWP_NOCLIENTSIZE
|
SWP_NOCLIENTMOVE
;
if
(
!
bRedraw
)
swp_flags
|=
SWP_NOREDRAW
;
SetWindowPos
(
hwnd
,
0
,
0
,
0
,
0
,
0
,
swp_flags
);
invalidate_dce
(
hwnd
,
NULL
);
}
return
ret
;
}
...
...
@@ -1590,11 +1591,13 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
{
WND
*
win
;
BOOL
ret
;
RECT
visible_rect
;
RECT
visible_rect
,
old_window_rect
;
DWORD
new_style
;
if
(
!
(
win
=
WIN_GetPtr
(
hwnd
)))
return
FALSE
;
if
(
win
==
WND_DESKTOP
||
win
==
WND_OTHER_PROCESS
)
return
FALSE
;
old_window_rect
=
win
->
rectWindow
;
SERVER_START_REQ
(
set_window_pos
)
{
req
->
handle
=
hwnd
;
...
...
@@ -1623,11 +1626,18 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
}
}
SERVER_END_REQ
;
new_style
=
win
->
dwStyle
;
WIN_ReleasePtr
(
win
);
if
(
ret
)
{
USER_Driver
->
pSetWindowPos
(
hwnd
,
insert_after
,
swp_flags
,
window_rect
,
client_rect
,
&
visible_rect
,
valid_rects
);
if
((((
swp_flags
&
SWP_AGG_NOPOSCHANGE
)
!=
SWP_AGG_NOPOSCHANGE
)
&&
(
new_style
&
WS_VISIBLE
))
||
(
swp_flags
&
(
SWP_HIDEWINDOW
|
SWP_SHOWWINDOW
)))
invalidate_dce
(
hwnd
,
&
old_window_rect
);
}
return
ret
;
}
...
...
dlls/winex11.drv/Makefile.in
View file @
1642fbcb
...
...
@@ -14,7 +14,6 @@ C_SRCS = \
clipboard.c
\
clipping.c
\
codepage.c
\
dce.c
\
desktop.c
\
dib.c
\
dib_convert.c
\
...
...
dlls/winex11.drv/dce.c
deleted
100644 → 0
View file @
4273a8ab
/*
* USER DCE functions
*
* Copyright 1993, 2005 Alexandre Julliard
* Copyright 1996, 1997 Alex Korobka
*
* 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 <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "win.h"
#include "windef.h"
#include "wingdi.h"
#include "x11drv.h"
#include "wine/server.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
dc
);
struct
dce
{
struct
list
entry
;
/* entry in global DCE list */
HDC
hdc
;
HWND
hwnd
;
HRGN
clip_rgn
;
DWORD
flags
;
void
*
class_ptr
;
/* ptr to identify window class for class DCEs */
ULONG
count
;
/* usage count; 0 or 1 for cache DCEs, always 1 for window DCEs,
always >= 1 for class DCEs */
};
static
struct
list
dce_list
=
LIST_INIT
(
dce_list
);
static
BOOL
CALLBACK
dc_hook
(
HDC
hDC
,
WORD
code
,
DWORD_PTR
data
,
LPARAM
lParam
);
static
CRITICAL_SECTION
dce_section
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
{
0
,
0
,
&
dce_section
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": dce_section"
)
}
};
static
CRITICAL_SECTION
dce_section
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
const
WCHAR
displayW
[]
=
{
'D'
,
'I'
,
'S'
,
'P'
,
'L'
,
'A'
,
'Y'
,
0
};
/***********************************************************************
* dump_cache
*/
static
void
dump_cache
(
void
)
{
struct
dce
*
dce
;
EnterCriticalSection
(
&
dce_section
);
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
TRACE
(
"%p: hwnd %p dcx %08x %s %s
\n
"
,
dce
,
dce
->
hwnd
,
dce
->
flags
,
(
dce
->
flags
&
DCX_CACHE
)
?
"Cache"
:
"Owned"
,
dce
->
count
?
"InUse"
:
""
);
}
LeaveCriticalSection
(
&
dce_section
);
}
/***********************************************************************
* update_visible_region
*
* Set the visible region and X11 drawable for the DC associated to
* a given window.
*/
static
void
update_visible_region
(
struct
dce
*
dce
)
{
NTSTATUS
status
;
HRGN
vis_rgn
=
0
;
HWND
top
=
0
;
struct
x11drv_escape_set_drawable
escape
;
struct
x11drv_win_data
*
data
;
DWORD
flags
=
dce
->
flags
;
size_t
size
=
256
;
/* don't clip siblings if using parent clip region */
if
(
flags
&
DCX_PARENTCLIP
)
flags
&=
~
DCX_CLIPSIBLINGS
;
/* fetch the visible region from the server */
do
{
RGNDATA
*
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
)
+
size
-
1
);
if
(
!
data
)
return
;
SERVER_START_REQ
(
get_visible_region
)
{
req
->
window
=
dce
->
hwnd
;
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
data
->
Buffer
,
size
);
if
(
!
(
status
=
wine_server_call
(
req
)))
{
size_t
reply_size
=
wine_server_reply_size
(
reply
);
data
->
rdh
.
dwSize
=
sizeof
(
data
->
rdh
);
data
->
rdh
.
iType
=
RDH_RECTANGLES
;
data
->
rdh
.
nCount
=
reply_size
/
sizeof
(
RECT
);
data
->
rdh
.
nRgnSize
=
reply_size
;
vis_rgn
=
ExtCreateRegion
(
NULL
,
size
,
data
);
top
=
reply
->
top_win
;
escape
.
dc_rect
.
left
=
reply
->
win_rect
.
left
-
reply
->
top_rect
.
left
;
escape
.
dc_rect
.
top
=
reply
->
win_rect
.
top
-
reply
->
top_rect
.
top
;
escape
.
dc_rect
.
right
=
reply
->
win_rect
.
right
-
reply
->
top_rect
.
left
;
escape
.
dc_rect
.
bottom
=
reply
->
win_rect
.
bottom
-
reply
->
top_rect
.
top
;
escape
.
drawable_rect
.
left
=
reply
->
top_rect
.
left
;
escape
.
drawable_rect
.
top
=
reply
->
top_rect
.
top
;
escape
.
drawable_rect
.
right
=
reply
->
top_rect
.
right
;
escape
.
drawable_rect
.
bottom
=
reply
->
top_rect
.
bottom
;
}
else
size
=
reply
->
total_size
;
}
SERVER_END_REQ
;
HeapFree
(
GetProcessHeap
(),
0
,
data
);
}
while
(
status
==
STATUS_BUFFER_OVERFLOW
);
if
(
status
||
!
vis_rgn
)
return
;
if
(
dce
->
clip_rgn
)
CombineRgn
(
vis_rgn
,
vis_rgn
,
dce
->
clip_rgn
,
(
flags
&
DCX_INTERSECTRGN
)
?
RGN_AND
:
RGN_DIFF
);
escape
.
fbconfig_id
=
0
;
escape
.
gl_drawable
=
0
;
escape
.
pixmap
=
0
;
if
(
top
==
dce
->
hwnd
&&
((
data
=
X11DRV_get_win_data
(
dce
->
hwnd
))
!=
NULL
)
&&
IsIconic
(
dce
->
hwnd
)
&&
data
->
icon_window
)
{
escape
.
drawable
=
data
->
icon_window
;
}
else
if
(
top
==
dce
->
hwnd
&&
(
flags
&
DCX_WINDOW
))
{
escape
.
drawable
=
X11DRV_get_whole_window
(
top
);
}
else
{
escape
.
drawable
=
X11DRV_get_client_window
(
top
);
escape
.
fbconfig_id
=
X11DRV_get_fbconfig_id
(
dce
->
hwnd
);
escape
.
gl_drawable
=
X11DRV_get_gl_drawable
(
dce
->
hwnd
);
escape
.
pixmap
=
X11DRV_get_gl_pixmap
(
dce
->
hwnd
);
}
escape
.
code
=
X11DRV_SET_DRAWABLE
;
escape
.
mode
=
IncludeInferiors
;
ExtEscape
(
dce
->
hdc
,
X11DRV_ESCAPE
,
sizeof
(
escape
),
(
LPSTR
)
&
escape
,
0
,
NULL
);
/* map region to DC coordinates */
OffsetRgn
(
vis_rgn
,
-
(
escape
.
drawable_rect
.
left
+
escape
.
dc_rect
.
left
),
-
(
escape
.
drawable_rect
.
top
+
escape
.
dc_rect
.
top
)
);
SelectVisRgn
(
dce
->
hdc
,
vis_rgn
);
DeleteObject
(
vis_rgn
);
}
/***********************************************************************
* release_dce
*/
static
void
release_dce
(
struct
dce
*
dce
)
{
struct
x11drv_escape_set_drawable
escape
;
if
(
!
dce
->
hwnd
)
return
;
/* already released */
if
(
dce
->
clip_rgn
)
DeleteObject
(
dce
->
clip_rgn
);
dce
->
clip_rgn
=
0
;
dce
->
hwnd
=
0
;
dce
->
flags
&=
DCX_CACHE
;
escape
.
code
=
X11DRV_SET_DRAWABLE
;
escape
.
drawable
=
root_window
;
escape
.
mode
=
IncludeInferiors
;
escape
.
drawable_rect
=
virtual_screen_rect
;
SetRect
(
&
escape
.
dc_rect
,
0
,
0
,
virtual_screen_rect
.
right
-
virtual_screen_rect
.
left
,
virtual_screen_rect
.
bottom
-
virtual_screen_rect
.
top
);
escape
.
fbconfig_id
=
0
;
escape
.
gl_drawable
=
0
;
escape
.
pixmap
=
0
;
ExtEscape
(
dce
->
hdc
,
X11DRV_ESCAPE
,
sizeof
(
escape
),
(
LPSTR
)
&
escape
,
0
,
NULL
);
}
/***********************************************************************
* delete_clip_rgn
*/
static
void
delete_clip_rgn
(
struct
dce
*
dce
)
{
if
(
!
dce
->
clip_rgn
)
return
;
/* nothing to do */
dce
->
flags
&=
~
(
DCX_EXCLUDERGN
|
DCX_INTERSECTRGN
);
DeleteObject
(
dce
->
clip_rgn
);
dce
->
clip_rgn
=
0
;
/* make it dirty so that the vis rgn gets recomputed next time */
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
}
/***********************************************************************
* alloc_cache_dce
*
* Allocate a new cache DCE.
*/
static
struct
dce
*
alloc_cache_dce
(
void
)
{
struct
dce
*
dce
;
if
(
!
(
dce
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
dce
)
)))
return
NULL
;
if
(
!
(
dce
->
hdc
=
CreateDCW
(
displayW
,
NULL
,
NULL
,
NULL
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
return
0
;
}
SaveDC
(
dce
->
hdc
);
/* store DCE handle in DC hook data field */
SetDCHook
(
dce
->
hdc
,
dc_hook
,
(
DWORD_PTR
)
dce
);
dce
->
hwnd
=
0
;
dce
->
clip_rgn
=
0
;
dce
->
flags
=
DCX_CACHE
;
dce
->
class_ptr
=
NULL
;
dce
->
count
=
1
;
EnterCriticalSection
(
&
dce_section
);
list_add_head
(
&
dce_list
,
&
dce
->
entry
);
LeaveCriticalSection
(
&
dce_section
);
return
dce
;
}
/***********************************************************************
* alloc_window_dce
*
* Allocate a DCE for a newly created window if necessary.
*/
void
alloc_window_dce
(
struct
x11drv_win_data
*
data
)
{
struct
dce
*
dce
;
void
*
class_ptr
=
NULL
;
LONG
style
=
GetClassLongW
(
data
->
hwnd
,
GCL_STYLE
);
if
(
!
(
style
&
(
CS_CLASSDC
|
CS_OWNDC
)))
return
;
/* nothing to do */
if
(
!
(
style
&
CS_OWNDC
))
/* class dc */
{
/* hack: get the class pointer from the window structure */
WND
*
win
=
WIN_GetPtr
(
data
->
hwnd
);
class_ptr
=
win
->
class
;
WIN_ReleasePtr
(
win
);
EnterCriticalSection
(
&
dce_section
);
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
(
dce
->
class_ptr
==
class_ptr
)
{
dce
->
count
++
;
data
->
dce
=
dce
;
LeaveCriticalSection
(
&
dce_section
);
return
;
}
}
LeaveCriticalSection
(
&
dce_section
);
}
/* now allocate a new one */
if
(
!
(
dce
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
dce
)
)))
return
;
if
(
!
(
dce
->
hdc
=
CreateDCW
(
displayW
,
NULL
,
NULL
,
NULL
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
return
;
}
/* store DCE handle in DC hook data field */
SetDCHook
(
dce
->
hdc
,
dc_hook
,
(
DWORD_PTR
)
dce
);
dce
->
hwnd
=
data
->
hwnd
;
dce
->
clip_rgn
=
0
;
dce
->
flags
=
0
;
dce
->
class_ptr
=
class_ptr
;
dce
->
count
=
1
;
if
(
style
&
CS_OWNDC
)
{
LONG
win_style
=
GetWindowLongW
(
data
->
hwnd
,
GWL_STYLE
);
if
(
win_style
&
WS_CLIPCHILDREN
)
dce
->
flags
|=
DCX_CLIPCHILDREN
;
if
(
win_style
&
WS_CLIPSIBLINGS
)
dce
->
flags
|=
DCX_CLIPSIBLINGS
;
}
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
EnterCriticalSection
(
&
dce_section
);
list_add_tail
(
&
dce_list
,
&
dce
->
entry
);
LeaveCriticalSection
(
&
dce_section
);
data
->
dce
=
dce
;
}
/***********************************************************************
* free_window_dce
*
* Free a class or window DCE.
*/
void
free_window_dce
(
struct
x11drv_win_data
*
data
)
{
struct
dce
*
dce
=
data
->
dce
;
if
(
dce
)
{
EnterCriticalSection
(
&
dce_section
);
if
(
!--
dce
->
count
)
{
list_remove
(
&
dce
->
entry
);
SetDCHook
(
dce
->
hdc
,
NULL
,
0L
);
DeleteDC
(
dce
->
hdc
);
if
(
dce
->
clip_rgn
)
DeleteObject
(
dce
->
clip_rgn
);
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
}
else
if
(
dce
->
hwnd
==
data
->
hwnd
)
{
release_dce
(
dce
);
}
LeaveCriticalSection
(
&
dce_section
);
data
->
dce
=
NULL
;
}
/* now check for cache DCEs */
EnterCriticalSection
(
&
dce_section
);
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
(
dce
->
hwnd
!=
data
->
hwnd
)
continue
;
if
(
!
(
dce
->
flags
&
DCX_CACHE
))
continue
;
if
(
dce
->
count
)
WARN
(
"GetDC() without ReleaseDC() for window %p
\n
"
,
data
->
hwnd
);
release_dce
(
dce
);
dce
->
count
=
0
;
}
LeaveCriticalSection
(
&
dce_section
);
}
/***********************************************************************
* invalidate_dce
*
* It is called from SetWindowPos() - we have to
* mark as dirty all busy DCEs for windows that have pWnd->parent as
* an ancestor and whose client rect intersects with specified update
* rectangle. In addition, pWnd->parent DCEs may need to be updated if
* DCX_CLIPCHILDREN flag is set.
*/
void
invalidate_dce
(
HWND
hwnd
,
const
RECT
*
rect
)
{
HWND
hwndScope
=
GetAncestor
(
hwnd
,
GA_PARENT
);
if
(
hwndScope
)
{
struct
dce
*
dce
;
TRACE
(
"scope hwnd = %p %s
\n
"
,
hwndScope
,
wine_dbgstr_rect
(
rect
)
);
if
(
TRACE_ON
(
dc
))
dump_cache
();
/* walk all DCEs and fixup non-empty entries */
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
(
!
dce
->
hwnd
)
continue
;
if
((
dce
->
hwnd
==
hwndScope
)
&&
!
(
dce
->
flags
&
DCX_CLIPCHILDREN
))
continue
;
/* child window positions don't bother us */
/* check if DCE window is within the z-order scope */
if
(
hwndScope
==
dce
->
hwnd
||
hwndScope
==
GetDesktopWindow
()
||
IsChild
(
hwndScope
,
dce
->
hwnd
))
{
if
(
hwnd
!=
dce
->
hwnd
)
{
/* check if the window rectangle intersects this DCE window */
RECT
tmp
;
GetWindowRect
(
dce
->
hwnd
,
&
tmp
);
MapWindowPoints
(
0
,
hwndScope
,
(
POINT
*
)
&
tmp
,
2
);
if
(
!
IntersectRect
(
&
tmp
,
&
tmp
,
rect
))
continue
;
}
if
(
!
dce
->
count
)
{
/* Don't bother with visible regions of unused DCEs */
TRACE
(
"
\t
purged %p dce [%p]
\n
"
,
dce
,
dce
->
hwnd
);
release_dce
(
dce
);
}
else
{
/* Set dirty bits in the hDC and DCE structs */
TRACE
(
"
\t
fixed up %p dce [%p]
\n
"
,
dce
,
dce
->
hwnd
);
SetHookFlags
(
dce
->
hdc
,
DCHF_INVALIDATEVISRGN
);
}
}
}
/* dce list */
}
}
/***********************************************************************
* X11DRV_GetDCEx (X11DRV.@)
*
* Unimplemented flags: DCX_LOCKWINDOWUPDATE
*/
HDC
X11DRV_GetDCEx
(
HWND
hwnd
,
HRGN
hrgnClip
,
DWORD
flags
)
{
static
const
DWORD
clip_flags
=
DCX_PARENTCLIP
|
DCX_CLIPSIBLINGS
|
DCX_CLIPCHILDREN
|
DCX_WINDOW
;
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
struct
dce
*
dce
;
BOOL
bUpdateVisRgn
=
TRUE
;
HWND
parent
;
LONG
window_style
=
GetWindowLongW
(
hwnd
,
GWL_STYLE
);
TRACE
(
"hwnd %p, hrgnClip %p, flags %08x
\n
"
,
hwnd
,
hrgnClip
,
flags
);
/* fixup flags */
if
(
flags
&
(
DCX_WINDOW
|
DCX_PARENTCLIP
))
flags
|=
DCX_CACHE
;
if
(
flags
&
DCX_USESTYLE
)
{
flags
&=
~
(
DCX_CLIPCHILDREN
|
DCX_CLIPSIBLINGS
|
DCX_PARENTCLIP
);
if
(
window_style
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
if
(
!
(
flags
&
DCX_WINDOW
))
{
if
(
GetClassLongW
(
hwnd
,
GCL_STYLE
)
&
CS_PARENTDC
)
flags
|=
DCX_PARENTCLIP
;
if
(
window_style
&
WS_CLIPCHILDREN
&&
!
(
window_style
&
WS_MINIMIZE
))
flags
|=
DCX_CLIPCHILDREN
;
if
(
!
data
||
!
data
->
dce
)
flags
|=
DCX_CACHE
;
}
}
if
(
flags
&
DCX_WINDOW
)
flags
&=
~
DCX_CLIPCHILDREN
;
parent
=
GetAncestor
(
hwnd
,
GA_PARENT
);
if
(
!
parent
||
(
parent
==
GetDesktopWindow
()))
flags
=
(
flags
&
~
DCX_PARENTCLIP
)
|
DCX_CLIPSIBLINGS
;
/* it seems parent clip is ignored when clipping siblings or children */
if
(
flags
&
(
DCX_CLIPSIBLINGS
|
DCX_CLIPCHILDREN
))
flags
&=
~
DCX_PARENTCLIP
;
if
(
flags
&
DCX_PARENTCLIP
)
{
LONG
parent_style
=
GetWindowLongW
(
parent
,
GWL_STYLE
);
if
(
(
window_style
&
WS_VISIBLE
)
&&
(
parent_style
&
WS_VISIBLE
)
)
{
flags
&=
~
DCX_CLIPCHILDREN
;
if
(
parent_style
&
WS_CLIPSIBLINGS
)
flags
|=
DCX_CLIPSIBLINGS
;
}
}
/* find a suitable DCE */
if
(
flags
&
DCX_CACHE
)
{
struct
dce
*
dceEmpty
=
NULL
,
*
dceUnused
=
NULL
;
/* Strategy: First, we attempt to find a non-empty but unused DCE with
* compatible flags. Next, we look for an empty entry. If the cache is
* full we have to purge one of the unused entries.
*/
EnterCriticalSection
(
&
dce_section
);
LIST_FOR_EACH_ENTRY
(
dce
,
&
dce_list
,
struct
dce
,
entry
)
{
if
((
dce
->
flags
&
DCX_CACHE
)
&&
!
dce
->
count
)
{
dceUnused
=
dce
;
if
(
!
dce
->
hwnd
)
dceEmpty
=
dce
;
else
if
((
dce
->
hwnd
==
hwnd
)
&&
!
((
dce
->
flags
^
flags
)
&
clip_flags
))
{
TRACE
(
"
\t
found valid %p dce [%p], flags %08x
\n
"
,
dce
,
hwnd
,
dce
->
flags
);
bUpdateVisRgn
=
FALSE
;
break
;
}
}
}
if
(
&
dce
->
entry
==
&
dce_list
)
/* nothing found */
dce
=
dceEmpty
?
dceEmpty
:
dceUnused
;
if
(
dce
)
dce
->
count
=
1
;
LeaveCriticalSection
(
&
dce_section
);
/* if there's no dce empty or unused, allocate a new one */
if
(
!
dce
)
dce
=
alloc_cache_dce
();
if
(
!
dce
)
return
0
;
}
else
{
flags
|=
DCX_NORESETATTRS
;
dce
=
data
->
dce
;
if
(
dce
->
hwnd
==
hwnd
)
{
TRACE
(
"
\t
skipping hVisRgn update
\n
"
);
bUpdateVisRgn
=
FALSE
;
/* updated automatically, via DCHook() */
}
else
{
/* we should free dce->clip_rgn here, but Windows apparently doesn't */
dce
->
flags
&=
~
(
DCX_EXCLUDERGN
|
DCX_INTERSECTRGN
);
dce
->
clip_rgn
=
0
;
}
}
if
(
flags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
))
{
/* if the extra clip region has changed, get rid of the old one */
if
(
dce
->
clip_rgn
!=
hrgnClip
||
((
flags
^
dce
->
flags
)
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
)))
delete_clip_rgn
(
dce
);
dce
->
clip_rgn
=
hrgnClip
;
if
(
!
dce
->
clip_rgn
)
dce
->
clip_rgn
=
CreateRectRgn
(
0
,
0
,
0
,
0
);
dce
->
flags
|=
flags
&
(
DCX_INTERSECTRGN
|
DCX_EXCLUDERGN
);
bUpdateVisRgn
=
TRUE
;
}
dce
->
hwnd
=
hwnd
;
dce
->
flags
=
(
dce
->
flags
&
~
clip_flags
)
|
(
flags
&
clip_flags
);
if
(
SetHookFlags
(
dce
->
hdc
,
DCHF_VALIDATEVISRGN
))
bUpdateVisRgn
=
TRUE
;
/* DC was dirty */
if
(
bUpdateVisRgn
)
update_visible_region
(
dce
);
if
(
!
(
flags
&
DCX_NORESETATTRS
))
{
RestoreDC
(
dce
->
hdc
,
1
);
/* initial save level is always 1 */
SaveDC
(
dce
->
hdc
);
/* save the state again for next time */
}
TRACE
(
"(%p,%p,0x%x): returning %p
\n
"
,
hwnd
,
hrgnClip
,
flags
,
dce
->
hdc
);
return
dce
->
hdc
;
}
/***********************************************************************
* X11DRV_ReleaseDC (X11DRV.@)
*/
INT
X11DRV_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
,
BOOL
end_paint
)
{
struct
dce
*
dce
;
BOOL
ret
=
FALSE
;
TRACE
(
"%p %p
\n
"
,
hwnd
,
hdc
);
EnterCriticalSection
(
&
dce_section
);
dce
=
(
struct
dce
*
)
GetDCHook
(
hdc
,
NULL
);
if
(
dce
&&
dce
->
count
)
{
if
(
end_paint
||
(
dce
->
flags
&
DCX_CACHE
))
delete_clip_rgn
(
dce
);
if
(
dce
->
flags
&
DCX_CACHE
)
dce
->
count
=
0
;
ret
=
TRUE
;
}
LeaveCriticalSection
(
&
dce_section
);
return
ret
;
}
/***********************************************************************
* dc_hook
*
* See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
*/
static
BOOL
CALLBACK
dc_hook
(
HDC
hDC
,
WORD
code
,
DWORD_PTR
data
,
LPARAM
lParam
)
{
BOOL
retv
=
TRUE
;
struct
dce
*
dce
=
(
struct
dce
*
)
data
;
TRACE
(
"hDC = %p, %u
\n
"
,
hDC
,
code
);
if
(
!
dce
)
return
0
;
assert
(
dce
->
hdc
==
hDC
);
switch
(
code
)
{
case
DCHC_INVALIDVISRGN
:
/* GDI code calls this when it detects that the
* DC is dirty (usually after SetHookFlags()). This
* means that we have to recompute the visible region.
*/
if
(
dce
->
count
)
update_visible_region
(
dce
);
else
/* non-fatal but shouldn't happen */
WARN
(
"DC is not in use!
\n
"
);
break
;
case
DCHC_DELETEDC
:
/*
* Windows will not let you delete a DC that is busy
* (between GetDC and ReleaseDC)
*/
if
(
dce
->
count
)
{
WARN
(
"Application trying to delete a busy DC %p
\n
"
,
dce
->
hdc
);
retv
=
FALSE
;
}
else
{
EnterCriticalSection
(
&
dce_section
);
list_remove
(
&
dce
->
entry
);
LeaveCriticalSection
(
&
dce_section
);
if
(
dce
->
clip_rgn
)
DeleteObject
(
dce
->
clip_rgn
);
HeapFree
(
GetProcessHeap
(),
0
,
dce
);
}
break
;
}
return
retv
;
}
/**********************************************************************
* WindowFromDC (X11DRV.@)
*/
HWND
X11DRV_WindowFromDC
(
HDC
hdc
)
{
struct
dce
*
dce
;
HWND
hwnd
=
0
;
EnterCriticalSection
(
&
dce_section
);
if
((
dce
=
(
struct
dce
*
)
GetDCHook
(
hdc
,
NULL
)))
hwnd
=
dce
->
hwnd
;
LeaveCriticalSection
(
&
dce_section
);
return
hwnd
;
}
dlls/winex11.drv/opengl.c
View file @
1642fbcb
...
...
@@ -1468,8 +1468,6 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
ERR
(
"Couldn't set format of the window, returning failure
\n
"
);
return
FALSE
;
}
physDev
->
gl_drawable
=
X11DRV_get_gl_drawable
(
hwnd
);
}
else
if
(
physDev
->
bitmap
)
{
if
(
!
(
value
&
GLX_PIXMAP_BIT
))
{
...
...
dlls/winex11.drv/window.c
View file @
1642fbcb
...
...
@@ -71,6 +71,8 @@ static const char visual_id_prop[] = "__wine_x11_visual_id";
extern
int
usexcomposite
;
extern
void
WIN_invalidate_dce
(
HWND
hwnd
,
const
RECT
*
rect
);
/* FIXME: to be removed */
/***********************************************************************
* is_window_managed
*
...
...
@@ -471,7 +473,7 @@ done:
wine_tsx11_lock
();
XFlush
(
display
);
wine_tsx11_unlock
();
invalidate_dce
(
hwnd
,
&
data
->
window_rect
);
WIN_invalidate_dce
(
hwnd
,
NULL
);
return
TRUE
;
}
...
...
@@ -542,7 +544,6 @@ static void sync_gl_drawable(Display *display, struct x11drv_win_data *data)
SetPropA
(
data
->
hwnd
,
gl_drawable_prop
,
(
HANDLE
)
data
->
gl_drawable
);
SetPropA
(
data
->
hwnd
,
pixmap_prop
,
(
HANDLE
)
data
->
pixmap
);
invalidate_dce
(
data
->
hwnd
,
&
data
->
window_rect
);
}
...
...
@@ -1307,7 +1308,6 @@ void X11DRV_DestroyWindow( HWND hwnd )
wine_tsx11_unlock
();
}
free_window_dce
(
data
);
destroy_whole_window
(
display
,
data
);
destroy_icon_window
(
display
,
data
);
...
...
@@ -1489,9 +1489,6 @@ struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd )
hwnd
,
data
->
whole_window
,
data
->
client_window
,
wine_dbgstr_rect
(
&
data
->
window_rect
),
wine_dbgstr_rect
(
&
data
->
whole_rect
),
wine_dbgstr_rect
(
&
data
->
client_rect
));
}
/* get class or window DC if needed */
alloc_window_dce
(
data
);
return
data
;
}
...
...
@@ -1533,57 +1530,80 @@ Window X11DRV_get_client_window( HWND hwnd )
/***********************************************************************
*
X11DRV_get_fbconfig_id
*
X11DRV_get_ic
*
* Return the GLXFBConfig ID of the drawable used by the window for
* OpenGL rendering. This is 0 for windows without a pixel format set.
* Return the X input context associated with a window
*/
XI
D
X11DRV_get_fbconfig_id
(
HWND
hwnd
)
XI
C
X11DRV_get_ic
(
HWND
hwnd
)
{
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
if
(
!
data
)
return
(
XID
)
GetPropA
(
hwnd
,
fbconfig_id_prop
)
;
return
data
->
fbconfig_id
;
if
(
!
data
)
return
0
;
return
data
->
xic
;
}
/***********************************************************************
* X11DRV_get_gl_drawable
*
* Return the GL drawable for this window.
* X11DRV_GetDC (X11DRV.@)
*/
Drawable
X11DRV_get_gl_drawable
(
HWND
hwnd
)
void
X11DRV_GetDC
(
HDC
hdc
,
HWND
hwnd
,
HWND
top
,
const
RECT
*
win_rect
,
const
RECT
*
top_rect
,
DWORD
flags
)
{
struct
x11drv_escape_set_drawable
escape
;
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
if
(
!
data
)
return
(
Drawable
)
GetPropA
(
hwnd
,
gl_drawable_prop
);
return
data
->
gl_drawable
;
}
escape
.
code
=
X11DRV_SET_DRAWABLE
;
escape
.
mode
=
IncludeInferiors
;
escape
.
fbconfig_id
=
0
;
escape
.
gl_drawable
=
0
;
escape
.
pixmap
=
0
;
/***********************************************************************
* X11DRV_get_gl_pixmap
*
* Return the Pixmap associated with the GL drawable (if any) for this window.
*/
Pixmap
X11DRV_get_gl_pixmap
(
HWND
hwnd
)
{
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
if
(
top
==
hwnd
&&
data
&&
IsIconic
(
hwnd
)
&&
data
->
icon_window
)
{
escape
.
drawable
=
data
->
icon_window
;
}
else
if
(
top
==
hwnd
&&
(
flags
&
DCX_WINDOW
))
{
escape
.
drawable
=
data
?
data
->
whole_window
:
X11DRV_get_whole_window
(
hwnd
);
}
else
{
escape
.
drawable
=
X11DRV_get_client_window
(
top
);
escape
.
fbconfig_id
=
data
?
data
->
fbconfig_id
:
(
XID
)
GetPropA
(
hwnd
,
fbconfig_id_prop
);
escape
.
gl_drawable
=
data
?
data
->
gl_drawable
:
(
Drawable
)
GetPropA
(
hwnd
,
gl_drawable_prop
);
escape
.
pixmap
=
data
?
data
->
pixmap
:
(
Pixmap
)
GetPropA
(
hwnd
,
pixmap_prop
);
}
if
(
!
data
)
return
(
Pixmap
)
GetPropA
(
hwnd
,
pixmap_prop
);
return
data
->
pixmap
;
escape
.
dc_rect
.
left
=
win_rect
->
left
-
top_rect
->
left
;
escape
.
dc_rect
.
top
=
win_rect
->
top
-
top_rect
->
top
;
escape
.
dc_rect
.
right
=
win_rect
->
right
-
top_rect
->
left
;
escape
.
dc_rect
.
bottom
=
win_rect
->
bottom
-
top_rect
->
top
;
escape
.
drawable_rect
.
left
=
top_rect
->
left
;
escape
.
drawable_rect
.
top
=
top_rect
->
top
;
escape
.
drawable_rect
.
right
=
top_rect
->
right
;
escape
.
drawable_rect
.
bottom
=
top_rect
->
bottom
;
ExtEscape
(
hdc
,
X11DRV_ESCAPE
,
sizeof
(
escape
),
(
LPSTR
)
&
escape
,
0
,
NULL
);
}
/***********************************************************************
* X11DRV_get_ic
*
* Return the X input context associated with a window
* X11DRV_ReleaseDC (X11DRV.@)
*/
XIC
X11DRV_get_ic
(
HWND
hwnd
)
void
X11DRV_ReleaseDC
(
HWND
hwnd
,
HDC
hdc
)
{
struct
x11drv_win_data
*
data
=
X11DRV_get_win_data
(
hwnd
);
if
(
!
data
)
return
0
;
return
data
->
xic
;
struct
x11drv_escape_set_drawable
escape
;
escape
.
code
=
X11DRV_SET_DRAWABLE
;
escape
.
drawable
=
root_window
;
escape
.
mode
=
IncludeInferiors
;
escape
.
drawable_rect
=
virtual_screen_rect
;
SetRect
(
&
escape
.
dc_rect
,
0
,
0
,
virtual_screen_rect
.
right
-
virtual_screen_rect
.
left
,
virtual_screen_rect
.
bottom
-
virtual_screen_rect
.
top
);
escape
.
fbconfig_id
=
0
;
escape
.
gl_drawable
=
0
;
escape
.
pixmap
=
0
;
ExtEscape
(
hdc
,
X11DRV_ESCAPE
,
sizeof
(
escape
),
(
LPSTR
)
&
escape
,
0
,
NULL
);
}
...
...
@@ -1708,7 +1728,6 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
if
((
data
=
X11DRV_get_win_data
(
hwnd
)))
{
sync_window_region
(
thread_display
(),
data
,
hrgn
);
invalidate_dce
(
hwnd
,
&
data
->
window_rect
);
}
else
if
(
GetWindowThreadProcessId
(
hwnd
,
NULL
)
!=
GetCurrentThreadId
())
{
...
...
dlls/winex11.drv/winex11.drv.spec
View file @
1642fbcb
...
...
@@ -96,11 +96,11 @@
@ cdecl EnumClipboardFormats(long) X11DRV_EnumClipboardFormats
@ cdecl GetClipboardData(long ptr ptr) X11DRV_GetClipboardData
@ cdecl GetClipboardFormatName(long ptr long) X11DRV_GetClipboardFormatName
@ cdecl GetDC
Ex(long long long) X11DRV_GetDCEx
@ cdecl GetDC
(long long long ptr ptr long) X11DRV_GetDC
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ cdecl RegisterClipboardFormat(wstr) X11DRV_RegisterClipboardFormat
@ cdecl ReleaseDC(long long
long
) X11DRV_ReleaseDC
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData
@ cdecl SetFocus(long) X11DRV_SetFocus
...
...
@@ -112,7 +112,6 @@
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
@ cdecl ShowWindow(long long) X11DRV_ShowWindow
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
@ cdecl WindowFromDC(long) X11DRV_WindowFromDC
@ cdecl WindowMessage(long long long long) X11DRV_WindowMessage
# WinTab32
...
...
dlls/winex11.drv/winpos.c
View file @
1642fbcb
...
...
@@ -141,15 +141,11 @@ void X11DRV_SetWindowStyle( HWND hwnd, DWORD old_style )
new_style
=
GetWindowLongW
(
hwnd
,
GWL_STYLE
);
changed
=
new_style
^
old_style
;
if
(
changed
&
WS_VISIBLE
)
if
(
(
changed
&
WS_VISIBLE
)
&&
(
new_style
&
WS_VISIBLE
)
)
{
data
=
X11DRV_get_win_data
(
hwnd
);
if
(
data
)
invalidate_dce
(
hwnd
,
&
data
->
window_rect
);
/* we don't unmap windows, that causes trouble with the window manager */
if
(
!
(
new_style
&
WS_VISIBLE
))
return
;
if
(
!
data
&&
!
(
data
=
X11DRV_create_win_data
(
hwnd
)))
return
;
if
(
!
(
data
=
X11DRV_get_win_data
(
hwnd
))
&&
!
(
data
=
X11DRV_create_win_data
(
hwnd
)))
return
;
if
(
data
->
whole_window
&&
X11DRV_is_window_rect_mapped
(
&
data
->
window_rect
))
{
...
...
@@ -361,15 +357,6 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
SERVER_END_REQ
;
}
/* invalidate DCEs */
if
((((
swp_flags
&
SWP_AGG_NOPOSCHANGE
)
!=
SWP_AGG_NOPOSCHANGE
)
&&
(
new_style
&
WS_VISIBLE
))
||
(
swp_flags
&
(
SWP_HIDEWINDOW
|
SWP_SHOWWINDOW
)))
{
RECT
rect
;
UnionRect
(
&
rect
,
rectWindow
,
&
old_window_rect
);
invalidate_dce
(
hwnd
,
&
rect
);
}
TRACE
(
"win %p window %s client %s style %08x
\n
"
,
hwnd
,
wine_dbgstr_rect
(
rectWindow
),
wine_dbgstr_rect
(
rectClient
),
new_style
);
...
...
@@ -788,8 +775,6 @@ void X11DRV_MapNotify( HWND hwnd, XEvent *event )
OffsetRect
(
&
rect
,
virtual_screen_rect
.
left
,
virtual_screen_rect
.
top
);
X11DRV_X_to_window_rect
(
data
,
&
rect
);
invalidate_dce
(
hwnd
,
&
data
->
window_rect
);
if
(
win
->
flags
&
WIN_RESTORE_MAX
)
style
|=
WS_MAXIMIZE
;
WIN_SetStyle
(
hwnd
,
style
,
WS_MINIMIZE
);
WIN_ReleasePtr
(
win
);
...
...
dlls/winex11.drv/x11drv.h
View file @
1642fbcb
...
...
@@ -492,12 +492,6 @@ struct x11drv_escape_set_drawable
Pixmap
pixmap
;
/* Pixmap for a GLXPixmap gl_drawable */
};
struct
x11drv_escape_set_dce
{
enum
x11drv_escape_codes
code
;
/* escape code (X11DRV_SET_DRAWABLE) */
struct
dce
*
dce
;
/* pointer to DCE (opaque ptr for GDI) */
};
/**************************************************************************
* X11 USER driver
*/
...
...
@@ -676,7 +670,6 @@ struct x11drv_win_data
BOOL
managed
:
1
;
/* is window managed? */
BOOL
mapped
:
1
;
/* is window mapped? (in either normal or iconic state) */
DWORD
wm_state
;
/* bit mask of active x11drv_wm_state values */
struct
dce
*
dce
;
/* DCE for CS_OWNDC or CS_CLASSDC windows */
unsigned
int
lock_changes
;
/* lock count for X11 change requests */
HBITMAP
hWMIconBitmap
;
HBITMAP
hWMIconMask
;
...
...
@@ -686,9 +679,6 @@ extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern
struct
x11drv_win_data
*
X11DRV_create_win_data
(
HWND
hwnd
);
extern
Window
X11DRV_get_whole_window
(
HWND
hwnd
);
extern
Window
X11DRV_get_client_window
(
HWND
hwnd
);
extern
XID
X11DRV_get_fbconfig_id
(
HWND
hwnd
);
extern
Drawable
X11DRV_get_gl_drawable
(
HWND
hwnd
);
extern
Pixmap
X11DRV_get_gl_pixmap
(
HWND
hwnd
);
extern
BOOL
X11DRV_is_window_rect_mapped
(
const
RECT
*
rect
);
extern
XIC
X11DRV_get_ic
(
HWND
hwnd
);
extern
BOOL
X11DRV_set_win_format
(
HWND
hwnd
,
XID
fbconfig
);
...
...
@@ -699,10 +689,6 @@ extern void mark_drawable_dirty( Drawable old, Drawable new );
extern
Drawable
create_glxpixmap
(
Display
*
display
,
XVisualInfo
*
vis
,
Pixmap
parent
);
extern
void
flush_gl_drawable
(
X11DRV_PDEVICE
*
physDev
);
extern
void
alloc_window_dce
(
struct
x11drv_win_data
*
data
);
extern
void
free_window_dce
(
struct
x11drv_win_data
*
data
);
extern
void
invalidate_dce
(
HWND
hwnd
,
const
RECT
*
rect
);
/* X context to associate a hwnd to an X window */
extern
XContext
winContext
;
...
...
include/win.h
View file @
1642fbcb
...
...
@@ -38,6 +38,7 @@ typedef struct tagWND
HWND
parent
;
/* Window parent */
HWND
owner
;
/* Window owner */
struct
tagCLASS
*
class
;
/* Window class */
struct
dce
*
dce
;
/* DCE pointer */
WNDPROC
winproc
;
/* Window procedure */
DWORD
dwMagic
;
/* Magic number (must be WND_MAGIC) */
DWORD
tid
;
/* Owner thread id */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment