Skip to content

Instantly share code, notes, and snippets.

@evanmiller
Created February 15, 2014 18:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanmiller/9022903 to your computer and use it in GitHub Desktop.
Save evanmiller/9022903 to your computer and use it in GitHub Desktop.
{
"metadata": {
"language": "Julia",
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"C interface. Note the path convention"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"foo = ccall((:CGImageSourceCopyTypeIdentifiers, \"ImageIO.framework/ImageIO\"), \n",
" Ptr{Void}, ())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"Ptr{Void} @0x00007ff531162560"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ccall(:CFShow, Ptr{Void}, (Ptr{Void}, ), foo)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
"Ptr{Void} @0x0000000000000000"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"(\n",
" \"public.jpeg\",\n",
" \"public.png\",\n",
" \"com.compuserve.gif\",\n",
" \"public.jpeg-2000\",\n",
" \"com.canon.tif-raw-image\",\n",
" \"com.adobe.raw-image\",\n",
" \"com.canon.cr2-raw-image\",\n",
" \"com.leafamerica.raw-image\",\n",
" \"com.hasselblad.fff-raw-image\",\n",
" \"com.hasselblad.3fr-raw-image\",\n",
" \"com.nikon.raw-image\",\n",
" \"com.nikon.nrw-raw-image\",\n",
" \"com.pentax.raw-image\",\n",
" \"com.samsung.raw-image\",\n",
" \"com.sony.raw-image\",\n",
" \"com.sony.sr2-raw-image\",\n",
" \"com.sony.arw-raw-image\",\n",
" \"com.epson.raw-image\",\n",
" \"com.kodak.raw-image\",\n",
" \"public.tiff\",\n",
" \"com.apple.icns\",\n",
" \"com.canon.crw-raw-image\",\n",
" \"com.fuji.raw-image\",\n",
" \"com.panasonic.raw-image\",\n",
" \"com.panasonic.rw2-raw-image\",\n",
" \"com.leica.raw-image\",\n",
" \"com.leica.rwl-raw-image\",\n",
" \"com.konicaminolta.raw-image\",\n",
" \"com.olympus.sr-raw-image\",\n",
" \"com.olympus.or-raw-image\",\n",
" \"com.olympus.raw-image\",\n",
" \"com.adobe.photoshop-image\",\n",
" \"com.microsoft.ico\",\n",
" \"com.microsoft.bmp\",\n",
" \"public.xbitmap-image\",\n",
" \"com.microsoft.cur\",\n",
" \"com.truevision.tga-image\",\n",
" \"com.sgi.sgi-image\",\n",
" \"com.apple.macpaint-image\",\n",
" \"com.ilm.openexr-image\",\n",
" \"public.radiance\",\n",
" \"public.mpo-image\",\n",
" \"com.apple.pict\",\n",
" \"com.apple.quicktime-image\",\n",
" \"com.kodak.flashpix-image\"\n",
")\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Playing with selectors:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"foo = ccall(:sel_getUid, Ptr{Void}, (Ptr{Uint8}, ), \"setTitle:\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 6,
"text": [
"Ptr{Void} @0x00007fff8d34e41d"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"bar = ccall(:sel_getName, Ptr{Uint8}, (Ptr{Void}, ), foo)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 7,
"text": [
"Ptr{Uint8} @0x00007fff8d34e41d"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"bytestring(bar)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 8,
"text": [
"\"setTitle:\""
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some function calls are tricky. Quoting from:\n",
"https://code.google.com/p/jscocoa/wiki/BridgeSupport\n",
"\n",
"**dylib**\n",
"Some frameworks may carry a dynamic library (.dylib), storing callable versions of inline functions. NSMakePoint, NSMakeRect and others are functions inlined at compile time \u2014 they have no address that dlsym can resolve. The dylib 'un-inlines' these functions, creating a runtime callable equivalent of an inline function.\n",
"\n",
"It seems like the full path is needed in ccall for these. See the NSLog functions, below, for an example.\n",
"\n",
"## Handy functions here:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Objective-C message send\n",
"# Only handles single selectors with no arguments for the moment\n",
"# Default return type is an opaque pointer, can be changed with third argument\n",
"oms{T}(id, uid, ::Type{T}=Ptr{Void}) = ccall(:objc_msgSend, T, (Ptr{Void}, Ptr{Void}), \n",
" id, selector(uid))\n",
"# Objective-c get class\n",
"# Default return type is an opaque pointer, can be changed with second argument\n",
"ogc{T}(id, ::Type{T}=Ptr{Void}) = ccall((:objc_getClass, \"Cocoa.framework/Cocoa\"), \n",
" Ptr{Void}, (Ptr{Uint8},), id)\n",
"# Objective-C selector\n",
"selector(sel::String) = ccall(:sel_getUid, Ptr{Void}, (Ptr{Uint8}, ), sel)\n",
"\n",
"\n",
"NSString(init::String) = ccall(:objc_msgSend, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Ptr{Uint8}, Uint64),\n",
" oms(ogc(\"NSString\"), \"alloc\"), \n",
" selector(\"initWithCString:encoding:\"), init, 1)\n",
"\n",
"NSLog(str::String, obj) = ccall((:NSLog, \"/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation\"), \n",
" Void, (Ptr{Void}, Ptr{Void}), NSString(str), obj)\n",
"NSLog(str::String) = ccall((:NSLog, \"/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation\"), \n",
" Void, (Ptr{Void}, ), NSString(str))\n",
"NSLog(obj::Ptr) = ccall((:NSLog, \"/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation\"), \n",
" Void, (Ptr{Void}, ), obj)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"text": [
"NSLog (generic function with 3 methods)"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Try to pop up a window:\n",
"Mimic this:\n",
"```\n",
"id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200)\n",
" styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]\n",
" autorelease];\n",
"[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];\n",
"[window setTitle:appName];\n",
"[window makeKeyAndOrderFront:nil];\n",
"```\n",
"\n",
"First, some types to mirror the Apple structures:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"immutable NSPoint\n",
" x::Cdouble\n",
" y::Cdouble\n",
"end\n",
"\n",
"immutable NSSize\n",
" w::Cdouble\n",
" h::Cdouble\n",
"end\n",
"\n",
"immutable NSRect\n",
" point::NSPoint\n",
" sz::NSSize\n",
"end\n",
"string(r::NSRect) = \"{$(r.point.x), $(r.point.y)}, {$(r.sz.w), $(r.sz.h)}\"\n",
"#NSPoint(x, y) = NSPoint(convert(Cdouble, x), convert(Cdouble, y))\n",
"#NSSize(w, h) = NSSize(convert(Cdouble, w), convert(Cdouble, h))\n",
"#NSRect(x, y, w, h) = NSRect(NSPoint(convert(Cdouble, x), convert(Cdouble, y)), NSSize(convert(Cdouble, w), convert(Cdouble, h)))\n",
"NSRect(x, y, w, h) = NSRect(NSPoint(x, y), NSSize(w, h))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 10,
"text": [
"NSRect (constructor with 2 methods)"
]
}
],
"prompt_number": 10
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200)\n",
" styleMask:NSTitledWindowMask \n",
" backing:NSBackingStoreBuffered defer:NO] autorelease];"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"msg = selector(\"initWithContentRect:styleMask:backing:defer:\")\n",
"rect_ptr = ccall((:NSMakeRect, \"/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation\"), \n",
"Ptr{NSRect}, (Cdouble, Cdouble, Cdouble, Cdouble), 0, 0, 200, 200)\n",
"@show my_rect = unsafe_load(rect_ptr)\n",
"#value = ccall(:objc_msgSend, Ptr{Void}, (Ptr{Void}, Ptr{Void}, NSRect), ogc(\"NSValue\"), selector(\"valueWithRect:\"), my_rect)\n",
"#NSLog(\"Value: %@\", value)\n",
"stylemask = 1 << 0 | 1 << 1 | 1 << 3\n",
"\n",
"window = ccall(:objc_msgSend, Ptr{Void}, (Ptr{Void}, Ptr{Void}, NSRect, Uint64, Uint64, Int),\n",
"oms(ogc(\"NSWindow\"), \"alloc\"), msg, my_rect, stylemask, 2, true)\n",
"\n",
"window = ccall(:objc_msgSend, Ptr{Void}, (Ptr{Void}, Ptr{Void}, NSRect, Uint64, Uint64, Int),\n",
"oms(ogc(\"NSWindow\"), \"alloc\"), msg, NSRect(0, 0, 200, 200), stylemask, 2, true)\n",
"\n",
"oms(window, \"autorelease\", Void)\n",
"NSLog(\"Window: %@\", window)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"my_rect = unsafe_load(rect_ptr) => NSRect(NSPoint(0.0,0.0),NSSize(200.0,200.0))"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"2014-02-13 10:30:46.536 julia-basic[72725:507] Window: <NSWindow: 0x7ff5311d9b60>\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"#[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];\n",
"[window center];"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"msg = selector(\"cascadeTopLeftFromPoint:\")\n",
"##@show pt_ptr = ccall((:NSMakePoint, \"/System/Library/Frameworks/Foundation.framework/Resources/BridgeSupport/Foundation\"), \n",
"##Ptr{NSPoint}, (Cdouble, Cdouble), 20, 20)\n",
"##@show foo = unsafe_load(pt_ptr)\n",
"ccall(:objc_msgSend, Void, (Ptr{Void}, Ptr{Void}, NSPoint), window, msg, NSPoint(30, 30))\n",
"#oms(window, \"center\", Void)\n",
"NSLog(\"Window: %@\", window)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stderr",
"text": [
"2014-02-13 10:30:51.277 julia-basic[72725:507] Window: <NSWindow: 0x7ff5311d9b60>\n"
]
}
],
"prompt_number": 12
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"[window setTitle:appName];"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"msg = selector(\"setTitle:\")\n",
"ccall(:objc_msgSend, Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), window, msg, NSString(\"Foo\"))\n",
"NSLog(\"Window: %@\", window)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stderr",
"text": [
"2014-02-13 10:30:53.769 julia-basic[72725:507] Window: <NSWindow: 0x7ff5311d9b60>\n"
]
}
],
"prompt_number": 13
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"#[window makeKeyAndOrderFront:nil];\n",
"[window makeKeyWindow];"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#msg = selector(\"makeKeyAndOrderFront:\")\n",
"#ccall(:objc_msgSend, Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), window, msg, C_NULL)\n",
"oms(window, \"makeKeyWindow\", Void)\n",
"# ---does nothing"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"How about this instead?\n",
"[NSApp runModalForWindow: myWindow];"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#ccall(:objc_msgSend, Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), ogc(\"NSApp\"), selector(\"runModalForWindow:\"), window)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Query my window properties"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"@show oms(window, \"maxSize\", NSSize)\n",
"@show oms(window, \"minSize\", NSSize)\n",
"@show oms(window, \"occlusionState\", Uint64) # huh? \n",
"@show oms(window, \"preferredBackingLocation\", Uint64)\n",
"@show oms(window, \"preservesContentDuringLiveResize\", Bool)\n",
"@show oms(window, \"screen\", Uint64)\n",
"@show oms(window, \"frameOrigin\", NSPoint)\n",
"@show oms(window, \"frameTopLeftPoint\", NSPoint)\n",
"@show oms(window, \"level\", Uint64)\n",
"@show oms(window, \"isMovable\", Bool)\n",
"@show oms(window, \"isOpaque\", Bool)\n",
"@show oms(window, \"showsResizeIndicator\", Bool)\n",
"@show oms(window, \"showsToolbarButton\", Bool)\n",
"@show oms(window, \"styleMask\", Uint64) # important\n",
"@show oms(window, \"windowNumber\", Int) #?\n",
"@show oms(window, \"canBecomeKeyWindow\", Bool) #?\n",
"@show oms(window, \"frame\", NSRect) #?\n",
"#NSLog(oms(window, \"title\", Ptr{Void}))\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"oms(window,\"maxSize\",NSSize) => NSSize(3.4028234663852886e38,3.4028234663852886e38)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"oms(window,\"minSize\",NSSize) => NSSize(0.0,22.0)\n",
"oms(window,\"occlusionState\",Uint64) => 0x0000000000002000\n",
"oms(window,\"preferredBackingLocation\",Uint64) => 0x0000000000000000\n",
"oms(window,\"preservesContentDuringLiveResize\",Bool) => true\n",
"oms(window,\"screen\",Uint64) => 0x0000000000000000\n",
"oms(window,\"frameOrigin\",NSPoint) => NSPoint(30.0,8.0)\n",
"oms(window,\"frameTopLeftPoint\",NSPoint) => NSPoint(30.0,30.0)\n",
"oms(window,\"level\",Uint64) => 0x0000000000000000\n",
"oms(window,\"isMovable\",Bool) => true\n",
"oms(window,\"isOpaque\",Bool) => true\n",
"oms(window,\"showsResizeIndicator\",Bool) => false\n",
"oms(window,\"showsToolbarButton\",Bool) => false\n",
"oms(window,\"styleMask\",Uint64) => 0x000000000000000b\n",
"oms(window,\"windowNumber\",Int) => -1\n",
"oms(window,\"canBecomeKeyWindow\",Bool) => true\n",
"oms(window,\"frame\",NSRect) => NSRect(NSPoint(1.390671161566996e-309,5.432309224866e-312),NSSize(NaN,NaN))\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"text": [
"NSRect(NSPoint(1.390671161566996e-309,5.432309224866e-312),NSSize(NaN,NaN))"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment