CGEventCreateKeyboardEvent just crashes?!?
-
Hi all,
anybody can use CGEventCreateKeyboardEvent?
I create the simplest project possible. Call the function exactly the
way it's documented. And always got a nice small SIGBUS...
Here's my source:
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
NSLog(@"Hello, Apple World! What's there with them blasted
events?!?");
CGEventRef er=CGEventCreateKeyboardEvent (NULL, (CGKeyCode)56,
true); // directly from docs
NSLog(@"actually, got event ref at %x. Bye.",er);
[pool release];
return 0;
}
Here's the project (I've tried plain C one, too): http://www.ocs.cz/
apps/CGEventCrash.zip
Will be very grateful for any advice what I do wrong...
---
Ondra ÄŒada
OCSoftware: <ocs...> http://www.ocs.cz
private <ondra...> http://www.ocs.cz/oc -
Hi Ondra,
I ran into this problem a while ago and never could figure out what
was wrong. If you don't need the CGEventRef back, trying using
CGPostKeyboardEvent() instead. It looks like this:
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)56, true);
-Phil
On Oct 4, 2006, at 1:56 PM, Ondra Cada wrote:
> Hi all,
>
> anybody can use CGEventCreateKeyboardEvent?
>
> I create the simplest project possible. Call the function exactly
> the way it's documented. And always got a nice small SIGBUS...
>
> Here's my source:
>
> int main (int argc, const char * argv[]) {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
> // insert code here...
> NSLog(@"Hello, Apple World! What's there with them blasted
> events?!?");
> CGEventRef er=CGEventCreateKeyboardEvent (NULL, (CGKeyCode)56,
> true); // directly from docs
> NSLog(@"actually, got event ref at %x. Bye.",er);
> [pool release];
> return 0;
> }
>
> Here's the project (I've tried plain C one, too): http://www.ocs.cz/
> apps/CGEventCrash.zip
>
> Will be very grateful for any advice what I do wrong...
> ---
> Ondra ÄŒada
> OCSoftware: <ocs...> http://www.ocs.cz
> private <ondra...> http://www.ocs.cz/oc
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<Cocoa-dev...>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/<dev...>
>
> This email sent to <dev...>
>
-
On Oct 4, 2006, at 4:56 AM, Ondra Cada wrote:
> Hi all,
>
> anybody can use CGEventCreateKeyboardEvent?
>
> I create the simplest project possible. Call the function exactly
> the way it's documented. And always got a nice small SIGBUS...
>
> Here's my source:
>
> int main (int argc, const char * argv[]) {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
> // insert code here...
> NSLog(@"Hello, Apple World! What's there with them blasted
> events?!?");
> CGEventRef er=CGEventCreateKeyboardEvent (NULL, (CGKeyCode)56,
> true); // directly from docs
> NSLog(@"actually, got event ref at %x. Bye.",er);
> [pool release];
> return 0;
> }
The problem is that CGEventCreateKeyboardEvent is supposed to use the
default event source if you pass NULL for the first param, but a bug
in the Tiger implementation caused it to not initialize the default
source soon enough and so it crashed when attempting to use it. This
has been fixed in Leopard. The recommended workaround is to call
CFRelease(CGEventCreate(NULL)) before calling the other APIs.
-eric -
Eric,
On 4.10.2006, at 16:37, Eric Schlegel wrote:
> The recommended workaround is to call CFRelease(CGEventCreate
> (NULL)) before calling the other APIs
thanks a lot.
Well... now it does not crash, but it does not seem to do anything
else, either. May I please ask for a bit more advice what am I
overlooking? I would think the following code should hide iTunes; it
does not though -- regardless the value of wait I try:
#import <Foundation/Foundation.h>
#import <unistd.h> // usleep
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
NSLog(@"Hello, Apple World! What's there with them blasted
events?!?");
CFRelease(CGEventCreate(NULL));
// find iTunes
ProcessSerialNumber serial;
serial.highLongOfPSN=0;
serial.lowLongOfPSN=kNoProcess;
ProcessInfoRec pinfo;
pinfo.processInfoLength=sizeof(ProcessInfoRec);
pinfo.processName=NULL;
pinfo.processAppSpec=NULL;
pinfo.processLocation=NULL;
BOOL ok=NO;
for (;;) {
if (GetNextProcess(&serial)!=noErr) break; // found nothing
if (GetProcessInformation(&serial,&pinfo)==noErr) // 'hook'
is iTunes
if ([(id)UTCreateStringForOSType(pinfo.processSignature)
isEqualToString:@"hook"]) {
ok=YES;
break;
}
}
if (ok) { // just hide it, for the moment
unsigned wait=100000;
NSLog(@"allright, sending...");
CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
(CGKeyCode)0x37, true)); // command
usleep(wait);
CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
(CGKeyCode)0x04, true)); // h
usleep(wait);
CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
(CGKeyCode)0x04, false));
usleep(wait);
CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
(CGKeyCode)0x37, false));
NSLog(@"sent all");
}
[pool release];
return 0;
}
Thanks a lot in advance,
---
Ondra ÄŒada
OCSoftware: <ocs...> http://www.ocs.cz
private <ondra...> http://www.ocs.cz/oc -
Ondra, there's a better way.
http://developer.apple.com/documentation/Carbon/Reference/
Process_Manager/Reference/reference.html#//apple_ref/c/func/
ShowHideProcess
On Oct 4, 2006, at 9:27 AM, Ondra Cada wrote:
> Eric,
>
> On 4.10.2006, at 16:37, Eric Schlegel wrote:
>
>> The recommended workaround is to call CFRelease(CGEventCreate
>> (NULL)) before calling the other APIs
>
> thanks a lot.
>
> Well... now it does not crash, but it does not seem to do anything
> else, either. May I please ask for a bit more advice what am I
> overlooking? I would think the following code should hide iTunes;
> it does not though -- regardless the value of wait I try:
>
> #import <Foundation/Foundation.h>
> #import <unistd.h> // usleep
>
> int main (int argc, const char * argv[]) {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
> // insert code here...
> NSLog(@"Hello, Apple World! What's there with them blasted
> events?!?");
> CFRelease(CGEventCreate(NULL));
> // find iTunes
> ProcessSerialNumber serial;
> serial.highLongOfPSN=0;
> serial.lowLongOfPSN=kNoProcess;
> ProcessInfoRec pinfo;
> pinfo.processInfoLength=sizeof(ProcessInfoRec);
> pinfo.processName=NULL;
> pinfo.processAppSpec=NULL;
> pinfo.processLocation=NULL;
> BOOL ok=NO;
> for (;;) {
> if (GetNextProcess(&serial)!=noErr) break; // found nothing
> if (GetProcessInformation(&serial,&pinfo)==noErr) // 'hook'
> is iTunes
> if ([(id)UTCreateStringForOSType
> (pinfo.processSignature) isEqualToString:@"hook"]) {
> ok=YES;
> break;
> }
> }
> if (ok) { // just hide it, for the moment
> unsigned wait=100000;
> NSLog(@"allright, sending...");
> CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
> (CGKeyCode)0x37, true)); // command
> usleep(wait);
> CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
> (CGKeyCode)0x04, true)); // h
> usleep(wait);
> CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
> (CGKeyCode)0x04, false));
> usleep(wait);
> CGEventPostToPSN(&serial,CGEventCreateKeyboardEvent (NULL,
> (CGKeyCode)0x37, false));
> NSLog(@"sent all");
> }
> [pool release];
> return 0;
> }
>
> Thanks a lot in advance,
> ---
> Ondra ÄŒada
> OCSoftware: <ocs...> http://www.ocs.cz
> private <ondra...> http://www.ocs.cz/oc
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Cocoa-dev mailing list (<Cocoa-dev...>)
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/jstiles%
> 40blizzard.com
>
> This email sent to <jstiles...>
-
John,
On 4.10.2006, at 18:50, John Stiles wrote:
> Ondra, there's a better way.
> http://developer.apple.com/documentation/Carbon/Reference/
> Process_Manager/Reference/reference.html#//apple_ref/c/func/
> ShowHideProcess
definitely, sorry I haven't made it clean: the Cmd-h is just the
simplest test I have been able to make up. The real goal is much more
comprehensive control of the application though :) -- generally I
need to send both keyboard and mouse events at will.
Which, alas, so far does not work at all, whatever I try :/
---
Ondra ÄŒada
OCSoftware: <ocs...> http://www.ocs.cz
private <ondra...> http://www.ocs.cz/oc -
On Oct 4, 2006, at 11:27 AM, Ondra Cada wrote:
> On 4.10.2006, at 16:37, Eric Schlegel wrote:
>
>> The recommended workaround is to call CFRelease(CGEventCreate
>> (NULL)) before calling the other APIs
>
> thanks a lot.
>
> Well... now it does not crash, but it does not seem to do anything
> else, either. May I please ask for a bit more advice what am I
> overlooking? I would think the following code should hide iTunes;
> it does not though -- regardless the value of wait I try:
I think that I was unable to get events created with the default
source to work, but had success when I created and used a private
source:
/* psn holds target's PSN, code is keycode to send, state is up/down */
CGEventSourceRef source = CGEventSourceCreate
(kCGEventSourceStatePrivate);
CGEventRef ev = CGEventCreateKeyboardEvent(source, code, state);
CGEventPostToPSN(&psn, ev);
-Greg



