Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hacking Mac OS X Cocoa API from Perl

typester
November 18, 2011

Hacking Mac OS X Cocoa API from Perl

YAPC::Asia 2011 Tokyo

typester

November 18, 2011
Tweet

More Decks by typester

Other Decks in Programming

Transcript

  1. "CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL w 3FFOHP

    'BDFCPPLJOUFHSBUFE7P*1BQQMJDBUJPOGPSJ04 w 72$IFDLFS 7PJDF2VPUJFOUBOBMZ[FSGPS1$BOEJ04
  2. "CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL w 3FFOHP

    'BDFCPPLJOUFHSBUFE7P*1BQQMJDBUJPOGPSJ04 w 72$IFDLFS 7PJDF2VPUJFOUBOBMZ[FSGPS1$BOEJ04 w 0OFNPSFUIJOH 8JMMCFSFMFBTFECFGPSFUIJTYNBT
  3. 0CKFDUJWF$ • #import <Foundation/Foundation.h> int main(int argc, char** argv) {

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // Objective-C code here NSLog(@”Hello World!”); [pool drain]; return 0; }
  4. 'PPD • #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h"

    XS(func) { dXSARGS; // code here XSRETURN(0); } XS(boot_Foo) { newXS("Foo::xs_function", func, __FILE__); }
  5. .BLFpMF1-GPS'PPD • use inc::Module::Install; # some basic descriptions here use_ppport

    '3.19'; WriteAll; w .PEVMF*OTUBMM946UJM w 4FFBMTP%BUB.FTTBHF1BDL %BUB".'94 UIBUJTVTJOH UIJTQTFVEP94UFDIOJRVF
  6. .BLFpMF1-GPS'PPN w VTFJOD.PEVMF*OTUBMM TPNFCBTJDEFTDSJQUJPOTIFSF VTF@QQQPSU DD@BQQFOE@UP@MJCTMPCKD NBLFNBLFS@BSHT\EZOBNJD@MJC^\ 05)&3-%'-"(4GSBNFXPSL'PVOEBUJPO ^ \

    IUUQXXXNBJMBSDIJWFDPNNBLFNBLFS!QFSMPSHNTHIUNM "EETPNFSFRVJSFENBDIJOFSZUPTVQQPSUNpMFT QBDLBHF.: TVCD@P\ NZJOIFSJUFETIJGU461&3D@P !@  JOIFSJUFE&0.&44 N 0#+@&95    $$$.%  $$$%-'-"(4 * 1&3-@*/$  1"45)36@%&'*/&  %&'*/&  N &0.&44 JOIFSJUFE ^ TVCYT@D\ NZJOIFSJUFETIJGU461&3YT@D !@  JOIFSJUFE&0.&44 YTN   946#1136/  9413050"3(  946#11"3(4  946#11@&953"@"3(4  YT YTN .7  YTN N &0.&44 JOIFSJUFE ^ TVCJOJU@EJSTDBO\ NZTFMGTIJGU TFMG461&3JOJU@EJSTDBO  GPSFBDINZOBNF TFMGMTEJS TFMGDVSEJS \
  7. )FMMPN • #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h"

    // undefine Move macro, this is conflict to Mac OS X QuickDraw API. #undef Move #import <Foundation/Foundation.h> XS(hello) { dXSARGS; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Hello!"); [pool drain]; XSRETURN(0); } XS(boot_Hello) { newXS("Hello::hello", hello, __FILE__); }
  8. $PQJFTBOEQBTUFTGPS94 • XS(function) { dXSARGS; SV* sv_args1 = ST(0); SV*

    sv_args2 = ST(1); // code here ST(0) = some_sv; ST(1) = some_sv2; XSRETURN(2); }
  9. $PQJFTBOEQBTUFTGPS94 • XS(function) { dXSARGS; if (items < 2) {

    Perl_croak(aTHX_ "Usage: function($args1, $args2)"); } SV* sv_args1 = ST(0); SV* sv_args2 = ST(1); // code here ST(0) = some_sv; ST(1) = some_sv2; XSRETURN(2); }
  10. GPS0CKFDUJWF$BOE1FSM w 1FSMTUSJOHUP/44USJOH STRLEN len; char* c = SvPV(sv, len);

    NSString* str = [NSString stringWithUTF8String:c]; w /44USJOHUP1FSMTUSJOH SV* sv = sv_2mortal(newSV(0)); sv_setpv(sv, [str UTF8String]);
  11. GPS0CKFDUJWF$BOE1FSM w 1FSMOVNCFSUP/4/VNCFS NSNumber* n; if (SvNOKp(sv)) { n =

    [NSNumber numberWithDouble:(double)SvNVX(sv))]; } else if (SvIOK_UV(sv)) { n = [NSNumber numberWithDouble:(double)SvUV(sv))]; } else if (SvIOKp(sv)) { n = [NSNumber numberWithDouble:(double)SvIV(sv))]; } w /4/VNCFSUP1FSMOVNCFS SV* sv = sv_2mortal(newSVnv([n doubleValue]));
  12. $PDPB(SPXM • use Cocoa::Growl ':all'; # register application growl_register( app

    => 'My growl script', icon => '/path/to/icon.png', # or 'http://urlto/icon' notifications => [qw(Notification1 Notification2)], );
  13. $PDPB(SPXM •use Cocoa::Growl ':all'; # show growl notification growl_notify( name

    => 'Notification1', title => 'Hello!', description => 'Growl world!', );
  14. $PDPB(SPXM • use Cocoa::EventLoop; use Cocoa::Growl ':all'; growl_register( name =>

    'test script', notifications => ['test notification'], ); my $wait = 1; growl_notify( name => 'test notification', title => 'Hello', description => 'Growl World!', on_click => sub { warn 'click'; $wait = 0; }, on_timeout => sub { warn 'timeout'; $want = 0; }, ); Cocoa::EventLoop->run_while(0.1) while unless $wait;
  15. "OZ&WFOU*NQM$PDPB • use AnyEvent; use Cocoa::EventLoop; use Cocoa::Growl; my $cv

    = AE::cv; growl_notify( name => 'test notification', title => 'Hello', description => 'Growl World!', on_click => sub { warn ‘click’; $cv->send; }, on_timeout => sub { warn ‘timeout’; $cv->send; }, ); $cv->recv;