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
24 #include <Security/AuthSession.h>
25 #include <IOKit/pwr_mgt/IOPMLib.h>
29 #include "wine/server.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
33 #ifndef kIOPMAssertionTypePreventUserIdleDisplaySleep
34 #define kIOPMAssertionTypePreventUserIdleDisplaySleep CFSTR("PreventUserIdleDisplaySleep")
36 #ifndef kCFCoreFoundationVersionNumber10_7
37 #define kCFCoreFoundationVersionNumber10_7 635.00
40 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
43 /**************************************************************************
46 const char* debugstr_cf(CFTypeRef t)
51 if (!t) return "(null)";
53 if (CFGetTypeID(t) == CFStringGetTypeID())
56 s = CFCopyDescription(t);
57 ret = CFStringGetCStringPtr(s, kCFStringEncodingUTF8);
58 if (ret) ret = debugstr_a(ret);
61 const UniChar* u = CFStringGetCharactersPtr(s);
63 ret = debugstr_wn((const WCHAR*)u, CFStringGetLength(s));
68 int len = min(CFStringGetLength(s), sizeof(buf)/sizeof(buf[0]));
69 CFStringGetCharacters(s, CFRangeMake(0, len), buf);
70 ret = debugstr_wn(buf, len);
72 if (s != t) CFRelease(s);
77 /***********************************************************************
80 static void set_app_icon(void)
82 CFArrayRef images = create_app_icon_images();
85 macdrv_set_application_icon(images);
91 /***********************************************************************
94 static BOOL process_attach(void)
96 SessionAttributeBits attributes;
99 assert(NUM_EVENT_TYPES <= sizeof(macdrv_event_mask) * 8);
101 status = SessionGetInfo(callerSecuritySession, NULL, &attributes);
102 if (status != noErr || !(attributes & sessionHasGraphicAccess))
105 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
107 macdrv_err_on = ERR_ON(macdrv);
108 if (macdrv_start_cocoa_app(GetTickCount64()))
110 ERR("Failed to start Cocoa app main loop\n");
115 macdrv_clipboard_process_attach();
121 /***********************************************************************
124 static void thread_detach(void)
126 struct macdrv_thread_data *data = macdrv_thread_data();
130 macdrv_destroy_event_queue(data->queue);
131 if (data->keyboard_layout_uchr)
132 CFRelease(data->keyboard_layout_uchr);
133 HeapFree(GetProcessHeap(), 0, data);
138 /***********************************************************************
139 * set_queue_display_fd
141 * Store the event queue fd into the message queue
143 static void set_queue_display_fd(int fd)
148 if (wine_server_fd_to_handle(fd, GENERIC_READ | SYNCHRONIZE, 0, &handle))
150 MESSAGE("macdrv: Can't allocate handle for event queue fd\n");
153 SERVER_START_REQ(set_queue_fd)
155 req->handle = wine_server_obj_handle(handle);
156 ret = wine_server_call(req);
161 MESSAGE("macdrv: Can't store handle for event queue fd\n");
168 /***********************************************************************
169 * macdrv_init_thread_data
171 struct macdrv_thread_data *macdrv_init_thread_data(void)
173 struct macdrv_thread_data *data = macdrv_thread_data();
175 if (data) return data;
177 if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
179 ERR("could not create data\n");
183 if (!(data->queue = macdrv_create_event_queue(macdrv_handle_event)))
185 ERR("macdrv: Can't create event queue.\n");
189 data->keyboard_layout_uchr = macdrv_copy_keyboard_layout(&data->keyboard_type, &data->iso_keyboard);
190 macdrv_compute_keyboard_layout(data);
192 set_queue_display_fd(macdrv_get_event_queue_fd(data->queue));
193 TlsSetValue(thread_data_tls_index, data);
199 /***********************************************************************
202 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
208 case DLL_PROCESS_ATTACH:
209 IME_RegisterClasses(hinst);
210 ret = process_attach();
212 case DLL_THREAD_DETACH:
219 /***********************************************************************
220 * SystemParametersInfo (MACDRV.@)
222 BOOL CDECL macdrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
226 case SPI_GETSCREENSAVEACTIVE:
229 CFDictionaryRef assertionStates;
230 IOReturn status = IOPMCopyAssertionsStatus(&assertionStates);
231 if (status == kIOReturnSuccess)
233 CFNumberRef count = CFDictionaryGetValue(assertionStates, kIOPMAssertionTypeNoDisplaySleep);
234 CFNumberRef count2 = CFDictionaryGetValue(assertionStates, kIOPMAssertionTypePreventUserIdleDisplaySleep);
235 long longCount = 0, longCount2 = 0;
238 CFNumberGetValue(count, kCFNumberLongType, &longCount);
240 CFNumberGetValue(count2, kCFNumberLongType, &longCount2);
242 *(BOOL *)ptr_param = !longCount && !longCount2;
243 CFRelease(assertionStates);
247 WARN("Could not determine screen saver state, error code %d\n", status);
248 *(BOOL *)ptr_param = TRUE;
254 case SPI_SETSCREENSAVEACTIVE:
256 static IOPMAssertionID powerAssertion = kIOPMNullAssertionID;
259 if (powerAssertion != kIOPMNullAssertionID)
261 IOPMAssertionRelease(powerAssertion);
262 powerAssertion = kIOPMNullAssertionID;
265 else if (powerAssertion == kIOPMNullAssertionID)
267 CFStringRef assertName;
268 /*Are we running Lion or later?*/
269 if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7)
270 assertName = kIOPMAssertionTypePreventUserIdleDisplaySleep;
272 assertName = kIOPMAssertionTypeNoDisplaySleep;
273 IOPMAssertionCreateWithName( assertName, kIOPMAssertionLevelOn,
274 CFSTR("Wine Process requesting no screen saver"),