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

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

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

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