source: trunk/src/kernel/qwidget_pm.cpp@ 61

Last change on this file since 61 was 61, checked in by dmik, 20 years ago

Implemented QRegion(..., QRegion::Eclipse) and QRegion(QPointArray &,...) constructors.
Improved Qt<->GPI region coordinates translation (it's now implicit), QRegion::handle() takes a height of the target devise as an argument (defaults to 0).

  • Property svn:keywords set to Id
File size: 60.9 KB
Line 
1/****************************************************************************
2** $Id: qwidget_pm.cpp 61 2006-02-06 21:43:39Z dmik $
3**
4** Implementation of QWidget and QWindow classes for OS/2
5**
6** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qapplication.h"
39#include "qapplication_p.h"
40#include "qpainter.h"
41#include "qbitmap.h"
42#include "qwidgetlist.h"
43#include "qwidgetintdict.h"
44#include "qobjectlist.h"
45#include "qaccel.h"
46#include "qimage.h"
47#include "qfocusdata.h"
48#include "qlayout.h"
49#include "qt_os2.h"
50#include "qpaintdevicemetrics.h"
51#include "qcursor.h"
52#include <private/qapplication_p.h>
53//@@TODO (dmik): remove?
54//#include <private/qinputcontext_p.h>
55
56const QString qt_reg_winclass( int ); // defined in qapplication_pm.cpp
57//@@TODO (dmik): later?
58//void qt_olednd_unregister( QWidget* widget, QOleDropTarget *dst ); // dnd_win
59//QOleDropTarget* qt_olednd_register( QWidget* widget );
60
61
62extern bool qt_nograb();
63//@@TODO (dmik): later (qregion_pm.cpp)
64//extern HRGN qt_win_bitmapToRegion(const QBitmap& bitmap);
65
66// defined in qapplication_pm.cpp
67extern void qt_sendBlocked( QObject *obj, QWidget *modal, QEvent *e, bool override );
68
69static QWidget *mouseGrb = 0;
70static QCursor *mouseGrbCur = 0;
71static QWidget *keyboardGrb = 0;
72
73extern "C" MRESULT EXPENTRY QtWndProc( HWND, ULONG, MPARAM, MPARAM );
74extern PFNWP QtOldFrameProc;
75extern "C" MRESULT EXPENTRY QtFrameProc( HWND, ULONG, MPARAM, MPARAM );
76
77PFNWP QtOldSysMenuProc;
78extern "C" MRESULT EXPENTRY QtSysMenuProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
79{
80 if ( msg == WM_MENUEND ) {
81 // the pull-down menu is closed, always dismiss the system menu itself
82 WinPostMsg( hwnd, MM_ENDMENUMODE, MPFROMSHORT(TRUE), 0 );
83 }
84 return QtOldSysMenuProc( hwnd, msg, mp1, mp2 );
85}
86
87static void removeSysMenuAccels( HWND frame )
88{
89 HWND sysMenu = WinWindowFromID( frame, FID_SYSMENU );
90 if ( !sysMenu )
91 return;
92
93 SHORT subId = SHORT1FROMMR( WinSendMsg( sysMenu, MM_ITEMIDFROMPOSITION, 0, 0 ) );
94 if ( subId != MIT_ERROR ) {
95 MENUITEM item;
96 WinSendMsg( sysMenu, MM_QUERYITEM, MPFROM2SHORT(subId, FALSE), MPFROMP(&item) );
97 HWND subMenu = item.hwndSubMenu;
98 if ( subMenu ) {
99 USHORT cnt = SHORT1FROMMR( WinSendMsg( subMenu, MM_QUERYITEMCOUNT, 0, 0 ) );
100 for ( int i = 0; i < cnt; i++ ) {
101 USHORT id = SHORT1FROMMR(
102 WinSendMsg( subMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0 ) );
103 if ( id == SC_TASKMANAGER || id == SC_CLOSE ) {
104 // accels for these entries always work in Qt, skip them
105 continue;
106 }
107 USHORT len = SHORT1FROMMR(
108 WinSendMsg( subMenu, MM_QUERYITEMTEXTLENGTH, MPFROMSHORT(id), 0 ) );
109 if ( len++ ) {
110 char *text = new char[len];
111 WinSendMsg( subMenu, MM_QUERYITEMTEXT,
112 MPFROM2SHORT(id, len), MPFROMP(text) );
113 char *tab = strrchr( text, '\t' );
114 if ( tab ) {
115 *tab = 0;
116 WinSendMsg( subMenu, MM_SETITEMTEXT,
117 MPFROMSHORT(id), MPFROMP(text) );
118 }
119 delete[] text;
120 }
121 }
122 // sublclass the system menu to leave the menu mode completely
123 // when the user presses the ESC key. by default, pressing ESC
124 // while the pull-down menu is showing brings us to the menu bar,
125 // which is confusing in the case of the system menu, because
126 // there is only one item on the menu bar, and we cannot see
127 // that it is active when the frame window has an icon.
128 PFNWP oldProc = WinSubclassWindow( sysMenu, QtSysMenuProc );
129 // set QtOldSysMenuProc only once: it must be the same for
130 // all FID_SYSMENU windows.
131 if ( !QtOldSysMenuProc )
132 QtOldSysMenuProc = oldProc;
133 }
134 }
135}
136
137/*****************************************************************************
138 QWidget member functions
139 *****************************************************************************/
140
141//#define QT_DEBUGWINCREATEDESTROY
142
143void QWidget::create( WId window, bool initializeWindow, bool destroyOldWindow )
144{
145 // When window is not zero, it represents an existing (external) window
146 // handle we should create a QWidget "wrapper" for to incorporate it to the
147 // Qt widget hierarchy. But so far I have never seen this method called
148 // with window != 0, so we ignore this argument (as well as the other two
149 // that make sense only together with it) for now and will not implement
150 // this functionality until there's a real need.
151
152 Q_ASSERT( window == 0 );
153 Q_UNUSED( initializeWindow );
154 Q_UNUSED( destroyOldWindow );
155
156 if ( testWState(WState_Created) && window == 0 )
157 return;
158 setWState( WState_Created ); // set created flag
159
160 if ( !parentWidget() || parentWidget()->isDesktop() )
161 setWFlags( WType_TopLevel ); // top-level widget
162
163 static int sw = -1, sh = -1;
164
165 bool topLevel = testWFlags(WType_TopLevel);
166 bool popup = testWFlags(WType_Popup);
167 bool dialog = testWFlags(WType_Dialog);
168 bool desktop = testWFlags(WType_Desktop);
169 WId id = 0;
170
171 if ( popup ) {
172 /// @todo (dmik) WStyle_StaysOnTop is ignored for now (does nothing)
173 setWFlags(WStyle_StaysOnTop); // a popup stays on top
174 }
175
176 if ( sw < 0 ) { // get the screen size
177 sw = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
178 sh = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
179 }
180
181 if ( dialog || popup || desktop ) { // these are top-level, too
182 topLevel = TRUE;
183 setWFlags( WType_TopLevel );
184 }
185
186 if ( desktop ) { // desktop widget
187 popup = FALSE; // force this flags off
188 /// @todo (dmik)
189 // use WinGetMaxPosition () to take into account such things as XCenter?
190 crect.setRect( 0, 0, sw, sh );
191 }
192
193 PCSZ title = NULL;
194 ULONG style = 0;
195 ULONG fId = 0, fStyle = 0, fcFlags = 0;
196
197 if ( popup ) {
198 style |= WS_SAVEBITS;
199 } else if ( !topLevel ) {
200 if ( !testWFlags(WStyle_Customize) )
201 setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_MinMax | WStyle_SysMenu );
202 } else if (!desktop ) {
203 if ( !testWFlags(WStyle_Customize) ) {
204 if ( testWFlags(WStyle_Tool) ) {
205 // a special case for WStyle_Tool w/o WStyle_Customize.
206 // it violates the Qt docs but it is used by QPopupMenu
207 // to create torn-off menus.
208 setWFlags( WStyle_Title );
209 } else {
210 if ( dialog )
211 setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu );
212 else
213 setWFlags( WStyle_NormalBorder | WStyle_Title | WStyle_MinMax | WStyle_SysMenu );
214 }
215 }
216 }
217 if ( !desktop ) {
218 /// @todo (dmik)
219 // this is temporarily commented out because QSplitter sets
220 // WPaintUnclipped which causes terrible flicker in QFileDialog's list
221 // box and list view. This needs to be investigated. Qt/Win32 does also
222 // comment this out...
223 /* if ( !testWFlags( WPaintUnclipped ) ) */
224 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
225 // for all top-level windows except popups we create a WC_FRAME
226 // as a parent and owner.
227 if ( topLevel && !popup ) {
228 if ( !testWFlags(WStyle_NoBorder) ) {
229 if ( testWFlags(WStyle_NormalBorder) ) {
230 fcFlags |= FCF_SIZEBORDER;
231 } else if ( testWFlags(WStyle_DialogBorder) ) {
232 fcFlags |= FCF_DLGBORDER;
233 } else if ( testWFlags(WStyle_Tool) ) {
234 fcFlags |= FCF_BORDER;
235 }
236 }
237 if ( testWFlags(WStyle_Title) )
238 fcFlags |= FCF_TITLEBAR;
239 if ( testWFlags(WStyle_SysMenu) )
240 fcFlags |= FCF_SYSMENU | FCF_CLOSEBUTTON;
241 if ( testWFlags(WStyle_Minimize) )
242 fcFlags |= FCF_MINBUTTON;
243 if ( testWFlags(WStyle_Maximize) )
244 fcFlags |= FCF_MAXBUTTON;
245 fStyle |= FS_NOMOVEWITHOWNER | FS_NOBYTEALIGN;
246 fStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
247 }
248 }
249 if ( testWFlags(WStyle_Title) ) {
250 title = topLevel ? qAppName() : name();
251 }
252
253 // The WState_Created flag is checked by translateConfigEvent() in
254 // qapplication_pm.cpp. We switch it off temporarily to avoid move
255 // and resize events during creation
256 clearWState( WState_Created );
257
258 QString className = qt_reg_winclass( getWFlags() );
259 PCSZ pszClassName = className.latin1();
260
261 if ( desktop ) { // desktop widget
262 id = WinQueryDesktopWindow( 0, 0 );
263 QWidget *otherDesktop = find( id ); // is there another desktop?
264 if ( otherDesktop && otherDesktop->testWFlags(WPaintDesktop) ) {
265 otherDesktop->setWinId( 0 ); // remove id from widget mapper
266 setWinId( id ); // make sure otherDesktop is
267 otherDesktop->setWinId( id ); // found first
268 } else {
269 setWinId( id );
270 }
271 } else if ( topLevel ) {
272 // create top-level widget
273 HWND ownerw = 0;
274 if ( !popup ) {
275 QWidget *p = parentWidget();
276 if ( p && !p->isDesktop() )
277 ownerw = p->topLevelWidget()->winFId();
278 }
279
280 if ( !popup ) {
281 // create WC_FRAME
282 FRAMECDATA fcData;
283 fcData.cb = sizeof(FRAMECDATA);
284 fcData.flCreateFlags = fcFlags;
285 fcData.hmodResources = NULL;
286 fcData.idResources = 0;
287#if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY)
288 qDebug(
289 "|Creating top level window [%s] (frame):\n"
290 "| owner = %08lX\n"
291 "| title = '%s'\n"
292 "| style = %08lX\n"
293 "| fcFlags = %08lX",
294 name(), ownerw, title, fStyle, fcFlags
295 );
296#endif
297 fId = WinCreateWindow(
298 HWND_DESKTOP, WC_FRAME, title, fStyle, 0, 0, 0, 0,
299 ownerw, HWND_TOP, 0, &fcData, NULL
300 );
301#ifndef QT_NO_DEBUG
302#ifdef QT_DEBUGWINCREATEDESTROY
303 qDebug( "| hwnd = %08lX", fId );
304#endif
305 if ( fId == 0 )
306 qSystemWarning( "QWidget: Failed to create frame window" );
307#endif
308 PFNWP oldProc = WinSubclassWindow( fId, QtFrameProc );
309 // set QtOldFrameProc only once: it must be the same for
310 // all WC_FRAME windows.
311 if ( !QtOldFrameProc )
312 QtOldFrameProc = oldProc;
313
314 removeSysMenuAccels( fId );
315
316 // create client
317#if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY)
318 qDebug(
319 "|Creating top level window [%s] (client):\n"
320 "| owner & parent = %08lX\n"
321 "| class = '%s'\n"
322 "| title = '%s'\n"
323 "| style = %08lX",
324 name(), fId, pszClassName, title, style
325 );
326#endif
327 id = WinCreateWindow(
328 fId, pszClassName, title, style, 0, 0, 0, 0,
329 fId, HWND_BOTTOM, FID_CLIENT, NULL, NULL
330 );
331 } else {
332#if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY)
333 qDebug(
334 "|Creating top level window [%s]:\n"
335 "| owner = %08lX\n"
336 "| class = '%s'\n"
337 "| title = '%s'\n"
338 "| style = %08lX",
339 name(), ownerw, pszClassName, title, style
340 );
341#endif
342 id = WinCreateWindow(
343 HWND_DESKTOP, pszClassName, title, style, 0, 0, 0, 0,
344 ownerw, HWND_TOP, 0, NULL, NULL
345 );
346 }
347#ifndef QT_NO_DEBUG
348#ifdef QT_DEBUGWINCREATEDESTROY
349 qDebug( "| hwnd = %08lX", id );
350#endif
351 if ( id == 0 )
352 qSystemWarning( "QWidget: Failed to create window" );
353#endif
354 setWinId( id );
355 /// @todo (dmik) WStyle_StaysOnTop is ignored for now (does nothing)
356/*
357 if ( testWFlags( WStyle_StaysOnTop) )
358 SetWindowPos( id, HWND_TOPMOST, 0, 0, 100, 100, SWP_NOACTIVATE );
359*/
360
361 // When the FS_SHELLPOSITION flag is specified during WC_FRAME window
362 // creation its size and position remains zero until it is shown
363 // for the first time. So, we don't use FS_SHELLPOSITION but emulate
364 // its functionality here.
365 SWP swp;
366 WinQueryTaskSizePos( 0, 0, &swp );
367 WinSetWindowPos( fId, 0, swp.x, swp.y, swp.cx, swp.cy, SWP_SIZE | SWP_MOVE );
368 } else {
369 // create child widget
370 HWND parentw = parentWidget()->winId();
371#if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY)
372 qDebug(
373 "|Creating child window [%s]:\n"
374 "| owner & parent = %08lX\n"
375 "| class = '%s'\n"
376 "| title = '%s'\n"
377 "| style = %08lX",
378 name(), parentw, pszClassName, title, style
379 );
380#endif
381 id = WinCreateWindow(
382 parentw, pszClassName, title, style,
383 0, parentWidget()->crect.height() - 30, 100, 30,
384 parentw, HWND_TOP, 0, NULL, NULL
385 );
386#ifndef QT_NO_DEBUG
387#ifdef QT_DEBUGWINCREATEDESTROY
388 qDebug( "| hwnd = %08lX", id );
389#endif
390 if ( id == 0 )
391 qSystemWarning( "QWidget: Failed to create window" );
392#endif
393 setWinId( id );
394 }
395
396 if ( desktop ) {
397 setWState( WState_Visible );
398 } else {
399 SWP cswp;
400 WinQueryWindowPos( id, &cswp );
401 if ( topLevel ) {
402 QTLWExtra *top = topData();
403 if ( fId ) {
404 SWP fswp;
405 WinQueryWindowPos( fId, &fswp );
406 // flip y coordinates
407 fswp.y = sh - (fswp.y + fswp.cy);
408 cswp.y = fswp.cy - (cswp.y + cswp.cy);
409 crect.setRect(
410 fswp.x + cswp.x, fswp.y + cswp.y,
411 cswp.cx, cswp.cy
412 );
413
414 top->fleft = cswp.x;
415 top->ftop = cswp.y;
416 top->fright = fswp.cx - cswp.x - cswp.cx;
417 top->fbottom = fswp.cy - cswp.y - cswp.cy;
418 top->fId = fId;
419 } else {
420 // flip y coordinate
421 cswp.y = sh - (cswp.y + cswp.cy);
422 crect.setRect( cswp.x, cswp.y, cswp.cx, cswp.cy );
423 }
424 fstrut_dirty = FALSE;
425 } else {
426 int cy = parentWidget()->crect.height();
427 // flip y coordinate
428 cswp.y = cy - (cswp.y + cswp.cy);
429 crect.setRect( cswp.x, cswp.y, cswp.cx, cswp.cy );
430 }
431 }
432
433 setWState( WState_Created ); // accept move/resize events
434 hps = 0; // no presentation space
435
436 setFontSys();
437
438/// @todo (dmik) remove?
439// QInputContext::enable( this, im_enabled & !((bool)testWState(WState_Disabled)) );
440}
441
442
443void QWidget::destroy( bool destroyWindow, bool destroySubWindows )
444{
445 deactivateWidgetCleanup();
446 if ( testWState(WState_Created) ) {
447 clearWState( WState_Created );
448 if ( children() ) {
449 QObjectListIt it(*children());
450 register QObject *obj;
451 while ( (obj=it.current()) ) { // destroy all widget children
452 ++it;
453 if ( obj->isWidgetType() )
454 ((QWidget*)obj)->destroy(destroySubWindows,
455 destroySubWindows);
456 }
457 }
458 if ( mouseGrb == this )
459 releaseMouse();
460 if ( keyboardGrb == this )
461 releaseKeyboard();
462 if ( testWFlags(WShowModal) ) // just be sure we leave modal
463 qt_leave_modal( this );
464 else if ( testWFlags(WType_Popup) )
465 qApp->closePopup( this );
466 if ( destroyWindow && !testWFlags(WType_Desktop) ) {
467 HWND id = winId();
468 if ( isTopLevel() && !testWFlags(WType_Popup) ) {
469 // extra data including extra->topextra has been already
470 // deleted at this point by deleteExtra() and therefore
471 // calling winFId() useless -- it will always return the
472 // client window handle. Use WinQueryWindow() instead.
473 id = WinQueryWindow( id, QW_PARENT );
474 }
475#if !defined(QT_NO_DEBUG) && defined(QT_DEBUGWINCREATEDESTROY)
476 qDebug(
477 "|Destroying window:\n"
478 "| hwnd = %08lX",
479 id
480 );
481#endif
482 WinDestroyWindow( id );
483 }
484 setWinId( 0 );
485 }
486}
487
488void QWidget::reparentSys( QWidget *parent, WFlags f, const QPoint &p,
489 bool showIt )
490{
491 QWidget* oldtlw = topLevelWidget();
492 WId old_winfid = winFId();
493
494 // hide and reparent our own window away. Otherwise we might get
495 // destroyed when emitting the child remove event below. See QWorkspace.
496 // this is also necessary for modal windows to leave the modal state
497 // correctly.
498 if ( isVisible() ) {
499 hide();
500 WinSetParent( old_winfid, HWND_OBJECT, FALSE );
501 WinSetOwner( old_winfid, 0 );
502 }
503
504 // unblock the widget if blocked
505 QWidget *blockedBy = 0;
506 if ( isTopLevel() )
507 blockedBy = (QWidget*) WinQueryWindowULong( winId(), QWL_QTMODAL );
508 if ( !blockedBy && parentWidget() )
509 blockedBy = (QWidget*) WinQueryWindowULong(
510 parentWidget()->topLevelWidget()->winId(), QWL_QTMODAL );
511 if ( blockedBy ) {
512 QEvent e( QEvent::WindowUnblocked );
513 qt_sendBlocked( this, blockedBy, &e, FALSE );
514 }
515
516 bool accept_drops = acceptDrops();
517 if ( accept_drops )
518 setAcceptDrops( FALSE ); // ole dnd unregister (we will register again below)
519 if ( testWFlags(WType_Desktop) )
520 old_winfid = 0;
521 setWinId( 0 );
522 if ( isTopLevel() ) {
523 QTLWExtra *top = topData();
524 if ( top->swEntry ) {
525 WinRemoveSwitchEntry( top->swEntry );
526 top->swEntry = 0;
527 }
528 top->fId = 0;
529 }
530
531 if ( parent != parentObj ) {
532 if ( parentObj ) // remove from parent
533 parentObj->removeChild( this );
534 if ( parent ) // insert into new parent
535 parent->insertChild( this );
536 }
537
538 bool enable = isEnabled(); // remember status
539 FocusPolicy fp = focusPolicy();
540 QSize s = size();
541 QString capt = caption();
542 widget_flags = f;
543 clearWState( WState_Created | WState_Visible | WState_ForceHide );
544 create();
545 if ( isTopLevel() || (!parent || parent->isVisible() ) )
546 setWState( WState_ForceHide ); // new widgets do not show up in already visible parents
547 const QObjectList *chlist = children();
548 if ( chlist ) { // reparent children
549 SWP swp;
550 QObjectListIt it( *chlist );
551 QObject *obj;
552 while ( (obj=it.current()) ) {
553 if ( obj->isWidgetType() ) {
554 QWidget *w = (QWidget *)obj;
555 if ( w->isPopup() )
556 ;
557 else if ( w->isTopLevel() ) {
558 w->reparent( this, w->getWFlags(), w->pos(), !w->isHidden() );
559 } else {
560 WinSetParent( w->winId(), winId(), FALSE );
561 WinSetOwner( w->winId(), winId() );
562 // bring PM coords into accordance with Qt coords,
563 // otherwise setGeometry() below will wrongly position
564 // children if this widget manages their layout.
565 int hd = height() - s.height();
566 WinQueryWindowPos( w->winId(), &swp );
567 swp.y += hd;
568 WinSetWindowPos( w->winId(), 0, swp.x, swp.y, 0, 0, SWP_MOVE );
569 }
570 }
571 ++it;
572 }
573 }
574
575 // block the widget if it should be blocked
576 blockedBy = 0;
577 if ( parentWidget() )
578 blockedBy = (QWidget*) WinQueryWindowULong(
579 parentWidget()->topLevelWidget()->winId(), QWL_QTMODAL );
580 if ( blockedBy ) {
581 if ( isTopLevel() && testWFlags( WGroupLeader ) )
582 blockedBy = 0;
583 } else {
584 QWidget *topModal = qApp->activeModalWidget();
585 if (
586 topModal && this != topModal && parentWidget() != topModal &&
587 isTopLevel() && !testWFlags( WGroupLeader )
588 )
589 blockedBy = topModal;
590 }
591 if ( blockedBy ) {
592 QEvent e( QEvent::WindowBlocked );
593 qt_sendBlocked( this, blockedBy, &e, FALSE );
594 }
595
596 setGeometry( p.x(), p.y(), s.width(), s.height() );
597 setEnabled( enable );
598 setFocusPolicy( fp );
599 if ( !capt.isNull() ) {
600 extra->topextra->caption = QString::null;
601 setCaption( capt );
602 }
603 if ( showIt )
604 show();
605 if ( old_winfid )
606 WinDestroyWindow( old_winfid );
607
608 reparentFocusWidgets( oldtlw ); // fix focus chains
609
610 if ( accept_drops )
611 setAcceptDrops( TRUE );
612
613//@@TODO (dmik): remove?
614//#ifdef Q_OS_TEMP
615// // Show borderless toplevel windows in tasklist & NavBar
616// if ( !parent ) {
617// QString txt = caption().isEmpty()?qAppName():caption();
618// SetWindowText( winId(), (TCHAR*)txt.ucs2() );
619// }
620//#endif
621}
622
623QPoint QWidget::mapToGlobal( const QPoint &pos ) const
624{
625 if ( !isVisible() || isMinimized() )
626 return mapTo( topLevelWidget(), pos ) + topLevelWidget()->pos() +
627 (topLevelWidget()->geometry().topLeft() - topLevelWidget()->frameGeometry().topLeft());
628 POINTL ptl;
629 ptl.x = pos.x();
630 // flip y (local) coordinate
631 ptl.y = height() - (pos.y() + 1);
632 WinMapWindowPoints( winId(), HWND_DESKTOP, &ptl, 1 );
633 // flip y (global) coordinate
634 ptl.y = QApplication::desktop()->height() - (ptl.y + 1);
635 return QPoint( ptl.x, ptl.y );
636}
637
638QPoint QWidget::mapFromGlobal( const QPoint &pos ) const
639{
640 if ( !isVisible() || isMinimized() )
641 return mapFrom( topLevelWidget(), pos - topLevelWidget()->pos() );
642 POINTL ptl;
643 ptl.x = pos.x();
644 // flip y (global) coordinate
645 ptl.y = QApplication::desktop()->height() - (pos.y() + 1);
646 WinMapWindowPoints( HWND_DESKTOP, winId(), &ptl, 1 );
647 // flip y (local) coordinate
648 ptl.y = height() - (ptl.y + 1);
649 return QPoint( ptl.x, ptl.y );
650}
651
652void QWidget::setFontSys( QFont *f )
653{
654//@@TODO (dmik): should this do something on OS/2?
655//@@TODO (dmik): remove?
656// QInputContext::setFont( this, (f ? *f : font()) );
657}
658
659void QWidget::setMicroFocusHint(int x, int y, int width, int height, bool text, QFont *f)
660{
661//@@TODO (dmik): do we need to create a caret (cursor) in OS/2 also?
662// currently, try to do so (which can be useful for 3rd-party apps
663// that are interested in the current cursor position, i.e. where the user
664// input is now taking place.
665 // flip y coordinate
666 int fy = crect.height() - (y + height);
667 WinCreateCursor( winId(), x, fy, width, height, CURSOR_SOLID, NULL );
668
669//@@TODO (dmik): remove?
670// if ( text )
671// QInputContext::setFocusHint( x, y, width, height, this );
672 setFontSys( f );
673
674 if ( QRect( x, y, width, height ) != microFocusHint() )
675 extraData()->micro_focus_hint.setRect( x, y, width, height );
676}
677
678void QWidget::resetInputContext()
679{
680//@@TODO (dmik): remove?
681// QInputContext::accept();
682}
683
684void QWidget::setBackgroundColorDirect( const QColor &color )
685{
686 bg_col = color;
687 if ( extra && extra->bg_pix ) { // kill the background pixmap
688 delete extra->bg_pix;
689 extra->bg_pix = 0;
690 }
691}
692
693
694static int allow_null_pixmaps = 0;
695
696
697void QWidget::setBackgroundPixmapDirect( const QPixmap &pixmap )
698{
699 QPixmap old;
700 if ( extra && extra->bg_pix )
701 old = *extra->bg_pix;
702 if ( !allow_null_pixmaps && pixmap.isNull() ) {
703 if ( extra && extra->bg_pix ) {
704 delete extra->bg_pix;
705 extra->bg_pix = 0;
706 }
707 } else {
708 if ( extra && extra->bg_pix )
709 delete extra->bg_pix;
710 else
711 createExtra();
712 extra->bg_pix = new QPixmap( pixmap );
713 }
714}
715
716
717void QWidget::setBackgroundEmpty()
718{
719 allow_null_pixmaps++;
720 setErasePixmap(QPixmap());
721 allow_null_pixmaps--;
722}
723
724extern void qt_set_cursor( QWidget *, const QCursor & ); // qapplication_pm.cpp
725
726void QWidget::setCursor( const QCursor &cursor )
727{
728 if ( cursor.handle() != arrowCursor.handle()
729 || (extra && extra->curs) ) {
730 createExtra();
731 delete extra->curs;
732 extra->curs = new QCursor(cursor);
733 }
734 setWState( WState_OwnCursor );
735 qt_set_cursor( this, QWidget::cursor() );
736}
737
738void QWidget::unsetCursor()
739{
740 if ( extra ) {
741 delete extra->curs;
742 extra->curs = 0;
743 }
744 if ( !isTopLevel() )
745 clearWState( WState_OwnCursor );
746 qt_set_cursor( this, cursor() );
747}
748
749void QWidget::setCaption( const QString &caption )
750{
751 if ( QWidget::caption() == caption )
752 return; // for less flicker
753 topData()->caption = caption;
754
755 QCString cap = caption.local8Bit();
756 WinSetWindowText( winFId(), cap );
757
758 HSWITCH swEntry = topData()->swEntry;
759 if ( swEntry ) {
760 SWCNTRL swc;
761 WinQuerySwitchEntry( swEntry, &swc );
762 strncpy( swc.szSwtitle, cap, sizeof(swc.szSwtitle)-1 );
763 swc.szSwtitle [sizeof(swc.szSwtitle)-1] = 0;
764 WinChangeSwitchEntry( swEntry, &swc );
765 }
766
767 QEvent e( QEvent::CaptionChange );
768 QApplication::sendEvent( this, &e );
769}
770
771void QWidget::setIcon( const QPixmap &pixmap )
772{
773 QTLWExtra* x = topData();
774 delete x->icon;
775 x->icon = 0;
776 HPOINTER oldIcon = x->pmIcon;
777 x->pmIcon = 0;
778
779 if ( !pixmap.isNull() ) { // valid icon
780 x->icon = new QPixmap( pixmap );
781
782 if ( isTopLevel() ) {
783 const QPixmap *normal = 0;
784 const QPixmap *mini = 0;
785
786 // QPixmap::createIcon() is not yet capable to create both normal
787 // and mini icons (due to a bug in WinCreateIconIndirect), so
788 // if the specified pixmap is equal or larger than the normal icon
789 // size, then we create a normal icon, otherwise a mini one.
790
791 int iconw = WinQuerySysValue( HWND_DESKTOP, SV_CXICON );
792 int iconh = WinQuerySysValue( HWND_DESKTOP, SV_CYICON );
793 if ( pixmap.width() >= iconw && pixmap.height() >= iconh ) {
794 normal = &pixmap;
795 } else {
796 mini = &pixmap;
797 }
798
799 x->pmIcon = QPixmap::createIcon( false, 0, 0, normal, mini );
800 }
801 }
802
803 if ( isTopLevel() )
804 WinSendMsg( x->fId, WM_SETICON, MPFROMLONG( x->pmIcon ), 0 );
805
806 if ( oldIcon )
807 WinDestroyPointer( oldIcon );
808
809 QEvent e( QEvent::IconChange );
810 QApplication::sendEvent( this, &e );
811}
812
813
814void QWidget::setIconText( const QString &iconText )
815{
816 topData()->iconText = iconText;
817}
818
819QCursor *qt_grab_cursor()
820{
821 return mouseGrbCur;
822}
823
824void QWidget::grabMouse()
825{
826 if ( !qt_nograb() ) {
827 if ( mouseGrb )
828 mouseGrb->releaseMouse();
829 WinSetCapture( HWND_DESKTOP, winFId() );
830 mouseGrb = this;
831 }
832}
833
834void QWidget::grabMouse( const QCursor &cursor )
835{
836 if ( !qt_nograb() ) {
837 if ( mouseGrb )
838 mouseGrb->releaseMouse();
839 WinSetCapture( HWND_DESKTOP, winFId() );
840 mouseGrbCur = new QCursor( cursor );
841 WinSetPointer( HWND_DESKTOP, mouseGrbCur->handle() );
842 mouseGrb = this;
843 }
844}
845
846void QWidget::releaseMouse()
847{
848 if ( !qt_nograb() && mouseGrb == this ) {
849 WinSetCapture( HWND_DESKTOP, 0 );
850 if ( mouseGrbCur ) {
851 delete mouseGrbCur;
852 mouseGrbCur = 0;
853 }
854 mouseGrb = 0;
855 }
856}
857
858void QWidget::grabKeyboard()
859{
860 if ( !qt_nograb() ) {
861 if ( keyboardGrb )
862 keyboardGrb->releaseKeyboard();
863 keyboardGrb = this;
864 }
865}
866
867void QWidget::releaseKeyboard()
868{
869 if ( !qt_nograb() && keyboardGrb == this )
870 keyboardGrb = 0;
871}
872
873
874QWidget *QWidget::mouseGrabber()
875{
876 return mouseGrb;
877}
878
879QWidget *QWidget::keyboardGrabber()
880{
881 return keyboardGrb;
882}
883
884void QWidget::setActiveWindow()
885{
886 WinSetActiveWindow( HWND_DESKTOP, topLevelWidget()->winFId() );
887}
888
889void QWidget::update()
890{
891 update( 0, 0, -1, -1 );
892}
893
894void QWidget::update( int x, int y, int w, int h )
895{
896 if ( w && h &&
897 (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
898 if ( w < 0 )
899 w = crect.width() - x;
900 if ( h < 0 )
901 h = crect.height() - y;
902
903 // flip y coordinate
904 y = crect.height() - (y + h);
905 RECTL rcl = { x, y, x + w, y + h };
906
907 // WinInvalidateRect() has such a "feature" that children are not
908 // actually extracted from the window's update region when it has
909 // the WS_CLIPCHILDREN flag, meaning that every child will anyway
910 // receive a WM_PAINT message if its visible region intersects with
911 // the update region of its parent, with its update region set to
912 // that intersection. This in turn means that if we invalidate the
913 // window completely, all its visible children wil completely repaint
914 // themselves, what is not we want. The solution is to manually
915 // substract children from the region we want to be updated.
916 ULONG wstyle = WinQueryWindowULong( winId(), QWL_STYLE );
917 if ( (wstyle & WS_CLIPCHILDREN) && children() ) {
918 HPS lhps = hps;
919 if ( !lhps ) lhps = qt_display_ps();
920 HRGN hrgn = GpiCreateRegion( lhps, 1, &rcl );
921 HRGN whrgn = GpiCreateRegion( lhps, 0, NULL );
922 int hgt = crect.height();
923
924 QObjectListIt it(*children());
925 register QObject *object;
926 QWidget *w;
927 while ( it ) {
928 object = it.current();
929 ++it;
930 if ( object->isWidgetType() ) {
931 w = (QWidget*)object;
932 if ( !w->isTopLevel() && w->isShown() ) {
933//@@TODO (dmik): later: substract the region of the child window
934// (WinQueryClipRegion()) instead of the window rectangle.
935 const QRect &r = w->crect;
936 rcl.xLeft = r.left();
937 rcl.yBottom = hgt - (r.bottom() + 1);
938 rcl.xRight = r.right() + 1;
939 rcl.yTop = hgt - r.top();
940 GpiSetRegion( lhps, whrgn, 1, &rcl );
941 GpiCombineRegion( lhps, hrgn, hrgn, whrgn, CRGN_DIFF );
942 }
943 }
944 }
945 GpiDestroyRegion( lhps, whrgn );
946 WinInvalidateRegion( winId(), hrgn, FALSE );
947 GpiDestroyRegion( lhps, hrgn );
948 } else {
949 WinInvalidateRect( winId(), &rcl, FALSE );
950 }
951 }
952}
953
954void QWidget::repaint( int x, int y, int w, int h, bool erase )
955{
956 if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
957#if defined (DEBUG_REPAINTRESIZE)
958 qDebug( "repaint(): [%s/%s/%08X] %d,%d; %d,%d erase: %d resizeNoErase: %d",
959 name(), className(), widget_flags, x, y, w, h, erase,
960 (testWFlags( WResizeNoErase ) != 0) );
961#endif
962 if ( w < 0 )
963 w = crect.width() - x;
964 if ( h < 0 )
965 h = crect.height() - y;
966 QRect r( x, y, w, h );
967 if ( r.isEmpty() )
968 return; // nothing to do
969
970 // flip y coordinate
971 int fy = crect.height() - (y + h);
972 RECTL rcl = { x, fy, x + w, fy + h };
973 WinValidateRect( winId(), &rcl, FALSE );
974
975 Q_ASSERT( !WinQueryWindowULong( winId(), QWL_QTCLIPRGN ) );
976 QRegion reg;
977 if ( r != rect() ) {
978 reg = QRegion( r );
979 WinSetWindowULong( winId(), QWL_QTCLIPRGN, (ULONG) &reg );
980 }
981
982 QPaintEvent e( r, erase );
983 if ( erase )
984 this->erase( x, y, w, h );
985 QApplication::sendEvent( this, &e );
986
987 WinSetWindowULong( winId(), QWL_QTCLIPRGN, 0 );
988 }
989}
990
991void QWidget::repaint( const QRegion& reg, bool erase )
992{
993 if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
994#if defined (DEBUG_REPAINTRESIZE)
995 qDebug( "repaint(): [%s/%s/%08X] <region> erase: %d resizeNoErase: %d",
996 name(), className(), widget_flags,
997 (testWFlags( WResizeNoErase ) != 0) );
998#endif
999 // convert region y coordinates from Qt to GPI (see qregion_pm.cpp)
1000 WinValidateRegion( winId(), reg.handle( height() ), FALSE );
1001
1002 Q_ASSERT( !WinQueryWindowULong( winId(), QWL_QTCLIPRGN ) );
1003 WinSetWindowULong( winId(), QWL_QTCLIPRGN, (ULONG) &reg );
1004
1005 QPaintEvent e( reg, erase );
1006 if ( erase )
1007 this->erase( reg );
1008 QApplication::sendEvent( this, &e );
1009
1010 WinSetWindowULong( winId(), QWL_QTCLIPRGN, 0 );
1011 }
1012}
1013
1014void QWidget::setWindowState(uint newstate)
1015{
1016 uint oldstate = windowState();
1017
1018 //@@TODO (dmik): should we deactivate the widget when no WindowActive
1019 // is specified? Guess no, because such behavior can be seen in Win32
1020 // (the only exception is when WindowMinimized is set w/o WindowActive).
1021 // As well as nothing is done in Win32 when only WindowActive is
1022 // specified.
1023 ULONG fl = (newstate & WindowActive) ?
1024 SWP_ACTIVATE :
1025 // mimic Win32 behavior
1026 (newstate & WindowMinimized) ? SWP_DEACTIVATE :
1027 // mimic Win32 behavior
1028 ((oldstate & WindowMinimized) &&
1029 (newstate & WindowMaximized)) ? SWP_ACTIVATE :
1030 0;
1031
1032 if (isTopLevel()) {
1033 WId id = winFId();
1034 QTLWExtra *top = topData();
1035
1036 if ((oldstate & WindowMaximized) != (newstate & WindowMaximized)) {
1037 if (isVisible() && !(newstate & WindowMinimized)) {
1038 ULONG f = (newstate & WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE;
1039 WinSetWindowPos( id, 0, 0, 0, 0, 0, fl | f );
1040 QRect r = topData()->normalGeometry;
1041 if (!(newstate & WindowMaximized) && r.width() >= 0) {
1042 if (pos() != r.topLeft() || size() !=r.size()) {
1043 top->normalGeometry = QRect( 0, 0, -1, -1 );
1044 r.addCoords( top->fleft, top->ftop, top->fleft, top->ftop);
1045 setGeometry( r );
1046 }
1047 }
1048 }
1049 }
1050
1051 if ((oldstate & WindowFullScreen) != (newstate & WindowFullScreen)) {
1052 if (newstate & WindowFullScreen) {
1053 if ( top->normalGeometry.width() < 0 && !(oldstate & WindowMaximized) )
1054 top->normalGeometry = QRect( pos(), size() );
1055 QRect r = QApplication::desktop()->screenGeometry(this);
1056 r.addCoords( -top->fleft, -top->fbottom, top->fright, top->ftop );
1057 WinSetWindowPos(
1058 id, 0, r.x(), r.y(), r.width(), r.height(),
1059 fl | SWP_SIZE | SWP_MOVE
1060 );
1061//@@TODO (dmik): we do not need to call updateFrameStrut() because the frame
1062// is not changed, but who will update our crect?..
1063// updateFrameStrut();
1064 } else {
1065 ULONG f = fl;
1066 // the widget is still maximized
1067 if ( newstate & WindowMaximized ) {
1068 if (isVisible())
1069 f |= SWP_MAXIMIZE;
1070 }
1071 if ( f ) WinSetWindowPos( id, 0, 0, 0, 0, 0, f );
1072 if ( !(newstate & WindowMaximized) ) {
1073 QRect r = top->normalGeometry;
1074 top->normalGeometry = QRect( 0, 0, -1, -1 );
1075 r.addCoords( top->fleft, top->ftop, top->fleft, top->ftop);
1076 setGeometry( r );
1077 }
1078//@@TODO (dmik): we do not need to call updateFrameStrut() because the frame
1079// is not changed, but who will update our crect?..
1080// else {
1081// updateFrameStrut();
1082// }
1083 }
1084 }
1085
1086 if ((oldstate & WindowMinimized) != (newstate & WindowMinimized)) {
1087 if (isVisible()) {
1088 ULONG f =
1089 (newstate & WindowMinimized) ? SWP_MINIMIZE :
1090 (newstate & WindowMaximized) ? SWP_MAXIMIZE : SWP_RESTORE;
1091 WinSetWindowPos( id, 0, 0, 0, 0, 0, fl | f );
1092 }
1093 }
1094 }
1095
1096 widget_state &= ~(WState_Minimized | WState_Maximized | WState_FullScreen);
1097 if (newstate & WindowMinimized)
1098 widget_state |= WState_Minimized;
1099 if (newstate & WindowMaximized)
1100 widget_state |= WState_Maximized;
1101 if (newstate & WindowFullScreen)
1102 widget_state |= WState_FullScreen;
1103
1104 QEvent e(QEvent::WindowStateChange);
1105 QApplication::sendEvent(this, &e);
1106}
1107
1108
1109/*
1110 \internal
1111 Platform-specific part of QWidget::hide().
1112*/
1113
1114void QWidget::hideWindow()
1115{
1116 deactivateWidgetCleanup();
1117 HWND id = winFId();
1118 WinShowWindow( id, FALSE );
1119 if ( isTopLevel() )
1120 WinSetWindowPos( id, 0, 0, 0, 0, 0, SWP_DEACTIVATE );
1121
1122 HSWITCH swEntry = topData()->swEntry;
1123 if ( swEntry ) {
1124 SWCNTRL swc;
1125 WinQuerySwitchEntry( swEntry, &swc );
1126 swc.uchVisibility = SWL_INVISIBLE;
1127 WinChangeSwitchEntry( swEntry, &swc );
1128 }
1129}
1130
1131
1132/*
1133 \internal
1134 Platform-specific part of QWidget::show().
1135*/
1136
1137void QWidget::showWindow()
1138{
1139 WinShowWindow( winFId(), TRUE );
1140 ULONG fl = 0;
1141 if ( isTopLevel() ) {
1142 // we do this check here bevause setWindowState() does not actually
1143 // change the window state when the window is not visible, assuming
1144 // it will be done here.
1145 if (testWState(WState_Minimized))
1146 fl |= SWP_MINIMIZE;
1147 else if (testWState(WState_Maximized))
1148 fl |= SWP_MAXIMIZE;
1149
1150 if (
1151 !testWFlags(WType_Popup | WStyle_Tool) &&
1152 (!testWFlags(WType_Dialog) || !parentWidget())
1153 ) {
1154 HSWITCH &swEntry = topData()->swEntry;
1155 if ( !swEntry ) {
1156 // lazily create a new window list entry
1157 HWND id = winFId(); // frame handle, if any
1158 PID pid;
1159 WinQueryWindowProcess( id, &pid, NULL );
1160 SWCNTRL swc;
1161 memset( &swc, 0, sizeof(SWCNTRL) );
1162 swc.hwnd = id;
1163 swc.idProcess = pid;
1164 swc.uchVisibility = SWL_VISIBLE;
1165 swc.fbJump = SWL_JUMPABLE;
1166 WinQueryWindowText( id, sizeof(swc.szSwtitle), swc.szSwtitle );
1167 swEntry = WinAddSwitchEntry( &swc );
1168 } else {
1169 SWCNTRL swc;
1170 WinQuerySwitchEntry( swEntry, &swc );
1171 swc.uchVisibility = SWL_VISIBLE;
1172 WinChangeSwitchEntry( swEntry, &swc );
1173 }
1174 }
1175 }
1176 if (!testWFlags(WStyle_Tool) && !isPopup())
1177 fl |= SWP_ACTIVATE;
1178 if ( fl )
1179 WinSetWindowPos( winFId(), 0, 0, 0, 0, 0, fl );
1180
1181//@@TODO (dmik): remove? in OS/2 WinShowWindow() does not influence
1182// any other state flags of the window (such as maximized/minimized, active),
1183// so, the window is always shown at its current state (i.e. if its state was
1184// not changed while it was hidden it will be restored to that state upon
1185// unhiding; if the state was changed, it will be restored to that new state).
1186// int sm = SW_SHOWNORMAL;
1187// if ( isTopLevel() ) {
1188// if (testWState(WState_Minimized))
1189// sm = SW_SHOWMINIMIZED;
1190// else if (testWState(WState_Maximized))
1191// sm = SW_SHOWMAXIMIZED;
1192// }
1193// if (testWFlags(WStyle_Tool) || isPopup())
1194// sm = SW_SHOWNOACTIVATE;
1195//
1196// ShowWindow( winId(), sm );
1197// UpdateWindow( winId() );
1198}
1199
1200void QWidget::raise()
1201{
1202 QWidget *p = parentWidget();
1203 if ( p && p->childObjects && p->childObjects->findRef(this) >= 0 )
1204 p->childObjects->append( p->childObjects->take() );
1205//@@TODO (dmik): remove? SWP_ZORDER doesn't cause activation in OS/2...
1206// uint f = ( isPopup() || testWFlags(WStyle_Tool) ) ? SWP_NOACTIVATE : 0;
1207 WinSetWindowPos( winFId(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );
1208}
1209
1210void QWidget::lower()
1211{
1212 QWidget *p = parentWidget();
1213 if ( p && p->childObjects && p->childObjects->findRef(this) >= 0 )
1214 p->childObjects->insert( 0, p->childObjects->take() );
1215//@@TODO (dmik): remove? SWP_ZORDER doesn't cause activation in OS/2...
1216// uint f = ( isPopup() || testWFlags(WStyle_Tool) ) ? SWP_NOACTIVATE : 0;
1217 WinSetWindowPos( winFId(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER );
1218}
1219
1220void QWidget::stackUnder( QWidget* w )
1221{
1222 QWidget *p = parentWidget();
1223 if ( !w || isTopLevel() || p != w->parentWidget() || this == w )
1224 return;
1225 if ( p && p->childObjects && p->childObjects->findRef(w) >= 0 && p->childObjects->findRef(this) >= 0 ) {
1226 p->childObjects->take();
1227 p->childObjects->insert( p->childObjects->findRef(w), this );
1228 }
1229 WinSetWindowPos( winId(), w->winId(), 0, 0, 0, 0, SWP_ZORDER );
1230}
1231
1232//
1233// The internal qPMRequestConfig, defined in qeventloop_pm.cpp, stores move,
1234// resize and setGeometry requests for a widget that is already
1235// processing a config event. The purpose is to avoid recursion.
1236//
1237void qPMRequestConfig( WId, int, int, int, int, int );
1238
1239void QWidget::internalSetGeometry( int x, int y, int w, int h, bool isMove )
1240{
1241 if ( extra ) { // any size restrictions?
1242 w = QMIN(w,extra->maxw);
1243 h = QMIN(h,extra->maxh);
1244 w = QMAX(w,extra->minw);
1245 h = QMAX(h,extra->minh);
1246 }
1247 if ( w < 1 ) // invalid size
1248 w = 1;
1249 if ( h < 1 )
1250 h = 1;
1251 QSize oldSize( size() );
1252 QPoint oldPos( pos() );
1253 if ( !isTopLevel() )
1254 isMove = (crect.topLeft() != QPoint( x, y ));
1255 if ( isMove == FALSE && oldSize.width()==w && oldSize.height()==h )
1256 return;
1257 clearWState(WState_Maximized);
1258 clearWState(WState_FullScreen);
1259 if (isTopLevel())
1260 topData()->normalGeometry = QRect(0, 0, -1, -1);
1261 if ( testWState(WState_ConfigPending) ) { // processing config event
1262 qPMRequestConfig( winId(), isMove ? 2 : 1, x, y, w, h );
1263 } else {
1264 setWState( WState_ConfigPending );
1265 if ( isTopLevel() ) {
1266//@@TODO (dmik): remove, no need to check for extra...
1267// QRect fr( frameGeometry() );
1268// if ( extra ) {
1269// fr.setLeft( fr.left() + x - crect.left() );
1270// fr.setTop( fr.top() + y - crect.top() );
1271// fr.setRight( fr.right() + ( x + w - 1 ) - crect.right() );
1272// fr.setBottom( fr.bottom() + ( y + h - 1 ) - crect.bottom() );
1273// }
1274// MoveWindow( winId(), fr.x(), fr.y(), fr.width(), fr.height(), TRUE );
1275// crect.setRect( x, y, w, h );
1276
1277//@@TODO (dmik): optimize: use extra->topextra directly (after updating fstrut
1278// if necessary) instead of calling frameGeometry()
1279 QRect fr( frameGeometry() );
1280 int fx = fr.left() + x - crect.left();
1281 int fy = fr.top() + y - crect.top();
1282 int fw = fr.width() + w - crect.width();
1283 int fh = fr.height() + h - crect.height();
1284 // flip y coordinate
1285 fy = QApplication::desktop()->height() - (fy + fh);
1286 crect.setRect( x, y, w, h );
1287 WinSetWindowPos( winFId(), 0, fx, fy, fw, fh, SWP_MOVE | SWP_SIZE );
1288 } else {
1289 // flip y coordinate
1290 int fy = parentWidget()->height() - (y + h);
1291 crect.setRect( x, y, w, h );
1292 WinSetWindowPos( winId(), 0, x, fy, w, h, SWP_MOVE | SWP_SIZE );
1293 }
1294 clearWState( WState_ConfigPending );
1295 }
1296
1297 bool isResize = w != oldSize.width() || h != oldSize.height();
1298 if ( isVisible() ) {
1299 if ( isMove && pos() != oldPos ) {
1300 QMoveEvent e( pos(), oldPos );
1301 QApplication::sendEvent( this, &e );
1302 }
1303 if ( isResize ) {
1304 QResizeEvent e( size(), oldSize );
1305 QApplication::sendEvent( this, &e );
1306 if ( !testWFlags( WStaticContents ) )
1307 repaint( !testWFlags(WResizeNoErase) );
1308 }
1309 } else {
1310 if ( isMove && pos() != oldPos )
1311 QApplication::postEvent( this,
1312 new QMoveEvent( pos(), oldPos ) );
1313 if ( isResize )
1314 QApplication::postEvent( this,
1315 new QResizeEvent( size(), oldSize ) );
1316 }
1317}
1318
1319void QWidget::setMinimumSize( int minw, int minh )
1320{
1321#if defined(QT_CHECK_RANGE)
1322 if ( minw < 0 || minh < 0 )
1323 qWarning("QWidget::setMinimumSize: The smallest allowed size is (0,0)");
1324#endif
1325 createExtra();
1326 if ( extra->minw == minw && extra->minh == minh )
1327 return;
1328 extra->minw = minw;
1329 extra->minh = minh;
1330 if ( minw > width() || minh > height() ) {
1331 bool resized = testWState( WState_Resized );
1332 resize( QMAX(minw,width()), QMAX(minh,height()) );
1333 if ( !resized )
1334 clearWState( WState_Resized ); //not a user resize
1335 }
1336 updateGeometry();
1337}
1338
1339void QWidget::setMaximumSize( int maxw, int maxh )
1340{
1341#if defined(QT_CHECK_RANGE)
1342 if ( maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX ) {
1343 qWarning("QWidget::setMaximumSize: The largest allowed size is (%d,%d)",
1344 QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
1345 maxw = QMIN( maxw, QWIDGETSIZE_MAX );
1346 maxh = QMIN( maxh, QWIDGETSIZE_MAX );
1347 }
1348 if ( maxw < 0 || maxh < 0 ) {
1349 qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
1350 "are not possible",
1351 name( "unnamed" ), className(), maxw, maxh );
1352 maxw = QMAX( maxw, 0 );
1353 maxh = QMAX( maxh, 0 );
1354 }
1355#endif
1356 createExtra();
1357 if ( extra->maxw == maxw && extra->maxh == maxh )
1358 return;
1359 extra->maxw = maxw;
1360 extra->maxh = maxh;
1361 if ( maxw < width() || maxh < height() ) {
1362 bool resized = testWState( WState_Resized );
1363 resize( QMIN(maxw,width()), QMIN(maxh,height()) );
1364 if ( !resized )
1365 clearWState( WState_Resized ); //not a user resize
1366 }
1367 updateGeometry();
1368}
1369
1370void QWidget::setSizeIncrement( int w, int h )
1371{
1372 createTLExtra();
1373 extra->topextra->incw = w;
1374 extra->topextra->inch = h;
1375}
1376
1377void QWidget::setBaseSize( int w, int h )
1378{
1379 createTLExtra();
1380 extra->topextra->basew = w;
1381 extra->topextra->baseh = h;
1382}
1383
1384extern void qt_erase_background( HPS, int, int, int, int,
1385 const QColor &, const QPixmap *, int, int, int );
1386
1387void QWidget::erase( int x, int y, int w, int h )
1388{
1389 // SIMILAR TO region ERASE BELOW
1390
1391 if ( backgroundMode()==NoBackground )
1392 return;
1393 if ( w < 0 )
1394 w = crect.width() - x;
1395 if ( h < 0 )
1396 h = crect.height() - y;
1397
1398 HPS lhps;
1399 bool tmphps;
1400
1401 if( QPainter::redirect( this ) ) {
1402 tmphps = FALSE;
1403 lhps = QPainter::redirect( this )->handle();
1404 Q_ASSERT( lhps );
1405 } else if ( !hps ) {
1406 tmphps = TRUE;
1407 lhps = getTargetPS();
1408 } else {
1409 tmphps = FALSE;
1410 lhps = hps;
1411 }
1412
1413 QPoint offset = backgroundOffset();
1414 int ox = offset.x();
1415 int oy = offset.y();
1416
1417 qt_erase_background(
1418 lhps, x, y, w, h, bg_col, backgroundPixmap(),
1419 ox, oy, crect.height()
1420 );
1421
1422 if ( tmphps )
1423 WinReleasePS( lhps );
1424}
1425
1426void QWidget::erase( const QRegion& rgn )
1427{
1428 // SIMILAR TO rect ERASE ABOVE
1429
1430 if ( backgroundMode()==NoBackground )
1431 return;
1432
1433 HPS lhps;
1434 bool tmphps;
1435
1436 if( QPainter::redirect( this ) ) {
1437 tmphps = FALSE;
1438 lhps = QPainter::redirect( this )->handle();
1439 Q_ASSERT( lhps );
1440 } else if ( !hps ) {
1441 tmphps = TRUE;
1442 lhps = getTargetPS();
1443 } else {
1444 tmphps = FALSE;
1445 lhps = hps;
1446 }
1447
1448 HRGN oldRegion = GpiQueryClipRegion( lhps );
1449 HRGN newRegion = 0;
1450 if ( oldRegion ) {
1451 GpiSetClipRegion( lhps, 0, NULL );
1452 newRegion = GpiCreateRegion( lhps, 0, NULL );
1453 GpiCombineRegion( lhps, newRegion, oldRegion, rgn.handle( height() ),
1454 CRGN_AND );
1455 } else {
1456 newRegion = rgn.handle( height() );
1457 }
1458 GpiSetClipRegion( lhps, newRegion, &oldRegion );
1459
1460 QPoint offset = backgroundOffset();
1461 int ox = offset.x();
1462 int oy = offset.y();
1463
1464 qt_erase_background(
1465 lhps, 0, 0, crect.width(), crect.height(),
1466 bg_col, backgroundPixmap(), ox, oy, crect.height()
1467 );
1468
1469 GpiSetClipRegion( lhps, oldRegion, NULL );
1470
1471 if ( oldRegion )
1472 GpiDestroyRegion( lhps, newRegion );
1473 if ( tmphps )
1474 WinReleasePS( lhps );
1475}
1476
1477
1478// helper function to extract regions of all windows that overlap the given
1479// hwnd subject to their z-order (excluding children of hwnd) from the given
1480// hrgn. hps is the presentation space of hrgn.
1481void qt_WinExcludeOverlappingWindows( HWND hwnd, HPS hps, HRGN hrgn )
1482{
1483 HRGN vr = GpiCreateRegion( hps, 0, NULL );
1484 RECTL r;
1485
1486 // enumerate all windows that are on top of this hwnd
1487 HWND id = hwnd, deskId = QApplication::desktop()->winId();
1488 do {
1489 HWND i = id;
1490 while( (i = WinQueryWindow( i, QW_PREV )) ) {
1491 if ( WinIsWindowShowing( i ) ) {
1492//@@TODO (dmik): probably we should use WinQueryClipRegion() here to
1493// handle non-rectangular windows properly
1494 WinQueryWindowRect( i, &r );
1495 WinMapWindowPoints( i, hwnd, (PPOINTL) &r, 2 );
1496 GpiSetRegion( hps, vr, 1, &r );
1497 GpiCombineRegion( hps, hrgn, hrgn, vr, CRGN_DIFF );
1498 }
1499 }
1500 id = WinQueryWindow( id, QW_PARENT );
1501 } while( id != deskId );
1502
1503 GpiDestroyRegion( hps, vr );
1504}
1505
1506// helper function to scroll window contents. WinScrollWindow() is a bit
1507// buggy and corrupts update regions sometimes (which leaves some outdated
1508// areas unpainted after scrolling), so we reimplement its functionality in
1509// this function. dy and clip->yBottom/yTop should be GPI coordinates, not Qt.
1510// all clip coordinates are inclusive.
1511void qt_WinScrollWindowWell( HWND hwnd, LONG dx, LONG dy, const PRECTL clip = NULL )
1512{
1513 WinLockVisRegions( HWND_DESKTOP, TRUE );
1514
1515 HPS lhps = WinGetClipPS(
1516 hwnd, HWND_TOP,
1517 PSF_LOCKWINDOWUPDATE | PSF_CLIPSIBLINGS
1518 );
1519 if ( clip )
1520 GpiIntersectClipRectangle( lhps, clip );
1521
1522 // remember the update region and validate it. it will be shifted and
1523 // invalidated again later
1524 HRGN update = GpiCreateRegion( lhps, 0, NULL );
1525 WinQueryUpdateRegion( hwnd, update );
1526 WinValidateRegion( hwnd, update, TRUE );
1527
1528 POINTL ptls[4];
1529 RECTL &sr = *(PRECTL) &ptls[2];
1530 RECTL &tr = *(PRECTL) &ptls[0];
1531
1532 // get the source rect for scrolling
1533 GpiQueryClipBox( lhps, &sr );
1534 sr.xRight++; sr.yTop++; // inclusive -> exclusive
1535
1536 // get the visible region ignoring areas covered by children
1537 HRGN visible = GpiCreateRegion( lhps, 1, &sr );
1538 qt_WinExcludeOverlappingWindows( hwnd, lhps, visible );
1539
1540 // scroll visible region rectangles separately to avoid the flicker
1541 // that could be produced by scrolling parts of overlapping windows
1542 RGNRECT ctl;
1543 ctl.ircStart = 1;
1544 ctl.crc = 0;
1545 ctl.crcReturned = 0;
1546 if ( dx >= 0 ) {
1547 if ( dy >= 0 ) ctl.ulDirection = RECTDIR_RTLF_TOPBOT;
1548 else ctl.ulDirection = RECTDIR_RTLF_BOTTOP;
1549 } else {
1550 if ( dy >= 0 ) ctl.ulDirection = RECTDIR_LFRT_TOPBOT;
1551 else ctl.ulDirection = RECTDIR_LFRT_BOTTOP;
1552 }
1553 GpiQueryRegionRects( lhps, visible, NULL, &ctl, NULL );
1554 ctl.crc = ctl.crcReturned;
1555 int rclcnt = ctl.crcReturned;
1556 PRECTL rcls = new RECTL[rclcnt];
1557 GpiQueryRegionRects( lhps, visible, NULL, &ctl, rcls );
1558 PRECTL r = rcls;
1559 for ( int i = 0; i < rclcnt; i++, r++ ) {
1560 // source rect
1561 sr = *r;
1562 // target rect
1563 tr.xLeft = sr.xLeft + dx;
1564 tr.xRight = sr.xRight + dx;
1565 tr.yBottom = sr.yBottom + dy;
1566 tr.yTop = sr.yTop + dy;
1567 GpiBitBlt( lhps, lhps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE );
1568 }
1569 delete [] rcls;
1570
1571 // make the scrolled version of the visible region
1572 HRGN scrolled = GpiCreateRegion( lhps, 0, NULL );
1573 GpiCombineRegion( lhps, scrolled, visible, 0, CRGN_COPY );
1574 // invalidate the initial update region
1575 GpiCombineRegion( lhps, scrolled, scrolled, update, CRGN_DIFF );
1576 // shift the region
1577 POINTL dp = { dx, dy };
1578 GpiOffsetRegion( lhps, scrolled, &dp );
1579 // substract scrolled from visible to get invalid areas
1580 GpiCombineRegion( lhps, scrolled, visible, scrolled, CRGN_DIFF );
1581
1582 WinInvalidateRegion( hwnd, scrolled, TRUE );
1583
1584 GpiDestroyRegion( lhps, scrolled );
1585 GpiDestroyRegion( lhps, visible );
1586 GpiDestroyRegion( lhps, update );
1587
1588 WinReleasePS( lhps );
1589
1590 WinLockVisRegions( HWND_DESKTOP, FALSE );
1591
1592 WinUpdateWindow( hwnd );
1593}
1594
1595void QWidget::scroll( int dx, int dy )
1596{
1597 if ( testWState( WState_BlockUpdates ) && !children() )
1598 return;
1599
1600 // move non-toplevel children
1601 if ( children() ) {
1602 QObjectListIt it(*children());
1603 register QObject *obj;
1604 int h = crect.height();
1605 while ( (obj=it.current()) ) {
1606 ++it;
1607 if ( obj->isWidgetType() ) {
1608 QWidget *w = (QWidget*)obj;
1609 if ( !w->isTopLevel() ) {
1610 WinSetWindowPos(
1611 w->winId(), 0,
1612 w->crect.left() + dx,
1613 // flip y coordinate
1614 h - (w->crect.bottom() + dy + 1),
1615 0, 0,
1616 SWP_MOVE | SWP_NOADJUST | SWP_NOREDRAW
1617 );
1618 // WinSetWindowPos() doesn't send WM_MOVE to windows w/o
1619 // CS_MOVENOTIFY, but having this style for non-toplevel
1620 // widgets is unwanted, so we send them WM_MOVE manually
1621 // to let their geometry to be properly updated by
1622 // QETWidget::translateConfigEvent().
1623 WinSendMsg( w->winId(), WM_MOVE, 0, 0 );
1624 }
1625 }
1626 }
1627 }
1628
1629 qt_WinScrollWindowWell( winId(), dx, -dy, NULL );
1630}
1631
1632void QWidget::scroll( int dx, int dy, const QRect& r )
1633{
1634 if ( testWState( WState_BlockUpdates ) )
1635 return;
1636
1637 int h = crect.height();
1638 // flip y coordinate (all coordinates are inclusive)
1639 RECTL rcl = { r.left(), h - (r.bottom() + 1), r.right(), h - (r.top() + 1) };
1640 qt_WinScrollWindowWell( winId(), dx, -dy, &rcl );
1641}
1642
1643void QWidget::drawText( int x, int y, const QString &str )
1644{
1645 if ( testWState(WState_Visible) ) {
1646 QPainter paint;
1647 paint.begin( this );
1648 paint.drawText( x, y, str );
1649 paint.end();
1650 }
1651}
1652
1653
1654int QWidget::metric( int m ) const
1655{
1656 LONG val;
1657 if ( m == QPaintDeviceMetrics::PdmWidth ) {
1658 val = crect.width();
1659 } else if ( m == QPaintDeviceMetrics::PdmHeight ) {
1660 val = crect.height();
1661 } else {
1662 HDC hdc = GpiQueryDevice( qt_display_ps() );
1663 switch ( m ) {
1664 case QPaintDeviceMetrics::PdmDpiX:
1665 case QPaintDeviceMetrics::PdmPhysicalDpiX:
1666 DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 1, &val );
1667 break;
1668 case QPaintDeviceMetrics::PdmDpiY:
1669 case QPaintDeviceMetrics::PdmPhysicalDpiY:
1670 DevQueryCaps( hdc, CAPS_VERTICAL_FONT_RES, 1, &val );
1671 break;
1672 case QPaintDeviceMetrics::PdmWidthMM:
1673 DevQueryCaps( hdc, CAPS_HORIZONTAL_RESOLUTION, 1, &val );
1674 val = width() * 1000 / val;
1675 break;
1676 case QPaintDeviceMetrics::PdmHeightMM:
1677 DevQueryCaps( hdc, CAPS_VERTICAL_RESOLUTION, 1, &val );
1678 val = width() * 1000 / val;
1679 break;
1680 case QPaintDeviceMetrics::PdmNumColors:
1681 DevQueryCaps( hdc, CAPS_COLORS, 1, &val );
1682 break;
1683 case QPaintDeviceMetrics::PdmDepth:
1684 LONG colorInfo [2];
1685 DevQueryCaps( hdc, CAPS_COLOR_PLANES, 2, colorInfo );
1686 val = colorInfo [0] * colorInfo [1];
1687 break;
1688 default:
1689 val = 0;
1690#if defined(QT_CHECK_RANGE)
1691 qWarning( "QWidget::metric: Invalid metric command" );
1692#endif
1693 }
1694 }
1695 return val;
1696}
1697
1698void QWidget::createSysExtra()
1699{
1700//@@TODO (dmik): later
1701// extra->dropTarget = 0;
1702}
1703
1704void QWidget::deleteSysExtra()
1705{
1706 setAcceptDrops( FALSE );
1707}
1708
1709void QWidget::createTLSysExtra()
1710{
1711 extra->topextra->fId = 0;
1712 extra->topextra->swEntry = 0;
1713 extra->topextra->pmIcon = 0;
1714}
1715
1716void QWidget::deleteTLSysExtra()
1717{
1718 if ( extra->topextra->pmIcon )
1719 WinDestroyPointer( extra->topextra->pmIcon );
1720 if ( extra->topextra->swEntry )
1721 WinRemoveSwitchEntry( extra->topextra->swEntry );
1722 // frame window (extra->topextra->fId) is destroyed in
1723 // destroy() if it exists
1724}
1725
1726bool QWidget::acceptDrops() const
1727{
1728 return 0;
1729//@@TODO (dmik): later
1730// return ( extra && extra->dropTarget );
1731}
1732
1733void QWidget::setAcceptDrops( bool on )
1734{
1735//@@TODO (dmik): later
1736// // Enablement is defined by extra->dropTarget != 0.
1737//
1738// if ( on ) {
1739// // Turn on.
1740// createExtra();
1741// QWExtra *extra = extraData();
1742// if ( !extra->dropTarget )
1743// extra->dropTarget = qt_olednd_register( this );
1744// } else {
1745// // Turn off.
1746// QWExtra *extra = extraData();
1747// if ( extra && extra->dropTarget ) {
1748// qt_olednd_unregister(this, extra->dropTarget);
1749// extra->dropTarget = 0;
1750// }
1751// }
1752}
1753
1754void QWidget::setMask( const QRegion &region )
1755{
1756 qWarning( "QWidget::setMask() is not yet implemented on OS/2" );
1757//@@TODO (dmik): later (don't forget to offset region, see qregion_pm.cpp)
1758// // Since SetWindowRegion takes ownership, and we need to translate,
1759// // we take a copy.
1760// HRGN wr = CreateRectRgn(0,0,1,1);
1761// CombineRgn(wr, region.handle(), 0, RGN_COPY);
1762//
1763// int fleft = 0, ftop = 0;
1764// if (isTopLevel()) {
1765// ftop = topData()->ftop;
1766// fleft = topData()->fleft;
1767// }
1768// OffsetRgn(wr, fleft, ftop );
1769// SetWindowRgn( winId(), wr, TRUE );
1770}
1771
1772void QWidget::setMask( const QBitmap &bitmap )
1773{
1774 qWarning( "QWidget::setMask() is not yet implemented on OS/2" );
1775//@@TODO (dmik): later
1776// HRGN wr = qt_win_bitmapToRegion(bitmap);
1777//
1778// int fleft = 0, ftop = 0;
1779// if (isTopLevel()) {
1780// ftop = topData()->ftop;
1781// fleft = topData()->fleft;
1782// }
1783// OffsetRgn(wr, fleft, ftop );
1784// SetWindowRgn( winId(), wr, TRUE );
1785}
1786
1787void QWidget::clearMask()
1788{
1789 qWarning( "QWidget::clearMask() is not yet implemented on OS/2" );
1790//@@TODO (dmik): later
1791// SetWindowRgn( winId(), 0, TRUE );
1792}
1793
1794void QWidget::setName( const char *name )
1795{
1796 QObject::setName( name );
1797}
1798
1799void QWidget::updateFrameStrut() const
1800{
1801 QWidget *that = (QWidget *) this;
1802
1803 if ( !isVisible() || isDesktop() ) {
1804 that->fstrut_dirty = isVisible();
1805 return;
1806 }
1807
1808 QTLWExtra *top = that->topData();
1809 if ( top->fId ) {
1810 // this widget has WC_FRAME
1811 SWP cswp;
1812 WinQueryWindowPos( winId(), &cswp );
1813 SWP fswp;
1814 WinQueryWindowPos( top->fId, &fswp );
1815 // flip y coordinates
1816 fswp.y = QApplication::desktop()->height() - (fswp.y + fswp.cy);
1817 cswp.y = fswp.cy - (cswp.y + cswp.cy);
1818 that->crect.setRect(
1819 fswp.x + cswp.x, fswp.y + cswp.y,
1820 cswp.cx, cswp.cy
1821 );
1822
1823 top->fleft = cswp.x;
1824 top->ftop = cswp.y;
1825 top->fright = fswp.cx - cswp.x - cswp.cx;
1826 top->fbottom = fswp.cy - cswp.y - cswp.cy;
1827 }
1828 that->fstrut_dirty = FALSE;
1829}
1830
1831void QWidget::setMouseTracking( bool enable )
1832{
1833 if ( enable )
1834 setWState( WState_MouseTracking );
1835 else
1836 clearWState( WState_MouseTracking );
1837}
1838
1839void QWidget::setWindowOpacity(double)
1840{
1841}
1842
1843double QWidget::windowOpacity() const
1844{
1845 return 1.0;
1846}
1847
1848/*
1849 \internal
1850 Returns the frame wihdow handle if this widget is a top-level widget and
1851 has the standard WC_FRAME as its parent/owner (where it is FID_CLIENT).
1852 If the widget does not have the standard frame or it is not top-level, this
1853 function simply retuns the winId() value.
1854*/
1855WId QWidget::winFId()
1856{
1857 HWND fId = 0;
1858 if ( isTopLevel() )
1859 fId = topData()->fId;
1860 if ( !fId )
1861 fId = winId();
1862 return fId;
1863}
1864
1865/*!
1866 * \internal
1867 *
1868 * Obtains a presentaiton space to draw on this widget, set up according
1869 * to widget flags. If \a m != Unclipped and WPaintUnclipped flag is not
1870 * set, a clip region is set on the returned PS according to \a m.
1871 *
1872 * The returned handle must be freed using WinReleasePS() after usage.
1873 */
1874HPS QWidget::getTargetPS( ClipMode m /* = ClipAll */ )
1875{
1876 HPS widgetPS = 0;
1877
1878 if ( isDesktop() ) {
1879 widgetPS = WinGetScreenPS( HWND_DESKTOP );
1880 } else {
1881 if ( m == Unclipped || testWFlags( WPaintUnclipped ) ) {
1882 widgetPS = WinGetClipPS( winId(), 0, PSF_PARENTCLIP );
1883 } else {
1884 widgetPS = WinGetPS( winId() );
1885 }
1886 }
1887
1888 return widgetPS;
1889}
1890
Note: See TracBrowser for help on using the repository browser.