author | Claus Gittinger <cg@exept.de> |
Sun, 03 May 2020 13:20:12 +0200 | |
changeset 25379 | 609d492f29a7 |
parent 25307 | c61bbab528d3 |
permissions | -rw-r--r-- |
24466 | 1 |
"{ Encoding: utf8 }" |
2 |
||
21452 | 3 |
" |
4 |
COPYRIGHT (c) 2013 by Claus Gittinger |
|
21455 | 5 |
All Rights Reserved |
21452 | 6 |
|
7 |
This software is furnished under a license and may be used |
|
8 |
only in accordance with the terms of that license and with the |
|
9 |
inclusion of the above copyright notice. This software may not |
|
10 |
be provided or otherwise made available to, or used by, any |
|
11 |
other person. No title to or ownership of the software is |
|
12 |
hereby transferred. |
|
13 |
" |
|
17471 | 14 |
"{ Package: 'stx:libbasic' }" |
15 |
||
16 |
"{ NameSpace: Smalltalk }" |
|
14819 | 17 |
|
17471 | 18 |
UnixOperatingSystem subclass:#OSXOperatingSystem |
19 |
instanceVariableNames:'' |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
20 |
classVariableNames:'NSApp' |
17471 | 21 |
poolDictionaries:'' |
22 |
category:'OS-Unix' |
|
23 |
! |
|
24 |
||
21452 | 25 |
!OSXOperatingSystem primitiveDefinitions! |
26 |
%{ |
|
27 |
||
22491 | 28 |
#ifdef __osx__ |
25044 | 29 |
# define OBJC_OLD_DISPATCH_PROTOTYPES 1 |
30 |
||
22491 | 31 |
// mhm - how could they forget this???? |
32 |
# ifndef __XPC_IOS_SIMULATOR_AVAILABLE_STARTING |
|
33 |
# define __XPC_IOS_SIMULATOR_AVAILABLE_STARTING(version) |
|
34 |
# endif |
|
35 |
#endif |
|
36 |
||
37 |
#ifndef __osx__ |
|
21452 | 38 |
# define NO_QUARTZ |
39 |
# define NO_COCOA |
|
22959 | 40 |
# define NO_CARBON |
24047 | 41 |
# define NO_COREGRAPHICS |
21452 | 42 |
#endif |
43 |
||
25087 | 44 |
#ifdef __GNUC__ |
45 |
# define NO_COCOA |
|
46 |
# define NO_COREGRAPHICS |
|
47 |
#endif |
|
48 |
||
22833 | 49 |
// #include <mach/clock.h> |
50 |
// #include <mach/mach.h> |
|
51 |
// #include <sys/time.h> |
|
52 |
// #include <mach/clock.h> |
|
53 |
||
21452 | 54 |
#ifndef NO_COCOA |
55 |
||
56 |
# undef Array |
|
57 |
# undef Number |
|
58 |
# undef Method |
|
59 |
# undef Point |
|
60 |
# undef Rectangle |
|
61 |
# undef Block |
|
62 |
# undef String |
|
63 |
# undef Character |
|
64 |
# undef Message |
|
65 |
# undef Object |
|
66 |
# undef Context |
|
67 |
# undef Time |
|
68 |
# undef Date |
|
69 |
# undef Set |
|
70 |
# undef Signal |
|
71 |
# undef Delay |
|
72 |
# undef NameSpace |
|
73 |
# undef Process |
|
74 |
# undef Processor |
|
75 |
# undef Class |
|
76 |
# undef FixedPoint |
|
77 |
# undef true |
|
78 |
# undef false |
|
79 |
||
80 |
# undef INT |
|
81 |
# undef UINT |
|
82 |
||
22491 | 83 |
# include <ApplicationServices/ApplicationServices.h> |
84 |
# include <CoreFoundation/CoreFoundation.h> |
|
21452 | 85 |
// #include <Foundation/Foundation.h> |
24047 | 86 |
# include <CoreGraphics/CGGeometry.h> |
21595 | 87 |
|
88 |
// #include <CoreGraphics/CGEventTypes.h> |
|
21452 | 89 |
|
22491 | 90 |
# include <stdlib.h> |
91 |
# include <stdio.h> |
|
92 |
# include <IOKit/graphics/IOGraphicsLib.h> |
|
21452 | 93 |
|
22491 | 94 |
# include <objc/runtime.h> |
95 |
# include <objc/message.h> |
|
21452 | 96 |
|
97 |
# ifdef __DEF_Array |
|
98 |
# define Array __DEF_Array |
|
99 |
# endif |
|
100 |
# ifdef __DEF_Number |
|
101 |
# define Number __DEF_Number |
|
102 |
# endif |
|
103 |
# ifdef __DEF_Method |
|
104 |
# define Method __DEF_Method |
|
105 |
# endif |
|
106 |
# ifdef __DEF_Point |
|
107 |
# define Point __DEF_Point |
|
108 |
# endif |
|
109 |
# ifdef __DEF_Rectangle |
|
110 |
# define Rectangle __DEF_Rectangle |
|
111 |
# endif |
|
112 |
# ifdef __DEF_Block |
|
113 |
# define Block __DEF_Block |
|
114 |
# endif |
|
115 |
# ifdef __DEF_String |
|
116 |
# define String __DEF_String |
|
117 |
# endif |
|
118 |
# ifdef __DEF_Character |
|
119 |
# define Character __DEF_Character |
|
120 |
# endif |
|
121 |
# ifdef __DEF_Message |
|
122 |
# define Message __DEF_Message |
|
123 |
# endif |
|
124 |
# ifdef __DEF_Object |
|
125 |
# define Object __DEF_Object |
|
126 |
# endif |
|
127 |
# ifdef __DEF_Context |
|
128 |
# define Context __DEF_Context |
|
129 |
# endif |
|
130 |
# ifdef __DEF_Date |
|
131 |
# define Date __DEF_Date |
|
132 |
# endif |
|
133 |
# ifdef __DEF_Time |
|
134 |
# define Time __DEF_Time |
|
135 |
# endif |
|
136 |
# ifdef __DEF_Set |
|
137 |
# define Set __DEF_Set |
|
138 |
# endif |
|
139 |
# ifdef __DEF_Signal |
|
140 |
# define Signal __DEF_Signal |
|
141 |
# endif |
|
142 |
# ifdef __DEF_Delay |
|
143 |
# define Delay __DEF_Delay |
|
144 |
# endif |
|
145 |
# ifdef __DEF_NameSpace |
|
146 |
# define NameSpace __DEF_NameSpace |
|
147 |
# endif |
|
148 |
# ifdef __DEF_Process |
|
149 |
# define Process __DEF_Process |
|
150 |
# endif |
|
151 |
# ifdef __DEF_Processor |
|
152 |
# define Processor __DEF_Processor |
|
153 |
# endif |
|
154 |
# ifdef __DEF_Class |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
155 |
# define STX_Class __DEF_Class |
21452 | 156 |
# endif |
157 |
# ifdef __DEF_FixedPoint |
|
158 |
# define FixedPoint __DEF_FixedPoint |
|
159 |
# endif |
|
160 |
# ifdef __DEF_true |
|
161 |
# undef true |
|
162 |
# define true __DEF_true |
|
163 |
# endif |
|
164 |
# ifdef __DEF_false |
|
165 |
# undef false |
|
166 |
# define false __DEF_false |
|
167 |
# endif |
|
168 |
||
169 |
# define INT STX_INT |
|
170 |
# define UINT STX_UINT |
|
171 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
172 |
typedef struct CMPoint { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
173 |
double x; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
174 |
double y; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
175 |
} CMPoint; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
176 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
177 |
typedef struct CMSize { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
178 |
double width; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
179 |
double height; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
180 |
} CMSize; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
181 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
182 |
typedef struct CMRect { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
183 |
CMPoint origin; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
184 |
CMSize size; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
185 |
} CMRect; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
186 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
187 |
typedef struct AppDel { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
188 |
Class isa; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
189 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
190 |
// Will be an NSWindow later. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
191 |
id window; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
192 |
} AppDelegate; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
193 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
194 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
195 |
enum { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
196 |
NSBorderlessWindowMask = 0, |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
197 |
NSTitledWindowMask = 1 << 0, |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
198 |
NSClosableWindowMask = 1 << 1, |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
199 |
NSMiniaturizableWindowMask = 1 << 2, |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
200 |
NSResizableWindowMask = 1 << 3, |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
201 |
}; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
202 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
203 |
typedef id(*CMacsSimpleMessage)(id, SEL); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
204 |
typedef void(*CMacsVoidMessage)(id, SEL); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
205 |
typedef void(*CMacsVoidMessage1)(id, SEL, void *); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
206 |
typedef id(*CMacsRectMessage1)(id, SEL, CMRect); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
207 |
typedef id(*CMacsWindowInitMessage)(id, SEL, CMRect, int, int, bool); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
208 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
209 |
extern CMacsSimpleMessage cmacs_simple_msgSend; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
210 |
extern CMacsVoidMessage cmacs_void_msgSend; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
211 |
extern CMacsVoidMessage1 cmacs_void_msgSend1; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
212 |
extern CMacsRectMessage1 cmacs_rect_msgSend1; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
213 |
extern CMacsWindowInitMessage cmacs_window_init_msgSend; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
214 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
215 |
#endif // NO_COCOA |
21452 | 216 |
|
217 |
%} |
|
218 |
! ! |
|
219 |
||
220 |
!OSXOperatingSystem primitiveFunctions! |
|
221 |
%{ |
|
222 |
||
223 |
#ifndef NO_COCOA |
|
224 |
||
24047 | 225 |
struct ev { |
226 |
struct ev* nextEvent; |
|
227 |
CGEventType type; |
|
228 |
CGKeyCode keycode; |
|
229 |
int x,y; |
|
230 |
int button; |
|
231 |
}; |
|
232 |
static struct ev *nextRecordedEvent = NULL; |
|
233 |
static struct ev *lastRecordedEvent = NULL; |
|
234 |
||
21452 | 235 |
CGEventRef |
236 |
myCGEventCallback(CGEventTapProxy proxy, CGEventType type, |
|
237 |
CGEventRef event, void *refcon) |
|
238 |
{ |
|
24047 | 239 |
if ((type == kCGEventKeyDown) || (type == kCGEventKeyUp)) { |
240 |
// The incoming keycode. |
|
241 |
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); |
|
242 |
} |
|
243 |
if (type == kCGEventMouseMoved) { |
|
244 |
// loc = [NSEvent mouseLocation] |
|
245 |
// int x = loc.x; |
|
246 |
// int y = loc.y; |
|
247 |
} |
|
21452 | 248 |
// We must return the event for it to be useful. |
249 |
return event; |
|
250 |
} |
|
251 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
252 |
BOOL |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
253 |
AppDel_didFinishLaunching(AppDelegate *self, SEL _cmd, id notification) { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
254 |
// self->window = cmacs_simple_msgSend((id)objc_getClass("NSWindow"), sel_getUid("alloc")); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
255 |
// |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
256 |
// /// Create an instance of the window. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
257 |
// self->window = cmacs_window_init_msgSend(self->window, sel_getUid("initWithContentRect:styleMask:backing:defer:"), (CMRect){0,0,1024,460}, (NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask), 0, false); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
258 |
// |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
259 |
// /// Create an instance of our view class. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
260 |
// /// |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
261 |
// /// Relies on the view having declared a constructor that allocates a class pair for it. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
262 |
// id view = cmacs_rect_msgSend1(cmacs_simple_msgSend((id)objc_getClass("View"), sel_getUid("alloc")), sel_getUid("initWithFrame:"), (CMRect){ 0, 0, 320, 480 }); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
263 |
// |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
264 |
// // here we simply add the view to the window. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
265 |
// cmacs_void_msgSend1(self->window, sel_getUid("setContentView:"), view); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
266 |
// cmacs_simple_msgSend(self->window, sel_getUid("becomeFirstResponder")); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
267 |
// |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
268 |
// // Shows our window in the bottom-left hand corner of the screen. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
269 |
// cmacs_void_msgSend1(self->window, sel_getUid("makeKeyAndOrderFront:"), self); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
270 |
return YES; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
271 |
} |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
272 |
|
21452 | 273 |
#endif // NO_COCOA |
274 |
||
275 |
%} |
|
276 |
! ! |
|
277 |
||
278 |
!OSXOperatingSystem class methodsFor:'documentation'! |
|
279 |
||
280 |
copyright |
|
281 |
" |
|
282 |
COPYRIGHT (c) 2013 by Claus Gittinger |
|
21455 | 283 |
All Rights Reserved |
21452 | 284 |
|
285 |
This software is furnished under a license and may be used |
|
286 |
only in accordance with the terms of that license and with the |
|
287 |
inclusion of the above copyright notice. This software may not |
|
288 |
be provided or otherwise made available to, or used by, any |
|
289 |
other person. No title to or ownership of the software is |
|
290 |
hereby transferred. |
|
291 |
" |
|
292 |
! |
|
293 |
||
294 |
documentation |
|
295 |
" |
|
296 |
a small number of OS-X specific redefinitions here. |
|
297 |
||
298 |
[Author:] |
|
21455 | 299 |
Claus Gittinger |
21452 | 300 |
" |
301 |
! ! |
|
17471 | 302 |
|
303 |
!OSXOperatingSystem class methodsFor:'initialization'! |
|
304 |
||
305 |
initializeCodeset |
|
306 |
super initializeCodeset. |
|
17493 | 307 |
Codeset := #'utf8-mac'. |
17494 | 308 |
CodesetEncoder := nil. |
17471 | 309 |
! ! |
14819 | 310 |
|
21452 | 311 |
!OSXOperatingSystem class methodsFor:'cocoa - events'! |
312 |
||
21591 | 313 |
finishLaunching |
314 |
"tell the system, that I have finished my startup phase. |
|
315 |
OSX will stop bounding the launch icon then." |
|
21596 | 316 |
|
21591 | 317 |
NSApp isNil ifTrue:[ |
21596 | 318 |
self getNSApp |
21591 | 319 |
]. |
320 |
%{ |
|
321 |
#ifndef NO_COCOA |
|
322 |
id NSApp = __externalAddressVal(@global(NSApp)); |
|
24339 | 323 |
extern int __stxNSAppIsRunning(); |
21591 | 324 |
|
24339 | 325 |
if (!__stxNSAppIsRunning()) { |
24095 | 326 |
objc_msgSend(NSApp, sel_getUid("finishLaunching")); |
327 |
} |
|
21591 | 328 |
RETURN(self); |
329 |
#endif // NO_COCOA |
|
330 |
%}. |
|
331 |
"/ if compiled without COCOA support (which you should not), |
|
332 |
"/ the icon will probably continue to bounce... |
|
333 |
"/ ... but we do not want an error here. |
|
21596 | 334 |
|
21591 | 335 |
"/ self primitiveFailed |
336 |
||
337 |
" |
|
338 |
self finishLaunching |
|
339 |
" |
|
340 |
||
341 |
"Modified: / 28-02-2017 / 10:59:15 / cg" |
|
342 |
! |
|
343 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
344 |
generateButtonEvent:button down:down x:screenX y:screenY |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
345 |
"synthesize and send a button event to the screen" |
21584 | 346 |
%{ |
347 |
#ifndef NO_COCOA |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
348 |
if (__bothSmallInteger(screenX, screenY) |
21584 | 349 |
&& __isSmallInteger(button)) { |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
350 |
CGPoint pt; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
351 |
pt.x = __intVal(screenX); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
352 |
pt.y = __intVal(screenY); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
353 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
354 |
CGEventType evType; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
355 |
CGMouseButton evButton = __intVal(button); |
21584 | 356 |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
357 |
switch (evButton) { |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
358 |
case 1: |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
359 |
evType = (down == true) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
360 |
evButton = 0; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
361 |
break; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
362 |
case 2: |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
363 |
evType = (down == true) ? kCGEventRightMouseDown : kCGEventRightMouseUp; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
364 |
evButton = 1; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
365 |
break; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
366 |
case 3: |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
367 |
evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
368 |
evButton = 2; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
369 |
break; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
370 |
default: |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
371 |
evType = (down == true) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
372 |
evButton = __intVal(button) - 1; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
373 |
break; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
374 |
} |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
375 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
376 |
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, evType, pt, evButton); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
377 |
CGEventSetType(theEvent, evType); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
378 |
CGEventPost(kCGHIDEventTap, theEvent); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
379 |
CFRelease(theEvent); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
380 |
RETURN(self); |
21584 | 381 |
} |
382 |
#endif // NO_COCOA |
|
383 |
%}. |
|
384 |
self primitiveFailed |
|
385 |
||
386 |
" |
|
387 |
OperatingSystem generateButtonEvent:1 down:true x:150 y:150. |
|
388 |
OperatingSystem generateButtonEvent:1 down:false x:150 y:150. |
|
389 |
||
390 |
OperatingSystem generateButtonEvent:2 down:true x:150 y:150. |
|
391 |
OperatingSystem generateButtonEvent:2 down:false x:150 y:150. |
|
392 |
" |
|
393 |
||
394 |
"Created: / 28-02-2017 / 00:15:18 / cg" |
|
395 |
! |
|
396 |
||
21621 | 397 |
generateKeyboardEvent:keyCode down:down |
398 |
"synthesize and send a keyboard event to the screen" |
|
399 |
%{ |
|
400 |
#ifndef NO_COCOA |
|
401 |
if (__isSmallInteger(keyCode)) { |
|
21627 | 402 |
int evType; |
403 |
||
404 |
CGEventRef theEvent = CGEventCreateKeyboardEvent(NULL, __intVal(keyCode), (down==true)?1:0); |
|
405 |
CGEventSetType(theEvent, (down==true) ? kCGEventKeyDown:kCGEventKeyUp); |
|
406 |
CGEventPost(kCGHIDEventTap, theEvent); |
|
407 |
CFRelease(theEvent); |
|
408 |
RETURN(self); |
|
21621 | 409 |
} |
410 |
#endif // NO_COCOA |
|
411 |
%}. |
|
412 |
self primitiveFailed |
|
413 |
||
414 |
" |
|
415 |
OperatingSystem generateKeyboardEvent:6 down:true. |
|
416 |
OperatingSystem generateKeyboardEvent:6 down:false. |
|
417 |
" |
|
418 |
||
419 |
"Created: / 02-03-2017 / 16:35:04 / cg" |
|
420 |
! |
|
421 |
||
422 |
generateMouseMoveEventX:screenX y:screenY |
|
24047 | 423 |
"synthesize and send a mouse move event to the screen" |
21621 | 424 |
%{ |
425 |
#ifndef NO_COCOA |
|
426 |
if (__bothSmallInteger(screenX, screenY)) { |
|
21627 | 427 |
CGPoint pt; |
428 |
pt.x = __intVal(screenX); |
|
429 |
pt.y = __intVal(screenY); |
|
21621 | 430 |
|
21627 | 431 |
CGEventType evType; |
432 |
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, pt, 0); |
|
433 |
CGEventSetType(theEvent, kCGEventMouseMoved); |
|
434 |
CGEventPost(kCGHIDEventTap, theEvent); |
|
435 |
CFRelease(theEvent); |
|
436 |
RETURN(self); |
|
21621 | 437 |
} |
438 |
#endif // NO_COCOA |
|
439 |
%}. |
|
440 |
self primitiveFailed |
|
441 |
||
442 |
" |
|
443 |
OperatingSystem generateMouseMoveEventX:150 y:5. |
|
444 |
Delay waitFor:(1 seconds). |
|
445 |
OperatingSystem generateMouseMoveEventX:1050 y:150. |
|
446 |
" |
|
447 |
||
448 |
"Created: / 02-03-2017 / 20:01:51 / cg" |
|
449 |
! |
|
450 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
451 |
getNSApp |
23114 | 452 |
"get the NSApplication instance and remember in the global named NSApp" |
453 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
454 |
%{ |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
455 |
#ifndef NO_COCOA |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
456 |
Class AppDelClass = NULL; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
457 |
id NSApp = NULL; |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
458 |
|
21731 | 459 |
# if 0 /* not needed */ |
21597 | 460 |
Class poolClass = objc_getClass("NSAutoreleasePool"); |
21594 | 461 |
if (poolClass == NULL) { |
21597 | 462 |
fprintf(stderr, "OSX: Unable to get NSAutoreleasePool\n"); |
463 |
RETURN(false); |
|
21594 | 464 |
} |
465 |
id pool = objc_msgSend(poolClass, sel_registerName("alloc")); |
|
466 |
if (pool == NULL) { |
|
21597 | 467 |
fprintf(stderr, "OSX: Unable to create NSAutoreleasePool\n"); |
468 |
RETURN(false); |
|
21594 | 469 |
} |
470 |
objc_msgSend(pool, sel_registerName("init")); |
|
21731 | 471 |
# endif |
21594 | 472 |
|
21731 | 473 |
# if 0 /* not needed */ |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
474 |
AppDelClass = objc_allocateClassPair((Class)objc_getClass("NSObject"), "AppDelegate", 0); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
475 |
class_addMethod(AppDelClass, sel_getUid("applicationDidFinishLaunching:"), (IMP)AppDel_didFinishLaunching, "i@:@"); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
476 |
objc_registerClassPair(AppDelClass); |
21731 | 477 |
# endif |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
478 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
479 |
NSApp = objc_msgSend((id)objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
480 |
if (NSApp == NULL) { |
21597 | 481 |
fprintf(stderr,"OSX: Failed to initialize NSApplication\n"); |
482 |
RETURN(false); |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
483 |
} |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
484 |
@global(NSApp) = __MKEXTERNALADDRESS(NSApp); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
485 |
|
24069 | 486 |
# if 0 /* not needed */ |
21594 | 487 |
id req = objc_msgSend(NSApp,sel_getUid("requestUserAttention:"),0); |
488 |
objc_msgSend(NSApp,sel_getUid("cancelUserAttentionRequest:"),req); |
|
24069 | 489 |
# endif |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
490 |
|
21731 | 491 |
# if 0 /* not needed */ |
21594 | 492 |
id appDelInst = objc_msgSend((id)objc_getClass("AppDelegate"), sel_getUid("alloc")); |
493 |
objc_msgSend(appDelInst, sel_getUid("init")); |
|
494 |
objc_msgSend(NSApp, sel_getUid("setDelegate:"), appDelInst); |
|
21731 | 495 |
# endif |
21594 | 496 |
|
21731 | 497 |
# if 0 /* not needed */ |
21594 | 498 |
objc_msgSend(pool, sel_registerName("release")); |
21731 | 499 |
# endif |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
500 |
RETURN(true); |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
501 |
#endif // NO_COCOA |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
502 |
%}. |
25250 | 503 |
^ false |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
504 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
505 |
" |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
506 |
self getNSApp |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
507 |
" |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
508 |
|
21594 | 509 |
"Modified: / 28-02-2017 / 13:45:39 / cg" |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
510 |
! |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
511 |
|
21591 | 512 |
receiveNextEvent |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
513 |
%{ |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
514 |
#ifndef NO_COCOA |
21591 | 515 |
CFMachPortRef eventTap; |
516 |
CGEventMask eventMask; |
|
517 |
CFRunLoopSourceRef runLoopSource; |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
518 |
|
21591 | 519 |
// Create an event tap. We are interested in key presses. |
24047 | 520 |
// sigh: a global event tap requires root privileges |
521 |
eventMask = ((1 << kCGEventKeyDown) |
|
522 |
| (1 << kCGEventKeyUp) |
|
523 |
| (1 << kCGEventMouseMoved)); |
|
21591 | 524 |
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, |
525 |
eventMask, NULL, myCGEventCallback); |
|
526 |
if (!eventTap) { |
|
527 |
fprintf(stderr, "failed to create event tap\n"); |
|
528 |
} else { |
|
529 |
fprintf(stderr, "ok\n"); |
|
530 |
||
531 |
// Create a run loop source. |
|
532 |
runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0); |
|
533 |
// Enable the event tap. |
|
534 |
CGEventTapEnable(eventTap, true); |
|
535 |
} |
|
536 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
537 |
#endif // NO_COCOA |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
538 |
%}. |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
539 |
self primitiveFailed |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
540 |
|
21591 | 541 |
"Modified: / 28-02-2017 / 01:05:04 / cg" |
21452 | 542 |
! ! |
543 |
||
17297
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
544 |
!OSXOperatingSystem class methodsFor:'dummy shell operations'! |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
545 |
|
22655 | 546 |
openApplicationForDocument:aFilenameOrString operation:operationSymbol |
547 |
"open a windows-shell/mac finder/desktop application to present the document contained in aFilenameOrString. |
|
548 |
This is typically used to present help-files, html documents, pdf documents etc. |
|
549 |
operationSymbol is one of: |
|
22833 | 550 |
open |
551 |
edit |
|
552 |
explore |
|
22655 | 553 |
" |
554 |
||
555 |
|openCmd| |
|
556 |
||
557 |
(openCmd := self openApplicationHelperCommand) notNil ifTrue:[ |
|
22833 | 558 |
(operationSymbol = 'open') ifTrue:[ |
559 |
self executeCommand:'open "',aFilenameOrString asFilename pathName,'"' |
|
560 |
] ifFalse:[ |
|
561 |
(operationSymbol = 'explore') ifTrue:[ |
|
562 |
self executeCommand:'open -R "',aFilenameOrString asFilename pathName,'"' |
|
563 |
]. |
|
564 |
]. |
|
22655 | 565 |
]. |
566 |
! |
|
567 |
||
17297
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
568 |
openApplicationHelperCommand |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
569 |
"Return a command line helper to open a default application for file or URL" |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
570 |
|
18279 | 571 |
(self canExecuteCommand: 'open') ifTrue:[ |
572 |
^ 'open' |
|
17297
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
573 |
]. |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
574 |
^ nil |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
575 |
|
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
576 |
"Created: / 13-01-2015 / 09:23:18 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
17427 | 577 |
! |
578 |
||
17428 | 579 |
openTerminalWithCommand:shellCommand inBackground:inBackground |
17427 | 580 |
"open a new terminal, which executes a command" |
581 |
||
17428 | 582 |
|cmd| |
583 |
||
584 |
cmd := 'osascript -e ''tell application "Terminal" to do script "%1"''' bindWith:shellCommand. |
|
585 |
||
586 |
inBackground ifTrue:[ |
|
18279 | 587 |
^ self |
588 |
startProcess:cmd |
|
589 |
inputFrom:nil |
|
590 |
outputTo:nil |
|
591 |
errorTo:nil |
|
592 |
auxFrom:nil |
|
593 |
environment:nil |
|
594 |
inDirectory:nil |
|
17428 | 595 |
] ifFalse:[ |
18279 | 596 |
^ self executeCommand:cmd |
17428 | 597 |
]. |
17427 | 598 |
|
599 |
" |
|
17428 | 600 |
OSXOperatingSystem openTerminalWithCommand:'ls -l' inBackground:true |
17427 | 601 |
" |
17297
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
602 |
! ! |
a56ba300949c
Overriden openApplicationForDocument... to use desktop-specific "open" command.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
17179
diff
changeset
|
603 |
|
14819 | 604 |
!OSXOperatingSystem class methodsFor:'file queries'! |
605 |
||
606 |
caseSensitiveFilenames |
|
607 |
"return true, if the OS has caseSensitive file naming. |
|
608 |
On MSDOS, this will return false; |
|
19817 | 609 |
on a real OS, we return true. |
610 |
Be aware, that OSX can be configured to be either. |
|
611 |
Also, that it actually depends on the mounted volume" |
|
14819 | 612 |
|
18279 | 613 |
"/ actually, this is wrong and depends on the mounted volume; |
614 |
"/ so we need a query for a particular directory (and/or volume). |
|
14819 | 615 |
^ false |
616 |
||
617 |
"Modified: / 5.6.1998 / 18:35:18 / cg" |
|
16381 | 618 |
! |
619 |
||
16644 | 620 |
defaultPackagePath |
20639 | 621 |
"redefined to add /Application and /Library stuff" |
20642 | 622 |
"called by Smalltalk initSystemPath" |
623 |
"self defaultPackagePath" |
|
16644 | 624 |
|
21452 | 625 |
|path executablePath executableDir packagesDir |
20637 | 626 |
libDir appDir versionsDir vsnDirName vsnDir| |
16644 | 627 |
|
628 |
path := super defaultPackagePath. |
|
629 |
||
630 |
executablePath := OperatingSystem pathOfSTXExecutable. |
|
631 |
executablePath notNil ifTrue:[ |
|
21452 | 632 |
executableDir := executablePath asFilename directory. |
633 |
packagesDir := executableDir directory directory / 'Packages'. |
|
634 |
packagesDir exists ifTrue:[ |
|
635 |
packagesDir := packagesDir pathName. |
|
636 |
(path includes:packagesDir) ifFalse:[ |
|
637 |
path add:packagesDir. |
|
638 |
]. |
|
639 |
]. |
|
640 |
libDir := '/Library/Frameworks/SmalltalkX.framework' asFilename. |
|
641 |
libDir exists ifTrue:[ |
|
642 |
versionsDir := libDir / 'Versions'. |
|
643 |
versionsDir exists ifTrue:[ |
|
644 |
vsnDirName := '%1.%2.%3' |
|
645 |
bindWith:Smalltalk majorVersionNr |
|
646 |
with:Smalltalk minorVersionNr |
|
647 |
with:Smalltalk revisionNr. |
|
648 |
vsnDir := versionsDir / vsnDirName. |
|
649 |
vsnDir exists ifTrue:[ |
|
650 |
vsnDir := vsnDir pathName. |
|
651 |
(path includes:vsnDir) ifFalse:[ |
|
652 |
path add:vsnDir. |
|
653 |
]. |
|
654 |
]. |
|
655 |
]. |
|
656 |
]. |
|
657 |
appDir := '/Applications/SmalltalkX/' asFilename. |
|
658 |
appDir exists ifTrue:[ |
|
659 |
versionsDir := appDir / 'Versions'. |
|
660 |
versionsDir exists ifTrue:[ |
|
661 |
vsnDirName := '%1.%2.%3' |
|
662 |
bindWith:Smalltalk majorVersionNr |
|
663 |
with:Smalltalk minorVersionNr |
|
664 |
with:Smalltalk revisionNr. |
|
665 |
vsnDir := versionsDir / vsnDirName. |
|
666 |
vsnDir exists ifTrue:[ |
|
667 |
vsnDir := vsnDir pathName. |
|
668 |
(path includes:vsnDir) ifFalse:[ |
|
669 |
path add:vsnDir. |
|
670 |
]. |
|
671 |
]. |
|
672 |
]. |
|
673 |
]. |
|
16644 | 674 |
]. |
16647 | 675 |
^ path |
16644 | 676 |
! |
677 |
||
22655 | 678 |
getDocumentsDirectory |
679 |
"return your documents directory. |
|
680 |
Under osx, that's the user's 'Documents' folder. |
|
681 |
The fallback for other OS's may return the user's home directory." |
|
682 |
||
683 |
"{ Pragma: +optSpace }" |
|
684 |
||
685 |
|home documentsFolder| |
|
686 |
||
687 |
(home := self getHomeDirectory) notNil ifTrue:[ |
|
22833 | 688 |
(documentsFolder := home asFilename / 'Documents') exists ifTrue:[ |
689 |
^ documentsFolder pathName |
|
690 |
]. |
|
22655 | 691 |
]. |
692 |
^ home |
|
693 |
||
694 |
" |
|
695 |
OperatingSystem getDocumentsDirectory |
|
696 |
" |
|
697 |
! |
|
698 |
||
16677 | 699 |
getDriveList |
700 |
"return a list of volumes in the system." |
|
701 |
||
702 |
^ ('/Volumes' asFilename directoryContents) |
|
703 |
, super getDriveList |
|
704 |
! |
|
705 |
||
16381 | 706 |
getTrashDirectory |
707 |
"get the name of a trash folder (if the OS supports it), |
|
708 |
or nil, if not. |
|
709 |
Must be redefined to return non nil in concrete operating systems" |
|
710 |
||
711 |
^ '~/.Trash' |
|
16677 | 712 |
! |
713 |
||
714 |
pathNameForDrive:driveName |
|
715 |
"given a drive name, return the pathname to open it as a directory. |
|
716 |
For Windows, this is the driveName itself. |
|
717 |
For OSX, '/Volumes' is prepended. |
|
718 |
Other OSs might prepent the pount point (i.e. /mnt/)" |
|
719 |
||
16905 | 720 |
driveName isNil ifTrue:[^ nil]. |
16677 | 721 |
driveName asFilename isAbsolute ifTrue:[^ driveName]. |
722 |
^ '/Volumes/',driveName |
|
17177 | 723 |
! |
724 |
||
725 |
supportsVolumes |
|
18279 | 726 |
"return true if the os support a list of drives/volumes |
17179 | 727 |
(here we can return a list of mounted drives in /Volumes)" |
17177 | 728 |
|
729 |
^ true |
|
14819 | 730 |
! ! |
731 |
||
21452 | 732 |
!OSXOperatingSystem class methodsFor:'quartz - screen'! |
733 |
||
734 |
getFrameBufferImage:displayNr |
|
735 |
"returns the framebuffer as an image object" |
|
736 |
||
21580 | 737 |
^ self getFrameBufferImage:displayNr in:nil |
738 |
||
739 |
" |
|
740 |
self getFrameBufferImage:0 |
|
741 |
" |
|
742 |
||
743 |
"Modified: / 25-02-2017 / 10:57:17 / cg" |
|
744 |
! |
|
21452 | 745 |
|
21580 | 746 |
getFrameBufferImage:displayNr in:aRectangleOrNil |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
747 |
"returns the frameBuffer (if rect-arg is nil) |
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
748 |
or part of the framebuffer (if non-nil) as an image object" |
21580 | 749 |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
750 |
|rx ry rwidth rheight bytesPerPixel bytesPerRow address pixels depth pad img ok| |
21580 | 751 |
|
752 |
aRectangleOrNil notNil ifTrue:[ |
|
25250 | 753 |
rx := aRectangleOrNil left. |
754 |
ry := aRectangleOrNil top. |
|
755 |
rwidth := aRectangleOrNil width. |
|
756 |
rheight := aRectangleOrNil height. |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
757 |
]. |
21452 | 758 |
%{ |
21596 | 759 |
#ifndef NO_COCOA |
21580 | 760 |
CGImageRef image_ref; |
761 |
CGDirectDisplayID displayID = CGMainDisplayID(); |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
762 |
|
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
763 |
ok = false; |
21580 | 764 |
if (rx == nil) { |
25250 | 765 |
image_ref = CGDisplayCreateImage(displayID); |
21580 | 766 |
} else { |
25250 | 767 |
CGRect rect; |
768 |
rect.origin.x = (CGFloat)__intVal(rx); |
|
769 |
rect.origin.y = (CGFloat)__intVal(ry); |
|
770 |
rect.size.width = (CGFloat)__intVal(rwidth); |
|
771 |
rect.size.height = (CGFloat)__intVal(rheight); |
|
772 |
image_ref = CGDisplayCreateImageForRect(displayID, rect); |
|
21580 | 773 |
} |
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
774 |
|
21580 | 775 |
if (image_ref != NULL) { |
25250 | 776 |
CGDataProviderRef provider = CGImageGetDataProvider(image_ref); |
777 |
CFDataRef dataref = CGDataProviderCopyData(provider); |
|
778 |
size_t c_width = CGImageGetWidth(image_ref); |
|
779 |
size_t c_height = CGImageGetHeight(image_ref); |
|
780 |
size_t c_bytesPerRow = CGImageGetBytesPerRow(image_ref); |
|
781 |
size_t c_bytesPerPixel = CGImageGetBitsPerPixel(image_ref) / 8; |
|
782 |
unsigned char *c_pixels = (unsigned char *)CFDataGetBytePtr(dataref); |
|
21452 | 783 |
|
25250 | 784 |
if (c_bytesPerPixel == 4) { |
785 |
int row; |
|
786 |
pixels = __BYTEARRAY_UNINITIALIZED_NEW_INT(c_width * c_height * 3); |
|
787 |
unsigned char *srcRowPtr = c_pixels; |
|
788 |
unsigned char *dstRowPtr = __byteArrayVal(pixels); |
|
24377 | 789 |
|
25250 | 790 |
for (row=c_height; row>0; row--) { |
791 |
int col = c_width; |
|
792 |
unsigned int *pixSrcPtr = (unsigned int*)srcRowPtr; |
|
793 |
unsigned char *pixDstPtr = dstRowPtr; |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
794 |
|
25250 | 795 |
// convert abgr to rgb |
23954 | 796 |
#if (__POINTER_SIZE__ == 8) && defined(__LSBFIRST__) |
25250 | 797 |
if (((INT)pixSrcPtr & 7) == 0) { |
798 |
// is aligned |
|
799 |
for (; col > 4; col -= 4) { |
|
800 |
// pick 4 pixels (16byte with 2 INT fetches) store as 12byte (4ints) |
|
801 |
unsigned INT pix12 = ((unsigned INT*)pixSrcPtr)[0]; |
|
802 |
unsigned INT pix34 = ((unsigned INT*)pixSrcPtr)[1]; |
|
803 |
unsigned int w; |
|
804 |
||
805 |
pixSrcPtr += 4; |
|
806 |
// a2 r2 g2 b2 a1 r1 g1 b1 => r1..g1..b1..r2..g2..b2 |
|
807 |
w = (pix12 >> 16) & 0xFF; // r1 |
|
808 |
w |= ((pix12 >> 8) & 0xFF) << 8; // g1 |
|
809 |
w |= (pix12 & 0xFF) << 16; // b1 |
|
810 |
w |= ((pix12 >> 48) & 0xFF)<<24; // r2 |
|
811 |
((int*)pixDstPtr)[0] = w; |
|
812 |
w = (pix12 >> 40) & 0xFF; // g2 |
|
813 |
w |= ((pix12 >> 32) & 0xFF)<<8; // b2 |
|
814 |
w |= ((pix34 >> 16) & 0xFF)<<16; // r3 |
|
815 |
w |= ((pix34 >> 8) & 0xFF) <<24; // g3 |
|
816 |
((int*)pixDstPtr)[1] = w; |
|
817 |
w = (pix34 & 0xFF); // b3 |
|
818 |
w |= ((pix34 >> 48) & 0xFF)<<8; // r4 |
|
819 |
w |= ((pix34 >> 40) & 0xFF)<<16; // g2 |
|
820 |
w |= ((pix12 >> 32) & 0xFF)<<24; // b2 |
|
821 |
((int*)pixDstPtr)[2] = w; |
|
822 |
pixDstPtr += 12; |
|
823 |
} |
|
824 |
} |
|
825 |
for (; col > 2; col -= 2) { |
|
826 |
// pick 2 pixels (8byte with one fetch) store as 6byte |
|
827 |
unsigned INT pix12 = ((unsigned INT*)pixSrcPtr)[0]; |
|
828 |
pixSrcPtr += 2; |
|
829 |
// a2 r2 g2 b2 a1 r1 g1 b1 => r1..g1..b1..r2..g2..b2 |
|
830 |
pixDstPtr[0] = (pix12 >> 16) & 0xFF; |
|
831 |
pixDstPtr[1] = (pix12 >> 8) & 0xFF; |
|
832 |
pixDstPtr[2] = pix12 & 0xFF; |
|
833 |
pixDstPtr[3] = (pix12 >> 48) & 0xFF; |
|
834 |
pixDstPtr[4] = (pix12 >> 40) & 0xFF; |
|
835 |
pixDstPtr[5] = (pix12 >> 32) & 0xFF; |
|
836 |
pixDstPtr += 6; |
|
837 |
} |
|
23954 | 838 |
#endif |
21452 | 839 |
|
25250 | 840 |
for (; col>0;col--) { |
841 |
unsigned int pix = *pixSrcPtr++; |
|
23954 | 842 |
#if 0 |
25250 | 843 |
pix = ((pix >> 16) & 0x0000FF)|((pix << 16) & 0xFF0000)|(pix & 0x00FF00); |
844 |
pixDstPtr[0] = (pix >> 0); |
|
845 |
pixDstPtr[1] = (pix >> 8); |
|
846 |
pixDstPtr[2] = (pix >> 16); |
|
23954 | 847 |
#else |
25250 | 848 |
pixDstPtr[0] = (pix >> 16) & 0xFF; |
849 |
pixDstPtr[1] = (pix >> 8) & 0xFF; |
|
850 |
pixDstPtr[2] = pix & 0xFF; |
|
23954 | 851 |
#endif |
25250 | 852 |
pixDstPtr += 3; |
853 |
} |
|
854 |
dstRowPtr += c_width * 3; |
|
855 |
srcRowPtr += c_bytesPerRow; |
|
856 |
} |
|
857 |
bytesPerPixel = __MKSMALLINT(3); |
|
858 |
bytesPerRow = __MKSMALLINT( c_width*3 ); |
|
859 |
ok = true; |
|
860 |
} else { |
|
861 |
// to be determined what we get... |
|
862 |
ok = false; |
|
863 |
} |
|
864 |
CFRelease(dataref); |
|
865 |
CGImageRelease(image_ref); |
|
21580 | 866 |
|
25250 | 867 |
rwidth = __MKUINT( c_width ); |
868 |
rheight = __MKUINT( c_height ); |
|
21580 | 869 |
} |
870 |
||
871 |
// the following is no longer supported by apple |
|
872 |
// CGDisplayBaseAddress is deprecated |
|
873 |
// |
|
874 |
// uint32_t rowBytes, rowUInt32s, *screen; |
|
875 |
// |
|
876 |
// CGDirectDisplayID targetDisplay = 0; |
|
877 |
// |
|
878 |
// screen = (uint32_t *)CGDisplayBaseAddress(targetDisplay); |
|
879 |
// rowBytes = CGDisplayBytesPerRow(targetDisplay); |
|
880 |
// rowUInt32s = rowBytes / 4; |
|
881 |
// rwidth = __MKUINT( CGDisplayPixelsWide(targetDisplay) ); |
|
882 |
// rheight = __MKUINT( CGDisplayPixelsHigh(targetDisplay) ); |
|
883 |
// |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
884 |
|
21596 | 885 |
#endif // NO_COCOA |
21452 | 886 |
|
887 |
%}. |
|
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
888 |
(ok not or:[rwidth isNil]) ifTrue:[ |
25250 | 889 |
^ self primitiveFailed |
21452 | 890 |
]. |
891 |
depth := bytesPerPixel * 8. |
|
892 |
||
21587
3ac571f08fbf
hooks to send finishLaunching to NSApp
Claus Gittinger <cg@exept.de>
parents:
21585
diff
changeset
|
893 |
"/ Transcript printf:'w:%d h:%d bpp:%d depth:%d bpr: %d\n' |
21580 | 894 |
"/ withAll:{ rwidth . rheight . bytesPerPixel . depth . bytesPerRow}. |
21452 | 895 |
|
21598 | 896 |
( #(24) includes:depth) ifFalse:[ |
25250 | 897 |
"/ check what we get here... |
898 |
^ self primitiveFailed:'unsupported depth' |
|
21452 | 899 |
]. |
900 |
||
21580 | 901 |
img := Image extent:(rwidth @ rheight) depth:depth bits:pixels. |
21598 | 902 |
depth == 24 ifTrue:[ |
25250 | 903 |
img bitsPerSample:#[8 8 8]. |
904 |
img samplesPerPixel:3. |
|
905 |
img photometric:#rgb. |
|
21598 | 906 |
] ifFalse:[ |
25250 | 907 |
depth == 16 ifTrue:[ |
908 |
"/ to be determined... |
|
909 |
img bitsPerSample:#[5 5 5]. |
|
910 |
img samplesPerPixel:3. |
|
911 |
img photometric:#rgb. |
|
912 |
]. |
|
21627 | 913 |
]. |
21452 | 914 |
^ img |
21580 | 915 |
|
916 |
" |
|
917 |
self getFrameBufferImage:0 in:nil |
|
918 |
self getFrameBufferImage:0 in:(100@100 corner:301@303) |
|
21598 | 919 |
|
920 |
Delay waitFor:3 seconds. self getFrameBufferImage:0 in:nil |
|
21580 | 921 |
" |
922 |
||
923 |
"Created: / 25-02-2017 / 09:49:07 / cg" |
|
21598 | 924 |
"Modified (comment): / 28-02-2017 / 15:22:17 / cg" |
24378 | 925 |
"Modified: / 27-06-2019 / 15:21:51 / Claus Gittinger" |
21625 | 926 |
! |
927 |
||
24047 | 928 |
getMousePosition |
929 |
|xLoc yLoc| |
|
930 |
||
931 |
%{ |
|
932 |
#ifndef NO_COREGRAPHICS |
|
933 |
CGEventRef event = CGEventCreate(NULL); |
|
934 |
CGPoint loc = CGEventGetLocation(event); |
|
935 |
CFRelease(event); |
|
936 |
||
937 |
xLoc = __MKFLOAT(loc.x); |
|
938 |
yLoc = __MKFLOAT(loc.y); |
|
939 |
#endif // NO_COREGRAPHICS |
|
940 |
%}. |
|
941 |
^ xLoc @ yLoc |
|
942 |
! |
|
943 |
||
21627 | 944 |
getScreenBounds:displayNr |
21625 | 945 |
"returns the bounds of the screen. |
946 |
This is needed, because the dimension of the XQuartz screen does not include the dock." |
|
947 |
||
948 |
|rx ry rwidth rheight| |
|
949 |
||
950 |
%{ |
|
951 |
#ifndef NO_COCOA |
|
952 |
CGDirectDisplayID targetDisplay = 0; |
|
953 |
||
954 |
rx = ry = __MKSMALLINT(0); |
|
955 |
rwidth = __MKUINT( CGDisplayPixelsWide(targetDisplay) ); |
|
956 |
rheight = __MKUINT( CGDisplayPixelsHigh(targetDisplay) ); |
|
957 |
#endif // NO_COCOA |
|
958 |
%}. |
|
959 |
(rwidth isNil) ifTrue:[ |
|
21627 | 960 |
^ self primitiveFailed |
21625 | 961 |
]. |
962 |
^ rx@ry extent:(rwidth@rheight) |
|
963 |
||
964 |
" |
|
21627 | 965 |
self getScreenBounds:0 |
21625 | 966 |
" |
967 |
||
968 |
"Created: / 05-03-2017 / 11:10:08 / cg" |
|
21452 | 969 |
! ! |
970 |
||
22962 | 971 |
!OSXOperatingSystem class methodsFor:'sound & voice'! |
972 |
||
24464 | 973 |
bestVoiceForLanguage:language |
974 |
"choose a voice as per language" |
|
975 |
||
25307 | 976 |
|voiceName| |
977 |
||
978 |
(voiceName := super bestVoiceForLanguage:language) notNil ifTrue:[^ voiceName]. |
|
979 |
||
980 |
"/ some hardcoded names |
|
981 |
"/ TODO: ask os and choose what is present. |
|
24464 | 982 |
language = 'de' ifTrue:[ |
25307 | 983 |
^ 'Anna' |
25250 | 984 |
]. |
24464 | 985 |
language = 'en' ifTrue:[ |
25307 | 986 |
^ 'Fiona' |
987 |
]. |
|
988 |
language = 'fr' ifTrue:[ |
|
989 |
^ 'Aurelie' |
|
990 |
]. |
|
991 |
language = 'es' ifTrue:[ |
|
992 |
^ 'Monica' |
|
993 |
]. |
|
994 |
language = 'it' ifTrue:[ |
|
995 |
^ 'Alice' |
|
996 |
]. |
|
997 |
language = 'nl' ifTrue:[ |
|
998 |
^ 'Claire' |
|
25250 | 999 |
]. |
24464 | 1000 |
^ nil |
25250 | 1001 |
|
24464 | 1002 |
" |
25307 | 1003 |
OperatingSystem setVoice:'Andrea' forLanguage:'fr' |
1004 |
OperatingSystem setVoice:nil forLanguage:'fr' |
|
1005 |
||
24464 | 1006 |
self bestVoiceForLanguage:'de' |
25307 | 1007 |
self bestVoiceForLanguage:'en' |
1008 |
self bestVoiceForLanguage:'es' |
|
1009 |
self bestVoiceForLanguage:'fr' |
|
24464 | 1010 |
" |
1011 |
||
1012 |
"Created: / 23-07-2019 / 10:20:21 / Claus Gittinger" |
|
1013 |
! |
|
1014 |
||
23314 | 1015 |
canPlaySound |
1016 |
^ true |
|
1017 |
||
1018 |
"Created: / 29-08-2018 / 09:35:52 / Claus Gittinger" |
|
1019 |
! |
|
1020 |
||
1021 |
canSpeak |
|
1022 |
^ true |
|
1023 |
||
1024 |
"Created: / 29-08-2018 / 09:45:16 / Claus Gittinger" |
|
1025 |
! |
|
1026 |
||
22962 | 1027 |
playSound:soundFile |
24877 | 1028 |
"use 'afplay ...'" |
22962 | 1029 |
|
1030 |
^ self executeCommand:('afplay "%1"' bindWith:soundFile asFilename pathName) |
|
1031 |
||
1032 |
" |
|
24877 | 1033 |
self playSound:(Expecco::Expecco projectDirectory / 'resources/sounds/test_complete.wav') |
22962 | 1034 |
" |
1035 |
! |
|
1036 |
||
22970 | 1037 |
voiceCommandSpec |
1038 |
^ #( |
|
23114 | 1039 |
"/ triples are: |
1040 |
"/ -command |
|
1041 |
"/ -commandline for default voice |
|
1042 |
"/ -commandline for specific voice |
|
1043 |
( |
|
1044 |
'say' |
|
1045 |
'say "%2"' |
|
1046 |
'say -v "%1" "%2"' |
|
1047 |
) |
|
1048 |
) |
|
22966 | 1049 |
! |
1050 |
||
1051 |
voiceInfo |
|
1052 |
"return a list of available voices plus info: |
|
1053 |
for each available voice, a triple is returned, containing: |
|
23114 | 1054 |
voiceName language_territory comment/description |
22966 | 1055 |
" |
1056 |
||
1057 |
^ (PipeStream outputFromCommand:'say -v ?') |
|
23114 | 1058 |
asCollectionOfLines |
1059 |
collect:[:l | |
|
1060 |
|s name lang comment| |
|
1061 |
||
1062 |
s := l readStream. |
|
1063 |
"/ skip forward for two separators |
|
1064 |
[ |
|
1065 |
[s next isLetterOrDigit] whileTrue:[]. |
|
1066 |
s peek isLetterOrDigit |
|
1067 |
] whileTrue. |
|
1068 |
name := l copyFrom:1 to:s position - 1. |
|
1069 |
s skipSeparators. |
|
1070 |
lang := s upToSeparator. |
|
1071 |
s skipSeparators. |
|
1072 |
s next == $# ifTrue:[ |
|
1073 |
s skipSeparators. |
|
1074 |
comment := s upToEnd utf8Decoded. |
|
1075 |
]. |
|
1076 |
{ name . lang . comment } |
|
1077 |
] |
|
22962 | 1078 |
|
1079 |
" |
|
22966 | 1080 |
OperatingSystem voiceInfo |
22962 | 1081 |
" |
23314 | 1082 |
! |
1083 |
||
1084 |
voiceMapping |
|
1085 |
"return a mapping from common (OS-independent) voice names |
|
1086 |
to OS-specific names or IDs. |
|
1087 |
The speak:voiceName interface will recognize both. |
|
1088 |
For portable programs, always use the OS-independent name and |
|
1089 |
let every OS xlate to its internal name." |
|
1090 |
||
1091 |
|info map v| |
|
1092 |
||
1093 |
VoiceMapping notNil ifTrue:[^ VoiceMapping]. |
|
1094 |
||
1095 |
info := self voiceInfo. |
|
1096 |
map := OrderedCollection new. |
|
1097 |
v := info detect:[:entry | #('Tom' 'Alex' 'Fred' 'Bruce' 'Ralph' 'Daniel') includes:entry first] ifNone:nil. |
|
1098 |
map add:( 'male' -> (v ? #(nil)) first ). |
|
1099 |
v := info detect:[:entry | #('Samantha' 'Fiona' 'Karen' 'Moira') includes:entry first] ifNone:nil. |
|
1100 |
map add:( 'female' -> (v ? #(nil)) first ). |
|
1101 |
v := info detect:[:entry | #('Zarvox') includes:entry first] ifNone:nil. |
|
1102 |
map add:( 'computer' -> (v ? #(nil)) first ). |
|
1103 |
map add:( 'default' -> nil ). |
|
1104 |
VoiceMapping := map. |
|
1105 |
^ VoiceMapping |
|
24047 | 1106 |
|
23314 | 1107 |
"on OSX, this could be: |
24047 | 1108 |
^ { |
1109 |
'male' -> 'Alex' . |
|
1110 |
'female' -> 'Fiona' . |
|
1111 |
'computer' -> 'Zarvox' . |
|
1112 |
'default' -> 'Fiona' |
|
1113 |
} |
|
23314 | 1114 |
" |
1115 |
||
1116 |
" |
|
1117 |
OperatingSystem voiceMapping |
|
1118 |
" |
|
1119 |
||
1120 |
"Created: / 29-08-2018 / 09:55:00 / Claus Gittinger" |
|
22962 | 1121 |
! ! |
1122 |
||
22833 | 1123 |
!OSXOperatingSystem class methodsFor:'time and date'! |
1124 |
||
1125 |
getOSTimeWithNanos |
|
1126 |
"This returns the OS time as a 2-element vector with milliseconds (as before) |
|
1127 |
plus nanoseconds. |
|
1128 |
The base of the returned value is not consistent across |
|
1129 |
different OS's - some return the number of nanoseconds since jan, 1st 1970; |
|
1130 |
others since 1900. The Time classes are prepared for this, and |
|
1131 |
convert as appropriate (by using my fromOSTime: conversion methods). |
|
1132 |
||
1133 |
Don't use this method in application code since it is an internal (private) |
|
1134 |
interface. For compatibility use instances of Time, Date or Timestamp to work with." |
|
1135 |
||
1136 |
|seconds millis nanos| |
|
1137 |
%{ |
|
24047 | 1138 |
// all of the experiments below only provide 1us resolution on my machine |
1139 |
// Not sure if that has to do with the OSX version (high sierra) |
|
22833 | 1140 |
// therefore, it is disabled, and we fall back to the inherited method, |
1141 |
// which returns microsecond resolution nanos anyway. |
|
1142 |
#if 0 |
|
1143 |
unsigned long _secs, _millis, _nanos; |
|
1144 |
||
1145 |
# if defined(CLOCK_REALTIME) && !defined(NO_CLOCK_GETTIME) |
|
1146 |
struct timespec ts; |
|
1147 |
static int has_clock_gettime = 1; |
|
1148 |
unsigned long _secs, _millis, _nanos; |
|
1149 |
||
1150 |
if (has_clock_gettime) { |
|
1151 |
if (clock_gettime(CLOCK_REALTIME, &ts) != -1) { |
|
1152 |
_secs = ts.tv_sec; |
|
1153 |
_millis = ts.tv_nsec / 1000000; |
|
1154 |
_nanos = ts.tv_nsec % 1000000; |
|
1155 |
||
1156 |
seconds = __MKUINT(_secs); |
|
1157 |
millis = __MKUINT(_millis); |
|
1158 |
nanos = __MKUINT(_nanos); |
|
1159 |
} else { |
|
1160 |
/* |
|
1161 |
* clock_gettime is not implemented in the kernel |
|
1162 |
* fall through to alternative implementation |
|
1163 |
*/ |
|
1164 |
has_clock_gettime = 0; |
|
1165 |
} |
|
1166 |
} |
|
1167 |
# else |
|
1168 |
# if 0 |
|
1169 |
// althoug documented, my osx doesn't have it... |
|
1170 |
uint32_t secpart; |
|
1171 |
uint32_t nsecpart; |
|
1172 |
||
1173 |
clock_get_calendar_nanotime(&secpart, &nsecpart); |
|
1174 |
||
1175 |
_secs = secpart; |
|
1176 |
_millis = nsecpart / 1000000; |
|
1177 |
_nanos = nsecpart % 1000000; |
|
1178 |
# else |
|
1179 |
// OS X does not have clock_gettime, use host_get_clock_service |
|
1180 |
clock_serv_t cclock; |
|
1181 |
mach_timespec_t mts; |
|
1182 |
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); |
|
1183 |
clock_get_time(cclock, &mts); |
|
1184 |
mach_port_deallocate(mach_task_self(), cclock); |
|
1185 |
||
1186 |
_secs = mts.tv_sec; |
|
1187 |
_millis = mts.tv_nsec / 1000000; |
|
1188 |
_nanos = mts.tv_nsec % 1000000; |
|
1189 |
# endif |
|
1190 |
||
1191 |
seconds = __MKUINT(_secs); |
|
1192 |
millis = __MKUINT(_millis); |
|
1193 |
nanos = __MKUINT(_nanos); |
|
1194 |
# endif |
|
1195 |
#endif |
|
1196 |
%}. |
|
1197 |
seconds notNil ifTrue:[ |
|
1198 |
^ { ((seconds * 1000) + millis) . nanos } |
|
1199 |
]. |
|
1200 |
||
1201 |
^ super getOSTimeWithNanos. |
|
1202 |
! ! |
|
1203 |
||
14819 | 1204 |
!OSXOperatingSystem class methodsFor:'documentation'! |
1205 |
||
1206 |
version |
|
19817 | 1207 |
^ '$Header$' |
14819 | 1208 |
! |
1209 |
||
1210 |
version_CVS |
|
19817 | 1211 |
^ '$Header$' |
14819 | 1212 |
! ! |
25307 | 1213 |