comctl32/tests: Use BOOL type where appropriate.
[wine.git] / dlls / winemac.drv / macdrv_main.c
blob5cdd13ce074d53a94aaf43b1b2100fa1c4a7f833
1 /*
2 * MACDRV initialization code
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2000 Alexandre Julliard
6 * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <Security/AuthSession.h>
25 #include <IOKit/pwr_mgt/IOPMLib.h>
27 #include "macdrv.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "wine/server.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
34 #ifndef kIOPMAssertionTypePreventUserIdleDisplaySleep
35 #define kIOPMAssertionTypePreventUserIdleDisplaySleep CFSTR("PreventUserIdleDisplaySleep")
36 #endif
37 #ifndef kCFCoreFoundationVersionNumber10_7
38 #define kCFCoreFoundationVersionNumber10_7 635.00
39 #endif
41 #define IS_OPTION_TRUE(ch) \
42 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
44 C_ASSERT(NUM_EVENT_TYPES <= sizeof(macdrv_event_mask) * 8);
46 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
48 int topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN;
49 int capture_displays_for_fullscreen = 0;
50 BOOL skip_single_buffer_flushes = FALSE;
51 BOOL allow_vsync = TRUE;
52 BOOL allow_set_gamma = TRUE;
53 int left_option_is_alt = 0;
54 int right_option_is_alt = 0;
55 BOOL allow_software_rendering = FALSE;
56 HMODULE macdrv_module = 0;
59 /**************************************************************************
60 * debugstr_cf
62 const char* debugstr_cf(CFTypeRef t)
64 CFStringRef s;
65 const char* ret;
67 if (!t) return "(null)";
69 if (CFGetTypeID(t) == CFStringGetTypeID())
70 s = t;
71 else
72 s = CFCopyDescription(t);
73 ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8);
74 if (ret) ret = debugstr_a(ret);
75 if (!ret)
77 const UniChar* u = CFStringGetCharactersPtr(s);
78 if (u)
79 ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s));
81 if (!ret)
83 UniChar buf[200];
84 int len = min(CFStringGetLength(s), sizeof(buf)/sizeof(buf[0]));
85 CFStringGetCharacters(s, CFRangeMake(0, len), buf);
86 ret = debugstr_wn(buf, len);
88 if (s != t) CFRelease(s);
89 return ret;
93 /***********************************************************************
94 * get_config_key
96 * Get a config key from either the app-specific or the default config
98 static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name,
99 char *buffer, DWORD size)
101 if (appkey && !RegQueryValueExA(appkey, name, 0, NULL, (LPBYTE)buffer, &size)) return 0;
102 if (defkey && !RegQueryValueExA(defkey, name, 0, NULL, (LPBYTE)buffer, &size)) return 0;
103 return ERROR_FILE_NOT_FOUND;
107 /***********************************************************************
108 * setup_options
110 * Set up the Mac driver options.
112 static void setup_options(void)
114 char buffer[MAX_PATH + 16];
115 HKEY hkey, appkey = 0;
116 DWORD len;
118 /* @@ Wine registry key: HKCU\Software\Wine\Mac Driver */
119 if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Mac Driver", &hkey)) hkey = 0;
121 /* open the app-specific key */
123 len = GetModuleFileNameA(0, buffer, MAX_PATH);
124 if (len && len < MAX_PATH)
126 HKEY tmpkey;
127 char *p, *appname = buffer;
128 if ((p = strrchr(appname, '/'))) appname = p + 1;
129 if ((p = strrchr(appname, '\\'))) appname = p + 1;
130 strcat(appname, "\\Mac Driver");
131 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Mac Driver */
132 if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey))
134 if (RegOpenKeyA(tmpkey, appname, &appkey)) appkey = 0;
135 RegCloseKey(tmpkey);
139 if (!get_config_key(hkey, appkey, "WindowsFloatWhenInactive", buffer, sizeof(buffer)))
141 if (!strcmp(buffer, "none"))
142 topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONE;
143 else if (!strcmp(buffer, "all"))
144 topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_ALL;
145 else
146 topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN;
149 if (!get_config_key(hkey, appkey, "CaptureDisplaysForFullscreen", buffer, sizeof(buffer)))
150 capture_displays_for_fullscreen = IS_OPTION_TRUE(buffer[0]);
152 if (!get_config_key(hkey, appkey, "SkipSingleBufferFlushes", buffer, sizeof(buffer)))
153 skip_single_buffer_flushes = IS_OPTION_TRUE(buffer[0]);
155 if (!get_config_key(hkey, appkey, "AllowVerticalSync", buffer, sizeof(buffer)))
156 allow_vsync = IS_OPTION_TRUE(buffer[0]);
158 if (!get_config_key(hkey, appkey, "AllowSetGamma", buffer, sizeof(buffer)))
159 allow_set_gamma = IS_OPTION_TRUE(buffer[0]);
161 if (!get_config_key(hkey, appkey, "LeftOptionIsAlt", buffer, sizeof(buffer)))
162 left_option_is_alt = IS_OPTION_TRUE(buffer[0]);
163 if (!get_config_key(hkey, appkey, "RightOptionIsAlt", buffer, sizeof(buffer)))
164 right_option_is_alt = IS_OPTION_TRUE(buffer[0]);
166 if (!get_config_key(hkey, appkey, "AllowSoftwareRendering", buffer, sizeof(buffer)))
167 allow_software_rendering = IS_OPTION_TRUE(buffer[0]);
169 if (appkey) RegCloseKey(appkey);
170 if (hkey) RegCloseKey(hkey);
174 /***********************************************************************
175 * process_attach
177 static BOOL process_attach(void)
179 SessionAttributeBits attributes;
180 OSStatus status;
182 status = SessionGetInfo(callerSecuritySession, NULL, &attributes);
183 if (status != noErr || !(attributes & sessionHasGraphicAccess))
184 return FALSE;
186 setup_options();
188 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
190 macdrv_err_on = ERR_ON(macdrv);
191 if (macdrv_start_cocoa_app(GetTickCount64()))
193 ERR("Failed to start Cocoa app main loop\n");
194 return FALSE;
197 macdrv_clipboard_process_attach();
199 return TRUE;
203 /***********************************************************************
204 * thread_detach
206 static void thread_detach(void)
208 struct macdrv_thread_data *data = macdrv_thread_data();
210 if (data)
212 macdrv_destroy_event_queue(data->queue);
213 if (data->keyboard_layout_uchr)
214 CFRelease(data->keyboard_layout_uchr);
215 HeapFree(GetProcessHeap(), 0, data);
216 /* clear data in case we get re-entered from user32 before the thread is truly dead */
217 TlsSetValue(thread_data_tls_index, NULL);
222 /***********************************************************************
223 * set_queue_display_fd
225 * Store the event queue fd into the message queue
227 static void set_queue_display_fd(int fd)
229 HANDLE handle;
230 int ret;
232 if (wine_server_fd_to_handle(fd, GENERIC_READ | SYNCHRONIZE, 0, &handle))
234 MESSAGE("macdrv: Can't allocate handle for event queue fd\n");
235 ExitProcess(1);
237 SERVER_START_REQ(set_queue_fd)
239 req->handle = wine_server_obj_handle(handle);
240 ret = wine_server_call(req);
242 SERVER_END_REQ;
243 if (ret)
245 MESSAGE("macdrv: Can't store handle for event queue fd\n");
246 ExitProcess(1);
248 CloseHandle(handle);
252 /***********************************************************************
253 * macdrv_init_thread_data
255 struct macdrv_thread_data *macdrv_init_thread_data(void)
257 struct macdrv_thread_data *data = macdrv_thread_data();
259 if (data) return data;
261 if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
263 ERR("could not create data\n");
264 ExitProcess(1);
267 if (!(data->queue = macdrv_create_event_queue(macdrv_handle_event)))
269 ERR("macdrv: Can't create event queue.\n");
270 ExitProcess(1);
273 data->keyboard_layout_uchr = macdrv_copy_keyboard_layout(&data->keyboard_type, &data->iso_keyboard);
274 macdrv_compute_keyboard_layout(data);
276 set_queue_display_fd(macdrv_get_event_queue_fd(data->queue));
277 TlsSetValue(thread_data_tls_index, data);
279 return data;
283 /***********************************************************************
284 * DllMain
286 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
288 BOOL ret = TRUE;
290 switch(reason)
292 case DLL_PROCESS_ATTACH:
293 macdrv_module = hinst;
294 ret = process_attach();
295 break;
296 case DLL_THREAD_DETACH:
297 thread_detach();
298 break;
300 return ret;
303 /***********************************************************************
304 * SystemParametersInfo (MACDRV.@)
306 BOOL CDECL macdrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
308 switch (action)
310 case SPI_GETSCREENSAVEACTIVE:
311 if (ptr_param)
313 CFDictionaryRef assertionStates;
314 IOReturn status = IOPMCopyAssertionsStatus(&assertionStates);
315 if (status == kIOReturnSuccess)
317 CFNumberRef count = CFDictionaryGetValue(assertionStates, kIOPMAssertionTypeNoDisplaySleep);
318 CFNumberRef count2 = CFDictionaryGetValue(assertionStates, kIOPMAssertionTypePreventUserIdleDisplaySleep);
319 long longCount = 0, longCount2 = 0;
321 if (count)
322 CFNumberGetValue(count, kCFNumberLongType, &longCount);
323 if (count2)
324 CFNumberGetValue(count2, kCFNumberLongType, &longCount2);
326 *(BOOL *)ptr_param = !longCount && !longCount2;
327 CFRelease(assertionStates);
329 else
331 WARN("Could not determine screen saver state, error code %d\n", status);
332 *(BOOL *)ptr_param = TRUE;
334 return TRUE;
336 break;
338 case SPI_SETSCREENSAVEACTIVE:
340 static IOPMAssertionID powerAssertion = kIOPMNullAssertionID;
341 if (int_param)
343 if (powerAssertion != kIOPMNullAssertionID)
345 IOPMAssertionRelease(powerAssertion);
346 powerAssertion = kIOPMNullAssertionID;
349 else if (powerAssertion == kIOPMNullAssertionID)
351 CFStringRef assertName;
352 /*Are we running Lion or later?*/
353 if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7)
354 assertName = kIOPMAssertionTypePreventUserIdleDisplaySleep;
355 else
356 assertName = kIOPMAssertionTypeNoDisplaySleep;
357 IOPMAssertionCreateWithName( assertName, kIOPMAssertionLevelOn,
358 CFSTR("Wine Process requesting no screen saver"),
359 &powerAssertion);
362 break;
364 return FALSE;