root/branches/0_9_1/qcontrol/cocoaControlDOServer.m

Revision 93, 11.8 kB (checked in by mike, 1 year ago)

[fix] remove crashed/stray guests from doServer (#15)
[fix] Q Control: StopPC Icon is a forcequit if task is not responding or doServer is not responding (#15)
[fix] Fullscreen: alt-tabing back to Q brings you back to FS Guest (#32)
[fix] Fullscreen: switching animation always vertical
[fix] Fullscreen: honor aspect ratio, only factors of 1/1.25/1.5/1.75/2.0/3.0/4.0... (#18)
[fix] doServer: added missing dealloc
[fix] quartz: panther compiling
[fix] quartz: small drawspeed improvements
[fix] backport bgr support for bigendians (andreasf) (#14)
[new] Q Control: EditPC can be used (read only) when guest is running (#23)
[new] Q Control: commandline as tooltips of guests (#23)
[new] Q icon

Line 
1 /*
2  * QEMU Cocoa Control Distributed Object Server
3  *
4  * Copyright (c) 2006 - 2007 Mike Kronenberg
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 #import <unistd.h>
26
27 #import "cocoaControlDOServer.h"
28
29 #import "cocoaControlController.h"
30
31 #import "../host-cocoa/CGSPrivate.h"
32
33 @implementation cocoaControlDOServer
34
35 - (id) init
36 {
37 //    NSLog(@"cocoaControlDOServer: init");
38
39     [super init];
40
41     NSConnection *theConnection;
42     theConnection = [NSConnection defaultConnection];
43     [theConnection setRootObject:self];
44
45     if ([theConnection registerName:@"qdoserver"] == NO) {
46         NSLog(@"cocoaControlDOServer: could not establisch qcontrol server");
47     }
48
49     guests = [[NSMutableDictionary alloc] init];
50     [guests retain];
51
52     return self;
53 }
54
55 - (void) dealloc
56 {
57 //    NSLog(@"cocoaControlDOServer: dealloc");
58
59     [guests release];
60
61     if (lastGuestDeactivated) {
62         [lastGuestDeactivated release];
63     }
64
65     [super dealloc];
66 }
67
68 -(void) setSender:(id)sender
69 {
70 //    NSLog(@"cocoaControlDOServer: setSender");
71
72     qControl = sender;
73 }
74
75 - (BOOL) guestRegister: (id) guest withName: (NSString *) name
76 {
77 //    NSLog(@"cocoaControlDOServer: registerGuest:%@ withName:%@\n", [guest description], name);
78    
79     if ([guests objectForKey:name] == nil) {
80         [guests setObject:guest forKey:name];
81 //      NSLog(@"OK");
82         return TRUE;
83     } else {
84         NSLog(@"cocoaControlDOServer: guestRegister: failed");
85         return FALSE;
86     }
87 }
88
89 - (BOOL) guestUnregisterWithName: (NSString *) name
90 {
91 //    NSLog(@"cocoaControlDOServer: unregisterGuestWithName:%@\n", name);
92    
93     if ([guests objectForKey:name] != nil) {
94         [guests removeObjectForKey:name];
95         return TRUE;
96     } else {
97         NSLog(@"cocoaControlDOServer: guestUnregisterWithName: failed");
98         return FALSE;
99     }
100 }
101
102 - (BOOL) guestSwitch: (NSString *) name fullscreen:(BOOL)fullscreen previousGuestName:(NSString *)previousGuestName
103 {
104 //    NSLog(@"guestSwitch: windowSwitchKeyPressed:%@ fullscreen:%d previousGuest:%@\n", name, fullscreen, previousGuestName);
105
106     int i;
107     NSArray *keys = [guests allKeys];
108     int a = [keys count] - 1;
109
110     if (previousGuestName) {
111         for (i = 0; i < [keys count]; i++) {
112             if ([[keys objectAtIndex:i] isEqual:previousGuestName]) {
113                 a = i;
114             }
115         }
116     } else {
117         for (i = 0; i < [keys count]; i++) {
118             if ([[keys objectAtIndex:i] isEqual:name]) {
119                 a = i - 1;
120             }
121         }
122     }
123
124     ProcessSerialNumber psn;
125     id obj = nil;
126     BOOL nFullscreen = FALSE;
127
128     if (a > -1) {
129         /* move QEMU to front */
130         GetProcessForPID( [[[qControl pcsTasks] objectForKey:[keys objectAtIndex:a]] processIdentifier], &psn );
131         obj = [guests objectForKey:[keys objectAtIndex:a]];
132         if ([obj fullscreen])
133             nFullscreen = TRUE;
134     } else
135         GetProcessForPID( [[NSProcessInfo processInfo ] processIdentifier ], &psn );
136
137     if (fullscreen||nFullscreen) {
138         /* setup transition */
139         CGSConnection cid = _CGSDefaultConnection();
140         int transitionHandle = -1;
141         CGSTransitionSpec transitionSpecifications;
142
143         transitionSpecifications.type = 7;          //transition;
144         transitionSpecifications.option = 0;        //option;
145         transitionSpecifications.wid = 0;           //wid
146         transitionSpecifications.backColour = 0;    //background color
147
148         /* freeze desktop: OSStatus CGSNewTransition(const CGSConnection cid, const CGSTransitionSpec* transitionSpecifications, int *transitionHandle) */
149         CGSNewTransition(cid, &transitionSpecifications, &transitionHandle);
150
151         /* change windows */
152         if (nFullscreen)
153             [obj guestUnhide];
154
155         if (fullscreen)
156             [[guests objectForKey:name] guestHide];
157
158         if (a > -1) //avoid activating "Q Control"
159             SetFrontProcess( &psn );
160         else {
161             [[qControl mainWindow] orderWindow:NSWindowAbove relativeTo:[[guests objectForKey:name] guestWindowNumber]];
162             SetFrontProcess( &psn );
163         }
164
165         /* wait */
166         usleep(10000);
167
168         /* run transition: OSStatus CGSInvokeTransition(const CGSConnection cid, int transitionHandle, float duration) */
169         CGSInvokeTransition(cid, transitionHandle, 1.0);
170        
171     } else {
172         if (a > -1) //avoid activating "Q Control"
173             SetFrontProcess( &psn );
174         else {
175             [[qControl mainWindow] orderWindow:NSWindowAbove relativeTo:[[guests objectForKey:name] guestWindowNumber]];
176             SetFrontProcess( &psn );
177         }
178     }
179
180     return true;
181 }
182
183 - (BOOL) guestSwitch: (NSString *) name fullscreen:(BOOL)fullscreen nextGuestName:(NSString *)nextGuestName
184 {
185 //    NSLog(@"guestSwitch: windowSwitchKeyPressed:%@ fullscreen:%d nextGuest:%@\n", name, fullscreen, nextGuestName);
186
187     int i;
188     int a = 0;
189     NSArray *keys = [guests allKeys];
190
191     if (nextGuestName) {
192         for (i = 0; i < [keys count]; i++) {
193             if ([[keys objectAtIndex:i] isEqual:nextGuestName]) {
194                 a = i;
195             }
196         }
197     } else {
198         for (i = 0; i < [keys count]; i++) {
199             if ([[keys objectAtIndex:i] isEqual:name]) {
200                 a = i + 1;
201             }
202         }
203     }
204
205     ProcessSerialNumber psn;
206     id obj = nil;
207     BOOL nFullscreen = FALSE;
208
209     if (a < [keys count]) {
210         /* move QEMU to front */
211         GetProcessForPID( [[[qControl pcsTasks] objectForKey:[keys objectAtIndex:a]] processIdentifier], &psn );
212         obj = [guests objectForKey:[keys objectAtIndex:a]];
213         if ([obj fullscreen])
214             nFullscreen = TRUE;
215     } else
216         GetProcessForPID( [[NSProcessInfo processInfo ] processIdentifier ], &psn );
217
218     if (fullscreen||nFullscreen) {
219         /* setup transition */
220         CGSConnection cid = _CGSDefaultConnection();
221         int transitionHandle = -1;
222         CGSTransitionSpec transitionSpecifications;
223
224         transitionSpecifications.type = 7;          //transition;
225         transitionSpecifications.option = 8;        //option;
226         transitionSpecifications.wid = 0;           //wid
227         transitionSpecifications.backColour = 0;    //background color
228
229         /* freeze desktop: OSStatus CGSNewTransition(const CGSConnection cid, const CGSTransitionSpec* transitionSpecifications, int *transitionHandle) */
230         CGSNewTransition(cid, &transitionSpecifications, &transitionHandle);
231                            
232         /* change windows */
233         if (nFullscreen)
234             [obj guestUnhide];
235
236         if (fullscreen)
237             [[guests objectForKey:name] guestHide];
238
239         if (a < [keys count]) //avoid activating "Q Control"
240             SetFrontProcess( &psn );
241         else {
242             [[qControl mainWindow] orderWindow:NSWindowAbove relativeTo:[[guests objectForKey:name] guestWindowNumber]];
243             SetFrontProcess( &psn );
244         }
245
246         /* wait */
247         usleep(10000);
248
249         /* run transition: OSStatus CGSInvokeTransition(const CGSConnection cid, int transitionHandle, float duration) */
250         CGSInvokeTransition(cid, transitionHandle, 1.0);
251
252     } else {
253         if (a < [keys count]) //avoid activating "Q Control"
254             SetFrontProcess( &psn );
255         else {
256             [[qControl mainWindow] orderWindow:NSWindowAbove relativeTo:[[guests objectForKey:name] guestWindowNumber]];
257             SetFrontProcess( &psn );
258         }
259     }
260    
261     return true;
262 }
263
264 /* NEED SOME DOXYGEN HERE */
265 - (BOOL) guestDeactivated: (bycopy NSString *) name
266 {
267 //    NSLog(@"cocoaControlDOServer: guestDeactivated: %@", name);
268
269     if (lastGuestDeactivated) {
270         [lastGuestDeactivated release];
271     }
272     if (name) {
273         lastGuestDeactivated = [NSString stringWithString:name];
274         [lastGuestDeactivated retain];
275     } else {
276         lastGuestDeactivated = nil;
277     }
278
279     return TRUE;
280 }
281
282 - (int) guestWindowLevel: (NSString *) guest
283 {
284 //  NSLog(@"cocoaControlDOServer: guestWindowLevel: %@", guest);
285
286     id obj = [guests objectForKey:guest];
287     if (obj != nil) {
288 //      NSLog(@"OK");
289         return [obj guestWindowLevel];
290     } else {
291         NSLog(@"cocoaControlDOServer: guestWindowLevel: failed");
292         return FALSE;
293     }
294 }
295
296 - (int) guestWindowNumber: (NSString *) guest
297 {
298 //  NSLog(@"cocoaControlDOServer: guestWindowNumber: %@", guest);
299
300     id obj = [guests objectForKey:guest];
301     if (obj != nil) {
302 //      NSLog(@"OK");
303         return [obj guestWindowNumber];
304     } else {
305 //        NSLog(@"cocoaControlDOServer: guestWindowNumber: failed");
306         return FALSE;
307     }
308 }
309
310 - (BOOL) guestOrderFrontRegardless: (NSString *) guest
311 {
312 //  NSLog(@"cocoaControlDOServer: bringToFront: %@", guest);
313
314     id obj = [guests objectForKey:guest];
315     if (obj != nil) {
316 //      NSLog(@"OK");
317         return [obj guestOrderFrontRegardless];
318     } else {
319         NSLog(@"cocoaControlDOServer: guestOrderFrontRegardless");
320         return FALSE;
321     }
322 }
323
324 - (BOOL) guestOrderWindow:(NSWindowOrderingMode)place relativeTo:(int)otherWindowNumber guest:(NSString *) guest
325 {
326 //  NSLog(@"cocoaControlDOServer: guestOrderWindow: %@", guest);
327
328     id obj = [guests objectForKey:guest];
329     if (obj != nil) {
330 //      NSLog(@"OK");
331         return [obj guestOrderWindow:place relativeTo:otherWindowNumber];
332     } else {
333         NSLog(@"cocoaControlDOServer: guestOrderWindow: failed");
334         return FALSE;
335     }
336 }
337
338 - (BOOL) guestHide: (NSString *) guest
339 {
340 //  NSLog(@"cocoaControlDOServer: hide: %@", guest);
341
342     id obj = [guests objectForKey:guest];
343     if (obj != nil) {
344 //      NSLog(@"OK");
345         return [obj guestHide];
346     } else {
347         NSLog(@"cocoaControlDOServer: guestHide: failed");
348         return FALSE;
349     }
350 }
351
352 - (BOOL) guestUnhide: (NSString *) guest
353 {
354 //  NSLog(@"cocoaControlDOServer: show: %@", guest);
355
356     id obj = [guests objectForKey:guest];
357     if (obj != nil) {
358 //      NSLog(@"OK");
359         return [obj guestUnhide];
360     } else {
361         NSLog(@"cocoaControlDOServer: cocoaControlDOServer: failed");
362         return FALSE;
363     }
364 }
365
366 - (BOOL) guestPause: (NSString *) guest
367 {
368 //  NSLog(@"cocoaControlDOServer: pause: %@", guest);
369
370     id obj = [guests objectForKey:guest];
371     if (obj != nil) {
372 //      NSLog(@"OK");
373         return [obj guestPause];
374     } else {
375         NSLog(@"cocoaControlDOServer: cocoaControlDOServer: failed");
376         return FALSE;
377     }
378 }
379
380 - (BOOL) guestStop: (NSString *) guest
381 {
382 //  NSLog(@"cocoaControlDOServer: stop: %@", guest);
383
384     id obj = [guests objectForKey:guest];
385     if (obj != nil) {
386         return [obj guestStop];
387     } else {
388         NSLog(@"cocoaControlDOServer: cocoaControlDOServer: failed");
389         return FALSE;
390     }
391 }
392
393 - (id) lastGuestDeactivated
394 {
395 //  NSLog(@"cocoaControlDOServer: lastGuestDeactivated: %@", lastGuestDeactivated);
396
397     if (lastGuestDeactivated) {
398         if ([[guests objectForKey:lastGuestDeactivated] fullscreen]) {
399             return lastGuestDeactivated;
400         }
401     }
402     return nil;
403 }
404
405 - (NSMutableDictionary *) guests
406 {
407     return guests;
408 }
409 @end
Note: See TracBrowser for help on using the browser.