M: string stack-size c-type stack-size ;
-M: c-type stack-size size>> ;
+M: c-type stack-size size>> cell align ;
GENERIC: byte-length ( seq -- n ) flushable
"double" define-primitive-type
"long" "ptrdiff_t" typedef
-
+ "long" "intptr_t" typedef
"ulong" "size_t" typedef
] with-compilation-unit
! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays generic hashtables kernel kernel.private
-math namespaces parser sequences strings words libc
+math namespaces parser sequences strings words libc fry
alien.c-types alien.structs.fields cpu.architecture ;
IN: alien.structs
-: if-value-structs? ( ctype true false -- )
- value-structs?
- [ drop call ] [ >r 2drop "void*" r> call ] if ; inline
-
TUPLE: struct-type size align fields ;
M: struct-type heap-size size>> ;
M: struct-type c-type-stack-align? drop f ;
-M: struct-type unbox-parameter
- [ %unbox-struct ] [ unbox-parameter ] if-value-structs? ;
+: if-value-struct ( ctype true false -- )
+ [ dup value-struct? ] 2dip '[ drop "void*" @ ] if ; inline
-M: struct-type unbox-return
- f swap %unbox-struct ;
+M: struct-type unbox-parameter
+ [ %unbox-large-struct ] [ unbox-parameter ] if-value-struct ;
M: struct-type box-parameter
- [ %box-struct ] [ box-parameter ] if-value-structs? ;
+ [ %box-large-struct ] [ box-parameter ] if-value-struct ;
+
+: if-small-struct ( c-type true false -- ? )
+ [ dup struct-small-enough? ] 2dip '[ f swap @ ] if ; inline
+
+M: struct-type unbox-return
+ [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ;
M: struct-type box-return
- f swap %box-struct ;
+ [ %box-small-struct ] [ %box-large-struct ] if-small-struct ;
M: struct-type stack-size
- [ heap-size ] [ stack-size ] if-value-structs? ;
+ [ heap-size ] [ stack-size ] if-value-struct ;
: c-struct? ( type -- ? ) (c-type) struct-type? ;
-rot define-c-type ;
: define-struct-early ( name vocab fields -- fields )
- -rot [ rot first2 <field-spec> ] 2curry map ;
+ [ first2 <field-spec> ] with with map ;
: compute-struct-align ( types -- n )
[ c-type-align ] map supremum ;
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: http.client checksums checksums.openssl splitting assocs
+USING: http.client checksums checksums.md5 splitting assocs
kernel io.files bootstrap.image sequences io urls ;
IN: bootstrap.image.download
: need-new-image? ( image -- ? )
dup exists?
[
- [ openssl-md5 checksum-file hex-string ]
+ [ md5 checksum-file hex-string ]
[ download-checksums at ]
bi = not
] [ drop t ] if ;
IN: command-line
HELP: run-bootstrap-init
-{ $description "Runs the " { $snippet ".factor-boot-rc" } " file in the user's home directory unless the " { $snippet "-no-user-init" } " command line switch was given." } ;
+{ $description "Runs the bootstrap initialization file in the user's home directory, unless the " { $snippet "-no-user-init" } " command line switch was given. This file is named " { $snippet ".factor-boot-rc" } " on Unix and " { $snippet "factor-boot-rc" } " on Windows." } ;
HELP: run-user-init
-{ $description "Runs the " { $snippet ".factor-rc" } " file in the user's home directory unless the " { $snippet "-no-user-init" } " command line switch was given." } ;
+{ $description "Runs the startup initialization file in the user's home directory, unless the " { $snippet "-no-user-init" } " command line switch was given. This file is named " { $snippet ".factor-rc" } " on Unix and " { $snippet "factor-rc" } " on Windows." } ;
HELP: cli-param
{ $values { "param" string } }
"A number of command line switches can be passed to a bootstrap image to modify the behavior of the resulting image:"
{ $table
{ { $snippet "-output-image=" { $emphasis "image" } } { "Save the result to " { $snippet "image" } ". The default is " { $snippet "factor.image" } "." } }
- { { $snippet "-no-user-init" } { "Inhibits the running of the " { $snippet ".factor-boot-rc" } " file in the user's home directory." } }
+ { { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } }
{ { $snippet "-include=" { $emphasis "components..." } } "A list of components to include (see below)." }
{ { $snippet "-exclude=" { $emphasis "components..." } } "A list of components to exclude." }
{ { $snippet "-ui-backend=" { $emphasis "backend" } } { "One of " { $snippet "x11" } ", " { $snippet "windows" } ", or " { $snippet "cocoa" } ". The default is platform-specific." } }
"By default, all optional components are loaded. To load all optional components except for a given list, use the " { $snippet "-exclude=" } " switch; to only load specified optional components, use the " { $snippet "-include=" } "."
$nl
"For example, to build an image with the compiler but no other components, you could do:"
-{ $code "./factor -i=boot.ppc.image -include=compiler" }
+{ $code "./factor -i=boot.macosx-ppc.image -include=compiler" }
"To build an image with everything except for the user interface and graphical tools,"
-{ $code "./factor -i=boot.ppc.image -exclude=\"ui ui.tools\"" }
+{ $code "./factor -i=boot.macosx-ppc.image -exclude=\"ui ui.tools\"" }
"To generate a bootstrap image in the first place, see " { $link "bootstrap.image" } "." ;
ARTICLE: "standard-cli-args" "Command line switches for general usage"
{ $table
{ { $snippet "-e=" { $emphasis "code" } } { "This specifies a code snippet to evaluate. If you want Factor to exit immediately after, also specify " { $snippet "-run=none" } "." } }
{ { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link POSTPONE: MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } ", " { $vocab-link "ui" } " or " { $vocab-link "none" } "." } }
- { { $snippet "-no-user-init" } { "Inhibits the running of the " { $snippet ".factor-rc" } " file in the user's home directory on startup." } }
+ { { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } }
{ { $snippet "-quiet" } { "If set, " { $link run-file } " and " { $link require } " will not print load messages." } }
{ { $snippet "-script" } { "Equivalent to " { $snippet "-quiet -run=none" } "." $nl "On Unix systems, Factor can be used for scripting - just create an executable text file whose first line is:" { $code "#! /usr/local/bin/factor -script" } "The space after " { $snippet "#!" } " is necessary because of Factor syntax." } }
} ;
+ARTICLE: "factor-boot-rc" "Bootstrap initialization file"
+"The botstrap initialization file is named " { $snippet "factor-boot-rc" } " on Windows and " { $snippet ".factor-boot-rc" } " on Unix. This file can contain " { $link require } " calls for vocabularies you use frequently, and other such long-running tasks that you do not want to perform every time Factor starts."
+$nl
+"A word to run this file from an existing Factor session:"
+{ $subsection run-bootstrap-init }
+"For example, if you changed " { $snippet ".factor-boot-rc" } " and do not want to bootstrap again, you can just invoke " { $link run-bootstrap-init } " in the listener." ;
+
+ARTICLE: "factor-rc" "Startup initialization file"
+"The startup initialization file is named " { $snippet "factor-rc" } " on Windows and " { $snippet ".factor-rc" } " on Unix. If it exists, it is run every time Factor starts."
+$nl
+"A word to run this file from an existing Factor session:"
+{ $subsection run-user-init } ;
+
ARTICLE: "rc-files" "Running code on startup"
-"Unless the " { $snippet "-no-user-init" } " command line switch is specified, The startup routine runs the " { $snippet ".factor-rc" } " file in the user's home directory, if it exists. This file can contain initialization and customization for your development environment."
+"Factor looks for two files in your home directory."
+{ $subsection "factor-boot-rc" }
+{ $subsection "factor-rc" }
+"The " { $snippet "-no-user-init" } " command line switch will inhibit the running of these files."
$nl
-"The " { $snippet ".factor-rc" } " and " { $snippet ".factor-boot-rc" } " files can be run explicitly:"
-{ $subsection run-user-init }
-{ $subsection run-bootstrap-init } ;
+"If you are unsure where the files should be located, evaluate the following code:"
+{ $code
+ "USE: command-line"
+ "\"factor-rc\" rc-path print"
+ "\"factor-boot-rc\" rc-path print"
+}
+"Here is an example " { $snippet ".factor-boot-rc" } " which sets up GVIM editor integration, adds an additional vocabulary root (see " { $link "vocabs.roots" } "), and increases the font size in the UI by setting the DPI (dots-per-inch) variable:"
+{ $code
+ "USING: editors.gvim vocabs.loader ui.freetype namespaces sequences ;"
+ "\"/opt/local/bin\" \\ gvim-path set-global"
+ "\"/home/jane/src/\" vocab-roots get push"
+ "100 dpi set-global"
+} ;
ARTICLE: "cli" "Command line usage"
"Zero or more command line arguments may be passed to the Factor runtime. Command line arguments starting with a dash (" { $snippet "-" } ") is interpreted as switches. All other arguments are taken to be file names to be run by " { $link run-file } "."
splitting io.files eval ;
IN: command-line
+: rc-path ( name -- path )
+ os windows? [ "." prepend ] unless
+ home prepend-path ;
+
: run-bootstrap-init ( -- )
"user-init" get [
- home ".factor-boot-rc" append-path ?run-file
+ "factor-boot-rc" rc-path ?run-file
] when ;
: run-user-init ( -- )
"user-init" get [
- home ".factor-rc" append-path ?run-file
+ "factor-rc" rc-path ?run-file
] when ;
: cli-var-param ( name value -- ) swap set-global ;
GENERIC: inc-reg-class ( register-class -- )
: ?dummy-stack-params ( reg-class -- )
- dummy-stack-params? [ reg-size stack-params +@ ] [ drop ] if ;
+ dummy-stack-params? [ reg-size cell align stack-params +@ ] [ drop ] if ;
: ?dummy-int-params ( reg-class -- )
dummy-int-params? [ reg-size cell /i 1 max int-regs +@ ] [ drop ] if ;
: spill-param ( reg-class -- n reg-class )
stack-params get
- >r reg-size stack-params +@ r>
+ >r reg-size cell align stack-params +@ r>
stack-params ;
: fastcall-param ( reg-class -- n reg-class )
{ $description "Enables the optimizing compiler." } ;
HELP: disable-compiler
-{ $description "Enables the optimizing compiler." } ;
+{ $description "Disable the optimizing compiler." } ;
ARTICLE: "compiler-usage" "Calling the optimizing compiler"
"Normally, new word definitions are recompiled automatically. This can be changed:"
! Make sure XT doesn't get clobbered in stack frame
-: ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a ptr -- result y )
- "void"
+: ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result y )
+ "int"
f "ffi_test_31"
{ "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" }
alien-invoke gc 3 ;
-[ 3 ] [ 42 [ ] each ffi_test_31 ] unit-test
+[ 861 3 ] [ 42 [ ] each ffi_test_31 ] unit-test
+
+: ffi_test_31_point_5 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result )
+ "float"
+ f "ffi_test_31_point_5"
+ { "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" }
+ alien-invoke ;
+
+[ 861.0 ] [ 42 [ >float ] each ffi_test_31_point_5 ] unit-test
FUNCTION: longlong ffi_test_21 long x long y ;
if ;
: (build-tree-from-word) ( word -- )
- dup
- [ "inline" word-prop ]
- [ "recursive" word-prop ] bi and [
- 1quotation f initial-recursive-state infer-quot
- ] [
- [ specialized-def ] [ initial-recursive-state ] bi
- infer-quot
- ] if ;
+ dup initial-recursive-state recursive-state set
+ dup [ "inline" word-prop ] [ "recursive" word-prop ] bi and
+ [ 1quotation ] [ specialized-def ] if
+ infer-quot-here ;
: check-cannot-infer ( word -- )
dup "cannot-infer" word-prop [ cannot-infer-effect ] [ drop ] if ;
HOOK: small-enough? cpu ( n -- ? )
! Is this structure small enough to be returned in registers?
-HOOK: struct-small-enough? cpu ( heap-size -- ? )
+HOOK: struct-small-enough? cpu ( c-type -- ? )
-! Do we pass value structs by value or hidden reference?
-HOOK: value-structs? cpu ( -- ? )
+! Do we pass this struct by value or hidden reference?
+HOOK: value-struct? cpu ( c-type -- ? )
! If t, all parameters are shadowed by dummy stack parameters
HOOK: dummy-stack-params? cpu ( -- ? )
M: stack-params param-reg drop ;
M: stack-params param-regs drop f ;
-
-: if-small-struct ( n size true false -- ? )
- [ 2dup [ not ] [ struct-small-enough? ] bi* and ] 2dip
- [ '[ nip @ ] ] dip if ;
- inline
-
-: %unbox-struct ( n c-type -- )
- [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ;
-
-: %box-struct ( n c-type -- )
- [ %box-small-struct ] [ %box-large-struct ] if-small-struct ;
M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ;
-M: ppc value-structs? f ;
+M: ppc value-struct? drop f ;
M: ppc dummy-stack-params? f ;
M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
-M: ppc value-structs? t ;
+M: ppc value-struct? drop t ;
M: ppc dummy-stack-params? t ;
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel layouts system math alien.c-types
+USING: kernel layouts system math alien.c-types sequences
compiler.cfg.registers cpu.architecture cpu.x86.assembler cpu.x86 ;
IN: cpu.x86.64.winnt
M: x86.64 reserved-area-size 4 cells ;
-M: x86.64 struct-small-enough? ( size -- ? )
- heap-size cell <= ;
+M: x86.64 struct-small-enough? heap-size { 1 2 4 8 } member? ;
+
+M: x86.64 value-struct? heap-size { 1 2 4 8 } member? ;
M: x86.64 dummy-stack-params? f ;
<<
"longlong" "ptrdiff_t" typedef
+"longlong" "intptr_t" typedef
"int" "long" typedef
"uint" "ulong" typedef
>>
temp-reg-1 2 cells [+] ds-reg MOV
temp-reg-1 3 cells [+] rs-reg MOV ;
-M: x86 value-structs? t ;
+M: x86 value-struct? drop t ;
M: x86 small-enough? ( n -- ? )
HEX: -80000000 HEX: 7fffffff between? ;
USING: definitions io.launcher kernel parser words sequences math
-math.parser namespaces editors make ;
+math.parser namespaces editors make system ;
IN: editors.emacs
: emacsclient ( file line -- )
[
\ emacsclient get "emacsclient" or ,
- "--no-wait" ,
+ os windows? [ "--no-wait" , ] unless
"+" swap number>string append ,
,
] { } make try-process ;
{ "FT_Pos" "advance-x" }
{ "FT_Pos" "advance-y" }
- { "long" "format" }
+ { "intptr_t" "format" }
{ "int" "bitmap-rows" }
{ "int" "bitmap-width" }
</table>
<p>
- <button>Update</button>
+ <button type="submit">Update</button>
<t:validation-errors />
</p>
</table>
- <button>Recover password</button>
+ <button type="submit">Recover password</button>
</t:form>
</table>
<p>
- <button>Set password</button>
+ <button type="submit">Set password</button>
<t:validation-errors />
</p>
<p>
- <button>Register</button>
+ <button type="submit">Register</button>
<t:validation-errors />
</p>
<p>
- <button>Log in</button>
+ <button type="submit">Log in</button>
<t:validation-errors />
</p>
: escape-char ( ch -- )
dup H{
- { CHAR: " "__quote__" }
+ { CHAR: " "__quo__" }
{ CHAR: * "__star__" }
{ CHAR: : "__colon__" }
{ CHAR: < "__lt__" }
{ CHAR: > "__gt__" }
- { CHAR: ? "__question__" }
- { CHAR: \\ "__backslash__" }
+ { CHAR: ? "__que__" }
+ { CHAR: \\ "__back__" }
{ CHAR: | "__pipe__" }
- { CHAR: _ "__underscore__" }
{ CHAR: / "__slash__" }
- { CHAR: \\ "__backslash__" }
{ CHAR: , "__comma__" }
{ CHAR: @ "__at__" }
} at [ % ] [ , ] ?if ;
[ [ title>> ] compare ] sort ;
: article-apropos ( string -- results )
- "articles.idx" temp-file offline-apropos ;
+ "articles.idx" offline-apropos ;
: word-apropos ( string -- results )
- "words.idx" temp-file offline-apropos ;
+ "words.idx" offline-apropos ;
: vocab-apropos ( string -- results )
- "vocabs.idx" temp-file offline-apropos ;
+ "vocabs.idx" offline-apropos ;
USING: io io.files io.streams.string io.encodings.utf8
html.templates html.templates.fhtml kernel
-tools.test sequences parser ;
+tools.test sequences parser splitting prettyprint ;
IN: html.templates.fhtml.tests
: test-template ( path -- ? )
prepend
[
".fhtml" append <fhtml> [ call-template ] with-string-writer
+ <string-reader> lines
] keep
- ".html" append utf8 file-contents = ;
+ ".html" append utf8 file-lines
+ [ . . ] [ = ] 2bi ;
[ t ] [ "example" test-template ] unit-test
[ t ] [ "bug" test-template ] unit-test
] when*
] unless ;
+: (start-server) ( threaded-server -- )
+ init-server
+ dup threaded-server [
+ dup name>> [
+ [ listen-on [ start-accept-loop ] parallel-each ]
+ [ ready>> raise-flag ]
+ bi
+ ] with-logging
+ ] with-variable ;
+
PRIVATE>
: start-server ( threaded-server -- )
- init-server
- dup secure-config>> [
- dup threaded-server [
- dup name>> [
- [ listen-on [ start-accept-loop ] parallel-each ]
- [ ready>> raise-flag ]
- bi
- ] with-logging
- ] with-variable
- ] with-secure-context ;
+ #! Only create a secure-context if we want to listen on
+ #! a secure port, otherwise start-server won't work at
+ #! all if SSL is not available.
+ dup secure>> [
+ dup secure-config>> [
+ (start-server)
+ ] with-secure-context
+ ] [
+ (start-server)
+ ] if ;
: wait-for-server ( threaded-server -- )
ready>> wait-for-flag ;
-USING: io.launcher tools.test calendar accessors environment\r
-namespaces kernel system arrays io io.files io.encodings.ascii\r
-sequences parser assocs hashtables math continuations eval ;\r
-IN: io.windows.launcher.nt.tests\r
-\r
-[ ] [\r
- <process>\r
- "notepad" >>command\r
- 1/2 seconds >>timeout\r
- "notepad" set\r
-] unit-test\r
-\r
-[ f ] [ "notepad" get process-running? ] unit-test\r
-\r
-[ f ] [ "notepad" get process-started? ] unit-test\r
-\r
-[ ] [ "notepad" [ run-detached ] change ] unit-test\r
-\r
-[ "notepad" get wait-for-process ] must-fail\r
-\r
-[ t ] [ "notepad" get killed>> ] unit-test\r
-\r
-[ f ] [ "notepad" get process-running? ] unit-test\r
-\r
-[ ] [\r
- <process>\r
- vm "-quiet" "-run=hello-world" 3array >>command\r
- "out.txt" temp-file >>stdout\r
- try-process\r
-] unit-test\r
-\r
-[ "Hello world" ] [\r
- "out.txt" temp-file ascii file-lines first\r
-] unit-test\r
-\r
-[ ] [\r
- <process>\r
- vm "-run=listener" 2array >>command\r
- +closed+ >>stdin\r
- try-process\r
-] unit-test\r
-\r
-[ ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "stderr.factor" 3array >>command\r
- "out.txt" temp-file >>stdout\r
- "err.txt" temp-file >>stderr\r
- try-process\r
- ] with-directory\r
-] unit-test\r
-\r
-[ "output" ] [\r
- "out.txt" temp-file ascii file-lines first\r
-] unit-test\r
-\r
-[ "error" ] [\r
- "err.txt" temp-file ascii file-lines first\r
-] unit-test\r
-\r
-[ ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "stderr.factor" 3array >>command\r
- "out.txt" temp-file >>stdout\r
- +stdout+ >>stderr\r
- try-process\r
- ] with-directory\r
-] unit-test\r
-\r
-[ "outputerror" ] [\r
- "out.txt" temp-file ascii file-lines first\r
-] unit-test\r
-\r
-[ "output" ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "stderr.factor" 3array >>command\r
- "err2.txt" temp-file >>stderr\r
- ascii <process-reader> lines first\r
- ] with-directory\r
-] unit-test\r
-\r
-[ "error" ] [\r
- "err2.txt" temp-file ascii file-lines first\r
-] unit-test\r
-\r
-[ t ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "env.factor" 3array >>command\r
- ascii <process-reader> contents\r
- ] with-directory eval\r
-\r
- os-envs =\r
-] unit-test\r
-\r
-[ t ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "env.factor" 3array >>command\r
- +replace-environment+ >>environment-mode\r
- os-envs >>environment\r
- ascii <process-reader> contents\r
- ] with-directory eval\r
- \r
- os-envs =\r
-] unit-test\r
-\r
-[ "B" ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "env.factor" 3array >>command\r
- { { "A" "B" } } >>environment\r
- ascii <process-reader> contents\r
- ] with-directory eval\r
-\r
- "A" swap at\r
-] unit-test\r
-\r
-[ f ] [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "env.factor" 3array >>command\r
- { { "HOME" "XXX" } } >>environment\r
- +prepend-environment+ >>environment-mode\r
- ascii <process-reader> contents\r
- ] with-directory eval\r
-\r
- "HOME" swap at "XXX" =\r
-] unit-test\r
-\r
-2 [\r
- [ ] [\r
- <process>\r
- "cmd.exe /c dir" >>command\r
- "dir.txt" temp-file >>stdout\r
- try-process\r
- ] unit-test\r
-\r
- [ ] [ "dir.txt" temp-file delete-file ] unit-test\r
-] times\r
-\r
-[ "append-test" temp-file delete-file ] ignore-errors\r
-\r
-[ "Hello appender\r\nHello appender\r\n" ] [\r
- 2 [\r
- "resource:basis/io/windows/nt/launcher/test" [\r
- <process>\r
- vm "-script" "append.factor" 3array >>command\r
- "append-test" temp-file <appender> >>stdout\r
- try-process\r
- ] with-directory\r
- ] times\r
- \r
- "append-test" temp-file ascii file-contents\r
-] unit-test\r
+USING: io.launcher tools.test calendar accessors environment
+namespaces kernel system arrays io io.files io.encodings.ascii
+sequences parser assocs hashtables math continuations eval ;
+IN: io.windows.launcher.nt.tests
+
+[ ] [
+ <process>
+ "notepad" >>command
+ 1/2 seconds >>timeout
+ "notepad" set
+] unit-test
+
+[ f ] [ "notepad" get process-running? ] unit-test
+
+[ f ] [ "notepad" get process-started? ] unit-test
+
+[ ] [ "notepad" [ run-detached ] change ] unit-test
+
+[ "notepad" get wait-for-process ] must-fail
+
+[ t ] [ "notepad" get killed>> ] unit-test
+
+[ f ] [ "notepad" get process-running? ] unit-test
+
+[ ] [
+ <process>
+ vm "-quiet" "-run=hello-world" 3array >>command
+ "out.txt" temp-file >>stdout
+ try-process
+] unit-test
+
+[ "Hello world" ] [
+ "out.txt" temp-file ascii file-lines first
+] unit-test
+
+[ ] [
+ <process>
+ vm "-run=listener" 2array >>command
+ +closed+ >>stdin
+ try-process
+] unit-test
+
+[ ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "stderr.factor" 3array >>command
+ "out.txt" temp-file >>stdout
+ "err.txt" temp-file >>stderr
+ try-process
+ ] with-directory
+] unit-test
+
+[ "output" ] [
+ "out.txt" temp-file ascii file-lines first
+] unit-test
+
+[ "error" ] [
+ "err.txt" temp-file ascii file-lines first
+] unit-test
+
+[ ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "stderr.factor" 3array >>command
+ "out.txt" temp-file >>stdout
+ +stdout+ >>stderr
+ try-process
+ ] with-directory
+] unit-test
+
+[ "outputerror" ] [
+ "out.txt" temp-file ascii file-lines first
+] unit-test
+
+[ "output" ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "stderr.factor" 3array >>command
+ "err2.txt" temp-file >>stderr
+ ascii <process-reader> lines first
+ ] with-directory
+] unit-test
+
+[ "error" ] [
+ "err2.txt" temp-file ascii file-lines first
+] unit-test
+
+[ t ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "env.factor" 3array >>command
+ ascii <process-reader> contents
+ ] with-directory eval
+
+ os-envs =
+] unit-test
+
+[ t ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "env.factor" 3array >>command
+ +replace-environment+ >>environment-mode
+ os-envs >>environment
+ ascii <process-reader> contents
+ ] with-directory eval
+
+ os-envs =
+] unit-test
+
+[ "B" ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "env.factor" 3array >>command
+ { { "A" "B" } } >>environment
+ ascii <process-reader> contents
+ ] with-directory eval
+
+ "A" swap at
+] unit-test
+
+[ f ] [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "env.factor" 3array >>command
+ { { "USERPROFILE" "XXX" } } >>environment
+ +prepend-environment+ >>environment-mode
+ ascii <process-reader> contents
+ ] with-directory eval
+
+ "USERPROFILE" swap at "XXX" =
+] unit-test
+
+2 [
+ [ ] [
+ <process>
+ "cmd.exe /c dir" >>command
+ "dir.txt" temp-file >>stdout
+ try-process
+ ] unit-test
+
+ [ ] [ "dir.txt" temp-file delete-file ] unit-test
+] times
+
+[ "append-test" temp-file delete-file ] ignore-errors
+
+[ "Hello appender\r\nHello appender\r\n" ] [
+ 2 [
+ "resource:basis/io/windows/nt/launcher/test" [
+ <process>
+ vm "-script" "append.factor" 3array >>command
+ "append-test" temp-file <appender> >>stdout
+ try-process
+ ] with-directory
+ ] times
+
+ "append-test" temp-file ascii file-contents
+] unit-test
over glEnableClientState dip glDisableClientState ; inline
: words>values ( word/value-seq -- value-seq )
- [ dup word? [ execute ] [ ] if ] map ;
+ [ dup word? [ execute ] when ] map ;
: (all-enabled) ( seq quot -- )
over [ glEnable ] each dip [ glDisable ] each ; inline
: (rect-vertices) ( dim -- vertices )
{
- [ drop 0 1 ]
- [ first 1- 1 ]
- [ [ first 1- ] [ second ] bi ]
- [ second 0 swap ]
+ [ drop 0.5 0.5 ]
+ [ first 0.5 - 0.5 ]
+ [ [ first 0.5 - ] [ second 0.5 - ] bi ]
+ [ second 0.5 - 0.5 swap ]
} cleave 8 narray >c-float-array ;
: rect-vertices ( dim -- )
[ ] [ \ curry see ] unit-test
[ "POSTPONE: [" ] [ \ [ unparse ] unit-test
+
+TUPLE: started-out-hustlin' ;
+
+GENERIC: ended-up-ballin'
+
+M: started-out-hustlin' ended-up-ballin' ; inline
+
+[ "USING: prettyprint.tests ;\nM: started-out-hustlin' ended-up-ballin' ; inline\n" ] [
+ [ { started-out-hustlin' ended-up-ballin' } see ] with-string-writer
+] unit-test
block>
] with-use nl ;
+M: method-spec see
+ first2 method see ;
+
GENERIC: see-class* ( word -- )
M: union-class see-class*
+warning+ (inference-error) ; inline
M: inference-error error.
- [ "In word: " write word>> . ] [ error>> error. ] bi ;
+ [ word>> [ "In word: " write . ] when* ] [ error>> error. ] bi ;
TUPLE: literal-expected ;
"The recursive word " write
word>> pprint
" calls itself with a different set of quotation parameters than were input" print ;
+
+TUPLE: unknown-primitive-error ;
+
+M: unknown-primitive-error error.
+ drop
+ "Cannot determine stack effect statically" print ;
{ \ load-locals [ infer-load-locals ] }
{ \ get-local [ infer-get-local ] }
{ \ drop-locals [ infer-drop-locals ] }
- { \ do-primitive [ \ do-primitive cannot-infer-effect ] }
+ { \ do-primitive [ unknown-primitive-error inference-warning ] }
{ \ alien-invoke [ infer-alien-invoke ] }
{ \ alien-indirect [ infer-alien-indirect ] }
{ \ alien-callback [ infer-alien-callback ] }
namespaces stack-checker.recursive-state.tree ;
IN: stack-checker.recursive-state
-TUPLE: recursive-state words word quotations inline-words ;
-
-C: <recursive-state> recursive-state
+TUPLE: recursive-state word words quotations inline-words ;
: prepare-recursive-state ( word rstate -- rstate )
swap >>word
dup "A" throw [ bogus-error ] [ drop ] if ; inline recursive
[ bogus-error ] must-infer
+
+[ [ clear ] infer. ] [ inference-error? ] must-fail-with
unportable
-windows
tools
:: (draw-string) ( open-font sprites string loc -- )
GL_TEXTURE_2D [
loc [
- -0.5 0.5 0.0 glTranslated
string open-font string char-widths scan-sums [
[ open-font sprites ] 2dip draw-char
] 2each
line-height * ;
: caret-loc ( editor -- loc )
- [ editor-caret* ] keep 2dup loc>x
+ [ editor-caret* ] keep 2dup loc>x 1+
rot first rot line>y 2array ;
: caret-dim ( editor -- dim )
: scroll>caret ( editor -- )
dup graft-state>> second [
- dup caret-loc over caret-dim { 1 0 } v+ <rect>
+ dup caret-loc over caret-dim <rect>
over scroll>rect
] when drop ;
dup grid set
dup rect-dim half-gap v- grid-dim set
compute-grid
- { 0 1 } draw-grid-lines
- { 1 0 } draw-grid-lines
+ [ { 1 0 } draw-grid-lines ]
+ [
+ { 0.5 -0.5 } gl-translate
+ { 0 1 } draw-grid-lines
+ ] bi*
] with-scope ;
[ rect-intersect ] keep
dim>> dup { 0 1 } v* viewport-translation set
{ 0 0 } over gl-viewport
- -0.5 swap first2 [ 0.5 - ] [ 0.5 + ] bi* 0.5 gluOrtho2D
+ 0 swap first2 0 gluOrtho2D
clip set
do-clip ;
unportable
-windows
-com
bindings
unportable
-windows
-com
bindings
unportable
-windows
-com
bindings
unportable
-windows
bindings
: THREAD_PRIORITY_TIME_CRITICAL 15 ; inline
C-STRUCT: OVERLAPPED
- { "int" "internal" }
- { "int" "internal-high" }
- { "int" "offset" }
- { "int" "offset-high" }
- { "void*" "event" } ;
+ { "UINT_PTR" "internal" }
+ { "UINT_PTR" "internal-high" }
+ { "DWORD" "offset" }
+ { "DWORD" "offset-high" }
+ { "HANDLE" "event" } ;
C-STRUCT: SYSTEMTIME
{ "WORD" "wYear" }
unportable
-windows
bindings
TYPEDEF: void* LPCVOID
TYPEDEF: float FLOAT
-TYPEDEF: short HALF_PTR
-TYPEDEF: ushort UHALF_PTR
-TYPEDEF: int INT_PTR
-TYPEDEF: uint UINT_PTR
+
+TYPEDEF: intptr_t HALF_PTR
+TYPEDEF: intptr_t UHALF_PTR
+TYPEDEF: intptr_t INT_PTR
+TYPEDEF: intptr_t UINT_PTR
TYPEDEF: int LONG_PTR
TYPEDEF: ulong ULONG_PTR
! Make sure we use correct to_c_string form when writing
[ ] [ "\0" write ] unit-test
+[ ] [
+ "It seems Jobs has lost his grasp on reality again.\n"
+ "separator-test.txt" temp-file latin1 set-file-contents
+] unit-test
+
[
{
{ "It seems " CHAR: J }
}
] [
[
- "resource:core/io/test/separator-test.txt"
+ "separator-test.txt" temp-file
latin1 <file-reader> [
"J" read-until 2array ,
"i" read-until 2array ,
+++ /dev/null
-It seems Jobs has lost his grasp on reality again.
{ { $snippet "extra" } " - additional contributed libraries." }
{ { $snippet "work" } " - a root for vocabularies which are not intended to be contributed back to Factor." }
}
-"Your own vocabularies should go into " { $snippet "extra" } " or " { $snippet "work" } ", depending on whether or not you intend to contribute them back to the Factor project. If you wish to work on vocabularies outside of the Factor source directory, create a " { $snippet "~/.factor-rc" } " file like the following,"
+"Your own vocabularies should go into " { $snippet "extra" } " or " { $snippet "work" } ", depending on whether or not you intend to contribute them back to the Factor project. If you wish to work on vocabularies outside of the Factor source directory, create a " { $link "factor-boot-rc" } " file like the following:"
{ $code
"USING: namespaces sequences vocabs.loader ;"
"\"/home/jane/sources/\" vocab-roots get push"
-! Unit tests for vocabs.loader vocabulary
IN: vocabs.loader.tests
USING: vocabs.loader tools.test continuations vocabs math
kernel arrays sequences namespaces io.streams.string
parser source-files words assocs classes.tuple definitions
-debugger compiler.units tools.vocabs accessors eval ;
+debugger compiler.units tools.vocabs accessors eval
+combinators ;
! This vocab should not exist, but just in case...
[ ] [
[ "xabbabbja" forget-vocab ] with-compilation-unit
forget-junk
+
+[ ] [ [ "vocabs.loader.test.e" forget-vocab ] with-compilation-unit ] unit-test
+
+[ "vocabs.loader.test.e" require ]
+[ relative-overflow? ] must-fail-with
f over set-vocab-source-loaded?
[ vocab-source-path [ parse-file ] [ [ ] ] if* ] keep
t swap set-vocab-source-loaded?
- [ % ] [ call ] if-bootstrapping ;
+ [ % ] [ assert-depth ] if-bootstrapping ;
: load-docs ( vocab -- vocab )
load-help? get [
--- /dev/null
+unportable
: init-rule ( -- ) 8 <hashtable> >rule ;
: rule-keys ( -- array )
-{ { 1 1 1 }
- { 1 1 0 }
- { 1 0 1 }
- { 1 0 0 }
- { 0 1 1 }
- { 0 1 0 }
- { 0 0 1 }
- { 0 0 0 } } ;
+ { { 1 1 1 }
+ { 1 1 0 }
+ { 1 0 1 }
+ { 1 0 0 }
+ { 0 1 1 }
+ { 0 1 0 }
+ { 0 0 1 }
+ { 0 0 0 } } ;
: rule-values ( n -- seq ) >bin 8 CHAR: 0 pad-left string>digits ;
: set-rule ( n -- )
-dup >rule-number rule-values rule-keys [ rule> set-at ] 2each ;
+ dup >rule-number rule-values rule-keys [ rule> set-at ] 2each ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! step-capped-line
: cap-line ( line -- 0-line-0 ) { 0 } prepend { 0 } append ;
: wrap-line ( a-line-z -- za-line-za )
-dup peek 1array swap dup first 1array append append ;
+ dup peek 1array swap dup first 1array append append ;
: step-line ( line -- new-line ) 3 <clumps> [ pattern>state ] map ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: interesting ( -- seq )
-{ 18 22 26 30 41 45 54 60 73 75 82 86 89 90 97 101 102 105 106 107 109
- 110 120 121 122 124 126 129 137 146 147 149 150 151 153 154 161 165 } ;
+ { 18 22 26 30 41 45 54 60 73 75 82 86 89 90 97 101 102 105 106 107 109
+ 110 120 121 122 124 126 129 137 146 147 149 150 151 153 154 161 165 } ;
: mild ( -- seq ) { 6 9 11 57 62 74 118 } ;
VAR: last-line
: run-rule ( -- )
-last-line> height> [ drop step-capped-line dup ] map >bitmap >last-line ;
+ last-line> height> [ drop step-capped-line dup ] map >bitmap >last-line ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Call a 'model' quotation with the current 'view'.
: with-view ( quot -- )
-slate> rect-dim first >width
-slate> rect-dim second >height
-call
-slate> relayout-1 ;
+ slate> rect-dim first >width
+ slate> rect-dim second >height
+ call
+ slate> relayout-1 ;
! Create a quotation that is appropriate for buttons and gesture handler.
USING: benchmark.regex-dna io io.files io.encodings.ascii
-io.streams.string kernel tools.test ;
+io.streams.string kernel tools.test splitting ;
IN: benchmark.regex-dna.tests
[ t ] [
"resource:extra/benchmark/regex-dna/regex-dna-test-in.txt"
- [ regex-dna ] with-string-writer
+ [ regex-dna ] with-string-writer string-lines
"resource:extra/benchmark/regex-dna/regex-dna-test-out.txt"
- ascii file-contents =
+ ascii file-lines =
] unit-test
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: init-variables ( -- )
-1.0 >cohesion-weight
-1.0 >alignment-weight
-1.0 >separation-weight
+ 1.0 >cohesion-weight
+ 1.0 >alignment-weight
+ 1.0 >separation-weight
-75 >cohesion-radius
-50 >alignment-radius
-25 >separation-radius
+ 75 >cohesion-radius
+ 50 >alignment-radius
+ 25 >separation-radius
-180 >cohesion-view-angle
-180 >alignment-view-angle
-180 >separation-view-angle
+ 180 >cohesion-view-angle
+ 180 >alignment-view-angle
+ 180 >separation-view-angle
-10 >time-slice ;
+ 10 >time-slice ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! random-boid and random-boids
: constrain ( n a b -- n ) rot min max ;
: angle-between ( vec vec -- angle )
-2dup v. -rot norm swap norm * / -1 1 constrain acos rad>deg ;
+ 2dup v. -rot norm swap norm * / -1 1 constrain acos rad>deg ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate
- mortar random-weighted cfdg ;
+ random-weighted cfdg ;
IN: cfdg.models.game1-turn6
USING: kernel namespaces math opengl.gl opengl.glu ui ui.gadgets.slate
- mortar random-weighted cfdg ;
+ random-weighted cfdg ;
IN: cfdg.models.sierpinski
: changelog ( -- authors )
image parent-directory [
- "git-log --pretty=format:%an" ascii <process-reader> lines
+ "git log --pretty=format:%an" ascii <process-reader> lines
] with-directory ;
: patch-counts ( authors -- assoc )
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-USING: kernel combinators sequences math math.functions math.vectors mortar
- slot-accessors x x.widgets.wm.root x.widgets.wm.frame sequences.lib ;
-IN: factory.commands
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: up-till-frame ( window -- wm-frame )
-{ { [ dup <wm-frame> is? ]
- [ ] }
- { [ dup $dpy $default-root $id over $id = ]
- [ drop f ] }
- { [ t ]
- [ <- parent up-till-frame ] } } cond ;
-
-: pointer-window ( -- window ) dpy> <- pointer-window ;
-
-: pointer-frame ( -- wm-frame )
-pointer-window up-till-frame dup <wm-frame> is? [ ] [ drop f ] if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: maximize ( -- ) pointer-frame wm-frame-maximize drop ;
-
-: minimize ( -- ) pointer-frame <- unmap drop ;
-
-: maximize-vertical ( -- ) pointer-frame wm-frame-maximize-vertical drop ;
-
-: restore ( -- ) pointer-frame <- restore-state drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
-
-: tile-master ( -- )
-
-wm-root>
- <- children
- [ <- mapped? ] filter
- [ check-window-table ] map
- reverse
-
-unclip
- { 0 0 } <-- move
- wm-root> <- size { 1/2 1 } v*
- [ floor ] map <-- resize
- <- adjust-child
-drop
-
-dup empty? [ drop ] [
-
-wm-root> <- width 2 / floor [ <-- set-width ] curry map
-wm-root> <- height over length / floor [ <-- set-height ] curry map
-
-wm-root> <- width 2 / floor [ <-- set-x ] curry map
-
-wm-root> <- height over length / over length [ * floor ] map-with
-[ <-- set-y <- adjust-child ] 2map
-
-drop
-
-] if ;
-
-! : tile-master ( -- )
-
-! wm-root>
-! <- children
-! [ <- mapped? ] filter
-! [ check-window-table ] map
-! reverse
-
-! { { [ dup empty? ] [ drop ] }
-! { [ dup length 1 = ] [ drop maximize ] }
-! { [ t ] [ tile-master* ] }
+++ /dev/null
-! -*-factor-*-
-
-USING: kernel unix vars mortar mortar.sugar slot-accessors
- x.widgets.wm.menu x.widgets.wm.unmapped-frames-menu
- factory.commands factory.load ;
-
-IN: factory
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! Helper words
-
-: new-wm-menu ( -- menu ) <wm-menu> new* 1 <-- set-border-width ;
-
-: shrink-wrap ( menu -- ) dup <- calc-size <-- resize drop ;
-
-: set-menu-items ( items menu -- ) swap >>items shrink-wrap ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: apps-menu
-
-apps-menu> not [ new-wm-menu >apps-menu ] when
-
-{ { "Emacs" [ "emacs &" system drop ] }
- { "KMail" [ "kmail &" system drop ] }
- { "Akregator" [ "akregator &" system drop ] }
- { "Amarok" [ "amarok &" system drop ] }
- { "K3b" [ "k3b &" system drop ] }
- { "xchat" [ "xchat &" system drop ] }
- { "Nautilus" [ "nautilus --no-desktop &" system drop ] }
- { "synaptic" [ "gksudo synaptic &" system drop ] }
- { "Volume control" [ "gnome-volume-control &" system drop ] }
- { "Azureus" [ "~/azureus/azureus &" system drop ] }
- { "Xephyr" [ "Xephyr -host-cursor :1 &" system drop ] }
- { "Stop Xephyr" [ "pkill Xephyr &" system drop ] }
- { "Stop Firefox" [ "pkill firefox &" system drop ] }
-} apps-menu> set-menu-items
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: emacs-menu
-
-emacs-menu> not [ new-wm-menu >emacs-menu ] when
-
-{ { "Start Emacs" [ "emacs &" system drop ] }
- { "Small" [ "emacsclient -e '(make-small-frame-command)' &" system drop ] }
- { "Large" [ "emacsclient -e '(make-frame-command)' &" system drop ] }
- { "Full" [ "emacsclient -e '(make-full-frame-command)' &" system drop ] }
- { "Gnus" [ "emacsclient -e '(gnus-other-frame)' &" system drop ] }
- { "Factor" [ "emacsclient -e '(run-factor-other-frame)' &" system drop ] }
-} emacs-menu> set-menu-items
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: mail-menu
-
-mail-menu> not [ new-wm-menu >mail-menu ] when
-
-{ { "Kmail" [ "kmail &" system drop ] }
- { "compose" [ "kmail --composer &" system drop ] }
- { "slava" [ "kmail slava@factorcode.org &" system drop ] }
- { "erg" [ "kmail doug.coleman@gmail.com &" system drop ] }
- { "doublec" [ "kmail chris.double@double.co.nz &" system drop ] }
- { "yuuki" [ "kmail matthew.willis@mac.com &" system drop ] }
-} mail-menu> set-menu-items
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: factor-menu
-
-factor-menu> not [ new-wm-menu >factor-menu ] when
-
-{ { "Factor" [ "cd /scratch/repos/Factor ; ./factor &" system drop ] }
- { "Factor (tty)"
- [ "cd /scratch/repos/Factor ; xterm -e ./factor -run=listener &"
- system drop ] }
- { "Terminal : repos/Factor"
- [ "cd /scratch/repos/Factor ; xterm &" system drop ] }
- { "darcs whatsnew"
- [ "cd /scratch/repos/Factor ; xterm -e 'darcs whatsnew | less' &"
- system drop ] }
- { "darcs pull"
- [ "cd /scratch/repos/Factor ; xterm -e 'darcs pull http://factorcode.org/repos' &" system drop ] }
- { "darcs push"
- [ "cd /scratch/repos/Factor ; xterm -e 'darcs push dharmatech@onigirihouse.com:doc-root/repos' &" system drop ] }
-} factor-menu> set-menu-items
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: factory-menu
-
-factory-menu> not [ new-wm-menu >factory-menu ] when
-
-{ { "Maximize" [ maximize ] }
- { "Maximize Vertical" [ maximize-vertical ] }
- { "Restore" [ restore ] }
- { "Hide" [ minimize ] }
- { "Tile Master" [ tile-master ] }
-}
-
-factory-menu> set-menu-items
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! VAR: root-menu
-
-{ { "xterm" [ "urxvt -bd grey +sb &" system drop ] }
- { "Firefox" [ "firefox &" system drop ] }
- { "xclock" [ "xclock &" system drop ] }
- { "Apps >" [ apps-menu> <- popup ] }
- { "Factor >" [ factor-menu> <- popup ] }
- { "Unmapped frames >" [ unmapped-frames-menu> <- popup ] }
- { "Emacs >" [ emacs-menu> <- popup ] }
- { "Mail >" [ mail-menu> <- popup ] }
- { "onigirihouse" [ "xterm -e 'ssh dharmatech@onigirihouse.com' &"
- system drop ] }
- { "Edit menus" [ edit-factory-menus ] }
- { "Reload menus" [ load-factory-menus ] }
- { "Factory >" [ factory-menu> <- popup ] }
-} root-menu> set-menu-items
-
+++ /dev/null
-! -*-factor-*-
-
-USING: kernel mortar x
- x.widgets.wm.root
- x.widgets.wm.workspace
- x.widgets.wm.unmapped-frames-menu
- factory.load
- tty-server ;
-
-IN: factory
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-create-root-menu
-create-unmapped-frames-menu
-load-factory-menus
-6 setup-workspaces
-
-wm-root>
- no-modifiers "F12" [ root-menu> <- popup ] <---- set-key-action
- control-alt "LEFT" [ prev-workspace ] <---- set-key-action
- control-alt "RIGHT" [ next-workspace ] <---- set-key-action
- alt "TAB" [ circulate-focus ] <---- set-key-action
-drop
-
-9010 tty-server
+++ /dev/null
-
-USING: kernel parser io io.files namespaces sequences editors threads vars
- mortar mortar.sugar slot-accessors
- x
- x.widgets.wm.root
- x.widgets.wm.frame
- x.widgets.wm.menu
- factory.load
- factory.commands ;
-
-IN: factory
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: manage-windows ( -- )
-dpy get $default-root <- children [ <- mapped? ] filter
-[ $id <wm-frame> new* drop ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: root-menu
-
-: create-root-menu ( -- ) <wm-menu> new* 1 <-- set-border-width >root-menu ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: start-factory ( display-string -- )
-<display> new* >dpy
-install-default-error-handler
-create-wm-root
-init-atoms
-manage-windows
-load-factory-rc ;
-
-: factory ( -- ) f start-factory stop ;
-
-MAIN: factory
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel io.files parser editors sequences ;
-
-IN: factory.load
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: file-or ( file file -- file ) over exists? [ drop ] [ nip ] if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: personal-factory-rc ( -- path ) home "/.factory-rc" append ;
-
-: system-factory-rc ( -- path ) "extra/factory/factory-rc" resource-path ;
-
-: factory-rc ( -- path ) personal-factory-rc system-factory-rc file-or ;
-
-: load-factory-rc ( -- ) factory-rc run-file ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: personal-factory-menus ( -- path ) home "/.factory-menus" append ;
-
-: system-factory-menus ( -- path )
-"extra/factory/factory-menus" resource-path ;
-
-: factory-menus ( -- path )
-personal-factory-menus system-factory-menus file-or ;
-
-: load-factory-menus ( -- ) factory-menus run-file ;
-
-: edit-factory-menus ( -- ) factory-menus 0 edit-location ;
+++ /dev/null
-Window manager for the X Window System
+++ /dev/null
-applications
unportable
-input
-gamepads
-joysticks
-windows
+games
unportable
-gamepads
-joysticks
-mac
-input
+games
-gamepads
-joysticks
-input
+games
-joysticks
-gamepads
-input
+games
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: sequences mortar slot-accessors ;
-
-IN: geom.dim
-
-SYMBOL: <dim>
-
-<dim> { "dim" } accessors define-independent-class
-
-<dim> {
-
-"width" !( dim -- width ) [ $dim first ]
-
-"height" !( dim -- second ) [ $dim second ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel arrays sequences math.vectors mortar slot-accessors ;
-
-IN: geom.pos
-
-SYMBOL: <pos>
-
-<pos> { "pos" } accessors define-independent-class
-
-<pos> {
-
-"x" !( pos -- x ) [ $pos first ]
-
-"y" !( pos -- y ) [ $pos second ]
-
-"set-x" !( pos x -- pos ) [ 0 pick $pos set-nth ]
-
-"set-y" !( pos y -- pos ) [ 1 pick $pos set-nth ]
-
-"distance" !( pos pos -- distance ) [ $pos swap $pos v- norm ]
-
-"move-by" !( pos offset -- pos ) [ over $pos v+ >>pos ]
-
-"move-by-x" !( pos x-offset -- pos ) [ 0 2array <-- move-by ]
-
-"move-by-y" !( pos y-offset -- pos ) [ 0 swap 2array <-- move-by ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces arrays sequences math.vectors
- mortar slot-accessors geom.pos geom.dim ;
-
-IN: geom.rect
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-USE: math
-
-: v+y ( pos y -- pos ) 0 swap 2array v+ ;
-
-: v-y ( pos y -- pos ) 0 swap 2array v- ;
-
-: v+x ( pos x -- pos ) 0 2array v+ ;
-
-: v-x ( pos x -- pos ) 0 2array v- ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: <rect>
-
-<rect>
- <pos> class-slots <dim> class-slots append
- <pos> class-methods <dim> class-methods append { H{ } } append
- { H{ } }
-4array <rect> set-global
-
-! { 0 0 } { 0 0 } <rect> new
-
-<rect> {
-
-"top-left" !( rect -- point ) [ $pos ]
-
-"top-right" !( rect -- point ) [ dup $pos swap <- width 1- v+x ]
-
-"bottom-left" !( rect -- point ) [ dup $pos swap <- height 1- v+y ]
-
-"bottom-right" !( rect -- point ) [ dup $pos swap $dim { 1 1 } v- v+ ]
-
-} add-methods
\ No newline at end of file
[ [ [ blank? ] trim ] change-text ] when
] map ;
-: find-by-id ( vector id -- vector' )
+: find-by-id ( vector id -- vector' elt/f )
'[ attributes>> "id" at _ = ] find ;
-: find-by-class ( vector id -- vector' )
+: find-by-class ( vector id -- vector' elt/f )
'[ attributes>> "class" at _ = ] find ;
-: find-by-name ( vector string -- vector )
+: find-by-name ( vector string -- vector elt/f )
>lower '[ name>> _ = ] find ;
: find-by-id-between ( vector string -- vector' )
[ attributes>> "id" swap at _ = ] bi and
] dupd find find-between* ;
-: find-by-attribute-key ( vector key -- vector' )
+: find-by-attribute-key ( vector key -- vector' elt/? )
>lower
[ attributes>> at _ = ] filter sift ;
-mac
bindings
-system
+unportable
-mac
bindings
-system
+unportable
-gamepads
-joysticks
+games
IN: mason.child.tests
USING: mason.child mason.config tools.test namespaces ;
-[ { "make" "clean" "winnt-x86-32" } ] [
+[ { "make" "winnt-x86-32" } ] [
[
"winnt" target-os set
"x86.32" target-cpu set
] with-scope
] unit-test
-[ { "make" "clean" "macosx-x86-32" } ] [
+[ { "make" "macosx-x86-32" } ] [
[
"macosx" target-os set
"x86.32" target-cpu set
] with-scope
] unit-test
-[ { "gmake" "clean" "netbsd-ppc" } ] [
+[ { "gmake" "netbsd-ppc" } ] [
[
"netbsd" target-os set
"ppc" target-cpu set
! See http://factorcode.org/license.txt for BSD license.
USING: kernel namespaces make debugger sequences io.files
io.launcher arrays accessors calendar continuations
-combinators.short-circuit mason.common mason.report mason.platform ;
+combinators.short-circuit mason.common mason.report
+mason.platform mason.config http.client ;
IN: mason.child
: make-cmd ( -- args )
- [ gnu-make , "clean" , platform , ] { } make ;
+ gnu-make platform 2array ;
+
+: download-dlls ( -- )
+ target-os get "winnt" = [
+ "http://factorcode.org/dlls/"
+ target-cpu get "x86.64" = [ "64/" append ] when
+ [ "freetype6.dll" append ]
+ [ "zlib1.dll" append ] bi
+ [ download ] bi@
+ ] when ;
: make-vm ( -- )
"factor" [
+ download-dlls
+
<process>
make-cmd >>command
"../compile-log" >>stdout
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel io parser lexer words namespaces quotations arrays assocs sequences
- splitting grouping math generalizations ;
-
-IN: mortar
-
-! class { name slots methods class-methods }
-
-: class-name ( class -- name ) dup symbol? [ get ] when first ;
-
-: class-slots ( class -- slots ) dup symbol? [ get ] when second ;
-
-: class-methods ( class -- methods ) dup symbol? [ get ] when third ;
-
-: class-class-methods ( class -- methods ) dup symbol? [ get ] when fourth ;
-
-: class? ( thing -- ? )
-dup array?
-[ dup length 4 = [ first symbol? ] [ drop f ] if ]
-[ drop f ]
-if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: add-method ( class name quot -- )
-rot get class-methods peek swapd set-at ;
-
-: add-class-method ( class name quot -- )
-rot get class-class-methods peek swapd set-at ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! object { class values }
-
-: object-class ( object -- class ) first ;
-
-: object-values ( object -- values ) second ;
-
-: object? ( thing -- ? )
-dup array?
-[ dup length 2 = [ first class? ] [ drop f ] if ]
-[ drop f ]
-if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: is? ( object class -- ? ) swap object-class class-name = ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: new ( class -- object )
-get dup >r class-slots length narray r> swap 2array ;
-
-: new-empty ( class -- object )
-get dup >r class-slots length f <array> r> swap 2array ;
-
-! : new* ( class -- object ) new-empty <- init ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: slot-value ( object slot -- value )
-over object-class class-slots index swap object-values nth ;
-
-: set-slot-value ( object slot value -- object )
-swap pick object-class class-slots index pick object-values set-nth ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! : send-message ( object message -- )
-! over object-class class-methods assoc-stack call ;
-
-: send-message ( object message -- )
-2dup swap object-class class-methods assoc-stack dup
-[ nip call ]
-! [ drop nip "message not understood: " write print flush ]
-[ drop "message not understood: " write print drop ]
-if ;
-
-: <- scan parsed \ send-message parsed ; parsing
-
-! : send-message* ( message n -- )
-! 1+ npick object-class class-methods assoc-stack call ;
-
-: send-message* ( message n -- )
-1+ npick dupd object-class class-methods assoc-stack dup
-[ nip call ]
-[ drop "message not understood: " write print flush ]
-if ;
-
-: <-- scan parsed 2 parsed \ send-message* parsed ; parsing
-
-: <--- scan parsed 3 parsed \ send-message* parsed ; parsing
-
-: <---- scan parsed 4 parsed \ send-message* parsed ; parsing
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: send-message-to-class ( class message -- )
-over class-class-methods assoc-stack call ;
-
-: <<- scan parsed \ send-message-to-class parsed ; parsing
-
-: send-message-to-class* ( message n -- )
-1+ npick class-class-methods assoc-stack call ;
-
-: <<-- scan parsed 2 parsed \ send-message-to-class* parsed ; parsing
-
-: <<--- scan parsed 3 parsed \ send-message-to-class* parsed ; parsing
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: send-message-next ( object message -- )
-over object-class class-methods but-last assoc-stack call ;
-
-: <-~ scan parsed \ send-message-next parsed ; parsing
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! : new* ( class -- object ) <<- create ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-IN: slot-accessors
-
-IN: mortar
-
-! : generate-slot-getter ( name -- )
-! "$" over append "slot-accessors" create swap [ slot-value ] curry
-! define-compound ;
-
-: generate-slot-getter ( name -- )
-"$" over append "slot-accessors" create swap [ slot-value ] curry define ;
-
-! : generate-slot-setter ( name -- )
-! ">>" over append "slot-accessors" create swap [ swap set-slot-value ] curry
-! define-compound ;
-
-: generate-slot-setter ( name -- )
-">>" over append "slot-accessors" create swap [ swap set-slot-value ] curry
-define ;
-
-: generate-slot-accessors ( name -- )
-dup
-generate-slot-getter
-generate-slot-setter ;
-
-: accessors ( seq -- seq ) dup peek [ generate-slot-accessors ] each ; parsing
-
-! : slots:
-! ";" parse-tokens dup [ generate-slot-accessors ] each parsed ; parsing
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! : <symbol> ( string -- symbol ) in get create dup define-symbol ;
-
-: empty-method-table ( -- array ) H{ } clone 1array ;
-
-! : define-simple-class ( name parent slots -- )
-! >r >r <symbol>
-! r> dup class-slots r> append
-! swap dup class-methods empty-method-table append
-! swap class-class-methods empty-method-table append
-! 4array dup first set-global ;
-
-: define-simple-class ( name parent slots -- )
->r dup class-slots r> append
-swap dup class-methods empty-method-table append
-swap class-class-methods empty-method-table append
-4array dup first set-global ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: define-independent-class ( name slots -- )
-empty-method-table empty-method-table 4array dup first set-global ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: add-methods ( class seq -- ) 2 group [ first2 add-method ] with each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: !( ")" parse-tokens drop ; parsing
\ No newline at end of file
+++ /dev/null
-
-USING: mortar ;
-
-IN: mortar.sugar
-
-: new* ( class -- object ) <<- create ;
\ No newline at end of file
+++ /dev/null
-extensions
+++ /dev/null
-Chris Double
+++ /dev/null
-! Copyright (C) 2007 Chris Double.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: help.syntax help.markup threads ;\r
-\r
-IN: odbc\r
-\r
-HELP: odbc-init \r
-{ $values { "env" "an ODBC environment handle" } } \r
-{ $description \r
- "Initializes the ODBC driver manager and returns the " \r
- "environment handle required by " { $link odbc-connect } "."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-connect \r
-{ $values { "env" "an ODBC environment handle" } { "dsn" "a string" } { "dbc" "an ODBC database connection handle" } } \r
-{ $description \r
- "Connects to the database identified by the ODBC data source name (DSN). " \r
- "The environment handle is usually obtained by a call to " { $link odbc-init } ". The result is the ODBC connection handle which can be used in other ODBC calls. When finished with the connection handle " { $link odbc-disconnect } " must be called on it."\r
-} \r
-{ $examples { $code "dbc get \"DSN=mydsn\" odbc-connect" } }\r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-disconnect \r
-{ $values { "dbc" "an ODBC database connection handle" } } \r
-{ $description \r
- "Disconnects from the given database." \r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-prepare\r
-{ $values { "dbc" "an ODBC database connection handle" } { "string" "a string containing SQL" } { "statement" "an ODBC statement handle" } } \r
-{ $description \r
- "Prepares (precompiles) the given SQL string, ready for execution with " { $link odbc-execute } ". When finished with the statement " { $link odbc-free-statement } " must be called on it." \r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-free-statement\r
-{ $values { "statement" "an ODBC statement handle" } } \r
-{ $description \r
- "Closes the statement handle and frees up all resources associated with it." \r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-execute\r
-{ $values { "statement" "an ODBC statement handle" } } \r
-{ $description \r
- "Executes the statement. Once this is done " { $link odbc-next-row } " can be called to retrieve rows." \r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-next-row\r
-{ $values { "statement" "an ODBC statement handle" } { "bool" "a boolean indicating success or failure" } } \r
-{ $description \r
- "Retrieves the next available row from the database. If no next row is available then " { $link f } " is returned. Once the row is retrieved " { $link odbc-number-of-columns } ", " { $link odbc-describe-column } ", " { $link odbc-get-field } " and " { $link odbc-get-row-fields } " can be used to query the data retrieved." \r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-number-of-columns\r
-{ $values { "statement" "an ODBC statement handle" } { "number" "a number" } } \r
-{ $description \r
- "Returns the number of columns of data retrieved."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-describe-column\r
-{ $values { "statement" "an ODBC statement handle" } { "n" "a column number starting from one" } { "column" "a column object" } } \r
-{ $description \r
- "Retrieves column information for the given column number from the statement. The column number must be one or greater. The " { $link <column> } " object returned provides data type, name, etc."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-get-field\r
-{ $values { "statement" "an ODBC statement handle" } { "column" "a column number starting from one or a <column> object" } { "field" "a <field> object" } } \r
-{ $description \r
- "Returns a field object which contains the data for the field in the given column in the current row. The column can be identified by a number or a <column> object. The datatype of the contents of the field depends on the type of the column itself. Note that this word can only be safely called once on each column in a given row with most ODBC drivers. Subsequent calls on the same row for the same column can fail."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-get-row-fields\r
-{ $values { "statement" "an ODBC statement handle" } { "seq" "a sequence" } } \r
-{ $description \r
- "Returns a sequence of all field data for the current row. Note that this isnot the <field> objects, but the data for that field. This word can only be called once on a given row. Subsequent calls on the same row may fail on some ODBC drivers."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-get-all-rows\r
-{ $values { "statement" "an ODBC statement handle" } { "seq" "a sequence" } } \r
-{ $description \r
- "Returns a sequence of all rows available from the statement. Effectively it is the contents of the entire query so may take some time and memory. Each element of the sequence is itself a sequence containing the data for that row. A " { $link yield } " is performed an various intervals so as to not lock up the Factor instance while it is running."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
-\r
-HELP: odbc-query\r
-{ $values { "string" "a string containing SQL" } { "dsn" "a DSN string" } { "result" "a sequence" } } \r
-{ $description \r
- "This word initializes odbc, connects to the database with the given DSN, executes the query string and returns the result as a sequence. It cleans up all resources it uses. It is an inefficient way of running multiple queries but is useful for the occasional query, testing at the REPL, or as an example of how to do it."\r
-} \r
-{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+++ /dev/null
-! Copyright (C) 2007 Chris Double.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel alien alien.strings alien.syntax
-combinators alien.c-types strings sequences namespaces make
-words math threads io.encodings.ascii ;
-IN: odbc
-
-<< "odbc" "odbc32.dll" "stdcall" add-library >>
-
-LIBRARY: odbc
-
-TYPEDEF: void* usb_dev_handle*
-TYPEDEF: short SQLRETURN
-TYPEDEF: short SQLSMALLINT
-TYPEDEF: short* SQLSMALLINT*
-TYPEDEF: ushort SQLUSMALLINT
-TYPEDEF: uint* SQLUINTEGER*
-TYPEDEF: int SQLINTEGER
-TYPEDEF: char SQLCHAR
-TYPEDEF: char* SQLCHAR*
-TYPEDEF: void* SQLHANDLE
-TYPEDEF: void* SQLHANDLE*
-TYPEDEF: void* SQLHENV
-TYPEDEF: void* SQLHDBC
-TYPEDEF: void* SQLHSTMT
-TYPEDEF: void* SQLHWND
-TYPEDEF: void* SQLPOINTER
-
-: SQL-HANDLE-ENV ( -- number ) 1 ; inline
-: SQL-HANDLE-DBC ( -- number ) 2 ; inline
-: SQL-HANDLE-STMT ( -- number ) 3 ; inline
-: SQL-HANDLE-DESC ( -- number ) 4 ; inline
-
-: SQL-NULL-HANDLE ( -- alien ) f ; inline
-
-: SQL-ATTR-ODBC-VERSION ( -- number ) 200 ; inline
-
-: SQL-OV-ODBC2 ( -- number ) 2 <alien> ; inline
-: SQL-OV-ODBC3 ( -- number ) 3 <alien> ; inline
-
-: SQL-SUCCESS ( -- number ) 0 ; inline
-: SQL-SUCCESS-WITH-INFO ( -- number ) 1 ; inline
-: SQL-NO-DATA-FOUND ( -- number ) 100 ; inline
-
-: SQL-DRIVER-NOPROMPT ( -- number ) 0 ; inline
-: SQL-DRIVER-PROMPT ( -- number ) 2 ; inline
-
-: SQL-C-DEFAULT ( -- number ) 99 ; inline
-
-SYMBOL: SQL-CHAR
-SYMBOL: SQL-VARCHAR
-SYMBOL: SQL-LONGVARCHAR
-SYMBOL: SQL-WCHAR
-SYMBOL: SQL-WCHARVAR
-SYMBOL: SQL-WLONGCHARVAR
-SYMBOL: SQL-DECIMAL
-SYMBOL: SQL-SMALLINT
-SYMBOL: SQL-NUMERIC
-SYMBOL: SQL-INTEGER
-SYMBOL: SQL-REAL
-SYMBOL: SQL-FLOAT
-SYMBOL: SQL-DOUBLE
-SYMBOL: SQL-BIT
-SYMBOL: SQL-TINYINT
-SYMBOL: SQL-BIGINT
-SYMBOL: SQL-BINARY
-SYMBOL: SQL-VARBINARY
-SYMBOL: SQL-LONGVARBINARY
-SYMBOL: SQL-TYPE-DATE
-SYMBOL: SQL-TYPE-TIME
-SYMBOL: SQL-TYPE-TIMESTAMP
-SYMBOL: SQL-TYPE-UTCDATETIME
-SYMBOL: SQL-TYPE-UTCTIME
-SYMBOL: SQL-INTERVAL-MONTH
-SYMBOL: SQL-INTERVAL-YEAR
-SYMBOL: SQL-INTERVAL-YEAR-TO-MONTH
-SYMBOL: SQL-INTERVAL-DAY
-SYMBOL: SQL-INTERVAL-HOUR
-SYMBOL: SQL-INTERVAL-MINUTE
-SYMBOL: SQL-INTERVAL-SECOND
-SYMBOL: SQL-INTERVAL-DAY-TO-HOUR
-SYMBOL: SQL-INTERVAL-DAY-TO-MINUTE
-SYMBOL: SQL-INTERVAL-DAY-TO-SECOND
-SYMBOL: SQL-INTERVAL-HOUR-TO-MINUTE
-SYMBOL: SQL-INTERVAL-HOUR-TO-SECOND
-SYMBOL: SQL-INTERVAL-MINUTE-TO-SECOND
-SYMBOL: SQL-GUID
-SYMBOL: SQL-TYPE-UNKNOWN
-
-: convert-sql-type ( number -- symbol )
- {
- { 1 [ SQL-CHAR ] }
- { 12 [ SQL-VARCHAR ] }
- { -1 [ SQL-LONGVARCHAR ] }
- { -8 [ SQL-WCHAR ] }
- { -9 [ SQL-WCHARVAR ] }
- { -10 [ SQL-WLONGCHARVAR ] }
- { 3 [ SQL-DECIMAL ] }
- { 5 [ SQL-SMALLINT ] }
- { 2 [ SQL-NUMERIC ] }
- { 4 [ SQL-INTEGER ] }
- { 7 [ SQL-REAL ] }
- { 6 [ SQL-FLOAT ] }
- { 8 [ SQL-DOUBLE ] }
- { -7 [ SQL-BIT ] }
- { -6 [ SQL-TINYINT ] }
- { -5 [ SQL-BIGINT ] }
- { -2 [ SQL-BINARY ] }
- { -3 [ SQL-VARBINARY ] }
- { -4 [ SQL-LONGVARBINARY ] }
- { 91 [ SQL-TYPE-DATE ] }
- { 92 [ SQL-TYPE-TIME ] }
- { 93 [ SQL-TYPE-TIMESTAMP ] }
- [ drop SQL-TYPE-UNKNOWN ]
- } case ;
-
-: succeeded? ( n -- bool )
- #! Did the call succeed (SQL-SUCCESS or SQL-SUCCESS-WITH-INFO)
- {
- { SQL-SUCCESS [ t ] }
- { SQL-SUCCESS-WITH-INFO [ t ] }
- [ drop f ]
- } case ;
-
-FUNCTION: SQLRETURN SQLAllocHandle ( SQLSMALLINT handleType, SQLHANDLE inputHandle, SQLHANDLE* outputHandlePtr ) ;
-FUNCTION: SQLRETURN SQLSetEnvAttr ( SQLHENV environmentHandle, SQLINTEGER attribute, SQLPOINTER valuePtr, SQLINTEGER stringLength ) ;
-FUNCTION: SQLRETURN SQLDriverConnect ( SQLHDBC connectionHandle, SQLHWND windowHandle, SQLCHAR* inConnectionString, SQLSMALLINT stringLength, SQLCHAR* outConnectionString, SQLSMALLINT bufferLength, SQLSMALLINT* stringLength2Ptr, SQLUSMALLINT driverCompletion ) ;
-FUNCTION: SQLRETURN SQLDisconnect ( SQLHDBC connectionHandle ) ;
-FUNCTION: SQLRETURN SQLPrepare ( SQLHSTMT statementHandle, SQLCHAR* statementText, SQLINTEGER length ) ;
-FUNCTION: SQLRETURN SQLExecute ( SQLHSTMT statementHandle ) ;
-FUNCTION: SQLRETURN SQLFreeHandle ( SQLSMALLINT handleType, SQLHANDLE handle ) ;
-FUNCTION: SQLRETURN SQLFetch ( SQLHSTMT statementHandle ) ;
-FUNCTION: SQLRETURN SQLNumResultCols ( SQLHSTMT statementHandle, SQLSMALLINT* columnCountPtr ) ;
-FUNCTION: SQLRETURN SQLDescribeCol ( SQLHSTMT statementHandle, SQLSMALLINT columnNumber, SQLCHAR* columnName, SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr, SQLUINTEGER* columnSizePtr, SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr ) ;
-FUNCTION: SQLRETURN SQLGetData ( SQLHSTMT statementHandle, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValuePtr, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_indPtr ) ;
-
-: alloc-handle ( type parent -- handle )
- f <void*> [ SQLAllocHandle ] keep swap succeeded? [
- *void*
- ] [
- drop f
- ] if ;
-
-: alloc-env-handle ( -- handle )
- SQL-HANDLE-ENV SQL-NULL-HANDLE alloc-handle ;
-
-: alloc-dbc-handle ( env -- handle )
- SQL-HANDLE-DBC swap alloc-handle ;
-
-: alloc-stmt-handle ( dbc -- handle )
- SQL-HANDLE-STMT swap alloc-handle ;
-
-: temp-string ( length -- byte-array length )
- [ CHAR: \space <string> ascii string>alien ] keep ;
-
-: odbc-init ( -- env )
- alloc-env-handle
- [
- SQL-ATTR-ODBC-VERSION SQL-OV-ODBC3 0 SQLSetEnvAttr
- succeeded? [ "odbc-init failed" throw ] unless
- ] keep ;
-
-: odbc-connect ( env dsn -- dbc )
- >r alloc-dbc-handle dup r>
- f swap dup length 1024 temp-string 0 <short> SQL-DRIVER-NOPROMPT
- SQLDriverConnect succeeded? [ "odbc-connect failed" throw ] unless ;
-
-: odbc-disconnect ( dbc -- )
- SQLDisconnect succeeded? [ "odbc-disconnect failed" throw ] unless ;
-
-: odbc-prepare ( dbc string -- statement )
- >r alloc-stmt-handle dup r> dup length SQLPrepare succeeded? [ "odbc-prepare failed" throw ] unless ;
-
-: odbc-free-statement ( statement -- )
- SQL-HANDLE-STMT swap SQLFreeHandle succeeded? [ "odbc-free-statement failed" throw ] unless ;
-
-: odbc-execute ( statement -- )
- SQLExecute succeeded? [ "odbc-execute failed" throw ] unless ;
-
-: odbc-next-row ( statement -- bool )
- SQLFetch succeeded? ;
-
-: odbc-number-of-columns ( statement -- number )
- 0 <short> [ SQLNumResultCols succeeded? ] keep swap [
- *short
- ] [
- drop f
- ] if ;
-
-TUPLE: column nullable digits size type name number ;
-
-C: <column> column
-
-: odbc-describe-column ( statement n -- column )
- dup >r
- 1024 CHAR: \space <string> ascii string>alien dup >r
- 1024
- 0 <short>
- 0 <short> dup >r
- 0 <uint> dup >r
- 0 <short> dup >r
- 0 <short> dup >r
- SQLDescribeCol succeeded? [
- r> *short
- r> *short
- r> *uint
- r> *short convert-sql-type
- r> ascii alien>string
- r> <column>
- ] [
- r> drop r> drop r> drop r> drop r> drop r> drop
- "odbc-describe-column failed" throw
- ] if ;
-
-: dereference-type-pointer ( byte-array column -- object )
- type>> {
- { SQL-CHAR [ ascii alien>string ] }
- { SQL-VARCHAR [ ascii alien>string ] }
- { SQL-LONGVARCHAR [ ascii alien>string ] }
- { SQL-WCHAR [ ascii alien>string ] }
- { SQL-WCHARVAR [ ascii alien>string ] }
- { SQL-WLONGCHARVAR [ ascii alien>string ] }
- { SQL-SMALLINT [ *short ] }
- { SQL-INTEGER [ *long ] }
- { SQL-REAL [ *float ] }
- { SQL-FLOAT [ *double ] }
- { SQL-DOUBLE [ *double ] }
- { SQL-TINYINT [ *char ] }
- { SQL-BIGINT [ *longlong ] }
- [ nip [ "Unknown SQL Type: " % name>> % ] "" make ]
- } case ;
-
-TUPLE: field value column ;
-
-C: <field> field
-
-: odbc-get-field ( statement column -- field )
- dup column? [ dupd odbc-describe-column ] unless dup >r number>>
- SQL-C-DEFAULT
- 8192 CHAR: \space <string> ascii string>alien dup >r
- 8192
- f SQLGetData succeeded? [
- r> r> [ dereference-type-pointer ] keep <field>
- ] [
- r> drop r> [
- "SQLGetData Failed for Column: " %
- dup name>> %
- " of type: " % dup type>> name>> %
- ] "" make swap <field>
- ] if ;
-
-: odbc-get-row-fields ( statement -- seq )
- [
- dup odbc-number-of-columns [
- 1+ odbc-get-field value>> ,
- ] with each
- ] { } make ;
-
-: (odbc-get-all-rows) ( statement -- )
- dup odbc-next-row [ dup odbc-get-row-fields , yield (odbc-get-all-rows) ] [ drop ] if ;
-
-: odbc-get-all-rows ( statement -- seq )
- [ (odbc-get-all-rows) ] { } make ;
-
-: odbc-query ( string dsn -- result )
- odbc-init swap odbc-connect [
- swap odbc-prepare
- dup odbc-execute
- dup odbc-get-all-rows
- swap odbc-free-statement
- ] keep odbc-disconnect ;
+++ /dev/null
-ODBC (Open DataBase Connectivity) binding
opengl
-glsl
bindings
\ No newline at end of file
text
javascript
parsing
+languages
text
javascript
parsing
+languages
text
javascript
parsing
+languages
text
javascript
parsing
+languages
+++ /dev/null
-
-USING: kernel sequences math math.order
- ui.gadgets ui.gadgets.tracks ui.gestures
- bake.fry accessors ;
-
-IN: ui.gadgets.tiling
-
-TUPLE: tiling < track gadgets tiles first focused ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: init-tiling ( tiling -- tiling )
- init-track
- { 1 0 } >>orientation
- V{ } clone >>gadgets
- 2 >>tiles
- 0 >>first
- 0 >>focused ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: <tiling> ( -- gadget ) tiling new init-tiling ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: bounded-subseq ( seq a b -- seq )
- [ 0 max ] dip
- pick length [ min ] curry bi@
- rot
- subseq ;
-
-: tiling-gadgets-to-map ( tiling -- gadgets )
- [ gadgets>> ]
- [ first>> ]
- [ [ first>> ] [ tiles>> ] bi + ]
- tri
- bounded-subseq ;
-
-: tiling-map-gadgets ( tiling -- tiling )
- dup clear-track
- dup tiling-gadgets-to-map [ 1 track-add ] each ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: tiling-add ( tiling gadget -- tiling )
- over gadgets>> push
- tiling-map-gadgets ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: first-gadget ( tiling -- index ) drop 0 ;
-
-: last-gadget ( tiling -- index ) gadgets>> length 1 - ;
-
-: first-viewable ( tiling -- index ) first>> ;
-
-: last-viewable ( tiling -- index ) [ first>> ] [ tiles>> ] bi + 1 - ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: make-focused-mapped ( tiling -- tiling )
-
- dup [ focused>> ] [ first>> ] bi <
- [ dup first>> 1 - >>first ]
- [ ]
- if
-
- dup [ last-viewable ] [ focused>> ] bi <
- [ dup first>> 1 + >>first ]
- [ ]
- if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: check-focused-bounds ( tiling -- tiling )
- dup focused>> 0 max over gadgets>> length 1 - min >>focused ;
-
-: focus-prev ( tiling -- tiling )
- dup focused>> 1 - >>focused
- check-focused-bounds
- make-focused-mapped
- tiling-map-gadgets
- dup request-focus ;
-
-: focus-next ( tiling -- tiling )
- dup focused>> 1 + >>focused
- check-focused-bounds
- make-focused-mapped
- tiling-map-gadgets
- dup request-focus ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: exchanged! ( seq a b -- )
- [ 0 max ] bi@
- pick length 1 - '[ _ min ] bi@
- rot exchange ;
-
-: move-prev ( tiling -- tiling )
- dup [ gadgets>> ] [ focused>> 1 - ] [ focused>> ] tri exchanged!
- focus-prev ;
-
-: move-next ( tiling -- tiling )
- dup [ gadgets>> ] [ focused>> ] [ focused>> 1 + ] tri exchanged!
- focus-next ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: add-tile ( tiling -- tiling )
- dup tiles>> 1 + >>tiles
- tiling-map-gadgets ;
-
-: del-tile ( tiling -- tiling )
- dup tiles>> 1 - 1 max >>tiles
- tiling-map-gadgets ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-M: tiling focusable-child* ( tiling -- child/t )
- [ focused>> ] [ gadgets>> ] bi nth ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: tiling-shelf < tiling ;
-TUPLE: tiling-pile < tiling ;
-
-: <tiling-shelf> ( -- gadget )
- tiling-shelf new init-tiling { 1 0 } >>orientation ;
-
-: <tiling-pile> ( -- gadget )
- tiling-pile new init-tiling { 0 1 } >>orientation ;
-
-tiling-shelf
- H{
- { T{ key-down f { A+ } "LEFT" } [ focus-prev drop ] }
- { T{ key-down f { A+ } "RIGHT" } [ focus-next drop ] }
- { T{ key-down f { S+ A+ } "LEFT" } [ move-prev drop ] }
- { T{ key-down f { S+ A+ } "RIGHT" } [ move-next drop ] }
- { T{ key-down f { C+ } "[" } [ del-tile drop ] }
- { T{ key-down f { C+ } "]" } [ add-tile drop ] }
- }
-set-gestures
-
-tiling-pile
- H{
- { T{ key-down f { A+ } "UP" } [ focus-prev drop ] }
- { T{ key-down f { A+ } "DOWN" } [ focus-next drop ] }
- { T{ key-down f { S+ A+ } "UP" } [ move-prev drop ] }
- { T{ key-down f { S+ A+ } "DOWN" } [ move-next drop ] }
- { T{ key-down f { C+ } "[" } [ del-tile drop ] }
- { T{ key-down f { C+ } "]" } [ add-tile drop ] }
- }
-set-gestures
{ "search" [ 1 v-min-length 50 v-max-length v-one-line ] }
} validate-params
- help-dir set-current-directory
-
- "search" value article-apropos "articles" set-value
- "search" value word-apropos "words" set-value
- "search" value vocab-apropos "vocabs" set-value
+ help-dir [
+ "search" value article-apropos "articles" set-value
+ "search" value word-apropos "words" set-value
+ "search" value vocab-apropos "vocabs" set-value
+ ] with-directory
{ help-webapp "search" } <chloe-content>
] >>submit ;
<t:form t:action="$help-webapp/search">
<t:field t:name="search" />
- <button>Search</button>
+ <button type="submit">Search</button>
</t:form>
<t:if t:value="articles">
</tr>
</table>
- <p> <button>Submit</button> </p>
+ <p> <button type="submit">Submit</button> </p>
</t:form>
</t:chloe>
</tr>
</table>
- <p> <button>Done</button> </p>
+ <p> <button type="submit">Done</button> </p>
</t:form>
<t:form t:action="$wee-url">
<p>Shorten URL: <t:field t:name="url" t:size="40" /></p>
- <button>Shorten</button>
+ <button type="submit">Shorten</button>
</t:form>
</t:chloe>
</p>
<p>
- <button>Save</button>
+ <button type="submit">Save</button>
</p>
</t:form>
</tr>
</table>
- <button>View</button>
+ <button type="submit">View</button>
</t:form>
</t:chloe>
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces arrays sequences math x11.xlib
- mortar slot-accessors x ;
-
-IN: x.font
-
-SYMBOL: <font>
-
-<font> { "dpy" "name" "id" "struct" } accessors define-independent-class
-
-<font> "create" !( name <font> -- font ) [
-new-empty swap >>name dpy get >>dpy
-dpy get $ptr over $name XLoadQueryFont >>struct
-dup $struct XFontStruct-fid >>id
-] add-class-method
-
-<font> {
-
-"ascent" !( font -- ascent ) [ $struct XFontStruct-ascent ]
-
-"descent" !( font -- ascent ) [ $struct XFontStruct-descent ]
-
-"height" !( font -- ascent ) [ dup <- ascent swap <- descent + ]
-
-"text-width" !( font string -- width ) [ >r $struct r> dup length XTextWidth ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces arrays x11.xlib mortar mortar.sugar
- slot-accessors x x.font ;
-
-IN: x.gc
-
-SYMBOL: <gc>
-
-<gc> { "dpy" "ptr" "font" } accessors define-independent-class
-
-<gc> "create" !( <gc> -- gc ) [
-new-empty dpy get >>dpy
-dpy get $ptr dpy get $default-root $id 0 f XCreateGC >>ptr
-"6x13" <font> new* >>font
-] add-class-method
-
-<gc> {
-
-"set-subwindow-mode" !( gc mode -- gc )
- [ >r dup $dpy $ptr over $ptr r> XSetSubwindowMode drop ]
-
-"set-function" !( gc function -- gc )
- [ >r dup $dpy $ptr over $ptr r> XSetFunction drop ]
-
-"set-foreground" !( gc foreground -- gc )
- [ >r dup $dpy $ptr over $ptr r> lookup-color XSetForeground drop ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-USING: kernel strings assocs sequences math ;
-
-IN: x.keysym-table
-
-: keysym-table ( -- table )
-H{ { HEX: FF08 "BACKSPACE" }
- { HEX: FF09 "TAB" }
- { HEX: FF0D "RETURN" }
- { HEX: FF8D "ENTER" }
- { HEX: FF1B "ESCAPE" }
- { HEX: FFFF "DELETE" }
- { HEX: FF50 "HOME" }
- { HEX: FF51 "LEFT" }
- { HEX: FF52 "UP" }
- { HEX: FF53 "RIGHT" }
- { HEX: FF54 "DOWN" }
- { HEX: FF55 "PAGE-UP" }
- { HEX: FF56 "PAGE-DOWN" }
- { HEX: FF57 "END" }
- { HEX: FF58 "BEGIN" }
- { HEX: FFBE "F1" }
- { HEX: FFBF "F2" }
- { HEX: FFC0 "F3" }
- { HEX: FFC1 "F4" }
- { HEX: FFC2 "F5" }
- { HEX: FFC3 "F6" }
- { HEX: FFC4 "F7" }
- { HEX: FFC5 "F8" }
- { HEX: FFC6 "F9" }
- { HEX: FFC7 "F10" }
- { HEX: FFC8 "F11" }
- { HEX: FFC9 "F12" }
- { HEX: FFE1 "LEFT-SHIFT" }
- { HEX: FFE2 "RIGHT-SHIFT" }
- { HEX: FFE3 "LEFT-CONTROL" }
- { HEX: FFE4 "RIGHT-CONTROL" }
- { HEX: FFE5 "CAPSLOCK" }
- { HEX: FFE9 "LEFT-ALT" }
- { HEX: FFEA "RIGHT-ALT" }
-} ;
-
-: keysym>name ( keysym -- name )
-dup keysym-table at dup [ nip ] [ drop 1string ] if ;
-
-: name>keysym ( name -- keysym ) keysym-table value-at ;
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel arrays math.vectors mortar mortar.sugar x.gc slot-accessors geom.pos ;
-
-IN: x.pen
-
-SYMBOL: <pen>
-
-<pen> <pos> { "window" "gc" } accessors define-simple-class
-
-<pen> "create" !( window <pen> -- pen )
-[ new-empty swap >>window <gc> new* >>gc 0 0 2array >>pos ]
-add-class-method
-
-<pen> {
-
-"line-to" ! ( pen point -- pen )
- [ 2dup >r dup $window swap dup $gc swap $pos r> <---- draw-line >>pos ]
-
-"line-by" ! ( pen offset -- pen )
- [ 2dup >r dup $window swap dup $gc swap $pos dup r> v+ <---- draw-line
- <-- move-by ]
-
-"draw-string" ! ( pen string -- pen )
- [ >r dup dup $window swap dup $gc swap $pos r> <---- draw-string ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel combinators math x11.xlib
- mortar mortar.sugar slot-accessors x.gc x.widgets.label ;
-
-IN: x.widgets.button
-
-SYMBOL: <button>
-
-<button>
- <label>
- { "action-1" "action-2" "action-3" } accessors
-define-simple-class
-
-<button> "create" !( <button> -- button ) [
-new-empty
-<gc> new* >>gc ExposureMask ButtonPressMask bitor >>mask <- init-widget
-] add-class-method
-
-<button> "handle-button-press" !( event button -- ) [
-{ { [ over XButtonEvent-button Button1 = ] [ nip $action-1 call ] }
- { [ over XButtonEvent-button Button2 = ] [ nip $action-2 call ] }
- { [ over XButtonEvent-button Button3 = ] [ nip $action-3 call ] } }
-cond
-] add-method
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel strings arrays sequences sequences.lib math x11.xlib
- mortar mortar.sugar slot-accessors x x.pen x.widgets ;
-
-IN: x.widgets.keymenu
-
-SYMBOL: <keymenu>
-
-<keymenu> <widget> { "items" "pen" } accessors define-simple-class
-
-<keymenu> "create" !( <keymenu> -- keymenu )
- [ new-empty <- keymenu-init ]
-add-class-method
-
-: numbers-and-letters ( -- seq )
-"1234567890abcdefghijklmnopqrstuvwxyz" [ 1string ] { } map-as ;
-
-<keymenu> {
-
-"keymenu-init" !( keymenu -- keymenu ) [
- dup <pen> new* >>pen
- ExposureMask KeyPressMask bitor >>mask
- <- init-widget
-]
-
-"item-labels" !( keymenu -- labels ) [ $items [ first ] map ]
-
-"item-actions" !( keymenu -- actions ) [ $items [ second ] map ]
-
-"keymenu-labels" !( keymenu -- seq )
-[ numbers-and-letters swap <- item-labels [ " - " swap 3append ] 2map ]
-
-"reset-pen" !( keymenu -- keymenu ) [
- dup $pen
- 1 <-- set-x
- dup $gc $font <- ascent 1+ <-- set-y
- drop ]
-
-"handle-expose" !( event keymenu -- ) [
- nip
- <- reset-pen
- dup $pen swap <- keymenu-labels
- [ <-- draw-string dup $gc $font <- height <-- move-by-y ] each drop ]
-
-"keymenu-handle-key-press" !( event keymenu -- ) [
- swap 0 key-event-to-string numbers-and-letters index
- [ swap <- item-actions ?nth [ call ] when* ]
- [ drop ]
- if* ]
-
-"handle-key-press" !( event keymenu -- ) [ <- keymenu-handle-key-press ]
-
-"calc-height" !( keymenu -- height )
- [ dup $items length swap $pen $gc $font <- height * ]
-
-"calc-width" !( keymenu -- width )
- [ dup $pen $gc $font
- swap $items [ first " " append ] map
- dup empty? [ drop "" ] [ longest ] if
- <-- text-width ]
-
-"calc-size" !( keymenu -- size )
- [ dup <- calc-width swap <- calc-height 2array ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel x11.xlib mortar mortar.sugar slot-accessors x.gc x.widgets ;
-
-IN: x.widgets.label
-
-SYMBOL: <label>
-
-<label> <widget> { "gc" "text" } accessors define-simple-class
-
-<label> "create" !( text <label> -- label ) [
-new-empty swap >>text <gc> new* >>gc ExposureMask >>mask <- init-widget
-] add-class-method
-
-<label> "handle-expose" !( event label -- ) [
- nip <- clear dup $gc { 20 20 } pick $text <---- draw-string
-] add-method
+++ /dev/null
-
-USING: kernel io namespaces arrays sequences combinators math x11.xlib
- mortar slot-accessors x ;
-
-IN: x.widgets
-
-SYMBOL: <widget>
-
-<widget> <window> { "mask" } accessors define-simple-class
-
-<widget> {
-
-"init-widget" !( widget -- widget )
- [ <- init-window <- add-to-window-table dup $mask <-- select-input ]
-
-"add-to-window-table" !( window -- window )
- [ dup $dpy over <-- add-to-window-table ]
-
-"remove-from-window-table" !( window -- window )
- [ dup $dpy over <-- remove-from-window-table ]
-
-"handle-event" !( event widget -- ) [
- over XAnyEvent-type
- { { [ dup Expose = ] [ drop <- handle-expose ] }
- { [ dup KeyPress = ] [ drop <- handle-key-press ] }
- { [ dup ButtonPress = ] [ drop <- handle-button-press ] }
- { [ dup EnterNotify = ] [ drop <- handle-enter-window ] }
- { [ dup DestroyNotify = ] [ drop <- handle-destroy-window ] }
- { [ dup MapRequest = ] [ drop <- handle-map-request ] }
- { [ dup MapNotify = ] [ drop <- handle-map ] }
- { [ dup ConfigureRequest = ] [ drop <- handle-configure-request ] }
- { [ dup UnmapNotify = ] [ drop <- handle-unmap ] }
- { [ dup PropertyNotify = ] [ drop <- handle-property ] }
- { [ t ] [ "handle-event :: ignoring event"
- print flush 3drop ] }
- } cond ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel io namespaces arrays sequences
- x11.xlib mortar slot-accessors x x.widgets ;
-
-IN: x.widgets.wm.child
-
-SYMBOL: <wm-child>
-
-<wm-child> <widget> { } define-simple-class
-
-<wm-child> "create" !( id <wm-child> -- wm-child ) [
- new-empty swap >>id dpy get >>dpy PropertyChangeMask >>mask
- <- add-to-save-set
- 0 <-- set-border-width
- <- add-to-window-table
- dup $mask <-- select-input
-] add-class-method
-
-<wm-child> "handle-property" !( event wm-child -- ) [
- drop
- "child handle-property :: atom name = " write
- XPropertyEvent-atom get-atom-name print flush
-] add-method
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces arrays sequences combinators math.vectors
- x11.xlib x11.constants
- mortar slot-accessors x x.gc geom.rect ;
-
-IN: x.widgets.wm.frame.drag
-
-SYMBOL: <wm-frame-drag>
-
-<wm-frame-drag>
- { "dpy" "gc" "frame" "event" "push" "posn" } accessors
-define-independent-class
-
-<wm-frame-drag> {
-
-"next-event" !( wfdm -- wfdm ) [ dup $dpy over $event <-- next-event 2drop ]
-
-"event-type" !( wfdm -- wfdm event-type ) [ dup $event XAnyEvent-type ]
-
-"drag-offset" !( wfdm -- offset ) [ dup $posn swap $push v- ]
-
-"update-posn" !( wfd -- wfd ) [ dup $event XMotionEvent-root-position >>posn ]
-
-} add-methods
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel combinators namespaces math.vectors x11.xlib x11.constants
- mortar mortar.sugar slot-accessors x x.gc x.widgets.wm.frame.drag ;
-
-IN: x.widgets.wm.frame.drag.move
-
-SYMBOL: <wm-frame-drag-move>
-
-<wm-frame-drag-move> <wm-frame-drag> { } define-simple-class
-
-<wm-frame-drag-move> "create" !( event frame <wm-frame-drag-move> -- ) [
- new-empty swap >>frame swap >>event dup $frame $dpy >>dpy
-
- <gc> new*
- IncludeInferiors <-- set-subwindow-mode
- GXxor <-- set-function
- "white" <-- set-foreground
- >>gc
-
- dup $event XButtonEvent-root-position >>push
- dup $event XButtonEvent-root-position >>posn
- <- draw-move-outline
- <- loop
-] add-class-method
-
-<wm-frame-drag-move> {
-
-"move-outline" !( wfdm -- rect )
- [ dup $frame <- as-rect swap <- drag-offset <-- move-by ]
-
-"draw-move-outline" !( wfdm -- wfdm )
- [ dpy get $default-root over $gc pick <- move-outline <--- draw-rect ]
-
-"loop" !( wfdm -- wfdm ) [
- <- next-event
- { { [ <- event-type MotionNotify = ]
- [ <- draw-move-outline <- update-posn <- draw-move-outline <- loop ] }
- { [ <- event-type ButtonRelease = ]
- [ <- draw-move-outline
- dup $frame <- position over <- drag-offset v+ >r
- dup $frame r> <-- move drop
- dup $frame <- raise drop drop ] }
- { [ t ] [ <- loop ] } }
- cond ]
-
-} add-methods
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel combinators namespaces math.vectors x11.xlib x11.constants
- mortar mortar.sugar slot-accessors geom.rect x x.gc x.widgets.wm.frame.drag ;
-
-IN: x.widgets.wm.frame.drag.size
-
-SYMBOL: <wm-frame-drag-size>
-
-<wm-frame-drag-size> <wm-frame-drag> { } define-simple-class
-
-<wm-frame-drag-size> "create" !( event frame <wfds> -- ) [
- new-empty swap >>frame swap >>event
- dup $frame $dpy >>dpy
-
- <gc> new*
- IncludeInferiors <-- set-subwindow-mode
- GXxor <-- set-function
- "white" <-- set-foreground
- >>gc
-
- dup $event XButtonEvent-root-position >>push
- dup $event XButtonEvent-root-position >>posn
- <- draw-size-outline <- loop
-] add-class-method
-
-<wm-frame-drag-size> {
-
-"size-outline" !( wfds -- rect )
- [ dup $frame <- position swap $posn over v- <rect> new ]
-
-"draw-size-outline" !( wfdm -- wfdm )
- [ dup $dpy $default-root over $gc pick <- size-outline <--- draw-rect ]
-
-"loop" !( wfdm -- ) [
- <- next-event
- { { [ <- event-type MotionNotify = ]
- [ <- draw-size-outline <- update-posn <- draw-size-outline <- loop ] }
- { [ <- event-type ButtonRelease = ]
- [ <- draw-size-outline
- dup $frame over $posn pick $frame <- position v- <-- resize
- <- adjust-child drop ] }
- { [ t ] [ <- loop ] } }
- cond ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-
-USING: kernel io combinators namespaces quotations arrays sequences
- math math.vectors
- x11.xlib x11.constants
- mortar mortar.sugar slot-accessors
- geom.rect
- math.bitwise
- x x.gc x.widgets
- x.widgets.button
- x.widgets.wm.child
- x.widgets.wm.frame.drag.move
- x.widgets.wm.frame.drag.size ;
-
-IN: x.widgets.wm.frame
-
-SYMBOL: <wm-frame>
-
-<wm-frame> <widget> { "child" "gc" "last-state" } accessors define-simple-class
-
-<wm-frame> "create" !( id <wm-frame> -- wm-frame ) [
- new-empty
- swap <wm-child> new* >>child
- <gc> new* "white" <-- set-foreground >>gc
-
- {
- SubstructureRedirectMask
- ExposureMask
- ButtonPressMask
- ButtonReleaseMask
- ButtonMotionMask
- EnterWindowMask
- ! experimental masks
- SubstructureNotifyMask
- } flags
- >>mask
-
- <- init-widget
- "cornflowerblue" <-- set-background
- dup $child <- position <-- move
- dup $child over <-- reparent drop
- <- position-child
- <- fit-to-child
- <- make-frame-button
-
- <- map-subwindows
- <- map
-] add-class-method
-
-SYMBOL: WM_PROTOCOLS
-SYMBOL: WM_DELETE_WINDOW
-
-: init-atoms ( -- )
-"WM_PROTOCOLS" 0 intern-atom WM_PROTOCOLS set
-"WM_DELETE_WINDOW" 0 intern-atom WM_DELETE_WINDOW set ;
-
-<wm-frame> {
-
-"fit-to-child" !( wm-frame -- wm-frame )
- [ dup $child <- size { 10 20 } v+ <-- resize ]
-
-"position-child" !( wm-frame -- wm-frame )
- [ dup $child { 5 15 } <-- move drop ]
-
-"set-child-size" !( wm-frame size -- frame )
- [ >r dup $child r> <-- resize drop <- fit-to-child ]
-
-"set-child-width" !( wm-frame width -- frame )
- [ >r dup $child r> <- set-width drop <- fit-to-child ]
-
-"set-child-height" !( wm-frame height -- frame )
- [ >r dup $child r> <- set-height drop <- fit-to-child ]
-
-"adjust-child" !( wm-frame -- wm-frame )
- [ dup $child over <- size { 10 20 } v- <-- resize drop ]
-
-"update-title" !( wm-frame -- wm-frame )
- [ <- clear
- dup >r
- ! dup $gc { 5 1 } pick $child <- fetch-name <--- draw-string/top-left
- dup $gc { 5 11 } pick $child <- fetch-name <---- draw-string
- r> ]
-
-"delete-child" !( wm-frame -- wm-frame ) [
- dup $child WM_PROTOCOLS get WM_DELETE_WINDOW get <--- send-client-message
- drop ]
-
-"drag-move" !( event wm-frame -- ) [ <wm-frame-drag-move> new* ]
-
-"drag-size" !( event wm-frame -- ) [ <wm-frame-drag-size> new* ]
-
-"make-frame-button" !( frame -- frame ) [
-<button> new*
- over <-- reparent
- "" >>text
- over [ <- unmap drop ] curry >>action-1
- over [ <- delete-child drop ] curry >>action-3
- { 9 9 } <-- resize
- NorthEastGravity <-- set-gravity
- "white" <-- set-background
- over <- width 9 - 5 - 3 2array <-- move
- drop ]
-
-! !!!!!!!!!! Event handlers !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-"handle-enter-window" !( event wm-frame -- )
- [ nip $child RevertToPointerRoot CurrentTime <--- set-input-focus drop ]
-
-"handle-expose" !( event wm-frame -- ) [ nip <- clear <- update-title drop ]
-
-"handle-button-press" !( event wm-frame -- ) [
- over XButtonEvent-button
- { { [ dup Button1 = ] [ drop <- drag-move ] }
- { [ dup Button2 = ] [ drop <- drag-size ] }
- { [ t ] [ 3drop ] } }
- cond ]
-
-"handle-map" !( event wm-frame -- )
- [ "<wm-frame> handle-map :: ignoring values" print flush 2drop ]
-
-"handle-unmap" !( event wm-frame -- ) [ nip <- unmap drop ]
-
-"handle-destroy-window" !( event wm-frame -- ) [
- nip dup $child <- remove-from-window-table drop
- <- remove-from-window-table <- destroy ]
-
-"handle-configure-request" !( event frame -- ) [
- { { [ over dup CWX? swap CWY? and ]
- [ over XConfigureRequestEvent-position <-- move ] }
- { [ over CWX? ] [ over XConfigureRequestEvent-x <-- set-x ] }
- { [ over CWY? ] [ over XConfigureRequestEvent-y <-- set-y ] }
- { [ t ] [ "<wm-frame> handle-configure-request :: move not requested"
- print flush ] } }
- cond
-
- { { [ over dup CWWidth? swap CWHeight? and ]
- [ over XConfigureRequestEvent-size <-- set-child-size ] }
- { [ over CWWidth? ]
- [ over XConfigureRequestEvent-width <-- set-child-width ] }
- { [ over CWHeight? ]
- [ over XConfigureRequestEvent-height <-- set-child-height ] }
- { [ t ]
- [ "<wm-frame> handle-configure-request :: resize not requested"
- print flush ] } }
- cond
- 2drop ]
-
-} add-methods
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: wm-frame-maximize ( wm-frame -- wm-frame )
-<- save-state
-{ 0 0 } <-- move
-dup $dpy $default-root <- size
- <-- resize
-<- adjust-child
-<- raise ;
-
-: wm-frame-maximize-vertical ( wm-frame -- wm-frame )
-0 <-- set-y
-dup $dpy $default-root <- height
- <-- set-height
-<- adjust-child ;
-
-<wm-frame> "save-state" !( wm-frame -- wm-frame ) [
- dup <- position
- over <- size
- <rect> new
- >>last-state
-] add-method
-
-<wm-frame> "restore-state" !( wm-frame -- wm-frame ) [
- dup $last-state $pos <-- move
- dup $last-state $dim <-- resize
- <- adjust-child
-] add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel x11.constants mortar mortar.sugar slot-accessors x.widgets.keymenu ;
-
-IN: x.widgets.wm.menu
-
-SYMBOL: <wm-menu>
-
-<wm-menu> <keymenu> { } define-simple-class
-
-<wm-menu> "create" !( <wm-menu> -- wm-menu )
- [ new-empty <- keymenu-init ]
-add-class-method
-
-<wm-menu> {
-
-"wm-menu-handle-key-press" !( event wm-menu -- )
- [ <- unmap <- keymenu-handle-key-press ]
-
-"handle-key-press" !( event wm-menu -- ) [ <- wm-menu-handle-key-press ]
-
-"wm-menu-popup" !( wm-menu -- wm-menu )
- [ <- map <- raise RevertToPointerRoot CurrentTime <--- set-input-focus ]
-
-"popup" !( wm-menu -- wm-menu ) [ <- wm-menu-popup ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel io combinators namespaces arrays assocs sequences math
- x11.xlib
- x11.constants
- vars mortar slot-accessors
- x x.keysym-table x.widgets x.widgets.wm.child x.widgets.wm.frame ;
-
-IN: x.widgets.wm.root
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: <wm-root>
-
-<wm-root>
- <widget>
- { "keymap" } accessors
-define-simple-class
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: wm-root
-
-: create-wm-root ( -- )
- <wm-root> new-empty
- dpy> >>dpy
- dpy> $default-root $id >>id
- SubstructureRedirectMask >>mask
- <- add-to-window-table
- SubstructureRedirectMask <-- select-input
- H{ } clone >>keymap
- >wm-root ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: find-in-table ( window -- object )
-dup >r $id dpy get $window-table at r> or ;
-
-: circulate-focus ( -- )
-dpy get $default-root <- children
-[ find-in-table ] map [ <- mapped? ] filter dup length 1 >
-[ reverse dup first <- lower drop
- second <- raise
- dup <wm-frame> is? [ $child ] [ ] if
- RevertToPointerRoot CurrentTime <--- set-input-focus drop ]
-[ drop ]
-if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: managed? ( id -- ? )
-dpy get $window-table values [ <wm-child> is? ] filter [ $id ] map member? ;
-
-: event>keyname ( event -- keyname ) lookup-keysym keysym>name ;
-
-: event>state-and-name ( event -- array )
-dup XKeyEvent-state swap event>keyname 2array ;
-
-: resolve-key-event ( keymap event -- item ) event>state-and-name swap at ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<wm-root> {
-
-"handle-map-request" !( event wm-root -- ) [
- { { [ over XMapRequestEvent-window managed? ]
- [ "<wm-root> handle-map-request :: window already managed" print flush
- 2drop ] }
- { [ t ] [ drop XMapRequestEvent-window <wm-frame> <<- create drop ] } }
- cond ]
-
-"handle-unmap" !( event wm-root -- ) [ 2drop ]
-
-"handle-key-press" !( event wm-root -- )
- [ $keymap swap resolve-key-event call ]
-
-"grab-key" !( wm-root modifiers keyname -- wm-root modifiers keyname ) [
- 3dup name>keysym keysym-to-keycode spin
- False GrabModeAsync GrabModeAsync grab-key ]
-
-"set-key-action" !( wm-root modifiers keyname action -- wm-root ) [
- >r <--- grab-key r>
- -rot 2array pick $keymap set-at ]
-
-"handle-configure-request" !( event wm-root -- ) [
- $dpy over XConfigureRequestEvent-window <window> new ! event window
- { { [ over dup CWX? swap CWY? and ]
- [ over XConfigureRequestEvent-position <-- move ] }
- { [ over CWX? ] [ over XConfigureRequestEvent-x <-- set-x ] }
- { [ over CWY? ] [ over XConfigureRequestEvent-y <-- set-y ] }
- { [ t ] [ "<wm-root> handle-configure-request :: move not requested"
- print flush ] } }
- cond
-
- { { [ over dup CWWidth? swap CWHeight? and ]
- [ over XConfigureRequestEvent-size <-- resize ] }
- { [ over CWWidth? ] [ over XConfigureRequestEvent-width <-- set-width ] }
- { [ over CWHeight? ] [ over XConfigureRequestEvent-height <-- set-height ] }
- { [ t ] [ "<wm-root> handle-configure-request :: resize not requested"
- print flush ] } }
- cond
- 2drop ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces quotations arrays assocs sequences
- mortar slot-accessors x x.widgets.wm.menu x.widgets.wm.frame
- vars ;
-
-IN: x.widgets.wm.unmapped-frames-menu
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: <unmapped-frames-menu>
-
-<unmapped-frames-menu> <wm-menu> { } define-simple-class
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-VAR: unmapped-frames-menu
-
-: create-unmapped-frames-menu ( -- )
-<unmapped-frames-menu>
- new-empty
- <- keymenu-init
- 1 <-- set-border-width
->unmapped-frames-menu ;
-
-: unmapped-frames ( -- seq )
-dpy get $window-table values
-[ <wm-frame> is? ] filter [ <- mapped? not ] filter ;
-
-<unmapped-frames-menu> {
-
-"refresh" !( menu -- menu ) [
- unmapped-frames dup
- [ $child <- fetch-name ] map swap
- [ [ <- map ] curry ] map
- [ 2array ] 2map
- >>items
- dup <- calc-size <-- resize ]
-
-"popup" !( menu -- menu ) [ <- refresh <- wm-menu-popup ]
-
-} add-methods
\ No newline at end of file
+++ /dev/null
-Eduardo Cavazos
+++ /dev/null
-
-USING: kernel namespaces namespaces.lib math sequences vars mortar
-accessors slot-accessors x ;
-
-IN: x.widgets.wm.workspace
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-TUPLE: workspace windows ;
-
-C: <workspace> workspace
-
-VAR: workspaces
-
-VAR: current-workspace
-
-: init-workspaces ( -- ) V{ } clone >workspaces ;
-
-: add-workspace ( -- ) { } clone <workspace> workspaces> push ;
-
-: mapped-windows ( -- seq )
-dpy get $default-root <- children [ <- mapped? ] filter ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: switch-to-workspace ( n -- )
-mapped-windows current-workspace> workspaces> nth (>>windows)
-mapped-windows [ <- unmap drop ] each
-dup workspaces> nth windows>> [ <- map drop ] each
-current-workspace set* ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: next-workspace ( -- )
-current-workspace> 1+ dup workspaces> length <
-[ switch-to-workspace ] [ drop ] if ;
-
-: prev-workspace ( -- )
-current-workspace> 1- dup 0 >=
-[ switch-to-workspace ] [ drop ] if ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: setup-workspaces ( n -- )
-workspaces>
- [ drop ]
- [ init-workspaces [ add-workspace ] times 0 >current-workspace ]
-if ;
\ No newline at end of file
+++ /dev/null
-
-USING: kernel io alien alien.c-types alien.strings namespaces threads
- arrays sequences assocs math vars combinators.lib
- x11.constants x11.events x11.xlib mortar slot-accessors geom.rect
- io.encodings.ascii ;
-
-IN: x
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SYMBOL: <display>
-
-SYMBOL: <window>
-
-! SYMBOL: dpy
-
-VAR: dpy
-
-<display>
- { "ptr"
- "name"
- "default-screen"
- "default-root"
- "default-gc"
- "black-pixel"
- "white-pixel"
- "colormap"
- "window-table" } accessors
-define-independent-class
-
-<display> "create" !( name <display> -- display ) [
- new-empty swap >>name
- dup $name dup [ ascii string>alien ] [ ] if XOpenDisplay
- dup [ >>ptr ] [ "XOpenDisplay error" throw ] if
- dup $ptr XDefaultScreen >>default-screen
- dup $ptr XDefaultRootWindow dupd <window> new >>default-root
- dup $ptr over $default-screen XDefaultGC >>default-gc
- dup $ptr over $default-screen XBlackPixel >>black-pixel
- dup $ptr over $default-screen XWhitePixel >>white-pixel
- dup $ptr over $default-screen XDefaultColormap >>colormap
- H{ } clone >>window-table
- [ <- start-event-loop ] in-thread
-] add-class-method
-
-{ "id" } accessors drop
-
-DEFER: check-window-table
-
-<display> {
-
-"add-to-window-table" !( display window -- )
- [ dup $id rot $window-table set-at ]
-
-"remove-from-window-table" !( display window -- )
- [ $id swap $window-table delete-at ]
-
-"next-event" !( display event -- display event )
- [ over $ptr over XNextEvent drop ]
-
-"events-queued" !( display mode -- n ) [ >r $ptr r> XEventsQueued ]
-
-"concurrent-next-event" !( display event -- display event )
- [ over QueuedAfterFlush <-- events-queued 0 >
- [ <-- next-event ] [ 100 sleep <-- concurrent-next-event ] if ]
-
-"event-loop" !( display event -- )
-[ <-- concurrent-next-event
- 2dup >r >r
- dup XAnyEvent-window rot $window-table at dup
- [ <- handle-event ] [ 2drop ] if
- r> r>
- <-- event-loop ]
-
-"start-event-loop" !( display -- ) [ "XEvent" <c-object> <-- event-loop ]
-
-"flush" !( display -- display ) [ dup $ptr XFlush drop ]
-
-"pointer-window" !( display -- window ) [
- dup $ptr
- over $default-root $id
- 0 <Window>
- 0 <Window> dup >r
- 0 <int>
- 0 <int>
- 0 <int>
- 0 <int>
- 0 <uint>
- XQueryPointer drop
- r> *Window <window> new
- check-window-table ]
-
-} add-methods
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<window> { "dpy" "id" } accessors define-independent-class
-
-: create-window ( -- window ) <window> new-empty <- init-window ;
-
-: create-window-from-id ( dpy id -- window ) <window> new ;
-
-: check-window-table ( window -- window )
- dup $id
- over $dpy $window-table
- at
- swap or ;
-
-<window> "init-window"
- !( window -- window )
- [ dpy get
- >>dpy
- dpy get $ptr
- dpy get $default-root $id
- 0 0 100 100 0
- dpy get $black-pixel
- dpy get $white-pixel
- XCreateSimpleWindow
- >>id ]
-add-method
-
-! <window> new-empty <- init
-
-<window> "raw"
- !( window -- dpy-ptr id )
- [ dup $dpy $ptr swap $id ]
-add-method
-
-<window> "move"
- !( window point -- window )
- [ >r dup <- raw r> first2 XMoveWindow drop ]
-add-method
-
-<window> "set-x" !( window x -- window ) [
- over <- y 2array <-- move
-] add-method
-
-<window> "set-y" !( window y -- window ) [
- over <- x swap 2array <-- move
-] add-method
-
-<window> "flush"
- !( window -- window )
- [ dup $dpy <- flush drop ]
-add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 3 - Window Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! 3.3 - Creating Windows
-
-<window> "destroy" !( window -- window )
- [ dup <- raw XDestroyWindow drop ]
-add-method
-
-<window> "map"
- !( window -- window )
- [ dup <- raw XMapWindow drop ]
-add-method
-
-<window> "map-subwindows"
- !( window -- window )
- [ dup <- raw XMapSubwindows drop ]
-add-method
-
-<window> "unmap"
- !( window -- window )
- [ dup <- raw XUnmapWindow drop ]
-add-method
-
-<window> "unmap-subwindows"
- !( window -- window )
- [ dup <- raw XUnmapSubwindows drop ]
-add-method
-
-! 3.7 - Configuring Windows
-
-<window> "resize"
- !( window size -- window )
- [ >r dup <- raw r> first2 XResizeWindow drop ]
-add-method
-
-<window> "set-width"
- !( window width -- window )
- [ over <- height 2array <-- resize ]
-add-method
-
-<window> "set-height"
- !( window height -- window )
- [ over <- width swap 2array <-- resize ]
-add-method
-
-<window> "set-border-width"
- !( window n -- window )
- [ >r dup <- raw r> XSetWindowBorderWidth drop ]
-add-method
-
-! 3.8 Changing Window Stacking Order
-
-<window> "raise"
- !( window -- window )
- [ dup <- raw XRaiseWindow drop ]
-add-method
-
-<window> "lower"
- !( window -- window )
- [ dup <- raw XLowerWindow drop ]
-add-method
-
-! 3.9 - Changing Window Attributes
-
-! : change-window-attributes ( valuemask attr window -- )
-! -rot >r >r <- raw r> r> XChangeWindowAttributes drop ;
-
-<window> "change-attributes" !( window valuemask attr -- window ) [
->r >r dup <- raw r> r> XChangeWindowAttributes drop
-] add-method
-
-DEFER: lookup-color
-
-<window> "set-background"
- !( window color -- window )
- [ >r dup <- raw r> lookup-color XSetWindowBackground drop ]
-add-method
-
-<window> "set-gravity" !( window gravity -- window ) [
-CWWinGravity swap
-"XSetWindowAttributes" <c-object> tuck set-XSetWindowAttributes-win_gravity
-<--- change-attributes
-] add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 4 - Window Information Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! 4.1 - Obtaining Window Information
-
-<window> {
-
-"children" !( window -- seq )
- [ <- raw 0 <uint> 0 <uint> f <void*> 0 <uint> 2dup >r >r XQueryTree drop
- r> r> swap *void* swap *uint c-uint-array>
- [ dpy get swap <window> new ] map ]
-
-"parent" !( window -- parent ) [
- dup $dpy >r
-
- dup $dpy $ptr
- swap $id
- 0 <Window>
- 0 <Window> dup >r
- f <void*>
- 0 <uint>
- XQueryTree drop
- r> *Window
- r> swap
- <window> new
- check-window-table ]
-
-"size" !( window -- size )
- [ <- raw 0 <Window> 0 <int> 0 <int>
- 0 <uint> 0 <uint> 2dup 2array >r
- 0 <uint> 0 <uint>
- XGetGeometry drop r> [ *uint ] map ]
-
-"width" !( window -- width ) [ <- size first ]
-
-"height" !( window -- height ) [ <- size second ]
-
-"position" !( window -- position )
- [ <- raw 0 <Window>
- 0 <uint> 0 <uint> 2dup 2array >r
- 0 <uint> 0 <uint> 0 <uint> 0 <uint>
- XGetGeometry drop r> [ *int ] map ]
-
-"x" !( window -- x ) [ <- position first ]
-
-"y" !( window -- y ) [ <- position second ]
-
-"as-rect" !( window -- rect ) [ dup <- position swap <- size <rect> new ]
-
-"attributes" !( window -- XWindowAttributes )
- [ <- raw "XWindowAttributes" <c-object> dup >r XGetWindowAttributes drop r> ]
-
-"map-state" !( window -- state ) [ <- attributes XWindowAttributes-map_state ]
-
-"mapped?" !( window -- ? ) [ <- map-state IsUnmapped = not ]
-
-} add-methods
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: get-atom-name ( atom -- name ) dpy get $ptr swap XGetAtomName ;
-
-: intern-atom ( atom-name only-if-exists? -- atom )
-dpy get $ptr -rot XInternAtom ;
-
-: lookup-color ( name -- pixel )
-dpy get $ptr dpy get $colormap rot
-"XColor" <c-object> dup >r "XColor" <c-object> XLookupColor drop
-dpy get $ptr dpy get $colormap r> dup >r XAllocColor drop r> XColor-pixel ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 8 - Graphics Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<window> "clear"
- !( window -- window )
- [ dup <- raw XClearWindow drop ]
-add-method
-
-<window> "draw-string"
- !( window gc pos string -- )
- [ >r >r >r <- raw r> $ptr r> [ >fixnum ] map first2 r> dup length
- XDrawString drop ]
-add-method
-
-! <window> "draw-string"
-! !( window gc pos string -- )
-! [ >r >r >r <- raw r> $ptr r> [ >fixnum ] map first2 r> dup length
-! XDrawString drop ]
-! add-method
-
-<window> "draw-line"
- !( window gc a b -- )
- [ >r >r >r <- raw r> $ptr r> first2 r> first2 XDrawLine drop ]
-add-method
-
-<window> "draw-rect"
- !( window gc rect -- )
- [ 3dup dup <- top-left swap <- top-right <---- draw-line
- 3dup dup <- top-right swap <- bottom-right <---- draw-line
- 3dup dup <- bottom-left swap <- bottom-right <---- draw-line
- dup <- top-left swap <- bottom-left <---- draw-line ]
-add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 9 - Window and Session Manager Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<window> "reparent"
- !( window parent -- window )
- [ >r dup <- raw r> $id 0 0 XReparentWindow drop ]
-add-method
-
-<window> "add-to-save-set" !( window -- window ) [
- dup <- raw XAddToSaveSet drop
-] add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 10 - Events
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: XButtonEvent-root-position ( event -- position )
-dup XButtonEvent-x_root swap XButtonEvent-y_root 2array ;
-
-: XMotionEvent-root-position ( event -- position )
-dup XMotionEvent-x_root swap XMotionEvent-y_root 2array ;
-
-! Utility words for XConfigureRequestEvent
-
-: XConfigureRequestEvent-position ( XConfigureRequestEvent -- position )
-dup XConfigureRequestEvent-x swap XConfigureRequestEvent-y 2array ;
-
-: XConfigureRequestEvent-size ( XConfigureRequestEvent -- size )
-dup XConfigureRequestEvent-width swap XConfigureRequestEvent-height 2array ;
-
-: bit-test ( a b -- t-or-f ) bitand 0 = not ;
-
-: CWX? ( XConfigureRequestEvent -- bool )
-XConfigureRequestEvent-value_mask CWX bit-test ;
-
-: CWY? ( XConfigureRequestEvent -- bool )
-XConfigureRequestEvent-value_mask CWY bit-test ;
-
-: CWWidth? ( XConfigureRequestEvent -- bool )
-XConfigureRequestEvent-value_mask CWWidth bit-test ;
-
-: CWHeight? ( XConfigureRequestEvent -- bool )
-XConfigureRequestEvent-value_mask CWHeight bit-test ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 11 - Event Handling Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<window> "select-input"
- !( window mask -- window )
- [ >r dup <- raw r> XSelectInput drop ]
-add-method
-
-! 11.8 - Handling Protocol Errors
-
-SYMBOL: error-handler-quot
-
-: error-handler-callback ( -- xt )
-"void" { "Display*" "XErrorEvent*" } "cdecl"
-[ error-handler-quot get call ] alien-callback ;
-
-: set-error-handler ( quot -- )
-error-handler-quot set error-handler-callback XSetErrorHandler drop ;
-
-: install-default-error-handler ( -- )
-[ "X11 : error-handler called" print flush ] set-error-handler ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 12 - Input Device Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! 12.2 - Keyboard Grabbing
-
-: grab-key
-( keycode modifiers grab-window owner-events pointer-mode keyboard-mode -- )
->r >r >r <- raw >r -rot r> r> r> r> XGrabKey drop ;
-
-! 12.5 - Controlling Input Focus
-
-<window> "set-input-focus" !( window revert-to time -- window )
- [ >r >r dup <- raw r> r> XSetInputFocus drop ]
-add-method
-
-: get-input-focus ( -- window )
- dpy> $ptr
- 0 <Window> dup >r
- 0 <int>
- XGetInputFocus drop
- r> *Window
- dpy> swap
- create-window-from-id
- check-window-table ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 14 - Inter-Client Communication Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-<window> "fetch-name" !( window -- name-or-f )
- [ <- raw f <void*> dup >r XFetchName drop r>
- dup *void* [ drop f ] [ *void* ascii alien>string ] if ]
-add-method
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! 16 - Application Utility Functions
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-! 16.1 - Using Keyboard Utility Functions
-
-! this should go in xlib.factor
-
-USING: alien.syntax ;
-
-FUNCTION: KeyCode XKeysymToKeycode ( Display* display, KeySym keysym ) ;
-
-FUNCTION: KeySym XKeycodeToKeysym ( Display* display,
- KeyCode keycode,
- int index ) ;
-
-FUNCTION: char* XKeysymToString ( KeySym keysym ) ;
-
-: keysym-to-keycode ( keysym -- keycode ) dpy get $ptr swap XKeysymToKeycode ;
-
-USE: strings
-
-: lookup-string* ( event -- keysym string )
-10 "char" <c-array> dup >r 10 0 <KeySym> dup >r f XLookupString
-r> *KeySym swap r> swap c-char-array> >string ;
-
-: lookup-string ( event -- string ) lookup-string* nip ;
-
-: lookup-keysym ( event -- keysym ) lookup-string* drop ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!7
-
-: event-to-keysym ( event index -- keysym )
->r dup XKeyEvent-display swap XKeyEvent-keycode r> XKeycodeToKeysym ;
-
-: keysym-to-string ( keysym -- string ) XKeysymToString ;
-
-: key-event-to-string ( event index -- str ) event-to-keysym keysym-to-string ;
-
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! Misc
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-: no-modifiers ( -- mask ) 0 ;
-
-: control-alt ( -- mask ) ControlMask Mod1Mask bitor ;
-
-: alt ( -- mask ) Mod1Mask ;
-
-: True 1 ;
-: False 0 ;
-
-<window> "send-client-message" !( window message-type data -- window ) [
-
-"XClientMessageEvent" <c-object>
-
-tuck set-XClientMessageEvent-data0
-tuck set-XClientMessageEvent-message_type
-over $id over set-XClientMessageEvent-window
-ClientMessage over set-XClientMessageEvent-type
-32 over set-XClientMessageEvent-format
-CurrentTime over set-XClientMessageEvent-data1
-
->r dup <- raw False NoEventMask r> XSendEvent drop
-
-] add-method
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+USING: kernel combinators sequences math math.functions math.vectors mortar
+ slot-accessors x x.widgets.wm.root x.widgets.wm.frame sequences.lib ;
+IN: factory.commands
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: up-till-frame ( window -- wm-frame )
+{ { [ dup <wm-frame> is? ]
+ [ ] }
+ { [ dup $dpy $default-root $id over $id = ]
+ [ drop f ] }
+ { [ t ]
+ [ <- parent up-till-frame ] } } cond ;
+
+: pointer-window ( -- window ) dpy> <- pointer-window ;
+
+: pointer-frame ( -- wm-frame )
+pointer-window up-till-frame dup <wm-frame> is? [ ] [ drop f ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: maximize ( -- ) pointer-frame wm-frame-maximize drop ;
+
+: minimize ( -- ) pointer-frame <- unmap drop ;
+
+: maximize-vertical ( -- ) pointer-frame wm-frame-maximize-vertical drop ;
+
+: restore ( -- ) pointer-frame <- restore-state drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+
+: tile-master ( -- )
+
+wm-root>
+ <- children
+ [ <- mapped? ] filter
+ [ check-window-table ] map
+ reverse
+
+unclip
+ { 0 0 } <-- move
+ wm-root> <- size { 1/2 1 } v*
+ [ floor ] map <-- resize
+ <- adjust-child
+drop
+
+dup empty? [ drop ] [
+
+wm-root> <- width 2 / floor [ <-- set-width ] curry map
+wm-root> <- height over length / floor [ <-- set-height ] curry map
+
+wm-root> <- width 2 / floor [ <-- set-x ] curry map
+
+wm-root> <- height over length / over length [ * floor ] map-with
+[ <-- set-y <- adjust-child ] 2map
+
+drop
+
+] if ;
+
+! : tile-master ( -- )
+
+! wm-root>
+! <- children
+! [ <- mapped? ] filter
+! [ check-window-table ] map
+! reverse
+
+! { { [ dup empty? ] [ drop ] }
+! { [ dup length 1 = ] [ drop maximize ] }
+! { [ t ] [ tile-master* ] }
--- /dev/null
+! -*-factor-*-
+
+USING: kernel unix vars mortar mortar.sugar slot-accessors
+ x.widgets.wm.menu x.widgets.wm.unmapped-frames-menu
+ factory.commands factory.load ;
+
+IN: factory
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Helper words
+
+: new-wm-menu ( -- menu ) <wm-menu> new* 1 <-- set-border-width ;
+
+: shrink-wrap ( menu -- ) dup <- calc-size <-- resize drop ;
+
+: set-menu-items ( items menu -- ) swap >>items shrink-wrap ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: apps-menu
+
+apps-menu> not [ new-wm-menu >apps-menu ] when
+
+{ { "Emacs" [ "emacs &" system drop ] }
+ { "KMail" [ "kmail &" system drop ] }
+ { "Akregator" [ "akregator &" system drop ] }
+ { "Amarok" [ "amarok &" system drop ] }
+ { "K3b" [ "k3b &" system drop ] }
+ { "xchat" [ "xchat &" system drop ] }
+ { "Nautilus" [ "nautilus --no-desktop &" system drop ] }
+ { "synaptic" [ "gksudo synaptic &" system drop ] }
+ { "Volume control" [ "gnome-volume-control &" system drop ] }
+ { "Azureus" [ "~/azureus/azureus &" system drop ] }
+ { "Xephyr" [ "Xephyr -host-cursor :1 &" system drop ] }
+ { "Stop Xephyr" [ "pkill Xephyr &" system drop ] }
+ { "Stop Firefox" [ "pkill firefox &" system drop ] }
+} apps-menu> set-menu-items
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: emacs-menu
+
+emacs-menu> not [ new-wm-menu >emacs-menu ] when
+
+{ { "Start Emacs" [ "emacs &" system drop ] }
+ { "Small" [ "emacsclient -e '(make-small-frame-command)' &" system drop ] }
+ { "Large" [ "emacsclient -e '(make-frame-command)' &" system drop ] }
+ { "Full" [ "emacsclient -e '(make-full-frame-command)' &" system drop ] }
+ { "Gnus" [ "emacsclient -e '(gnus-other-frame)' &" system drop ] }
+ { "Factor" [ "emacsclient -e '(run-factor-other-frame)' &" system drop ] }
+} emacs-menu> set-menu-items
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: mail-menu
+
+mail-menu> not [ new-wm-menu >mail-menu ] when
+
+{ { "Kmail" [ "kmail &" system drop ] }
+ { "compose" [ "kmail --composer &" system drop ] }
+ { "slava" [ "kmail slava@factorcode.org &" system drop ] }
+ { "erg" [ "kmail doug.coleman@gmail.com &" system drop ] }
+ { "doublec" [ "kmail chris.double@double.co.nz &" system drop ] }
+ { "yuuki" [ "kmail matthew.willis@mac.com &" system drop ] }
+} mail-menu> set-menu-items
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: factor-menu
+
+factor-menu> not [ new-wm-menu >factor-menu ] when
+
+{ { "Factor" [ "cd /scratch/repos/Factor ; ./factor &" system drop ] }
+ { "Factor (tty)"
+ [ "cd /scratch/repos/Factor ; xterm -e ./factor -run=listener &"
+ system drop ] }
+ { "Terminal : repos/Factor"
+ [ "cd /scratch/repos/Factor ; xterm &" system drop ] }
+ { "darcs whatsnew"
+ [ "cd /scratch/repos/Factor ; xterm -e 'darcs whatsnew | less' &"
+ system drop ] }
+ { "darcs pull"
+ [ "cd /scratch/repos/Factor ; xterm -e 'darcs pull http://factorcode.org/repos' &" system drop ] }
+ { "darcs push"
+ [ "cd /scratch/repos/Factor ; xterm -e 'darcs push dharmatech@onigirihouse.com:doc-root/repos' &" system drop ] }
+} factor-menu> set-menu-items
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: factory-menu
+
+factory-menu> not [ new-wm-menu >factory-menu ] when
+
+{ { "Maximize" [ maximize ] }
+ { "Maximize Vertical" [ maximize-vertical ] }
+ { "Restore" [ restore ] }
+ { "Hide" [ minimize ] }
+ { "Tile Master" [ tile-master ] }
+}
+
+factory-menu> set-menu-items
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! VAR: root-menu
+
+{ { "xterm" [ "urxvt -bd grey +sb &" system drop ] }
+ { "Firefox" [ "firefox &" system drop ] }
+ { "xclock" [ "xclock &" system drop ] }
+ { "Apps >" [ apps-menu> <- popup ] }
+ { "Factor >" [ factor-menu> <- popup ] }
+ { "Unmapped frames >" [ unmapped-frames-menu> <- popup ] }
+ { "Emacs >" [ emacs-menu> <- popup ] }
+ { "Mail >" [ mail-menu> <- popup ] }
+ { "onigirihouse" [ "xterm -e 'ssh dharmatech@onigirihouse.com' &"
+ system drop ] }
+ { "Edit menus" [ edit-factory-menus ] }
+ { "Reload menus" [ load-factory-menus ] }
+ { "Factory >" [ factory-menu> <- popup ] }
+} root-menu> set-menu-items
+
--- /dev/null
+! -*-factor-*-
+
+USING: kernel mortar x
+ x.widgets.wm.root
+ x.widgets.wm.workspace
+ x.widgets.wm.unmapped-frames-menu
+ factory.load
+ tty-server ;
+
+IN: factory
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+create-root-menu
+create-unmapped-frames-menu
+load-factory-menus
+6 setup-workspaces
+
+wm-root>
+ no-modifiers "F12" [ root-menu> <- popup ] <---- set-key-action
+ control-alt "LEFT" [ prev-workspace ] <---- set-key-action
+ control-alt "RIGHT" [ next-workspace ] <---- set-key-action
+ alt "TAB" [ circulate-focus ] <---- set-key-action
+drop
+
+9010 tty-server
--- /dev/null
+
+USING: kernel parser io io.files namespaces sequences editors threads vars
+ mortar mortar.sugar slot-accessors
+ x
+ x.widgets.wm.root
+ x.widgets.wm.frame
+ x.widgets.wm.menu
+ factory.load
+ factory.commands ;
+
+IN: factory
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: manage-windows ( -- )
+dpy get $default-root <- children [ <- mapped? ] filter
+[ $id <wm-frame> new* drop ] each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: root-menu
+
+: create-root-menu ( -- ) <wm-menu> new* 1 <-- set-border-width >root-menu ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: start-factory ( display-string -- )
+<display> new* >dpy
+install-default-error-handler
+create-wm-root
+init-atoms
+manage-windows
+load-factory-rc ;
+
+: factory ( -- ) f start-factory stop ;
+
+MAIN: factory
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel io.files parser editors sequences ;
+
+IN: factory.load
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: file-or ( file file -- file ) over exists? [ drop ] [ nip ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: personal-factory-rc ( -- path ) home "/.factory-rc" append ;
+
+: system-factory-rc ( -- path ) "extra/factory/factory-rc" resource-path ;
+
+: factory-rc ( -- path ) personal-factory-rc system-factory-rc file-or ;
+
+: load-factory-rc ( -- ) factory-rc run-file ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: personal-factory-menus ( -- path ) home "/.factory-menus" append ;
+
+: system-factory-menus ( -- path )
+"extra/factory/factory-menus" resource-path ;
+
+: factory-menus ( -- path )
+personal-factory-menus system-factory-menus file-or ;
+
+: load-factory-menus ( -- ) factory-menus run-file ;
+
+: edit-factory-menus ( -- ) factory-menus 0 edit-location ;
--- /dev/null
+Window manager for the X Window System
--- /dev/null
+applications
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: sequences mortar slot-accessors ;
+
+IN: geom.dim
+
+SYMBOL: <dim>
+
+<dim> { "dim" } accessors define-independent-class
+
+<dim> {
+
+"width" !( dim -- width ) [ $dim first ]
+
+"height" !( dim -- second ) [ $dim second ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel arrays sequences math.vectors mortar slot-accessors ;
+
+IN: geom.pos
+
+SYMBOL: <pos>
+
+<pos> { "pos" } accessors define-independent-class
+
+<pos> {
+
+"x" !( pos -- x ) [ $pos first ]
+
+"y" !( pos -- y ) [ $pos second ]
+
+"set-x" !( pos x -- pos ) [ 0 pick $pos set-nth ]
+
+"set-y" !( pos y -- pos ) [ 1 pick $pos set-nth ]
+
+"distance" !( pos pos -- distance ) [ $pos swap $pos v- norm ]
+
+"move-by" !( pos offset -- pos ) [ over $pos v+ >>pos ]
+
+"move-by-x" !( pos x-offset -- pos ) [ 0 2array <-- move-by ]
+
+"move-by-y" !( pos y-offset -- pos ) [ 0 swap 2array <-- move-by ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces arrays sequences math.vectors
+ mortar slot-accessors geom.pos geom.dim ;
+
+IN: geom.rect
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+USE: math
+
+: v+y ( pos y -- pos ) 0 swap 2array v+ ;
+
+: v-y ( pos y -- pos ) 0 swap 2array v- ;
+
+: v+x ( pos x -- pos ) 0 2array v+ ;
+
+: v-x ( pos x -- pos ) 0 2array v- ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: <rect>
+
+<rect>
+ <pos> class-slots <dim> class-slots append
+ <pos> class-methods <dim> class-methods append { H{ } } append
+ { H{ } }
+4array <rect> set-global
+
+! { 0 0 } { 0 0 } <rect> new
+
+<rect> {
+
+"top-left" !( rect -- point ) [ $pos ]
+
+"top-right" !( rect -- point ) [ dup $pos swap <- width 1- v+x ]
+
+"bottom-left" !( rect -- point ) [ dup $pos swap <- height 1- v+y ]
+
+"bottom-right" !( rect -- point ) [ dup $pos swap $dim { 1 1 } v- v+ ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel io parser lexer words namespaces quotations arrays assocs sequences
+ splitting grouping math generalizations ;
+
+IN: mortar
+
+! class { name slots methods class-methods }
+
+: class-name ( class -- name ) dup symbol? [ get ] when first ;
+
+: class-slots ( class -- slots ) dup symbol? [ get ] when second ;
+
+: class-methods ( class -- methods ) dup symbol? [ get ] when third ;
+
+: class-class-methods ( class -- methods ) dup symbol? [ get ] when fourth ;
+
+: class? ( thing -- ? )
+dup array?
+[ dup length 4 = [ first symbol? ] [ drop f ] if ]
+[ drop f ]
+if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: add-method ( class name quot -- )
+rot get class-methods peek swapd set-at ;
+
+: add-class-method ( class name quot -- )
+rot get class-class-methods peek swapd set-at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! object { class values }
+
+: object-class ( object -- class ) first ;
+
+: object-values ( object -- values ) second ;
+
+: object? ( thing -- ? )
+dup array?
+[ dup length 2 = [ first class? ] [ drop f ] if ]
+[ drop f ]
+if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: is? ( object class -- ? ) swap object-class class-name = ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: new ( class -- object )
+get dup >r class-slots length narray r> swap 2array ;
+
+: new-empty ( class -- object )
+get dup >r class-slots length f <array> r> swap 2array ;
+
+! : new* ( class -- object ) new-empty <- init ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: slot-value ( object slot -- value )
+over object-class class-slots index swap object-values nth ;
+
+: set-slot-value ( object slot value -- object )
+swap pick object-class class-slots index pick object-values set-nth ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! : send-message ( object message -- )
+! over object-class class-methods assoc-stack call ;
+
+: send-message ( object message -- )
+2dup swap object-class class-methods assoc-stack dup
+[ nip call ]
+! [ drop nip "message not understood: " write print flush ]
+[ drop "message not understood: " write print drop ]
+if ;
+
+: <- scan parsed \ send-message parsed ; parsing
+
+! : send-message* ( message n -- )
+! 1+ npick object-class class-methods assoc-stack call ;
+
+: send-message* ( message n -- )
+1+ npick dupd object-class class-methods assoc-stack dup
+[ nip call ]
+[ drop "message not understood: " write print flush ]
+if ;
+
+: <-- scan parsed 2 parsed \ send-message* parsed ; parsing
+
+: <--- scan parsed 3 parsed \ send-message* parsed ; parsing
+
+: <---- scan parsed 4 parsed \ send-message* parsed ; parsing
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: send-message-to-class ( class message -- )
+over class-class-methods assoc-stack call ;
+
+: <<- scan parsed \ send-message-to-class parsed ; parsing
+
+: send-message-to-class* ( message n -- )
+1+ npick class-class-methods assoc-stack call ;
+
+: <<-- scan parsed 2 parsed \ send-message-to-class* parsed ; parsing
+
+: <<--- scan parsed 3 parsed \ send-message-to-class* parsed ; parsing
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: send-message-next ( object message -- )
+over object-class class-methods but-last assoc-stack call ;
+
+: <-~ scan parsed \ send-message-next parsed ; parsing
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! : new* ( class -- object ) <<- create ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IN: slot-accessors
+
+IN: mortar
+
+! : generate-slot-getter ( name -- )
+! "$" over append "slot-accessors" create swap [ slot-value ] curry
+! define-compound ;
+
+: generate-slot-getter ( name -- )
+"$" over append "slot-accessors" create swap [ slot-value ] curry define ;
+
+! : generate-slot-setter ( name -- )
+! ">>" over append "slot-accessors" create swap [ swap set-slot-value ] curry
+! define-compound ;
+
+: generate-slot-setter ( name -- )
+">>" over append "slot-accessors" create swap [ swap set-slot-value ] curry
+define ;
+
+: generate-slot-accessors ( name -- )
+dup
+generate-slot-getter
+generate-slot-setter ;
+
+: accessors ( seq -- seq ) dup peek [ generate-slot-accessors ] each ; parsing
+
+! : slots:
+! ";" parse-tokens dup [ generate-slot-accessors ] each parsed ; parsing
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! : <symbol> ( string -- symbol ) in get create dup define-symbol ;
+
+: empty-method-table ( -- array ) H{ } clone 1array ;
+
+! : define-simple-class ( name parent slots -- )
+! >r >r <symbol>
+! r> dup class-slots r> append
+! swap dup class-methods empty-method-table append
+! swap class-class-methods empty-method-table append
+! 4array dup first set-global ;
+
+: define-simple-class ( name parent slots -- )
+>r dup class-slots r> append
+swap dup class-methods empty-method-table append
+swap class-class-methods empty-method-table append
+4array dup first set-global ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: define-independent-class ( name slots -- )
+empty-method-table empty-method-table 4array dup first set-global ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: add-methods ( class seq -- ) 2 group [ first2 add-method ] with each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: !( ")" parse-tokens drop ; parsing
\ No newline at end of file
--- /dev/null
+
+USING: mortar ;
+
+IN: mortar.sugar
+
+: new* ( class -- object ) <<- create ;
\ No newline at end of file
--- /dev/null
+extensions
--- /dev/null
+Chris Double
--- /dev/null
+! Copyright (C) 2007 Chris Double.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: help.syntax help.markup threads ;\r
+\r
+IN: odbc\r
+\r
+HELP: odbc-init \r
+{ $values { "env" "an ODBC environment handle" } } \r
+{ $description \r
+ "Initializes the ODBC driver manager and returns the " \r
+ "environment handle required by " { $link odbc-connect } "."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-connect \r
+{ $values { "env" "an ODBC environment handle" } { "dsn" "a string" } { "dbc" "an ODBC database connection handle" } } \r
+{ $description \r
+ "Connects to the database identified by the ODBC data source name (DSN). " \r
+ "The environment handle is usually obtained by a call to " { $link odbc-init } ". The result is the ODBC connection handle which can be used in other ODBC calls. When finished with the connection handle " { $link odbc-disconnect } " must be called on it."\r
+} \r
+{ $examples { $code "dbc get \"DSN=mydsn\" odbc-connect" } }\r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-disconnect \r
+{ $values { "dbc" "an ODBC database connection handle" } } \r
+{ $description \r
+ "Disconnects from the given database." \r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-prepare\r
+{ $values { "dbc" "an ODBC database connection handle" } { "string" "a string containing SQL" } { "statement" "an ODBC statement handle" } } \r
+{ $description \r
+ "Prepares (precompiles) the given SQL string, ready for execution with " { $link odbc-execute } ". When finished with the statement " { $link odbc-free-statement } " must be called on it." \r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-free-statement\r
+{ $values { "statement" "an ODBC statement handle" } } \r
+{ $description \r
+ "Closes the statement handle and frees up all resources associated with it." \r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-execute\r
+{ $values { "statement" "an ODBC statement handle" } } \r
+{ $description \r
+ "Executes the statement. Once this is done " { $link odbc-next-row } " can be called to retrieve rows." \r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-next-row\r
+{ $values { "statement" "an ODBC statement handle" } { "bool" "a boolean indicating success or failure" } } \r
+{ $description \r
+ "Retrieves the next available row from the database. If no next row is available then " { $link f } " is returned. Once the row is retrieved " { $link odbc-number-of-columns } ", " { $link odbc-describe-column } ", " { $link odbc-get-field } " and " { $link odbc-get-row-fields } " can be used to query the data retrieved." \r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-number-of-columns\r
+{ $values { "statement" "an ODBC statement handle" } { "number" "a number" } } \r
+{ $description \r
+ "Returns the number of columns of data retrieved."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-describe-column\r
+{ $values { "statement" "an ODBC statement handle" } { "n" "a column number starting from one" } { "column" "a column object" } } \r
+{ $description \r
+ "Retrieves column information for the given column number from the statement. The column number must be one or greater. The " { $link <column> } " object returned provides data type, name, etc."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-get-field\r
+{ $values { "statement" "an ODBC statement handle" } { "column" "a column number starting from one or a <column> object" } { "field" "a <field> object" } } \r
+{ $description \r
+ "Returns a field object which contains the data for the field in the given column in the current row. The column can be identified by a number or a <column> object. The datatype of the contents of the field depends on the type of the column itself. Note that this word can only be safely called once on each column in a given row with most ODBC drivers. Subsequent calls on the same row for the same column can fail."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-get-row-fields\r
+{ $values { "statement" "an ODBC statement handle" } { "seq" "a sequence" } } \r
+{ $description \r
+ "Returns a sequence of all field data for the current row. Note that this isnot the <field> objects, but the data for that field. This word can only be called once on a given row. Subsequent calls on the same row may fail on some ODBC drivers."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-get-all-rows\r
+{ $values { "statement" "an ODBC statement handle" } { "seq" "a sequence" } } \r
+{ $description \r
+ "Returns a sequence of all rows available from the statement. Effectively it is the contents of the entire query so may take some time and memory. Each element of the sequence is itself a sequence containing the data for that row. A " { $link yield } " is performed an various intervals so as to not lock up the Factor instance while it is running."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
+\r
+HELP: odbc-query\r
+{ $values { "string" "a string containing SQL" } { "dsn" "a DSN string" } { "result" "a sequence" } } \r
+{ $description \r
+ "This word initializes odbc, connects to the database with the given DSN, executes the query string and returns the result as a sequence. It cleans up all resources it uses. It is an inefficient way of running multiple queries but is useful for the occasional query, testing at the REPL, or as an example of how to do it."\r
+} \r
+{ $see-also odbc-init odbc-connect odbc-disconnect odbc-prepare odbc-free-statement odbc-execute odbc-next-row odbc-number-of-columns odbc-describe-column odbc-get-field odbc-get-row-fields odbc-get-all-rows odbc-query } ;\r
--- /dev/null
+! Copyright (C) 2007 Chris Double.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel alien alien.strings alien.syntax
+combinators alien.c-types strings sequences namespaces make
+words math threads io.encodings.ascii ;
+IN: odbc
+
+<< "odbc" "odbc32.dll" "stdcall" add-library >>
+
+LIBRARY: odbc
+
+TYPEDEF: void* usb_dev_handle*
+TYPEDEF: short SQLRETURN
+TYPEDEF: short SQLSMALLINT
+TYPEDEF: short* SQLSMALLINT*
+TYPEDEF: ushort SQLUSMALLINT
+TYPEDEF: uint* SQLUINTEGER*
+TYPEDEF: int SQLINTEGER
+TYPEDEF: char SQLCHAR
+TYPEDEF: char* SQLCHAR*
+TYPEDEF: void* SQLHANDLE
+TYPEDEF: void* SQLHANDLE*
+TYPEDEF: void* SQLHENV
+TYPEDEF: void* SQLHDBC
+TYPEDEF: void* SQLHSTMT
+TYPEDEF: void* SQLHWND
+TYPEDEF: void* SQLPOINTER
+
+: SQL-HANDLE-ENV ( -- number ) 1 ; inline
+: SQL-HANDLE-DBC ( -- number ) 2 ; inline
+: SQL-HANDLE-STMT ( -- number ) 3 ; inline
+: SQL-HANDLE-DESC ( -- number ) 4 ; inline
+
+: SQL-NULL-HANDLE ( -- alien ) f ; inline
+
+: SQL-ATTR-ODBC-VERSION ( -- number ) 200 ; inline
+
+: SQL-OV-ODBC2 ( -- number ) 2 <alien> ; inline
+: SQL-OV-ODBC3 ( -- number ) 3 <alien> ; inline
+
+: SQL-SUCCESS ( -- number ) 0 ; inline
+: SQL-SUCCESS-WITH-INFO ( -- number ) 1 ; inline
+: SQL-NO-DATA-FOUND ( -- number ) 100 ; inline
+
+: SQL-DRIVER-NOPROMPT ( -- number ) 0 ; inline
+: SQL-DRIVER-PROMPT ( -- number ) 2 ; inline
+
+: SQL-C-DEFAULT ( -- number ) 99 ; inline
+
+SYMBOL: SQL-CHAR
+SYMBOL: SQL-VARCHAR
+SYMBOL: SQL-LONGVARCHAR
+SYMBOL: SQL-WCHAR
+SYMBOL: SQL-WCHARVAR
+SYMBOL: SQL-WLONGCHARVAR
+SYMBOL: SQL-DECIMAL
+SYMBOL: SQL-SMALLINT
+SYMBOL: SQL-NUMERIC
+SYMBOL: SQL-INTEGER
+SYMBOL: SQL-REAL
+SYMBOL: SQL-FLOAT
+SYMBOL: SQL-DOUBLE
+SYMBOL: SQL-BIT
+SYMBOL: SQL-TINYINT
+SYMBOL: SQL-BIGINT
+SYMBOL: SQL-BINARY
+SYMBOL: SQL-VARBINARY
+SYMBOL: SQL-LONGVARBINARY
+SYMBOL: SQL-TYPE-DATE
+SYMBOL: SQL-TYPE-TIME
+SYMBOL: SQL-TYPE-TIMESTAMP
+SYMBOL: SQL-TYPE-UTCDATETIME
+SYMBOL: SQL-TYPE-UTCTIME
+SYMBOL: SQL-INTERVAL-MONTH
+SYMBOL: SQL-INTERVAL-YEAR
+SYMBOL: SQL-INTERVAL-YEAR-TO-MONTH
+SYMBOL: SQL-INTERVAL-DAY
+SYMBOL: SQL-INTERVAL-HOUR
+SYMBOL: SQL-INTERVAL-MINUTE
+SYMBOL: SQL-INTERVAL-SECOND
+SYMBOL: SQL-INTERVAL-DAY-TO-HOUR
+SYMBOL: SQL-INTERVAL-DAY-TO-MINUTE
+SYMBOL: SQL-INTERVAL-DAY-TO-SECOND
+SYMBOL: SQL-INTERVAL-HOUR-TO-MINUTE
+SYMBOL: SQL-INTERVAL-HOUR-TO-SECOND
+SYMBOL: SQL-INTERVAL-MINUTE-TO-SECOND
+SYMBOL: SQL-GUID
+SYMBOL: SQL-TYPE-UNKNOWN
+
+: convert-sql-type ( number -- symbol )
+ {
+ { 1 [ SQL-CHAR ] }
+ { 12 [ SQL-VARCHAR ] }
+ { -1 [ SQL-LONGVARCHAR ] }
+ { -8 [ SQL-WCHAR ] }
+ { -9 [ SQL-WCHARVAR ] }
+ { -10 [ SQL-WLONGCHARVAR ] }
+ { 3 [ SQL-DECIMAL ] }
+ { 5 [ SQL-SMALLINT ] }
+ { 2 [ SQL-NUMERIC ] }
+ { 4 [ SQL-INTEGER ] }
+ { 7 [ SQL-REAL ] }
+ { 6 [ SQL-FLOAT ] }
+ { 8 [ SQL-DOUBLE ] }
+ { -7 [ SQL-BIT ] }
+ { -6 [ SQL-TINYINT ] }
+ { -5 [ SQL-BIGINT ] }
+ { -2 [ SQL-BINARY ] }
+ { -3 [ SQL-VARBINARY ] }
+ { -4 [ SQL-LONGVARBINARY ] }
+ { 91 [ SQL-TYPE-DATE ] }
+ { 92 [ SQL-TYPE-TIME ] }
+ { 93 [ SQL-TYPE-TIMESTAMP ] }
+ [ drop SQL-TYPE-UNKNOWN ]
+ } case ;
+
+: succeeded? ( n -- bool )
+ #! Did the call succeed (SQL-SUCCESS or SQL-SUCCESS-WITH-INFO)
+ {
+ { SQL-SUCCESS [ t ] }
+ { SQL-SUCCESS-WITH-INFO [ t ] }
+ [ drop f ]
+ } case ;
+
+FUNCTION: SQLRETURN SQLAllocHandle ( SQLSMALLINT handleType, SQLHANDLE inputHandle, SQLHANDLE* outputHandlePtr ) ;
+FUNCTION: SQLRETURN SQLSetEnvAttr ( SQLHENV environmentHandle, SQLINTEGER attribute, SQLPOINTER valuePtr, SQLINTEGER stringLength ) ;
+FUNCTION: SQLRETURN SQLDriverConnect ( SQLHDBC connectionHandle, SQLHWND windowHandle, SQLCHAR* inConnectionString, SQLSMALLINT stringLength, SQLCHAR* outConnectionString, SQLSMALLINT bufferLength, SQLSMALLINT* stringLength2Ptr, SQLUSMALLINT driverCompletion ) ;
+FUNCTION: SQLRETURN SQLDisconnect ( SQLHDBC connectionHandle ) ;
+FUNCTION: SQLRETURN SQLPrepare ( SQLHSTMT statementHandle, SQLCHAR* statementText, SQLINTEGER length ) ;
+FUNCTION: SQLRETURN SQLExecute ( SQLHSTMT statementHandle ) ;
+FUNCTION: SQLRETURN SQLFreeHandle ( SQLSMALLINT handleType, SQLHANDLE handle ) ;
+FUNCTION: SQLRETURN SQLFetch ( SQLHSTMT statementHandle ) ;
+FUNCTION: SQLRETURN SQLNumResultCols ( SQLHSTMT statementHandle, SQLSMALLINT* columnCountPtr ) ;
+FUNCTION: SQLRETURN SQLDescribeCol ( SQLHSTMT statementHandle, SQLSMALLINT columnNumber, SQLCHAR* columnName, SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr, SQLUINTEGER* columnSizePtr, SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr ) ;
+FUNCTION: SQLRETURN SQLGetData ( SQLHSTMT statementHandle, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValuePtr, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_indPtr ) ;
+
+: alloc-handle ( type parent -- handle )
+ f <void*> [ SQLAllocHandle ] keep swap succeeded? [
+ *void*
+ ] [
+ drop f
+ ] if ;
+
+: alloc-env-handle ( -- handle )
+ SQL-HANDLE-ENV SQL-NULL-HANDLE alloc-handle ;
+
+: alloc-dbc-handle ( env -- handle )
+ SQL-HANDLE-DBC swap alloc-handle ;
+
+: alloc-stmt-handle ( dbc -- handle )
+ SQL-HANDLE-STMT swap alloc-handle ;
+
+: temp-string ( length -- byte-array length )
+ [ CHAR: \space <string> ascii string>alien ] keep ;
+
+: odbc-init ( -- env )
+ alloc-env-handle
+ [
+ SQL-ATTR-ODBC-VERSION SQL-OV-ODBC3 0 SQLSetEnvAttr
+ succeeded? [ "odbc-init failed" throw ] unless
+ ] keep ;
+
+: odbc-connect ( env dsn -- dbc )
+ >r alloc-dbc-handle dup r>
+ f swap dup length 1024 temp-string 0 <short> SQL-DRIVER-NOPROMPT
+ SQLDriverConnect succeeded? [ "odbc-connect failed" throw ] unless ;
+
+: odbc-disconnect ( dbc -- )
+ SQLDisconnect succeeded? [ "odbc-disconnect failed" throw ] unless ;
+
+: odbc-prepare ( dbc string -- statement )
+ >r alloc-stmt-handle dup r> dup length SQLPrepare succeeded? [ "odbc-prepare failed" throw ] unless ;
+
+: odbc-free-statement ( statement -- )
+ SQL-HANDLE-STMT swap SQLFreeHandle succeeded? [ "odbc-free-statement failed" throw ] unless ;
+
+: odbc-execute ( statement -- )
+ SQLExecute succeeded? [ "odbc-execute failed" throw ] unless ;
+
+: odbc-next-row ( statement -- bool )
+ SQLFetch succeeded? ;
+
+: odbc-number-of-columns ( statement -- number )
+ 0 <short> [ SQLNumResultCols succeeded? ] keep swap [
+ *short
+ ] [
+ drop f
+ ] if ;
+
+TUPLE: column nullable digits size type name number ;
+
+C: <column> column
+
+: odbc-describe-column ( statement n -- column )
+ dup >r
+ 1024 CHAR: \space <string> ascii string>alien dup >r
+ 1024
+ 0 <short>
+ 0 <short> dup >r
+ 0 <uint> dup >r
+ 0 <short> dup >r
+ 0 <short> dup >r
+ SQLDescribeCol succeeded? [
+ r> *short
+ r> *short
+ r> *uint
+ r> *short convert-sql-type
+ r> ascii alien>string
+ r> <column>
+ ] [
+ r> drop r> drop r> drop r> drop r> drop r> drop
+ "odbc-describe-column failed" throw
+ ] if ;
+
+: dereference-type-pointer ( byte-array column -- object )
+ type>> {
+ { SQL-CHAR [ ascii alien>string ] }
+ { SQL-VARCHAR [ ascii alien>string ] }
+ { SQL-LONGVARCHAR [ ascii alien>string ] }
+ { SQL-WCHAR [ ascii alien>string ] }
+ { SQL-WCHARVAR [ ascii alien>string ] }
+ { SQL-WLONGCHARVAR [ ascii alien>string ] }
+ { SQL-SMALLINT [ *short ] }
+ { SQL-INTEGER [ *long ] }
+ { SQL-REAL [ *float ] }
+ { SQL-FLOAT [ *double ] }
+ { SQL-DOUBLE [ *double ] }
+ { SQL-TINYINT [ *char ] }
+ { SQL-BIGINT [ *longlong ] }
+ [ nip [ "Unknown SQL Type: " % name>> % ] "" make ]
+ } case ;
+
+TUPLE: field value column ;
+
+C: <field> field
+
+: odbc-get-field ( statement column -- field )
+ dup column? [ dupd odbc-describe-column ] unless dup >r number>>
+ SQL-C-DEFAULT
+ 8192 CHAR: \space <string> ascii string>alien dup >r
+ 8192
+ f SQLGetData succeeded? [
+ r> r> [ dereference-type-pointer ] keep <field>
+ ] [
+ r> drop r> [
+ "SQLGetData Failed for Column: " %
+ dup name>> %
+ " of type: " % dup type>> name>> %
+ ] "" make swap <field>
+ ] if ;
+
+: odbc-get-row-fields ( statement -- seq )
+ [
+ dup odbc-number-of-columns [
+ 1+ odbc-get-field value>> ,
+ ] with each
+ ] { } make ;
+
+: (odbc-get-all-rows) ( statement -- )
+ dup odbc-next-row [ dup odbc-get-row-fields , yield (odbc-get-all-rows) ] [ drop ] if ;
+
+: odbc-get-all-rows ( statement -- seq )
+ [ (odbc-get-all-rows) ] { } make ;
+
+: odbc-query ( string dsn -- result )
+ odbc-init swap odbc-connect [
+ swap odbc-prepare
+ dup odbc-execute
+ dup odbc-get-all-rows
+ swap odbc-free-statement
+ ] keep odbc-disconnect ;
--- /dev/null
+ODBC (Open DataBase Connectivity) binding
--- /dev/null
+
+USING: kernel sequences math math.order
+ ui.gadgets ui.gadgets.tracks ui.gestures
+ bake.fry accessors ;
+
+IN: ui.gadgets.tiling
+
+TUPLE: tiling < track gadgets tiles first focused ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: init-tiling ( tiling -- tiling )
+ init-track
+ { 1 0 } >>orientation
+ V{ } clone >>gadgets
+ 2 >>tiles
+ 0 >>first
+ 0 >>focused ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: <tiling> ( -- gadget ) tiling new init-tiling ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: bounded-subseq ( seq a b -- seq )
+ [ 0 max ] dip
+ pick length [ min ] curry bi@
+ rot
+ subseq ;
+
+: tiling-gadgets-to-map ( tiling -- gadgets )
+ [ gadgets>> ]
+ [ first>> ]
+ [ [ first>> ] [ tiles>> ] bi + ]
+ tri
+ bounded-subseq ;
+
+: tiling-map-gadgets ( tiling -- tiling )
+ dup clear-track
+ dup tiling-gadgets-to-map [ 1 track-add ] each ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: tiling-add ( tiling gadget -- tiling )
+ over gadgets>> push
+ tiling-map-gadgets ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: first-gadget ( tiling -- index ) drop 0 ;
+
+: last-gadget ( tiling -- index ) gadgets>> length 1 - ;
+
+: first-viewable ( tiling -- index ) first>> ;
+
+: last-viewable ( tiling -- index ) [ first>> ] [ tiles>> ] bi + 1 - ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: make-focused-mapped ( tiling -- tiling )
+
+ dup [ focused>> ] [ first>> ] bi <
+ [ dup first>> 1 - >>first ]
+ [ ]
+ if
+
+ dup [ last-viewable ] [ focused>> ] bi <
+ [ dup first>> 1 + >>first ]
+ [ ]
+ if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: check-focused-bounds ( tiling -- tiling )
+ dup focused>> 0 max over gadgets>> length 1 - min >>focused ;
+
+: focus-prev ( tiling -- tiling )
+ dup focused>> 1 - >>focused
+ check-focused-bounds
+ make-focused-mapped
+ tiling-map-gadgets
+ dup request-focus ;
+
+: focus-next ( tiling -- tiling )
+ dup focused>> 1 + >>focused
+ check-focused-bounds
+ make-focused-mapped
+ tiling-map-gadgets
+ dup request-focus ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: exchanged! ( seq a b -- )
+ [ 0 max ] bi@
+ pick length 1 - '[ _ min ] bi@
+ rot exchange ;
+
+: move-prev ( tiling -- tiling )
+ dup [ gadgets>> ] [ focused>> 1 - ] [ focused>> ] tri exchanged!
+ focus-prev ;
+
+: move-next ( tiling -- tiling )
+ dup [ gadgets>> ] [ focused>> ] [ focused>> 1 + ] tri exchanged!
+ focus-next ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: add-tile ( tiling -- tiling )
+ dup tiles>> 1 + >>tiles
+ tiling-map-gadgets ;
+
+: del-tile ( tiling -- tiling )
+ dup tiles>> 1 - 1 max >>tiles
+ tiling-map-gadgets ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+M: tiling focusable-child* ( tiling -- child/t )
+ [ focused>> ] [ gadgets>> ] bi nth ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: tiling-shelf < tiling ;
+TUPLE: tiling-pile < tiling ;
+
+: <tiling-shelf> ( -- gadget )
+ tiling-shelf new init-tiling { 1 0 } >>orientation ;
+
+: <tiling-pile> ( -- gadget )
+ tiling-pile new init-tiling { 0 1 } >>orientation ;
+
+tiling-shelf
+ H{
+ { T{ key-down f { A+ } "LEFT" } [ focus-prev drop ] }
+ { T{ key-down f { A+ } "RIGHT" } [ focus-next drop ] }
+ { T{ key-down f { S+ A+ } "LEFT" } [ move-prev drop ] }
+ { T{ key-down f { S+ A+ } "RIGHT" } [ move-next drop ] }
+ { T{ key-down f { C+ } "[" } [ del-tile drop ] }
+ { T{ key-down f { C+ } "]" } [ add-tile drop ] }
+ }
+set-gestures
+
+tiling-pile
+ H{
+ { T{ key-down f { A+ } "UP" } [ focus-prev drop ] }
+ { T{ key-down f { A+ } "DOWN" } [ focus-next drop ] }
+ { T{ key-down f { S+ A+ } "UP" } [ move-prev drop ] }
+ { T{ key-down f { S+ A+ } "DOWN" } [ move-next drop ] }
+ { T{ key-down f { C+ } "[" } [ del-tile drop ] }
+ { T{ key-down f { C+ } "]" } [ add-tile drop ] }
+ }
+set-gestures
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces arrays sequences math x11.xlib
+ mortar slot-accessors x ;
+
+IN: x.font
+
+SYMBOL: <font>
+
+<font> { "dpy" "name" "id" "struct" } accessors define-independent-class
+
+<font> "create" !( name <font> -- font ) [
+new-empty swap >>name dpy get >>dpy
+dpy get $ptr over $name XLoadQueryFont >>struct
+dup $struct XFontStruct-fid >>id
+] add-class-method
+
+<font> {
+
+"ascent" !( font -- ascent ) [ $struct XFontStruct-ascent ]
+
+"descent" !( font -- ascent ) [ $struct XFontStruct-descent ]
+
+"height" !( font -- ascent ) [ dup <- ascent swap <- descent + ]
+
+"text-width" !( font string -- width ) [ >r $struct r> dup length XTextWidth ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces arrays x11.xlib mortar mortar.sugar
+ slot-accessors x x.font ;
+
+IN: x.gc
+
+SYMBOL: <gc>
+
+<gc> { "dpy" "ptr" "font" } accessors define-independent-class
+
+<gc> "create" !( <gc> -- gc ) [
+new-empty dpy get >>dpy
+dpy get $ptr dpy get $default-root $id 0 f XCreateGC >>ptr
+"6x13" <font> new* >>font
+] add-class-method
+
+<gc> {
+
+"set-subwindow-mode" !( gc mode -- gc )
+ [ >r dup $dpy $ptr over $ptr r> XSetSubwindowMode drop ]
+
+"set-function" !( gc function -- gc )
+ [ >r dup $dpy $ptr over $ptr r> XSetFunction drop ]
+
+"set-foreground" !( gc foreground -- gc )
+ [ >r dup $dpy $ptr over $ptr r> lookup-color XSetForeground drop ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+USING: kernel strings assocs sequences math ;
+
+IN: x.keysym-table
+
+: keysym-table ( -- table )
+H{ { HEX: FF08 "BACKSPACE" }
+ { HEX: FF09 "TAB" }
+ { HEX: FF0D "RETURN" }
+ { HEX: FF8D "ENTER" }
+ { HEX: FF1B "ESCAPE" }
+ { HEX: FFFF "DELETE" }
+ { HEX: FF50 "HOME" }
+ { HEX: FF51 "LEFT" }
+ { HEX: FF52 "UP" }
+ { HEX: FF53 "RIGHT" }
+ { HEX: FF54 "DOWN" }
+ { HEX: FF55 "PAGE-UP" }
+ { HEX: FF56 "PAGE-DOWN" }
+ { HEX: FF57 "END" }
+ { HEX: FF58 "BEGIN" }
+ { HEX: FFBE "F1" }
+ { HEX: FFBF "F2" }
+ { HEX: FFC0 "F3" }
+ { HEX: FFC1 "F4" }
+ { HEX: FFC2 "F5" }
+ { HEX: FFC3 "F6" }
+ { HEX: FFC4 "F7" }
+ { HEX: FFC5 "F8" }
+ { HEX: FFC6 "F9" }
+ { HEX: FFC7 "F10" }
+ { HEX: FFC8 "F11" }
+ { HEX: FFC9 "F12" }
+ { HEX: FFE1 "LEFT-SHIFT" }
+ { HEX: FFE2 "RIGHT-SHIFT" }
+ { HEX: FFE3 "LEFT-CONTROL" }
+ { HEX: FFE4 "RIGHT-CONTROL" }
+ { HEX: FFE5 "CAPSLOCK" }
+ { HEX: FFE9 "LEFT-ALT" }
+ { HEX: FFEA "RIGHT-ALT" }
+} ;
+
+: keysym>name ( keysym -- name )
+dup keysym-table at dup [ nip ] [ drop 1string ] if ;
+
+: name>keysym ( name -- keysym ) keysym-table value-at ;
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel arrays math.vectors mortar mortar.sugar x.gc slot-accessors geom.pos ;
+
+IN: x.pen
+
+SYMBOL: <pen>
+
+<pen> <pos> { "window" "gc" } accessors define-simple-class
+
+<pen> "create" !( window <pen> -- pen )
+[ new-empty swap >>window <gc> new* >>gc 0 0 2array >>pos ]
+add-class-method
+
+<pen> {
+
+"line-to" ! ( pen point -- pen )
+ [ 2dup >r dup $window swap dup $gc swap $pos r> <---- draw-line >>pos ]
+
+"line-by" ! ( pen offset -- pen )
+ [ 2dup >r dup $window swap dup $gc swap $pos dup r> v+ <---- draw-line
+ <-- move-by ]
+
+"draw-string" ! ( pen string -- pen )
+ [ >r dup dup $window swap dup $gc swap $pos r> <---- draw-string ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel combinators math x11.xlib
+ mortar mortar.sugar slot-accessors x.gc x.widgets.label ;
+
+IN: x.widgets.button
+
+SYMBOL: <button>
+
+<button>
+ <label>
+ { "action-1" "action-2" "action-3" } accessors
+define-simple-class
+
+<button> "create" !( <button> -- button ) [
+new-empty
+<gc> new* >>gc ExposureMask ButtonPressMask bitor >>mask <- init-widget
+] add-class-method
+
+<button> "handle-button-press" !( event button -- ) [
+{ { [ over XButtonEvent-button Button1 = ] [ nip $action-1 call ] }
+ { [ over XButtonEvent-button Button2 = ] [ nip $action-2 call ] }
+ { [ over XButtonEvent-button Button3 = ] [ nip $action-3 call ] } }
+cond
+] add-method
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel strings arrays sequences sequences.lib math x11.xlib
+ mortar mortar.sugar slot-accessors x x.pen x.widgets ;
+
+IN: x.widgets.keymenu
+
+SYMBOL: <keymenu>
+
+<keymenu> <widget> { "items" "pen" } accessors define-simple-class
+
+<keymenu> "create" !( <keymenu> -- keymenu )
+ [ new-empty <- keymenu-init ]
+add-class-method
+
+: numbers-and-letters ( -- seq )
+"1234567890abcdefghijklmnopqrstuvwxyz" [ 1string ] { } map-as ;
+
+<keymenu> {
+
+"keymenu-init" !( keymenu -- keymenu ) [
+ dup <pen> new* >>pen
+ ExposureMask KeyPressMask bitor >>mask
+ <- init-widget
+]
+
+"item-labels" !( keymenu -- labels ) [ $items [ first ] map ]
+
+"item-actions" !( keymenu -- actions ) [ $items [ second ] map ]
+
+"keymenu-labels" !( keymenu -- seq )
+[ numbers-and-letters swap <- item-labels [ " - " swap 3append ] 2map ]
+
+"reset-pen" !( keymenu -- keymenu ) [
+ dup $pen
+ 1 <-- set-x
+ dup $gc $font <- ascent 1+ <-- set-y
+ drop ]
+
+"handle-expose" !( event keymenu -- ) [
+ nip
+ <- reset-pen
+ dup $pen swap <- keymenu-labels
+ [ <-- draw-string dup $gc $font <- height <-- move-by-y ] each drop ]
+
+"keymenu-handle-key-press" !( event keymenu -- ) [
+ swap 0 key-event-to-string numbers-and-letters index
+ [ swap <- item-actions ?nth [ call ] when* ]
+ [ drop ]
+ if* ]
+
+"handle-key-press" !( event keymenu -- ) [ <- keymenu-handle-key-press ]
+
+"calc-height" !( keymenu -- height )
+ [ dup $items length swap $pen $gc $font <- height * ]
+
+"calc-width" !( keymenu -- width )
+ [ dup $pen $gc $font
+ swap $items [ first " " append ] map
+ dup empty? [ drop "" ] [ longest ] if
+ <-- text-width ]
+
+"calc-size" !( keymenu -- size )
+ [ dup <- calc-width swap <- calc-height 2array ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel x11.xlib mortar mortar.sugar slot-accessors x.gc x.widgets ;
+
+IN: x.widgets.label
+
+SYMBOL: <label>
+
+<label> <widget> { "gc" "text" } accessors define-simple-class
+
+<label> "create" !( text <label> -- label ) [
+new-empty swap >>text <gc> new* >>gc ExposureMask >>mask <- init-widget
+] add-class-method
+
+<label> "handle-expose" !( event label -- ) [
+ nip <- clear dup $gc { 20 20 } pick $text <---- draw-string
+] add-method
--- /dev/null
+
+USING: kernel io namespaces arrays sequences combinators math x11.xlib
+ mortar slot-accessors x ;
+
+IN: x.widgets
+
+SYMBOL: <widget>
+
+<widget> <window> { "mask" } accessors define-simple-class
+
+<widget> {
+
+"init-widget" !( widget -- widget )
+ [ <- init-window <- add-to-window-table dup $mask <-- select-input ]
+
+"add-to-window-table" !( window -- window )
+ [ dup $dpy over <-- add-to-window-table ]
+
+"remove-from-window-table" !( window -- window )
+ [ dup $dpy over <-- remove-from-window-table ]
+
+"handle-event" !( event widget -- ) [
+ over XAnyEvent-type
+ { { [ dup Expose = ] [ drop <- handle-expose ] }
+ { [ dup KeyPress = ] [ drop <- handle-key-press ] }
+ { [ dup ButtonPress = ] [ drop <- handle-button-press ] }
+ { [ dup EnterNotify = ] [ drop <- handle-enter-window ] }
+ { [ dup DestroyNotify = ] [ drop <- handle-destroy-window ] }
+ { [ dup MapRequest = ] [ drop <- handle-map-request ] }
+ { [ dup MapNotify = ] [ drop <- handle-map ] }
+ { [ dup ConfigureRequest = ] [ drop <- handle-configure-request ] }
+ { [ dup UnmapNotify = ] [ drop <- handle-unmap ] }
+ { [ dup PropertyNotify = ] [ drop <- handle-property ] }
+ { [ t ] [ "handle-event :: ignoring event"
+ print flush 3drop ] }
+ } cond ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel io namespaces arrays sequences
+ x11.xlib mortar slot-accessors x x.widgets ;
+
+IN: x.widgets.wm.child
+
+SYMBOL: <wm-child>
+
+<wm-child> <widget> { } define-simple-class
+
+<wm-child> "create" !( id <wm-child> -- wm-child ) [
+ new-empty swap >>id dpy get >>dpy PropertyChangeMask >>mask
+ <- add-to-save-set
+ 0 <-- set-border-width
+ <- add-to-window-table
+ dup $mask <-- select-input
+] add-class-method
+
+<wm-child> "handle-property" !( event wm-child -- ) [
+ drop
+ "child handle-property :: atom name = " write
+ XPropertyEvent-atom get-atom-name print flush
+] add-method
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces arrays sequences combinators math.vectors
+ x11.xlib x11.constants
+ mortar slot-accessors x x.gc geom.rect ;
+
+IN: x.widgets.wm.frame.drag
+
+SYMBOL: <wm-frame-drag>
+
+<wm-frame-drag>
+ { "dpy" "gc" "frame" "event" "push" "posn" } accessors
+define-independent-class
+
+<wm-frame-drag> {
+
+"next-event" !( wfdm -- wfdm ) [ dup $dpy over $event <-- next-event 2drop ]
+
+"event-type" !( wfdm -- wfdm event-type ) [ dup $event XAnyEvent-type ]
+
+"drag-offset" !( wfdm -- offset ) [ dup $posn swap $push v- ]
+
+"update-posn" !( wfd -- wfd ) [ dup $event XMotionEvent-root-position >>posn ]
+
+} add-methods
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel combinators namespaces math.vectors x11.xlib x11.constants
+ mortar mortar.sugar slot-accessors x x.gc x.widgets.wm.frame.drag ;
+
+IN: x.widgets.wm.frame.drag.move
+
+SYMBOL: <wm-frame-drag-move>
+
+<wm-frame-drag-move> <wm-frame-drag> { } define-simple-class
+
+<wm-frame-drag-move> "create" !( event frame <wm-frame-drag-move> -- ) [
+ new-empty swap >>frame swap >>event dup $frame $dpy >>dpy
+
+ <gc> new*
+ IncludeInferiors <-- set-subwindow-mode
+ GXxor <-- set-function
+ "white" <-- set-foreground
+ >>gc
+
+ dup $event XButtonEvent-root-position >>push
+ dup $event XButtonEvent-root-position >>posn
+ <- draw-move-outline
+ <- loop
+] add-class-method
+
+<wm-frame-drag-move> {
+
+"move-outline" !( wfdm -- rect )
+ [ dup $frame <- as-rect swap <- drag-offset <-- move-by ]
+
+"draw-move-outline" !( wfdm -- wfdm )
+ [ dpy get $default-root over $gc pick <- move-outline <--- draw-rect ]
+
+"loop" !( wfdm -- wfdm ) [
+ <- next-event
+ { { [ <- event-type MotionNotify = ]
+ [ <- draw-move-outline <- update-posn <- draw-move-outline <- loop ] }
+ { [ <- event-type ButtonRelease = ]
+ [ <- draw-move-outline
+ dup $frame <- position over <- drag-offset v+ >r
+ dup $frame r> <-- move drop
+ dup $frame <- raise drop drop ] }
+ { [ t ] [ <- loop ] } }
+ cond ]
+
+} add-methods
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel combinators namespaces math.vectors x11.xlib x11.constants
+ mortar mortar.sugar slot-accessors geom.rect x x.gc x.widgets.wm.frame.drag ;
+
+IN: x.widgets.wm.frame.drag.size
+
+SYMBOL: <wm-frame-drag-size>
+
+<wm-frame-drag-size> <wm-frame-drag> { } define-simple-class
+
+<wm-frame-drag-size> "create" !( event frame <wfds> -- ) [
+ new-empty swap >>frame swap >>event
+ dup $frame $dpy >>dpy
+
+ <gc> new*
+ IncludeInferiors <-- set-subwindow-mode
+ GXxor <-- set-function
+ "white" <-- set-foreground
+ >>gc
+
+ dup $event XButtonEvent-root-position >>push
+ dup $event XButtonEvent-root-position >>posn
+ <- draw-size-outline <- loop
+] add-class-method
+
+<wm-frame-drag-size> {
+
+"size-outline" !( wfds -- rect )
+ [ dup $frame <- position swap $posn over v- <rect> new ]
+
+"draw-size-outline" !( wfdm -- wfdm )
+ [ dup $dpy $default-root over $gc pick <- size-outline <--- draw-rect ]
+
+"loop" !( wfdm -- ) [
+ <- next-event
+ { { [ <- event-type MotionNotify = ]
+ [ <- draw-size-outline <- update-posn <- draw-size-outline <- loop ] }
+ { [ <- event-type ButtonRelease = ]
+ [ <- draw-size-outline
+ dup $frame over $posn pick $frame <- position v- <-- resize
+ <- adjust-child drop ] }
+ { [ t ] [ <- loop ] } }
+ cond ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+
+USING: kernel io combinators namespaces quotations arrays sequences
+ math math.vectors
+ x11.xlib x11.constants
+ mortar mortar.sugar slot-accessors
+ geom.rect
+ math.bitwise
+ x x.gc x.widgets
+ x.widgets.button
+ x.widgets.wm.child
+ x.widgets.wm.frame.drag.move
+ x.widgets.wm.frame.drag.size ;
+
+IN: x.widgets.wm.frame
+
+SYMBOL: <wm-frame>
+
+<wm-frame> <widget> { "child" "gc" "last-state" } accessors define-simple-class
+
+<wm-frame> "create" !( id <wm-frame> -- wm-frame ) [
+ new-empty
+ swap <wm-child> new* >>child
+ <gc> new* "white" <-- set-foreground >>gc
+
+ {
+ SubstructureRedirectMask
+ ExposureMask
+ ButtonPressMask
+ ButtonReleaseMask
+ ButtonMotionMask
+ EnterWindowMask
+ ! experimental masks
+ SubstructureNotifyMask
+ } flags
+ >>mask
+
+ <- init-widget
+ "cornflowerblue" <-- set-background
+ dup $child <- position <-- move
+ dup $child over <-- reparent drop
+ <- position-child
+ <- fit-to-child
+ <- make-frame-button
+
+ <- map-subwindows
+ <- map
+] add-class-method
+
+SYMBOL: WM_PROTOCOLS
+SYMBOL: WM_DELETE_WINDOW
+
+: init-atoms ( -- )
+"WM_PROTOCOLS" 0 intern-atom WM_PROTOCOLS set
+"WM_DELETE_WINDOW" 0 intern-atom WM_DELETE_WINDOW set ;
+
+<wm-frame> {
+
+"fit-to-child" !( wm-frame -- wm-frame )
+ [ dup $child <- size { 10 20 } v+ <-- resize ]
+
+"position-child" !( wm-frame -- wm-frame )
+ [ dup $child { 5 15 } <-- move drop ]
+
+"set-child-size" !( wm-frame size -- frame )
+ [ >r dup $child r> <-- resize drop <- fit-to-child ]
+
+"set-child-width" !( wm-frame width -- frame )
+ [ >r dup $child r> <- set-width drop <- fit-to-child ]
+
+"set-child-height" !( wm-frame height -- frame )
+ [ >r dup $child r> <- set-height drop <- fit-to-child ]
+
+"adjust-child" !( wm-frame -- wm-frame )
+ [ dup $child over <- size { 10 20 } v- <-- resize drop ]
+
+"update-title" !( wm-frame -- wm-frame )
+ [ <- clear
+ dup >r
+ ! dup $gc { 5 1 } pick $child <- fetch-name <--- draw-string/top-left
+ dup $gc { 5 11 } pick $child <- fetch-name <---- draw-string
+ r> ]
+
+"delete-child" !( wm-frame -- wm-frame ) [
+ dup $child WM_PROTOCOLS get WM_DELETE_WINDOW get <--- send-client-message
+ drop ]
+
+"drag-move" !( event wm-frame -- ) [ <wm-frame-drag-move> new* ]
+
+"drag-size" !( event wm-frame -- ) [ <wm-frame-drag-size> new* ]
+
+"make-frame-button" !( frame -- frame ) [
+<button> new*
+ over <-- reparent
+ "" >>text
+ over [ <- unmap drop ] curry >>action-1
+ over [ <- delete-child drop ] curry >>action-3
+ { 9 9 } <-- resize
+ NorthEastGravity <-- set-gravity
+ "white" <-- set-background
+ over <- width 9 - 5 - 3 2array <-- move
+ drop ]
+
+! !!!!!!!!!! Event handlers !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+"handle-enter-window" !( event wm-frame -- )
+ [ nip $child RevertToPointerRoot CurrentTime <--- set-input-focus drop ]
+
+"handle-expose" !( event wm-frame -- ) [ nip <- clear <- update-title drop ]
+
+"handle-button-press" !( event wm-frame -- ) [
+ over XButtonEvent-button
+ { { [ dup Button1 = ] [ drop <- drag-move ] }
+ { [ dup Button2 = ] [ drop <- drag-size ] }
+ { [ t ] [ 3drop ] } }
+ cond ]
+
+"handle-map" !( event wm-frame -- )
+ [ "<wm-frame> handle-map :: ignoring values" print flush 2drop ]
+
+"handle-unmap" !( event wm-frame -- ) [ nip <- unmap drop ]
+
+"handle-destroy-window" !( event wm-frame -- ) [
+ nip dup $child <- remove-from-window-table drop
+ <- remove-from-window-table <- destroy ]
+
+"handle-configure-request" !( event frame -- ) [
+ { { [ over dup CWX? swap CWY? and ]
+ [ over XConfigureRequestEvent-position <-- move ] }
+ { [ over CWX? ] [ over XConfigureRequestEvent-x <-- set-x ] }
+ { [ over CWY? ] [ over XConfigureRequestEvent-y <-- set-y ] }
+ { [ t ] [ "<wm-frame> handle-configure-request :: move not requested"
+ print flush ] } }
+ cond
+
+ { { [ over dup CWWidth? swap CWHeight? and ]
+ [ over XConfigureRequestEvent-size <-- set-child-size ] }
+ { [ over CWWidth? ]
+ [ over XConfigureRequestEvent-width <-- set-child-width ] }
+ { [ over CWHeight? ]
+ [ over XConfigureRequestEvent-height <-- set-child-height ] }
+ { [ t ]
+ [ "<wm-frame> handle-configure-request :: resize not requested"
+ print flush ] } }
+ cond
+ 2drop ]
+
+} add-methods
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: wm-frame-maximize ( wm-frame -- wm-frame )
+<- save-state
+{ 0 0 } <-- move
+dup $dpy $default-root <- size
+ <-- resize
+<- adjust-child
+<- raise ;
+
+: wm-frame-maximize-vertical ( wm-frame -- wm-frame )
+0 <-- set-y
+dup $dpy $default-root <- height
+ <-- set-height
+<- adjust-child ;
+
+<wm-frame> "save-state" !( wm-frame -- wm-frame ) [
+ dup <- position
+ over <- size
+ <rect> new
+ >>last-state
+] add-method
+
+<wm-frame> "restore-state" !( wm-frame -- wm-frame ) [
+ dup $last-state $pos <-- move
+ dup $last-state $dim <-- resize
+ <- adjust-child
+] add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel x11.constants mortar mortar.sugar slot-accessors x.widgets.keymenu ;
+
+IN: x.widgets.wm.menu
+
+SYMBOL: <wm-menu>
+
+<wm-menu> <keymenu> { } define-simple-class
+
+<wm-menu> "create" !( <wm-menu> -- wm-menu )
+ [ new-empty <- keymenu-init ]
+add-class-method
+
+<wm-menu> {
+
+"wm-menu-handle-key-press" !( event wm-menu -- )
+ [ <- unmap <- keymenu-handle-key-press ]
+
+"handle-key-press" !( event wm-menu -- ) [ <- wm-menu-handle-key-press ]
+
+"wm-menu-popup" !( wm-menu -- wm-menu )
+ [ <- map <- raise RevertToPointerRoot CurrentTime <--- set-input-focus ]
+
+"popup" !( wm-menu -- wm-menu ) [ <- wm-menu-popup ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel io combinators namespaces arrays assocs sequences math
+ x11.xlib
+ x11.constants
+ vars mortar slot-accessors
+ x x.keysym-table x.widgets x.widgets.wm.child x.widgets.wm.frame ;
+
+IN: x.widgets.wm.root
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: <wm-root>
+
+<wm-root>
+ <widget>
+ { "keymap" } accessors
+define-simple-class
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: wm-root
+
+: create-wm-root ( -- )
+ <wm-root> new-empty
+ dpy> >>dpy
+ dpy> $default-root $id >>id
+ SubstructureRedirectMask >>mask
+ <- add-to-window-table
+ SubstructureRedirectMask <-- select-input
+ H{ } clone >>keymap
+ >wm-root ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: find-in-table ( window -- object )
+dup >r $id dpy get $window-table at r> or ;
+
+: circulate-focus ( -- )
+dpy get $default-root <- children
+[ find-in-table ] map [ <- mapped? ] filter dup length 1 >
+[ reverse dup first <- lower drop
+ second <- raise
+ dup <wm-frame> is? [ $child ] [ ] if
+ RevertToPointerRoot CurrentTime <--- set-input-focus drop ]
+[ drop ]
+if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: managed? ( id -- ? )
+dpy get $window-table values [ <wm-child> is? ] filter [ $id ] map member? ;
+
+: event>keyname ( event -- keyname ) lookup-keysym keysym>name ;
+
+: event>state-and-name ( event -- array )
+dup XKeyEvent-state swap event>keyname 2array ;
+
+: resolve-key-event ( keymap event -- item ) event>state-and-name swap at ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<wm-root> {
+
+"handle-map-request" !( event wm-root -- ) [
+ { { [ over XMapRequestEvent-window managed? ]
+ [ "<wm-root> handle-map-request :: window already managed" print flush
+ 2drop ] }
+ { [ t ] [ drop XMapRequestEvent-window <wm-frame> <<- create drop ] } }
+ cond ]
+
+"handle-unmap" !( event wm-root -- ) [ 2drop ]
+
+"handle-key-press" !( event wm-root -- )
+ [ $keymap swap resolve-key-event call ]
+
+"grab-key" !( wm-root modifiers keyname -- wm-root modifiers keyname ) [
+ 3dup name>keysym keysym-to-keycode spin
+ False GrabModeAsync GrabModeAsync grab-key ]
+
+"set-key-action" !( wm-root modifiers keyname action -- wm-root ) [
+ >r <--- grab-key r>
+ -rot 2array pick $keymap set-at ]
+
+"handle-configure-request" !( event wm-root -- ) [
+ $dpy over XConfigureRequestEvent-window <window> new ! event window
+ { { [ over dup CWX? swap CWY? and ]
+ [ over XConfigureRequestEvent-position <-- move ] }
+ { [ over CWX? ] [ over XConfigureRequestEvent-x <-- set-x ] }
+ { [ over CWY? ] [ over XConfigureRequestEvent-y <-- set-y ] }
+ { [ t ] [ "<wm-root> handle-configure-request :: move not requested"
+ print flush ] } }
+ cond
+
+ { { [ over dup CWWidth? swap CWHeight? and ]
+ [ over XConfigureRequestEvent-size <-- resize ] }
+ { [ over CWWidth? ] [ over XConfigureRequestEvent-width <-- set-width ] }
+ { [ over CWHeight? ] [ over XConfigureRequestEvent-height <-- set-height ] }
+ { [ t ] [ "<wm-root> handle-configure-request :: resize not requested"
+ print flush ] } }
+ cond
+ 2drop ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces quotations arrays assocs sequences
+ mortar slot-accessors x x.widgets.wm.menu x.widgets.wm.frame
+ vars ;
+
+IN: x.widgets.wm.unmapped-frames-menu
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: <unmapped-frames-menu>
+
+<unmapped-frames-menu> <wm-menu> { } define-simple-class
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+VAR: unmapped-frames-menu
+
+: create-unmapped-frames-menu ( -- )
+<unmapped-frames-menu>
+ new-empty
+ <- keymenu-init
+ 1 <-- set-border-width
+>unmapped-frames-menu ;
+
+: unmapped-frames ( -- seq )
+dpy get $window-table values
+[ <wm-frame> is? ] filter [ <- mapped? not ] filter ;
+
+<unmapped-frames-menu> {
+
+"refresh" !( menu -- menu ) [
+ unmapped-frames dup
+ [ $child <- fetch-name ] map swap
+ [ [ <- map ] curry ] map
+ [ 2array ] 2map
+ >>items
+ dup <- calc-size <-- resize ]
+
+"popup" !( menu -- menu ) [ <- refresh <- wm-menu-popup ]
+
+} add-methods
\ No newline at end of file
--- /dev/null
+Eduardo Cavazos
--- /dev/null
+
+USING: kernel namespaces namespaces.lib math sequences vars mortar
+accessors slot-accessors x ;
+
+IN: x.widgets.wm.workspace
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+TUPLE: workspace windows ;
+
+C: <workspace> workspace
+
+VAR: workspaces
+
+VAR: current-workspace
+
+: init-workspaces ( -- ) V{ } clone >workspaces ;
+
+: add-workspace ( -- ) { } clone <workspace> workspaces> push ;
+
+: mapped-windows ( -- seq )
+dpy get $default-root <- children [ <- mapped? ] filter ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: switch-to-workspace ( n -- )
+mapped-windows current-workspace> workspaces> nth (>>windows)
+mapped-windows [ <- unmap drop ] each
+dup workspaces> nth windows>> [ <- map drop ] each
+current-workspace set* ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: next-workspace ( -- )
+current-workspace> 1+ dup workspaces> length <
+[ switch-to-workspace ] [ drop ] if ;
+
+: prev-workspace ( -- )
+current-workspace> 1- dup 0 >=
+[ switch-to-workspace ] [ drop ] if ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: setup-workspaces ( n -- )
+workspaces>
+ [ drop ]
+ [ init-workspaces [ add-workspace ] times 0 >current-workspace ]
+if ;
\ No newline at end of file
--- /dev/null
+
+USING: kernel io alien alien.c-types alien.strings namespaces threads
+ arrays sequences assocs math vars combinators.lib
+ x11.constants x11.events x11.xlib mortar slot-accessors geom.rect
+ io.encodings.ascii ;
+
+IN: x
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SYMBOL: <display>
+
+SYMBOL: <window>
+
+! SYMBOL: dpy
+
+VAR: dpy
+
+<display>
+ { "ptr"
+ "name"
+ "default-screen"
+ "default-root"
+ "default-gc"
+ "black-pixel"
+ "white-pixel"
+ "colormap"
+ "window-table" } accessors
+define-independent-class
+
+<display> "create" !( name <display> -- display ) [
+ new-empty swap >>name
+ dup $name dup [ ascii string>alien ] [ ] if XOpenDisplay
+ dup [ >>ptr ] [ "XOpenDisplay error" throw ] if
+ dup $ptr XDefaultScreen >>default-screen
+ dup $ptr XDefaultRootWindow dupd <window> new >>default-root
+ dup $ptr over $default-screen XDefaultGC >>default-gc
+ dup $ptr over $default-screen XBlackPixel >>black-pixel
+ dup $ptr over $default-screen XWhitePixel >>white-pixel
+ dup $ptr over $default-screen XDefaultColormap >>colormap
+ H{ } clone >>window-table
+ [ <- start-event-loop ] in-thread
+] add-class-method
+
+{ "id" } accessors drop
+
+DEFER: check-window-table
+
+<display> {
+
+"add-to-window-table" !( display window -- )
+ [ dup $id rot $window-table set-at ]
+
+"remove-from-window-table" !( display window -- )
+ [ $id swap $window-table delete-at ]
+
+"next-event" !( display event -- display event )
+ [ over $ptr over XNextEvent drop ]
+
+"events-queued" !( display mode -- n ) [ >r $ptr r> XEventsQueued ]
+
+"concurrent-next-event" !( display event -- display event )
+ [ over QueuedAfterFlush <-- events-queued 0 >
+ [ <-- next-event ] [ 100 sleep <-- concurrent-next-event ] if ]
+
+"event-loop" !( display event -- )
+[ <-- concurrent-next-event
+ 2dup >r >r
+ dup XAnyEvent-window rot $window-table at dup
+ [ <- handle-event ] [ 2drop ] if
+ r> r>
+ <-- event-loop ]
+
+"start-event-loop" !( display -- ) [ "XEvent" <c-object> <-- event-loop ]
+
+"flush" !( display -- display ) [ dup $ptr XFlush drop ]
+
+"pointer-window" !( display -- window ) [
+ dup $ptr
+ over $default-root $id
+ 0 <Window>
+ 0 <Window> dup >r
+ 0 <int>
+ 0 <int>
+ 0 <int>
+ 0 <int>
+ 0 <uint>
+ XQueryPointer drop
+ r> *Window <window> new
+ check-window-table ]
+
+} add-methods
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<window> { "dpy" "id" } accessors define-independent-class
+
+: create-window ( -- window ) <window> new-empty <- init-window ;
+
+: create-window-from-id ( dpy id -- window ) <window> new ;
+
+: check-window-table ( window -- window )
+ dup $id
+ over $dpy $window-table
+ at
+ swap or ;
+
+<window> "init-window"
+ !( window -- window )
+ [ dpy get
+ >>dpy
+ dpy get $ptr
+ dpy get $default-root $id
+ 0 0 100 100 0
+ dpy get $black-pixel
+ dpy get $white-pixel
+ XCreateSimpleWindow
+ >>id ]
+add-method
+
+! <window> new-empty <- init
+
+<window> "raw"
+ !( window -- dpy-ptr id )
+ [ dup $dpy $ptr swap $id ]
+add-method
+
+<window> "move"
+ !( window point -- window )
+ [ >r dup <- raw r> first2 XMoveWindow drop ]
+add-method
+
+<window> "set-x" !( window x -- window ) [
+ over <- y 2array <-- move
+] add-method
+
+<window> "set-y" !( window y -- window ) [
+ over <- x swap 2array <-- move
+] add-method
+
+<window> "flush"
+ !( window -- window )
+ [ dup $dpy <- flush drop ]
+add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 3 - Window Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! 3.3 - Creating Windows
+
+<window> "destroy" !( window -- window )
+ [ dup <- raw XDestroyWindow drop ]
+add-method
+
+<window> "map"
+ !( window -- window )
+ [ dup <- raw XMapWindow drop ]
+add-method
+
+<window> "map-subwindows"
+ !( window -- window )
+ [ dup <- raw XMapSubwindows drop ]
+add-method
+
+<window> "unmap"
+ !( window -- window )
+ [ dup <- raw XUnmapWindow drop ]
+add-method
+
+<window> "unmap-subwindows"
+ !( window -- window )
+ [ dup <- raw XUnmapSubwindows drop ]
+add-method
+
+! 3.7 - Configuring Windows
+
+<window> "resize"
+ !( window size -- window )
+ [ >r dup <- raw r> first2 XResizeWindow drop ]
+add-method
+
+<window> "set-width"
+ !( window width -- window )
+ [ over <- height 2array <-- resize ]
+add-method
+
+<window> "set-height"
+ !( window height -- window )
+ [ over <- width swap 2array <-- resize ]
+add-method
+
+<window> "set-border-width"
+ !( window n -- window )
+ [ >r dup <- raw r> XSetWindowBorderWidth drop ]
+add-method
+
+! 3.8 Changing Window Stacking Order
+
+<window> "raise"
+ !( window -- window )
+ [ dup <- raw XRaiseWindow drop ]
+add-method
+
+<window> "lower"
+ !( window -- window )
+ [ dup <- raw XLowerWindow drop ]
+add-method
+
+! 3.9 - Changing Window Attributes
+
+! : change-window-attributes ( valuemask attr window -- )
+! -rot >r >r <- raw r> r> XChangeWindowAttributes drop ;
+
+<window> "change-attributes" !( window valuemask attr -- window ) [
+>r >r dup <- raw r> r> XChangeWindowAttributes drop
+] add-method
+
+DEFER: lookup-color
+
+<window> "set-background"
+ !( window color -- window )
+ [ >r dup <- raw r> lookup-color XSetWindowBackground drop ]
+add-method
+
+<window> "set-gravity" !( window gravity -- window ) [
+CWWinGravity swap
+"XSetWindowAttributes" <c-object> tuck set-XSetWindowAttributes-win_gravity
+<--- change-attributes
+] add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 4 - Window Information Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! 4.1 - Obtaining Window Information
+
+<window> {
+
+"children" !( window -- seq )
+ [ <- raw 0 <uint> 0 <uint> f <void*> 0 <uint> 2dup >r >r XQueryTree drop
+ r> r> swap *void* swap *uint c-uint-array>
+ [ dpy get swap <window> new ] map ]
+
+"parent" !( window -- parent ) [
+ dup $dpy >r
+
+ dup $dpy $ptr
+ swap $id
+ 0 <Window>
+ 0 <Window> dup >r
+ f <void*>
+ 0 <uint>
+ XQueryTree drop
+ r> *Window
+ r> swap
+ <window> new
+ check-window-table ]
+
+"size" !( window -- size )
+ [ <- raw 0 <Window> 0 <int> 0 <int>
+ 0 <uint> 0 <uint> 2dup 2array >r
+ 0 <uint> 0 <uint>
+ XGetGeometry drop r> [ *uint ] map ]
+
+"width" !( window -- width ) [ <- size first ]
+
+"height" !( window -- height ) [ <- size second ]
+
+"position" !( window -- position )
+ [ <- raw 0 <Window>
+ 0 <uint> 0 <uint> 2dup 2array >r
+ 0 <uint> 0 <uint> 0 <uint> 0 <uint>
+ XGetGeometry drop r> [ *int ] map ]
+
+"x" !( window -- x ) [ <- position first ]
+
+"y" !( window -- y ) [ <- position second ]
+
+"as-rect" !( window -- rect ) [ dup <- position swap <- size <rect> new ]
+
+"attributes" !( window -- XWindowAttributes )
+ [ <- raw "XWindowAttributes" <c-object> dup >r XGetWindowAttributes drop r> ]
+
+"map-state" !( window -- state ) [ <- attributes XWindowAttributes-map_state ]
+
+"mapped?" !( window -- ? ) [ <- map-state IsUnmapped = not ]
+
+} add-methods
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: get-atom-name ( atom -- name ) dpy get $ptr swap XGetAtomName ;
+
+: intern-atom ( atom-name only-if-exists? -- atom )
+dpy get $ptr -rot XInternAtom ;
+
+: lookup-color ( name -- pixel )
+dpy get $ptr dpy get $colormap rot
+"XColor" <c-object> dup >r "XColor" <c-object> XLookupColor drop
+dpy get $ptr dpy get $colormap r> dup >r XAllocColor drop r> XColor-pixel ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 8 - Graphics Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<window> "clear"
+ !( window -- window )
+ [ dup <- raw XClearWindow drop ]
+add-method
+
+<window> "draw-string"
+ !( window gc pos string -- )
+ [ >r >r >r <- raw r> $ptr r> [ >fixnum ] map first2 r> dup length
+ XDrawString drop ]
+add-method
+
+! <window> "draw-string"
+! !( window gc pos string -- )
+! [ >r >r >r <- raw r> $ptr r> [ >fixnum ] map first2 r> dup length
+! XDrawString drop ]
+! add-method
+
+<window> "draw-line"
+ !( window gc a b -- )
+ [ >r >r >r <- raw r> $ptr r> first2 r> first2 XDrawLine drop ]
+add-method
+
+<window> "draw-rect"
+ !( window gc rect -- )
+ [ 3dup dup <- top-left swap <- top-right <---- draw-line
+ 3dup dup <- top-right swap <- bottom-right <---- draw-line
+ 3dup dup <- bottom-left swap <- bottom-right <---- draw-line
+ dup <- top-left swap <- bottom-left <---- draw-line ]
+add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 9 - Window and Session Manager Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<window> "reparent"
+ !( window parent -- window )
+ [ >r dup <- raw r> $id 0 0 XReparentWindow drop ]
+add-method
+
+<window> "add-to-save-set" !( window -- window ) [
+ dup <- raw XAddToSaveSet drop
+] add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 10 - Events
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: XButtonEvent-root-position ( event -- position )
+dup XButtonEvent-x_root swap XButtonEvent-y_root 2array ;
+
+: XMotionEvent-root-position ( event -- position )
+dup XMotionEvent-x_root swap XMotionEvent-y_root 2array ;
+
+! Utility words for XConfigureRequestEvent
+
+: XConfigureRequestEvent-position ( XConfigureRequestEvent -- position )
+dup XConfigureRequestEvent-x swap XConfigureRequestEvent-y 2array ;
+
+: XConfigureRequestEvent-size ( XConfigureRequestEvent -- size )
+dup XConfigureRequestEvent-width swap XConfigureRequestEvent-height 2array ;
+
+: bit-test ( a b -- t-or-f ) bitand 0 = not ;
+
+: CWX? ( XConfigureRequestEvent -- bool )
+XConfigureRequestEvent-value_mask CWX bit-test ;
+
+: CWY? ( XConfigureRequestEvent -- bool )
+XConfigureRequestEvent-value_mask CWY bit-test ;
+
+: CWWidth? ( XConfigureRequestEvent -- bool )
+XConfigureRequestEvent-value_mask CWWidth bit-test ;
+
+: CWHeight? ( XConfigureRequestEvent -- bool )
+XConfigureRequestEvent-value_mask CWHeight bit-test ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 11 - Event Handling Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<window> "select-input"
+ !( window mask -- window )
+ [ >r dup <- raw r> XSelectInput drop ]
+add-method
+
+! 11.8 - Handling Protocol Errors
+
+SYMBOL: error-handler-quot
+
+: error-handler-callback ( -- xt )
+"void" { "Display*" "XErrorEvent*" } "cdecl"
+[ error-handler-quot get call ] alien-callback ;
+
+: set-error-handler ( quot -- )
+error-handler-quot set error-handler-callback XSetErrorHandler drop ;
+
+: install-default-error-handler ( -- )
+[ "X11 : error-handler called" print flush ] set-error-handler ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 12 - Input Device Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! 12.2 - Keyboard Grabbing
+
+: grab-key
+( keycode modifiers grab-window owner-events pointer-mode keyboard-mode -- )
+>r >r >r <- raw >r -rot r> r> r> r> XGrabKey drop ;
+
+! 12.5 - Controlling Input Focus
+
+<window> "set-input-focus" !( window revert-to time -- window )
+ [ >r >r dup <- raw r> r> XSetInputFocus drop ]
+add-method
+
+: get-input-focus ( -- window )
+ dpy> $ptr
+ 0 <Window> dup >r
+ 0 <int>
+ XGetInputFocus drop
+ r> *Window
+ dpy> swap
+ create-window-from-id
+ check-window-table ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 14 - Inter-Client Communication Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+<window> "fetch-name" !( window -- name-or-f )
+ [ <- raw f <void*> dup >r XFetchName drop r>
+ dup *void* [ drop f ] [ *void* ascii alien>string ] if ]
+add-method
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 16 - Application Utility Functions
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! 16.1 - Using Keyboard Utility Functions
+
+! this should go in xlib.factor
+
+USING: alien.syntax ;
+
+FUNCTION: KeyCode XKeysymToKeycode ( Display* display, KeySym keysym ) ;
+
+FUNCTION: KeySym XKeycodeToKeysym ( Display* display,
+ KeyCode keycode,
+ int index ) ;
+
+FUNCTION: char* XKeysymToString ( KeySym keysym ) ;
+
+: keysym-to-keycode ( keysym -- keycode ) dpy get $ptr swap XKeysymToKeycode ;
+
+USE: strings
+
+: lookup-string* ( event -- keysym string )
+10 "char" <c-array> dup >r 10 0 <KeySym> dup >r f XLookupString
+r> *KeySym swap r> swap c-char-array> >string ;
+
+: lookup-string ( event -- string ) lookup-string* nip ;
+
+: lookup-keysym ( event -- keysym ) lookup-string* drop ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!7
+
+: event-to-keysym ( event index -- keysym )
+>r dup XKeyEvent-display swap XKeyEvent-keycode r> XKeycodeToKeysym ;
+
+: keysym-to-string ( keysym -- string ) XKeysymToString ;
+
+: key-event-to-string ( event index -- str ) event-to-keysym keysym-to-string ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! Misc
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+: no-modifiers ( -- mask ) 0 ;
+
+: control-alt ( -- mask ) ControlMask Mod1Mask bitor ;
+
+: alt ( -- mask ) Mod1Mask ;
+
+: True 1 ;
+: False 0 ;
+
+<window> "send-client-message" !( window message-type data -- window ) [
+
+"XClientMessageEvent" <c-object>
+
+tuck set-XClientMessageEvent-data0
+tuck set-XClientMessageEvent-message_type
+over $id over set-XClientMessageEvent-window
+ClientMessage over set-XClientMessageEvent-type
+32 over set-XClientMessageEvent-format
+CurrentTime over set-XClientMessageEvent-data1
+
+>r dup <- raw False NoEventMask r> XSendEvent drop
+
+] add-method
\ No newline at end of file
return s;
}
-void ffi_test_31(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10, int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20, int x21, int x22, int x23, int x24, int x25, int x26, int x27, int x28, int x29, int x30, int x31, int x32, int x33, int x34, int x35, int x36, int x37, int x38, int x39, int x40, int x41) { }
+int ffi_test_31(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10, int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20, int x21, int x22, int x23, int x24, int x25, int x26, int x27, int x28, int x29, int x30, int x31, int x32, int x33, int x34, int x35, int x36, int x37, int x38, int x39, int x40, int x41)
+{
+ printf("ffi_test_31(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32,x33,x34,x35,x36,x37,x38,x39,x40,x41);
+ return x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + x26 + x27 + x28 + x29 + x30 + x31 + x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 + x40 + x41;
+}
+
+float ffi_test_31_point_5(float x0, float x1, float x2, float x3, float x4, float x5, float x6, float x7, float x8, float x9, float x10, float x11, float x12, float x13, float x14, float x15, float x16, float x17, float x18, float x19, float x20, float x21, float x22, float x23, float x24, float x25, float x26, float x27, float x28, float x29, float x30, float x31, float x32, float x33, float x34, float x35, float x36, float x37, float x38, float x39, float x40, float x41)
+{
+ printf("ffi_test_31_point_5(%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f)\n",x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32,x33,x34,x35,x36,x37,x38,x39,x40,x41);
+ return x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + x26 + x27 + x28 + x29 + x30 + x31 + x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 + x40 + x41;
+}
double ffi_test_32(struct test_struct_8 x, int y)
{
DLLEXPORT struct test_struct_6 ffi_test_29(void);
struct test_struct_7 { char x, y, z, a, b, c, d; };
DLLEXPORT struct test_struct_7 ffi_test_30(void);
-DLLEXPORT void ffi_test_31(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10, int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20, int x21, int x22, int x23, int x24, int x25, int x26, int x27, int x28, int x29, int x30, int x31, int x32, int x33, int x34, int x35, int x36, int x37, int x38, int x39, int x40, int x41);
+DLLEXPORT int ffi_test_31(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, int x8, int x9, int x10, int x11, int x12, int x13, int x14, int x15, int x16, int x17, int x18, int x19, int x20, int x21, int x22, int x23, int x24, int x25, int x26, int x27, int x28, int x29, int x30, int x31, int x32, int x33, int x34, int x35, int x36, int x37, int x38, int x39, int x40, int x41);
+DLLEXPORT float ffi_test_31_point_5(float x0, float x1, float x2, float x3, float x4, float x5, float x6, float x7, float x8, float x9, float x10, float x11, float x12, float x13, float x14, float x15, float x16, float x17, float x18, float x19, float x20, float x21, float x22, float x23, float x24, float x25, float x26, float x27, float x28, float x29, float x30, float x31, float x32, float x33, float x34, float x35, float x36, float x37, float x38, float x39, float x40, float x41);
struct test_struct_8 { double x; double y; };
DLLEXPORT double ffi_test_32(struct test_struct_8 x, int y);
struct test_struct_9 { float x; float y; };
}
else if(y < WORD_SIZE - TAG_BITS)
{
- F_FIXNUM mask = -(1L << (WORD_SIZE - 1 - TAG_BITS - y));
+ F_FIXNUM mask = -((F_FIXNUM)1 << (WORD_SIZE - 1 - TAG_BITS - y));
if((x > 0 && (x & mask) == 0) || (x & mask) == mask)
{
dpush(tag_fixnum(x << y));