root / cocoa.m @ 6f15b608
History | View | Annotate | Download (33.7 kB)
1 | 5b0753e0 | bellard | /* |
---|---|---|---|
2 | 5b0753e0 | bellard | * QEMU Cocoa display driver |
3 | 5b0753e0 | bellard | * |
4 | 5b0753e0 | bellard | * Copyright (c) 2005 Pierre d'Herbemont |
5 | 5b0753e0 | bellard | * many code/inspiration from SDL 1.2 code (LGPL) |
6 | 5b0753e0 | bellard | * |
7 | 5b0753e0 | bellard | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | 5b0753e0 | bellard | * of this software and associated documentation files (the "Software"), to deal |
9 | 5b0753e0 | bellard | * in the Software without restriction, including without limitation the rights |
10 | 5b0753e0 | bellard | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | 5b0753e0 | bellard | * copies of the Software, and to permit persons to whom the Software is |
12 | 5b0753e0 | bellard | * furnished to do so, subject to the following conditions: |
13 | 5b0753e0 | bellard | * |
14 | 5b0753e0 | bellard | * The above copyright notice and this permission notice shall be included in |
15 | 5b0753e0 | bellard | * all copies or substantial portions of the Software. |
16 | 5b0753e0 | bellard | * |
17 | 5b0753e0 | bellard | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | 5b0753e0 | bellard | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | 5b0753e0 | bellard | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
20 | 5b0753e0 | bellard | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | 5b0753e0 | bellard | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | 5b0753e0 | bellard | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
23 | 5b0753e0 | bellard | * THE SOFTWARE. |
24 | 5b0753e0 | bellard | */ |
25 | 5b0753e0 | bellard | /* |
26 | 5b0753e0 | bellard | Todo : x miniaturize window |
27 | 5b0753e0 | bellard | x center the window |
28 | 5b0753e0 | bellard | - save window position |
29 | 5b0753e0 | bellard | - handle keyboard event |
30 | 5b0753e0 | bellard | - handle mouse event |
31 | 5b0753e0 | bellard | - non 32 bpp support |
32 | 5b0753e0 | bellard | - full screen |
33 | 5b0753e0 | bellard | - mouse focus |
34 | 5b0753e0 | bellard | x simple graphical prompt to demo |
35 | 5b0753e0 | bellard | - better graphical prompt |
36 | 5b0753e0 | bellard | */ |
37 | da4dbf74 | bellard | |
38 | 5b0753e0 | bellard | #import <Cocoa/Cocoa.h> |
39 | 5b0753e0 | bellard | |
40 | da4dbf74 | bellard | #include "vl.h" |
41 | da4dbf74 | bellard | |
42 | 5b0753e0 | bellard | NSWindow *window = NULL; |
43 | 5b0753e0 | bellard | NSQuickDrawView *qd_view = NULL; |
44 | 5b0753e0 | bellard | |
45 | 5b0753e0 | bellard | |
46 | 5b0753e0 | bellard | int gArgc; |
47 | 5b0753e0 | bellard | char **gArgv; |
48 | 5b0753e0 | bellard | DisplayState current_ds; |
49 | 5b0753e0 | bellard | |
50 | 87f48e6a | bellard | int grab = 0; |
51 | 87f48e6a | bellard | int modifiers_state[256]; |
52 | 87f48e6a | bellard | |
53 | 5b0753e0 | bellard | /* main defined in qemu/vl.c */ |
54 | 5b0753e0 | bellard | int qemu_main(int argc, char **argv); |
55 | 5b0753e0 | bellard | |
56 | 5b0753e0 | bellard | /* To deal with miniaturization */ |
57 | 5b0753e0 | bellard | @interface QemuWindow : NSWindow |
58 | 5b0753e0 | bellard | { } |
59 | 5b0753e0 | bellard | @end |
60 | 5b0753e0 | bellard | |
61 | 5b0753e0 | bellard | |
62 | 5b0753e0 | bellard | /* |
63 | 5b0753e0 | bellard | ------------------------------------------------------ |
64 | 5b0753e0 | bellard | Qemu Video Driver |
65 | 5b0753e0 | bellard | ------------------------------------------------------ |
66 | 5b0753e0 | bellard | */ |
67 | 5b0753e0 | bellard | |
68 | 5b0753e0 | bellard | /* |
69 | 5b0753e0 | bellard | ------------------------------------------------------ |
70 | 5b0753e0 | bellard | cocoa_update |
71 | 5b0753e0 | bellard | ------------------------------------------------------ |
72 | 5b0753e0 | bellard | */ |
73 | 5b0753e0 | bellard | static void cocoa_update(DisplayState *ds, int x, int y, int w, int h) |
74 | 5b0753e0 | bellard | { |
75 | 5b0753e0 | bellard | //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h); |
76 | 5b0753e0 | bellard | |
77 | 5b0753e0 | bellard | /* Use QDFlushPortBuffer() to flush content to display */ |
78 | 5b0753e0 | bellard | RgnHandle dirty = NewRgn (); |
79 | 5b0753e0 | bellard | RgnHandle temp = NewRgn (); |
80 | 5b0753e0 | bellard | |
81 | 5b0753e0 | bellard | SetEmptyRgn (dirty); |
82 | 5b0753e0 | bellard | |
83 | 5b0753e0 | bellard | /* Build the region of dirty rectangles */ |
84 | 5b0753e0 | bellard | MacSetRectRgn (temp, x, y, |
85 | 5b0753e0 | bellard | x + w, y + h); |
86 | 5b0753e0 | bellard | MacUnionRgn (dirty, temp, dirty); |
87 | 5b0753e0 | bellard | |
88 | 5b0753e0 | bellard | /* Flush the dirty region */ |
89 | 5b0753e0 | bellard | QDFlushPortBuffer ( [ qd_view qdPort ], dirty ); |
90 | 5b0753e0 | bellard | DisposeRgn (dirty); |
91 | 5b0753e0 | bellard | DisposeRgn (temp); |
92 | 5b0753e0 | bellard | } |
93 | 5b0753e0 | bellard | |
94 | 5b0753e0 | bellard | /* |
95 | 5b0753e0 | bellard | ------------------------------------------------------ |
96 | 5b0753e0 | bellard | cocoa_resize |
97 | 5b0753e0 | bellard | ------------------------------------------------------ |
98 | 5b0753e0 | bellard | */ |
99 | 5b0753e0 | bellard | static void cocoa_resize(DisplayState *ds, int w, int h) |
100 | 5b0753e0 | bellard | { |
101 | 5b0753e0 | bellard | const int device_bpp = 32; |
102 | 5b0753e0 | bellard | static void *screen_pixels; |
103 | 5b0753e0 | bellard | static int screen_pitch; |
104 | 5b0753e0 | bellard | NSRect contentRect; |
105 | 5b0753e0 | bellard | |
106 | 5b0753e0 | bellard | //printf("resizing to %d %d\n", w, h); |
107 | 5b0753e0 | bellard | |
108 | 5b0753e0 | bellard | contentRect = NSMakeRect (0, 0, w, h); |
109 | 5b0753e0 | bellard | if(window) |
110 | 5b0753e0 | bellard | { |
111 | 5b0753e0 | bellard | [window close]; |
112 | 5b0753e0 | bellard | [window release]; |
113 | 5b0753e0 | bellard | } |
114 | 5b0753e0 | bellard | window = [ [ QemuWindow alloc ] initWithContentRect:contentRect |
115 | 5b0753e0 | bellard | styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask |
116 | 5b0753e0 | bellard | backing:NSBackingStoreBuffered defer:NO]; |
117 | 5b0753e0 | bellard | if(!window) |
118 | 5b0753e0 | bellard | { |
119 | 5b0753e0 | bellard | fprintf(stderr, "(cocoa) can't create window\n"); |
120 | 5b0753e0 | bellard | exit(1); |
121 | 5b0753e0 | bellard | } |
122 | 5b0753e0 | bellard | |
123 | 5b0753e0 | bellard | if(qd_view) |
124 | 5b0753e0 | bellard | [qd_view release]; |
125 | 5b0753e0 | bellard | |
126 | 5b0753e0 | bellard | qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ]; |
127 | 5b0753e0 | bellard | |
128 | 5b0753e0 | bellard | if(!qd_view) |
129 | 5b0753e0 | bellard | { |
130 | 5b0753e0 | bellard | fprintf(stderr, "(cocoa) can't create qd_view\n"); |
131 | 5b0753e0 | bellard | exit(1); |
132 | 5b0753e0 | bellard | } |
133 | 5b0753e0 | bellard | |
134 | 5b0753e0 | bellard | [ window setAcceptsMouseMovedEvents:YES ]; |
135 | 5b0753e0 | bellard | [ window setTitle:@"Qemu" ]; |
136 | 5b0753e0 | bellard | [ window setReleasedWhenClosed:NO ]; |
137 | 5b0753e0 | bellard | |
138 | 5b0753e0 | bellard | /* Set screen to black */ |
139 | 5b0753e0 | bellard | [ window setBackgroundColor: [NSColor blackColor] ]; |
140 | 5b0753e0 | bellard | |
141 | 5b0753e0 | bellard | /* set window position */ |
142 | 5b0753e0 | bellard | [ window center ]; |
143 | 5b0753e0 | bellard | |
144 | 5b0753e0 | bellard | [ qd_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; |
145 | 5b0753e0 | bellard | [ [ window contentView ] addSubview:qd_view ]; |
146 | 5b0753e0 | bellard | [ qd_view release ]; |
147 | 5b0753e0 | bellard | [ window makeKeyAndOrderFront:nil ]; |
148 | 5b0753e0 | bellard | |
149 | 5b0753e0 | bellard | /* Careful here, the window seems to have to be onscreen to do that */ |
150 | 5b0753e0 | bellard | LockPortBits ( [ qd_view qdPort ] ); |
151 | 5b0753e0 | bellard | screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort ] ) ); |
152 | 5b0753e0 | bellard | screen_pitch = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort ] ) ); |
153 | 5b0753e0 | bellard | UnlockPortBits ( [ qd_view qdPort ] ); |
154 | 5b0753e0 | bellard | { |
155 | 5b0753e0 | bellard | int vOffset = [ window frame ].size.height - |
156 | 5b0753e0 | bellard | [ qd_view frame ].size.height - [ qd_view frame ].origin.y; |
157 | 5b0753e0 | bellard | |
158 | 5b0753e0 | bellard | int hOffset = [ qd_view frame ].origin.x; |
159 | 5b0753e0 | bellard | |
160 | 5b0753e0 | bellard | screen_pixels += (vOffset * screen_pitch) + hOffset * (device_bpp/8); |
161 | 5b0753e0 | bellard | } |
162 | 5b0753e0 | bellard | ds->data = screen_pixels; |
163 | 5b0753e0 | bellard | ds->linesize = screen_pitch; |
164 | 5b0753e0 | bellard | ds->depth = device_bpp; |
165 | 5b0753e0 | bellard | ds->width = w; |
166 | 5b0753e0 | bellard | ds->height = h; |
167 | 5b0753e0 | bellard | |
168 | 5b0753e0 | bellard | current_ds = *ds; |
169 | 5b0753e0 | bellard | } |
170 | 5b0753e0 | bellard | |
171 | 5b0753e0 | bellard | /* |
172 | 5b0753e0 | bellard | ------------------------------------------------------ |
173 | 5b0753e0 | bellard | keymap conversion |
174 | 5b0753e0 | bellard | ------------------------------------------------------ |
175 | 5b0753e0 | bellard | */ |
176 | 5b0753e0 | bellard | |
177 | 87f48e6a | bellard | int keymap[] = |
178 | 5b0753e0 | bellard | { |
179 | 87f48e6a | bellard | // SdlI macI macH SdlH 104xtH 104xtC sdl |
180 | 87f48e6a | bellard | 30, // 0 0x00 0x1e A QZ_a |
181 | 87f48e6a | bellard | 31, // 1 0x01 0x1f S QZ_s |
182 | 87f48e6a | bellard | 32, // 2 0x02 0x20 D QZ_d |
183 | 87f48e6a | bellard | 33, // 3 0x03 0x21 F QZ_f |
184 | 87f48e6a | bellard | 35, // 4 0x04 0x23 H QZ_h |
185 | 87f48e6a | bellard | 34, // 5 0x05 0x22 G QZ_g |
186 | 87f48e6a | bellard | 44, // 6 0x06 0x2c Z QZ_z |
187 | 87f48e6a | bellard | 45, // 7 0x07 0x2d X QZ_x |
188 | 87f48e6a | bellard | 46, // 8 0x08 0x2e C QZ_c |
189 | 87f48e6a | bellard | 47, // 9 0x09 0x2f V QZ_v |
190 | 87f48e6a | bellard | 0, // 10 0x0A Undefined |
191 | 87f48e6a | bellard | 48, // 11 0x0B 0x30 B QZ_b |
192 | 87f48e6a | bellard | 16, // 12 0x0C 0x10 Q QZ_q |
193 | 87f48e6a | bellard | 17, // 13 0x0D 0x11 W QZ_w |
194 | 87f48e6a | bellard | 18, // 14 0x0E 0x12 E QZ_e |
195 | 87f48e6a | bellard | 19, // 15 0x0F 0x13 R QZ_r |
196 | 87f48e6a | bellard | 21, // 16 0x10 0x15 Y QZ_y |
197 | 87f48e6a | bellard | 20, // 17 0x11 0x14 T QZ_t |
198 | 87f48e6a | bellard | 2, // 18 0x12 0x02 1 QZ_1 |
199 | 87f48e6a | bellard | 3, // 19 0x13 0x03 2 QZ_2 |
200 | 87f48e6a | bellard | 4, // 20 0x14 0x04 3 QZ_3 |
201 | 87f48e6a | bellard | 5, // 21 0x15 0x05 4 QZ_4 |
202 | 87f48e6a | bellard | 7, // 22 0x16 0x07 6 QZ_6 |
203 | 87f48e6a | bellard | 6, // 23 0x17 0x06 5 QZ_5 |
204 | 87f48e6a | bellard | 13, // 24 0x18 0x0d = QZ_EQUALS |
205 | 87f48e6a | bellard | 10, // 25 0x19 0x0a 9 QZ_9 |
206 | 87f48e6a | bellard | 8, // 26 0x1A 0x08 7 QZ_7 |
207 | 87f48e6a | bellard | 12, // 27 0x1B 0x0c - QZ_MINUS |
208 | 87f48e6a | bellard | 9, // 28 0x1C 0x09 8 QZ_8 |
209 | 87f48e6a | bellard | 11, // 29 0x1D 0x0b 0 QZ_0 |
210 | 87f48e6a | bellard | 27, // 30 0x1E 0x1b ] QZ_RIGHTBRACKET |
211 | 87f48e6a | bellard | 24, // 31 0x1F 0x18 O QZ_o |
212 | 87f48e6a | bellard | 22, // 32 0x20 0x16 U QZ_u |
213 | 87f48e6a | bellard | 26, // 33 0x21 0x1a [ QZ_LEFTBRACKET |
214 | 87f48e6a | bellard | 23, // 34 0x22 0x17 I QZ_i |
215 | 87f48e6a | bellard | 25, // 35 0x23 0x19 P QZ_p |
216 | 87f48e6a | bellard | 28, // 36 0x24 0x1c ENTER QZ_RETURN |
217 | 87f48e6a | bellard | 38, // 37 0x25 0x26 L QZ_l |
218 | 87f48e6a | bellard | 36, // 38 0x26 0x24 J QZ_j |
219 | 87f48e6a | bellard | 40, // 39 0x27 0x28 ' QZ_QUOTE |
220 | 87f48e6a | bellard | 37, // 40 0x28 0x25 K QZ_k |
221 | 87f48e6a | bellard | 39, // 41 0x29 0x27 ; QZ_SEMICOLON |
222 | 87f48e6a | bellard | 43, // 42 0x2A 0x2b \ QZ_BACKSLASH |
223 | 87f48e6a | bellard | 51, // 43 0x2B 0x33 , QZ_COMMA |
224 | 87f48e6a | bellard | 53, // 44 0x2C 0x35 / QZ_SLASH |
225 | 87f48e6a | bellard | 49, // 45 0x2D 0x31 N QZ_n |
226 | 87f48e6a | bellard | 50, // 46 0x2E 0x32 M QZ_m |
227 | 87f48e6a | bellard | 52, // 47 0x2F 0x34 . QZ_PERIOD |
228 | 87f48e6a | bellard | 15, // 48 0x30 0x0f TAB QZ_TAB |
229 | 87f48e6a | bellard | 57, // 49 0x31 0x39 SPACE QZ_SPACE |
230 | 87f48e6a | bellard | 41, // 50 0x32 0x29 ` QZ_BACKQUOTE |
231 | 87f48e6a | bellard | 14, // 51 0x33 0x0e BKSP QZ_BACKSPACE |
232 | 87f48e6a | bellard | 0, // 52 0x34 Undefined |
233 | 87f48e6a | bellard | 1, // 53 0x35 0x01 ESC QZ_ESCAPE |
234 | 87f48e6a | bellard | 0, // 54 0x36 QZ_RMETA |
235 | 87f48e6a | bellard | 0, // 55 0x37 QZ_LMETA |
236 | 87f48e6a | bellard | 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT |
237 | 87f48e6a | bellard | 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK |
238 | 87f48e6a | bellard | 56, // 58 0x3A 0x38 L ALT QZ_LALT |
239 | 87f48e6a | bellard | 29, // 59 0x3B 0x1d L CTRL QZ_LCTRL |
240 | 87f48e6a | bellard | 54, // 60 0x3C 0x36 R SHFT QZ_RSHIFT |
241 | 87f48e6a | bellard | 184,// 61 0x3D 0xb8 E0,38 R ALT QZ_RALT |
242 | 87f48e6a | bellard | 157,// 62 0x3E 0x9d E0,1D R CTRL QZ_RCTRL |
243 | 87f48e6a | bellard | 0, // 63 0x3F Undefined |
244 | 87f48e6a | bellard | 0, // 64 0x40 Undefined |
245 | 87f48e6a | bellard | 0, // 65 0x41 Undefined |
246 | 87f48e6a | bellard | 0, // 66 0x42 Undefined |
247 | 87f48e6a | bellard | 55, // 67 0x43 0x37 KP * QZ_KP_MULTIPLY |
248 | 87f48e6a | bellard | 0, // 68 0x44 Undefined |
249 | 87f48e6a | bellard | 78, // 69 0x45 0x4e KP + QZ_KP_PLUS |
250 | 87f48e6a | bellard | 0, // 70 0x46 Undefined |
251 | 87f48e6a | bellard | 69, // 71 0x47 0x45 NUM QZ_NUMLOCK |
252 | 87f48e6a | bellard | 0, // 72 0x48 Undefined |
253 | 87f48e6a | bellard | 0, // 73 0x49 Undefined |
254 | 87f48e6a | bellard | 0, // 74 0x4A Undefined |
255 | 87f48e6a | bellard | 181,// 75 0x4B 0xb5 E0,35 KP / QZ_KP_DIVIDE |
256 | 87f48e6a | bellard | 152,// 76 0x4C 0x9c E0,1C KP EN QZ_KP_ENTER |
257 | 87f48e6a | bellard | 0, // 77 0x4D undefined |
258 | 87f48e6a | bellard | 74, // 78 0x4E 0x4a KP - QZ_KP_MINUS |
259 | 87f48e6a | bellard | 0, // 79 0x4F Undefined |
260 | 87f48e6a | bellard | 0, // 80 0x50 Undefined |
261 | 87f48e6a | bellard | 0, // 81 0x51 QZ_KP_EQUALS |
262 | 87f48e6a | bellard | 82, // 82 0x52 0x52 KP 0 QZ_KP0 |
263 | 87f48e6a | bellard | 79, // 83 0x53 0x4f KP 1 QZ_KP1 |
264 | 87f48e6a | bellard | 80, // 84 0x54 0x50 KP 2 QZ_KP2 |
265 | 87f48e6a | bellard | 81, // 85 0x55 0x51 KP 3 QZ_KP3 |
266 | 87f48e6a | bellard | 75, // 86 0x56 0x4b KP 4 QZ_KP4 |
267 | 87f48e6a | bellard | 76, // 87 0x57 0x4c KP 5 QZ_KP5 |
268 | 87f48e6a | bellard | 77, // 88 0x58 0x4d KP 6 QZ_KP6 |
269 | 87f48e6a | bellard | 71, // 89 0x59 0x47 KP 7 QZ_KP7 |
270 | 87f48e6a | bellard | 0, // 90 0x5A Undefined |
271 | 87f48e6a | bellard | 72, // 91 0x5B 0x48 KP 8 QZ_KP8 |
272 | 87f48e6a | bellard | 73, // 92 0x5C 0x49 KP 9 QZ_KP9 |
273 | 87f48e6a | bellard | 0, // 93 0x5D Undefined |
274 | 87f48e6a | bellard | 0, // 94 0x5E Undefined |
275 | 87f48e6a | bellard | 0, // 95 0x5F Undefined |
276 | 87f48e6a | bellard | 63, // 96 0x60 0x3f F5 QZ_F5 |
277 | 87f48e6a | bellard | 64, // 97 0x61 0x40 F6 QZ_F6 |
278 | 87f48e6a | bellard | 65, // 98 0x62 0x41 F7 QZ_F7 |
279 | 87f48e6a | bellard | 61, // 99 0x63 0x3d F3 QZ_F3 |
280 | 87f48e6a | bellard | 66, // 100 0x64 0x42 F8 QZ_F8 |
281 | 87f48e6a | bellard | 67, // 101 0x65 0x43 F9 QZ_F9 |
282 | 87f48e6a | bellard | 0, // 102 0x66 Undefined |
283 | 87f48e6a | bellard | 87, // 103 0x67 0x57 F11 QZ_F11 |
284 | 87f48e6a | bellard | 0, // 104 0x68 Undefined |
285 | 87f48e6a | bellard | 183,// 105 0x69 0xb7 QZ_PRINT |
286 | 87f48e6a | bellard | 0, // 106 0x6A Undefined |
287 | 87f48e6a | bellard | 70, // 107 0x6B 0x46 SCROLL QZ_SCROLLOCK |
288 | 87f48e6a | bellard | 0, // 108 0x6C Undefined |
289 | 87f48e6a | bellard | 68, // 109 0x6D 0x44 F10 QZ_F10 |
290 | 87f48e6a | bellard | 0, // 110 0x6E Undefined |
291 | 87f48e6a | bellard | 88, // 111 0x6F 0x58 F12 QZ_F12 |
292 | 87f48e6a | bellard | 0, // 112 0x70 Undefined |
293 | 87f48e6a | bellard | 110,// 113 0x71 0x0 QZ_PAUSE |
294 | 87f48e6a | bellard | 210,// 114 0x72 0xd2 E0,52 INSERT QZ_INSERT |
295 | 87f48e6a | bellard | 199,// 115 0x73 0xc7 E0,47 HOME QZ_HOME |
296 | 87f48e6a | bellard | 201,// 116 0x74 0xc9 E0,49 PG UP QZ_PAGEUP |
297 | 87f48e6a | bellard | 211,// 117 0x75 0xd3 E0,53 DELETE QZ_DELETE |
298 | 87f48e6a | bellard | 62, // 118 0x76 0x3e F4 QZ_F4 |
299 | 87f48e6a | bellard | 207,// 119 0x77 0xcf E0,4f END QZ_END |
300 | 87f48e6a | bellard | 60, // 120 0x78 0x3c F2 QZ_F2 |
301 | 87f48e6a | bellard | 209,// 121 0x79 0xd1 E0,51 PG DN QZ_PAGEDOWN |
302 | 87f48e6a | bellard | 59, // 122 0x7A 0x3b F1 QZ_F1 |
303 | 87f48e6a | bellard | 203,// 123 0x7B 0xcb e0,4B L ARROW QZ_LEFT |
304 | 87f48e6a | bellard | 205,// 124 0x7C 0xcd e0,4D R ARROW QZ_RIGHT |
305 | 87f48e6a | bellard | 208,// 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN |
306 | 87f48e6a | bellard | 200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP |
307 | 87f48e6a | bellard | /* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */ |
308 | 87f48e6a | bellard | |
309 | 87f48e6a | bellard | /* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */ |
310 | 87f48e6a | bellard | /* |
311 | 87f48e6a | bellard | 219 // 0xdb e0,5b L GUI |
312 | 87f48e6a | bellard | 220 // 0xdc e0,5c R GUI |
313 | 87f48e6a | bellard | 221 // 0xdd e0,5d APPS |
314 | 87f48e6a | bellard | // E0,2A,E0,37 PRNT SCRN |
315 | 87f48e6a | bellard | // E1,1D,45,E1,9D,C5 PAUSE |
316 | 87f48e6a | bellard | 83 // 0x53 0x53 KP . |
317 | 87f48e6a | bellard | // ACPI Scan Codes |
318 | 87f48e6a | bellard | 222 // 0xde E0, 5E Power |
319 | 87f48e6a | bellard | 223 // 0xdf E0, 5F Sleep |
320 | 87f48e6a | bellard | 227 // 0xe3 E0, 63 Wake |
321 | 87f48e6a | bellard | // Windows Multimedia Scan Codes |
322 | 87f48e6a | bellard | 153 // 0x99 E0, 19 Next Track |
323 | 87f48e6a | bellard | 144 // 0x90 E0, 10 Previous Track |
324 | 87f48e6a | bellard | 164 // 0xa4 E0, 24 Stop |
325 | 87f48e6a | bellard | 162 // 0xa2 E0, 22 Play/Pause |
326 | 87f48e6a | bellard | 160 // 0xa0 E0, 20 Mute |
327 | 87f48e6a | bellard | 176 // 0xb0 E0, 30 Volume Up |
328 | 87f48e6a | bellard | 174 // 0xae E0, 2E Volume Down |
329 | 87f48e6a | bellard | 237 // 0xed E0, 6D Media Select |
330 | 87f48e6a | bellard | 236 // 0xec E0, 6C E-Mail |
331 | 87f48e6a | bellard | 161 // 0xa1 E0, 21 Calculator |
332 | 87f48e6a | bellard | 235 // 0xeb E0, 6B My Computer |
333 | 87f48e6a | bellard | 229 // 0xe5 E0, 65 WWW Search |
334 | 87f48e6a | bellard | 178 // 0xb2 E0, 32 WWW Home |
335 | 87f48e6a | bellard | 234 // 0xea E0, 6A WWW Back |
336 | 87f48e6a | bellard | 233 // 0xe9 E0, 69 WWW Forward |
337 | 87f48e6a | bellard | 232 // 0xe8 E0, 68 WWW Stop |
338 | 87f48e6a | bellard | 231 // 0xe7 E0, 67 WWW Refresh |
339 | 87f48e6a | bellard | 230 // 0xe6 E0, 66 WWW Favorites |
340 | 87f48e6a | bellard | */ |
341 | 5b0753e0 | bellard | }; |
342 | 5b0753e0 | bellard | |
343 | 87f48e6a | bellard | int cocoa_keycode_to_qemu(int keycode) |
344 | 5b0753e0 | bellard | { |
345 | 87f48e6a | bellard | if((sizeof(keymap)/sizeof(int)) <= keycode) |
346 | 5b0753e0 | bellard | { |
347 | 5b0753e0 | bellard | printf("(cocoa) warning unknow keycode 0x%x\n", keycode); |
348 | 5b0753e0 | bellard | return 0; |
349 | 5b0753e0 | bellard | } |
350 | 5b0753e0 | bellard | return keymap[keycode]; |
351 | 5b0753e0 | bellard | } |
352 | 5b0753e0 | bellard | |
353 | 5b0753e0 | bellard | /* |
354 | 5b0753e0 | bellard | ------------------------------------------------------ |
355 | 5b0753e0 | bellard | cocoa_refresh |
356 | 5b0753e0 | bellard | ------------------------------------------------------ |
357 | 5b0753e0 | bellard | */ |
358 | 5b0753e0 | bellard | static void cocoa_refresh(DisplayState *ds) |
359 | 5b0753e0 | bellard | { |
360 | 5b0753e0 | bellard | //printf("cocoa_refresh \n"); |
361 | 5b0753e0 | bellard | NSDate *distantPast; |
362 | 5b0753e0 | bellard | NSEvent *event; |
363 | 5b0753e0 | bellard | NSAutoreleasePool *pool; |
364 | 5b0753e0 | bellard | |
365 | 5b0753e0 | bellard | pool = [ [ NSAutoreleasePool alloc ] init ]; |
366 | 5b0753e0 | bellard | distantPast = [ NSDate distantPast ]; |
367 | 5b0753e0 | bellard | |
368 | 95219897 | pbrook | vga_hw_update(); |
369 | 95219897 | pbrook | |
370 | 5b0753e0 | bellard | do { |
371 | 5b0753e0 | bellard | event = [ NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast |
372 | 5b0753e0 | bellard | inMode: NSDefaultRunLoopMode dequeue:YES ]; |
373 | 5b0753e0 | bellard | if (event != nil) { |
374 | 5b0753e0 | bellard | switch ([event type]) { |
375 | 87f48e6a | bellard | case NSFlagsChanged: |
376 | 5b0753e0 | bellard | { |
377 | 5b0753e0 | bellard | int keycode = cocoa_keycode_to_qemu([event keyCode]); |
378 | 7c206a75 | bellard | |
379 | 7c206a75 | bellard | if (keycode) |
380 | 87f48e6a | bellard | { |
381 | 7c206a75 | bellard | if (keycode == 58 || keycode == 69) { |
382 | 7c206a75 | bellard | /* emulate caps lock and num lock keydown and keyup */ |
383 | 7c206a75 | bellard | kbd_put_keycode(keycode); |
384 | 7c206a75 | bellard | kbd_put_keycode(keycode | 0x80); |
385 | 95219897 | pbrook | } else if (is_graphic_console()) { |
386 | 7c206a75 | bellard | if (keycode & 0x80) |
387 | 7c206a75 | bellard | kbd_put_keycode(0xe0); |
388 | 7c206a75 | bellard | if (modifiers_state[keycode] == 0) { |
389 | 7c206a75 | bellard | /* keydown */ |
390 | 7c206a75 | bellard | kbd_put_keycode(keycode & 0x7f); |
391 | 7c206a75 | bellard | modifiers_state[keycode] = 1; |
392 | 7c206a75 | bellard | } else { |
393 | 7c206a75 | bellard | /* keyup */ |
394 | 7c206a75 | bellard | kbd_put_keycode(keycode | 0x80); |
395 | 7c206a75 | bellard | modifiers_state[keycode] = 0; |
396 | 7c206a75 | bellard | } |
397 | 7c206a75 | bellard | } |
398 | 87f48e6a | bellard | } |
399 | 7c206a75 | bellard | |
400 | 87f48e6a | bellard | /* release Mouse grab when pressing ctrl+alt */ |
401 | 87f48e6a | bellard | if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) |
402 | 7c206a75 | bellard | { |
403 | 87f48e6a | bellard | [window setTitle: @"QEMU"]; |
404 | 87f48e6a | bellard | [NSCursor unhide]; |
405 | 87f48e6a | bellard | CGAssociateMouseAndMouseCursorPosition ( TRUE ); |
406 | 87f48e6a | bellard | grab = 0; |
407 | 7c206a75 | bellard | } |
408 | 5b0753e0 | bellard | } |
409 | 5b0753e0 | bellard | break; |
410 | 7c206a75 | bellard | |
411 | 87f48e6a | bellard | case NSKeyDown: |
412 | 87f48e6a | bellard | { |
413 | 87f48e6a | bellard | int keycode = cocoa_keycode_to_qemu([event keyCode]); |
414 | 87f48e6a | bellard | |
415 | 87f48e6a | bellard | /* handle command Key Combos */ |
416 | 87f48e6a | bellard | if ([event modifierFlags] & NSCommandKeyMask) { |
417 | 87f48e6a | bellard | switch ([event keyCode]) { |
418 | 87f48e6a | bellard | /* quit */ |
419 | 87f48e6a | bellard | case 12: /* q key */ |
420 | 87f48e6a | bellard | /* switch to windowed View */ |
421 | 87f48e6a | bellard | exit(0); |
422 | 87f48e6a | bellard | return; |
423 | 87f48e6a | bellard | } |
424 | 87f48e6a | bellard | } |
425 | 87f48e6a | bellard | |
426 | 87f48e6a | bellard | /* handle control + alt Key Combos */ |
427 | 87f48e6a | bellard | if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) { |
428 | 87f48e6a | bellard | switch (keycode) { |
429 | 87f48e6a | bellard | /* toggle Monitor */ |
430 | 87f48e6a | bellard | case 0x02 ... 0x0a: /* '1' to '9' keys */ |
431 | 87f48e6a | bellard | console_select(keycode - 0x02); |
432 | 87f48e6a | bellard | break; |
433 | 87f48e6a | bellard | } |
434 | 87f48e6a | bellard | } else { |
435 | 87f48e6a | bellard | /* handle standard key events */ |
436 | 95219897 | pbrook | if (is_graphic_console()) { |
437 | 87f48e6a | bellard | if (keycode & 0x80) //check bit for e0 in front |
438 | 87f48e6a | bellard | kbd_put_keycode(0xe0); |
439 | 87f48e6a | bellard | kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front |
440 | 87f48e6a | bellard | /* handle monitor key events */ |
441 | 87f48e6a | bellard | } else { |
442 | 5cbfcd00 | bellard | int keysym = 0; |
443 | 5cbfcd00 | bellard | |
444 | 87f48e6a | bellard | switch([event keyCode]) { |
445 | 5cbfcd00 | bellard | case 115: |
446 | 5cbfcd00 | bellard | keysym = QEMU_KEY_HOME; |
447 | 5cbfcd00 | bellard | break; |
448 | 5cbfcd00 | bellard | case 117: |
449 | 5cbfcd00 | bellard | keysym = QEMU_KEY_DELETE; |
450 | 5cbfcd00 | bellard | break; |
451 | 5cbfcd00 | bellard | case 119: |
452 | 5cbfcd00 | bellard | keysym = QEMU_KEY_END; |
453 | 5cbfcd00 | bellard | break; |
454 | 5cbfcd00 | bellard | case 123: |
455 | 5cbfcd00 | bellard | keysym = QEMU_KEY_LEFT; |
456 | 5cbfcd00 | bellard | break; |
457 | 5cbfcd00 | bellard | case 124: |
458 | 5cbfcd00 | bellard | keysym = QEMU_KEY_RIGHT; |
459 | 5cbfcd00 | bellard | break; |
460 | 5cbfcd00 | bellard | case 125: |
461 | 5cbfcd00 | bellard | keysym = QEMU_KEY_DOWN; |
462 | 5cbfcd00 | bellard | break; |
463 | 5cbfcd00 | bellard | case 126: |
464 | 5cbfcd00 | bellard | keysym = QEMU_KEY_UP; |
465 | 5cbfcd00 | bellard | break; |
466 | 5cbfcd00 | bellard | default: |
467 | 5cbfcd00 | bellard | { |
468 | 5cbfcd00 | bellard | NSString *ks = [event characters]; |
469 | 5cbfcd00 | bellard | |
470 | 5cbfcd00 | bellard | if ([ks length] > 0) |
471 | 5cbfcd00 | bellard | keysym = [ks characterAtIndex:0]; |
472 | 5cbfcd00 | bellard | } |
473 | 87f48e6a | bellard | } |
474 | 5cbfcd00 | bellard | if (keysym) |
475 | 5cbfcd00 | bellard | kbd_put_keysym(keysym); |
476 | 87f48e6a | bellard | } |
477 | 87f48e6a | bellard | } |
478 | 87f48e6a | bellard | } |
479 | 87f48e6a | bellard | break; |
480 | 87f48e6a | bellard | |
481 | 5b0753e0 | bellard | case NSKeyUp: |
482 | 5b0753e0 | bellard | { |
483 | 87f48e6a | bellard | int keycode = cocoa_keycode_to_qemu([event keyCode]); |
484 | 95219897 | pbrook | if (is_graphic_console()) { |
485 | 87f48e6a | bellard | if (keycode & 0x80) |
486 | 87f48e6a | bellard | kbd_put_keycode(0xe0); |
487 | 87f48e6a | bellard | kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key |
488 | 87f48e6a | bellard | } |
489 | 5b0753e0 | bellard | } |
490 | 5b0753e0 | bellard | break; |
491 | 87f48e6a | bellard | |
492 | 87f48e6a | bellard | case NSMouseMoved: |
493 | 87f48e6a | bellard | if (grab) { |
494 | 87f48e6a | bellard | int dx = [event deltaX]; |
495 | 87f48e6a | bellard | int dy = [event deltaY]; |
496 | 87f48e6a | bellard | int dz = [event deltaZ]; |
497 | 87f48e6a | bellard | int buttons = 0; |
498 | 87f48e6a | bellard | kbd_mouse_event(dx, dy, dz, buttons); |
499 | 87f48e6a | bellard | } |
500 | 87f48e6a | bellard | break; |
501 | 87f48e6a | bellard | |
502 | 5b0753e0 | bellard | case NSLeftMouseDown: |
503 | 87f48e6a | bellard | if (grab) { |
504 | 87f48e6a | bellard | int buttons = 0; |
505 | 87f48e6a | bellard | |
506 | 87f48e6a | bellard | /* leftclick+command simulates rightclick */ |
507 | 87f48e6a | bellard | if ([event modifierFlags] & NSCommandKeyMask) { |
508 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_RBUTTON; |
509 | 87f48e6a | bellard | } else { |
510 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_LBUTTON; |
511 | 87f48e6a | bellard | } |
512 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, buttons); |
513 | 87f48e6a | bellard | } else { |
514 | 87f48e6a | bellard | [NSApp sendEvent: event]; |
515 | 87f48e6a | bellard | } |
516 | 87f48e6a | bellard | break; |
517 | 87f48e6a | bellard | |
518 | 87f48e6a | bellard | case NSLeftMouseDragged: |
519 | 87f48e6a | bellard | if (grab) { |
520 | 87f48e6a | bellard | int dx = [event deltaX]; |
521 | 87f48e6a | bellard | int dy = [event deltaY]; |
522 | 87f48e6a | bellard | int dz = [event deltaZ]; |
523 | 87f48e6a | bellard | int buttons = 0; |
524 | 87f48e6a | bellard | if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) { //leftclick+command simulates rightclick |
525 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_RBUTTON; |
526 | 87f48e6a | bellard | } else { |
527 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_LBUTTON; |
528 | 87f48e6a | bellard | } |
529 | 87f48e6a | bellard | kbd_mouse_event(dx, dy, dz, buttons); |
530 | 87f48e6a | bellard | } |
531 | 87f48e6a | bellard | break; |
532 | 87f48e6a | bellard | |
533 | 5b0753e0 | bellard | case NSLeftMouseUp: |
534 | 87f48e6a | bellard | if (grab) { |
535 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, 0); |
536 | 87f48e6a | bellard | } else { |
537 | 87f48e6a | bellard | [window setTitle: @"QEMU (Press ctrl + alt to release Mouse)"]; |
538 | 87f48e6a | bellard | [NSCursor hide]; |
539 | 87f48e6a | bellard | CGAssociateMouseAndMouseCursorPosition ( FALSE ); |
540 | 87f48e6a | bellard | grab = 1; |
541 | 87f48e6a | bellard | //[NSApp sendEvent: event]; |
542 | 87f48e6a | bellard | } |
543 | 87f48e6a | bellard | break; |
544 | 87f48e6a | bellard | |
545 | 5b0753e0 | bellard | case NSRightMouseDown: |
546 | 87f48e6a | bellard | if (grab) { |
547 | 87f48e6a | bellard | int buttons = 0; |
548 | 87f48e6a | bellard | |
549 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_RBUTTON; |
550 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, buttons); |
551 | 87f48e6a | bellard | } else { |
552 | 87f48e6a | bellard | [NSApp sendEvent: event]; |
553 | 87f48e6a | bellard | } |
554 | 87f48e6a | bellard | break; |
555 | 87f48e6a | bellard | |
556 | 87f48e6a | bellard | case NSRightMouseDragged: |
557 | 87f48e6a | bellard | if (grab) { |
558 | 87f48e6a | bellard | int dx = [event deltaX]; |
559 | 87f48e6a | bellard | int dy = [event deltaY]; |
560 | 87f48e6a | bellard | int dz = [event deltaZ]; |
561 | 87f48e6a | bellard | int buttons = 0; |
562 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_RBUTTON; |
563 | 87f48e6a | bellard | kbd_mouse_event(dx, dy, dz, buttons); |
564 | 87f48e6a | bellard | } |
565 | 87f48e6a | bellard | break; |
566 | 87f48e6a | bellard | |
567 | 5b0753e0 | bellard | case NSRightMouseUp: |
568 | 87f48e6a | bellard | if (grab) { |
569 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, 0); |
570 | 87f48e6a | bellard | } else { |
571 | 87f48e6a | bellard | [NSApp sendEvent: event]; |
572 | 87f48e6a | bellard | } |
573 | 87f48e6a | bellard | break; |
574 | 87f48e6a | bellard | |
575 | 5b0753e0 | bellard | case NSOtherMouseDragged: |
576 | 87f48e6a | bellard | if (grab) { |
577 | 87f48e6a | bellard | int dx = [event deltaX]; |
578 | 87f48e6a | bellard | int dy = [event deltaY]; |
579 | 87f48e6a | bellard | int dz = [event deltaZ]; |
580 | 87f48e6a | bellard | int buttons = 0; |
581 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_MBUTTON; |
582 | 87f48e6a | bellard | kbd_mouse_event(dx, dy, dz, buttons); |
583 | 87f48e6a | bellard | } |
584 | 87f48e6a | bellard | break; |
585 | 87f48e6a | bellard | |
586 | 87f48e6a | bellard | case NSOtherMouseDown: |
587 | 87f48e6a | bellard | if (grab) { |
588 | 87f48e6a | bellard | int buttons = 0; |
589 | 87f48e6a | bellard | buttons |= MOUSE_EVENT_MBUTTON; |
590 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, buttons); |
591 | 87f48e6a | bellard | } else { |
592 | 87f48e6a | bellard | [NSApp sendEvent:event]; |
593 | 87f48e6a | bellard | } |
594 | 87f48e6a | bellard | break; |
595 | 87f48e6a | bellard | |
596 | 87f48e6a | bellard | case NSOtherMouseUp: |
597 | 87f48e6a | bellard | if (grab) { |
598 | 87f48e6a | bellard | kbd_mouse_event(0, 0, 0, 0); |
599 | 87f48e6a | bellard | } else { |
600 | 87f48e6a | bellard | [NSApp sendEvent: event]; |
601 | 87f48e6a | bellard | } |
602 | 87f48e6a | bellard | break; |
603 | 87f48e6a | bellard | |
604 | 87f48e6a | bellard | case NSScrollWheel: |
605 | 87f48e6a | bellard | if (grab) { |
606 | 87f48e6a | bellard | int dz = [event deltaY]; |
607 | 87f48e6a | bellard | kbd_mouse_event(0, 0, -dz, 0); |
608 | 87f48e6a | bellard | } |
609 | 87f48e6a | bellard | break; |
610 | 5b0753e0 | bellard | |
611 | 5b0753e0 | bellard | default: [NSApp sendEvent:event]; |
612 | 5b0753e0 | bellard | } |
613 | 5b0753e0 | bellard | } |
614 | 5b0753e0 | bellard | } while(event != nil); |
615 | 5b0753e0 | bellard | } |
616 | 5b0753e0 | bellard | |
617 | 5b0753e0 | bellard | /* |
618 | 5b0753e0 | bellard | ------------------------------------------------------ |
619 | 5b0753e0 | bellard | cocoa_cleanup |
620 | 5b0753e0 | bellard | ------------------------------------------------------ |
621 | 5b0753e0 | bellard | */ |
622 | 5b0753e0 | bellard | |
623 | 5b0753e0 | bellard | static void cocoa_cleanup(void) |
624 | 5b0753e0 | bellard | { |
625 | 5b0753e0 | bellard | |
626 | 5b0753e0 | bellard | } |
627 | 5b0753e0 | bellard | |
628 | 5b0753e0 | bellard | /* |
629 | 5b0753e0 | bellard | ------------------------------------------------------ |
630 | 5b0753e0 | bellard | cocoa_display_init |
631 | 5b0753e0 | bellard | ------------------------------------------------------ |
632 | 5b0753e0 | bellard | */ |
633 | 5b0753e0 | bellard | |
634 | 5b0753e0 | bellard | void cocoa_display_init(DisplayState *ds, int full_screen) |
635 | 5b0753e0 | bellard | { |
636 | 5b0753e0 | bellard | ds->dpy_update = cocoa_update; |
637 | 5b0753e0 | bellard | ds->dpy_resize = cocoa_resize; |
638 | 5b0753e0 | bellard | ds->dpy_refresh = cocoa_refresh; |
639 | 5b0753e0 | bellard | |
640 | 5b0753e0 | bellard | cocoa_resize(ds, 640, 400); |
641 | 5b0753e0 | bellard | |
642 | 5b0753e0 | bellard | atexit(cocoa_cleanup); |
643 | 5b0753e0 | bellard | } |
644 | 5b0753e0 | bellard | |
645 | 5b0753e0 | bellard | /* |
646 | 5b0753e0 | bellard | ------------------------------------------------------ |
647 | 5b0753e0 | bellard | Interface with Cocoa |
648 | 5b0753e0 | bellard | ------------------------------------------------------ |
649 | 5b0753e0 | bellard | */ |
650 | 5b0753e0 | bellard | |
651 | 5b0753e0 | bellard | |
652 | 5b0753e0 | bellard | /* |
653 | 5b0753e0 | bellard | ------------------------------------------------------ |
654 | 5b0753e0 | bellard | QemuWindow |
655 | 5b0753e0 | bellard | Some trick from SDL to use miniwindow |
656 | 5b0753e0 | bellard | ------------------------------------------------------ |
657 | 5b0753e0 | bellard | */ |
658 | 5b0753e0 | bellard | static void QZ_SetPortAlphaOpaque () |
659 | 5b0753e0 | bellard | { |
660 | 5b0753e0 | bellard | /* Assume 32 bit if( bpp == 32 )*/ |
661 | 5b0753e0 | bellard | if ( 1 ) { |
662 | 5b0753e0 | bellard | |
663 | 5b0753e0 | bellard | uint32_t *pixels = (uint32_t*) current_ds.data; |
664 | 5b0753e0 | bellard | uint32_t rowPixels = current_ds.linesize / 4; |
665 | 5b0753e0 | bellard | uint32_t i, j; |
666 | 5b0753e0 | bellard | |
667 | 5b0753e0 | bellard | for (i = 0; i < current_ds.height; i++) |
668 | 5b0753e0 | bellard | for (j = 0; j < current_ds.width; j++) { |
669 | 5b0753e0 | bellard | |
670 | 5b0753e0 | bellard | pixels[ (i * rowPixels) + j ] |= 0xFF000000; |
671 | 5b0753e0 | bellard | } |
672 | 5b0753e0 | bellard | } |
673 | 5b0753e0 | bellard | } |
674 | 5b0753e0 | bellard | |
675 | 5b0753e0 | bellard | @implementation QemuWindow |
676 | 5b0753e0 | bellard | - (void)miniaturize:(id)sender |
677 | 5b0753e0 | bellard | { |
678 | 5b0753e0 | bellard | |
679 | 5b0753e0 | bellard | /* make the alpha channel opaque so anim won't have holes in it */ |
680 | 5b0753e0 | bellard | QZ_SetPortAlphaOpaque (); |
681 | 5b0753e0 | bellard | |
682 | 5b0753e0 | bellard | [ super miniaturize:sender ]; |
683 | 5b0753e0 | bellard | |
684 | 5b0753e0 | bellard | } |
685 | 5b0753e0 | bellard | - (void)display |
686 | 5b0753e0 | bellard | { |
687 | 5b0753e0 | bellard | /* |
688 | 5b0753e0 | bellard | This method fires just before the window deminaturizes from the Dock. |
689 | 5b0753e0 | bellard | |
690 | 5b0753e0 | bellard | We'll save the current visible surface, let the window manager redraw any |
691 | 5b0753e0 | bellard | UI elements, and restore the SDL surface. This way, no expose event |
692 | 5b0753e0 | bellard | is required, and the deminiaturize works perfectly. |
693 | 5b0753e0 | bellard | */ |
694 | 5b0753e0 | bellard | |
695 | 5b0753e0 | bellard | /* make sure pixels are fully opaque */ |
696 | 5b0753e0 | bellard | QZ_SetPortAlphaOpaque (); |
697 | 5b0753e0 | bellard | |
698 | 5b0753e0 | bellard | /* save current visible SDL surface */ |
699 | 5b0753e0 | bellard | [ self cacheImageInRect:[ qd_view frame ] ]; |
700 | 5b0753e0 | bellard | |
701 | 5b0753e0 | bellard | /* let the window manager redraw controls, border, etc */ |
702 | 5b0753e0 | bellard | [ super display ]; |
703 | 5b0753e0 | bellard | |
704 | 5b0753e0 | bellard | /* restore visible SDL surface */ |
705 | 5b0753e0 | bellard | [ self restoreCachedImage ]; |
706 | 5b0753e0 | bellard | } |
707 | 5b0753e0 | bellard | |
708 | 5b0753e0 | bellard | @end |
709 | 5b0753e0 | bellard | |
710 | 5b0753e0 | bellard | |
711 | 5b0753e0 | bellard | /* |
712 | 5b0753e0 | bellard | ------------------------------------------------------ |
713 | 5b0753e0 | bellard | QemuCocoaGUIController |
714 | 5b0753e0 | bellard | NSApp's delegate - indeed main object |
715 | 5b0753e0 | bellard | ------------------------------------------------------ |
716 | 5b0753e0 | bellard | */ |
717 | 5b0753e0 | bellard | |
718 | 5b0753e0 | bellard | @interface QemuCocoaGUIController : NSObject |
719 | 5b0753e0 | bellard | { |
720 | 5b0753e0 | bellard | } |
721 | 5b0753e0 | bellard | - (void)applicationDidFinishLaunching: (NSNotification *) note; |
722 | 5b0753e0 | bellard | - (void)applicationWillTerminate:(NSNotification *)aNotification; |
723 | 5b0753e0 | bellard | |
724 | 5b0753e0 | bellard | - (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; |
725 | 5b0753e0 | bellard | |
726 | 5b0753e0 | bellard | - (void)startEmulationWithArgc:(int)argc argv:(char**)argv; |
727 | 5b0753e0 | bellard | @end |
728 | 5b0753e0 | bellard | |
729 | 5b0753e0 | bellard | @implementation QemuCocoaGUIController |
730 | 5b0753e0 | bellard | /* Called when the internal event loop has just started running */ |
731 | 5b0753e0 | bellard | - (void)applicationDidFinishLaunching: (NSNotification *) note |
732 | 5b0753e0 | bellard | { |
733 | 5a246934 | bellard | |
734 | 5a246934 | bellard | /* Display an open dialog box if no argument were passed or |
735 | 5a246934 | bellard | if qemu was launched from the finder ( the Finder passes "-psn" ) */ |
736 | 5a246934 | bellard | |
737 | 5a246934 | bellard | if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0) |
738 | 5b0753e0 | bellard | { |
739 | 5b0753e0 | bellard | NSOpenPanel *op = [[NSOpenPanel alloc] init]; |
740 | 5b0753e0 | bellard | |
741 | 5b0753e0 | bellard | cocoa_resize(¤t_ds, 640, 400); |
742 | 5b0753e0 | bellard | |
743 | 5b0753e0 | bellard | [op setPrompt:@"Boot image"]; |
744 | 5b0753e0 | bellard | |
745 | 5b0753e0 | bellard | [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"]; |
746 | 5b0753e0 | bellard | |
747 | 7a674b13 | bellard | [op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil] |
748 | 5b0753e0 | bellard | modalForWindow:window modalDelegate:self |
749 | 5b0753e0 | bellard | didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; |
750 | 5b0753e0 | bellard | } |
751 | 5a246934 | bellard | else |
752 | 5a246934 | bellard | { |
753 | 5a246934 | bellard | /* or Launch Qemu, with the global args */ |
754 | 5a246934 | bellard | [self startEmulationWithArgc:gArgc argv:gArgv]; |
755 | 5a246934 | bellard | } |
756 | 5b0753e0 | bellard | } |
757 | 5b0753e0 | bellard | |
758 | 5b0753e0 | bellard | - (void)applicationWillTerminate:(NSNotification *)aNotification |
759 | 5b0753e0 | bellard | { |
760 | 5b0753e0 | bellard | printf("Application will terminate\n"); |
761 | 5b0753e0 | bellard | qemu_system_shutdown_request(); |
762 | 5b0753e0 | bellard | /* In order to avoid a crash */ |
763 | 5b0753e0 | bellard | exit(0); |
764 | 5b0753e0 | bellard | } |
765 | 5b0753e0 | bellard | |
766 | 5b0753e0 | bellard | - (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo |
767 | 5b0753e0 | bellard | { |
768 | 5b0753e0 | bellard | if(returnCode == NSCancelButton) |
769 | 5b0753e0 | bellard | { |
770 | 5b0753e0 | bellard | exit(0); |
771 | 5b0753e0 | bellard | } |
772 | 5b0753e0 | bellard | |
773 | 5b0753e0 | bellard | if(returnCode == NSOKButton) |
774 | 5b0753e0 | bellard | { |
775 | 5b0753e0 | bellard | char *bin = "qemu"; |
776 | 5b0753e0 | bellard | char *img = (char*)[ [ sheet filename ] cString]; |
777 | 5b0753e0 | bellard | |
778 | 5b0753e0 | bellard | char **argv = (char**)malloc( sizeof(char*)*3 ); |
779 | 5b0753e0 | bellard | |
780 | 5b0753e0 | bellard | asprintf(&argv[0], "%s", bin); |
781 | 5b0753e0 | bellard | asprintf(&argv[1], "-hda"); |
782 | 5b0753e0 | bellard | asprintf(&argv[2], "%s", img); |
783 | 5b0753e0 | bellard | |
784 | 5b0753e0 | bellard | printf("Using argc %d argv %s -hda %s\n", 3, bin, img); |
785 | 5b0753e0 | bellard | |
786 | 5b0753e0 | bellard | [self startEmulationWithArgc:3 argv:(char**)argv]; |
787 | 5b0753e0 | bellard | } |
788 | 5b0753e0 | bellard | } |
789 | 5b0753e0 | bellard | |
790 | 5b0753e0 | bellard | - (void)startEmulationWithArgc:(int)argc argv:(char**)argv |
791 | 5b0753e0 | bellard | { |
792 | 5b0753e0 | bellard | int status; |
793 | 5b0753e0 | bellard | /* Launch Qemu */ |
794 | 5b0753e0 | bellard | printf("starting qemu...\n"); |
795 | 5b0753e0 | bellard | status = qemu_main (argc, argv); |
796 | 5b0753e0 | bellard | exit(status); |
797 | 5b0753e0 | bellard | } |
798 | 5b0753e0 | bellard | @end |
799 | 5b0753e0 | bellard | |
800 | 5b0753e0 | bellard | /* |
801 | 5b0753e0 | bellard | ------------------------------------------------------ |
802 | 5b0753e0 | bellard | Application Creation |
803 | 5b0753e0 | bellard | ------------------------------------------------------ |
804 | 5b0753e0 | bellard | */ |
805 | 5b0753e0 | bellard | |
806 | 5b0753e0 | bellard | /* Dock Connection */ |
807 | 5b0753e0 | bellard | typedef struct CPSProcessSerNum |
808 | 5b0753e0 | bellard | { |
809 | 5b0753e0 | bellard | UInt32 lo; |
810 | 5b0753e0 | bellard | UInt32 hi; |
811 | 5b0753e0 | bellard | } CPSProcessSerNum; |
812 | 5b0753e0 | bellard | |
813 | 5b0753e0 | bellard | extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); |
814 | 5b0753e0 | bellard | extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); |
815 | 5b0753e0 | bellard | extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); |
816 | 5b0753e0 | bellard | |
817 | 5b0753e0 | bellard | /* Menu Creation */ |
818 | 5b0753e0 | bellard | static void setApplicationMenu(void) |
819 | 5b0753e0 | bellard | { |
820 | 5b0753e0 | bellard | /* warning: this code is very odd */ |
821 | 5b0753e0 | bellard | NSMenu *appleMenu; |
822 | 5b0753e0 | bellard | NSMenuItem *menuItem; |
823 | 5b0753e0 | bellard | NSString *title; |
824 | 5b0753e0 | bellard | NSString *appName; |
825 | 5b0753e0 | bellard | |
826 | 5b0753e0 | bellard | appName = @"Qemu"; |
827 | 5b0753e0 | bellard | appleMenu = [[NSMenu alloc] initWithTitle:@""]; |
828 | 5b0753e0 | bellard | |
829 | 5b0753e0 | bellard | /* Add menu items */ |
830 | 5b0753e0 | bellard | title = [@"About " stringByAppendingString:appName]; |
831 | 5b0753e0 | bellard | [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; |
832 | 5b0753e0 | bellard | |
833 | 5b0753e0 | bellard | [appleMenu addItem:[NSMenuItem separatorItem]]; |
834 | 5b0753e0 | bellard | |
835 | 5b0753e0 | bellard | title = [@"Hide " stringByAppendingString:appName]; |
836 | 5b0753e0 | bellard | [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; |
837 | 5b0753e0 | bellard | |
838 | 5b0753e0 | bellard | menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; |
839 | 5b0753e0 | bellard | [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; |
840 | 5b0753e0 | bellard | |
841 | 5b0753e0 | bellard | [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; |
842 | 5b0753e0 | bellard | |
843 | 5b0753e0 | bellard | [appleMenu addItem:[NSMenuItem separatorItem]]; |
844 | 5b0753e0 | bellard | |
845 | 5b0753e0 | bellard | title = [@"Quit " stringByAppendingString:appName]; |
846 | 5b0753e0 | bellard | [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; |
847 | 5b0753e0 | bellard | |
848 | 5b0753e0 | bellard | |
849 | 5b0753e0 | bellard | /* Put menu into the menubar */ |
850 | 5b0753e0 | bellard | menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; |
851 | 5b0753e0 | bellard | [menuItem setSubmenu:appleMenu]; |
852 | 5b0753e0 | bellard | [[NSApp mainMenu] addItem:menuItem]; |
853 | 5b0753e0 | bellard | |
854 | 5b0753e0 | bellard | /* Tell the application object that this is now the application menu */ |
855 | 5b0753e0 | bellard | [NSApp setAppleMenu:appleMenu]; |
856 | 5b0753e0 | bellard | |
857 | 5b0753e0 | bellard | /* Finally give up our references to the objects */ |
858 | 5b0753e0 | bellard | [appleMenu release]; |
859 | 5b0753e0 | bellard | [menuItem release]; |
860 | 5b0753e0 | bellard | } |
861 | 5b0753e0 | bellard | |
862 | 5b0753e0 | bellard | /* Create a window menu */ |
863 | 5b0753e0 | bellard | static void setupWindowMenu(void) |
864 | 5b0753e0 | bellard | { |
865 | 5b0753e0 | bellard | NSMenu *windowMenu; |
866 | 5b0753e0 | bellard | NSMenuItem *windowMenuItem; |
867 | 5b0753e0 | bellard | NSMenuItem *menuItem; |
868 | 5b0753e0 | bellard | |
869 | 5b0753e0 | bellard | windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; |
870 | 5b0753e0 | bellard | |
871 | 5b0753e0 | bellard | /* "Minimize" item */ |
872 | 5b0753e0 | bellard | menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; |
873 | 5b0753e0 | bellard | [windowMenu addItem:menuItem]; |
874 | 5b0753e0 | bellard | [menuItem release]; |
875 | 5b0753e0 | bellard | |
876 | 5b0753e0 | bellard | /* Put menu into the menubar */ |
877 | 5b0753e0 | bellard | windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; |
878 | 5b0753e0 | bellard | [windowMenuItem setSubmenu:windowMenu]; |
879 | 5b0753e0 | bellard | [[NSApp mainMenu] addItem:windowMenuItem]; |
880 | 5b0753e0 | bellard | |
881 | 5b0753e0 | bellard | /* Tell the application object that this is now the window menu */ |
882 | 5b0753e0 | bellard | [NSApp setWindowsMenu:windowMenu]; |
883 | 5b0753e0 | bellard | |
884 | 5b0753e0 | bellard | /* Finally give up our references to the objects */ |
885 | 5b0753e0 | bellard | [windowMenu release]; |
886 | 5b0753e0 | bellard | [windowMenuItem release]; |
887 | 5b0753e0 | bellard | } |
888 | 5b0753e0 | bellard | |
889 | cae41b10 | bellard | static void CustomApplicationMain(void) |
890 | 5b0753e0 | bellard | { |
891 | 5b0753e0 | bellard | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
892 | 5b0753e0 | bellard | QemuCocoaGUIController *gui_controller; |
893 | 5b0753e0 | bellard | CPSProcessSerNum PSN; |
894 | 5b0753e0 | bellard | |
895 | 5b0753e0 | bellard | [NSApplication sharedApplication]; |
896 | 5b0753e0 | bellard | |
897 | 5b0753e0 | bellard | if (!CPSGetCurrentProcess(&PSN)) |
898 | 5b0753e0 | bellard | if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) |
899 | 5b0753e0 | bellard | if (!CPSSetFrontProcess(&PSN)) |
900 | 5b0753e0 | bellard | [NSApplication sharedApplication]; |
901 | 5b0753e0 | bellard | |
902 | 5b0753e0 | bellard | /* Set up the menubar */ |
903 | 5b0753e0 | bellard | [NSApp setMainMenu:[[NSMenu alloc] init]]; |
904 | 5b0753e0 | bellard | setApplicationMenu(); |
905 | 5b0753e0 | bellard | setupWindowMenu(); |
906 | 5b0753e0 | bellard | |
907 | 5b0753e0 | bellard | /* Create SDLMain and make it the app delegate */ |
908 | 5b0753e0 | bellard | gui_controller = [[QemuCocoaGUIController alloc] init]; |
909 | 5b0753e0 | bellard | [NSApp setDelegate:gui_controller]; |
910 | 5b0753e0 | bellard | |
911 | 5b0753e0 | bellard | /* Start the main event loop */ |
912 | 5b0753e0 | bellard | [NSApp run]; |
913 | 5b0753e0 | bellard | |
914 | 5b0753e0 | bellard | [gui_controller release]; |
915 | 5b0753e0 | bellard | [pool release]; |
916 | 5b0753e0 | bellard | } |
917 | 5b0753e0 | bellard | |
918 | 5b0753e0 | bellard | /* Real main of qemu-cocoa */ |
919 | 5b0753e0 | bellard | int main(int argc, char **argv) |
920 | 5b0753e0 | bellard | { |
921 | 5b0753e0 | bellard | gArgc = argc; |
922 | 5b0753e0 | bellard | gArgv = argv; |
923 | cae41b10 | bellard | |
924 | cae41b10 | bellard | CustomApplicationMain(); |
925 | cae41b10 | bellard | |
926 | 5b0753e0 | bellard | return 0; |
927 | 5b0753e0 | bellard | } |