4 * Copyright 1993 Robert J. Amstadt
23 WORD USER_HeapSel
= 0;
25 extern BOOL32
MENU_PatchResidentPopup( HQUEUE16
, WND
* );
26 extern void QUEUE_FlushMessages(HQUEUE16
);
28 /***********************************************************************
29 * GetFreeSystemResources (USER.284)
31 WORD
GetFreeSystemResources( WORD resType
)
33 int userPercent
, gdiPercent
;
37 case GFSR_USERRESOURCES
:
38 userPercent
= (int)LOCAL_CountFree( USER_HeapSel
) * 100 /
39 LOCAL_HeapSize( USER_HeapSel
);
43 case GFSR_GDIRESOURCES
:
44 gdiPercent
= (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
45 LOCAL_HeapSize( GDI_HeapSel
);
49 case GFSR_SYSTEMRESOURCES
:
50 userPercent
= (int)LOCAL_CountFree( USER_HeapSel
) * 100 /
51 LOCAL_HeapSize( USER_HeapSel
);
52 gdiPercent
= (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
53 LOCAL_HeapSize( GDI_HeapSel
);
59 return (WORD
)MIN( userPercent
, gdiPercent
);
63 /***********************************************************************
64 * SystemHeapInfo (TOOLHELP.71)
66 BOOL16
SystemHeapInfo( SYSHEAPINFO
*pHeapInfo
)
68 pHeapInfo
->wUserFreePercent
= GetFreeSystemResources( GFSR_USERRESOURCES
);
69 pHeapInfo
->wGDIFreePercent
= GetFreeSystemResources( GFSR_GDIRESOURCES
);
70 pHeapInfo
->hUserSegment
= USER_HeapSel
;
71 pHeapInfo
->hGDISegment
= GDI_HeapSel
;
76 /***********************************************************************
77 * TimerCount (TOOLHELP.80)
79 BOOL16
TimerCount( TIMERINFO
*pTimerInfo
)
82 * In standard mode, dwmsSinceStart = dwmsThisVM
84 * I tested this, under Windows in enhanced mode, and
85 * if you never switch VM (ie start/stop DOS) these
86 * values should be the same as well.
88 * Also, Wine should adjust for the hardware timer
89 * to reduce the amount of error to ~1ms.
90 * I can't be bothered, can you?
92 pTimerInfo
->dwmsSinceStart
= pTimerInfo
->dwmsThisVM
= GetTickCount();
97 /**********************************************************************
100 INT16
InitApp( HINSTANCE16 hInstance
)
104 /* Create task message queue */
105 queueSize
= GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
106 if (!SetMessageQueue32( queueSize
)) return 0;
111 /**********************************************************************
114 void USER_AppExit( HTASK16 hTask
, HINSTANCE16 hInstance
, HQUEUE16 hQueue
)
116 /* FIXME: empty clipboard if needed, maybe destroy menus (Windows
117 * only complains about them but does nothing);
120 WND
* desktop
= WIN_GetDesktop();
122 /* Patch desktop window */
123 if( desktop
->hmemTaskQ
== hQueue
)
124 desktop
->hmemTaskQ
= GetTaskQueue(TASK_GetNextTask(hTask
));
126 /* Patch resident popup menu window */
127 MENU_PatchResidentPopup( hQueue
, NULL
);
129 TIMER_RemoveQueueTimers( hQueue
);
131 QUEUE_FlushMessages( hQueue
);
132 HOOK_FreeQueueHooks( hQueue
);
134 QUEUE_SetExitingQueue( hQueue
);
135 WIN_ResetQueueWindows( desktop
->child
, hQueue
, (HQUEUE16
)0);
136 QUEUE_SetExitingQueue( 0 );
138 /* Free the message queue */
140 QUEUE_DeleteMsgQueue( hQueue
);
144 /***********************************************************************
147 * Clean-up everything and exit the Wine process.
148 * This is the back-end of ExitWindows(), called when all windows
149 * have agreed to be terminated.
151 void USER_ExitWindows(void)
153 /* Do the clean-up stuff */
156 SHELL_SaveRegistry();
162 /***********************************************************************
163 * ExitWindows16 (USER.7)
165 BOOL16
ExitWindows16( DWORD dwReturnCode
, UINT16 wReserved
)
167 return ExitWindowsEx( EWX_LOGOFF
, 0xffffffff );
171 /***********************************************************************
172 * ExitWindowsEx (USER32.195)
174 BOOL32
ExitWindowsEx( UINT32 flags
, DWORD reserved
)
180 /* We have to build a list of all windows first, as in EnumWindows */
182 if (!(list
= WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL
))) return FALSE
;
184 /* Send a WM_QUERYENDSESSION message to every window */
186 for (ppWnd
= list
, i
= 0; *ppWnd
; ppWnd
++, i
++)
188 /* Make sure that the window still exists */
189 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
190 if (!SendMessage16( (*ppWnd
)->hwndSelf
, WM_QUERYENDSESSION
, 0, 0 ))
195 /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
197 for (ppWnd
= list
; i
> 0; i
--, ppWnd
++)
199 if (!IsWindow32( (*ppWnd
)->hwndSelf
)) continue;
200 SendMessage16( (*ppWnd
)->hwndSelf
, WM_ENDSESSION
, result
, 0 );
202 HeapFree( SystemHeap
, 0, list
);
204 if (result
) USER_ExitWindows();