xref: /reactos/win32ss/user/ntuser/metric.c (revision 1de09c47)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS Win32k subsystem
4  * PURPOSE:          Window classes
5  * FILE:             win32ss/user/ntuser/metric.c
6  * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
7  *                   Timo Kreuzer (timo.kreuzer@reactos.org)
8  */
9 
10 #include <win32k.h>
11 DBG_DEFAULT_CHANNEL(UserSysparams);
12 
13 static BOOL Setup = FALSE;
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 BOOL FASTCALL UserIsDBCSEnabled(VOID)
18 {
19     return NLS_MB_CODE_PAGE_TAG;
20 }
21 
22 BOOL FASTCALL UserIsIMMEnabled(VOID)
23 {
24     if (NLS_MB_CODE_PAGE_TAG)
25         return TRUE;
26 
27     /* "LoadIMM" means Cicero despite its name */
28     return !!RegGetSectionDWORD(L"IMM", L"LoadIMM", FALSE);
29 }
30 
31 BOOL FASTCALL UserIsCiceroEnabled(VOID)
32 {
33 #if 1
34     return FALSE; /* FIXME: Cicero is not supported yet */
35 #else
36     if (RegGetSectionDWORD(L"IMM", L"DontLoadCTFIME", FALSE))
37         return FALSE;
38 
39     return UserIsIMMEnabled();
40 #endif
41 }
42 
43 BOOL
44 NTAPI
45 InitMetrics(VOID)
46 {
47     INT *piSysMet = gpsi->aiSysMet;
48     ULONG Width, Height;
49 
50     /* Note: used for the SM_CLEANBOOT metric */
51     DWORD dwValue = 0;
52     HKEY hKey = 0;
53 
54     /* Clean boot */
55     piSysMet[SM_CLEANBOOT] = 0; // Fallback value of 0 (normal mode)
56     if(NT_SUCCESS(RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option", &hKey)))
57     {
58         if(RegReadDWORD(hKey, L"OptionValue", &dwValue)) piSysMet[SM_CLEANBOOT] = (INT)dwValue;
59         ZwClose(hKey);
60     }
61 
62     /* FIXME: HACK, due to missing MDEV on first init */
63     if (!gpmdev)
64     {
65         Width = 640;
66         Height = 480;
67     }
68     else
69     {
70         Width = gpmdev->ppdevGlobal->gdiinfo.ulHorzRes;
71         Height = gpmdev->ppdevGlobal->gdiinfo.ulVertRes;
72     }
73 
74     /* Screen sizes */
75     piSysMet[SM_CXSCREEN] = Width;
76     piSysMet[SM_CYSCREEN] = Height;
77     piSysMet[SM_XVIRTUALSCREEN] = 0;
78     piSysMet[SM_YVIRTUALSCREEN] = 0;
79     piSysMet[SM_CXVIRTUALSCREEN] = Width;
80     piSysMet[SM_CYVIRTUALSCREEN] = Height;
81 
82     /* NC area sizes */
83     piSysMet[SM_CYCAPTION] = gspv.ncm.iCaptionHeight + 1;       // 19
84     piSysMet[SM_CYSMCAPTION] = gspv.ncm.iSmCaptionHeight + 1;   // 15;
85     piSysMet[SM_CXSIZE] = gspv.ncm.iCaptionHeight;              // 18;
86     piSysMet[SM_CYSIZE] = gspv.ncm.iCaptionHeight;              // 18;
87     piSysMet[SM_CXSMSIZE] = gspv.ncm.iSmCaptionWidth;   // 12; XP: piSysMet(SM_CYSMCAPTION) - 1
88     piSysMet[SM_CYSMSIZE] = gspv.ncm.iSmCaptionHeight;  // 14;
89     piSysMet[SM_CXBORDER] = 1; // Seems to be hardcoded
90     piSysMet[SM_CYBORDER] = 1; // Seems to be hardcoded
91     piSysMet[SM_CXFOCUSBORDER] = 1;
92     piSysMet[SM_CYFOCUSBORDER] = 1;
93     piSysMet[SM_CXDLGFRAME] = 3;
94     piSysMet[SM_CYDLGFRAME] = 3;
95     piSysMet[SM_CXEDGE] = 2;
96     piSysMet[SM_CYEDGE] = 2;
97     piSysMet[SM_CXFRAME] = piSysMet[SM_CXDLGFRAME] + gspv.ncm.iBorderWidth; // 4
98     piSysMet[SM_CYFRAME] = piSysMet[SM_CYDLGFRAME] + gspv.ncm.iBorderWidth; // 4
99 #if (_WIN32_WINNT >= 0x0600)
100     piSysMet[SM_CXPADDEDBORDER] = 0;
101 #endif
102 
103     /* Window sizes */
104     TRACE("ncm.iCaptionWidth=%d,GetSystemMetrics(SM_CYSIZE)=%d,GetSystemMetrics(SM_CXFRAME)=%d,avcwCaption=%d \n",
105            gspv.ncm.iCaptionWidth, piSysMet[SM_CYSIZE],piSysMet[SM_CXFRAME], gspv.tmCaptionFont.tmAveCharWidth);
106 
107     piSysMet[SM_CXMIN] = 3 * max(gspv.ncm.iCaptionWidth, 8) // 112
108                          + piSysMet[SM_CYSIZE] + 4
109                          + 4 * gspv.tmCaptionFont.tmAveCharWidth
110                          + 2 * piSysMet[SM_CXFRAME];
111     piSysMet[SM_CYMIN] = piSysMet[SM_CYCAPTION] + 2 * piSysMet[SM_CYFRAME]; // 27
112     piSysMet[SM_CXMAXIMIZED] = piSysMet[SM_CXSCREEN] + 2 * piSysMet[SM_CXFRAME];
113     piSysMet[SM_CYMAXIMIZED] = piSysMet[SM_CYSCREEN] - 20;
114     piSysMet[SM_CXFULLSCREEN] = piSysMet[SM_CXSCREEN];
115     piSysMet[SM_CYFULLSCREEN] = piSysMet[SM_CYMAXIMIZED] - piSysMet[SM_CYMIN];
116     piSysMet[SM_CYKANJIWINDOW] = 0;
117     piSysMet[SM_CXMINIMIZED] = gspv.mm.iWidth + 6;
118     piSysMet[SM_CYMINIMIZED] = piSysMet[SM_CYCAPTION] + 5;
119     piSysMet[SM_CXMINSPACING] = piSysMet[SM_CXMINIMIZED] + gspv.mm.iHorzGap;
120     piSysMet[SM_CYMINSPACING] = piSysMet[SM_CYMINIMIZED] + gspv.mm.iVertGap;
121     piSysMet[SM_CXMAXTRACK] = piSysMet[SM_CXVIRTUALSCREEN] + 4
122                               + 2 * piSysMet[SM_CXFRAME];
123     piSysMet[SM_CYMAXTRACK] = piSysMet[SM_CYVIRTUALSCREEN] + 4
124                               + 2 * piSysMet[SM_CYFRAME];
125 
126     /* Icon */
127     piSysMet[SM_CXVSCROLL] = gspv.ncm.iScrollWidth;     // 16;
128     piSysMet[SM_CYVTHUMB] = gspv.ncm.iScrollHeight;     // 16;
129     piSysMet[SM_CYHSCROLL] = gspv.ncm.iScrollWidth;     // 16;
130     piSysMet[SM_CXHTHUMB] = gspv.ncm.iScrollHeight;     // 16;
131     piSysMet[SM_CYVSCROLL] = gspv.ncm.iScrollHeight;    // 16
132     piSysMet[SM_CXHSCROLL] = gspv.ncm.iScrollHeight;    // 16;
133     piSysMet[SM_CXICON] = 32;
134     piSysMet[SM_CYICON] = 32;
135     piSysMet[SM_CXSMICON] = 16;
136     piSysMet[SM_CYSMICON] = 16;
137     piSysMet[SM_CXICONSPACING] = gspv.im.iHorzSpacing;  // 64;
138     piSysMet[SM_CYICONSPACING] = gspv.im.iVertSpacing;  // 64;
139     piSysMet[SM_CXCURSOR] = 32;
140     piSysMet[SM_CYCURSOR] = 32;
141     piSysMet[SM_CXMINTRACK] = piSysMet[SM_CXMIN];       // 117
142     piSysMet[SM_CYMINTRACK] = piSysMet[SM_CYMIN];       // 27
143     piSysMet[SM_CXDRAG] = 4;
144     piSysMet[SM_CYDRAG] = 4;
145     piSysMet[SM_ARRANGE] = gspv.mm.iArrange;            // 8;
146 
147     /* Menu */
148     piSysMet[SM_CYMENU] = gspv.ncm.iMenuHeight + 1;     // 19;
149     piSysMet[SM_MENUDROPALIGNMENT] = gspv.bMenuDropAlign;
150     piSysMet[SM_CXMENUCHECK] = ((1 + gspv.tmMenuFont.tmHeight +
151                                  gspv.tmMenuFont.tmExternalLeading) & ~1) - 1; // 13;
152     piSysMet[SM_CYMENUCHECK] = piSysMet[SM_CXMENUCHECK];
153     piSysMet[SM_CXMENUSIZE] = gspv.ncm.iMenuWidth;      // 18;
154     piSysMet[SM_CYMENUSIZE] = gspv.ncm.iMenuHeight;     // 18;
155 
156     /* Mouse */
157     piSysMet[SM_MOUSEPRESENT] = 1;
158     piSysMet[SM_MOUSEWHEELPRESENT] = 1;
159     piSysMet[SM_CMOUSEBUTTONS] = 2;
160     piSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap ? 1 : 0;
161     piSysMet[SM_CXDOUBLECLK] = gspv.iDblClickWidth;
162     piSysMet[SM_CYDOUBLECLK] = gspv.iDblClickHeight;
163 #if (_WIN32_WINNT >= 0x0600)
164     piSysMet[SM_MOUSEHORIZONTALWHEELPRESENT] = 0;
165 #endif
166 
167     /* Version info */
168     piSysMet[SM_TABLETPC] = 0;
169     piSysMet[SM_MEDIACENTER] = 0;
170     piSysMet[SM_STARTER] = 0;
171     piSysMet[SM_SERVERR2] = 0;
172     piSysMet[SM_PENWINDOWS] = 0;
173 
174     /* Other */
175     piSysMet[SM_DEBUG] = 0;
176     piSysMet[SM_NETWORK] = 3;
177     piSysMet[SM_SLOWMACHINE] = 0;
178     piSysMet[SM_SECURE] = 0;
179     piSysMet[SM_DBCSENABLED] = NLS_MB_CODE_PAGE_TAG;
180     piSysMet[SM_SHOWSOUNDS] = gspv.bShowSounds;
181     piSysMet[SM_MIDEASTENABLED] = 0;
182     piSysMet[SM_CMONITORS] = 1;
183     piSysMet[SM_SAMEDISPLAYFORMAT] = 1;
184     piSysMet[SM_IMMENABLED] = NLS_MB_CODE_PAGE_TAG;
185 
186     /* Reserved */
187     piSysMet[SM_RESERVED1] = 0;
188     piSysMet[SM_RESERVED2] = 0;
189     piSysMet[SM_RESERVED3] = 0;
190     piSysMet[SM_RESERVED4] = 0;
191     piSysMet[64] = 0;
192     piSysMet[65] = 0;
193     piSysMet[66] = 0;
194 #if (_WIN32_WINNT >= 0x0600)
195     piSysMet[90] = 0;
196 #endif
197 
198     if (UserIsDBCSEnabled())
199         gpsi->dwSRVIFlags |= SRVINFO_DBCSENABLED; /* DBCS Support */
200 
201     if (UserIsIMMEnabled())
202         gpsi->dwSRVIFlags |= SRVINFO_IMM32; /* IME Support */
203 
204     if (UserIsCiceroEnabled())
205         gpsi->dwSRVIFlags |= SRVINFO_CICERO_ENABLED; /* Cicero support */
206 
207     Setup = TRUE;
208 
209     return TRUE;
210 }
211 
212 LONG
213 NTAPI
214 UserGetSystemMetrics(ULONG Index)
215 {
216     ASSERT(gpsi);
217     ASSERT(Setup);
218     TRACE("UserGetSystemMetrics(%lu)\n", Index);
219 
220     if (Index == SM_DBCSENABLED)
221         return !!(gpsi->dwSRVIFlags & SRVINFO_DBCSENABLED);
222 
223     if (Index == SM_IMMENABLED)
224         return !!(gpsi->dwSRVIFlags & SRVINFO_IMM32);
225 
226     /* Get metrics from array */
227     if (Index < SM_CMETRICS)
228     {
229         return gpsi->aiSysMet[Index];
230     }
231 
232     /* Handle special values */
233     switch (Index)
234     {
235         case SM_REMOTESESSION:
236             return 0; // FIXME
237 
238         case SM_SHUTTINGDOWN:
239             return 0; // FIXME
240 
241         case SM_REMOTECONTROL:
242             return 0; // FIXME
243     }
244 
245     ERR("UserGetSystemMetrics() called with invalid index %lu\n", Index);
246     return 0;
247 }
248 
249 /* EOF */
250