! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: assocs kernel math namespaces sequences system
-kernel.private tuples bit-arrays byte-arrays float-arrays ;
+kernel.private tuples bit-arrays byte-arrays float-arrays
+shuffle arrays macros ;
IN: alien
! Some predicate classes used by the compiler for optimization
USING: arrays bunny.model bunny.cel-shaded
-combinators.lib continuations kernel math multiline
+combinators.cleave continuations kernel math multiline
opengl opengl.shaders opengl.framebuffers opengl.gl
opengl.capabilities sequences ui.gadgets combinators.cleave ;
IN: bunny.outlined
[ 2drop ] append ;
MACRO: map-call-with2 ( quots -- )
- [ (make-call-with2) ] keep length [ narray ] curry append ;
+ [
+ [ [ 2dup >r >r ] swap append [ r> r> ] append ] map concat
+ [ 2drop ] append
+ ] keep length [ narray ] curry append ;
MACRO: map-exec-with ( words -- )
[ 1quotation ] map [ map-call-with ] curry ;
: and? ( obj quot1 quot2 -- ? )
>r keep r> rot [ call ] [ 2drop f ] if ; inline
+MACRO: multikeep ( word out-indexes -- ... )
+ [
+ dup >r [ \ npick \ >r 3array % ] each
+ %
+ r> [ drop \ r> , ] each
+ ] [ ] make ;
+
: retry ( quot n -- )
[ drop ] rot compose attempt-all ; inline
IN: opengl.gl.macosx
: gl-function-context ( -- context ) 0 ; inline
-: gl-function-address ( name -- address ) "gl" load-library dlsym ; inline
+: gl-function-address ( name -- address ) f dlsym ; inline
: gl-function-calling-convention ( -- str ) "cdecl" ; inline
! See http://factorcode.org/license.txt for BSD license.
USING: kernel opengl.gl alien.c-types continuations namespaces
assocs alien libc opengl math sequences combinators.lib
-macros arrays combinators.cleave ;
+combinators.cleave macros arrays ;
IN: opengl.shaders
: with-gl-shader-source-ptr ( string quot -- )
GL_ATTACHED_SHADERS gl-program-get-int ; inline
: gl-program-shaders ( program -- shaders )
- dup gl-program-shaders-length [
- dup "GLuint" <c-array>
- [ 0 <int> swap glGetAttachedShaders ] keep
- ] keep c-uint-array> ;
+ dup gl-program-shaders-length
+ dup "GLuint" <c-array>
+ 0 <int> swap
+ [ glGetAttachedShaders ] { 3 1 } multikeep
+ c-uint-array> ;
: delete-gl-program-only ( program -- )
glDeleteProgram ; inline
! { "gl" "libGLES_CM.dll" "stdcall" }
! { "glu" "libGLES_CM.dll" "stdcall" }
! { "freetype" "libfreetype-6.dll" "stdcall" }
+ { "ole32" "ole32.dll" "stdcall" }
} [ first3 add-library ] each
--- /dev/null
+USING: kernel windows.com windows.com.syntax windows.ole32\r
+alien alien.syntax tools.test libc ;\r
+IN: windows.com.tests\r
+\r
+! Create some test COM interfaces\r
+\r
+COM-INTERFACE: ISimple IUnknown {216fb341-0eb2-44b1-8edb-60b76e353abc}\r
+ HRESULT returnOK ( )\r
+ HRESULT returnError ( ) ;\r
+\r
+COM-INTERFACE: IInherited ISimple {9620ecec-8438-423b-bb14-86f835aa40dd}\r
+ int getX ( ) ;\r
+ void setX ( int newX ) ;\r
+\r
+! Implement the IInherited interface in factor using alien-callbacks\r
+\r
+: QueryInterface-callback\r
+ "HRESULT" { "void*" "REFGUID" "void**" } "stdcall" [ nip 0 -rot set-void*-nth ]\r
+ alien-callback ;\r
+: AddRef-callback\r
+ "ULONG" { "void*" } "stdcall" [ drop 2 ]\r
+ alien-callback ;\r
+: Release-callback\r
+ "ULONG" { "void*" } "stdcall" [ drop 1 ]\r
+ alien-callback ;\r
+: returnOK-callback\r
+ "HRESULT"{ "void*" } "stdcall" [ drop S_OK ]\r
+ alien-callback ;\r
+: returnError-callback\r
+ "HRESULT"{ "void*" } "stdcall" [ drop E_FAIL ]\r
+ alien-callback ;\r
+: getX-callback\r
+ "int" { "void*" } "stdcall" [ test-interface-x ]\r
+ alien-callback ;\r
+: setX-callback\r
+ "void" { "void*" "int" } "stdcall" [ swap set-test-interface-x ]\r
+ alien-callback ;\r
+\r
+SYMBOL: +test-implementation-vtbl+\r
+{\r
+ QueryInterface-callback\r
+ AddRef-callback\r
+ Release-callback\r
+ returnOK-callback\r
+ returnError-callback\r
+ getX-callback\r
+ setX-callback\r
+} [ execute ] map >c-void*-array\r
++test-implementation-vtbl+ set\r
+\r
+C-STRUCT: test-implementation\r
+ { "void*" "vtbl" }\r
+ { "int" "x" } ;\r
+\r
+: (make-test-implementation) ( x imp -- imp )\r
+ [ set-test-implementation-x ] keep\r
+ +test-implementation-vtbl+ get over set-test-implementation-vtbl ;\r
+\r
+: <test-implementation> ( x -- imp )\r
+ "test-implementation" <c-object> (make-test-implementation) ;\r
+\r
+! Test that the words defined by COM-INTERFACE: do their magic\r
+\r
+"{216fb341-0eb2-44b1-8edb-60b76e353abc}" string>guid 1array [ ISimple-iid ] unit-test\r
+"{9620ecec-8438-423b-bb14-86f835aa40dd}" string>guid 1array [ IInherited-iid ] unit-test\r
+"{00000000-0000-0000-C000-000000000046}" string>guid 1array [ IUnknown-iid ] unit-test\r
+S_OK 1array [ 0 <test-implementation> ISimple::returnOK ] unit-test\r
+E_FAIL 1array [ 0 <test-implementation> ISimple::returnError ] unit-test\r
+1984 1array [ 0 <test-implementation> dup 1984 IInherited::setX IInherited::getX ] unit-test\r
+\r
+! Test that the helper functions for QueryInterface, AddRef, Release work\r
+\r
+: <malloced-test-implementation> ( x -- imp )\r
+ "test-implementation" heap-size malloc (make-test-implementation) ;\r
+\r
+SYMBOL: +guinea-pig-implementation+\r
+\r
+0 <malloced-test-implementation> +guinea-pig-implementation+ set\r
+[\r
+ +guinea-pig-implementation+ get 1array [\r
+ +guinea-pig-implementation+ get IUnknown-iid com-query-interface\r
+ ] unit-test\r
+\r
+ { } [ +guinea-pig-implementation+ get com-add-ref ] unit-test\r
+ { } [ +guinea-pig-implementation+ get com-release ] unit-test\r
+] [ +guinea-pig-implementation+ get free ] [ ] cleanup\r
+\r
--- /dev/null
+USING: alien alien.c-types windows.com.syntax windows.ole32\r
+windows.types continuations ;\r
+IN: windows.com\r
+\r
+COM-INTERFACE: IUnknown f {00000000-0000-0000-C000-000000000046}\r
+ HRESULT QueryInterface ( REFGUID iid, void** ppvObject )\r
+ ULONG AddRef ( )\r
+ ULONG Release ( ) ;\r
+\r
+: com-query-interface ( interface iid -- interface' )\r
+ f <void*> [ IUnknown::QueryInterface ] keep *void* ;\r
+\r
+: com-add-ref ( interface -- )\r
+ IUnknown::AddRef drop ; inline\r
+\r
+: com-release ( interface -- )\r
+ IUnknown::Release drop ; inline\r
--- /dev/null
+USING: alien alien.c-types kernel windows windows.ole32\r
+combinators.lib parser splitting sequences.lib ;\r
+IN: windows.com.syntax\r
+\r
+<PRIVATE\r
+\r
+: vtbl ( interface -- vtbl )\r
+ *void* ; inline\r
+: com-invoke ( ... interface n funcptr return parameters -- )\r
+ "stdcall" [\r
+ swap vtbl swap void*-nth\r
+ ] 4 ndip alien-indirect ;\r
+\r
+PRIVATE>\r
+\r
+: COM-INTERFACE:\r
+ scan\r
+ parse-inheritance\r
+ ";" parse-tokens { ")" } split\r
+ [ \r
+ ; parsing\r
+\r
{ "gl" "opengl32.dll" "stdcall" }
{ "glu" "glu32.dll" "stdcall" }
{ "freetype" "freetype6.dll" "cdecl" }
+ { "ole32" "ole32.dll" "stdcall" }
} [ first3 add-library ] each
--- /dev/null
+USING: alien alien.syntax alien.c-types math kernel sequences\r
+windows windows.types combinators.lib ;\r
+IN: windows.ole32\r
+\r
+LIBRARY: ole32\r
+\r
+C-STRUCT: GUID\r
+ { "DWORD" "part1" }\r
+ { "DWORD" "part2" }\r
+ { "DWORD" "part3" }\r
+ { "DWORD" "part4" } ;\r
+\r
+TYPEDEF: void* REFGUID\r
+TYPEDEF: void* LPUNKNOWN\r
+TYPEDEF: ushort* LPOLESTR\r
+\r
+FUNCTION: HRESULT CoCreateInstance ( REFGUID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFGUID riid, LPUNKNOWN out_ppv ) ;\r
+FUNCTION: BOOL IsEqualGUID ( REFGUID rguid1, REFGUID rguid2 ) ;\r
+FUNCTION: int StringFromGUID2 ( REFGUID rguid, LPOLESTR lpsz, int cchMax ) ;\r
+FUNCTION: HRESULT CLSIDFromString ( LPOLESTR lpsz, REFGUID out_rguid ) ;\r
+\r
+: S_OK 0 ; inline\r
+: S_FALSE 1 ; inline\r
+: E_FAIL HEX: 80004005 ; inline\r
+: E_INVALIDARG HEX: 80070057 ; inline\r
+\r
+: ole32-error ( n -- )\r
+ dup S_OK = [\r
+ drop\r
+ ] [ (win32-error-string) throw ] if ;\r
+\r
+: guid= ( a b -- ? )\r
+ IsEqualGUID c-bool> ;\r
+\r
+: GUID-STRING-LENGTH\r
+ "{01234567-89ab-cdef-0123-456789abcdef}" length ; inline\r
+\r
+: string>guid ( string -- guid )\r
+ string>u16-alien "GUID" <c-object> [ CLSIDFromString ole32-error ] keep ;\r
+: guid>string ( guid -- string )\r
+ GUID-STRING-LENGTH 1+ [ "ushort" <c-array> ] keep\r
+ [ StringFromGUID2 drop ] { 2 } multikeep alien>u16-string ;\r
+\r
USING: alien alien.c-types alien.syntax combinators
-kernel windows windows.user32 ;
+kernel windows windows.user32 windows.ole32 ;
IN: windows.shell32
: CSIDL_DESKTOP HEX: 00 ; inline
: CSIDL_FLAG_MASK HEX: ff00 ; inline
-: S_OK 0 ; inline
-: S_FALSE 1 ; inline
-: E_FAIL HEX: 80004005 ; inline
-: E_INVALIDARG HEX: 80070057 ; inline
: ERROR_FILE_NOT_FOUND 2 ; inline
: SHGFP_TYPE_CURRENT 0 ; inline
f "open" rot f f SW_SHOWNORMAL ShellExecute drop ;
: shell32-error ( n -- )
- dup S_OK = [
- drop
- ] [
- {
- ! { ERROR_FILE_NOT_FOUND [ "file not found" throw ] }
- ! { E_INVALIDARG [ "invalid arg" throw ] }
- [ (win32-error-string) throw ]
- } case
- ] if ;
+ ole32-error ; inline
: shell32-directory ( n -- str )
f swap f SHGFP_TYPE_DEFAULT