4 * Copyright 1993 Robert J. Amstadt
22 WORD USER_HeapSel
= 0;
24 extern BOOL32
MENU_SwitchTPWndTo(HTASK16
);
26 /***********************************************************************
27 * GetFreeSystemResources (USER.284)
29 WORD
GetFreeSystemResources( WORD resType
)
31 int userPercent
, gdiPercent
;
35 case GFSR_USERRESOURCES
:
36 userPercent
= (int)LOCAL_CountFree( USER_HeapSel
) * 100 /
37 LOCAL_HeapSize( USER_HeapSel
);
41 case GFSR_GDIRESOURCES
:
42 gdiPercent
= (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
43 LOCAL_HeapSize( GDI_HeapSel
);
47 case GFSR_SYSTEMRESOURCES
:
48 userPercent
= (int)LOCAL_CountFree( USER_HeapSel
) * 100 /
49 LOCAL_HeapSize( USER_HeapSel
);
50 gdiPercent
= (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
51 LOCAL_HeapSize( GDI_HeapSel
);
57 return (WORD
)MIN( userPercent
, gdiPercent
);
61 /***********************************************************************
62 * SystemHeapInfo (TOOLHELP.71)
64 BOOL16
SystemHeapInfo( SYSHEAPINFO
*pHeapInfo
)
66 pHeapInfo
->wUserFreePercent
= GetFreeSystemResources( GFSR_USERRESOURCES
);
67 pHeapInfo
->wGDIFreePercent
= GetFreeSystemResources( GFSR_GDIRESOURCES
);
68 pHeapInfo
->hUserSegment
= USER_HeapSel
;
69 pHeapInfo
->hGDISegment
= GDI_HeapSel
;
74 /***********************************************************************
75 * TimerCount (TOOLHELP.80)
77 BOOL16
TimerCount( TIMERINFO
*pTimerInfo
)
80 * In standard mode, dwmsSinceStart = dwmsThisVM
82 * I tested this, under Windows in enhanced mode, and
83 * if you never switch VM (ie start/stop DOS) these
84 * values should be the same as well.
86 * Also, Wine should adjust for the hardware timer
87 * to reduce the amount of error to ~1ms.
88 * I can't be bothered, can you?
90 pTimerInfo
->dwmsSinceStart
= pTimerInfo
->dwmsThisVM
= GetTickCount();
95 /**********************************************************************
98 INT16
InitApp( HINSTANCE16 hInstance
)
102 /* Create task message queue */
103 queueSize
= GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
104 if (!SetMessageQueue32( queueSize
)) return 0;
109 /**********************************************************************
112 void USER_AppExit( HTASK16 hTask
, HINSTANCE16 hInstance
, HQUEUE16 hQueue
)
114 /* FIXME: empty clipboard if needed, maybe destroy menus (Windows
115 * only complains about them but does nothing);
118 WND
* desktop
= WIN_GetDesktop();
120 /* Patch desktop window */
121 if( desktop
->hmemTaskQ
== hQueue
)
122 desktop
->hmemTaskQ
= GetTaskQueue(TASK_GetNextTask(hTask
));
124 /* Patch resident popup menu window */
125 MENU_SwitchTPWndTo(0);
127 TIMER_RemoveQueueTimers( hQueue
);
129 QUEUE_FlushMessages( hQueue
);
130 HOOK_FreeQueueHooks( hQueue
);
132 QUEUE_SetDoomedQueue( hQueue
);
133 WIN_ResetQueueWindows( desktop
->child
, hQueue
, (HQUEUE16
)0);
134 QUEUE_SetDoomedQueue( 0 );
136 /* Free the message queue */
138 QUEUE_DeleteMsgQueue( hQueue
);
142 /***********************************************************************
145 * Clean-up everything and exit the Wine process.
146 * This is the back-end of ExitWindows(), called when all windows
147 * have agreed to be terminated.
149 void USER_ExitWindows(void)
151 /* Do the clean-up stuff */
154 SHELL_SaveRegistry();
160 /***********************************************************************
161 * ExitWindows16 (USER.7)
163 BOOL16
ExitWindows16( DWORD dwReturnCode
, UINT16 wReserved
)
165 return ExitWindowsEx( EWX_LOGOFF
, 0xffffffff );
169 /***********************************************************************
170 * ExitWindowsEx (USER32.195)
172 BOOL32
ExitWindowsEx( UINT32 flags
, DWORD reserved
)
178 /* We have to build a list of all windows first, as in EnumWindows */
180 if (!(list
= WIN_BuildWinArray( WIN_GetDesktop() ))) return FALSE
;
182 /* Send a WM_QUERYENDSESSION message to every window */
184 for (ppWnd
= list
, i
= 0; *ppWnd
; ppWnd
++, i
++)
186 /* Make sure that the window still exists */
187 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
188 if (!SendMessage16( (*ppWnd
)->hwndSelf
, WM_QUERYENDSESSION
, 0, 0 ))
193 /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
195 for (ppWnd
= list
; i
> 0; i
--, ppWnd
++)
197 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
198 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ENDSESSION
, result
, 0 );
200 HeapFree( SystemHeap
, 0, list
);
202 if (result
) USER_ExitWindows();