1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "dcscreen.h"
14 #include "wx/dcscreen.h"
15 #include "wx/window.h"
17 //-----------------------------------------------------------------------------
18 // global data initialization
19 //-----------------------------------------------------------------------------
21 GdkWindow
*wxScreenDC::sm_overlayWindow
= (GdkWindow
*) NULL
;
22 int wxScreenDC::sm_overlayWindowX
= 0;
23 int wxScreenDC::sm_overlayWindowY
= 0;
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
33 #include "gdk/gdkprivate.h"
35 #include <netinet/in.h>
37 int nevent_masks
= 17;
38 int event_mask_table
[19] =
42 PointerMotionHintMask
,
47 ButtonPressMask
| OwnerGrabButtonMask
,
48 ButtonReleaseMask
| OwnerGrabButtonMask
,
62 gdk_window_transparent_new ( GdkWindow
*parent
,
63 GdkWindowAttr
*attributes
,
67 GdkWindowPrivate
*gprivate
;
68 GdkWindowPrivate
*parent_private
;
70 Display
*parent_display
;
73 XSetWindowAttributes xattributes
;
74 long xattributes_mask
;
75 XSizeHints size_hints
;
77 XClassHint
*class_hint
;
83 g_return_val_if_fail (attributes
!= NULL
, NULL
);
86 parent
= (GdkWindow
*) &gdk_root_parent
;
88 parent_private
= (GdkWindowPrivate
*) parent
;
89 if (parent_private
->destroyed
)
92 xparent
= parent_private
->xwindow
;
93 parent_display
= parent_private
->xdisplay
;
95 gprivate
= g_new (GdkWindowPrivate
, 1);
96 window
= (GdkWindow
*) gprivate
;
98 gprivate
->parent
= parent
;
100 if (parent_private
!= &gdk_root_parent
)
101 parent_private
->children
= g_list_prepend (parent_private
->children
, window
);
103 gprivate
->xdisplay
= parent_display
;
104 gprivate
->destroyed
= FALSE
;
105 gprivate
->resize_count
= 0;
106 gprivate
->ref_count
= 1;
107 xattributes_mask
= 0;
109 if (attributes_mask
& GDK_WA_X
)
114 if (attributes_mask
& GDK_WA_Y
)
121 gprivate
->width
= (attributes
->width
> 1) ? (attributes
->width
) : (1);
122 gprivate
->height
= (attributes
->height
> 1) ? (attributes
->height
) : (1);
123 gprivate
->window_type
= attributes
->window_type
;
124 gprivate
->extension_events
= FALSE
;
125 gprivate
->dnd_drag_data_type
= None
;
126 gprivate
->dnd_drag_data_typesavail
=
127 gprivate
->dnd_drop_data_typesavail
= NULL
;
128 gprivate
->dnd_drop_enabled
= gprivate
->dnd_drag_enabled
=
129 gprivate
->dnd_drag_accepted
= gprivate
->dnd_drag_datashow
=
130 gprivate
->dnd_drop_data_numtypesavail
=
131 gprivate
->dnd_drag_data_numtypesavail
= 0;
132 gprivate
->dnd_drag_eventmask
= gprivate
->dnd_drag_savedeventmask
= 0;
134 gprivate
->filters
= NULL
;
135 gprivate
->children
= NULL
;
137 window
->user_data
= NULL
;
139 if (attributes_mask
& GDK_WA_VISUAL
)
140 visual
= attributes
->visual
;
142 visual
= gdk_visual_get_system ();
143 xvisual
= ((GdkVisualPrivate
*) visual
)->xvisual
;
145 xattributes
.event_mask
= StructureNotifyMask
;
146 for (i
= 0; i
< nevent_masks
; i
++)
148 if (attributes
->event_mask
& (1 << (i
+ 1)))
149 xattributes
.event_mask
|= event_mask_table
[i
];
152 if (xattributes
.event_mask
)
153 xattributes_mask
|= CWEventMask
;
155 if(attributes_mask
& GDK_WA_NOREDIR
) {
156 xattributes
.override_redirect
=
157 (attributes
->override_redirect
== FALSE
)?False
:True
;
158 xattributes_mask
|= CWOverrideRedirect
;
160 xattributes
.override_redirect
= False
;
162 gclass
= InputOutput
;
163 depth
= visual
->depth
;
165 if (attributes_mask
& GDK_WA_COLORMAP
)
166 gprivate
->colormap
= attributes
->colormap
;
168 gprivate
->colormap
= gdk_colormap_get_system ();
170 xattributes
.colormap
= ((GdkColormapPrivate
*) gprivate
->colormap
)->xcolormap
;
171 xattributes_mask
|= CWColormap
;
173 xparent
= gdk_root_window
;
175 xattributes
.save_under
= True
;
176 xattributes
.override_redirect
= True
;
177 xattributes
.cursor
= None
;
178 xattributes_mask
|= CWSaveUnder
| CWOverrideRedirect
;
180 gprivate
->xwindow
= XCreateWindow (gprivate
->xdisplay
, xparent
,
181 x
, y
, gprivate
->width
, gprivate
->height
,
182 0, depth
, gclass
, xvisual
,
183 xattributes_mask
, &xattributes
);
184 gdk_window_ref (window
);
185 gdk_xid_table_insert (&gprivate
->xwindow
, window
);
187 if (gprivate
->colormap
)
188 gdk_colormap_ref (gprivate
->colormap
);
190 XSetWMProtocols (gprivate
->xdisplay
, gprivate
->xwindow
, gdk_wm_window_protocols
, 2);
192 size_hints
.flags
= PSize
;
193 size_hints
.width
= gprivate
->width
;
194 size_hints
.height
= gprivate
->height
;
196 wm_hints
.flags
= InputHint
| StateHint
| WindowGroupHint
;
197 wm_hints
.window_group
= gdk_leader_window
;
198 wm_hints
.input
= True
;
199 wm_hints
.initial_state
= NormalState
;
201 /* FIXME: Is there any point in doing this? Do any WM's pay
202 * attention to PSize, and even if they do, is this the
205 XSetWMNormalHints (gprivate
->xdisplay
, gprivate
->xwindow
, &size_hints
);
207 XSetWMHints (gprivate
->xdisplay
, gprivate
->xwindow
, &wm_hints
);
209 if (attributes_mask
& GDK_WA_TITLE
)
210 title
= attributes
->title
;
212 #if (GTK_MINOR_VERSION == 1)
213 title
= "Unknown"; // GLH: Well I don't know for the moment what to write here.
215 title
= gdk_progname
;
218 XmbSetWMProperties (gprivate
->xdisplay
, gprivate
->xwindow
,
223 if (attributes_mask
& GDK_WA_WMCLASS
)
225 class_hint
= XAllocClassHint ();
226 class_hint
->res_name
= attributes
->wmclass_name
;
227 class_hint
->res_class
= attributes
->wmclass_class
;
228 XSetClassHint (gprivate
->xdisplay
, gprivate
->xwindow
, class_hint
);
237 //-----------------------------------------------------------------------------
239 //-----------------------------------------------------------------------------
241 IMPLEMENT_DYNAMIC_CLASS(wxScreenDC
,wxPaintDC
)
243 wxScreenDC::wxScreenDC(void)
246 m_window
= (GdkWindow
*) NULL
;
247 m_cmap
= gdk_colormap_get_system();
249 if (sm_overlayWindow
)
251 m_window
= sm_overlayWindow
;
252 m_deviceOriginX
= - sm_overlayWindowX
;
253 m_deviceOriginY
= - sm_overlayWindowY
;
256 m_window
= GDK_ROOT_PARENT();
260 gdk_gc_set_subwindow( m_penGC
, GDK_INCLUDE_INFERIORS
);
261 gdk_gc_set_subwindow( m_brushGC
, GDK_INCLUDE_INFERIORS
);
262 gdk_gc_set_subwindow( m_textGC
, GDK_INCLUDE_INFERIORS
);
263 gdk_gc_set_subwindow( m_bgGC
, GDK_INCLUDE_INFERIORS
);
266 wxScreenDC::~wxScreenDC(void)
271 bool wxScreenDC::StartDrawingOnTop( wxWindow
*window
)
273 if (!window
) return StartDrawingOnTop();
277 window
->GetPosition( &x
, &y
);
280 window
->GetSize( &w
, &h
);
281 window
->ClientToScreen( &x
, &y
);
289 return StartDrawingOnTop( &rect
);
292 bool wxScreenDC::StartDrawingOnTop( wxRectangle
*rect
)
296 int width
= gdk_screen_width();
297 int height
= gdk_screen_height();
303 height
= rect
->height
;
306 sm_overlayWindowX
= x
;
307 sm_overlayWindowY
= y
;
313 attr
.height
= height
;
314 attr
.override_redirect
= TRUE
;
315 attr
.wclass
= GDK_INPUT_OUTPUT
;
317 attr
.window_type
= GDK_WINDOW_TEMP
;
319 // GTK cannot set transparent backgrounds. :-(
320 sm_overlayWindow
= gdk_window_transparent_new( NULL
, &attr
, GDK_WA_NOREDIR
| GDK_WA_X
| GDK_WA_Y
);
322 if (sm_overlayWindow
) gdk_window_show( sm_overlayWindow
);
324 return (sm_overlayWindow
);
327 bool wxScreenDC::EndDrawingOnTop(void)
329 if (sm_overlayWindow
) gdk_window_destroy( sm_overlayWindow
);
331 sm_overlayWindow
= NULL
;
332 sm_overlayWindowX
= 0;
333 sm_overlayWindowY
= 0;