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

Revision 93, 11.8 KB (checked in by mike, 2 years 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.