summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--otherlibs/labltk/Changes13
-rw-r--r--otherlibs/labltk/Makefile52
-rw-r--r--otherlibs/labltk/Makefile.nt37
-rw-r--r--otherlibs/labltk/README149
-rw-r--r--otherlibs/labltk/Widgets.src1306
-rw-r--r--otherlibs/labltk/browser/Makefile16
-rw-r--r--otherlibs/labltk/browser/Makefile.nt20
-rw-r--r--otherlibs/labltk/browser/searchpos.ml2
-rw-r--r--otherlibs/labltk/builtin/builtin_FilePattern.ml20
-rw-r--r--otherlibs/labltk/builtin/builtin_GetBitmap.ml14
-rw-r--r--otherlibs/labltk/builtin/builtin_GetCursor.ml37
-rw-r--r--otherlibs/labltk/builtin/builtin_GetPixel.ml17
-rw-r--r--otherlibs/labltk/builtin/builtin_ScrollValue.ml14
-rw-r--r--otherlibs/labltk/builtin/builtin_bind.ml307
-rw-r--r--otherlibs/labltk/builtin/builtin_bindtags.ml14
-rw-r--r--otherlibs/labltk/builtin/builtin_font.ml2
-rw-r--r--otherlibs/labltk/builtin/builtin_index.ml40
-rw-r--r--otherlibs/labltk/builtin/builtin_palette.ml13
-rw-r--r--otherlibs/labltk/builtin/builtin_text.ml30
-rw-r--r--otherlibs/labltk/builtin/builtinf_GetPixel.ml15
-rw-r--r--otherlibs/labltk/builtin/builtinf_bind.ml98
-rw-r--r--otherlibs/labltk/builtin/builtini_GetBitmap.ml20
-rw-r--r--otherlibs/labltk/builtin/builtini_GetCursor.ml35
-rw-r--r--otherlibs/labltk/builtin/builtini_GetPixel.ml26
-rw-r--r--otherlibs/labltk/builtin/builtini_ScrollValue.ml28
-rw-r--r--otherlibs/labltk/builtin/builtini_bind.ml138
-rw-r--r--otherlibs/labltk/builtin/builtini_bindtags.ml20
-rw-r--r--otherlibs/labltk/builtin/builtini_font.ml3
-rw-r--r--otherlibs/labltk/builtin/builtini_index.ml110
-rw-r--r--otherlibs/labltk/builtin/builtini_palette.ml14
-rw-r--r--otherlibs/labltk/builtin/builtini_text.ml42
-rw-r--r--otherlibs/labltk/builtin/canvas_bind.ml30
-rw-r--r--otherlibs/labltk/builtin/canvas_bind.mli9
-rw-r--r--otherlibs/labltk/builtin/dialog.ml33
-rw-r--r--otherlibs/labltk/builtin/dialog.mli16
-rw-r--r--otherlibs/labltk/builtin/image.ml33
-rw-r--r--otherlibs/labltk/builtin/image.mli9
-rw-r--r--otherlibs/labltk/builtin/optionmenu.ml56
-rw-r--r--otherlibs/labltk/builtin/optionmenu.mli26
-rw-r--r--otherlibs/labltk/builtin/rawimg.ml142
-rw-r--r--otherlibs/labltk/builtin/rawimg.mli44
-rw-r--r--otherlibs/labltk/builtin/report.ml19
-rw-r--r--otherlibs/labltk/builtin/selection_handle_set.ml49
-rw-r--r--otherlibs/labltk/builtin/selection_handle_set.mli11
-rw-r--r--otherlibs/labltk/builtin/selection_own_set.ml31
-rw-r--r--otherlibs/labltk/builtin/selection_own_set.mli11
-rw-r--r--otherlibs/labltk/builtin/text_tag_bind.ml74
-rw-r--r--otherlibs/labltk/builtin/text_tag_bind.mli9
-rw-r--r--otherlibs/labltk/builtin/winfo_contained.ml11
-rw-r--r--otherlibs/labltk/builtin/winfo_contained.mli11
-rw-r--r--otherlibs/labltk/camltk/.cvsignore3
-rw-r--r--otherlibs/labltk/camltk/Makefile47
-rw-r--r--otherlibs/labltk/camltk/Makefile.gen43
-rw-r--r--otherlibs/labltk/camltk/Makefile.gen.nt43
-rw-r--r--otherlibs/labltk/camltk/Makefile.nt43
-rw-r--r--otherlibs/labltk/compiler/.cvsignore6
-rw-r--r--otherlibs/labltk/compiler/.depend32
-rw-r--r--otherlibs/labltk/compiler/Makefile51
-rw-r--r--otherlibs/labltk/compiler/Makefile.nt58
-rw-r--r--otherlibs/labltk/compiler/code.mli22
-rw-r--r--otherlibs/labltk/compiler/compile.ml557
-rw-r--r--otherlibs/labltk/compiler/copyright15
-rw-r--r--otherlibs/labltk/compiler/flags.ml17
-rw-r--r--otherlibs/labltk/compiler/intf.ml146
-rw-r--r--otherlibs/labltk/compiler/lexer.mll45
-rw-r--r--otherlibs/labltk/compiler/maincompile.ml252
-rw-r--r--otherlibs/labltk/compiler/parser.mly25
-rw-r--r--otherlibs/labltk/compiler/pp.ml23
-rw-r--r--otherlibs/labltk/compiler/ppexec.ml60
-rw-r--r--otherlibs/labltk/compiler/pplex.mli18
-rw-r--r--otherlibs/labltk/compiler/pplex.mll57
-rw-r--r--otherlibs/labltk/compiler/ppparse.ml36
-rw-r--r--otherlibs/labltk/compiler/ppyac.mly52
-rw-r--r--otherlibs/labltk/compiler/printer.ml28
-rw-r--r--otherlibs/labltk/compiler/tables.ml45
-rw-r--r--otherlibs/labltk/compiler/tsort.ml30
-rw-r--r--otherlibs/labltk/examples_camltk/.cvsignore8
-rw-r--r--otherlibs/labltk/examples_camltk/Makefile52
-rw-r--r--otherlibs/labltk/examples_camltk/Makefile.nt38
-rw-r--r--otherlibs/labltk/examples_camltk/addition.ml53
-rw-r--r--otherlibs/labltk/examples_camltk/eyes.ml67
-rw-r--r--otherlibs/labltk/examples_camltk/fileinput.ml35
-rw-r--r--otherlibs/labltk/examples_camltk/fileopen.ml56
-rw-r--r--otherlibs/labltk/examples_camltk/helloworld.ml37
-rw-r--r--otherlibs/labltk/examples_camltk/images/CamlBook.gifbin0 -> 15167 bytes
-rw-r--r--otherlibs/labltk/examples_camltk/images/Lambda2.back.gifbin0 -> 53441 bytes
-rw-r--r--otherlibs/labltk/examples_camltk/images/dojoji.back.gifbin0 -> 49934 bytes
-rw-r--r--otherlibs/labltk/examples_camltk/jptest.ml23
-rw-r--r--otherlibs/labltk/examples_camltk/mytext.ml63
-rw-r--r--otherlibs/labltk/examples_camltk/socketinput.ml43
-rw-r--r--otherlibs/labltk/examples_camltk/taddition.ml53
-rw-r--r--otherlibs/labltk/examples_camltk/tetris.ml685
-rw-r--r--otherlibs/labltk/examples_camltk/text.ml55
-rw-r--r--otherlibs/labltk/examples_camltk/winskel.ml63
-rw-r--r--otherlibs/labltk/examples_labltk/.cvsignore7
-rw-r--r--otherlibs/labltk/examples_labltk/Lambda2.back.gifbin0 -> 53441 bytes
-rw-r--r--otherlibs/labltk/examples_labltk/Makefile50
-rw-r--r--otherlibs/labltk/examples_labltk/Makefile.nt50
-rw-r--r--otherlibs/labltk/examples_labltk/README20
-rw-r--r--otherlibs/labltk/examples_labltk/calc.ml129
-rw-r--r--otherlibs/labltk/examples_labltk/clock.ml133
-rw-r--r--otherlibs/labltk/examples_labltk/demo.ml167
-rw-r--r--otherlibs/labltk/examples_labltk/eyes.ml65
-rw-r--r--otherlibs/labltk/examples_labltk/hello.ml38
-rwxr-xr-xotherlibs/labltk/examples_labltk/hello.tcl5
-rw-r--r--otherlibs/labltk/examples_labltk/lang.ml75
-rw-r--r--otherlibs/labltk/examples_labltk/taquin.ml143
-rw-r--r--otherlibs/labltk/examples_labltk/tetris.ml710
-rw-r--r--otherlibs/labltk/frx/.depend38
-rw-r--r--otherlibs/labltk/frx/Makefile51
-rw-r--r--otherlibs/labltk/frx/Makefile.nt53
-rw-r--r--otherlibs/labltk/frx/README2
-rw-r--r--otherlibs/labltk/frx/frx_after.ml24
-rw-r--r--otherlibs/labltk/frx/frx_after.mli17
-rw-r--r--otherlibs/labltk/frx/frx_color.ml35
-rw-r--r--otherlibs/labltk/frx/frx_color.mli16
-rw-r--r--otherlibs/labltk/frx/frx_ctext.ml66
-rw-r--r--otherlibs/labltk/frx/frx_ctext.mli25
-rw-r--r--otherlibs/labltk/frx/frx_dialog.ml115
-rw-r--r--otherlibs/labltk/frx/frx_dialog.mli22
-rw-r--r--otherlibs/labltk/frx/frx_entry.ml42
-rw-r--r--otherlibs/labltk/frx/frx_entry.mli31
-rw-r--r--otherlibs/labltk/frx/frx_fileinput.ml40
-rw-r--r--otherlibs/labltk/frx/frx_fillbox.ml65
-rw-r--r--otherlibs/labltk/frx/frx_fillbox.mli31
-rw-r--r--otherlibs/labltk/frx/frx_fit.ml83
-rw-r--r--otherlibs/labltk/frx/frx_fit.mli29
-rw-r--r--otherlibs/labltk/frx/frx_focus.ml26
-rw-r--r--otherlibs/labltk/frx/frx_focus.mli18
-rw-r--r--otherlibs/labltk/frx/frx_font.ml51
-rw-r--r--otherlibs/labltk/frx/frx_font.mli20
-rw-r--r--otherlibs/labltk/frx/frx_group.ml22
-rw-r--r--otherlibs/labltk/frx/frx_lbutton.ml50
-rw-r--r--otherlibs/labltk/frx/frx_lbutton.mli24
-rw-r--r--otherlibs/labltk/frx/frx_listbox.ml92
-rw-r--r--otherlibs/labltk/frx/frx_listbox.mli32
-rw-r--r--otherlibs/labltk/frx/frx_mem.ml89
-rw-r--r--otherlibs/labltk/frx/frx_mem.mli22
-rw-r--r--otherlibs/labltk/frx/frx_misc.ml69
-rw-r--r--otherlibs/labltk/frx/frx_misc.mli21
-rw-r--r--otherlibs/labltk/frx/frx_req.ml198
-rw-r--r--otherlibs/labltk/frx/frx_req.mli43
-rw-r--r--otherlibs/labltk/frx/frx_rpc.ml55
-rw-r--r--otherlibs/labltk/frx/frx_rpc.mli25
-rw-r--r--otherlibs/labltk/frx/frx_selection.ml45
-rw-r--r--otherlibs/labltk/frx/frx_selection.mli17
-rw-r--r--otherlibs/labltk/frx/frx_synth.ml88
-rw-r--r--otherlibs/labltk/frx/frx_synth.mli31
-rw-r--r--otherlibs/labltk/frx/frx_text.ml229
-rw-r--r--otherlibs/labltk/frx/frx_text.mli46
-rw-r--r--otherlibs/labltk/frx/frx_toplevel.mli17
-rw-r--r--otherlibs/labltk/frx/frx_widget.ml24
-rw-r--r--otherlibs/labltk/frx/frx_widget.mli18
-rw-r--r--otherlibs/labltk/jpf/Makefile50
-rw-r--r--otherlibs/labltk/jpf/Makefile.nt28
-rw-r--r--otherlibs/labltk/jpf/README2
-rw-r--r--otherlibs/labltk/jpf/balloon.ml30
-rw-r--r--otherlibs/labltk/jpf/balloon.mli28
-rw-r--r--otherlibs/labltk/jpf/balloontest.ml34
-rw-r--r--otherlibs/labltk/jpf/fileselect.ml31
-rw-r--r--otherlibs/labltk/jpf/fileselect.mli31
-rw-r--r--otherlibs/labltk/jpf/jpf_font.ml218
-rw-r--r--otherlibs/labltk/jpf/jpf_font.mli54
-rw-r--r--otherlibs/labltk/jpf/shell.ml36
-rw-r--r--otherlibs/labltk/jpf/shell.mli17
-rw-r--r--otherlibs/labltk/labltk/.cvsignore3
-rw-r--r--otherlibs/labltk/labltk/Makefile45
-rw-r--r--otherlibs/labltk/labltk/Makefile.gen42
-rw-r--r--otherlibs/labltk/labltk/Makefile.gen.nt43
-rw-r--r--otherlibs/labltk/labltk/Makefile.nt43
-rw-r--r--otherlibs/labltk/lib/.cvsignore2
-rw-r--r--otherlibs/labltk/lib/Makefile110
-rw-r--r--otherlibs/labltk/lib/Makefile.gen.nt38
-rw-r--r--otherlibs/labltk/lib/Makefile.nt99
-rw-r--r--otherlibs/labltk/support/.depend12
-rw-r--r--otherlibs/labltk/support/Makefile45
-rw-r--r--otherlibs/labltk/support/Makefile.common18
-rw-r--r--otherlibs/labltk/support/Makefile.common.nt16
-rw-r--r--otherlibs/labltk/support/Makefile.nt46
-rw-r--r--otherlibs/labltk/support/camltk.h8
-rw-r--r--otherlibs/labltk/support/camltkwrap.ml77
-rw-r--r--otherlibs/labltk/support/camltkwrap.mli251
-rw-r--r--otherlibs/labltk/support/cltkCaml.c32
-rw-r--r--otherlibs/labltk/support/cltkEval.c212
-rw-r--r--otherlibs/labltk/support/cltkEvent.c35
-rw-r--r--otherlibs/labltk/support/cltkFile.c30
-rw-r--r--otherlibs/labltk/support/cltkImg.c111
-rw-r--r--otherlibs/labltk/support/cltkMain.c96
-rw-r--r--otherlibs/labltk/support/cltkMisc.c39
-rw-r--r--otherlibs/labltk/support/cltkTimer.c30
-rw-r--r--otherlibs/labltk/support/cltkUtf.c89
-rw-r--r--otherlibs/labltk/support/cltkVar.c52
-rw-r--r--otherlibs/labltk/support/cltkWait.c35
-rw-r--r--otherlibs/labltk/support/fileevent.ml46
-rw-r--r--otherlibs/labltk/support/fileevent.mli30
-rw-r--r--otherlibs/labltk/support/protocol.ml144
-rw-r--r--otherlibs/labltk/support/protocol.mli73
-rw-r--r--otherlibs/labltk/support/rawwidget.ml176
-rw-r--r--otherlibs/labltk/support/rawwidget.mli109
-rw-r--r--otherlibs/labltk/support/slave.ml30
-rw-r--r--otherlibs/labltk/support/support.ml40
-rw-r--r--otherlibs/labltk/support/support.mli32
-rw-r--r--otherlibs/labltk/support/textvariable.ml43
-rw-r--r--otherlibs/labltk/support/textvariable.mli30
-rw-r--r--otherlibs/labltk/support/timer.ml32
-rw-r--r--otherlibs/labltk/support/timer.mli30
-rw-r--r--otherlibs/labltk/support/tkwait.ml30
-rw-r--r--otherlibs/labltk/support/widget.ml196
-rw-r--r--otherlibs/labltk/support/widget.mli34
-rw-r--r--otherlibs/labltk/tkanim/.depend2
-rw-r--r--otherlibs/labltk/tkanim/Makefile65
-rw-r--r--otherlibs/labltk/tkanim/Makefile.nt76
-rw-r--r--otherlibs/labltk/tkanim/README5
-rw-r--r--otherlibs/labltk/tkanim/cltkaniminit.c26
-rw-r--r--otherlibs/labltk/tkanim/gifanimtest.ml71
-rw-r--r--otherlibs/labltk/tkanim/mmm.anim.gifbin0 -> 18501 bytes
-rw-r--r--otherlibs/labltk/tkanim/tkAnimGIF.c906
-rw-r--r--otherlibs/labltk/tkanim/tkAppInit.c141
-rw-r--r--otherlibs/labltk/tkanim/tkanim.ml230
-rw-r--r--otherlibs/labltk/tkanim/tkanim.mli95
220 files changed, 13053 insertions, 1967 deletions
diff --git a/otherlibs/labltk/Changes b/otherlibs/labltk/Changes
new file mode 100644
index 000000000..bd671fdb6
--- /dev/null
+++ b/otherlibs/labltk/Changes
@@ -0,0 +1,13 @@
+version 1.0a1
+
+General Changes
+* Merging CamlTk and LablTk API interfaces
+* Activate and Deactivate Events are added
+* Virtual events support
+* Added UTF conversion
+
+Incompatibilities between the previous camltk/labltk versions
+* CamlTk's bind_tag and bind_class superseded tag_bind and class_bind.
+* added optional arguments to some functions of CamlTk.
+* The library name libfrx and libjpf are changed to frxlib and jpflib
+ respectively, to avoid the library name confusion.
diff --git a/otherlibs/labltk/Makefile b/otherlibs/labltk/Makefile
index 1ba69dd0d..6fe24eb78 100644
--- a/otherlibs/labltk/Makefile
+++ b/otherlibs/labltk/Makefile
@@ -1,38 +1,70 @@
-# Top Makefile for LablTk
+# Top Makefile for mlTk
-SUBDIRS=compiler support lib jpf example browser
+SUBDIRS=compiler support lib labltk camltk jpf frx tkanim examples_labltk examples_camltk browser
all:
cd support; $(MAKE)
cd compiler; $(MAKE)
- cd lib; $(MAKE) -f Makefile.gen; $(MAKE)
+ cd labltk; $(MAKE) -f Makefile.gen
+ cd labltk; $(MAKE)
+ cd camltk; $(MAKE) -f Makefile.gen
+ cd camltk; $(MAKE)
+ cd lib; $(MAKE)
cd jpf; $(MAKE)
+ cd frx; $(MAKE)
+ cd tkanim; $(MAKE)
cd browser; $(MAKE)
allopt:
cd support; $(MAKE) opt
- cd lib; $(MAKE) -f Makefile.gen; $(MAKE) opt
+ cd labltk; $(MAKE) -f Makefile.gen
+ cd labltk; $(MAKE) opt
+ cd camltk; $(MAKE) -f Makefile.gen
+ cd camltk; $(MAKE) opt
+ cd lib; $(MAKE) opt
cd jpf; $(MAKE) opt
+ cd frx; $(MAKE) opt
+ cd tkanim; $(MAKE) opt
-lib: Widgets.src
- compiler/tkcompiler
- cd lib; $(MAKE)
+byte: all
+opt: allopt
+
+.PHONY: labltk camltk examples_labltk examples_camltk
+
+labltk: Widgets.src
+ compiler/tkcompiler -outdir labltk
+ cd labltk; $(MAKE)
+
+camltk: Widgets.src
+ compiler/tkcompiler -camltk -outdir camltk
+ cd camltk; $(MAKE)
+
+examples: examples_labltk examples_camltk
-example: example/all
+examples_labltk:
+ cd examples_labltk; $(MAKE) all
-example/all:
- cd example; $(MAKE) all
+examples_camltk:
+ cd examples_camltk; $(MAKE) all
install:
+ cd labltk; $(MAKE) install
+ cd camltk; $(MAKE) install
cd lib; $(MAKE) install
cd support; $(MAKE) install
cd compiler; $(MAKE) install
cd jpf; $(MAKE) install
+ cd frx; $(MAKE) install
+ cd tkanim; $(MAKE) install
cd browser; $(MAKE) install
installopt:
+ cd labltk; $(MAKE) installopt
+ cd camltk; $(MAKE) installopt
cd lib; $(MAKE) installopt
cd jpf; $(MAKE) installopt
+ cd frx; $(MAKE) installopt
+ cd tkanim; $(MAKE) installopt
partialclean clean:
for d in $(SUBDIRS); do \
diff --git a/otherlibs/labltk/Makefile.nt b/otherlibs/labltk/Makefile.nt
index 73530676d..c5e979a06 100644
--- a/otherlibs/labltk/Makefile.nt
+++ b/otherlibs/labltk/Makefile.nt
@@ -2,39 +2,58 @@
!include ..\..\config\Makefile.nt
-SUBDIRS=compiler support lib jpf browser
+SUBDIRS=compiler support lib labltk camltk jpf frx tkanim examples_labltk examples_camltk browser
all:
cd support & $(MAKEREC)
cd compiler & $(MAKEREC)
- cd lib & $(MAKE) -nologo -f Makefile.gen.nt & $(MAKEREC)
+ cd labltk & $(MAKE) -nologo -f Makefile.gen.nt
+ cd labltk & $(MAKEREC)
+ cd camltk & $(MAKE) -nologo -f Makefile.gen.nt
+ cd camltk & $(MAKEREC)
+ cd lib & $(MAKEREC)
cd jpf & $(MAKEREC)
+ cd frx & $(MAKEREC)
+ cd tkanim & $(MAKEREC)
cd browser & $(MAKEREC)
allopt:
cd support & $(MAKEREC) opt
- cd lib & $(MAKE) -nologo -f Makefile.gen.nt & $(MAKEREC) opt
+ cd labltk & $(MAKE) -nologo -f Makefile.gen.nt
+ cd labltk & $(MAKEREC) opt
+ cd camltk & $(MAKE) -nologo -f Makefile.gen.nt
+ cd camltk & $(MAKEREC) opt
+ cd lib & $(MAKEREC) opt
cd jpf & $(MAKEREC) opt
+ cd frx & $(MAKEREC) opt
+ cd tkanim & $(MAKEREC) opt
-lib: Widgets.src
- compiler/tkcompiler
- cd lib & $(MAKEREC)
+example: examples_labltk/all examples_camltk/all
-example: example/all
+examples_labltk/all:
+ cd examples_labltk & $(MAKEREC) all
-example/all:
- cd example & $(MAKEREC) all
+examples_camltk/all:
+ cd examples_camltk & $(MAKEREC) all
install:
+ cd labltk & $(MAKEREC) install
+ cd camltk & $(MAKEREC) install
cd lib & $(MAKEREC) install
cd support & $(MAKEREC) install
cd compiler & $(MAKEREC) install
cd jpf & $(MAKEREC) install
+ cd frx & $(MAKEREC) install
+ cd tkanim & $(MAKEREC) install
cd browser & $(MAKEREC) install
installopt:
+ cd labltk & $(MAKEREC) installopt
+ cd camltk & $(MAKEREC) installopt
cd lib & $(MAKEREC) installopt
cd jpf & $(MAKEREC) installopt
+ cd frx & $(MAKEREC) installopt
+ cd tkanim & $(MAKEREC) installopt
partialclean clean:
for %d in ($(SUBDIRS)) do (cd %d & $(MAKEREC) clean & cd ..)
diff --git a/otherlibs/labltk/README b/otherlibs/labltk/README
index 102b0fd82..cb9b8b8ab 100644
--- a/otherlibs/labltk/README
+++ b/otherlibs/labltk/README
@@ -1,25 +1,152 @@
-LablTk41 is a library for interfacing Objective Labl with the scripting
-language Tcl/Tk (all versions since 7.5/4.1, but no betas).
+INTRODUCTION
+============
+mlTk is a library for interfacing Objective Caml with the scripting
+language Tcl/Tk (all versions since 8.0.3, but no betas).
In addition to the basic interface with Tcl/Tk, this package contains
- * the LablBrowser code editor / library browser written by Jacques
+ * the OCamlBrowser code editor / library browser written by Jacques
Garrigue.
* the "jpf" library, written by Jun P. Furuse; it contains a "file
selector" and "balloon help" support
-
+ * the "frx" library, written by Francois Rouaix
+ * the "tkanim" library, which supports animated gif loading/display
+
+mlTk = CamlTk + LablTk
+======================
+There existed two parallel Tcl/Tk interfaces for O'Caml, CamlTk and LablTk.
+
+CamlTk uses classical features only, therefore it is easy to understand for
+the beginners of ML. It makes many conservative O'Caml gurus also happy.
+LablTk, on the other hand, uses rather newer features of O'Caml, the labeled
+optional arguments and polymorphic variants. Its syntax has much more Tcl/Tk
+script flavor, but provides more powerful typing than CamlTk at the same time
+(i.e. less run time type checking of widgets).
+Until now, these two interfaces have been distributed and maintained
+independently.
-REQUIREMENTS:
+mlTk unifies these libraries into one. Since mlTk provides the both API's,
+both CamlTk and LablTk users can compile their applications with mlTk,
+just with little fixes.
+
+REQUIREMENTS
+============
You must have already installed
- * Objective Label 2.02 Summer edition
- http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/
+ * Objective Caml source, version 3.04+8 or later
- * Tcl7.5/Tk4.1 through Tcl/Tk8.2
+ * Tcl/Tk 8.0.3 or later
http://www.scriptics.com/ or various mirrors
PLATFORMS:
Essentially any Unix/X Window System platform. We have tested
releases on Linux (ELF x86), FreeBSD (x86), SunOS4.1.x (sparc), DEC
-OSF/1 V4.0 (alpha), DGUX SVR4 (m88k). We have not attempted to
-compile this package on Windows.
+OSF/1 V4.0 (alpha), DGUX SVR4 (m88k) and Windows (VC++ and Cygwin).
+
+INSTALLATION
+============
+
+0. Check-out the O'Caml CVS source code tree.
+
+1. Compile O'Caml (= make world). If you want, also make opt.
+
+2. Untar this mlTk distribution in the otherlibs directory, just like
+ the labltk source tree.
+
+3. change directory to otherlibs/mltk, and make (and make opt)
+
+4. To install the library, make install (and make installopt)
+
+To compile mlTk, you need the O'Caml source tree, since mltk/camlbrowser
+requires some modules of O'Caml. If you are not interested in camlbrowser,
+you can compile mlTk without the O'Caml source tree, but you have to modify
+support/Makefile.common.
+
+
+Compile your CamlTk/LablTk applications with mlTk
+=================================================
+
+* General
+
+The names of the additional libraries libjpf and libfrx are changed
+to jpflib and frxlib respectively, to avoid the library name space confusion.
+
+* LablTk users
+
+Just change the occurrences of labltk in your Makefiles to mltk
+(i.e. -I +labltk => -I +mltk, labltk.cma => mltk.cma, and so on)
+Since the API functions are 100% compatible, you need not to change
+your .ml files.
+
+* CamlTk users
+
+ - Makefiles : apply the same modification explained above for LablTk users.
+
+ - open Camltk : The API modules and functions are stored in the modules
+ Camltk. Therefore you need to replace the module name Tk to Camltk.
+ For example, open Tk => open Camltk.
+
+ open Camltk (* instead of open Tk *)
+
+ let t = openTk ();;
+ let b = Button.create t [];;
+
+ - You may also need to open the Camltk module explicitly, when your
+ original module source contain no open Tk phrase. Widget and the other
+ Tcl/Tk related types are now under Camltk. (e.g. Widget.widget is now
+ Camltk.Widget.widget) Add open Camltk at the beginning of .mli files,
+ if these types are used:
+
+ open Camltk (* added for compiling under mlTk *)
+
+ val create_progress_bar : Widget.widget -> Widget.widget
+
+ - Eta expansion to flush optional arguments at registering callbacks.
+ Functions with the _displayof suffix are unified with their non-displayof
+ versions, using optional labeled arguments. For example, Bell.ring
+ had/have the following types:
+
+ before: Bell.ring : unit -> unit
+ now: Bell.ring : ?displayof:Camltk.widget -> unit -> unit
+
+ If you use these functions as callbacks directly like Command Bell.ring,
+ you need eta-expansions to flush these new optional arguments:
+
+ Button.create w [Command Bell.ring]
+
+ => Button.create w [Command (fun () -> Bell.ring ())]
+
+Use the both API's at the same time
+===================================
+It is possible to use the both API's in one program. If you want to use
+a widget library written in the different API from you use, you need to
+do it. (It will be confusing, but easier than porting the library itself
+from one to the other API.)
+
+For the users who mainly use LablTk API, CamlTk API is available
+in the modules start with 'C'. For example, the source file of
+the CamlTk button widget functions is CButton (and exported also as
+Camltk.Button).
+
+For the users who mainly use CamlTk API, LablTk API modules are exported
+inside Labltk module. For example, LablTk's Button module can be also
+accessible as Labltk.Button.
+
+In CamlTk, we have only one widget type, [widget]. This type is equivalent
+to the LablTk's type [any widget]. Therefore, if you want to apply CamlTk
+functions to LablTk widget, you can use [coe] function to coerce it to
+[any widget].
+
+To do the converse, the "widget-typers" are available inside the module Labltk.
+For example, to recover the type of a button widget, use Labltk.button.
+These widget-typers checks the types of widgets at run-time. If the widget
+type is different from the context type, a run-time exception is raised.
+
+ open Tk (* open LablTk API *)
+
+ let t = openTk ();; (* t is LablTk widget, toplevel widget *)
+ (* CButton.create takes [any widget]; [t] must be coerced to the type. *)
+ let caml_b = CButton.create (coe t) [];;
+ (* caml_b is [any widget], must be explicitly typed as [button widget],
+ when it is used with LablTk API functions *)
+ let b = Labltk.button caml_b in (* recover the type [button widget] *)
+ ...
-See the INSTALL file for installation instructions.
diff --git a/otherlibs/labltk/Widgets.src b/otherlibs/labltk/Widgets.src
index d1c7ad1bd..458c5eaa2 100644
--- a/otherlibs/labltk/Widgets.src
+++ b/otherlibs/labltk/Widgets.src
@@ -1,24 +1,35 @@
-############## Standard Tk4.1 Widgets and functions ##############
+%%%%%%%%%%%%%% Standard Tk8.0.3 Widgets and functions %%%%%%%%%%%%%%
type Widget external
-# cget will probably never be implemented with verifications
+% cget will probably never be implemented with verifications
function (string) cgets [widget; "cget"; string]
-# another version with some hack is
+% another version with some hack is
type options_constrs external
function (string) cget [widget; "cget"; options_constrs]
-# constructors of type options_constrs are of the form C<c>
-# where <c> is an option constructor (e.g. CBackground)
+% constructors of type options_constrs are of the form C<c>
+% where <c> is an option constructor (e.g. CBackground)
-##### Some types for standard options of widgets
+%%%%% Some types for standard options of widgets
type Anchor {
NW ["nw"] N ["n"] NE ["ne"]
W ["w"] Center ["center"] E ["e"]
SW ["sw"] S ["s"] SE ["se"]
}
-type Bitmap external # builtin_GetBitmap.ml
-type Cursor external # builtin_GetCursor.ml
-type Color external # builtin_GetCursor.ml
+type Bitmap external % builtin_GetBitmap.ml
+type Cursor external % builtin_GetCursor.ml
+type Color external % builtin_GetCursor.ml
+
+##ifdef CAMLTK
+
+type ImageBitmap {
+ BitmapImage [string]
+ }
+type ImagePhoto {
+ PhotoImage [string]
+ }
+
+##else
variant type ImageBitmap {
Bitmap [string]
@@ -31,6 +42,8 @@ variant type Image {
Photo [string]
}
+##endif
+
type Justification {
Justify_Left ["left"]
Justify_Center ["center"]
@@ -50,95 +63,101 @@ type Relief {
Groove ["groove"]
}
-type TextVariable external # textvariable.ml
-type Units external # builtin_GetPixel.ml
+type TextVariable external % textvariable.ml
+type Units external % builtin_GetPixel.ml
-##### The standard options, as defined in man page options(n)
-##### The subtype is never used
+%%%%% The standard options, as defined in man page options(n)
+%%%%% The subtype is never used
subtype option(standard) {
ActiveBackground ["-activebackground"; Color]
- ActiveBorderWidth ["-activeborderwidth"; int]
+ ActiveBorderWidth ["-activeborderwidth"; Units/int]
ActiveForeground ["-activeforeground"; Color]
Anchor ["-anchor"; Anchor]
Background ["-background"; Color]
Bitmap ["-bitmap"; Bitmap]
- BorderWidth ["-borderwidth"; int]
+ BorderWidth ["-borderwidth"; Units/int]
Cursor ["-cursor"; Cursor]
DisabledForeground ["-disabledforeground"; Color]
ExportSelection ["-exportselection"; bool]
Font ["-font"; string]
Foreground ["-foreground"; Color]
- Geometry ["-geometry"; string] # Too variable to encode
+% Geometry is not one of standard options...
+ Geometry ["-geometry"; string] % Too variable to encode
HighlightBackground ["-highlightbackground"; Color]
HighlightColor ["-highlightcolor"; Color]
- HighlightThickness ["-highlightthickness"; int]
+ HighlightThickness ["-highlightthickness"; Units/int]
+##ifdef CAMLTK
+ % images are split, to do additionnal static typing
+ ImageBitmap (ImageBitmap) ["-image"; ImageBitmap]
+ ImagePhoto (ImagePhoto) ["-image"; ImagePhoto]
+##else
Image ["-image"; Image]
-# it is old # images are split, to do additionnal static typing
-# ImageBitmap (ImageBitmap) ["-image"; ImageBitmap]
-# ImagePhoto (ImagePhoto) ["-image"; ImagePhoto]
+##endif
InsertBackground ["-insertbackground"; Color]
- InsertBorderWidth ["-insertborderwidth"; int]
- InsertOffTime ["-insertofftime"; int] # Positive only
- InsertOnTime ["-insertontime"; int] # Idem
- InsertWidth ["-insertwidth"; int]
+ InsertBorderWidth ["-insertborderwidth"; Units/int]
+ InsertOffTime ["-insertofftime"; int] % Positive only
+ InsertOnTime ["-insertontime"; int] % Idem
+ InsertWidth ["-insertwidth"; Units/int]
Jump ["-jump"; bool]
Justify ["-justify"; Justification]
Orient ["-orient"; Orientation]
- PadX ["-padx"; int]
- PadY ["-pady"; int]
+ PadX ["-padx"; Units/int]
+ PadY ["-pady"; Units/int]
Relief ["-relief"; Relief]
RepeatDelay ["-repeatdelay"; int]
RepeatInterval ["-repeatinterval"; int]
SelectBackground ["-selectbackground"; Color]
- SelectBorderWidth ["-selectborderwidth"; int]
+ SelectBorderWidth ["-selectborderwidth"; Units/int]
SelectForeground ["-selectforeground"; Color]
SetGrid ["-setgrid"; bool]
- # incomplete description of TakeFocus
+ % incomplete description of TakeFocus
TakeFocus ["-takefocus"; bool]
Text ["-text"; string]
TextVariable ["-textvariable"; TextVariable]
TroughColor ["-troughcolor"; Color]
UnderlinedChar ["-underline"; int]
- WrapLength ["-wraplength"; int]
- # Major incompatibility with Tk3.6 where it was function(int,int,int,int)
+ WrapLength ["-wraplength"; Units/int]
XScrollCommand ["-xscrollcommand"; function(first:float, last:float)]
YScrollCommand ["-yscrollcommand"; function(first:float, last:float)]
}
-#### Some other common types
-type Index external # builtin_index.ml
-type sequence ScrollValue external # builtin_ScrollValue.ml
-# type sequence ScrollValue {
-# MoveTo ["moveto"; float]
-# ScrollUnit ["scroll"; int; "unit"]
-# ScrollPage ["scroll"; int; "page"]
-# }
+%%%% Some other common types
+type Index external % builtin_index.ml
+type sequence ScrollValue external % builtin_ScrollValue.ml
+% type sequence ScrollValue {
+% MoveTo ["moveto"; float]
+% ScrollUnit ["scroll"; int; "unit"]
+% ScrollPage ["scroll"; int; "page"]
+% }
-##### bell(n)
+%%%%% bell(n)
module Bell {
+##ifdef CAMLTK
+ function () ring ["bell"; ?displayof:["-displayof"; widget]]
+ function () ring_displayof ["bell"; "-displayof" ; displayof: widget]
+##else
function () ring ["bell"; ?displayof:["-displayof"; widget]]
-# function () ring ["bell"]
-# function () ring_displayof ["bell"; "-displayof" ; displayof: widget]
+##endif
}
-##### bind(n)
-# builtin_bind.ml
+%%%%% bind(n)
+% builtin_bind.ml
-##### bindtags(n)
-#type Bindings {
-# TagBindings [string]
-# WidgetBindings [widget]
-# }
+%%%%% bindtags(n)
+%type Bindings {
+% TagBindings [string]
+% WidgetBindings [widget]
+% }
type Bindings external
function () bindtags ["bindtags"; widget; [bindings: Bindings list]]
function (Bindings list) bindtags_get ["bindtags"; widget]
-##### bitmap(n)
+%%%%% bitmap(n)
subtype option(bitmapimage) {
Background
Data ["-data"; string]
@@ -150,15 +169,19 @@ subtype option(bitmapimage) {
module Imagebitmap {
function (ImageBitmap) create ["image"; "create"; "bitmap"; ?name:[ImageBitmap]; option(bitmapimage) list]
- function () configure [ImageBitmap; "configure"; option(bitmapimage) list]
- function (string) configure_get [ImageBitmap; "configure"]
- # Functions inherited from the "image" TK class
+##ifdef CAMLTK
+ function (ImageBitmap) create_named ["image"; "create"; "bitmap"; ImageBitmap; option(bitmapimage) list]
+##endif
function () delete ["image"; "delete"; ImageBitmap]
function (int) height ["image"; "height"; ImageBitmap]
function (int) width ["image"; "width"; ImageBitmap]
+ function () configure [ImageBitmap; "configure"; option(bitmapimage) list]
+ function (string) configure_get [ImageBitmap; "configure"]
+ % Functions inherited from the "image" TK class
}
-##### button(n)
+%%%%% button(n)
+
type State {
Normal ["normal"]
Active ["active"]
@@ -166,7 +189,7 @@ type State {
}
widget button {
- # Standard options
+ % Standard options
option ActiveBackground
option ActiveForeground
option Anchor
@@ -180,9 +203,12 @@ widget button {
option HighlightBackground
option HighlightColor
option HighlightThickness
+##ifdef CAMLTK
+ option ImageBitmap
+ option ImagePhoto
+##else
option Image
-# option ImageBitmap
-# option ImagePhoto
+##endif
option Justify
option PadX
option PadY
@@ -192,11 +218,12 @@ widget button {
option TextVariable
option UnderlinedChar
option WrapLength
- # Widget specific options
+ % Widget specific options
option Command ["-command"; function ()]
- option Height ["-height"; int]
+ option Default ["-default"; State]
+ option Height ["-height"; Units/int]
option State ["-state"; State]
- option Width ["-width"; int]
+ option Width ["-width"; Units/int]
function () configure [widget(button); "configure"; option(button) list]
function (string) configure_get [widget(button); "configure"]
@@ -205,26 +232,26 @@ widget button {
}
-###### canvas(n)
-# Item ids and tags
+%%%%%% canvas(n)
+% Item ids and tags
type TagOrId {
Tag [string]
Id [int]
}
-# Indices: defined internally
-# subtype Index(canvas) {
-# Number End Insert SelFirst SelLast AtXY
-# }
+% Indices: defined internally
+% subtype Index(canvas) {
+% Number End Insert SelFirst SelLast AtXY
+% }
type SearchSpec {
Above ["above"; TagOrId]
All ["all"]
Below ["below"; TagOrId]
- Closest ["closest"; int; int]
- ClosestHalo (Closesthalo) ["closest"; int; int; int]
- ClosestHaloStart (Closesthalostart) ["closest"; int; int; int; TagOrId]
- Enclosed ["enclosed"; int;int;int;int]
+ Closest ["closest"; Units/int; Units/int]
+ ClosestHalo (Closesthalo) ["closest"; Units/int; Units/int; Units/int]
+ ClosestHaloStart (Closesthalostart) ["closest"; Units/int; Units/int; Units/int; TagOrId]
+ Enclosed ["enclosed"; Units/int;Units/int;Units/int;Units/int]
Overlapping ["overlapping"; int;int;int;int]
Withtag ["withtag"; TagOrId]
}
@@ -236,25 +263,25 @@ type ColorMode {
}
subtype option(postscript) {
- # Cannot support this without array variables
- # Colormap ["-colormap"; TextVariable]
+ % Cannot support this without array variables
+ % Colormap ["-colormap"; TextVariable]
Colormode ["-colormode"; ColorMode]
File ["-file"; string]
- # Fontmap ["-fontmap"; TextVariable]
+ % Fontmap ["-fontmap"; TextVariable]
Height
PageAnchor ["-pageanchor"; Anchor]
- PageHeight ["-pageheight"; int]
- PageWidth ["-pagewidth"; int]
- PageX ["-pagex"; int]
- PageY ["-pagey"; int]
+ PageHeight ["-pageheight"; Units/int]
+ PageWidth ["-pagewidth"; Units/int]
+ PageX ["-pagex"; Units/int]
+ PageY ["-pagey"; Units/int]
Rotate ["-rotate"; bool]
Width
- X ["-x"; int]
- Y ["-y"; int]
+ X ["-x"; Units/int]
+ Y ["-y"; Units/int]
}
-# Arc item configuration
+% Arc item configuration
type ArcStyle {
Arc ["arc"]
Chord ["chord"]
@@ -263,18 +290,19 @@ type ArcStyle {
subtype option(arc) {
Extent ["-extent"; float]
- # Fill is used by packer
+ Dash ["-dash"; string]
+ % Fill is used by packer
FillColor ["-fill"; Color]
Outline ["-outline"; Color]
OutlineStipple ["-outlinestipple"; Bitmap]
Start ["-start"; float]
Stipple ["-stipple"; Bitmap]
ArcStyle ["-style"; ArcStyle]
- Tags ["-tags"; [string list]]
+ Tags ["-tags"; [TagOrId/string list]]
Width
}
-# Bitmap item configuration
+% Bitmap item configuration
subtype option(bitmap) {
Anchor
Background
@@ -283,16 +311,19 @@ subtype option(bitmap) {
Tags
}
-# Image item configuration
+% Image item configuration
subtype option(image) {
Anchor
+##ifdef CAMLTK
+ ImagePhoto
+ ImageBitmap
+##else
Image
-# ImagePhoto
-# ImageBitmap
+##endif
Tags
}
-# Line item configuration
+% Line item configuration
type ArrowStyle {
Arrow_None ["none"]
Arrow_First ["first"]
@@ -314,8 +345,9 @@ type JoinStyle {
subtype option(line) {
ArrowStyle ["-arrow"; ArrowStyle]
- ArrowShape ["-arrowshape"; [int; int; int]]
+ ArrowShape ["-arrowshape"; [Units/int; Units/int; Units/int]]
CapStyle ["-capstyle"; CapStyle]
+ Dash
FillColor
JoinStyle ["-joinstyle"; JoinStyle]
Smooth ["-smooth"; bool]
@@ -325,35 +357,36 @@ subtype option(line) {
Width
}
-# Oval item configuration
+% Oval item configuration
subtype option(oval) {
- FillColor Outline Stipple Tags Width
+ Dash FillColor Outline Stipple Tags Width
}
-# Polygon item configuration
+% Polygon item configuration
subtype option(polygon) {
- FillColor Outline Smooth SplineSteps
+ Dash FillColor Outline Smooth SplineSteps
Stipple Tags Width
}
-# Rectangle item configuration
+% Rectangle item configuration
subtype option(rectangle) {
- FillColor Outline Stipple Tags Width
+ Dash FillColor Outline Stipple Tags Width
}
-# Text item configuration
+% Text item configuration
subtype option(canvastext) {
Anchor FillColor Font Justify
Stipple Tags Text Width
}
-# Window item configuration
+% Window item configuration
subtype option(window) {
Anchor Height Tags Width
Window ["-window"; widget]
+ Dash
}
-# Types of items
+% Types of items
type CanvasItem {
Arc_item ["arc"]
Bitmap_item ["bitmap"]
@@ -368,7 +401,7 @@ type CanvasItem {
}
widget canvas {
- # Standard options
+ % Standard options
option Background
option BorderWidth
option Cursor
@@ -387,51 +420,71 @@ widget canvas {
option TakeFocus
option XScrollCommand
option YScrollCommand
- # Widget specific options
+ % Widget specific options
option CloseEnough ["-closeenough"; float]
option Confine ["-confine"; bool]
- option Height ["-height"; int]
- option ScrollRegion ["-scrollregion"; [int;int;int;int]]
- option Width ["-width"; int]
- option XScrollIncrement ["-xscrollincrement"; int]
- option YScrollIncrement ["-yscrollincrement"; int]
+ option Height ["-height"; Units/int]
+ option ScrollRegion ["-scrollregion"; [Units/int;Units/int;Units/int;Units/int]]
+ option Width ["-width"; Units/int]
+ option XScrollIncrement ["-xscrollincrement"; Units/int]
+ option YScrollIncrement ["-yscrollincrement"; Units/int]
- function () addtag [widget(canvas); "addtag"; tag: string; specs: SearchSpec list] # Tag only
- # bbox not fully supported. should be builtin because of ambiguous result
- # will raise protocol__TkError if no items match TagOrId
+ function () addtag [widget(canvas); "addtag"; tag: TagOrId/string; specs: SearchSpec list] % Tag only
+ % bbox not fully supported. should be builtin because of ambiguous result
+ % will raise Protocol.TkError if no items match TagOrId
function (int,int,int,int) bbox [widget(canvas); "bbox"; TagOrId list]
external bind "builtin/canvas_bind"
+##ifdef CAMLTK
+ function (float) canvasx [widget(canvas); "canvasx"; ?spacing:[Units]; Units]
+ function (float) canvasy [widget(canvas); "canvasy"; ?spacing:[Units]; Units]
+ function (float) canvasx_grid [widget(canvas); "canvasx"; Units; Units]
+ function (float) canvasy_grid [widget(canvas); "canvasy"; Units; Units]
+##else
function (float) canvasx [widget(canvas); "canvasx"; x:int; ?spacing:[int]]
function (float) canvasy [widget(canvas); "canvasy"; y:int; ?spacing:[int]]
+##endif
function () configure [widget(canvas); "configure"; option(canvas) list]
function (string) configure_get [widget(canvas); "configure"]
- # TODO: check result
+ % TODO: check result
function (float list) coords_get [widget(canvas); "coords"; TagOrId]
+##ifdef CAMLTK
+ function () coords_set [widget(canvas); "coords"; TagOrId; xys: Units list]
+##else
function () coords_set [widget(canvas); "coords"; TagOrId; xys: {int, int} list]
- # create variations (see below)
+##endif
+ % create variations (see below)
function () dchars [widget(canvas); "dchars"; TagOrId; first: Index(canvas); last: Index(canvas)]
function () delete [widget(canvas); "delete"; TagOrId list]
- function () dtag [widget(canvas); "dtag"; TagOrId; tag: string]
+ function () dtag [widget(canvas); "dtag"; TagOrId; tag: TagOrId/string]
function (TagOrId list) find [widget(canvas); "find"; specs: SearchSpec list]
- # focus variations
+ % focus variations
function () focus_reset [widget(canvas); "focus"; ""]
function (TagOrId) focus_get [widget(canvas); "focus"]
function () focus [widget(canvas); "focus"; TagOrId]
- function (string list) gettags [widget(canvas); "gettags"; TagOrId]
+ function (TagOrId/string list) gettags [widget(canvas); "gettags"; TagOrId]
function () icursor [widget(canvas); "icursor"; TagOrId; index: Index(canvas)]
function (int) index [widget(canvas); "index"; TagOrId; index: Index(canvas)]
function () insert [widget(canvas); "insert"; TagOrId; before: Index(canvas); text: string]
+ % itemcget, itemconfigure are defined later
function () lower [widget(canvas); "lower"; TagOrId; ?below: [TagOrId]]
- function () move [widget(canvas); "move"; TagOrId; x: int; y: int]
+##ifdef CAMLTK
+ function () lower_below [widget(canvas); "lower"; TagOrId; TagOrId]
+ function () lower_bot [widget(canvas); "lower"; TagOrId]
+##endif
+ function () move [widget(canvas); "move"; TagOrId; x: Units/int; y: Units/int]
unsafe function (string) postscript [widget(canvas); "postscript"; option(postscript) list]
- # We use raise... with Module name
+ % We use raise with Module name
function () raise [widget(canvas); "raise"; TagOrId; ?above:[TagOrId]]
- function () scale [widget(canvas); "scale"; TagOrId; xorigin: int; yorigin: int; xscale: float; yscale: float]
- # For scan, use x:int and y:int since common usage is with mouse coordinates
+##ifdef CAMLTK
+ function () raise_above [widget(canvas); "raise"; TagOrId; TagOrId]
+ function () raise_top [widget(canvas); "raise"; TagOrId]
+##endif
+ function () scale [widget(canvas); "scale"; TagOrId; xorigin: Units/int; yorigin: Units/int; xscale: float; yscale: float]
+ % For scan, use x:int and y:int since common usage is with mouse coordinates
function () scan_mark [widget(canvas); "scan"; "mark"; x: int; y: int]
function () scan_dragto [widget(canvas); "scan"; "dragto"; x: int; y: int]
- # select variations
+ % select variations
function () select_adjust [widget(canvas); "select"; "adjust"; TagOrId; index: Index(canvas)]
function () select_clear [widget(canvas); "select"; "clear"]
function () select_from [widget(canvas); "select"; "from"; TagOrId; index: Index(canvas)]
@@ -444,16 +497,21 @@ widget canvas {
function () xview [widget(canvas); "xview"; scroll: ScrollValue]
function () yview [widget(canvas); "yview"; scroll: ScrollValue]
- # create and configure variations
- function (TagOrId) create_arc [widget(canvas); "create"; "arc"; x1: int; y1: int; x2: int; y2: int; option(arc) list]
- function (TagOrId) create_bitmap [widget(canvas); "create"; "bitmap"; x: int; y: int; option(bitmap) list]
- function (TagOrId) create_image [widget(canvas); "create"; "image"; x: int; y: int; option(image) list]
+ % create and configure variations
+ function (TagOrId) create_arc [widget(canvas); "create"; "arc"; x1: Units/int; y1: Units/int; x2: Units/int; y2: Units/int; option(arc) list]
+ function (TagOrId) create_bitmap [widget(canvas); "create"; "bitmap"; x: Units/int; y: Units/int; option(bitmap) list]
+ function (TagOrId) create_image [widget(canvas); "create"; "image"; x: Units/int; y: Units/int; option(image) list]
+##ifdef CAMLTK
+ function (TagOrId) create_line [widget(canvas); "create"; "line"; Units list; option(line) list]
+ function (TagOrId) create_polygon [widget(canvas); "create"; "polygon"; Units list; option(polygon) list]
+##else
function (TagOrId) create_line [widget(canvas); "create"; "line"; xys: {int, int} list; option(line) list]
- function (TagOrId) create_oval [widget(canvas); "create"; "oval"; x1: int; y1: int; x2: int; y2: int; option(oval) list]
function (TagOrId) create_polygon [widget(canvas); "create"; "polygon"; xys: {int, int} list; option(polygon) list]
- function (TagOrId) create_rectangle [widget(canvas); "create"; "rectangle"; x1: int; y1: int; x2: int; y2: int; option(rectangle) list]
- function (TagOrId) create_text [widget(canvas); "create"; "text"; x: int; y: int; option(canvastext) list]
- function (TagOrId) create_window [widget(canvas); "create"; "window"; x: int; y: int; option(window) list]
+##endif
+ function (TagOrId) create_oval [widget(canvas); "create"; "oval"; x1: Units/int; y1: Units/int; x2: Units/int; y2: Units/int; option(oval) list]
+ function (TagOrId) create_rectangle [widget(canvas); "create"; "rectangle"; x1: Units/int; y1: Units/int; x2: Units/int; y2: Units/int; option(rectangle) list]
+ function (TagOrId) create_text [widget(canvas); "create"; "text"; x: Units/int; y: Units/int; option(canvastext) list]
+ function (TagOrId) create_window [widget(canvas); "create"; "window"; x: Units/int; y: Units/int; option(window) list]
function (string) itemconfigure_get [widget(canvas); "itemconfigure"; TagOrId]
@@ -469,9 +527,9 @@ widget canvas {
}
-##### checkbutton(n)
+%%%%% checkbutton(n)
widget checkbutton {
- # Standard options
+ % Standard options
option ActiveBackground
option ActiveForeground
option Anchor
@@ -485,9 +543,12 @@ widget checkbutton {
option HighlightBackground
option HighlightColor
option HighlightThickness
+##ifdef CAMLTK
+ option ImageBitmap
+ option ImagePhoto
+##else
option Image
-# option ImageBitmap
-# option ImagePhoto
+##endif
option Justify
option PadX
option PadY
@@ -497,16 +558,19 @@ widget checkbutton {
option TextVariable
option UnderlinedChar
option WrapLength
- # Widget specific options
+ % Widget specific options
option Command
option Height
option IndicatorOn ["-indicatoron"; bool]
option OffValue ["-offvalue"; string]
option OnValue ["-onvalue"; string]
option SelectColor ["-selectcolor"; Color]
+##ifdef CAMLTK
+ option SelectImageBitmap (SelectImageBitmap) ["-selectimage"; ImageBitmap]
+ option SelectImagePhoto (SelectImagePhoto) ["-selectimage"; ImagePhoto]
+##else
option SelectImage ["-selectimage"; Image]
-# option SelectImageBitmap (SelectImageBitmap) ["-selectimage"; ImageBitmap]
-# option SelectImagePhoto (SelectImagePhoto) ["-selectimage"; ImagePhoto]
+##endif
option State
option Variable ["-variable"; TextVariable]
option Width
@@ -520,43 +584,41 @@ widget checkbutton {
function () toggle [widget(checkbutton); "toggle"]
}
-##### clipboard(n)
-subtype icccm(clipboard_clear) {
- DisplayOf ["-displayof"; widget]
- }
-
+%%%%% clipboard(n)
subtype icccm(clipboard_append) {
- DisplayOf ["-displayof"; widget]
ICCCMFormat ["-format"; string]
ICCCMType ["-type"; string]
}
module Clipboard {
- function () clear ["clipboard"; "clear"; icccm(clipboard_clear) list]
- function () append ["clipboard"; "append"; icccm(clipboard_append) list; "--"; data: string]
+ function () clear ["clipboard"; "clear"; ?displayof:["-displayof"; widget]]
+ function () append ["clipboard"; "append"; ?displayof:["-displayof"; widget]; icccm(clipboard_append) list; "--"; data: string]
}
-##### destroy(n)
+%%%%% destroy(n)
function () destroy ["destroy"; widget]
-##### tk_dialog(n)
+%%%%% tk_dialog(n)
module Dialog {
external create "builtin/dialog"
}
-##### entry(n)
-# Defined internally
-# subtype Index(entry) {
-# Number End Insert SelFirst SelLast At AnchorPoint
-# }
+%%%%% entry(n)
+% Defined internally
+% subtype Index(entry) {
+% Number End Insert SelFirst SelLast At AnchorPoint
+% }
+##ifndef CAMLTK
+% Only for Labltk. InputState is unified as State in Camltk
type InputState {
Normal ["normal"]
Disabled ["disabled"]
}
+##endif
widget entry {
- # Standard options
+ % Standard options
option Background
option BorderWidth
option Cursor
@@ -580,11 +642,16 @@ widget entry {
option TextVariable
option XScrollCommand
- # Widget specific options
+ % Widget specific options
option Show ["-show"; char]
+##ifdef CAMLTK
+ option State
+##else
option EntryState ["-state"; InputState]
+##endif
option TextWidth (Textwidth) ["-width"; int]
+ function (int,int,int,int) bbox [widget(entry); "bbox"; Index(entry)]
function () configure [widget(entry); "configure"; option(entry) list]
function (string) configure_get [widget(entry); "configure"]
function () delete_single [widget(entry); "delete"; index: Index(entry)]
@@ -595,7 +662,7 @@ widget entry {
function () insert [widget(entry); "insert"; index: Index(entry); text: string]
function () scan_mark [widget(entry); "scan"; "mark"; x: int]
function () scan_dragto [widget(entry); "scan"; "dragto"; x: int]
- # selection variation
+ % selection variation
function () selection_adjust [widget(entry); "selection"; "adjust"; index: Index(entry)]
function () selection_clear [widget(entry); "selection"; "clear"]
function () selection_from [widget(entry); "selection"; "from"; index: Index(entry)]
@@ -603,34 +670,104 @@ widget entry {
function () selection_range [widget(entry); "selection"; "range"; start: Index(entry) ; stop: Index(entry)]
function () selection_to [widget(entry); "selection"; "to"; index: Index(entry)]
+ function (float,float) xview_get [widget(entry); "xview"]
function () xview [widget(entry); "xview"; scroll: ScrollValue]
function () xview_index [widget(entry); "xview"; index: Index(entry)]
function (float, float) xview_get [widget(entry); "xview"]
}
-##### focus(n)
-##### tk_focusNext(n)
+%%%%% focus(n)
+%%%%% tk_focusNext(n)
module Focus {
- unsafe function (widget) get ["focus"]
- function () set ["focus"; widget]
+ unsafe function (widget) get ["focus"; ?displayof:["-displayof"; widget]]
unsafe function (widget) displayof ["focus"; "-displayof"; widget]
- function () force ["focus"; "-force"; widget]
+ function () set ["focus"; widget]
+ function () force ["focus"; "-force"; widget]
unsafe function (widget) lastfor ["focus"; "-lastfor"; widget]
unsafe function (widget) next ["tk_focusNext"; widget]
unsafe function (widget) prev ["tk_focusPrev"; widget]
- function () follows_mouse ["tk_focusFollowsMouse"]
+ function () follows_mouse ["tk_focusFollowsMouse"]
+}
+
+type font external % builtin/builtin_font.ml
+
+type weight {
+ Weight_Normal(Normal) ["normal"]
+ Weight_Bold(Bold) ["bold"]
+}
+
+type slant {
+ Slant_Roman(Roman) ["roman"]
+ Slant_Italic(Italic) ["italic"]
}
+type fontMetrics {
+ Ascent ["-ascent"]
+ Descent ["-descent"]
+ Linespace ["-linespace"]
+ Fixed ["-fixed"]
+}
+
+subtype options(font) {
+ Font_Family ["-family"; string]
+ Font_Size ["-size"; int]
+ Font_Weight ["-weight"; weight]
+ Font_Slant ["-slant"; slant]
+ Font_Underline ["-underline"; bool]
+ Font_Overstrike ["-overstrike"; bool]
+% later, JP only
+% Charset ["-charset"; string]
+%% Beware of the order of Compound ! Put it as the first option
+% Compound ["-compound"; [font list]]
+% Copy ["-copy"; string]
+}
+
+module Font {
+ function (string) actual ["font"; "actual"; font;
+ ?displayof:["-displayof"; widget];
+ options(font) list]
+##ifdef CAMLTK
+ function (string) actual_displayof ["font"; "actual"; font;
+ "-displayof"; widget;
+ options(font) list]
+##endif
+ function () configure ["font"; "configure"; font; options(font) list]
+ function (font) create ["font"; "create"; options(font) list]
+ function () delete ["font"; "delete"; font]
+ function (string list) families ["font"; "families";
+ ?displayof:["-displayof"; widget]]
+##ifdef CAMLTK
+ function (string list) families_displayof ["font"; "families";
+ "-displayof"; widget]
+##endif
+ function (int) measure ["font"; "measure"; font; string;
+ ?displayof:["-displayof"; widget]]
+##ifdef CAMLTK
+ function (int) measure_displayof ["font"; "measure"; font;
+ "-displayof"; widget; string ]
+##endif
+ function (int) metrics ["font"; "metrics"; font;
+ ?displayof:["-displayof"; widget];
+ fontMetrics ]
+##ifdef CAMLTK
+ function (int) metrics_displayof ["font"; "metrics"; font;
+ "-displayof"; widget;
+ fontMetrics ]
+##endif
+ function (string list) names ["font"; "names"]
+% JP
+% function () failsafe ["font"; "failsafe"; string]
+}
-##### frame(n)
+%%%%% frame(n)
type Colormap {
NewColormap (New) ["new"]
WidgetColormap (Widget) [widget]
}
-# Visual classes are: directcolor, grayscale, greyscale, pseudocolor,
-# staticcolor, staticgray, staticgrey, truecolor
+% Visual classes are: directcolor, grayscale, greyscale, pseudocolor,
+% staticcolor, staticgray, staticgrey, truecolor
type Visual {
ClassVisual (Clas) [[string; int]]
DefaultVisual ["default"]
@@ -640,7 +777,7 @@ type Visual {
}
widget frame {
- # Standard options
+ % Standard options
option BorderWidth
option Cursor
option HighlightBackground
@@ -649,22 +786,27 @@ widget frame {
option Relief
option TakeFocus
- # Widget specific options
+ % Widget specific options
option Background
+##ifdef CAMLTK
+ option Class ["-class"; string]
+##else
option Clas ["-class"; string]
+##endif
option Colormap ["-colormap"; Colormap]
+ option Container ["-container"; bool]
option Height
option Visual ["-visual"; Visual]
option Width
- # Class and Colormap and Visual cannot be changed
+ % Class and Colormap and Visual cannot be changed
function () configure [widget(frame); "configure"; option(frame) list]
function (string) configure_get [widget(frame); "configure"]
}
-##### grab(n)
+%%%%% grab(n)
type GrabStatus {
GrabNone ["none"]
GrabLocal ["local"]
@@ -672,26 +814,32 @@ type GrabStatus {
}
type GrabGlobal external
module Grab {
- function () set ["grab"; ?global:[GrabGlobal]; widget]
-# function () set_global ["grab"; "-global"; widget]
+ function () set ["grab"; "set"; ?global:[GrabGlobal]; widget]
+##ifdef CAMLTK
+ function () set_global ["grab"; "set"; "-global"; widget]
+##endif
unsafe function (widget list) current ["grab"; "current"; ?displayof:[widget]]
-# unsafe function (widget list) current ["grab"; "current"; widget]
-# unsafe function (widget list) all_current ["grab"; "current"]
+##ifdef CAMLTK
+ % all_current is now current.
+ % The old current is now current_of
+ unsafe function (widget list) current_of ["grab"; "current"; widget]
+##endif
function () release ["grab"; "release"; widget]
function (GrabStatus) status ["grab"; "status"; widget]
}
subtype option(rowcolumnconfigure) {
- Minsize ["-minsize"; int]
+ Minsize ["-minsize"; Units/int]
Weight ["-weight"; float]
+ Pad ["-pad"; Units/int]
}
subtype option(grid) {
Column ["-column"; int]
ColumnSpan ["-columnspan"; int]
In(Inside) ["-in"; widget]
- IPadX ["-ipadx"; int]
- IPadY ["-ipady"; int]
+ IPadX ["-ipadx"; Units/int]
+ IPadY ["-ipady"; Units/int]
PadX
PadY
Row ["-row"; int]
@@ -699,11 +847,13 @@ subtype option(grid) {
Sticky ["-sticky"; string]
}
-# Same as pack
+% Same as pack
function () grid ["grid"; widget list; option(grid) list]
module Grid {
- function (int,int,int,int) bbox ["grid"; "bbox"; widget; int; int]
+ function (int,int,int,int) bbox ["grid"; "bbox"; widget]
+ function (int,int,int,int) bbox_cell ["grid"; "bbox"; widget; column: int; row: int]
+ function (int,int,int,int) bbox_span ["grid"; "bbox"; widget; column1: int; row1: int; column2: int; row2: int]
function () column_configure
["grid"; "columnconfigure"; widget; int;
option(rowcolumnconfigure) list]
@@ -711,38 +861,36 @@ module Grid {
function (string) column_configure_get ["grid"; "columnconfigure"; widget;
int]
function () forget ["grid"; "forget"; widget list]
- ## info returns only a string
+ %% info returns only a string
function (string) info ["grid"; "info"; widget]
- ## TODO: check result values
- function (int,int) location ["grid"; "location"; widget; x:int; y:int]
+ %% TODO: check result values
+ function (int,int) location ["grid"; "location"; widget; x:Units/int; y:Units/int]
function (bool) propagate_get ["grid"; "propagate"; widget]
function () propagate_set ["grid"; "propagate"; widget; bool]
function () row_configure
["grid"; "rowconfigure"; widget; int; option(rowcolumnconfigure) list]
- function (string) row_configure_get
- ["grid"; "rowconfigure"; widget; int]
+ function (string) row_configure_get ["grid"; "rowconfigure"; widget; int]
function (int,int) size ["grid"; "size"; widget]
+##ifdef CAMLTK
function (widget list) slaves ["grid"; "slaves"; widget; ?column:["-column"; int]; ?row:["-row"; int]]
-# function (widget list) all_slaves ["grid"; "slaves"; widget]
-# function (widget list) row_slaves ["grid"; "slaves"; widget; "-row"; int]
-# function (widget list) column_slaves ["grid"; "slaves"; widget; "-column"; int]
+ function (widget list) row_slaves ["grid"; "slaves"; widget; "-row"; int]
+ function (widget list) column_slaves ["grid"; "slaves"; widget; "-column"; int]
+##else
+ function (widget list) slaves ["grid"; "slaves"; widget; ?column:["-column"; int]; ?row:["-row"; int]]
+##endif
}
+%%%%% image(n)
+%%%%% cf Imagephoto and Imagebitmap
+% Some functions on images are implemented in Imagephoto or Imagebitmap.
+module Image {
+ external names "builtin/image"
+}
-
-
-
-
-##### image(n)
-##### cf bitmap(n) and photo(n)
-# Some functions on images are not implemented
-# names, types
-
-
-##### label(n)
+%%%%% label(n)
widget label {
- # Standard options
+ % Standard options
option Anchor
option Background
option Bitmap
@@ -753,9 +901,12 @@ widget label {
option HighlightBackground
option HighlightColor
option HighlightThickness
+##ifdef CAMLTK
+ option ImageBitmap
+ option ImagePhoto
+##else
option Image
-# option ImageBitmap
-# option ImagePhoto
+##endif
option Justify
option PadX
option PadY
@@ -766,9 +917,9 @@ widget label {
option UnderlinedChar
option WrapLength
- # Widget specific options
+ % Widget specific options
option Height
- # use according to label contents
+ % use according to label contents
option Width
option TextWidth
@@ -777,12 +928,12 @@ widget label {
}
-##### listbox(n)
+%%%%% listbox(n)
-# Defined internally
-# subtype Index(listbox) {
-# Number Active AnchorPoint End AtXY
-#}
+% Defined internally
+% subtype Index(listbox) {
+% Number Active AnchorPoint End AtXY
+%}
type SelectModeType {
Single ["single"]
@@ -793,13 +944,14 @@ type SelectModeType {
widget listbox {
- # Standard options
+ % Standard options
option Background
option BorderWidth
option Cursor
option ExportSelection
- option Foreground
option Font
+ option Foreground
+ % Height is TextHeight
option HighlightBackground
option HighlightColor
option HighlightThickness
@@ -809,9 +961,10 @@ widget listbox {
option SelectForeground
option SetGrid
option TakeFocus
+ % Width is TextWidth
option XScrollCommand
option YScrollCommand
- # Widget specific options
+ % Widget specific options
option TextHeight ["-height"; int]
option TextWidth
option SelectMode ["-selectmode"; SelectModeType]
@@ -844,18 +997,19 @@ widget listbox {
function () yview [widget(listbox); "yview"; scroll: ScrollValue]
}
-##### lower(n)
+%%%%% lower(n)
function () lower_window ["lower"; widget; ?below:[widget]]
-#function () lower_window ["lower"; widget]
-#function () lower_window_below ["lower"; widget; below: widget]
+##ifdef CAMLTK
+function () lower_window_below ["lower"; widget; below: widget]
+##endif
-##### menu(n)
-##### tk_popup(n)
-# defined internally
-# subtype Index(menu) {
-# Number Active End Last None At Pattern
-# }
+%%%%% menu(n)
+%%%%% tk_popup(n)
+% defined internally
+% subtype Index(menu) {
+% Number Active End Last None At Pattern
+% }
type MenuItem {
Cascade_Item ["cascade"]
@@ -866,66 +1020,104 @@ type MenuItem {
TearOff_Item ["tearoff"]
}
-# notused as a subtype. just for cleaning up the rest.
+% notused as a subtype. just for cleaning up the rest.
subtype option(menuentry) {
ActiveBackground
ActiveForeground
Accelerator ["-accelerator"; string]
Background
Bitmap
+ ColumnBreak ["-columnbreak"; bool]
Command
Font
Foreground
+ HideMargin ["-hidemargin"; bool]
+##ifdef CAMLTK
+ ImageBitmap
+ ImagePhoto
+##else
Image
+##endif
IndicatorOn
Label ["-label"; string]
Menu ["-menu"; widget(menu)]
OffValue
OnValue
SelectColor
+##ifdef CAMLTK
+ SelectImageBitmap
+ SelectImagePhoto
+##else
SelectImage
+##endif
State
UnderlinedChar
Value ["-value"; string]
Variable
}
-# Options for cascade entry
+% Options for cascade entry
subtype option(menucascade) {
ActiveBackground ActiveForeground Accelerator
- Background Bitmap Command Font Foreground
- Image Label Menu State UnderlinedChar
+ Background Bitmap ColumnBreak Command Font Foreground
+ HideMargin
+##ifdef CAMLTK
+ ImageBitmap ImagePhoto
+##else
+ Image
+##endif
+ IndicatorOn Label Menu State UnderlinedChar
}
-# Options for radiobutton entry
+% Options for radiobutton entry
subtype option(menuradio) {
ActiveBackground ActiveForeground Accelerator
- Background Bitmap Command Font Foreground
- Image IndicatorOn Label
- SelectColor SelectImage
+ Background Bitmap ColumnBreak Command Font Foreground
+##ifdef CAMLTK
+ ImageBitmap ImagePhoto SelectImageBitmap SelectImagePhoto
+##else
+ Image SelectImage
+##endif
+ IndicatorOn Label SelectColor
State UnderlinedChar Value Variable
}
-# Options for checkbutton entry
+% Options for checkbutton entry
subtype option(menucheck) {
ActiveBackground ActiveForeground Accelerator
- Background Bitmap Command Font Foreground
- Image IndicatorOn Label
- OffValue OnValue SelectColor SelectImage
+ Background Bitmap ColumnBreak Command Font Foreground
+##ifdef CAMLTK
+ ImageBitmap SelectImageBitmap ImagePhoto SelectImagePhoto
+##else
+ Image SelectImage
+##endif
+ IndicatorOn Label
+ OffValue OnValue SelectColor
State UnderlinedChar Variable
}
-# Options for command entry
+% Options for command entry
subtype option(menucommand) {
ActiveBackground ActiveForeground Accelerator
- Background Bitmap Command Font Foreground
- Image Label State UnderlinedChar
+ Background Bitmap ColumnBreak Command Font Foreground
+##ifdef CAMLTK
+ ImageBitmap ImagePhoto
+##else
+ Image
+##endif
+ Label State UnderlinedChar
}
-# Separators and tearoffs don't have options
+type menuType {
+ Menu_Menubar ["menubar"]
+ Menu_Tearoff ["tearoff"]
+ Menu_Normal ["normal"]
+}
+
+% Separators and tearoffs don't have options
widget menu {
- # Standard options
+ % Standard options
option ActiveBackground
option ActiveBorderWidth
option ActiveForeground
@@ -937,21 +1129,25 @@ widget menu {
option Foreground
option Relief
option TakeFocus
- # Widget specific options
+ % Widget specific options
option PostCommand ["-postcommand"; function()]
option SelectColor
option TearOff ["-tearoff"; bool]
+ option TearOffCommand ["-tearoffcommand"; function(menu: widget(any), tornoff: widget(any)) ]
+ option MenuTitle ["-title"; string]
+ option MenuType ["-type"; menuType]
function () activate [widget(menu); "activate"; index: Index(menu)]
- # add variations
+ % add variations
function () add_cascade [widget(menu); "add"; "cascade"; option(menucascade) list]
function () add_checkbutton [widget(menu); "add"; "checkbutton"; option(menucheck) list]
function () add_command [widget(menu); "add"; "command"; option(menucommand) list]
function () add_radiobutton [widget(menu); "add"; "radiobutton"; option(menuradio) list]
function () add_separator [widget(menu); "add"; "separator"]
+ % not for user: function clone [widget(menu); "clone"; ???; menuType]
function () configure [widget(menu); "configure"; option(menu) list]
function (string) configure_get [widget(menu); "configure"]
- # beware of possible callback leak when deleting menu entries
+ % beware of possible callback leak when deleting menu entries
function () delete [widget(menu); "delete"; first: Index(menu); last: Index(menu)]
function () configure_cascade [widget(menu); "entryconfigure"; Index(menu); option(menucascade) list]
function () configure_checkbutton [widget(menu); "entryconfigure"; Index(menu); option(menucheck) list]
@@ -967,21 +1163,29 @@ widget menu {
function (string) invoke [widget(menu); "invoke"; index: Index(menu)]
function () post [widget(menu); "post"; x: int; y: int]
function () postcascade [widget(menu); "postcascade"; index: Index(menu)]
- # can't use type of course
+ % can't use type of course
function (MenuItem) typeof [widget(menu); "type"; index: Index(menu)]
function () unpost [widget(menu); "unpost"]
function (int) yposition [widget(menu); "yposition"; index: Index(menu)]
function () popup ["tk_popup"; widget(menu); x: int; y: int; ?entry:[Index(menu)]]
-# function () popup ["tk_popup"; widget(menu); x: int; y: int]
-# function () popup_entry ["tk_popup"; widget(menu); x: int; y: int; index: Index(menu)]
+##ifdef CAMLTK
+ function () popup_entry ["tk_popup"; widget(menu); x: int; y: int; index: Index(menu)]
+##endif
}
-##### menubutton(n)
+%%%%% menubutton(n)
+
+type menubuttonDirection {
+ Dir_Above ["above"]
+ Dir_Below ["below"]
+ Dir_Left ["left"]
+ Dir_Right ["right"]
+}
widget menubutton {
- # Standard options
+ % Standard options
option ActiveBackground
option ActiveForeground
option Anchor
@@ -995,9 +1199,12 @@ widget menubutton {
option HighlightBackground
option HighlightColor
option HighlightThickness
+##ifdef CAMLTK
+ option ImageBitmap
+ option ImagePhoto
+##else
option Image
-# option ImageBitmap
-# option ImagePhoto
+##endif
option Justify
option PadX
option PadY
@@ -1007,7 +1214,8 @@ widget menubutton {
option TextVariable
option UnderlinedChar
option WrapLength
- # Widget specific options
+ % Widget specific options
+ option Direction ["-direction"; menubuttonDirection ]
option Height
option IndicatorOn
option Menu ["-menu"; widget(menu)]
@@ -1021,9 +1229,9 @@ widget menubutton {
-##### message(n)
+%%%%% message(n)
widget message {
- # Standard options
+ % Standard options
option Anchor
option Background
option BorderWidth
@@ -1039,7 +1247,7 @@ widget message {
option TakeFocus
option Text
option TextVariable
- # Widget specific options
+ % Widget specific options
option Aspect ["-aspect"; int]
option Justify
option Width
@@ -1049,7 +1257,7 @@ widget message {
}
-##### option(n)
+%%%%% option(n)
type OptionPriority {
WidgetDefault ["widgetDefault"]
StartupFile ["startupFile"]
@@ -1058,6 +1266,22 @@ type OptionPriority {
Priority [int]
}
+##ifdef CAMLTK
+
+module Option {
+ unsafe function () add ["option"; "add"; string; string; OptionPriority]
+ function () clear ["option"; "clear"]
+ function (string) get ["option"; "get"; widget; string; string]
+ unsafe function () readfile ["option"; "readfile"; string; OptionPriority]
+ }
+%% Resource is now superseded by Option
+module Resource {
+ unsafe function () add ["option"; "add"; string; string; OptionPriority]
+ function () clear ["option"; "clear"]
+ function (string) get ["option"; "get"; widget; string; string]
+ unsafe function () readfile ["option"; "readfile"; string; OptionPriority]
+ }
+##else
module Option {
unsafe function () add
["option"; "add"; path: string; string; ?priority:[OptionPriority]]
@@ -1066,14 +1290,15 @@ module Option {
unsafe function () readfile
["option"; "readfile"; string; ?priority:[OptionPriority]]
}
+##endif
-##### tk_optionMenu(n)
+%%%%% tk_optionMenu(n)
module Optionmenu {
external create "builtin/optionmenu"
}
-##### pack(n)
+%%%%% pack(n)
type Side {
Side_Left ["left"]
Side_Right ["right"]
@@ -1095,8 +1320,8 @@ subtype option(pack) {
Expand ["-expand"; bool]
Fill ["-fill"; FillMode]
In(Inside) ["-in"; widget]
- IPadX ["-ipadx"; int]
- IPadY ["-ipady"; int]
+ IPadX ["-ipadx"; Units/int]
+ IPadY ["-ipady"; Units/int]
PadX
PadY
Side ["-side"; Side]
@@ -1107,12 +1332,13 @@ function () pack ["pack"; widget list; option(pack) list]
module Pack {
function () configure ["pack"; "configure"; widget list; option(pack) list]
function () forget ["pack"; "forget"; widget list]
+ function (string) info ["pack"; "info"; widget]
function (bool) propagate_get ["pack"; "propagate"; widget]
function () propagate_set ["pack"; "propagate"; widget; bool]
function (widget list) slaves ["pack"; "slaves"; widget]
}
-subtype TkPalette(any) { # Not sophisticated...
+subtype TkPalette(any) { % Not sophisticated...
PaletteActiveBackground ["activeBackground"; Color]
PaletteActiveForeground ["activeForeground"; Color]
PaletteBackground ["background"; Color]
@@ -1127,18 +1353,19 @@ subtype TkPalette(any) { # Not sophisticated...
PaletteTroughColor ["troughColor"; Color]
}
-##### tk_setPalette(n)
-#### can't simply encode general form of tk_setPalette
+%%%%% tk_setPalette(n)
+%%%% can't simply encode general form of tk_setPalette
module Palette {
function () set_background ["tk_setPalette"; Color]
function () set ["tk_setPalette"; TkPalette(any) list]
function () bisque ["tk_bisque"]
}
-##### photo(n)
-type PaletteType external # builtin_palette.ml
+%%%%% photo(n)
+type PaletteType external % builtin_palette.ml
subtype option(photoimage) {
+ % Channel ["-channel"; file_descr] % removed in 8.3 ?
Data
Format ["-format"; string]
File
@@ -1172,25 +1399,32 @@ subtype photo(write) {
}
module Imagephoto {
- function (ImagePhoto) create ["image"; "create"; "photo"; option(photoimage) list]
+ function (ImagePhoto) create ["image"; "create"; "photo"; ?name:[ImagePhoto]; option(photoimage) list]
+##ifdef CAMLTK
+ function (ImagePhoto) create_named ["image"; "create"; "photo"; ImagePhoto; option(photoimage) list]
+##endif
+ function () delete ["image"; "delete"; ImagePhoto]
+ function (int) height ["image"; "height"; ImagePhoto]
+ function (int) width ["image"; "width"; ImagePhoto]
+
+%name
+%type
+
function () blank [ImagePhoto; "blank"]
function () configure [ImagePhoto; "configure"; option(photoimage) list]
function (string) configure_get [ImagePhoto; "configure"]
function () copy [ImagePhoto; "copy"; src: ImagePhoto; photo(copy) list]
function (int, int, int) get [ImagePhoto; "get"; x: int; y: int]
-# can't express nested lists ?
-# function () put [ImagePhoto; "put"; [[Color list] list]; photo(put) list]
+% it is buggy ? can't express nested lists ?
+% function () put [ImagePhoto; "put"; [[Color list] list]; photo(put)]
function () read [ImagePhoto; "read"; file: string; photo(read) list]
function () redither [ImagePhoto; "redither"]
- function () write [ImagePhoto; "write"; photo(write) list]
- # Functions inherited from the "image" TK class
- function () delete ["image"; "delete"; ImagePhoto]
- function (int) height ["image"; "height"; ImagePhoto]
- function (int) width ["image"; "width"; ImagePhoto]
+ function () write [ImagePhoto; "write"; file: string; photo(write) list]
+ % Functions inherited from the "image" TK class
}
-##### place(n)
+%%%%% place(n)
type BorderMode {
Inside ["inside"]
Outside ["outside"]
@@ -1221,10 +1455,10 @@ module Place {
}
-##### radiobutton(n)
+%%%%% radiobutton(n)
widget radiobutton {
- # Standard options
+ % Standard options
option ActiveBackground
option ActiveForeground
option Anchor
@@ -1238,9 +1472,12 @@ widget radiobutton {
option HighlightBackground
option HighlightColor
option HighlightThickness
+##ifdef CAMLTK
+ option ImageBitmap
+ option ImagePhoto
+##else
option Image
-# option ImageBitmap
-# option ImagePhoto
+##endif
option Justify
option PadX
option PadY
@@ -1251,14 +1488,17 @@ widget radiobutton {
option UnderlinedChar
option WrapLength
- # Widget specific options
+ % Widget specific options
option Command
option Height
option IndicatorOn
option SelectColor
+##ifdef CAMLTK
+ option SelectImageBitmap
+ option SelectImagePhoto
+##else
option SelectImage
-# option SelectImageBitmap
-# option SelectImagePhoto
+##endif
option State
option Value
option Variable
@@ -1273,24 +1513,33 @@ widget radiobutton {
}
-##### raise(n)
-# We cannot use raise !!
+%%%%% raise(n)
+% We cannot use raise !!
function () raise_window ["raise"; widget; ?above:[widget]]
-#function () raise_window ["raise"; widget]
-#function () raise_window_above ["raise"; widget; above: widget]
-
-
-##### scale(n)
-## shared with scrollbars
+##ifdef CAMLTK
+function () raise_window_above ["raise"; widget; widget]
+##endif
+
+%%%%% scale(n)
+%% shared with scrollbars
+##ifdef CAMLTK
+subtype WidgetElement(scale) {
+ Slider ["slider"]
+ Trough1 ["trough1"]
+ Trough2 ["trough2"]
+ Beyond [""]
+ }
+##else
type ScaleElement {
Slider ["slider"]
Trough1 ["trough1"]
Trough2 ["trough2"]
Beyond [""]
}
+##endif
widget scale {
- # Standard options
+ % Standard options
option ActiveBackground
option Background
option BorderWidth
@@ -1307,32 +1556,48 @@ widget scale {
option TakeFocus
option TroughColor
- # Widget specific options
+ % Widget specific options
option BigIncrement ["-bigincrement"; float]
option ScaleCommand ["-command"; function (float)]
option Digits ["-digits"; int]
option From(Min) ["-from"; float]
option Label ["-label"; string]
- option Length ["-length"; int]
+ option Length ["-length"; Units/int]
option Resolution ["-resolution"; float]
option ShowValue ["-showvalue"; bool]
- option SliderLength ["-sliderlength"; int]
+ option SliderLength ["-sliderlength"; Units/int]
option State
option TickInterval ["-tickinterval"; float]
option To(Max) ["-to"; float]
option Variable
option Width
+##ifdef CAMLTK
+ function (int,int) coords [widget(scale); "coords"]
+ function (int,int) coords_at [widget(scale); "coords"; at: float]
+##else
+ function (int,int) coords [widget(scale); "coords"; ?at: [float]]
+##endif
function () configure [widget(scale); "configure"; option(scale) list]
function (string) configure_get [widget(scale); "configure"]
function (float) get [widget(scale); "get"]
function (float) get_xy [widget(scale); "get"; x: int; y: int]
- function (ScaleElement) identify [widget(scale); x: int; y: int]
+ function (WidgetElement/ScaleElement) identify [widget(scale); x: int; y: int]
function () set [widget(scale); "set"; float]
}
-##### scrollbar(n)
+%%%%% scrollbar(n)
+##ifdef CAMLTK
+subtype WidgetElement(scrollbar) {
+ Arrow1 ["arrow1"]
+ Trough1
+ Trough2
+ Slider
+ Arrow2 ["arrow2"]
+ Beyond
+ }
+##else
type ScrollbarElement {
Arrow1 ["arrow1"]
Trough1 ["through1"]
@@ -1341,9 +1606,10 @@ type ScrollbarElement {
Arrow2 ["arrow2"]
Beyond [""]
}
+##endif
widget scrollbar {
- # Standard options
+ % Standard options
option ActiveBackground
option Background
option BorderWidth
@@ -1358,30 +1624,34 @@ widget scrollbar {
option RepeatInterval
option TakeFocus
option TroughColor
- # Widget specific options
+ % Widget specific options
option ActiveRelief ["-activerelief"; Relief]
option ScrollCommand ["-command"; function(scroll: ScrollValue)]
- option ElementBorderWidth ["-elementborderwidth"; int]
+ option ElementBorderWidth ["-elementborderwidth"; Units/int]
option Width
+##ifdef CAMLTK
+ function () activate [widget(scrollbar); "activate"; element: WidgetElement(scrollbar)]
+##else
function () activate [widget(scrollbar); "activate"; element: ScrollbarElement]
- function (ScrollbarElement) activate_get [widget(scrollbar); "activate"]
+##endif
+ function (WidgetElement/ScrollbarElement) activate_get [widget(scrollbar); "activate"]
function () configure [widget(scrollbar); "configure"; option(scrollbar) list]
function (string) configure_get [widget(scrollbar); "configure"]
function (float) delta [widget(scrollbar); "delta"; x: int; y: int]
function (float) fraction [widget(scrollbar); "fraction"; x: int; y: int]
function (float, float) get [widget(scrollbar); "get"]
- function (int, int, int, int) old_get [widget(scrollbar); "get"]
- function (ScrollbarElement) identify [widget(scrollbar); "identify"; x: int; y: int]
+ function (int,int,int,int) old_get [widget(scrollbar); "get"]
+ function (WidgetElement/ScrollbarElement) identify [widget(scale); "identify"; int; int]
function () set [widget(scrollbar); "set"; first: float; last: float]
function () old_set [widget(scrollbar); "set"; total:int; window:int; first:int; last:int]
}
-##### selection(n)
+%%%%% selection(n)
subtype icccm(selection_clear) {
- DisplayOf
+ DisplayOf ["-displayof"; widget]
Selection ["-selection"; string]
}
@@ -1397,7 +1667,8 @@ subtype icccm(selection_ownset) {
}
subtype icccm(selection_handle) {
- Selection ICCCMType
+ Selection
+ ICCCMType
ICCCMFormat ["-format"; string]
}
@@ -1405,16 +1676,24 @@ module Selection {
function () clear ["selection"; "clear"; icccm(selection_clear) list]
function (string) get ["selection"; "get"; icccm(selection_get) list]
- # function () handle_set ["selection"; "handle"; icccm(selection_handle) list; widget; function(int,int)]
+ % function () handle_set ["selection"; "handle"; icccm(selection_handle) list; widget; function(int,int)]
external handle_set "builtin/selection_handle_set"
unsafe function (widget) own_get ["selection"; "own"; icccm(selection_clear) list]
- # builtin
- # function () own_set ["selection"; "own"; widget; icccm(selection_ownset) list]
+ % builtin
+ % function () own_set ["selection"; "own"; widget; icccm(selection_ownset) list]
external own_set "builtin/selection_own_set"
}
-##### text(n)
+%%%%% send(n)
+type SendOption {
+ SendDisplayOf ["-displayof"; widget] % DisplayOf is used for icccm !
+ SendAsync ["-async"]
+}
+
+unsafe function () send ["send"; SendOption list; "--"; app: string; command: string list]
+
+%%%%% text(n)
type TextIndex external
type TextTag external
@@ -1422,10 +1701,10 @@ type TextMark external
type TabType {
- TabLeft [int; "left"]
- TabRight [int; "right"]
- TabCenter [int; "center"]
- TabNumeric [int; "numeric"]
+ TabLeft [Units/int; "left"]
+ TabRight [Units/int; "right"]
+ TabCenter [Units/int; "center"]
+ TabNumeric [Units/int; "numeric"]
}
type WrapMode {
@@ -1443,7 +1722,6 @@ type Comparison {
NEQ (Neq) ["!="]
}
-
type MarkDirection {
Mark_Left ["left"]
Mark_Right ["right"]
@@ -1458,7 +1736,12 @@ type AlignType {
subtype option(embeddedi) {
Align ["-align"; AlignType]
+##ifdef CAMLTK
+ ImageBitmap
+ ImagePhoto
+##else
Image
+##endif
Name ["-name"; string]
PadX
PadY
@@ -1481,8 +1764,17 @@ type TextSearch {
Count ["-count"; TextVariable]
}
+type text_dump {
+ DumpAll ["-all"]
+ DumpCommand ["-command"; function (key: string, value: string, index: string)]
+ DumpMark ["-mark"]
+ DumpTag ["-tag"]
+ DumpText ["-text"]
+ DumpWindow ["-window"]
+ }
+
widget text {
- # Standard options
+ % Standard options
option Background
option BorderWidth
option Cursor
@@ -1508,12 +1800,16 @@ widget text {
option XScrollCommand
option YScrollCommand
- # Widget specific options
+ % Widget specific options
option TextHeight
- option Spacing1 ["-spacing1"; int]
- option Spacing2 ["-spacing2"; int]
- option Spacing3 ["-spacing3"; int]
+ option Spacing1 ["-spacing1"; Units/int]
+ option Spacing2 ["-spacing2"; Units/int]
+ option Spacing3 ["-spacing3"; Units/int]
+##ifdef CAMLTK
+ option State
+##else
option EntryState
+##endif
option Tabs ["-tabs"; [TabType list]]
option TextWidth
option Wrap ["-wrap"; WrapMode]
@@ -1526,6 +1822,11 @@ widget text {
function () delete [widget(text); "delete"; start: TextIndex; stop: TextIndex]
function () delete_char [widget(text); "delete"; index: TextIndex]
function (int, int, int, int, int) dlineinfo [widget(text); "dlineinfo"; index: TextIndex]
+
+ % require result parser
+ function (string list) dump [widget(text); "dump"; text_dump list; start: TextIndex; stop: TextIndex]
+ function (string list) dump_char [widget(text); "dump"; text_dump list; index: TextIndex]
+
function (string) get [widget(text); "get"; start: TextIndex; stop: TextIndex]
function (string) get_char [widget(text); "get"; index: TextIndex]
function () image_configure
@@ -1536,48 +1837,81 @@ widget text {
[widget(text); "image"; "create"; option(embeddedi) list]
function (string list) image_names [widget(text); "image"; "names"]
function (Index(text) as "[>`Linechar of int * int]") index [widget(text); "index"; index: TextIndex]
+##ifdef CAMLTK
+ function () insert [widget(text); "insert"; index: TextIndex; text: string; [TextTag list]]
+##else
function () insert [widget(text); "insert"; index: TextIndex; text: string; ?tags: [TextTag list]]
- # Mark
+##endif
+ % Mark
function () mark_gravity_set [widget(text); "mark"; "gravity"; mark: TextMark; direction: MarkDirection]
function (MarkDirection) mark_gravity_get [widget(text); "mark"; "gravity"; mark: TextMark]
function (TextMark list) mark_names [widget(text); "mark"; "names"]
+ function (TextMark) mark_next [widget(text); "mark"; "next"; index: TextIndex]
+ function (TextMark) mark_previous [widget(text); "mark"; "previous"; index: TextIndex]
function () mark_set [widget(text); "mark"; "set"; mark: TextMark; index: TextIndex]
function () mark_unset [widget(text); "mark"; "unset"; marks: TextMark list]
- # Scan
+ % Scan
function () scan_mark [widget(text); "scan"; "mark"; x: int; y: int]
function () scan_dragto [widget(text); "scan"; "dragto"; x: int; y: int]
+##ifdef CAMLTK
+ function (Index) search [widget(text); "search"; TextSearch list; "--"; string; TextIndex; TextIndex]
+##else
function (Index(text) as "[>`Linechar of int * int]") search [widget(text); "search"; switches: TextSearch list; "--"; pattern: string; start: TextIndex; ?stop: [TextIndex]]
+##endif
function () see [widget(text); "see"; index: TextIndex]
- # Tags
+ % Tags
function () tag_add [widget(text); "tag"; "add"; tag: TextTag; start: TextIndex; stop: TextIndex]
function () tag_add_char [widget(text); "tag"; "add"; tag: TextTag; index: TextIndex]
external tag_bind "builtin/text_tag_bind"
function () tag_configure [widget(text); "tag"; "configure"; tag: TextTag; option(texttag) list]
function () tag_delete [widget(text); "tag"; "delete"; TextTag list]
+
function () tag_lower [widget(text); "tag"; "lower"; tag: TextTag; ?below: [TextTag]]
-# function () tag_lower_below [widget(text); "tag"; "lower"; tag: TextTag; below: TextTag]
-# function () tag_lower_bot [widget(text); "tag"; "lower"; tag: TextTag]
+##ifdef CAMLTK
+ function () tag_lower_below [widget(text); "tag"; "lower"; TextTag; TextTag]
+ function () tag_lower_bot [widget(text); "tag"; "lower"; TextTag]
+##endif
+
function (TextTag list) tag_names [widget(text); "tag"; "names"; ?index: [TextIndex]]
-# function (TextTag list) tag_allnames [widget(text); "tag"; "names"]
-# function (TextTag list) tag_indexnames [widget(text); "tag"; "names"; index: TextIndex]
+##ifdef CAMLTK
+ function (TextTag list) tag_allnames [widget(text); "tag"; "names"]
+ function (TextTag list) tag_indexnames [widget(text); "tag"; "names"; TextIndex]
+##endif
+
+##ifdef CAMLTK
+ function (Index, Index) tag_nextrange [widget(text); "tag"; "nextrange"; TextTag; start: TextIndex; stop: TextIndex]
+ function (Index, Index) tag_prevrange [widget(text); "tag"; "prevrange"; TextTag; start: TextIndex; stop: TextIndex]
+##else
function (Index(text) as "[>`Linechar of int * int]", Index(text) as "[>`Linechar of int * int]") tag_nextrange [widget(text); "tag"; "nextrange"; tag: TextTag; start: TextIndex; ?stop: [TextIndex]]
+ function (Index(text) as "[>`Linechar of int * int]", Index(text) as "[>`Linechar of int * int]") tag_prevrange [widget(text); "tag"; "prevrange"; tag: TextTag; start: TextIndex; ?stop: [TextIndex]]
+##endif
+
function () tag_raise [widget(text); "tag"; "raise"; tag: TextTag; ?above: [TextTag]]
-# function () tag_raise_above [widget(text); "tag"; "raise"; tag: TextTag; above: TextTag]
-# function () tag_raise_top [widget(text); "tag"; "raise"; tag: TextTag ]
+##ifdef CAMLTK
+ function () tag_raise_above [widget(text); "tag"; "raise"; TextTag; TextTag]
+ function () tag_raise_top [widget(text); "tag"; "raise"; TextTag]
+##endif
+
+##ifdef CAMLTK
+ function (Index list) tag_ranges [widget(text); "tag"; "ranges"; TextTag]
+##else
function (Index(text) as "[>`Linechar of int * int]" list) tag_ranges [widget(text); "tag"; "ranges"; tag: TextTag]
+##endif
+
function () tag_remove [widget(text); "tag"; "remove"; tag: TextTag; start: TextIndex; stop: TextIndex]
function () tag_remove_char [widget(text); "tag"; "remove"; tag: TextTag; index: TextIndex]
+
function () window_configure [widget(text); "window"; "configure"; tag: TextTag; option(embeddedw) list]
function () window_create [widget(text); "window"; "create"; index: TextIndex; option(embeddedw) list]
function (widget list) window_names [widget(text); "window"; "names"]
- # scrolling
+ % scrolling
function (float,float) xview_get [widget(text); "xview"]
function (float,float) yview_get [widget(text); "yview"]
function () xview [widget(text); "xview"; scroll: ScrollValue]
function () yview [widget(text); "yview"; scroll: ScrollValue]
function () yview_index [widget(text); "yview"; index: TextIndex]
function () yview_index_pickplace [widget(text); "yview"; "-pickplace"; index: TextIndex]
- function () yview_line [widget(text); "yview"; line: int] # obsolete
+ function () yview_line [widget(text); "yview"; line: int] % obsolete
}
subtype option(texttag) {
@@ -1588,12 +1922,12 @@ subtype option(texttag) {
Font
Foreground
Justify
- LMargin1 ["-lmargin1"; int]
- LMargin2 ["-lmargin2"; int]
- Offset ["-offset"; int]
+ LMargin1 ["-lmargin1"; Units/int]
+ LMargin2 ["-lmargin2"; Units/int]
+ Offset ["-offset"; Units/int]
OverStrike ["-overstrike"; bool]
Relief
- RMargin ["-rmargin"; int]
+ RMargin ["-rmargin"; Units/int]
Spacing1
Spacing2
Spacing3
@@ -1603,11 +1937,22 @@ subtype option(texttag) {
}
-##### tk(n)
-function () appname_set ["tk"; "appname"; string]
-function (string) appname_get ["tk"; "appname"]
+%%%%% tk(n)
+unsafe function () appname_set ["tk"; "appname"; string]
+unsafe function (string) appname_get ["tk"; "appname"]
+function (float) scaling_get ["tk"; "scaling"; ?displayof:["-displayof"; widget]]
+unsafe function () scaling_set ["tk"; "scaling"; ?displayof:["-displayof"; widget]; float]
-##### tkwait(n)
+%%%%% tk_chooseColor(n)
+
+subtype option(chooseColor){
+ InitialColor ["-initialcolor"; Color]
+ Parent ["-parent"; widget]
+ Title ["-title"; string]
+ }
+function (Color) chooseColor ["tk_chooseColor"; option(chooseColor) list]
+
+%%%%% tkwait(n)
module Tkwait {
function () variable ["tkwait"; "variable"; TextVariable]
function () visibility ["tkwait"; "visibility"; widget]
@@ -1615,11 +1960,11 @@ module Tkwait {
}
-##### toplevel(n)
-# This module will be renamed "toplevelw" to avoid collision with
-# Caml Light standard toplevel module.
+%%%%% toplevel(n)
+% This module will be renamed "toplevelw" to avoid collision with
+% Caml Light standard toplevel module.
widget toplevel {
- # Standard options
+ % Standard options
option BorderWidth
option Cursor
option HighlightBackground
@@ -1628,12 +1973,19 @@ widget toplevel {
option Relief
option TakeFocus
- # Widget specific options
+ % Widget specific options
option Background
+##ifdef CAMLTK
+ option Class
+##else
option Clas
+##endif
option Colormap
+ option Container ["-container"; bool]
option Height
+ option Menu
option Screen ["-screen"; string]
+ option Use ["-use"; string] % must be hexadecimal "0x????"
option Visual
option Width
@@ -1642,47 +1994,53 @@ widget toplevel {
}
-##### update(n)
+%%%%% update(n)
function () update ["update"]
function () update_idletasks ["update"; "idletasks"]
-##### winfo(n)
+%%%%% winfo(n)
type AtomId {
AtomId [int]
}
module Winfo {
+
unsafe function (AtomId) atom ["winfo"; "atom"; ?displayof:["-displayof"; widget]; string]
unsafe function (string) atomname ["winfo"; "atomname"; ?displayof:["-displayof"; widget]; AtomId]
-# unsafe function (string) atomname ["winfo"; "atomname"; AtomId]
-# unsafe function (string) atomname_displayof ["winfo"; "atomname"; "-displayof"; displayof: widget; AtomId]
+##ifdef CAMLTK
+ unsafe function (AtomId) atom_displayof ["winfo"; "atom"; "-displayof"; widget; string]
+ unsafe function (string) atomname_displayof ["winfo"; "atomname"; "-displayof"; widget; AtomId]
+##endif
function (int) cells ["winfo"; "cells"; widget]
function (widget list) children ["winfo"; "children"; widget]
function (string) class_name ["winfo"; "class"; widget]
function (bool) colormapfull ["winfo"; "colormapfull"; widget]
unsafe function (widget) containing ["winfo"; "containing"; ?displayof:["-displayof"; widget]; x: int; y: int]
-# unsafe function (widget) containing ["winfo"; "containing"; x: int; y: int]
- # addition for applets
+##ifdef CAMLTK
+ unsafe function (widget) containing_displayof ["winfo"; "containing"; "-displayof"; widget; int; int]
+##endif
+ % addition for applets
external contained "builtin/winfo_contained"
-# unsafe function (widget) containing_displayof ["winfo"; "containing"; "-displayof"; displayof: widget; x: int; y: int]
function (int) depth ["winfo"; "depth"; widget]
function (bool) exists ["winfo"; "exists"; widget]
function (float) fpixels ["winfo"; "fpixels"; widget; length: Units]
function (string) geometry ["winfo"; "geometry"; widget]
function (int) height ["winfo"; "height"; widget]
unsafe function (string) id ["winfo"; "id"; widget]
- unsafe function (string list) interps_displayof ["winfo"; "interps"; ?displayof:["-displayof"; widget]]
-# unsafe function (string list) interps ["winfo"; "interps"]
-# unsafe function (string list) interps_displayof ["winfo"; "interps"; "-displayof"; displayof:widget]
+ unsafe function (string list) interps ["winfo"; "interps"; ?displayof:["-displayof"; widget]]
+##ifdef CAMLTK
+ unsafe function (string list) interps_displayof ["winfo"; "interps"; "-displayof"; widget]
+##endif
function (bool) ismapped ["winfo"; "ismapped"; widget]
function (string) manager ["winfo"; "manager"; widget]
function (string) name ["winfo"; "name"; widget]
- unsafe function (widget) parent ["winfo"; "parent"; widget] # bogus for top
+ unsafe function (widget) parent ["winfo"; "parent"; widget] % bogus for top
unsafe function (widget) pathname ["winfo"; "pathname"; ?displayof:["-displayof"; widget]; string]
-# unsafe function (widget) pathname ["winfo"; "pathname"; string]
-# unsafe function (widget) pathname_displayof ["winfo"; "pathname"; "-displayof"; displayof: widget; string]
+##ifdef CAMLTK
+ unsafe function (widget) pathname_displayof ["winfo"; "pathname"; "-displayof"; widget; string]
+##endif
function (int) pixels ["winfo"; "pixels"; widget; length: Units]
function (int) pointerx ["winfo"; "pointerx"; widget]
function (int) pointery ["winfo"; "pointery"; widget]
@@ -1692,20 +2050,21 @@ module Winfo {
function (int,int,int) rgb ["winfo"; "rgb"; widget; color: Color]
function (int) rootx ["winfo"; "rootx"; widget]
function (int) rooty ["winfo"; "rooty"; widget]
- function (string) screen ["winfo"; "screen"; widget]
+ unsafe function (string) screen ["winfo"; "screen"; widget]
function (int) screencells ["winfo"; "screencells"; widget]
function (int) screendepth ["winfo"; "screendepth"; widget]
function (int) screenheight ["winfo"; "screenheight"; widget]
- function (int) screenmmdepth ["winfo"; "screenmmdepth"; widget]
function (int) screenmmheight ["winfo"; "screenmmheight"; widget]
+ function (int) screenmmwidth ["winfo"; "screenmmwidth"; widget]
function (string) screenvisual ["winfo"; "screenvisual"; widget]
function (int) screenwidth ["winfo"; "screenwidth"; widget]
unsafe function (string) server ["winfo"; "server"; widget]
unsafe function (widget(toplevel)) toplevel ["winfo"; "toplevel"; widget]
function (bool) viewable ["winfo"; "viewable"; widget]
function (string) visual ["winfo"; "visual"; widget]
- # not so
- function (string) visualsavailable ["winfo"; "visualsavailable"; widget]
+ function (int) visualid ["winfo"; "visualid"; widget]
+ % need special parser
+ function (string) visualsavailable ["winfo"; "visualsavailable"; widget; ?includeids: [int list]]
function (int) vrootheight ["winfo"; "vrootheight"; widget]
function (int) vrootwidth ["winfo"; "vrootwidth"; widget]
function (int) vrootx ["winfo"; "vrootx"; widget]
@@ -1716,7 +2075,7 @@ module Winfo {
}
-##### wm(n)
+%%%%% wm(n)
type FocusModel {
FocusActive ["active"]
@@ -1724,107 +2083,174 @@ type FocusModel {
}
type WmFrom {
- FromUser ["user"]
- FromProgram ["program"]
+ User ["user"]
+ Program ["program"]
}
module Wm {
-### Aspect
- function () aspect_set ["wm"; "aspect"; widget; minnum:int; mindenom:int; maxnum:int; maxdenom:int]
- # aspect: problem with empty return
- function (int,int,int,int) aspect_get ["wm"; "aspect"; widget]
-### WM_CLIENT_MACHINE
- function () client_set ["wm"; "client"; widget; name: string]
- function (string) client_get ["wm"; "client"; widget]
-### WM_COLORMAP_WINDOWS
+%%% Aspect
+ function () aspect_set ["wm"; "aspect"; widget(toplevel); minnum:int; mindenom:int; maxnum:int; maxdenom:int]
+ % aspect: problem with empty return
+ function (int,int,int,int) aspect_get ["wm"; "aspect"; widget(toplevel)]
+%%% WM_CLIENT_MACHINE
+ function () client_set ["wm"; "client"; widget(toplevel); name: string]
+ function (string) client_get ["wm"; "client"; widget(toplevel)]
+%%% WM_COLORMAP_WINDOWS
function () colormapwindows_set
- ["wm"; "colormapwindows"; widget; [windows: widget list]]
+ ["wm"; "colormapwindows"; widget(toplevel); [windows: widget list]]
unsafe function (widget list) colormapwindows_get
- ["wm"; "colormapwindows"; widget]
-### WM_COMMAND
- function () command_clear ["wm"; "command"; widget; ""]
- function () command_set ["wm"; "command"; widget; [string list]]
- function (string list) command_get ["wm"; "command"; widget]
-
- function () deiconify ["wm"; "deiconify"; widget]
-
-### Focus model
- function () focusmodel_set ["wm"; "focusmodel"; widget; FocusModel]
- function (FocusModel) focusmodel_get ["wm"; "focusmodel"; widget]
-
- function (string) frame ["wm"; "frame"; widget]
-
-### Geometry
- function () geometry_set ["wm"; "geometry"; widget; string]
- function (string) geometry_get ["wm"; "geometry"; widget]
-
-### Grid
- function () grid_clear ["wm"; "grid"; widget; ""; ""; ""; ""]
- function () grid_set ["wm"; "grid"; widget; basewidth: int; baseheight: int; widthinc: int; heightinc: int]
- function (int,int,int,int) grid_get ["wm"; "grid"; widget]
-
-### Groups
- function () group_clear ["wm"; "group"; widget; ""]
- function () group_set ["wm"; "group"; widget; leader: widget]
- unsafe function (widget) group_get ["wm"; "group"; widget]
-### Icon bitmap
- function () iconbitmap_clear ["wm"; "iconbitmap"; widget; ""]
- function () iconbitmap_set ["wm"; "iconbitmap"; widget; Bitmap]
- function (Bitmap) iconbitmap_get ["wm"; "iconbitmap"; widget]
-
- function () iconify ["wm"; "iconify"; widget]
-
-### Icon mask
- function () iconmask_clear ["wm"; "iconmask"; widget; ""]
- function () iconmask_set ["wm"; "iconmask"; widget; Bitmap]
- function (Bitmap) iconmask_get ["wm"; "iconmask"; widget]
-
-### Icon name
- function () iconname_set ["wm"; "iconname"; widget; string]
- function (string) iconname_get ["wm"; "iconname"; widget]
-### Icon position
- function () iconposition_clear ["wm"; "iconposition"; widget; ""; ""]
- function () iconposition_set ["wm"; "iconposition"; widget; x: int; y: int]
- function (int,int) iconposition_get ["wm"; "iconposition"; widget]
-### Icon window
- function () iconwindow_clear ["wm"; "iconwindow"; widget; ""]
- function () iconwindow_set ["wm"; "iconwindow"; widget; icon: widget]
- unsafe function (widget) iconwindow_get ["wm"; "iconwindow"; widget]
-
-### Sizes
- function () maxsize_set ["wm"; "maxsize"; widget; width: int; height: int]
- function (int,int) maxsize_get ["wm"; "maxsize"; widget]
- function () minsize_set ["wm"; "minsize"; widget; width: int; height: int]
- function (int,int) minsize_get ["wm"; "minsize"; widget]
-### Override
- function () overrideredirect_set ["wm"; "overrideredirect"; widget; bool]
- function (bool) overrideredirect_get ["wm"; "overrideredirect"; widget]
-### Position
- function () positionfrom_clear ["wm"; "positionfrom"; widget; ""]
- function () positionfrom_set ["wm"; "positionfrom"; widget; WmFrom]
- function (WmFrom) positionfrom_get ["wm"; "positionfrom"; widget]
-### Protocols
- function () protocol_set ["wm"; "protocol"; widget; name: string; command: function()]
- function () protocol_clear ["wm"; "protocol"; widget; name: string; ""]
- function (string list) protocols ["wm"; "protocol"; widget]
-### Resize
+ ["wm"; "colormapwindows"; widget(toplevel)]
+%%% WM_COMMAND
+ function () command_clear ["wm"; "command"; widget(toplevel); ""]
+ function () command_set ["wm"; "command"; widget(toplevel); [string list]]
+ function (string list) command_get ["wm"; "command"; widget(toplevel)]
+
+ function () deiconify ["wm"; "deiconify"; widget(toplevel)]
+
+%%% Focus model
+ function () focusmodel_set ["wm"; "focusmodel"; widget(toplevel); FocusModel]
+ function (FocusModel) focusmodel_get ["wm"; "focusmodel"; widget(toplevel)]
+
+ function (string) frame ["wm"; "frame"; widget(toplevel)]
+
+%%% Geometry
+ function () geometry_set ["wm"; "geometry"; widget(toplevel); string]
+ function (string) geometry_get ["wm"; "geometry"; widget(toplevel)]
+
+%%% Grid
+ function () grid_clear ["wm"; "grid"; widget(toplevel); ""; ""; ""; ""]
+ function () grid_set ["wm"; "grid"; widget(toplevel); basewidth: int; baseheight: int; widthinc: int; heightinc: int]
+ function (int,int,int,int) grid_get ["wm"; "grid"; widget(toplevel)]
+
+%%% Groups
+ function () group_clear ["wm"; "group"; widget(toplevel); ""]
+ function () group_set ["wm"; "group"; widget(toplevel); leader: widget]
+ unsafe function (widget) group_get ["wm"; "group"; widget(toplevel)]
+%%% Icon bitmap
+ function () iconbitmap_clear ["wm"; "iconbitmap"; widget(toplevel); ""]
+ function () iconbitmap_set ["wm"; "iconbitmap"; widget(toplevel); Bitmap]
+ function (Bitmap) iconbitmap_get ["wm"; "iconbitmap"; widget(toplevel)]
+
+ function () iconify ["wm"; "iconify"; widget(toplevel)]
+
+%%% Icon mask
+ function () iconmask_clear ["wm"; "iconmask"; widget(toplevel); ""]
+ function () iconmask_set ["wm"; "iconmask"; widget(toplevel); Bitmap]
+ function (Bitmap) iconmask_get ["wm"; "iconmask"; widget(toplevel)]
+
+%%% Icon name
+ function () iconname_set ["wm"; "iconname"; widget(toplevel); string]
+ function (string) iconname_get ["wm"; "iconname"; widget(toplevel)]
+%%% Icon position
+ function () iconposition_clear ["wm"; "iconposition"; widget(toplevel); ""; ""]
+ function () iconposition_set ["wm"; "iconposition"; widget(toplevel); x: int; y: int]
+ function (int,int) iconposition_get ["wm"; "iconposition"; widget(toplevel)]
+%%% Icon window
+ function () iconwindow_clear ["wm"; "iconwindow"; widget(toplevel); ""]
+ function () iconwindow_set ["wm"; "iconwindow"; widget(toplevel); icon: widget(toplevel)]
+ unsafe function (widget(toplevel)) iconwindow_get ["wm"; "iconwindow"; widget(toplevel)]
+
+%%% Sizes
+ function () maxsize_set ["wm"; "maxsize"; widget(toplevel); width: int; height: int]
+ function (int,int) maxsize_get ["wm"; "maxsize"; widget(toplevel)]
+ function () minsize_set ["wm"; "minsize"; widget(toplevel); width: int; height: int]
+ function (int,int) minsize_get ["wm"; "minsize"; widget(toplevel)]
+%%% Override
+ unsafe function () overrideredirect_set ["wm"; "overrideredirect"; widget(toplevel); bool]
+ function (bool) overrideredirect_get ["wm"; "overrideredirect"; widget(toplevel)]
+%%% Position
+ function () positionfrom_clear ["wm"; "positionfrom"; widget(toplevel); ""]
+ function () positionfrom_set ["wm"; "positionfrom"; widget(toplevel); WmFrom]
+ function (WmFrom) positionfrom_get ["wm"; "positionfrom"; widget(toplevel)]
+%%% Protocols
+ function () protocol_set ["wm"; "protocol"; widget(toplevel); name: string; command: function()]
+ function () protocol_clear ["wm"; "protocol"; widget(toplevel); name: string; ""]
+ function (string list) protocols ["wm"; "protocol"; widget(toplevel)]
+%%% Resize
function () resizable_set ["wm"; "resizable"; widget(toplevel); width: bool; height: bool]
function (bool, bool) resizable_get ["wm"; "resizable"; widget(toplevel)]
-### Sizefrom
- function () sizefrom_clear ["wm"; "sizefrom"; widget; ""]
- function () sizefrom_set ["wm"; "sizefrom"; widget; WmFrom]
- function (WmFrom) sizefrom_get ["wm"; "sizefrom"; widget]
+%%% Sizefrom
+ function () sizefrom_clear ["wm"; "sizefrom"; widget(toplevel); ""]
+ function () sizefrom_set ["wm"; "sizefrom"; widget(toplevel); WmFrom]
+ function (WmFrom) sizefrom_get ["wm"; "sizefrom"; widget(toplevel)]
+
+ function (string) state ["wm"; "state"; widget(toplevel)]
+
+%%% Title
+ function (string) title_get ["wm"; "title"; widget(toplevel)]
+ function () title_set ["wm"; "title"; widget(toplevel); string]
+%%% Transient
+ function () transient_clear ["wm"; "transient"; widget(toplevel); ""]
+ function () transient_set ["wm"; "transient"; widget(toplevel); master: widget]
+ unsafe function (widget) transient_get ["wm"; "transient"; widget(toplevel)]
- function (string) state ["wm"; "state"; widget]
+ function () withdraw ["wm"; "withdraw"; widget(toplevel)]
-### Title
- function (string) title_get ["wm"; "title"; widget]
- function () title_set ["wm"; "title"; widget; string]
-### Transient
- function () transient_clear ["wm"; "transient"; widget; ""]
- function () transient_set ["wm"; "transient"; widget; master: widget(toplevel)]
- unsafe function (widget(toplevel)) transient_get ["wm"; "transient"; widget]
+}
+
+%%%%% tk_getOpenFile(n) (since version 8.0)
+type FilePattern external
+
+subtype option(getFile) {
+ DefaultExtension ["-defaultextension"; string]
+ FileTypes ["-filetypes"; [FilePattern list]]
+ InitialDir ["-initialdir"; string]
+ InitialFile ["-initialfile"; string]
+ Parent ["-parent"; widget]
+ Title ["-title"; string]
+}
+
+function (string) getOpenFile ["tk_getOpenFile"; option(getFile) list]
+function (string) getSaveFile ["tk_getSaveFile"; option(getFile) list]
- function () withdraw ["wm"; "withdraw"; widget]
+%%%%% tk_messageBox
+type MessageIcon {
+ Error ["error"]
+ Info ["info"]
+ Question ["question"]
+ Warning ["warning"]
+}
+type MessageType {
+ AbortRetryIgnore ["abortretryignore"]
+ Ok ["ok"]
+ OkCancel ["okcancel"]
+ RetryCancel ["retrycancel"]
+ YesNo ["yesno"]
+ YesNoCancel ["yesnocancel"]
+}
+subtype option(messageBox) {
+ MessageDefault ["-default"; string]
+ MessageIcon ["-icon"; MessageIcon]
+ Message ["-message"; string]
+ Parent
+ Title
+ MessageType ["-type"; MessageType]
+}
+function (string) messageBox ["tk_messageBox"; option(messageBox) list]
+
+module Tkvars {
+ function (string) library ["$tk_library"]
+ function (string) patchLevel ["$tk_patchLevel"]
+ function (bool) strictMotif ["$tk_strictMotif"]
+ function () set_strictMotif ["set"; "tk_strictMotif"; bool]
+ function (string) version ["$tk_version"]
}
+
+% Direct API calls, non Tcl-based modules
+
+module Pixmap {
+ external create "builtin/rawimg"
+ }
+
+%%% encodings : require if you want write your application international
+
+module Encoding {
+ function (string) convertfrom ["encoding"; "convertfrom";
+ ?encoding: [string]; string]
+ function (string) convertto ["encoding"; "convertto";
+ ?encoding: [string]; string]
+ function (string list) names ["encoding"; "names"]
+ function () system_set ["encoding"; "system"; string]
+ function (string) system_get ["encoding"; "system"]
+}
diff --git a/otherlibs/labltk/browser/Makefile b/otherlibs/labltk/browser/Makefile
index 547d10e88..97aafd41c 100644
--- a/otherlibs/labltk/browser/Makefile
+++ b/otherlibs/labltk/browser/Makefile
@@ -1,6 +1,6 @@
include ../support/Makefile.common
-LABLTKLIB=-I ../lib -I ../support
+LABLTKLIB=-I ../labltk -I ../lib -I ../support
OTHERSLIB=-I $(OTHERS)/unix -I $(OTHERS)/str
OCAMLTOPLIB=-I $(TOPDIR)/parsing -I $(TOPDIR)/utils -I $(TOPDIR)/typing
INCLUDES=$(OTHERSLIB) $(LABLTKLIB) $(OCAMLTOPLIB)
@@ -20,22 +20,22 @@ JG = jg_tk.cmo jg_config.cmo jg_bind.cmo jg_completion.cmo \
.SUFFIXES: .ml .mli .cmo .cmi .cmx
.ml.cmo:
- $(LABLCOMP) $(INCLUDES) $<
+ $(CAMLCOMP) $(INCLUDES) $<
.mli.cmi:
- $(LABLCOMP) $(INCLUDES) $<
+ $(CAMLCOMP) $(INCLUDES) $<
all: ocamlbrowser$(EXE)
ocamlbrowser$(EXE): $(TOPDIR)/toplevel/toplevellib.cma jglib.cma $(OBJ) \
- ../support/liblabltk41.a
- $(LABLC) -o ocamlbrowser$(EXE) $(INCLUDES) \
+ ../support/lib$(LIBNAME).a
+ $(CAMLC) -o ocamlbrowser$(EXE) $(INCLUDES) \
$(DLLPATH) \
$(TOPDIR)/toplevel/toplevellib.cma \
- unix.cma str.cma labltk.cma jglib.cma $(OBJ)
+ unix.cma str.cma $(LIBNAME).cma jglib.cma $(OBJ)
jglib.cma: $(JG)
- $(LABLCOMP) -a -o jglib.cma $(JG)
+ $(CAMLCOMP) -a -o jglib.cma $(JG)
#help.ml: help.txt
# printf 'let text = "' > $@
@@ -50,7 +50,7 @@ clean:
rm -f *.cm? ocamlbrowser$(EXE) dummy.mli *~ *.orig
depend:
- $(LABLDEP) *.ml *.mli > .depend
+ $(CAMLDEP) *.ml *.mli > .depend
dummy.mli:
rm -f $@
diff --git a/otherlibs/labltk/browser/Makefile.nt b/otherlibs/labltk/browser/Makefile.nt
index caa8f1176..43b3828b2 100644
--- a/otherlibs/labltk/browser/Makefile.nt
+++ b/otherlibs/labltk/browser/Makefile.nt
@@ -1,6 +1,6 @@
!include ..\support\Makefile.common.nt
-LABLTKLIB=-I ../lib -I ../support
+LABLTKLIB=-I ../labltk -I ../lib -I ../support
OTHERSLIB=-I $(OTHERS)/win32unix -I $(OTHERS)/str -I $(OTHERS)/systhreads
OCAMLTOPLIB=-I $(TOPDIR)/parsing -I $(TOPDIR)/utils -I $(TOPDIR)/typing
INCLUDES=$(OTHERSLIB) $(LABLTKLIB) $(OCAMLTOPLIB)
@@ -21,35 +21,35 @@ JG = jg_tk.cmo jg_config.cmo jg_bind.cmo jg_completion.cmo \
.SUFFIXES: .ml .mli .cmo .cmi .cmx
.ml.cmo:
- $(LABLCOMP) $(INCLUDES) $<
+ $(CAMLCOMP) $(INCLUDES) $<
.mli.cmi:
- $(LABLCOMP) $(INCLUDES) $<
+ $(CAMLCOMP) $(INCLUDES) $<
-.c.obj:
+y.c.obj:
$(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $<
all: ocamlbrowser.exe
ocamlbrowser.exe: $(TOPDIR)/toplevel/toplevellib.cma \
- ..\support\liblabltk41.lib
+ ..\support\lib$(LIBNAME).lib
ocamlbrowser.exe: jglib.cma $(OBJ) winmain.obj
- $(LABLC) -o ocamlbrowser.exe -custom $(INCLUDES) \
+ $(CAMLC) -o ocamlbrowser.exe -custom $(INCLUDES) \
$(TOPDIR)/toplevel/toplevellib.cma \
- unix.cma threads.cma str.cma labltk.cma jglib.cma $(OBJ) \
+ unix.cma threads.cma str.cma $(LIBNAME).cma jglib.cma $(OBJ) \
winmain.obj -cclib "/subsystem:windows"
jglib.cma: $(JG)
- $(LABLCOMP) -a -o jglib.cma $(JG)
+ $(CAMLCOMP) -a -o jglib.cma $(JG)
install:
if exist ocamlbrowser.exe cp ocamlbrowser.exe $(BINDIR)
clean:
- rm -f *.cm? ocamlbrowser dummy.mli *~ *.orig
+ rm -f *.cm? ocamlbrowser.exe dummy.mli *~ *.orig *.obj *.pdb
depend:
- $(LABLDEP) *.ml *.mli > .depend
+ $(CAMLDEP) *.ml *.mli > .depend
dummy.mli:
cp dummyWin.mli dummy.mli
diff --git a/otherlibs/labltk/browser/searchpos.ml b/otherlibs/labltk/browser/searchpos.ml
index 4302ad002..5e45718fe 100644
--- a/otherlibs/labltk/browser/searchpos.ml
+++ b/otherlibs/labltk/browser/searchpos.ml
@@ -255,7 +255,7 @@ let filter_modules () =
Hashtbl.remove shown_modules key)
shown_modules
let add_shown_module path ~widgets =
- Hashtbl'.add shown_modules ~key:path ~data:widgets
+ Hashtbl.add shown_modules path widgets
let find_shown_module path =
try
filter_modules ();
diff --git a/otherlibs/labltk/builtin/builtin_FilePattern.ml b/otherlibs/labltk/builtin/builtin_FilePattern.ml
new file mode 100644
index 000000000..f7dd1d60e
--- /dev/null
+++ b/otherlibs/labltk/builtin/builtin_FilePattern.ml
@@ -0,0 +1,20 @@
+(* File patterns *)
+(* type *)
+type filePattern = {
+ typename : string;
+ extensions : string list;
+ mactypes : string list
+ }
+(* /type *)
+
+let cCAMLtoTKfilePattern fp =
+ let typename = TkQuote (TkToken fp.typename) in
+ let extensions =
+ TkQuote (TkTokenList (List.map (fun x -> TkToken x) fp.extensions)) in
+ let mactypes =
+ match fp.mactypes with
+ | [] -> []
+ | [s] -> [TkToken s]
+ | _ -> [TkQuote (TkTokenList (List.map (fun x -> TkToken x) fp.mactypes))]
+ in
+ TkQuote (TkTokenList (typename :: extensions :: mactypes))
diff --git a/otherlibs/labltk/builtin/builtin_GetBitmap.ml b/otherlibs/labltk/builtin/builtin_GetBitmap.ml
index 060d77d32..bf02d20f8 100644
--- a/otherlibs/labltk/builtin/builtin_GetBitmap.ml
+++ b/otherlibs/labltk/builtin/builtin_GetBitmap.ml
@@ -1,8 +1,22 @@
(* Tk_GetBitmap emulation *)
+
+##ifdef CAMLTK
+
+(* type *)
+type bitmap =
+ | BitmapFile of string (* path of file *)
+ | Predefined of string (* bitmap name *)
+;;
+(* /type *)
+
+##else
+
(* type *)
type bitmap = [
| `File of string (* path of file *)
| `Predefined of string (* bitmap name *)
]
+;;
(* /type *)
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_GetCursor.ml b/otherlibs/labltk/builtin/builtin_GetCursor.ml
index 543fbc19c..4e7d61872 100644
--- a/otherlibs/labltk/builtin/builtin_GetCursor.ml
+++ b/otherlibs/labltk/builtin/builtin_GetCursor.ml
@@ -1,4 +1,21 @@
(* Color *)
+
+##ifdef CAMLTK
+
+(* type *)
+type color =
+ | NamedColor of string
+ | Black (* tk keyword: black *)
+ | White (* tk keyword: white *)
+ | Red (* tk keyword: red *)
+ | Green (* tk keyword: green *)
+ | Blue (* tk keyword: blue *)
+ | Yellow (* tk keyword: yellow *)
+;;
+(* /type *)
+
+##else
+
(* type *)
type color = [
| `Color of string
@@ -9,8 +26,25 @@ type color = [
| `Blue (* tk keyword: blue *)
| `Yellow (* tk keyword: yellow *)
]
+;;
(* /type *)
+##endif
+
+##ifdef CAMLTK
+
+(* type *)
+type cursor =
+ | XCursor of string
+ | XCursorFg of string * color
+ | XCursortFgBg of string * color * color
+ | CursorFileFg of string * color
+ | CursorMaskFile of string * string * color * color
+;;
+(* /type *)
+
+##else
+
(* Tk_GetCursor emulation *)
(* type *)
type cursor = [
@@ -20,5 +54,8 @@ type cursor = [
| `Cursorfilefg of string * color
| `Cursormaskfile of string * string * color * color
]
+;;
(* /type *)
+##endif
+
diff --git a/otherlibs/labltk/builtin/builtin_GetPixel.ml b/otherlibs/labltk/builtin/builtin_GetPixel.ml
index 017893470..772a2c284 100644
--- a/otherlibs/labltk/builtin/builtin_GetPixel.ml
+++ b/otherlibs/labltk/builtin/builtin_GetPixel.ml
@@ -1,4 +1,19 @@
(* Tk_GetPixels emulation *)
+
+##ifdef CAMLTK
+
+(* type *)
+type units =
+ | Pixels of int (* specified as floating-point, but inconvenient *)
+ | Centimeters of float
+ | Inches of float
+ | Millimeters of float
+ | PrinterPoint of float
+;;
+(* /type *)
+
+##else
+
(* type *)
type units = [
| `Pix of int
@@ -7,5 +22,7 @@ type units = [
| `Mm of float
| `Pt of float
]
+;;
(* /type *)
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_ScrollValue.ml b/otherlibs/labltk/builtin/builtin_ScrollValue.ml
index 250fd2eda..20869c6da 100644
--- a/otherlibs/labltk/builtin/builtin_ScrollValue.ml
+++ b/otherlibs/labltk/builtin/builtin_ScrollValue.ml
@@ -1,8 +1,22 @@
+##ifdef CAMLTK
+
+(* type *)
+type scrollValue =
+ | ScrollPage of int (* tk option: scroll <int> page *)
+ | ScrollUnit of int (* tk option: scroll <int> unit *)
+ | MoveTo of float (* tk option: moveto <float> *)
+;;
+(* /type *)
+
+##else
+
(* type *)
type scrollValue = [
| `Page of int (* tk option: scroll <int> page *)
| `Unit of int (* tk option: scroll <int> unit *)
| `Moveto of float (* tk option: moveto <float> *)
]
+;;
(* /type *)
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_bind.ml b/otherlibs/labltk/builtin/builtin_bind.ml
index e7c738dec..4f6d59598 100644
--- a/otherlibs/labltk/builtin/builtin_bind.ml
+++ b/otherlibs/labltk/builtin/builtin_bind.ml
@@ -1,9 +1,246 @@
-open Widget
+##ifdef CAMLTK
+
+open Widget;;
+
+(* Events and bindings *)
+(* Builtin types *)
+(* type *)
+type xEvent =
+ | Activate
+ | ButtonPress (* also Button, but we omit it *)
+ | ButtonPressDetail of int
+ | ButtonRelease
+ | ButtonReleaseDetail of int
+ | Circulate
+ | ColorMap (* not Colormap, avoiding confusion between the Colormap option *)
+ | Configure
+ | Deactivate
+ | Destroy
+ | Enter
+ | Expose
+ | FocusIn
+ | FocusOut
+ | Gravity
+ | KeyPress (* also Key, but we omit it *)
+ | KeyPressDetail of string (* /usr/include/X11/keysymdef.h *)
+ | KeyRelease
+ | KeyReleaseDetail of string
+ | Leave
+ | Map
+ | Motion
+ | Property
+ | Reparent
+ | Unmap
+ | Visibility
+ | Virtual of string (* Virtual event. Must be without modifiers *)
+;;
+(* /type *)
+
+(* type *)
+type modifier =
+ | Control
+ | Shift
+ | Lock
+ | Button1
+ | Button2
+ | Button3
+ | Button4
+ | Button5
+ | Double
+ | Triple
+ | Mod1
+ | Mod2
+ | Mod3
+ | Mod4
+ | Mod5
+ | Meta
+ | Alt
+;;
+(* /type *)
+
+(* Event structure, passed to bounded functions *)
+
+(* type *)
+type eventInfo =
+ {
+ (* %# : event serial number is unsupported *)
+ mutable ev_Above : int; (* tk: %a *)
+ mutable ev_ButtonNumber : int; (* tk: %b *)
+ mutable ev_Count : int; (* tk: %c *)
+ mutable ev_Detail : string; (* tk: %d *)
+ mutable ev_Focus : bool; (* tk: %f *)
+ mutable ev_Height : int; (* tk: %h *)
+ mutable ev_KeyCode : int; (* tk: %k *)
+ mutable ev_Mode : string; (* tk: %m *)
+ mutable ev_OverrideRedirect : bool; (* tk: %o *)
+ mutable ev_Place : string; (* tk: %p *)
+ mutable ev_State : string; (* tk: %s *)
+ mutable ev_Time : int; (* tk: %t *)
+ mutable ev_Width : int; (* tk: %w *)
+ mutable ev_MouseX : int; (* tk: %x *)
+ mutable ev_MouseY : int; (* tk: %y *)
+ mutable ev_Char : string; (* tk: %A *)
+ mutable ev_BorderWidth : int; (* tk: %B *)
+ mutable ev_SendEvent : bool; (* tk: %E *)
+ mutable ev_KeySymString : string; (* tk: %K *)
+ mutable ev_KeySymInt : int; (* tk: %N *)
+ mutable ev_RootWindow : int; (* tk: %R *)
+ mutable ev_SubWindow : int; (* tk: %S *)
+ mutable ev_Type : int; (* tk: %T *)
+ mutable ev_Widget : widget; (* tk: %W *)
+ mutable ev_RootX : int; (* tk: %X *)
+ mutable ev_RootY : int (* tk: %Y *)
+ }
+;;
+(* /type *)
+
+
+(* To avoid collision with other constructors (Width, State),
+ use Ev_ prefix *)
+(* type *)
+type eventField =
+ | Ev_Above
+ | Ev_ButtonNumber
+ | Ev_Count
+ | Ev_Detail
+ | Ev_Focus
+ | Ev_Height
+ | Ev_KeyCode
+ | Ev_Mode
+ | Ev_OverrideRedirect
+ | Ev_Place
+ | Ev_State
+ | Ev_Time
+ | Ev_Width
+ | Ev_MouseX
+ | Ev_MouseY
+ | Ev_Char
+ | Ev_BorderWidth
+ | Ev_SendEvent
+ | Ev_KeySymString
+ | Ev_KeySymInt
+ | Ev_RootWindow
+ | Ev_SubWindow
+ | Ev_Type
+ | Ev_Widget
+ | Ev_RootX
+ | Ev_RootY
+;;
+(* /type *)
+
+let filleventInfo ev v = function
+ | Ev_Above -> ev.ev_Above <- int_of_string v
+ | Ev_ButtonNumber -> ev.ev_ButtonNumber <- int_of_string v
+ | Ev_Count -> ev.ev_Count <- int_of_string v
+ | Ev_Detail -> ev.ev_Detail <- v
+ | Ev_Focus -> ev.ev_Focus <- v = "1"
+ | Ev_Height -> ev.ev_Height <- int_of_string v
+ | Ev_KeyCode -> ev.ev_KeyCode <- int_of_string v
+ | Ev_Mode -> ev.ev_Mode <- v
+ | Ev_OverrideRedirect -> ev.ev_OverrideRedirect <- v = "1"
+ | Ev_Place -> ev.ev_Place <- v
+ | Ev_State -> ev.ev_State <- v
+ | Ev_Time -> ev.ev_Time <- int_of_string v
+ | Ev_Width -> ev.ev_Width <- int_of_string v
+ | Ev_MouseX -> ev.ev_MouseX <- int_of_string v
+ | Ev_MouseY -> ev.ev_MouseY <- int_of_string v
+ | Ev_Char -> ev.ev_Char <- v
+ | Ev_BorderWidth -> ev.ev_BorderWidth <- int_of_string v
+ | Ev_SendEvent -> ev.ev_SendEvent <- v = "1"
+ | Ev_KeySymString -> ev.ev_KeySymString <- v
+ | Ev_KeySymInt -> ev.ev_KeySymInt <- int_of_string v
+ | Ev_RootWindow -> ev.ev_RootWindow <- int_of_string v
+ | Ev_SubWindow -> ev.ev_SubWindow <- int_of_string v
+ | Ev_Type -> ev.ev_Type <- int_of_string v
+ | Ev_Widget -> ev.ev_Widget <- cTKtoCAMLwidget v
+ | Ev_RootX -> ev.ev_RootX <- int_of_string v
+ | Ev_RootY -> ev.ev_RootY <- int_of_string v
+;;
+
+let wrapeventInfo f what =
+ let ev = {
+ ev_Above = 0;
+ ev_ButtonNumber = 0;
+ ev_Count = 0;
+ ev_Detail = "";
+ ev_Focus = false;
+ ev_Height = 0;
+ ev_KeyCode = 0;
+ ev_Mode = "";
+ ev_OverrideRedirect = false;
+ ev_Place = "";
+ ev_State = "";
+ ev_Time = 0;
+ ev_Width = 0;
+ ev_MouseX = 0;
+ ev_MouseY = 0;
+ ev_Char = "";
+ ev_BorderWidth = 0;
+ ev_SendEvent = false;
+ ev_KeySymString = "";
+ ev_KeySymInt = 0;
+ ev_RootWindow = 0;
+ ev_SubWindow = 0;
+ ev_Type = 0;
+ ev_Widget = Widget.default_toplevel;
+ ev_RootX = 0;
+ ev_RootY = 0 } in
+ function args ->
+ let l = ref args in
+ List.iter (function field ->
+ match !l with
+ [] -> ()
+ | v::rest -> filleventInfo ev v field; l:=rest)
+ what;
+ f ev
+;;
+
+let rec writeeventField = function
+ | [] -> ""
+ | field::rest ->
+ begin
+ match field with
+ | Ev_Above -> " %a"
+ | Ev_ButtonNumber ->" %b"
+ | Ev_Count -> " %c"
+ | Ev_Detail -> " %d"
+ | Ev_Focus -> " %f"
+ | Ev_Height -> " %h"
+ | Ev_KeyCode -> " %k"
+ | Ev_Mode -> " %m"
+ | Ev_OverrideRedirect -> " %o"
+ | Ev_Place -> " %p"
+ | Ev_State -> " %s"
+ | Ev_Time -> " %t"
+ | Ev_Width -> " %w"
+ | Ev_MouseX -> " %x"
+ | Ev_MouseY -> " %y"
+ (* Quoting is done by Tk *)
+ | Ev_Char -> " %A"
+ | Ev_BorderWidth -> " %B"
+ | Ev_SendEvent -> " %E"
+ | Ev_KeySymString -> " %K"
+ | Ev_KeySymInt -> " %N"
+ | Ev_RootWindow ->" %R"
+ | Ev_SubWindow -> " %S"
+ | Ev_Type -> " %T"
+ | Ev_Widget ->" %W"
+ | Ev_RootX -> " %X"
+ | Ev_RootY -> " %Y"
+ end
+ ^ writeeventField rest
+;;
+
+##else
+
+open Widget;;
(* Events and bindings *)
(* Builtin types *)
+
(* type *)
type event = [
+ | `Activate
| `ButtonPress (* also Button, but we omit it *)
| `ButtonPressDetail of int
| `ButtonRelease
@@ -11,6 +248,7 @@ type event = [
| `Circulate
| `Colormap
| `Configure
+ | `Deactivate
| `Destroy
| `Enter
| `Expose
@@ -28,6 +266,7 @@ type event = [
| `Reparent
| `Unmap
| `Visibility
+ | `Virtual of string (* Virtual event. Must be without modifiers *)
| `Modified of modifier list * event
]
@@ -50,40 +289,42 @@ and modifier = [
| `Meta
| `Alt
]
+;;
(* /type *)
(* Event structure, passed to bounded functions *)
(* type *)
-type eventInfo =
- {
- mutable ev_Above : int; (* tk: %a *)
- mutable ev_ButtonNumber : int; (* tk: %b *)
- mutable ev_Count : int; (* tk: %c *)
- mutable ev_Detail : string; (* tk: %d *)
- mutable ev_Focus : bool; (* tk: %f *)
- mutable ev_Height : int; (* tk: %h *)
- mutable ev_KeyCode : int; (* tk: %k *)
- mutable ev_Mode : string; (* tk: %m *)
- mutable ev_OverrideRedirect : bool; (* tk: %o *)
- mutable ev_Place : string; (* tk: %p *)
- mutable ev_State : string; (* tk: %s *)
- mutable ev_Time : int; (* tk: %t *)
- mutable ev_Width : int; (* tk: %w *)
- mutable ev_MouseX : int; (* tk: %x *)
- mutable ev_MouseY : int; (* tk: %y *)
- mutable ev_Char : string; (* tk: %A *)
- mutable ev_BorderWidth : int; (* tk: %B *)
- mutable ev_SendEvent : bool; (* tk: %E *)
- mutable ev_KeySymString : string; (* tk: %K *)
- mutable ev_KeySymInt : int; (* tk: %N *)
- mutable ev_RootWindow : int; (* tk: %R *)
- mutable ev_SubWindow : int; (* tk: %S *)
- mutable ev_Type : int; (* tk: %T *)
- mutable ev_Widget : any widget; (* tk: %W *)
- mutable ev_RootX : int; (* tk: %X *)
- mutable ev_RootY : int (* tk: %Y *)
+type eventInfo = {
+ (* %# : event serial number is unsupported *)
+ mutable ev_Above : int; (* tk: %a *)
+ mutable ev_ButtonNumber : int; (* tk: %b *)
+ mutable ev_Count : int; (* tk: %c *)
+ mutable ev_Detail : string; (* tk: %d *)
+ mutable ev_Focus : bool; (* tk: %f *)
+ mutable ev_Height : int; (* tk: %h *)
+ mutable ev_KeyCode : int; (* tk: %k *)
+ mutable ev_Mode : string; (* tk: %m *)
+ mutable ev_OverrideRedirect : bool; (* tk: %o *)
+ mutable ev_Place : string; (* tk: %p *)
+ mutable ev_State : string; (* tk: %s *)
+ mutable ev_Time : int; (* tk: %t *)
+ mutable ev_Width : int; (* tk: %w *)
+ mutable ev_MouseX : int; (* tk: %x *)
+ mutable ev_MouseY : int; (* tk: %y *)
+ mutable ev_Char : string; (* tk: %A *)
+ mutable ev_BorderWidth : int; (* tk: %B *)
+ mutable ev_SendEvent : bool; (* tk: %E *)
+ mutable ev_KeySymString : string; (* tk: %K *)
+ mutable ev_KeySymInt : int; (* tk: %N *)
+ mutable ev_RootWindow : int; (* tk: %R *)
+ mutable ev_SubWindow : int; (* tk: %S *)
+ mutable ev_Type : int; (* tk: %T *)
+ mutable ev_Widget : any widget; (* tk: %W *)
+ mutable ev_RootX : int; (* tk: %X *)
+ mutable ev_RootY : int (* tk: %Y *)
}
+;;
(* /type *)
@@ -118,6 +359,7 @@ type eventField = [
| `RootX
| `RootY
]
+;;
(* /type *)
let filleventInfo ev v : eventField -> unit = function
@@ -147,6 +389,7 @@ let filleventInfo ev v : eventField -> unit = function
| `Widget -> ev.ev_Widget <- cTKtoCAMLwidget v
| `RootX -> ev.ev_RootX <- int_of_string v
| `RootY -> ev.ev_RootY <- int_of_string v
+;;
let wrapeventInfo f (what : eventField list) =
let ev = {
@@ -185,8 +428,7 @@ let wrapeventInfo f (what : eventField list) =
| v :: rest -> filleventInfo ev v field; l := rest
end;
f ev
-
-
+;;
let rec writeeventField : eventField list -> string = function
| [] -> ""
@@ -222,3 +464,6 @@ let rec writeeventField : eventField list -> string = function
| `RootY -> " %Y"
end
^ writeeventField rest
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_bindtags.ml b/otherlibs/labltk/builtin/builtin_bindtags.ml
index a775188ee..e94c9668e 100644
--- a/otherlibs/labltk/builtin/builtin_bindtags.ml
+++ b/otherlibs/labltk/builtin/builtin_bindtags.ml
@@ -1,7 +1,21 @@
+##ifdef CAMLTK
+
+(* type *)
+type bindings =
+ | TagBindings of string (* tk option: <string> *)
+ | WidgetBindings of widget (* tk option: <widget> *)
+;;
+(* /type *)
+
+##else
+
(* type *)
type bindings = [
| `Tag of string (* tk option: <string> *)
| `Widget of any widget (* tk option: <widget> *)
]
+;;
(* /type *)
+##endif
+
diff --git a/otherlibs/labltk/builtin/builtin_font.ml b/otherlibs/labltk/builtin/builtin_font.ml
new file mode 100644
index 000000000..615f937e3
--- /dev/null
+++ b/otherlibs/labltk/builtin/builtin_font.ml
@@ -0,0 +1,2 @@
+type font = string
+
diff --git a/otherlibs/labltk/builtin/builtin_index.ml b/otherlibs/labltk/builtin/builtin_index.ml
index 750019b1c..3735fc040 100644
--- a/otherlibs/labltk/builtin/builtin_index.ml
+++ b/otherlibs/labltk/builtin/builtin_index.ml
@@ -4,6 +4,35 @@
listbox
*)
+##ifdef CAMLTK
+
+(* A large type for all indices in all widgets *)
+(* a bit overkill though *)
+
+(* type *)
+type index =
+ | Number of int (* no keyword *)
+ | ActiveElement (* tk keyword: active *)
+ | End (* tk keyword: end *)
+ | Last (* tk keyword: last *)
+ | NoIndex (* tk keyword: none *)
+ | Insert (* tk keyword: insert *)
+ | SelFirst (* tk keyword: sel.first *)
+ | SelLast (* tk keyword: sel.last *)
+ | At of int (* tk keyword: @n *)
+ | AtXY of int * int (* tk keyword: @x,y *)
+ | AnchorPoint (* tk keyword: anchor *)
+ | Pattern of string (* no keyword *)
+ | LineChar of int * int (* tk keyword: l.c *)
+ | Mark of string (* no keyword *)
+ | TagFirst of string (* tk keyword: tag.first *)
+ | TagLast of string (* tk keyword: tag.last *)
+ | Embedded of widget (* no keyword *)
+;;
+(* /type *)
+
+##else
+
type canvas_index = [
| `Num of int
| `End
@@ -12,6 +41,7 @@ type canvas_index = [
| `Sellast
| `Atxy of int * int
]
+;;
type entry_index = [
| `Num of int
@@ -22,6 +52,7 @@ type entry_index = [
| `At of int
| `Anchor
]
+;;
type listbox_index = [
| `Num of int
@@ -30,6 +61,7 @@ type listbox_index = [
| `End
| `Atxy of int * int
]
+;;
type menu_index = [
| `Num of int
@@ -40,6 +72,7 @@ type menu_index = [
| `At of int
| `Pattern of string
]
+;;
type text_index = [
| `Linechar of int * int
@@ -51,6 +84,9 @@ type text_index = [
| `Window of any widget
| `Image of string
]
+;;
+
+type linechar_index = int * int;;
+type num_index = int;;
-type linechar_index = int * int
-type num_index = int
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_palette.ml b/otherlibs/labltk/builtin/builtin_palette.ml
index 5c327f9f5..4eab69a0f 100644
--- a/otherlibs/labltk/builtin/builtin_palette.ml
+++ b/otherlibs/labltk/builtin/builtin_palette.ml
@@ -1,7 +1,20 @@
+##ifdef CAMLTK
+
+(* type *)
+type paletteType =
+ | GrayShades of int
+ | RGBShades of int * int * int
+;;
+(* /type *)
+
+##else
+
(* type *)
type paletteType = [
| `Gray of int
| `Rgb of int * int * int
]
+;;
(* /type *)
+##endif
diff --git a/otherlibs/labltk/builtin/builtin_text.ml b/otherlibs/labltk/builtin/builtin_text.ml
index f81c7f2fb..d4333dcb5 100644
--- a/otherlibs/labltk/builtin/builtin_text.ml
+++ b/otherlibs/labltk/builtin/builtin_text.ml
@@ -1,13 +1,35 @@
(* Not a string as such, more like a symbol *)
(* type *)
-type textMark = string
+type textMark = string;;
(* /type *)
(* type *)
-type textTag = string
+type textTag = string;;
(* /type *)
+##ifdef CAMLTK
+
+(* type *)
+type textModifier =
+ | CharOffset of int (* tk keyword: +/- Xchars *)
+ | LineOffset of int (* tk keyword: +/- Xlines *)
+ | LineStart (* tk keyword: linestart *)
+ | LineEnd (* tk keyword: lineend *)
+ | WordStart (* tk keyword: wordstart *)
+ | WordEnd (* tk keyword: wordend *)
+;;
+(* /type *)
+
+(* type *)
+type textIndex =
+ | TextIndex of index * textModifier list
+ | TextIndexNone
+;;
+(* /type *)
+
+##else
+
(* type *)
type textModifier = [
| `Char of int (* tk keyword: +/- Xchars *)
@@ -17,8 +39,12 @@ type textModifier = [
| `Wordstart (* tk keyword: wordstart *)
| `Wordend (* tk keyword: wordend *)
]
+;;
(* /type *)
(* type *)
type textIndex = text_index * textModifier list
+;;
(* /type *)
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtinf_GetPixel.ml b/otherlibs/labltk/builtin/builtinf_GetPixel.ml
index 50c434011..7e7c596bc 100644
--- a/otherlibs/labltk/builtin/builtinf_GetPixel.ml
+++ b/otherlibs/labltk/builtin/builtinf_GetPixel.ml
@@ -1,3 +1,16 @@
+##ifdef CAMLTK
+
+let pixels units =
+ let res =
+ tkEval
+ [|TkToken"winfo";
+ TkToken"pixels";
+ cCAMLtoTKwidget widget_any_table default_toplevel;
+ cCAMLtoTKunits units|] in
+ int_of_string res
+
+##else
+
let pixels units =
let res =
tkEval
@@ -6,3 +19,5 @@ let pixels units =
cCAMLtoTKwidget default_toplevel;
cCAMLtoTKunits units|] in
int_of_string res
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtinf_bind.ml b/otherlibs/labltk/builtin/builtinf_bind.ml
index 33bd10e84..e6b793d6d 100644
--- a/otherlibs/labltk/builtin/builtinf_bind.ml
+++ b/otherlibs/labltk/builtin/builtinf_bind.ml
@@ -1,3 +1,95 @@
+##ifdef CAMLTK
+
+(* type *)
+type bindAction =
+ | BindSet of eventField list * (eventInfo -> unit)
+ | BindSetBreakable of eventField list * (eventInfo -> unit)
+ | BindRemove
+ | BindExtend of eventField list * (eventInfo -> unit)
+(* /type *)
+
+(*
+FUNCTION
+ val bind:
+ widget -> (modifier list * xEvent) list -> bindAction -> unit
+/FUNCTION
+*)
+let bind widget eventsequence action =
+ tkCommand [| TkToken "bind";
+ TkToken (Widget.name widget);
+ cCAMLtoTKeventSequence eventsequence;
+ begin match action with
+ BindRemove -> TkToken ""
+ | BindSet (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what)
+ in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what))
+ | BindSetBreakable (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what)
+ in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what) ^
+ " ; if { $BreakBindingsSequence == 1 } then { break ;} ; set BreakBindingsSequence 0")
+ | BindExtend (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what)
+ in
+ TkToken ("+camlcb " ^ cbId ^ (writeeventField what))
+ end |]
+;;
+
+(* FUNCTION
+(* unsafe *)
+ val bind_class :
+ string -> (modifier list * xEvent) list -> bindAction -> unit
+(* /unsafe *)
+/FUNCTION class arg is not constrained *)
+
+let bind_class clas eventsequence action =
+ tkCommand [| TkToken "bind";
+ TkToken clas;
+ cCAMLtoTKeventSequence eventsequence;
+ begin match action with
+ BindRemove -> TkToken ""
+ | BindSet (what, f) ->
+ let cbId = register_callback Widget.dummy
+ (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what))
+ | BindSetBreakable (what, f) ->
+ let cbId = register_callback Widget.dummy
+ (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what)^
+ " ; if { $BreakBindingsSequence == 1 } then { break ;} ; set BreakBindingsSequence 0" )
+ | BindExtend (what, f) ->
+ let cbId = register_callback Widget.dummy
+ (wrapeventInfo f what) in
+ TkToken ("+camlcb " ^ cbId ^ (writeeventField what))
+ end |]
+;;
+
+(* FUNCTION
+(* unsafe *)
+ val bind_tag :
+ string -> (modifier list * xEvent) list -> bindAction -> unit
+(* /unsafe *)
+/FUNCTION *)
+
+let bind_tag = bind_class
+;;
+
+(*
+FUNCTION
+ val break : unit -> unit
+/FUNCTION
+*)
+let break = function () ->
+ Textvariable.set (Textvariable.coerce "BreakBindingsSequence") "1"
+;;
+
+(* Legacy functions *)
+let tag_bind = bind_tag;;
+let class_bind = bind_class;;
+
+##else
+
let bind_class ~events ?(extend = false) ?(breakable = false) ?(fields = [])
?action ?on:widget name =
let widget = match widget with None -> Widget.dummy | Some w -> coe w in
@@ -19,12 +111,15 @@ let bind_class ~events ?(extend = false) ?(breakable = false) ?(fields = [])
TkToken cb
end
|]
+;;
let bind ~events ?extend ?breakable ?fields ?action widget =
bind_class ~events ?extend ?breakable ?fields ?action ~on:widget
(Widget.name widget)
+;;
let bind_tag = bind_class
+;;
(*
FUNCTION
@@ -33,3 +128,6 @@ FUNCTION
*)
let break = function () ->
tkCommand [| TkToken "set" ; TkToken "BreakBindingsSequence" ; TkToken "1" |]
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_GetBitmap.ml b/otherlibs/labltk/builtin/builtini_GetBitmap.ml
index 0fff321bd..1afa0cd91 100644
--- a/otherlibs/labltk/builtin/builtini_GetBitmap.ml
+++ b/otherlibs/labltk/builtin/builtini_GetBitmap.ml
@@ -1,10 +1,28 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKbitmap = function
+ BitmapFile s -> TkToken ("@" ^ s)
+| Predefined s -> TkToken s
+;;
+
+let cTKtoCAMLbitmap s =
+ if s = "" then Predefined ""
+ else if String.get s 0 = '@'
+ then BitmapFile (String.sub s 1 (String.length s - 1))
+ else Predefined s
+;;
+
+##else
+
let cCAMLtoTKbitmap : bitmap -> tkArgs = function
| `File s -> TkToken ("@" ^ s)
| `Predefined s -> TkToken s
+;;
let cTKtoCAMLbitmap s =
if String.get s 0 = '@'
then `File (String.sub s ~pos:1 ~len:(String.length s - 1))
else `Predefined s
+;;
-
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_GetCursor.ml b/otherlibs/labltk/builtin/builtini_GetCursor.ml
index a1d312db6..b3e1af075 100644
--- a/otherlibs/labltk/builtin/builtini_GetCursor.ml
+++ b/otherlibs/labltk/builtin/builtini_GetCursor.ml
@@ -1,3 +1,32 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKcolor = function
+ NamedColor x -> TkToken x
+ | Black -> TkToken "black"
+ | White -> TkToken "white"
+ | Red -> TkToken "red"
+ | Green -> TkToken "green"
+ | Blue -> TkToken "blue"
+ | Yellow -> TkToken "yellow"
+;;
+
+let cTKtoCAMLcolor = function s -> NamedColor s
+;;
+
+let cCAMLtoTKcursor = function
+ XCursor s -> TkToken s
+ | XCursorFg (s,fg) ->
+ TkQuote(TkTokenList [TkToken s; cCAMLtoTKcolor fg])
+ | XCursortFgBg (s,fg,bg) ->
+ TkQuote(TkTokenList [TkToken s; cCAMLtoTKcolor fg; cCAMLtoTKcolor bg])
+ | CursorFileFg (s,fg) ->
+ TkQuote(TkTokenList [TkToken ("@"^s); cCAMLtoTKcolor fg])
+ | CursorMaskFile (s,m,fg,bg) ->
+ TkQuote(TkTokenList [TkToken ("@"^s); TkToken m; cCAMLtoTKcolor fg; cCAMLtoTKcolor bg])
+;;
+
+##else
+
let cCAMLtoTKcolor : color -> tkArgs = function
| `Color x -> TkToken x
| `Black -> TkToken "black"
@@ -6,9 +35,10 @@ let cCAMLtoTKcolor : color -> tkArgs = function
| `Green -> TkToken "green"
| `Blue -> TkToken "blue"
| `Yellow -> TkToken "yellow"
+;;
let cTKtoCAMLcolor = function s -> `Color s
-
+;;
let cCAMLtoTKcursor : cursor -> tkArgs = function
| `Xcursor s -> TkToken s
@@ -20,5 +50,6 @@ let cCAMLtoTKcursor : cursor -> tkArgs = function
TkQuote(TkTokenList [TkToken ("@"^s); cCAMLtoTKcolor fg])
| `Cursormaskfile (s,m,fg,bg) ->
TkQuote(TkTokenList [TkToken ("@"^s); TkToken m; cCAMLtoTKcolor fg; cCAMLtoTKcolor bg])
+;;
-
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_GetPixel.ml b/otherlibs/labltk/builtin/builtini_GetPixel.ml
index c1ebdb17d..65df3d31a 100644
--- a/otherlibs/labltk/builtin/builtini_GetPixel.ml
+++ b/otherlibs/labltk/builtin/builtini_GetPixel.ml
@@ -1,9 +1,33 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKunits = function
+ Pixels (foo) -> TkToken (string_of_int foo)
+ | Millimeters (foo) -> TkToken(string_of_float foo^"m")
+ | Inches (foo) -> TkToken(string_of_float foo^"i")
+ | PrinterPoint (foo) -> TkToken(string_of_float foo^"p")
+ | Centimeters (foo) -> TkToken(string_of_float foo^"c")
+;;
+
+let cTKtoCAMLunits str =
+ let len = String.length str in
+ let num_part str = String.sub str 0 (len - 1) in
+ match String.get str (pred len) with
+ 'c' -> Centimeters (float_of_string (num_part str))
+ | 'i' -> Inches (float_of_string (num_part str))
+ | 'm' -> Millimeters (float_of_string (num_part str))
+ | 'p' -> PrinterPoint (float_of_string (num_part str))
+ | _ -> Pixels(int_of_string str)
+;;
+
+##else
+
let cCAMLtoTKunits : units -> tkArgs = function
| `Pix (foo) -> TkToken (string_of_int foo)
| `Mm (foo) -> TkToken(string_of_float foo^"m")
| `In (foo) -> TkToken(string_of_float foo^"i")
| `Pt (foo) -> TkToken(string_of_float foo^"p")
| `Cm (foo) -> TkToken(string_of_float foo^"c")
+;;
let cTKtoCAMLunits str =
let len = String.length str in
@@ -14,4 +38,6 @@ let cTKtoCAMLunits str =
| 'm' -> `Mm (float_of_string (num_part str))
| 'p' -> `Pt (float_of_string (num_part str))
| _ -> `Pix(int_of_string str)
+;;
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_ScrollValue.ml b/otherlibs/labltk/builtin/builtini_ScrollValue.ml
index 28110337d..0361238b4 100644
--- a/otherlibs/labltk/builtin/builtini_ScrollValue.ml
+++ b/otherlibs/labltk/builtin/builtini_ScrollValue.ml
@@ -1,3 +1,27 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKscrollValue = function
+ ScrollPage v1 ->
+ TkTokenList [TkToken"scroll"; TkToken (string_of_int v1); TkToken"pages"]
+ | ScrollUnit v1 ->
+ TkTokenList [TkToken"scroll"; TkToken (string_of_int v1); TkToken"units"]
+ | MoveTo v1 ->
+ TkTokenList [TkToken"moveto"; TkToken (string_of_float v1)]
+;;
+
+(* str l -> scrllv -> str l *)
+let cTKtoCAMLscrollValue = function
+ "scroll"::n::"pages"::l ->
+ ScrollPage (int_of_string n), l
+ | "scroll"::n::"units"::l ->
+ ScrollUnit (int_of_string n), l
+ | "moveto"::f::l ->
+ MoveTo (float_of_string f), l
+ | _ -> raise (Invalid_argument "TKtoCAMLscrollValue")
+;;
+
+##else
+
let cCAMLtoTKscrollValue : scrollValue -> tkArgs = function
| `Page v1 ->
TkTokenList [TkToken"scroll"; TkToken (string_of_int v1); TkToken"pages"]
@@ -5,6 +29,7 @@ let cCAMLtoTKscrollValue : scrollValue -> tkArgs = function
TkTokenList [TkToken"scroll"; TkToken (string_of_int v1); TkToken"units"]
| `Moveto v1 ->
TkTokenList [TkToken"moveto"; TkToken (string_of_float v1)]
+;;
(* str l -> scrllv -> str l *)
let cTKtoCAMLscrollValue = function
@@ -15,3 +40,6 @@ let cTKtoCAMLscrollValue = function
| "moveto" :: f :: l ->
`Moveto (float_of_string f), l
| _ -> raise (Invalid_argument "TKtoCAMLscrollValue")
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_bind.ml b/otherlibs/labltk/builtin/builtini_bind.ml
index f00182db7..101e26186 100644
--- a/otherlibs/labltk/builtin/builtini_bind.ml
+++ b/otherlibs/labltk/builtin/builtini_bind.ml
@@ -1,3 +1,74 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKxEvent = function
+ | Activate -> "Activate"
+ | ButtonPress -> "ButtonPress"
+ | ButtonPressDetail n -> "ButtonPress-"^string_of_int n
+ | ButtonRelease -> "ButtonRelease"
+ | ButtonReleaseDetail n -> "ButtonRelease-"^string_of_int n
+ | Circulate -> "Circulate"
+ | ColorMap -> "Colormap"
+ | Configure -> "Configure"
+ | Deactivate -> "Deactivate"
+ | Destroy -> "Destroy"
+ | Enter -> "Enter"
+ | Expose -> "Expose"
+ | FocusIn -> "FocusIn"
+ | FocusOut -> "FocusOut"
+ | Gravity -> "Gravity"
+ | KeyPress -> "KeyPress"
+ | KeyPressDetail s -> "KeyPress-"^s
+ | KeyRelease -> "KeyRelease"
+ | KeyReleaseDetail s -> "KeyRelease-"^s
+ | Leave -> "Leave"
+ | Map -> "Map"
+ | Motion -> "Motion"
+ | Property -> "Property"
+ | Reparent -> "Reparent"
+ | Unmap -> "Unmap"
+ | Visibility -> "Visibility"
+ | Virtual s -> "<"^s^">"
+;;
+
+let cCAMLtoTKmodifier = function
+ | Control -> "Control-"
+ | Shift -> "Shift-"
+ | Lock -> "Lock-"
+ | Button1 -> "Button1-"
+ | Button2 -> "Button2-"
+ | Button3 -> "Button3-"
+ | Button4 -> "Button4-"
+ | Button5 -> "Button5-"
+ | Double -> "Double-"
+ | Triple -> "Triple-"
+ | Mod1 -> "Mod1-"
+ | Mod2 -> "Mod2-"
+ | Mod3 -> "Mod3-"
+ | Mod4 -> "Mod4-"
+ | Mod5 -> "Mod5-"
+ | Meta -> "Meta-"
+ | Alt -> "Alt-"
+;;
+
+exception IllegalVirtualEvent
+
+(* type event = modifier list * xEvent *)
+let cCAMLtoTKevent (ml, xe) =
+ match xe with
+ | Virtual s ->
+ if ml = [] then "<<"^s^">>"
+ else raise IllegalVirtualEvent
+ | _ ->
+ "<" ^ (String.concat " " (List.map cCAMLtoTKmodifier ml))
+ ^ (cCAMLtoTKxEvent xe) ^ ">"
+;;
+
+(* type eventSequence == (modifier list * xEvent) list *)
+let cCAMLtoTKeventSequence l =
+ TkToken(List.fold_left (^) "" (List.map cCAMLtoTKevent l))
+
+##else
+
let cCAMLtoTKmodifier : modifier -> string = function
| `Control -> "Control-"
| `Shift -> "Shift-"
@@ -16,39 +87,50 @@ let cCAMLtoTKmodifier : modifier -> string = function
| `Mod5 -> "Mod5-"
| `Meta -> "Meta-"
| `Alt -> "Alt-"
+;;
+
+exception IllegalVirtualEvent
let cCAMLtoTKevent (ev : event) =
+ let modified = ref false in
let rec convert = function
- | `ButtonPress -> "ButtonPress"
- | `ButtonPressDetail n -> "ButtonPress-"^string_of_int n
- | `ButtonRelease -> "ButtonRelease"
- | `ButtonReleaseDetail n -> "ButtonRelease-"^string_of_int n
- | `Circulate -> "Circulate"
- | `Colormap -> "Colormap"
- | `Configure -> "Configure"
- | `Destroy -> "Destroy"
- | `Enter -> "Enter"
- | `Expose -> "Expose"
- | `FocusIn -> "FocusIn"
- | `FocusOut -> "FocusOut"
- | `Gravity -> "Gravity"
- | `KeyPress -> "KeyPress"
- | `KeyPressDetail s -> "KeyPress-"^s
- | `KeyRelease -> "KeyRelease"
- | `KeyReleaseDetail s -> "KeyRelease-"^s
- | `Leave -> "Leave"
- | `Map -> "Map"
- | `Motion -> "Motion"
- | `Property -> "Property"
- | `Reparent -> "Reparent"
- | `Unmap -> "Unmap"
- | `Visibility -> "Visibility"
- | `Modified(ml, ev) ->
- String.concat ~sep:"" (List.map ~f:cCAMLtoTKmodifier ml)
- ^ convert ev
+ | `Activate -> "Activate"
+ | `ButtonPress -> "ButtonPress"
+ | `ButtonPressDetail n -> "ButtonPress-"^string_of_int n
+ | `ButtonRelease -> "ButtonRelease"
+ | `ButtonReleaseDetail n -> "ButtonRelease-"^string_of_int n
+ | `Circulate -> "Circulate"
+ | `Colormap -> "Colormap"
+ | `Configure -> "Configure"
+ | `Deactivate -> "Deactivate"
+ | `Destroy -> "Destroy"
+ | `Enter -> "Enter"
+ | `Expose -> "Expose"
+ | `FocusIn -> "FocusIn"
+ | `FocusOut -> "FocusOut"
+ | `Gravity -> "Gravity"
+ | `KeyPress -> "KeyPress"
+ | `KeyPressDetail s -> "KeyPress-"^s
+ | `KeyRelease -> "KeyRelease"
+ | `KeyReleaseDetail s -> "KeyRelease-"^s
+ | `Leave -> "Leave"
+ | `Map -> "Map"
+ | `Motion -> "Motion"
+ | `Property -> "Property"
+ | `Reparent -> "Reparent"
+ | `Unmap -> "Unmap"
+ | `Visibility -> "Visibility"
+ | `Virtual s ->
+ if !modified then raise IllegalVirtualEvent else "<"^s^">"
+ | `Modified(ml, ev) ->
+ modified := true;
+ String.concat ~sep:"" (List.map ~f:cCAMLtoTKmodifier ml)
+ ^ convert ev
in "<" ^ convert ev ^ ">"
+;;
let cCAMLtoTKeventSequence (l : event list) =
TkToken(String.concat ~sep:"" (List.map ~f:cCAMLtoTKevent l))
+;;
-
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_bindtags.ml b/otherlibs/labltk/builtin/builtini_bindtags.ml
index 9b27563e1..e09734870 100644
--- a/otherlibs/labltk/builtin/builtini_bindtags.ml
+++ b/otherlibs/labltk/builtin/builtini_bindtags.ml
@@ -1,9 +1,29 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKbindings = function
+ | WidgetBindings v1 -> cCAMLtoTKwidget widget_any_table v1
+ | TagBindings v1 -> TkToken v1
+;;
+
+(* this doesn't really belong here *)
+let cTKtoCAMLbindings s =
+ if String.length s > 0 && s.[0] = '.' then
+ WidgetBindings (cTKtoCAMLwidget s)
+ else TagBindings s
+;;
+
+##else
+
let cCAMLtoTKbindings = function
| `Widget v1 -> cCAMLtoTKwidget v1
| `Tag v1 -> TkToken v1
+;;
(* this doesn't really belong here *)
let cTKtoCAMLbindings s =
if String.length s > 0 && s.[0] = '.' then
`Widget (cTKtoCAMLwidget s)
else `Tag s
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_font.ml b/otherlibs/labltk/builtin/builtini_font.ml
new file mode 100644
index 000000000..521b24d6d
--- /dev/null
+++ b/otherlibs/labltk/builtin/builtini_font.ml
@@ -0,0 +1,3 @@
+let cCAMLtoTKfont (s : font) = TkToken s
+let cTKtoCAMLfont (s : font) = s
+
diff --git a/otherlibs/labltk/builtin/builtini_index.ml b/otherlibs/labltk/builtin/builtini_index.ml
index 0e48a4b83..9e43c4f76 100644
--- a/otherlibs/labltk/builtin/builtini_index.ml
+++ b/otherlibs/labltk/builtin/builtini_index.ml
@@ -1,3 +1,97 @@
+##ifdef CAMLTK
+
+(* sp to avoid being picked up by doc scripts *)
+ type index_constrs =
+ CNumber
+ | CActiveElement
+ | CEnd
+ | CLast
+ | CNoIndex
+ | CInsert
+ | CSelFirst
+ | CSelLast
+ | CAt
+ | CAtXY
+ | CAnchorPoint
+ | CPattern
+ | CLineChar
+ | CMark
+ | CTagFirst
+ | CTagLast
+ | CEmbedded
+;;
+
+let index_any_table =
+ [CNumber; CActiveElement; CEnd; CLast; CNoIndex; CInsert; CSelFirst;
+ CSelLast; CAt; CAtXY; CAnchorPoint; CPattern; CLineChar;
+ CMark; CTagFirst; CTagLast; CEmbedded]
+;;
+
+let index_canvas_table =
+ [CNumber; CEnd; CInsert; CSelFirst; CSelLast; CAtXY]
+;;
+let index_entry_table =
+ [CNumber; CAnchorPoint; CEnd; CInsert; CSelFirst; CSelLast; CAt]
+;;
+let index_listbox_table =
+ [CNumber; CActiveElement; CAnchorPoint; CEnd; CAtXY]
+;;
+let index_menu_table =
+ [CNumber; CActiveElement; CEnd; CLast; CNoIndex; CAt; CPattern]
+;;
+let index_text_table =
+ [CLineChar; CAtXY; CEnd; CMark; CTagFirst; CTagLast; CEmbedded]
+;;
+
+let cCAMLtoTKindex table = function
+ Number x -> chk_sub "Number" table CNumber; TkToken (string_of_int x)
+ | ActiveElement -> chk_sub "ActiveElement" table CActiveElement; TkToken "active"
+ | End -> chk_sub "End" table CEnd; TkToken "end"
+ | Last -> chk_sub "Last" table CLast; TkToken "last"
+ | NoIndex -> chk_sub "NoIndex" table CNoIndex; TkToken "none"
+ | Insert -> chk_sub "Insert" table CInsert; TkToken "insert"
+ | SelFirst -> chk_sub "SelFirst" table CSelFirst; TkToken "sel.first"
+ | SelLast -> chk_sub "SelLast" table CSelLast; TkToken "sel.last"
+ | At n -> chk_sub "At" table CAt; TkToken ("@"^string_of_int n)
+ | AtXY (x,y) -> chk_sub "AtXY" table CAtXY;
+ TkToken ("@"^string_of_int x^","^string_of_int y)
+ | AnchorPoint -> chk_sub "AnchorPoint" table CAnchorPoint; TkToken "anchor"
+ | Pattern s -> chk_sub "Pattern" table CPattern; TkToken s
+ | LineChar (l,c) -> chk_sub "LineChar" table CLineChar;
+ TkToken (string_of_int l^"."^string_of_int c)
+ | Mark s -> chk_sub "Mark" table CMark; TkToken s
+ | TagFirst t -> chk_sub "TagFirst" table CTagFirst;
+ TkToken (t^".first")
+ | TagLast t -> chk_sub "TagLast" table CTagLast;
+ TkToken (t^".last")
+ | Embedded w -> chk_sub "Embedded" table CEmbedded;
+ cCAMLtoTKwidget widget_any_table w
+;;
+
+let char_index c s =
+ let rec find i =
+ if i >= String.length s
+ then raise Not_found
+ else if String.get s i = c then i
+ else find (i+1) in
+ find 0
+;;
+
+(* Assume returned values are only numerical and l.c *)
+(* .menu index returns none if arg is none, but blast it *)
+let cTKtoCAMLindex s =
+ try
+ let p = char_index '.' s in
+ LineChar(int_of_string (String.sub s 0 p),
+ int_of_string (String.sub s (p+1) (String.length s - p - 1)))
+ with
+ Not_found ->
+ try Number (int_of_string s)
+ with _ -> raise (Invalid_argument ("TKtoCAMLindex: "^s))
+;;
+
+##else
+
let cCAMLtoTKindex (* Don't put explicit typing *) = function
| `Num x -> TkToken (string_of_int x)
| `Active -> TkToken "active"
@@ -17,12 +111,13 @@ let cCAMLtoTKindex (* Don't put explicit typing *) = function
| `Taglast t -> TkToken (t ^ ".last")
| `Window (w : any widget) -> cCAMLtoTKwidget w
| `Image s -> TkToken s
+;;
-let cCAMLtoTKcanvas_index = (cCAMLtoTKindex : canvas_index -> tkArgs)
-let cCAMLtoTKentry_index = (cCAMLtoTKindex : entry_index -> tkArgs)
-let cCAMLtoTKlistbox_index = (cCAMLtoTKindex : listbox_index -> tkArgs)
-let cCAMLtoTKmenu_index = (cCAMLtoTKindex : menu_index -> tkArgs)
-let cCAMLtoTKtext_index = (cCAMLtoTKindex : text_index -> tkArgs)
+let cCAMLtoTKcanvas_index = (cCAMLtoTKindex : canvas_index -> tkArgs);;
+let cCAMLtoTKentry_index = (cCAMLtoTKindex : entry_index -> tkArgs);;
+let cCAMLtoTKlistbox_index = (cCAMLtoTKindex : listbox_index -> tkArgs);;
+let cCAMLtoTKmenu_index = (cCAMLtoTKindex : menu_index -> tkArgs);;
+let cCAMLtoTKtext_index = (cCAMLtoTKindex : text_index -> tkArgs);;
(* Assume returned values are only numerical and l.c *)
@@ -35,8 +130,11 @@ let cTKtoCAMLtext_index s =
with
Not_found ->
raise (Invalid_argument ("TKtoCAMLtext_index: " ^ s))
-
+;;
let cTKtoCAMLlistbox_index s =
try `Num (int_of_string s)
with _ -> raise (Invalid_argument ("TKtoCAMLlistbox_index: " ^ s))
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_palette.ml b/otherlibs/labltk/builtin/builtini_palette.ml
index 10a6e1dc4..b9529c3fa 100644
--- a/otherlibs/labltk/builtin/builtini_palette.ml
+++ b/otherlibs/labltk/builtin/builtini_palette.ml
@@ -1,5 +1,19 @@
+##ifdef CAMLTK
+
+let cCAMLtoTKpaletteType = function
+ GrayShades (foo) -> TkToken (string_of_int foo)
+ | RGBShades (r,v,b) -> TkToken (string_of_int r^"/"^
+ string_of_int v^"/"^
+ string_of_int b)
+;;
+
+##else
+
let cCAMLtoTKpaletteType : paletteType -> tkArgs = function
| `Gray (foo) -> TkToken (string_of_int foo)
| `Rgb (r,v,b) -> TkToken (string_of_int r ^ "/" ^
string_of_int v ^ "/" ^
string_of_int b)
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/builtini_text.ml b/otherlibs/labltk/builtin/builtini_text.ml
index e27d72edb..966c28a32 100644
--- a/otherlibs/labltk/builtin/builtini_text.ml
+++ b/otherlibs/labltk/builtin/builtini_text.ml
@@ -1,8 +1,40 @@
-let cCAMLtoTKtextMark x = TkToken x
-let cTKtoCAMLtextMark x = x
+let cCAMLtoTKtextMark x = TkToken x;;
+let cTKtoCAMLtextMark x = x;;
-let cCAMLtoTKtextTag x = TkToken x
-let cTKtoCAMLtextTag x = x
+let cCAMLtoTKtextTag x = TkToken x;;
+let cTKtoCAMLtextTag x = x;;
+
+##ifdef CAMLTK
+
+(* TextModifiers are never returned by Tk *)
+let ppTextModifier = function
+ CharOffset n ->
+ if n > 0 then "+" ^ (string_of_int n) ^ "chars"
+ else if n = 0 then ""
+ else (string_of_int n) ^ "chars"
+ | LineOffset n ->
+ if n > 0 then "+" ^ (string_of_int n) ^ "lines"
+ else if n = 0 then ""
+ else (string_of_int n) ^ "lines"
+ | LineStart -> " linestart"
+ | LineEnd -> " lineend"
+ | WordStart -> " wordstart"
+ | WordEnd -> " wordend"
+;;
+
+let ppTextIndex = function
+ | TextIndexNone -> ""
+ | TextIndex (base, ml) ->
+ match cCAMLtoTKindex index_text_table base with
+ | TkToken ppbase -> List.fold_left (^) ppbase (List.map ppTextModifier ml)
+ | _ -> assert false
+;;
+
+let cCAMLtoTKtextIndex i =
+ TkToken (ppTextIndex i)
+;;
+
+##else
(* TextModifiers are never returned by Tk *)
let cCAMLtoTKtextIndex (i : textIndex) =
@@ -27,4 +59,6 @@ let cCAMLtoTKtextIndex (i : textIndex) =
| _ -> assert false
in
TkToken (ppTextIndex i)
+;;
+##endif
diff --git a/otherlibs/labltk/builtin/canvas_bind.ml b/otherlibs/labltk/builtin/canvas_bind.ml
index 1ac0dac2b..c153525de 100644
--- a/otherlibs/labltk/builtin/canvas_bind.ml
+++ b/otherlibs/labltk/builtin/canvas_bind.ml
@@ -1,3 +1,30 @@
+##ifdef CAMLTK
+
+let bind widget tag eventsequence action =
+ tkCommand [|
+ cCAMLtoTKwidget widget_canvas_table widget;
+ TkToken "bind";
+ cCAMLtoTKtagOrId tag;
+ cCAMLtoTKeventSequence eventsequence;
+ begin match action with
+ | BindRemove -> TkToken ""
+ | BindSet (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what))
+ | BindSetBreakable (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what)^
+ " ; if { $BreakBindingsSequence == 1 } then { break ;} ; \
+ set BreakBindingsSequence 0")
+ | BindExtend (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("+camlcb " ^ cbId ^ (writeeventField what))
+ end
+ |]
+;;
+
+##else
+
let bind ~events
?(extend = false) ?(breakable = false) ?(fields = [])
?action widget tag =
@@ -20,3 +47,6 @@ let bind ~events
TkToken cb
end
|]
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/canvas_bind.mli b/otherlibs/labltk/builtin/canvas_bind.mli
index b680c5fac..39ce93e7c 100644
--- a/otherlibs/labltk/builtin/canvas_bind.mli
+++ b/otherlibs/labltk/builtin/canvas_bind.mli
@@ -1,3 +1,10 @@
+##ifdef CAMLTK
+
+val bind : widget -> tagOrId ->
+ (modifier list * xEvent) list -> bindAction -> unit
+
+##else
+
val bind :
events: event list ->
?extend: bool ->
@@ -5,3 +12,5 @@ val bind :
?fields: eventField list ->
?action: (eventInfo -> unit) ->
canvas widget -> tagOrId -> unit
+
+##endif
diff --git a/otherlibs/labltk/builtin/dialog.ml b/otherlibs/labltk/builtin/dialog.ml
index 84e5274bf..260ec78e1 100644
--- a/otherlibs/labltk/builtin/dialog.ml
+++ b/otherlibs/labltk/builtin/dialog.ml
@@ -1,3 +1,33 @@
+##ifdef CAMLTK
+
+let create ?name parent title mesg bitmap def buttons =
+ let w = Widget.new_atom "toplevel" ~parent ?name in
+ let res = tkEval [|TkToken"tk_dialog";
+ cCAMLtoTKwidget widget_any_table w;
+ TkToken title;
+ TkToken mesg;
+ cCAMLtoTKbitmap bitmap;
+ TkToken (string_of_int def);
+ TkTokenList (List.map (function x -> TkToken x) buttons)|]
+ in
+ int_of_string res
+;;
+
+let create_named parent name title mesg bitmap def buttons =
+ let w = Widget.new_atom "toplevel" ~parent ~name in
+ let res = tkEval [|TkToken"tk_dialog";
+ cCAMLtoTKwidget widget_any_table w;
+ TkToken title;
+ TkToken mesg;
+ cCAMLtoTKbitmap bitmap;
+ TkToken (string_of_int def);
+ TkTokenList (List.map (function x -> TkToken x) buttons)|]
+ in
+ int_of_string res
+;;
+
+##else
+
let create ~parent ~title ~message ~buttons ?name
?(bitmap = `Predefined "") ?(default = -1) () =
let w = Widget.new_atom "toplevel" ?name ~parent in
@@ -10,3 +40,6 @@ let create ~parent ~title ~message ~buttons ?name
TkTokenList (List.map ~f:(fun x -> TkToken x) buttons)|]
in
int_of_string res
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/dialog.mli b/otherlibs/labltk/builtin/dialog.mli
index d0f6398c3..debb6ce20 100644
--- a/otherlibs/labltk/builtin/dialog.mli
+++ b/otherlibs/labltk/builtin/dialog.mli
@@ -1,3 +1,17 @@
+##ifdef CAMLTK
+
+val create : ?name: string ->
+ widget -> string -> string -> bitmap -> int -> string list -> int
+ (* [create ~name parent title message bitmap default button_names]
+ cf. tk_dialog *)
+
+val create_named :
+ widget -> string -> string -> string -> bitmap -> int -> string list -> int
+ (* [create_named parent name title message bitmap default button_names]
+ cf. tk_dialog *)
+
+##else
+
val create :
parent: 'a widget ->
title: string ->
@@ -6,3 +20,5 @@ val create :
?name: string -> ?bitmap: bitmap -> ?default: int -> unit ->int
(* [create title message bitmap default button_names parent]
cf. tk_dialog *)
+
+##endif
diff --git a/otherlibs/labltk/builtin/image.ml b/otherlibs/labltk/builtin/image.ml
new file mode 100644
index 000000000..ac4c7238a
--- /dev/null
+++ b/otherlibs/labltk/builtin/image.ml
@@ -0,0 +1,33 @@
+##ifdef CAMLTK
+
+let cTKtoCAMLimage s =
+ let res = tkEval [|TkToken "image"; TkToken "type"; TkToken s|] in
+ match res with
+ | "bitmap" -> ImageBitmap (BitmapImage s)
+ | "photo" -> ImagePhoto (PhotoImage s)
+ | _ -> raise (TkError ("unknown image type \"" ^ res ^ "\""))
+;;
+
+let names () =
+ let res = tkEval [|TkToken "image"; TkToken "names"|] in
+ let names = splitlist res in
+ List.map cTKtoCAMLimage names
+;;
+
+##else
+
+let cTKtoCAMLimage s =
+ let res = tkEval [|TkToken "image"; TkToken "type"; TkToken s|] in
+ match res with
+ | "bitmap" -> `Bitmap s
+ | "photo" -> `Photo s
+ | _ -> raise (TkError ("unknown image type \"" ^ res ^ "\""))
+;;
+
+let names () =
+ let res = tkEval [|TkToken "image"; TkToken "names"|] in
+ let names = splitlist res in
+ List.map cTKtoCAMLimage names
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/image.mli b/otherlibs/labltk/builtin/image.mli
new file mode 100644
index 000000000..a92a9f8c7
--- /dev/null
+++ b/otherlibs/labltk/builtin/image.mli
@@ -0,0 +1,9 @@
+##ifdef CAMLTK
+
+val names : unit -> options list
+
+##else
+
+val names : unit -> image list
+
+##endif
diff --git a/otherlibs/labltk/builtin/optionmenu.ml b/otherlibs/labltk/builtin/optionmenu.ml
index ae2614087..8b738d9d3 100644
--- a/otherlibs/labltk/builtin/optionmenu.ml
+++ b/otherlibs/labltk/builtin/optionmenu.ml
@@ -1,4 +1,39 @@
-open Protocol
+##ifdef CAMLTK
+
+open Protocol;;
+(* Implementation of the tk_optionMenu *)
+
+let create ?name parent variable values =
+ let w = Widget.new_atom "menubutton" ~parent ?name in
+ let mw = Widget.new_atom "menu" ~parent:w ~name:"menu" in
+ let res =
+ tkEval [|TkToken "tk_optionMenu";
+ TkToken (Widget.name w);
+ cCAMLtoTKtextVariable variable;
+ TkTokenList (List.map (function x -> TkToken x) values)|] in
+ if res <> Widget.name mw then
+ raise (TkError "internal error in Optionmenu.create")
+ else
+ w,mw
+;;
+
+let create_named parent name variable values =
+ let w = Widget.new_atom "menubutton" ~parent ~name in
+ let mw = Widget.new_atom "menu" ~parent:w ~name: "menu" in
+ let res =
+ tkEval [|TkToken "tk_optionMenu";
+ TkToken (Widget.name w);
+ cCAMLtoTKtextVariable variable;
+ TkTokenList (List.map (function x -> TkToken x) values)|] in
+ if res <> Widget.name mw then
+ raise (TkError "internal error in Optionmenu.create")
+ else
+ w,mw
+;;
+
+##else
+
+open Protocol;;
(* Implementation of the tk_optionMenu *)
let create ~parent ~variable ?name values =
@@ -6,11 +41,14 @@ let create ~parent ~variable ?name values =
let mw = Widget.new_atom "menu" ~parent:w ~name:"menu" in
(* assumes .menu naming *)
let res =
- tkEval [|TkToken "tk_optionMenu";
- TkToken (Widget.name w);
- cCAMLtoTKtextVariable variable;
- TkTokenList (List.map ~f:(fun x -> TkToken x) values)|] in
- if res <> Widget.name mw then
- raise (TkError "internal error in Optionmenu.create")
- else
- w, mw
+ tkEval [|TkToken "tk_optionMenu";
+ TkToken (Widget.name w);
+ cCAMLtoTKtextVariable variable;
+ TkTokenList (List.map ~f:(fun x -> TkToken x) values)|] in
+ if res <> Widget.name mw then
+ raise (TkError "internal error in Optionmenu.create")
+ else
+ w, mw
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/optionmenu.mli b/otherlibs/labltk/builtin/optionmenu.mli
index 46a9051f0..0c6b5c9e1 100644
--- a/otherlibs/labltk/builtin/optionmenu.mli
+++ b/otherlibs/labltk/builtin/optionmenu.mli
@@ -1,7 +1,21 @@
+##ifdef CAMLTK
+
(* Support for tk_optionMenu *)
-val create: parent:'a widget -> variable:textVariable ->
- ?name: string -> string list -> menubutton widget * menu widget
- (* [create parent var options] creates a multi-option
- menubutton and its associated menu. The option is also stored
- in the variable. Both widgets (menubutton and menu) are
- returned *)
+val create: ?name: string ->
+ widget -> textVariable -> string list -> widget * widget
+(** [create ?name parent var options] creates a multi-option menubutton and
+ its associated menu. The option is also stored in the variable.
+ Both widgets (menubutton and menu) are returned. *)
+
+##else
+
+(* Support for tk_optionMenu *)
+val create:
+ parent:'a widget ->
+ variable:textVariable ->
+ ?name: string -> string list -> menubutton widget * menu widget
+(** [create ~parent ~var ~name options] creates a multi-option menubutton
+ and its associated menu. The option is also stored in the variable.
+ Both widgets (menubutton and menu) are returned *)
+
+##endif
diff --git a/otherlibs/labltk/builtin/rawimg.ml b/otherlibs/labltk/builtin/rawimg.ml
new file mode 100644
index 000000000..6bd0ad283
--- /dev/null
+++ b/otherlibs/labltk/builtin/rawimg.ml
@@ -0,0 +1,142 @@
+external rawget : string -> string
+ = "camltk_getimgdata"
+external rawset : string -> string -> int -> int -> int -> int -> unit
+ = "camltk_setimgdata_bytecode" (* all int parameters MUST be positive *)
+ "camltk_setimgdata_native"
+
+type t = {
+ pixmap_width : int;
+ pixmap_height: int;
+ pixmap_data: string
+}
+
+type pixel = string (* 3 chars *)
+
+(* pixmap will be an abstract type *)
+let width pix = pix.pixmap_width
+let height pix = pix.pixmap_height
+
+
+(* note: invalid size would have been caught by String.create, but we put
+ * it here for documentation purpose *)
+let create w h =
+ if w < 0 || h < 0 then invalid_arg "invalid size"
+ else {
+ pixmap_width = w;
+ pixmap_height = h;
+ pixmap_data = String.create (w * h * 3);
+ }
+
+(*
+ * operations on pixmaps
+ *)
+let unsafe_copy pix_from pix_to =
+ String.unsafe_blit pix_from.pixmap_data 0
+ pix_to.pixmap_data 0
+ (String.length pix_from.pixmap_data)
+
+(* We check only the length. w,h might be different... *)
+let copy pix_from pix_to =
+ let l = String.length pix_from.pixmap_data in
+ if l <> String.length pix_to.pixmap_data then
+ raise (Invalid_argument "copy: incompatible length")
+ else unsafe_copy pix_from pix_to
+
+
+(* Pixel operations *)
+let unsafe_get_pixel pixmap x y =
+ let pos = (y * pixmap.pixmap_width + x) * 3 in
+ let r = String.create 3 in
+ String.unsafe_blit pixmap.pixmap_data pos r 0 3;
+ r
+
+let unsafe_set_pixel pixmap x y pixel =
+ let pos = (y * pixmap.pixmap_width + x) * 3 in
+ String.unsafe_blit pixel 0 pixmap.pixmap_data pos 3
+
+(* To get safe operations, we can either check x,y wrt [0,w[ and [0,h[
+ or rely on blit checking. We choose the first for clarity.
+ *)
+let get_pixel pix x y =
+ if x < 0 || y < 0 || x >= pix.pixmap_width || y >= pix.pixmap_height
+ then invalid_arg "invalid pixel"
+ else unsafe_get_pixel pix x y
+
+(* same check (pixel being abstract, it must be of good size *)
+let set_pixel pix x y pixel =
+ if x < 0 || y < 0 || x >= pix.pixmap_width || y >= pix.pixmap_height
+ then invalid_arg "invalid pixel"
+ else unsafe_set_pixel pix x y pixel
+
+(* black as default_color, if at all needed *)
+let default_color = "\000\000\000"
+
+(* Char.chr does range checking *)
+let pixel r g b =
+ let s = String.create 3 in
+ s.[0] <- Char.chr r;
+ s.[1] <- Char.chr g;
+ s.[2] <- Char.chr b;
+ s
+
+##ifdef CAMLTK
+
+(* create pixmap from an existing image *)
+let get photo =
+ match photo with
+ | PhotoImage s -> {
+ pixmap_width = CImagephoto.width photo;
+ pixmap_height = CImagephoto.height photo;
+ pixmap_data = rawget s;
+ }
+
+(* copy a full pixmap into an image *)
+let set photo pix =
+ match photo with
+ | PhotoImage s ->
+ rawset s pix.pixmap_data 0 0 pix.pixmap_width pix.pixmap_height
+
+(* general blit of pixmap into image *)
+let blit photo pix x y w h =
+ if x < 0 || y < 0 || w < 0 || h < 0 then invalid_arg "negative argument"
+ else match photo with
+ | PhotoImage s ->
+ rawset s pix.pixmap_data x y w h
+
+(* get from a file *)
+let from_file filename =
+ let img = CImagephoto.create [File filename] in
+ let pix = get img in
+ CImagephoto.delete img;
+ pix
+
+##else
+
+(* create pixmap from an existing image *)
+let get photo =
+ match photo with
+ | `Photo s -> {
+ pixmap_width = Imagephoto.width photo;
+ pixmap_height = Imagephoto.height photo;
+ pixmap_data = rawget s;
+ }
+
+(* copy a full pixmap into an image *)
+let set photo pix =
+ match photo with
+ | `Photo s -> rawset s pix.pixmap_data 0 0 pix.pixmap_width pix.pixmap_height
+
+(* general blit of pixmap into image *)
+let blit photo pix x y w h =
+ if x < 0 || y < 0 || w < 0 || h < 0 then invalid_arg "negative argument"
+ else match photo with
+ | `Photo s -> rawset s pix.pixmap_data x y w h
+
+(* get from a file *)
+let from_file filename =
+ let img = Imagephoto.create ~file: filename () in
+ let pix = get img in
+ Imagephoto.delete img;
+ pix
+
+##endif
diff --git a/otherlibs/labltk/builtin/rawimg.mli b/otherlibs/labltk/builtin/rawimg.mli
new file mode 100644
index 000000000..1bb120f64
--- /dev/null
+++ b/otherlibs/labltk/builtin/rawimg.mli
@@ -0,0 +1,44 @@
+(*
+ * Minimal pixmap support
+ *)
+
+type t
+type pixel
+
+val width : t -> int
+ (* [width pixmap] *)
+val height : t -> int
+ (* [height pixmap] *)
+
+val create : int -> int -> t
+ (* [create width height] *)
+val get : imagePhoto -> t
+ (* [get img] *)
+val set : imagePhoto -> t -> unit
+ (* [set img pixmap] *)
+val blit : imagePhoto -> t -> int -> int -> int -> int -> unit
+ (* [blit img pixmap x y w h] (all ints must be non-negative) *)
+val from_file : string -> t
+ (* [from_file filename] *)
+
+val copy : t -> t -> unit
+ (* [copy src dst] *)
+
+(*
+ * Pixel operations
+ *)
+val get_pixel : t -> int -> int -> pixel
+ (* [get_pixel pixmap x y] *)
+val set_pixel : t -> int -> int -> pixel -> unit
+ (* [set_pixel pixmap x y pixel] *)
+val default_color : pixel
+
+val pixel : int -> int -> int -> pixel
+ (* [pixel r g b] (r,g,b must be in [0..255]) *)
+
+(*-*)
+(* unsafe *)
+val unsafe_copy : t -> t -> unit
+val unsafe_get_pixel : t -> int -> int -> pixel
+val unsafe_set_pixel : t -> int -> int -> pixel -> unit
+(* /unsafe *)
diff --git a/otherlibs/labltk/builtin/report.ml b/otherlibs/labltk/builtin/report.ml
index 72a8848c4..852b4c141 100644
--- a/otherlibs/labltk/builtin/report.ml
+++ b/otherlibs/labltk/builtin/report.ml
@@ -1,12 +1,17 @@
(* Report globals from protocol *)
-let openTk = openTk
-and closeTk = closeTk
-and mainLoop = mainLoop
-and register = register
+let opentk = Protocol.opentk
+let keywords = Protocol.keywords
+let opentk_with_args = Protocol.opentk_with_args
+let openTk = Protocol.openTk
+let openTkClass = Protocol.openTkClass
+let openTkDisplayClass = Protocol.openTkDisplayClass
+let closeTk = Protocol.closeTk
+let mainLoop = Protocol.mainLoop
+let register = Protocol.register
(* From support *)
-let may = may
-let maycons = maycons
+let may = Support.may
+let maycons = Support.maycons
(* From widget *)
-let coe = coe
+let coe = Widget.coe
diff --git a/otherlibs/labltk/builtin/selection_handle_set.ml b/otherlibs/labltk/builtin/selection_handle_set.ml
index d46a90f13..946f25424 100644
--- a/otherlibs/labltk/builtin/selection_handle_set.ml
+++ b/otherlibs/labltk/builtin/selection_handle_set.ml
@@ -1,16 +1,41 @@
+##ifdef CAMLTK
+
+(* The function *must* use tkreturn *)
+let handle_set opts w cmd =
+ tkCommand [|
+ TkToken"selection";
+ TkToken"handle";
+ TkTokenList
+ (List.map
+ (function x -> cCAMLtoTKicccm w icccm_selection_handle_table x)
+ opts);
+ cCAMLtoTKwidget widget_any_table w;
+ let id = register_callback w (function args ->
+ let (a1,args) = int_of_string (List.hd args), List.tl args in
+ let (a2,args) = int_of_string (List.hd args), List.tl args in
+ cmd a1 a2) in
+ TkToken ("camlcb "^id)
+ |]
+;;
+
+##else
+
(* The function *must* use tkreturn *)
let handle_set ~command =
selection_handle_icccm_optionals (fun opts w ->
- tkCommand [|TkToken"selection";
- TkToken"handle";
- TkTokenList opts;
- cCAMLtoTKwidget w;
- let id = register_callback w ~callback:
- begin fun args ->
- let pos = int_of_string (List.hd args) in
- let len = int_of_string (List.nth args 1) in
- tkreturn (command ~pos ~len)
- end
- in TkToken ("camlcb " ^ id)
- |])
+ tkCommand [|
+ TkToken"selection";
+ TkToken"handle";
+ TkTokenList opts;
+ cCAMLtoTKwidget w;
+ let id = register_callback w ~callback:
+ begin fun args ->
+ let pos = int_of_string (List.hd args) in
+ let len = int_of_string (List.nth args 1) in
+ tkreturn (command ~pos ~len)
+ end
+ in TkToken ("camlcb " ^ id)
+ |])
+;;
+##endif
diff --git a/otherlibs/labltk/builtin/selection_handle_set.mli b/otherlibs/labltk/builtin/selection_handle_set.mli
index c053bdc34..66ae6b734 100644
--- a/otherlibs/labltk/builtin/selection_handle_set.mli
+++ b/otherlibs/labltk/builtin/selection_handle_set.mli
@@ -1,4 +1,13 @@
+##ifdef CAMLTK
+
+val handle_set : icccm list -> widget -> (int -> int -> unit) -> unit
+(** tk invocation: selection handle <icccm list> <widget> <command> *)
+
+##else
+
val handle_set :
command: (pos:int -> len:int -> string) ->
?format: string -> ?selection:string -> ?typ: string -> 'a widget -> unit
-(* tk invocation: selection handle <icccm list> <widget> <command> *)
+(** tk invocation: selection handle <icccm list> <widget> <command> *)
+
+##endif
diff --git a/otherlibs/labltk/builtin/selection_own_set.ml b/otherlibs/labltk/builtin/selection_own_set.ml
index 8e64177ef..011abef84 100644
--- a/otherlibs/labltk/builtin/selection_own_set.ml
+++ b/otherlibs/labltk/builtin/selection_own_set.ml
@@ -1,8 +1,29 @@
+##ifdef CAMLTK
+
+(* builtin to handle callback association to widget *)
+let own_set v1 v2 =
+ tkCommand [|
+ TkToken"selection";
+ TkToken"own";
+ TkTokenList
+ (List.map
+ (function x -> cCAMLtoTKicccm v2 icccm_selection_ownset_table x)
+ v1);
+ cCAMLtoTKwidget widget_any_table v2
+ |]
+;;
+
+##else
+
(* builtin to handle callback association to widget *)
let own_set ?command =
-selection_ownset_icccm_optionals ?command (fun opts w ->
-tkCommand [|TkToken"selection";
- TkToken"own";
- TkTokenList opts;
- cCAMLtoTKwidget w|])
+ selection_ownset_icccm_optionals ?command (fun opts w ->
+ tkCommand [|
+ TkToken"selection";
+ TkToken"own";
+ TkTokenList opts;
+ cCAMLtoTKwidget w
+ |])
+;;
+##endif
diff --git a/otherlibs/labltk/builtin/selection_own_set.mli b/otherlibs/labltk/builtin/selection_own_set.mli
index d05450903..95b3de363 100644
--- a/otherlibs/labltk/builtin/selection_own_set.mli
+++ b/otherlibs/labltk/builtin/selection_own_set.mli
@@ -1,3 +1,12 @@
+##ifdef CAMLTK
+
+val own_set : icccm list -> widget -> unit
+(** tk invocation: selection own <icccm list> <widget> *)
+
+##else
+
val own_set :
?command:(unit->unit) -> ?selection:string -> 'a widget -> unit
-(* tk invocation: selection own <icccm list> <widget> *)
+(** tk invocation: selection own <icccm list> <widget> *)
+
+##endif
diff --git a/otherlibs/labltk/builtin/text_tag_bind.ml b/otherlibs/labltk/builtin/text_tag_bind.ml
index f9539b22e..e07fbaf20 100644
--- a/otherlibs/labltk/builtin/text_tag_bind.ml
+++ b/otherlibs/labltk/builtin/text_tag_bind.ml
@@ -1,23 +1,55 @@
+##ifdef CAMLTK
+
+let tag_bind widget tag eventsequence action =
+ check_class widget widget_text_table;
+ tkCommand [|
+ cCAMLtoTKwidget widget_text_table widget;
+ TkToken "tag";
+ TkToken "bind";
+ cCAMLtoTKtextTag tag;
+ cCAMLtoTKeventSequence eventsequence;
+ begin match action with
+ | BindRemove -> TkToken ""
+ | BindSet (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what))
+ | BindSetBreakable (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("camlcb " ^ cbId ^ (writeeventField what) ^
+ " ; if { $BreakBindingsSequence == 1 } then { break ;} ; \
+ set BreakBindingsSequence 0")
+ | BindExtend (what, f) ->
+ let cbId = register_callback widget (wrapeventInfo f what) in
+ TkToken ("+camlcb " ^ cbId ^ (writeeventField what))
+ end
+ |]
+;;
+
+##else
+
let tag_bind ~tag ~events ?(extend = false) ?(breakable = false)
?(fields = []) ?action widget =
- tkCommand
- [| cCAMLtoTKwidget widget;
- TkToken "tag";
- TkToken "bind";
- cCAMLtoTKtextTag tag;
- cCAMLtoTKeventSequence events;
- begin match action with
- | None -> TkToken ""
- | Some f ->
- let cbId =
- register_callback widget ~callback: (wrapeventInfo f fields) in
- let cb = if extend then "+camlcb " else "camlcb " in
- let cb = cb ^ cbId ^ writeeventField fields in
- let cb =
- if breakable then
- cb ^ " ; if { $BreakBindingsSequence == 1 } then { break ;}"
- ^ " ; set BreakBindingsSequence 0"
- else cb in
- TkToken cb
- end
- |]
+ tkCommand [|
+ cCAMLtoTKwidget widget;
+ TkToken "tag";
+ TkToken "bind";
+ cCAMLtoTKtextTag tag;
+ cCAMLtoTKeventSequence events;
+ begin match action with
+ | None -> TkToken ""
+ | Some f ->
+ let cbId =
+ register_callback widget ~callback: (wrapeventInfo f fields) in
+ let cb = if extend then "+camlcb " else "camlcb " in
+ let cb = cb ^ cbId ^ writeeventField fields in
+ let cb =
+ if breakable then
+ cb ^ " ; if { $BreakBindingsSequence == 1 } then { break ;}"
+ ^ " ; set BreakBindingsSequence 0"
+ else cb in
+ TkToken cb
+ end
+ |]
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/text_tag_bind.mli b/otherlibs/labltk/builtin/text_tag_bind.mli
index 40b969926..1f334a796 100644
--- a/otherlibs/labltk/builtin/text_tag_bind.mli
+++ b/otherlibs/labltk/builtin/text_tag_bind.mli
@@ -1,4 +1,13 @@
+##ifdef CAMLTK
+
+val tag_bind:
+ widget -> textTag -> (modifier list * xEvent) list -> bindAction -> unit
+
+##else
+
val tag_bind :
tag: string -> events: event list ->
?extend: bool -> ?breakable: bool -> ?fields: eventField list ->
?action: (eventInfo -> unit) -> text widget -> unit
+
+##endif
diff --git a/otherlibs/labltk/builtin/winfo_contained.ml b/otherlibs/labltk/builtin/winfo_contained.ml
index 768f1015e..f1fb3735c 100644
--- a/otherlibs/labltk/builtin/winfo_contained.ml
+++ b/otherlibs/labltk/builtin/winfo_contained.ml
@@ -1,2 +1,13 @@
+##ifdef CAMLTK
+
+let contained x y w =
+ w = containing x y
+;;
+
+##else
+
let contained ~x ~y w =
forget_type w = containing ~x ~y ()
+;;
+
+##endif
diff --git a/otherlibs/labltk/builtin/winfo_contained.mli b/otherlibs/labltk/builtin/winfo_contained.mli
index 0baf36ebd..41cc57c0f 100644
--- a/otherlibs/labltk/builtin/winfo_contained.mli
+++ b/otherlibs/labltk/builtin/winfo_contained.mli
@@ -1,2 +1,11 @@
+##ifdef CAMLTK
+
+val contained : int -> int -> widget -> bool
+(** [contained x y w] returns true if (x,y) is in w *)
+
+##else
+
val contained : x:int -> y:int -> 'a widget -> bool
-(* [contained x y w] returns true if (x,y) is in w *)
+(** [contained x y w] returns true if (x,y) is in w *)
+
+##endif
diff --git a/otherlibs/labltk/camltk/.cvsignore b/otherlibs/labltk/camltk/.cvsignore
new file mode 100644
index 000000000..585067641
--- /dev/null
+++ b/otherlibs/labltk/camltk/.cvsignore
@@ -0,0 +1,3 @@
+*.ml *.mli labltktop labltk
+modules
+.depend
diff --git a/otherlibs/labltk/camltk/Makefile b/otherlibs/labltk/camltk/Makefile
new file mode 100644
index 000000000..6477627ae
--- /dev/null
+++ b/otherlibs/labltk/camltk/Makefile
@@ -0,0 +1,47 @@
+include ../support/Makefile.common
+
+COMPFLAGS= -I ../support
+
+TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo
+
+all: camltkobjs
+
+opt: camltkobjsx
+
+include ./modules
+
+CAMLTKOBJS= $(CWIDGETOBJS) cTk.cmo camltk.cmo
+CAMLTKOBJSX = $(CAMLTKOBJS:.cmo=.cmx)
+
+camltkobjs: $(CAMLTKOBJS)
+
+camltkobjsx: $(CAMLTKOBJSX)
+
+# All .{ml,mli} files are generated in this directory
+clean:
+ rm -f *.cm* *.ml *.mli *.o *.a
+ $(MAKE) -f Makefile.gen clean
+
+install: $(CAMLTKOBJS)
+ if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(CAMLTKOBJS:.cmo=.cmi) $(CWIDGETOBJS:.cmo=.mli) $(INSTALLDIR)
+ chmod 644 $(INSTALLDIR)/*.cmi
+
+installopt: $(CAMLTKOBJSX)
+ @if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(CAMLTKOBJSX) $(INSTALLDIR)
+ chmod 644 $(INSTALLDIR)/*.cmx
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+include .depend
diff --git a/otherlibs/labltk/camltk/Makefile.gen b/otherlibs/labltk/camltk/Makefile.gen
new file mode 100644
index 000000000..990627183
--- /dev/null
+++ b/otherlibs/labltk/camltk/Makefile.gen
@@ -0,0 +1,43 @@
+include ../support/Makefile.common
+
+all: cTk.ml camltk.ml .depend
+
+_tkgen.ml: ../Widgets.src ../compiler/tkcompiler
+ cd ..; ../../boot/ocamlrun compiler/tkcompiler -camltk -outdir camltk
+
+cTk.ml camltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../builtin/builtin_*.ml
+ (echo '##define CAMLTK'; \
+ echo 'include Camltkwrap'; \
+ echo 'open Widget'; \
+ echo 'open Protocol'; \
+ echo 'open Textvariable'; \
+ echo ; \
+ cat ../builtin/report.ml; \
+ echo ; \
+ cat ../builtin/builtin_*.ml; \
+ echo ; \
+ cat _tkgen.ml; \
+ echo ; \
+ echo ; \
+ echo 'module Tkintf = struct'; \
+ cat ../builtin/builtini_*.ml; \
+ cat _tkigen.ml; \
+ echo 'end (* module Tkintf *)'; \
+ echo ; \
+ echo ; \
+ echo 'open Tkintf' ;\
+ echo ; \
+ echo ; \
+ cat ../builtin/builtinf_*.ml; \
+ cat _tkfgen.ml; \
+ echo ; \
+ ) > _cTk.ml
+ ../../../boot/ocamlrun ../compiler/pp < _cTk.ml > cTk.ml
+ rm -f _cTk.ml
+ $(CAMLDEP) -I ../support [a-z]*.mli [a-z]*.ml > .depend
+
+../compiler/pp:
+ cd ../compiler; $(MAKE) pp
+
+clean:
+ rm -f modules .depend
diff --git a/otherlibs/labltk/camltk/Makefile.gen.nt b/otherlibs/labltk/camltk/Makefile.gen.nt
new file mode 100644
index 000000000..bee2939db
--- /dev/null
+++ b/otherlibs/labltk/camltk/Makefile.gen.nt
@@ -0,0 +1,43 @@
+!include ..\support\Makefile.common.nt
+
+all: cTk.ml camltk.ml .depend
+
+_tkgen.ml: ..\Widgets.src ..\compiler\tkcompiler.exe
+ cd .. & ..\..\boot\ocamlrun compiler/tkcompiler.exe -camltk -outdir camltk
+
+# dependencies are broken: wouldn't work with gmake 3.77
+
+cTk.ml camltk.ml .depend: _tkgen.ml ..\builtin\report.ml ..\compiler\pp.exe #../builtin/builtin_*.ml
+ type << > _cTk.ml
+##define CAMLTK
+include Camltkwrap
+open Widget
+open Protocol
+open Textvariable
+<<
+ type ..\builtin\report.ml >> _cTk.ml
+ type ..\builtin\builtin_*.ml >> _cTk.ml
+ type _tkgen.ml >> _cTk.ml
+ type << >> _cTk.ml
+
+
+module Tkintf = struct
+<<
+ type ..\builtin\builtini_*.ml >> _cTk.ml
+ type _tkigen.ml >> _cTk.ml
+ type << >> _cTk.ml
+end (* module Tkintf *)
+
+
+open Tkintf
+
+
+<<
+ type ..\builtin\builtinf_*.ml >> _cTk.ml
+ type _tkfgen.ml >> _cTk.ml
+ ..\..\..\boot\ocamlrun ..\compiler\pp.exe < _cTk.ml > cTk.ml
+ rm -f _cTk.ml
+ $(CAMLDEP) -I ..\support *.mli *.ml > .depend
+
+clean:
+ rm -f modules .depend
diff --git a/otherlibs/labltk/camltk/Makefile.nt b/otherlibs/labltk/camltk/Makefile.nt
new file mode 100644
index 000000000..66988797c
--- /dev/null
+++ b/otherlibs/labltk/camltk/Makefile.nt
@@ -0,0 +1,43 @@
+!include ..\support\Makefile.common.nt
+
+COMPFLAGS= -I ../support
+
+all: camltkobjs
+
+opt: camltkobjsx
+
+# All .{ml,mli} files are generated in this directory
+clean :
+ rm -f *.cm* *.ml *.mli *.a *.obj
+ $(MAKE) -f Makefile.gen.nt clean
+
+!include .\modules
+
+CAMLTKOBJS = $(WIDGETOBJS) cTk.cmo camltk.cmo
+CAMLTKOBJSX = $(CAMLTKOBJS:.cmo=.cmx)
+
+camltkobjs: $(CAMLTKOBJS)
+
+camltkobjsx: $(CAMLTKOBJSX)
+
+install: $(CAMLTKOBJS)
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp *.cmi [a-z]*.mli $(INSTALLDIR)
+
+installopt: $(CAMLTKOBJSX)
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp $(CAMLTKOBJSX) $(INSTALLDIR)
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+!include .depend
diff --git a/otherlibs/labltk/compiler/.cvsignore b/otherlibs/labltk/compiler/.cvsignore
index 178a0fab7..060114e62 100644
--- a/otherlibs/labltk/compiler/.cvsignore
+++ b/otherlibs/labltk/compiler/.cvsignore
@@ -3,3 +3,9 @@ parser.output
parser.ml
parser.mli
tkcompiler
+pp
+copyright.ml
+pplex.ml
+ppyac.ml
+ppyac.output
+ppyac.mli
diff --git a/otherlibs/labltk/compiler/.depend b/otherlibs/labltk/compiler/.depend
index 01a938ff5..d33149e8c 100644
--- a/otherlibs/labltk/compiler/.depend
+++ b/otherlibs/labltk/compiler/.depend
@@ -1,15 +1,27 @@
-compile.cmo: tables.cmo
-compile.cmx: tables.cmx
-intf.cmo: compile.cmo tables.cmo
-intf.cmx: compile.cmx tables.cmx
+pplex.cmi: ppyac.cmi
+ppyac.cmi: code.cmi
+compile.cmo: code.cmi flags.cmo ppexec.cmo ppparse.cmo tables.cmo
+compile.cmx: code.cmi flags.cmx ppexec.cmx ppparse.cmx tables.cmx
+intf.cmo: code.cmi compile.cmo flags.cmo ppexec.cmo ppparse.cmo tables.cmo
+intf.cmx: code.cmi compile.cmx flags.cmx ppexec.cmx ppparse.cmx tables.cmx
lexer.cmo: parser.cmi
lexer.cmx: parser.cmx
-maincompile.cmo: compile.cmo intf.cmo lexer.cmo parser.cmi printer.cmo \
- tables.cmo tsort.cmo
-maincompile.cmx: compile.cmx intf.cmx lexer.cmx parser.cmx printer.cmx \
- tables.cmx tsort.cmx
-parser.cmo: tables.cmo parser.cmi
-parser.cmx: tables.cmx parser.cmi
+maincompile.cmo: code.cmi compile.cmo flags.cmo intf.cmo lexer.cmo parser.cmi \
+ ppexec.cmo ppparse.cmo printer.cmo tables.cmo tsort.cmo
+maincompile.cmx: code.cmi compile.cmx flags.cmx intf.cmx lexer.cmx parser.cmx \
+ ppexec.cmx ppparse.cmx printer.cmx tables.cmx tsort.cmx
+parser.cmo: flags.cmo tables.cmo parser.cmi
+parser.cmx: flags.cmx tables.cmx parser.cmi
+pp.cmo: ppexec.cmo ppparse.cmo
+pp.cmx: ppexec.cmx ppparse.cmx
+ppexec.cmo: code.cmi
+ppexec.cmx: code.cmi
+pplex.cmo: ppyac.cmi pplex.cmi
+pplex.cmx: ppyac.cmx pplex.cmi
+ppparse.cmo: pplex.cmi ppyac.cmi
+ppparse.cmx: pplex.cmx ppyac.cmx
+ppyac.cmo: code.cmi ppyac.cmi
+ppyac.cmx: code.cmi ppyac.cmi
printer.cmo: tables.cmo
printer.cmx: tables.cmx
tables.cmo: tsort.cmo
diff --git a/otherlibs/labltk/compiler/Makefile b/otherlibs/labltk/compiler/Makefile
index 302ad2588..a2b845331 100644
--- a/otherlibs/labltk/compiler/Makefile
+++ b/otherlibs/labltk/compiler/Makefile
@@ -1,36 +1,63 @@
include ../support/Makefile.common
-OBJS= ../support/support.cmo tsort.cmo tables.cmo printer.cmo lexer.cmo \
+OBJS= ../support/support.cmo flags.cmo copyright.cmo \
+ tsort.cmo tables.cmo printer.cmo lexer.cmo \
+ pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo \
parser.cmo compile.cmo intf.cmo maincompile.cmo
-tkcompiler : $(OBJS)
- $(LABLC) $(LINKFLAGS) -o tkcompiler $(OBJS)
+PPOBJS= pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo pp.cmo
+
+all: tkcompiler$(EXE) pp$(EXE)
+
+tkcompiler$(EXE) : $(OBJS)
+ $(CAMLC) -g $(LINKFLAGS) -o tkcompiler$(EXE) $(OBJS)
+
+pp$(EXE): $(PPOBJS)
+ $(CAMLC) -g $(LINKFLAGS) -o pp$(EXE) $(PPOBJS)
lexer.ml: lexer.mll
- $(LABLLEX) lexer.mll
+ $(CAMLLEX) lexer.mll
parser.ml parser.mli: parser.mly
- $(LABLYACC) -v parser.mly
+ $(CAMLYACC) -v parser.mly
+
+pplex.ml: pplex.mll
+ $(CAMLLEX) pplex.mll
+
+pplex.mli: ppyac.cmi
+
+ppyac.ml ppyac.mli: ppyac.mly
+ $(CAMLYACC) -v ppyac.mly
+
+copyright.ml: copyright
+ (echo "let copyright=\"\\"; \
+ cat copyright; \
+ echo "\""; \
+ echo "let write ~w = w copyright;;") > copyright.ml
clean :
- rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler parser.output
+ rm -f *.cm* parser.ml parser.mli lexer.ml copyright.ml
+ rm -f pplex.ml ppyac.ml ppyac.mli ppyac.output
+ rm -f tkcompiler$(EXE) pp$(EXE) parser.output
scratch :
- rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler
+ rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler$(EXE)
+ rm -f *.cm* pplex.ml ppyac.ml ppyac.mli pp$(EXE)
install:
- cp tkcompiler $(LABLTKDIR)
+ cp tkcompiler$(EXE) $(INSTALLDIR)
+ cp pp$(EXE) $(INSTALLDIR)
.SUFFIXES :
.SUFFIXES : .mli .ml .cmi .cmo .mlp
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) -I ../support $<
+ $(CAMLCOMP) -g $(COMPFLAGS) -I ../support $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) -I ../support $<
+ $(CAMLCOMP) -g $(COMPFLAGS) -I ../support $<
-depend: parser.ml parser.mli lexer.ml
- $(LABLDEP) *.mli *.ml > .depend
+depend: parser.ml parser.mli lexer.ml pplex.ml ppyac.ml ppyac.mli
+ $(CAMLDEP) *.mli *.ml > .depend
include .depend
diff --git a/otherlibs/labltk/compiler/Makefile.nt b/otherlibs/labltk/compiler/Makefile.nt
index d211c548a..4a18e8ee5 100644
--- a/otherlibs/labltk/compiler/Makefile.nt
+++ b/otherlibs/labltk/compiler/Makefile.nt
@@ -1,36 +1,68 @@
!include ..\support\Makefile.common.nt
-OBJS= ../support/support.cmo tsort.cmo tables.cmo lexer.cmo parser.cmo \
- compile.cmo intf.cmo printer.cmo maincompile.cmo
+OBJS= ../support/support.cmo flags.cmo copyright.cmo \
+ tsort.cmo tables.cmo printer.cmo lexer.cmo \
+ pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo \
+ parser.cmo compile.cmo intf.cmo maincompile.cmo
-tkcompiler : $(OBJS)
- $(LABLC) $(LINKFLAGS) -o tkcompiler $(OBJS)
+PPOBJS= pplex.cmo ppyac.cmo ppexec.cmo ppparse.cmo pp.cmo
+
+all: tkcompiler.exe pp.exe
+
+tkcompiler.exe : $(OBJS)
+ $(CAMLC) $(LINKFLAGS) -o tkcompiler.exe $(OBJS)
+
+pp.exe : $(PPOBJS)
+ $(CAMLC) $(LINKFLAGS) -o pp.exe $(PPOBJS)
lexer.ml: lexer.mll
- $(LABLLEX) lexer.mll
+ $(CAMLLEX) lexer.mll
parser.ml parser.mli: parser.mly
- $(LABLYACC) -v parser.mly
+ $(CAMLYACC) -v parser.mly
+
+pplex.ml: pplex.mll
+ $(CAMLLEX) pplex.mll
+
+pplex.mli: ppyac.cmi
+
+ppyac.ml ppyac.mli: ppyac.mly
+ $(CAMLYACC) -v ppyac.mly
+
+copyright.ml: copyright
+ type << > copyright.ml
+let copyright="
+<<
+ type copyright >> copyright.ml
+ type << >> copyright.ml
+"
+
+let write ~w = w copyright;;
+<<
clean :
- rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler parser.output
+ rm -f *.cm* parser.ml parser.mli lexer.ml copyright.ml
+ rm -f pplex.ml ppyac.ml ppyac.mli ppyac.output
+ rm -f tkcompiler.exe pp.exe parser.output
scratch :
- rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler
+ rm -f *.cm* parser.ml parser.mli lexer.ml tkcompiler.exe
+ rm -f *.cm* pplex.ml ppyac.ml ppyac.mli pp.exe
install:
- cp tkcompiler $(LABLTKDIR)
+ cp tkcompiler.exe $(INSTALLDIR)
+ cp pp.exe $(INSTALLDIR)
.SUFFIXES :
.SUFFIXES : .mli .ml .cmi .cmo .mlp
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) -I ../support $<
+ $(CAMLCOMP) $(COMPFLAGS) -I ../support $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) -I ../support $<
+ $(CAMLCOMP) $(COMPFLAGS) -I ../support $<
-depend: parser.ml parser.mli lexer.ml
- $(LABLDEP) *.mli *.ml > .depend
+depend: parser.ml parser.mli lexer.ml pplex.ml ppyac.ml ppyac.mli
+ $(CAMLDEP) *.mli *.ml > .depend
!include .depend
diff --git a/otherlibs/labltk/compiler/code.mli b/otherlibs/labltk/compiler/code.mli
new file mode 100644
index 000000000..6f3e29213
--- /dev/null
+++ b/otherlibs/labltk/compiler/code.mli
@@ -0,0 +1,22 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+type code =
+ | Line of string
+ | Ifdef of bool * string * code list * code list option
+ | Define of string
+ | Undef of string
+;;
diff --git a/otherlibs/labltk/compiler/compile.ml b/otherlibs/labltk/compiler/compile.ml
index 1b496ec92..78adbcee6 100644
--- a/otherlibs/labltk/compiler/compile.ml
+++ b/otherlibs/labltk/compiler/compile.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -27,14 +27,30 @@ let labeloff ~at l = match l with
"", t -> t
| l, t -> raise (Failure ("labeloff: " ^ l ^ " at " ^ at))
-let labelstring l =
+let labltk_labelstring l =
if l = "" then l else
if l.[0] = '?' then l ^ ":" else
"~" ^ l ^ ":"
-let typelabel l =
+let camltk_labelstring l =
+ if l = "" then l else
+ if l.[0] = '?' then l ^ ":" else ""
+
+let labelstring l =
+ if !Flags.camltk then camltk_labelstring l
+ else labltk_labelstring l
+
+let labltk_typelabel l =
if l = "" then l else l ^ ":"
+let camltk_typelabel l =
+ if l = "" then l
+ else if l.[0] = '?' then l ^ ":" else ""
+
+let typelabel l =
+ if !Flags.camltk then camltk_typelabel l
+ else labltk_typelabel l
+
let forbidden = [ "class"; "type"; "in"; "from"; "to" ]
let nicknames =
[ "class", "clas";
@@ -70,8 +86,8 @@ let rec types_of_template = function
| TypeArg (l, t) -> [l, t]
| ListArg l -> List.flatten (List.map ~f:types_of_template l)
| OptionalArgs (l, tl, _) ->
- begin
- match List.flatten (List.map ~f:types_of_template tl) with
+ begin
+ match List.flatten (List.map ~f:types_of_template tl) with
["", t] -> ["?" ^ l, t]
| [_, _] -> raise (Failure "0 label required")
| _ -> raise (Failure "0 or more than 1 args in for optionals")
@@ -92,74 +108,81 @@ let ppMLtype ?(any=false) ?(return=false) ?(def=false) ?(counter=ref 0) =
| String -> "string"
(* new *)
| List (Subtype (sup, sub)) ->
- if return then
- sub ^ "_" ^ sup ^ " list"
- else
- begin
- try
- let typdef = Hashtbl.find types_table sup in
- let fcl = List.assoc sub typdef.subtypes in
- let tklabels = List.map ~f:gettklabel fcl in
- let l = List.map fcl ~f:
- begin fun fc ->
- "?" ^ begin let p = gettklabel fc in
- if count ~item:p tklabels > 1 then small fc.var_name else p
- end
- ^ ":" ^
- let l = types_of_template fc.template in
- match l with
- [] -> "unit"
- | [lt] -> ppMLtype (labeloff lt ~at:"ppMLtype")
- | l ->
- "(" ^ String.concat ~sep:"*"
- (List.map l
- ~f:(fun lt -> ppMLtype (labeloff lt ~at:"ppMLtype")))
- ^ ")"
- end in
- String.concat ~sep:" ->\n" l
- with
- Not_found -> Printf.eprintf "ppMLtype %s/%s\n" sup sub; exit (-1)
- end
+ if !Flags.camltk then "(* " ^ sub ^ " *) " ^ sup ^ " list"
+ else begin
+ if return then
+ sub ^ "_" ^ sup ^ " list"
+ else begin
+ try
+ let typdef = Hashtbl.find types_table sup in
+ let fcl = List.assoc sub typdef.subtypes in
+ let tklabels = List.map ~f:gettklabel fcl in
+ let l = List.map fcl ~f:
+ begin fun fc ->
+ "?" ^ begin let p = gettklabel fc in
+ if count ~item:p tklabels > 1 then small fc.var_name else p
+ end
+ ^ ":" ^
+ let l = types_of_template fc.template in
+ match l with
+ [] -> "unit"
+ | [lt] -> ppMLtype (labeloff lt ~at:"ppMLtype")
+ | l ->
+ "(" ^ String.concat ~sep:"*"
+ (List.map l
+ ~f:(fun lt -> ppMLtype (labeloff lt ~at:"ppMLtype")))
+ ^ ")"
+ end in
+ String.concat ~sep:" ->\n" l
+ with
+ Not_found -> Printf.eprintf "ppMLtype %s/%s\n" sup sub; exit (-1)
+ end
+ end
| List ty -> (ppMLtype ty) ^ " list"
| Product tyl ->
"(" ^ String.concat ~sep:" * " (List.map ~f:ppMLtype tyl) ^ ")"
| Record tyl ->
String.concat ~sep:" * "
(List.map tyl ~f:(fun (l, t) -> typelabel l ^ ppMLtype t))
- | Subtype ("widget", sub) -> sub ^ " widget"
+ | Subtype ("widget", sub) ->
+ if !Flags.camltk then "(* " ^ sub ^" *) widget" else sub ^ " widget"
| UserDefined "widget" ->
- if any then "any widget" else
- let c = String.make 1 (Char.chr(Char.code 'a' + !counter))
- in
- incr counter;
- "'" ^ c ^ " widget"
+ if !Flags.camltk then "widget"
+ else begin
+ if any then "any widget" else
+ let c = String.make 1 (Char.chr(Char.code 'a' + !counter)) in
+ incr counter;
+ "'" ^ c ^ " widget"
+ end
| UserDefined s ->
- (* a bit dirty hack for ImageBitmap and ImagePhoto *)
- begin
- try
- let typdef = Hashtbl.find types_table s in
- if typdef.variant then
- if return then try
- "[>" ^
- String.concat ~sep:"|"
- (List.map typdef.constructors ~f:
- begin
- fun c ->
- "`" ^ c.var_name ^
- (match types_of_template c.template with
- [] -> ""
- | l -> " of " ^ ppMLtype (Product (List.map l
- ~f:(labeloff ~at:"ppMLtype UserDefined"))))
- end) ^ "]"
- with
- Not_found -> prerr_endline ("ppMLtype " ^ s ^ " ?"); s
- else if not def && List.length typdef.constructors > 1 then
- "[< " ^ s ^ "]"
+ if !Flags.camltk then s
+ else begin
+ (* a bit dirty hack for ImageBitmap and ImagePhoto *)
+ try
+ let typdef = Hashtbl.find types_table s in
+ if typdef.variant then
+ if return then try
+ "[>" ^
+ String.concat ~sep:"|"
+ (List.map typdef.constructors ~f:
+ begin
+ fun c ->
+ "`" ^ c.var_name ^
+ (match types_of_template c.template with
+ [] -> ""
+ | l -> " of " ^ ppMLtype (Product (List.map l
+ ~f:(labeloff ~at:"ppMLtype UserDefined"))))
+ end) ^ "]"
+ with
+ Not_found -> prerr_endline ("ppMLtype " ^ s ^ " ?"); s
+ else if not def && List.length typdef.constructors > 1 then
+ "[< " ^ s ^ "]"
+ else s
else s
- else s
- with Not_found -> s
- end
- | Subtype (s, s') -> s' ^ "_" ^ s
+ with Not_found -> s
+ end
+ | Subtype (s, s') ->
+ if !Flags.camltk then "(* " ^ s' ^ " *) " ^ s else s' ^ "_" ^ s
| Function (Product tyl) ->
raise (Failure "Function (Product tyl) ? ppMLtype")
| Function (Record tyl) ->
@@ -168,7 +191,9 @@ let ppMLtype ?(any=false) ?(return=false) ?(def=false) ?(counter=ref 0) =
^ " -> unit)"
| Function ty ->
"(" ^ (ppMLtype ty) ^ " -> unit)"
- | As (_, s) -> s
+ | As (t, s) ->
+ if !Flags.camltk then ppMLtype t
+ else s
in
ppMLtype
@@ -207,7 +232,7 @@ let write_constructors ~w = function
write_constructor ~w x;
List.iter l ~f:
begin fun x ->
- w "\n | ";
+ w "\n | ";
write_constructor ~w x
end
@@ -229,12 +254,12 @@ let write_variants ~w = function
| l ->
List.iter l ~f:
begin fun x ->
- w "\n | ";
+ w "\n | ";
write_variant ~w x
end
(* Definition of a type *)
-let write_type ~intf:w ~impl:w' name ~def:typdef =
+let labltk_write_type ~intf:w ~impl:w' name ~def:typdef =
(* Only needed if no subtypes, otherwise use optionals *)
if typdef.subtypes = [] then begin
w "(* Variant type *)\n";
@@ -243,6 +268,54 @@ let write_type ~intf:w ~impl:w' name ~def:typdef =
w "\n]\n\n"
end
+(* CamlTk: List of constructors, for runtime subtyping *)
+let write_constructor_set ~w ~sep = function
+ | [] -> fatal_error "empty type"
+ | x::l ->
+ w ("C" ^ x.ml_name);
+ List.iter l ~f: (function x ->
+ w sep;
+ w ("C" ^ x.ml_name))
+
+(* CamlTk: Definition of a type *)
+let camltk_write_type ~intf:w ~impl:w' name ~def:typdef =
+ (* Put markers for extraction *)
+ w "(* type *)\n";
+ w ("type " ^ name ^ " =\n");
+ w " | ";
+ write_constructors ~w (sort_components typdef.constructors);
+ w "\n\n";
+ (* Dynamic Subtyping *)
+ if typdef.subtypes <> [] then begin
+ (* The set of its constructors *)
+ if name = "options" then begin
+ w "(* type *)\n";
+ w ("type "^name^"_constrs =\n\t")
+ end else begin
+ (* added some prefix to avoid being picked up in documentation *)
+ w ("(* no doc *) type "^name^"_constrs =\n")
+ end;
+ w " | ";
+ write_constructor_set ~w:w ~sep: "\n | "
+ (sort_components typdef.constructors);
+ w "\n\n";
+ (* The set of all constructors *)
+ w' ("let "^name^"_any_table = [");
+ write_constructor_set ~w:w' ~sep:"; "
+ (sort_components typdef.constructors);
+ w' ("]\n\n");
+ (* The subset of constructors for each subtype *)
+ List.iter ~f:(function (s,l) ->
+ w' ("let "^name^"_"^s^"_table = [");
+ write_constructor_set ~w:w' ~sep:"; " (sort_components l);
+ w' ("]\n\n"))
+ typdef.subtypes
+ end
+
+let write_type ~intf:w ~impl:w' name ~def:typdef =
+ (if !Flags.camltk then camltk_write_type else labltk_write_type)
+ ~intf:w ~impl:w' name ~def:typdef
+
(************************************************************)
(* Converters *)
(************************************************************)
@@ -257,10 +330,14 @@ let rec converterTKtoCAML ~arg = function
| Char -> "String.get " ^ arg ^ " 0"
| String -> arg
| UserDefined s -> "cTKtoCAML" ^ s ^ " " ^ arg
- | Subtype ("widget", s') ->
+ | Subtype ("widget", s') when not !Flags.camltk ->
String.concat ~sep:" "
["(Obj.magic (cTKtoCAMLwidget "; arg; ") :"; s'; "widget)"]
- | Subtype (s, s') -> "cTKtoCAML" ^ s' ^ "_" ^ s ^ " " ^ arg
+ | Subtype (s, s') ->
+ if !Flags.camltk then
+ "cTKtoCAML" ^ s ^ " " ^ arg
+ else
+ "cTKtoCAML" ^ s' ^ "_" ^ s ^ " " ^ arg
| List ty ->
begin match type_parser_arity ty with
OneToken ->
@@ -322,7 +399,9 @@ let rec wrapper_code ~name ty =
end in
String.concat ~sep:"" readarg ^ name ^ " " ^
String.concat ~sep:" "
- (List.map2 ~f:(fun v (l, _) -> labelstring l ^ v) vnames tyl)
+ (List.map2 ~f:(fun v (l, _) ->
+ if !Flags.camltk then v
+ else labelstring l ^ v) vnames tyl)
(* all other types are read in one operation *)
| List ty ->
@@ -364,16 +443,17 @@ let can_generate_parser constructors =
let pp = {zeroary = []; intpar = []; stringpar = []} in
if List.for_all constructors ~f:
begin fun c ->
+ let vname = if !Flags.camltk then c.ml_name else c.var_name in
match c.template with
ListArg [StringArg s] ->
- pp.zeroary <- (s, "`" ^ c.var_name) ::
+ pp.zeroary <- (s, vname) ::
pp.zeroary; true
| ListArg [TypeArg(_, Int)] | ListArg[TypeArg(_, Float)] ->
if pp.intpar <> [] then false
- else (pp.intpar <- ["`" ^ c.var_name]; true)
+ else (pp.intpar <- [vname]; true)
| ListArg [TypeArg(_, String)] ->
if pp.stringpar <> [] then false
- else (pp.stringpar <- ["`" ^ c.var_name]; true)
+ else (pp.stringpar <- [vname]; true)
| _ -> false
end
then ParserPieces pp
@@ -382,7 +462,46 @@ let can_generate_parser constructors =
(* We can generate parsers only for simple types *)
(* we should avoid multiple walks *)
-let write_TKtoCAML ~w name ~def:typdef =
+let labltk_write_TKtoCAML ~w name ~def:typdef =
+ if typdef.parser_arity = MultipleToken then
+ prerr_string ("You must write cTKtoCAML" ^ name ^
+ " : string list ->" ^ name ^ " * string list\n")
+ else
+ let write ~consts ~name =
+ match can_generate_parser consts with
+ NoParser ->
+ prerr_string
+ ("You must write cTKtoCAML" ^ name ^ " : string ->" ^ name ^ "\n")
+ | ParserPieces pp ->
+ w ("let cTKtoCAML" ^ name ^ " n =\n");
+ (* First check integer *)
+ if pp.intpar <> [] then
+ begin
+ w (" try `" ^ List.hd pp.intpar ^ " (int_of_string n)\n");
+ w (" with _ ->\n")
+ end;
+ w (" match n with\n");
+ List.iter pp.zeroary ~f:
+ begin fun (tk, ml) ->
+ w " | \""; w tk; w "\" -> `"; w ml; w "\n"
+ end;
+ let final = if pp.stringpar <> [] then
+ "n -> `" ^ List.hd pp.stringpar ^ " n"
+ else "s -> Pervasives.raise (Invalid_argument (\"cTKtoCAML"
+ ^ name ^ ": \" ^ s))"
+ in
+ w " | ";
+ w final;
+ w "\n\n"
+ in
+ begin
+ write ~name ~consts:typdef.constructors;
+ List.iter typdef.subtypes ~f: begin
+ fun (subname, consts) -> write ~name:(subname ^ "_" ^ name) ~consts
+ end
+ end
+
+let camltk_write_TKtoCAML ~w name ~def:typdef =
if typdef.parser_arity = MultipleToken then
prerr_string ("You must write cTKtoCAML" ^ name ^
" : string list ->" ^ name ^ " * string list\n")
@@ -421,6 +540,10 @@ let write_TKtoCAML ~w name ~def:typdef =
end
end
+let write_TKtoCAML ~w name ~def:typdef =
+ (if !Flags.camltk then camltk_write_TKtoCAML else labltk_write_TKtoCAML)
+ ~w name ~def: typdef
+
(******************************)
(* Converters *)
(******************************)
@@ -439,19 +562,43 @@ let rec converterCAMLtoTK ~context_widget argname ty =
let name = "cCAMLtoTK" ^ s ^ " " in
let args = argname in
let args =
+ if !Flags.camltk then begin
+ if is_subtyped s then (* unconstraint subtype *)
+ s ^ "_any_table " ^ args
+ else args
+ end else args
+ in
+ let args =
if requires_widget_context s then
context_widget ^ " " ^ args
else args in
name ^ args
| Subtype ("widget", s') ->
- let name = "cCAMLtoTKwidget" in
- let args = "(" ^ argname ^ " : " ^ s' ^ " widget)" in
- name ^ args
+ if !Flags.camltk then
+ let name = "cCAMLtoTKwidget " in
+ let args = "widget_"^s'^"_table "^argname in
+ let args =
+ if requires_widget_context "widget" then
+ context_widget^" "^args
+ else args in
+ name^args
+ else begin
+ let name = "cCAMLtoTKwidget " in
+ let args = "(" ^ argname ^ " : " ^ s' ^ " widget)" in
+ name ^ args
+ end
| Subtype (s, s') ->
- let name = "cCAMLtoTK" ^ s' ^ "_" ^ s ^ " " in
+ let name =
+ if !Flags.camltk then "cCAMLtoTK" ^ s ^ " "
+ else "cCAMLtoTK" ^ s' ^ "_" ^ s ^ " "
+ in
let args =
- if safetype then "(" ^ argname ^ " : [< " ^ s' ^ "_" ^ s ^ "])"
- else argname
+ if !Flags.camltk then begin
+ s^"_"^s'^"_table "^argname
+ end else begin
+ if safetype then "(" ^ argname ^ " : [< " ^ s' ^ "_" ^ s ^ "])"
+ else argname
+ end
in
let args =
if requires_widget_context s then context_widget ^ " " ^ args
@@ -499,15 +646,22 @@ let code_of_template ~context_widget ?func:(funtemplate=false) template =
let newvar = ref newvar1 in
let rec coderec = function
StringArg s -> "TkToken \"" ^ s ^ "\""
- | TypeArg (_, List (Subtype (sup, sub) as ty)) ->
- let typdef = Hashtbl.find types_table sup in
- let classdef = List.assoc sub typdef.subtypes in
- let lbl = gettklabel (List.hd classdef) in
- catch_opts := (sub ^ "_" ^ sup, lbl);
- newvar := newvar2;
- "TkTokenList opts"
+ | TypeArg (_, List (Subtype (sup, sub) as ty)) when not !Flags.camltk ->
+ begin try
+ let typdef = Hashtbl.find types_table sup in
+ let classdef = List.assoc sub typdef.subtypes in
+ let lbl = gettklabel (List.hd classdef) in
+ catch_opts := (sub ^ "_" ^ sup, lbl);
+ newvar := newvar2;
+ "TkTokenList opts"
+ with Not_found ->
+ raise (Failure (Printf.sprintf "type %s(%s) not found" sup sub));
+ end
| TypeArg (l, List ty) ->
- "TkTokenList (List.map ~f:(function x -> "
+ (if !Flags.camltk then
+ "TkTokenList (List.map (function x -> "
+ else
+ "TkTokenList (List.map ~f:(function x -> ")
^ converterCAMLtoTK ~context_widget "x" ty
^ ") " ^ !newvar l ^ ")"
| TypeArg (l, Function tyarg) ->
@@ -549,7 +703,7 @@ let code_of_template ~context_widget ?func:(funtemplate=false) template =
*)
(* For each case of a concrete type *)
-let write_clause ~w ~context_widget comp =
+let labltk_write_clause ~w ~context_widget comp =
let warrow () = w " -> " in
w "`";
w comp.var_name;
@@ -570,9 +724,39 @@ let write_clause ~w ~context_widget comp =
end;
w code
+let camltk_write_clause ~w ~context_widget ~subtype comp =
+ let warrow () =
+ w " -> ";
+ if subtype then
+ w ("chk_sub \""^comp.ml_name^"\" table C" ^ comp.ml_name ^ "; ")
+ in
+
+ w comp.ml_name; (* we use ml_name, not var_name, specialized for labltk *)
+
+ let code, variables, variables2, (co, _) =
+ code_of_template ~context_widget comp.template in
+
+ (* no subtype I think ... *)
+ if co <> "" then raise (Failure "write_clause subtype ?");
+ begin match variables with
+ | [] -> warrow()
+ | [x] -> w " "; w (labeloff x ~at:"write_clause"); warrow()
+ | l ->
+ w " ( ";
+ w (String.concat ~sep:", " (List.map ~f:(labeloff ~at:"write_clause") l));
+ w ")";
+ warrow()
+ end;
+ w code
+
+let write_clause ~w ~context_widget ~subtype comp =
+ if !Flags.camltk then camltk_write_clause ~w ~context_widget ~subtype comp
+ else labltk_write_clause ~w ~context_widget comp
+
(* The full converter *)
let write_CAMLtoTK ~w ~def:typdef ?safetype:(st = true) name =
let write_one name constrs =
+ let subtype = typdef.subtypes <> [] in
w ("let cCAMLtoTK" ^ name);
let context_widget =
if typdef.requires_widget_context then begin
@@ -580,6 +764,7 @@ let write_CAMLtoTK ~w ~def:typdef ?safetype:(st = true) name =
end
else
"dummy" in
+ if !Flags.camltk && subtype then w " table";
if st then begin
w " : ";
if typdef.variant then w ("[< " ^ name ^ "]") else w name;
@@ -587,32 +772,38 @@ let write_CAMLtoTK ~w ~def:typdef ?safetype:(st = true) name =
end;
w (" = function");
List.iter constrs
- ~f:(fun c -> w "\n | "; write_clause ~w ~context_widget c);
+ ~f:(fun c -> w "\n | "; write_clause ~w ~context_widget ~subtype c);
w "\n\n\n"
in
- (* Only needed if no subtypes, otherwise use optionals *)
let constrs = typdef.constructors in
- if typdef.subtypes == [] then
- write_one name constrs
- else
- List.iter constrs ~f:
- begin fun fc ->
- let code, vars, _, (co, _) =
- code_of_template ~context_widget:"dummy" fc.template in
- if co <> "" then fatal_error "optionals in optionals";
- let vars = List.map ~f:snd vars in
- w "let ccCAMLtoTK"; w name; w "_"; w (small fc.ml_name);
- w " ("; w (String.concat ~sep:", " vars); w ") =\n ";
- w code; w "\n\n"
- end
+ if !Flags.camltk then write_one name constrs
+ else begin
+ (* Only needed if no subtypes, otherwise use optionals *)
+ if typdef.subtypes == [] then
+ write_one name constrs
+ else
+ List.iter constrs ~f:
+ begin fun fc ->
+ let code, vars, _, (co, _) =
+ code_of_template ~context_widget:"dummy" fc.template in
+ if co <> "" then fatal_error "optionals in optionals";
+ let vars = List.map ~f:snd vars in
+ w "let ccCAMLtoTK"; w name; w "_"; w (small fc.ml_name);
+ w " ("; w (String.concat ~sep:", " vars); w ") =\n ";
+ w code; w "\n\n"
+ end
+ end
(* Tcl does not really return "lists". It returns sp separated tokens *)
let rec write_result_parsing ~w = function
List String ->
w "(splitlist res)"
| List ty ->
- w (" List.map ~f: " ^ converterTKtoCAML ~arg:"(splitlist res)" ty)
+ if !Flags.camltk then
+ w (" List.map " ^ converterTKtoCAML ~arg:"(splitlist res)" ty)
+ else
+ w (" List.map ~f: " ^ converterTKtoCAML ~arg:"(splitlist res)" ty)
| Product tyl -> raise (Failure "Product -> record was done. ???")
| Record tyl -> (* of course all the labels are "" *)
let rnames = varnames ~prefix:"r" (List.length tyl) in
@@ -641,7 +832,7 @@ let rec write_result_parsing ~w = function
OneToken -> w (converterTKtoCAML ~arg:"res" ty)
| MultipleToken -> w (converterTKtoCAML ~arg:"(splitlist res)" ty)
-let write_function ~w def =
+let labltk_write_function ~w def =
w ("let " ^ def.ml_name);
(* a bit approximative *)
let context_widget = match def.template with
@@ -690,8 +881,86 @@ let write_function ~w def =
if co <> "" then w ")";
w "\n\n"
-let write_create ~w clas =
- (w "let create ?name =\n" : unit);
+let camltk_write_function ~w def =
+ w ("let " ^ def.ml_name);
+ (* a bit approximative *)
+ let context_widget = match def.template with
+ ListArg (TypeArg(_, UserDefined("widget")) :: _) -> "v1"
+ | ListArg (TypeArg(_, Subtype("widget", _)) :: _) -> "v1"
+ | _ -> "dummy" in
+
+ let code, variables, variables2, (co, lbl) =
+ code_of_template ~func:true ~context_widget def.template in
+ (* Arguments *)
+ let uv, ov =
+ let rec replace_args ~u ~o = function
+ [] -> u, o
+ | ("", x) :: ls ->
+ replace_args ~u:(x :: u) ~o ls
+ | (p, _ as x) :: ls when p.[0] = '?' ->
+ replace_args ~u ~o:(x :: o) ls
+ | (_,x) :: ls ->
+ replace_args ~u:(x::u) ~o ls
+ in
+ replace_args ~u:[] ~o:[] (List.rev (variables @ variables2))
+ in
+ let has_opts = ov <> [] (* (ov <> [] || co <> "") *) in
+ if not has_opts then List.iter uv ~f:(fun x -> w " "; w x);
+ List.iter ov ~f:(fun (l, v) -> w " "; w (labelstring l); w v);
+ begin
+ if uv = [] then w " ()" else
+ if has_opts then List.iter uv ~f:(fun x -> w " "; w x);
+ w " =\n"
+ end;
+ begin match def.result with
+ | Unit | As (Unit, _) -> w "tkCommand "; w code
+ | ty ->
+ w "let res = tkEval "; w code ; w " in \n";
+ write_result_parsing ~w ty
+ end;
+ w "\n\n"
+
+(*
+ w ("let " ^ def.ml_name);
+ (* a bit approximative *)
+ let context_widget = match def.template with
+ ListArg (TypeArg(_, UserDefined("widget")) :: _) -> "v1"
+ | ListArg (TypeArg(_, Subtype("widget", _)) :: _) -> "v1"
+ | _ -> "dummy" in
+
+ let code, variables, variables2, (co, lbl) =
+ code_of_template ~func:true ~context_widget def.template in
+ let variables = variables @ variables2 in
+ (* Arguments *)
+ begin match variables with
+ [] -> w " () =\n"
+ | l ->
+ let has_normal_argument = ref false in
+ List.iter (fun (l,x) ->
+ w " ";
+ if l <> "" then
+ if l.[0] = '?' then w (l ^ ":") else has_normal_argument := true
+ else has_normal_argument := true;
+ w x) l;
+ if not !has_normal_argument then w " ()";
+ w " =\n"
+ end;
+ begin match def.result with
+ | Unit | As (Unit, _) -> w "tkCommand "; w code
+ | ty ->
+ w "let res = tkEval "; w code ; w " in \n";
+ write_result_parsing ~w ty
+ end;
+ w "\n\n"
+*)
+
+let write_function ~w def =
+ if !Flags.camltk then camltk_write_function ~w def
+ else labltk_write_function ~w def
+;;
+
+let labltk_write_create ~w clas =
+ w ("let create ?name =\n");
w (" " ^ clas ^ "_options_optionals (fun opts parent ->\n");
w (" let w = new_atom \"" ^ clas ^ "\" ~parent ?name in\n");
w " tkCommand [|";
@@ -700,6 +969,28 @@ let write_create ~w clas =
w (" TkTokenList opts |];\n");
w (" w)\n\n\n")
+let camltk_write_create ~w clas =
+ w ("let create ?name parent options =\n");
+ w (" let w = new_atom \"" ^ clas ^ "\" ~parent ?name in\n");
+ w " tkCommand [|";
+ w ("TkToken \"" ^ clas ^ "\";\n");
+ w (" TkToken (Widget.name w);\n");
+ w (" TkTokenList (List.map (function x -> "^
+ converterCAMLtoTK "w" "x" (Subtype("options",clas)) ^ ") options)\n");
+ w (" |];\n");
+ w (" w\n\n")
+
+let camltk_write_named_create ~w clas =
+ w ("let create_named parent name options =\n");
+ w (" let w = new_atom \"" ^ clas ^ "\" ~parent ~name in\n");
+ w " tkCommand [|";
+ w ("TkToken \"" ^ clas ^ "\";\n");
+ w (" TkToken (Widget.name w);\n");
+ w (" TkTokenList (List.map (function x -> "^
+ converterCAMLtoTK "w" "x" (Subtype("options",clas)) ^ ") options)\n");
+ w (" |];\n");
+ w (" w\n\n")
+
(* Search Path. *)
let search_path = ref ["."]
@@ -724,19 +1015,21 @@ let write_external ~w def =
begin try
let realname = find_in_path !search_path (fname ^ ".ml") in
let ic = open_in_bin realname in
- begin try
- while true do
- w (input_line ic);
- w "\n"
- done
- with
- | End_of_file -> close_in ic
- end
+ try
+ let code_list = Ppparse.parse_channel ic in
+ close_in ic;
+ List.iter (Ppexec.exec (fun _ -> ()) w)
+ (if !Flags.camltk then
+ Code.Define "CAMLTK" :: code_list else code_list );
+ with
+ | Ppparse.Error s ->
+ close_in ic;
+ raise (Compiler_Error (Printf.sprintf "Preprocess error: %s" s))
with
| Not_found ->
raise (Compiler_Error ("can't find external file: " ^ fname))
end
-| _ -> raise (Compiler_Error "invalid external definition")
+ | _ -> raise (Compiler_Error "invalid external definition")
let write_catch_optionals ~w clas ~def:typdef =
if typdef.subtypes = [] then () else
diff --git a/otherlibs/labltk/compiler/copyright b/otherlibs/labltk/compiler/copyright
new file mode 100644
index 000000000..23dff46dc
--- /dev/null
+++ b/otherlibs/labltk/compiler/copyright
@@ -0,0 +1,15 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
diff --git a/otherlibs/labltk/compiler/flags.ml b/otherlibs/labltk/compiler/flags.ml
new file mode 100644
index 000000000..009d5e725
--- /dev/null
+++ b/otherlibs/labltk/compiler/flags.ml
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+let camltk = ref false;;
diff --git a/otherlibs/labltk/compiler/intf.ml b/otherlibs/labltk/compiler/intf.ml
index 9e262ede6..e155ec5ee 100644
--- a/otherlibs/labltk/compiler/intf.ml
+++ b/otherlibs/labltk/compiler/intf.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -23,7 +23,7 @@ open StdLabels
open Tables
open Compile
-let write_create_p ~w wname =
+let labltk_write_create_p ~w wname =
w "val create :\n ?name:string ->\n";
begin
try
@@ -50,13 +50,27 @@ let write_create_p ~w wname =
with Not_found -> fatal_error "in write_create_p"
end;
w (" ->\n 'a widget -> " ^ wname ^ " widget\n");
- w " (* [create p options ?name] creates a new widget with\n";
- w " parent p and new patch component name.\n";
- w " Options are restricted to the widget class subset,\n";
- w " and checked dynamically. *)\n"
+ w "(** [create ?name parent options...] creates a new widget with\n";
+ w " parent [parent] and new patch component [name], if specified. *)\n\n"
+;;
+
+let camltk_write_create_p ~w wname =
+ w "val create : ?name: string -> widget -> options list -> widget \n";
+ w "(** [create ?name parent options] creates a new widget with\n";
+ w " parent [parent] and new patch component [name] if specified.\n";
+ w " Options are restricted to the widget class subset, and checked\n";
+ w " dynamically. *)\n\n"
+;;
+
+let camltk_write_named_create_p ~w wname =
+ w "val create_named : widget -> string -> options list -> widget \n";
+ w "(** [create_named parent name options] creates a new widget with\n";
+ w " parent [parent] and new patch component [name].\n";
+ w " This function is now obsolete and unified with [create]. *)\n\n";
+;;
(* Unsafe: write special comment *)
-let write_function_type ~w def =
+let labltk_write_function_type ~w def =
if not def.safe then w "(* unsafe *)\n";
w "val "; w def.ml_name; w " : ";
let us, ls, os =
@@ -87,8 +101,69 @@ let write_function_type ~w def =
w (ppMLtype ~any:true ~return:true def.result); (* RETURN TYPE !!! *)
w " \n";
(* w "(* tk invocation: "; w (doc_of_template def.template); w " *)"; *)
- if def.safe then w "\n\n"
- else w "\n(* /unsafe *)\n\n"
+ if def.safe then w "\n"
+ else w "\n(* /unsafe *)\n"
+
+let camltk_write_function_type ~w def =
+ if not def.safe then w "(* unsafe *)\n";
+ w "val "; w def.ml_name; w " : ";
+ let us, os =
+ let tys = types_of_template def.template in
+ let rec replace_args ~u ~o = function
+ [] -> u, o
+ | ("", _ as x)::ls ->
+ replace_args ~u:(x::u) ~o ls
+ | (p, _ as x)::ls when p.[0] = '?' ->
+ replace_args ~u ~o:(x::o) ls
+ | x::ls ->
+ replace_args ~u:(x::u) ~o ls
+ in
+ replace_args ~u:[] ~o:[] (List.rev tys)
+ in
+ let counter = ref 0 in
+ let params =
+ if os = [] then us else os @ us in
+ List.iter params ~f:
+ begin fun (l, t) ->
+ if l <> "" then if l.[0] = '?' then w (l ^ ":");
+ w (ppMLtype t ~counter);
+ w " -> "
+ end;
+ if us = [] then w "unit -> ";
+ w (ppMLtype ~any:true ~return:true def.result); (* RETURN TYPE !!! *)
+ w " \n";
+(* w "(* tk invocation: "; w (doc_of_template def.template); w " *)"; *)
+ if def.safe then w "\n"
+ else w "\n(* /unsafe *)\n"
+
+(*
+ if not def.safe then w "(* unsafe *)\n";
+ w "val "; w def.ml_name; w " : ";
+ let tys = types_of_template def.template in
+ let counter = ref 0 in
+ let have_normal_arg = ref false in
+ List.iter tys ~f:
+ begin fun (l, t) ->
+ if l <> "" then
+ if l.[0] = '?' then w (l^":")
+ else begin
+ have_normal_arg := true;
+ w (" (* " ^ l ^ ":*)")
+ end
+ else have_normal_arg := true;
+ w (ppMLtype t ~counter);
+ w " -> "
+ end;
+ if not !have_normal_arg then w "unit -> ";
+ w (ppMLtype ~any:true ~return:true def.result); (* RETURN TYPE !!! *)
+ w " \n";
+ if def.safe then w "\n"
+ else w "\n(* /unsafe *)\n"
+*)
+
+let write_function_type ~w def =
+ if !Flags.camltk then camltk_write_function_type ~w def
+ else labltk_write_function_type ~w def
let write_external_type ~w def =
match def.template with
@@ -96,18 +171,19 @@ let write_external_type ~w def =
begin try
let realname = find_in_path !search_path (fname ^ ".mli") in
let ic = open_in_bin realname in
- if not def.safe then w "(* unsafe *)\n";
- begin try
- while true do
- w (input_line ic);
- w "\n"
- done
- with
- | End_of_file ->
- close_in ic;
- if def.safe then w "\n\n"
- else w "\n(* /unsafe *)\n\n"
- end
+ try
+ let code_list = Ppparse.parse_channel ic in
+ close_in ic;
+ if not def.safe then w "(* unsafe *)\n";
+ List.iter (Ppexec.exec (fun _ -> ()) w)
+ (if !Flags.camltk then
+ Code.Define "CAMLTK" :: code_list else code_list );
+ if def.safe then w "\n\n"
+ else w "\n(* /unsafe *)\n\n"
+ with
+ | Ppparse.Error s ->
+ close_in ic;
+ raise (Compiler_Error (Printf.sprintf "Preprocess error: %s" s))
with
| Not_found ->
raise (Compiler_Error ("can't find external file: " ^ fname))
diff --git a/otherlibs/labltk/compiler/lexer.mll b/otherlibs/labltk/compiler/lexer.mll
index 7231656d1..5c04dc674 100644
--- a/otherlibs/labltk/compiler/lexer.mll
+++ b/otherlibs/labltk/compiler/lexer.mll
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -31,7 +31,7 @@ let current_line = ref 1
let keyword_table = (Hashtbl.create 149 : (string, token) Hashtbl.t)
let _ = List.iter
- ~f:(fun (str,tok) -> Hashtbl'.add keyword_table ~key:str ~data:tok)
+ ~f:(fun (str,tok) -> Hashtbl.add keyword_table str tok)
[
"int", TYINT;
"float", TYFLOAT;
@@ -125,7 +125,9 @@ rule main = parse
| ";" { SEMICOLON }
| ":" {COLON}
| "?" {QUESTION}
- | "#" { comment lexbuf; main lexbuf }
+ | "/" {SLASH}
+ | "%" { comment lexbuf; main lexbuf }
+ | "##line" { line lexbuf; main lexbuf }
| eof { EOF }
| _
{ raise (Lexical_error("illegal character")) }
@@ -157,3 +159,12 @@ and comment = parse
| eof { () }
| _ { comment lexbuf }
+and linenum = parse
+ | ['0'-'9']+ {
+ let next_line = int_of_string (Lexing.lexeme lexbuf) in
+ current_line := next_line - 1
+ }
+ | _ { raise (Lexical_error("illegal ##line directive: no line number"))}
+
+and line = parse
+ | [' ' '\t']* { linenum lexbuf }
diff --git a/otherlibs/labltk/compiler/maincompile.ml b/otherlibs/labltk/compiler/maincompile.ml
index 6955afb6e..19b770554 100644
--- a/otherlibs/labltk/compiler/maincompile.ml
+++ b/otherlibs/labltk/compiler/maincompile.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -30,7 +30,7 @@ let verbose_endline s =
if !flag_verbose then prerr_endline s
let input_name = ref "Widgets.src"
-let output_dir = ref "lib"
+let output_dir = ref ""
let destfile f = Filename.concat !output_dir f
let usage () =
@@ -45,14 +45,30 @@ let prerr_error_header () =
prerr_string (string_of_int !Lexer.current_line);
prerr_string ": "
-
+(* parse Widget.src config file *)
let parse_file filename =
let ic = open_in_bin filename in
+ let lexbuf =
+ try
+ let code_list = Ppparse.parse_channel ic in
+ close_in ic;
+ let buf = Buffer.create 50000 in
+ List.iter (Ppexec.exec
+ (fun l -> Buffer.add_string buf
+ (Printf.sprintf "##line %d\n" l))
+ (Buffer.add_string buf))
+ (if !Flags.camltk then Code.Define "CAMLTK" :: code_list
+ else code_list);
+ Lexing.from_string (Buffer.contents buf)
+ with
+ | Ppparse.Error s ->
+ close_in ic;
+ raise (Compiler_Error (Printf.sprintf "Preprocess error: %s" s))
+ in
try
- let lexbuf = Lexing.from_channel ic in
- while true do
- Parser.entry Lexer.main lexbuf
- done
+ while true do
+ Parser.entry Lexer.main lexbuf
+ done
with
Parsing.Parse_error ->
close_in ic;
@@ -120,44 +136,51 @@ let uniq_clauses = function
let c = constr.var_name in
if Hashtbl.mem t c
then (check_constr constr (Hashtbl.find t c))
- else Hashtbl'.add t ~key:c ~data:constr);
+ else Hashtbl.add t c constr);
elements t;;
let option_hack oc =
if Hashtbl.mem types_table "options" then
let typdef = Hashtbl.find types_table "options" in
let hack =
- { parser_arity = OneToken;
- constructors =
- begin
- let constrs =
- List.map typdef.constructors ~f:
- begin fun c ->
- { component = Constructor;
- ml_name = c.ml_name;
- var_name = c.var_name; (* as variants *)
- template =
- begin match c.template with
- ListArg (x :: _) -> x
- | _ -> fatal_error "bogus hack"
- end;
- result = UserDefined "options_constrs";
- safe = true }
- end in
- uniq_clauses constrs
- end;
- subtypes = [];
- requires_widget_context = false;
- variant = false }
+ { parser_arity = OneToken;
+ constructors = begin
+ let constrs =
+ List.map typdef.constructors ~f:
+ begin fun c ->
+ { component = Constructor;
+ ml_name = (if !Flags.camltk then "C" ^ c.ml_name
+ else c.ml_name);
+ var_name = c.var_name; (* as variants *)
+ template =
+ begin match c.template with
+ ListArg (x :: _) -> x
+ | _ -> fatal_error "bogus hack"
+ end;
+ result = UserDefined "options_constrs";
+ safe = true }
+ end in
+ if !Flags.camltk then constrs else uniq_clauses constrs (* JPF ?? *)
+ end;
+ subtypes = [];
+ requires_widget_context = false;
+ variant = false }
in
write_CAMLtoTK
~w:(output_string oc) ~def:hack ~safetype:false "options_constrs"
+let realname name =
+ (* module name fix for camltk *)
+ if !Flags.camltk then "c" ^ (String.capitalize name)
+ else name
+;;
+
+(* analize the parsed Widget.src and output source files *)
let compile () =
- verbose_endline "Creating tkgen.ml ...";
- let oc = open_out_bin (destfile "tkgen.ml") in
- let oc' = open_out_bin (destfile "tkigen.ml") in
- let oc'' = open_out_bin (destfile "tkfgen.ml") in
+ verbose_endline "Creating _tkgen.ml ...";
+ let oc = open_out_bin (destfile "_tkgen.ml") in
+ let oc' = open_out_bin (destfile "_tkigen.ml") in
+ let oc'' = open_out_bin (destfile "_tkfgen.ml") in
let sorted_types = Tsort.sort types_order in
verbose_endline " writing types ...";
List.iter sorted_types ~f:
@@ -175,7 +198,8 @@ let compile () =
if List.mem typname !types_returned then
write_TKtoCAML ~w:(output_string oc') typname ~def:typdef;
verbose_string "CO ";
- write_catch_optionals ~w:(output_string oc') typname ~def:typdef;
+ if not !Flags.camltk then (* only for LablTk *)
+ write_catch_optionals ~w:(output_string oc') typname ~def:typdef;
verbose_endline "."
with Not_found ->
if not (List.mem_assoc typname !types_external) then
@@ -195,32 +219,49 @@ let compile () =
close_out oc'';
(* Write the interface for public functions *)
(* this interface is used only for documentation *)
- verbose_endline "Creating tkgen.mli ...";
- let oc = open_out_bin (destfile "tkgen.mli") in
+ verbose_endline "Creating _tkgen.mli ...";
+ let oc = open_out_bin (destfile "_tkgen.mli") in
List.iter (sort_components !function_table)
~f:(write_function_type ~w:(output_string oc));
close_out oc;
verbose_endline "Creating other ml, mli ...";
let write_module wname wdef =
verbose_endline (" "^wname);
- let modname = wname in
+ let modname = realname wname in
let oc = open_out_bin (destfile (modname ^ ".ml"))
and oc' = open_out_bin (destfile (modname ^ ".mli")) in
+ Copyright.write ~w:(output_string oc);
+ Copyright.write ~w:(output_string oc');
begin match wdef.module_type with
Widget -> output_string oc' ("(* The "^wname^" widget *)\n")
| Family -> output_string oc' ("(* The "^wname^" commands *)\n")
end;
- output_string oc "open Protocol\n";
List.iter ~f:(fun s -> output_string oc s; output_string oc' s)
- [ "open StdLabels\n";
- "open Tk\n";
- "open Tkintf\n";
- "open Widget\n";
- "open Textvariable\n" ];
+ begin
+ if !Flags.camltk then
+ [ "open CTk\n";
+ "open Tkintf\n";
+ "open Widget\n";
+ "open Textvariable\n\n" ]
+ else
+ [ "open StdLabels\n";
+ "open Tk\n";
+ "open Tkintf\n";
+ "open Widget\n";
+ "open Textvariable\n\n" ]
+ end;
+ output_string oc "open Protocol\n";
begin match wdef.module_type with
Widget ->
- write_create ~w:(output_string oc) wname;
- write_create_p ~w:(output_string oc') wname
+ if !Flags.camltk then begin
+ camltk_write_create ~w:(output_string oc) wname;
+ camltk_write_named_create ~w:(output_string oc) wname;
+ camltk_write_create_p ~w:(output_string oc') wname;
+ camltk_write_named_create_p ~w:(output_string oc') wname;
+ end else begin
+ labltk_write_create ~w:(output_string oc) wname;
+ labltk_write_create_p ~w:(output_string oc') wname
+ end
| Family -> ()
end;
List.iter ~f:(write_function ~w:(output_string oc))
@@ -234,24 +275,86 @@ let compile () =
close_out oc;
close_out oc'
in Hashtbl.iter write_module module_table;
+
+ (* wrapper code camltk.ml and labltk.ml *)
+ if !Flags.camltk then begin
+ let oc = open_out_bin (destfile "camltk.ml") in
+ Copyright.write ~w:(output_string oc);
+ output_string oc
+"(** This module Camltk provides the module name spaces of the CamlTk API.
+
+ The users of the CamlTk API should open this module first to access
+ the types, functions and modules of the CamlTk API easier.
+ For the documentation of each sub modules such as [Button] and [Toplevel],
+ refer to its defintion file, [cButton.mli], [cToplevel.mli], etc.
+ *)
+
+";
+ output_string oc "include CTk\n";
+ output_string oc "module Tk = CTk\n";
+ Hashtbl.iter (fun name _ ->
+ let cname = realname name in
+ output_string oc (Printf.sprintf "module %s = %s;;\n"
+ (String.capitalize name)
+ (String.capitalize cname))) module_table;
+ close_out oc
+ end else begin
+ let oc = open_out_bin (destfile "labltk.ml") in
+ Copyright.write ~w:(output_string oc);
+ output_string oc
+"(** This module Labltk provides the module name spaces of the LablTk API,
+ useful to call LablTk functions inside CamlTk programs. 100% LablTk users
+ do not need to use this. *)
+
+";
+ output_string oc "module Widget = Widget;;
+module Protocol = Protocol;;
+module Textvariable = Textvariable;;
+module Fileevent = Fileevent;;
+module Timer = Timer;;
+";
+ Hashtbl.iter (fun name _ ->
+ let cname = realname name in
+ output_string oc (Printf.sprintf "module %s = %s;;\n"
+ (String.capitalize name)
+ (String.capitalize name))) module_table;
+ (* widget typer *)
+ output_string oc "\n(** Widget typers *)\n\nopen Widget\n\n";
+ Hashtbl.iter (fun name def ->
+ match def.module_type with
+ | Widget ->
+ output_string oc (Printf.sprintf
+ "let %s (w : any widget) =\n" name);
+ output_string oc (Printf.sprintf
+ " Rawwidget.check_class w widget_%s_table;\n" name);
+ output_string oc (Printf.sprintf
+ " (Obj.magic w : %s widget);;\n\n" name);
+ | _ -> () ) module_table;
+ close_out oc
+ end;
+
(* write the module list for the Makefile *)
(* and hack to death until it works *)
let oc = open_out_bin (destfile "modules") in
- output_string oc "WIDGETOBJS=";
+ if !Flags.camltk then output_string oc "CWIDGETOBJS="
+ else output_string oc "WIDGETOBJS=";
Hashtbl.iter
(fun name _ ->
+ let name = realname name in
output_string oc name;
output_string oc ".cmo ")
module_table;
output_string oc "\n";
Hashtbl.iter
(fun name _ ->
+ let name = realname name in
output_string oc name;
output_string oc ".ml ")
module_table;
- output_string oc ": tkgen.ml\n\n";
+ output_string oc ": _tkgen.ml\n\n";
Hashtbl.iter
(fun name _ ->
+ let name = realname name in
output_string oc name;
output_string oc ".cmo : ";
output_string oc name;
@@ -261,14 +364,37 @@ let compile () =
output_string oc name;
output_string oc ".mli\n")
module_table;
+
+ (* for camltk.ml wrapper *)
+ if !Flags.camltk then begin
+ output_string oc "camltk.cmo : cTk.cmo ";
+ Hashtbl.iter
+ (fun name _ ->
+ let name = realname name in
+ output_string oc name;
+ output_string oc ".cmo ") module_table;
+ output_string oc "\n"
+ end;
+
close_out oc
let main () =
Arg.parse
[ "-verbose", Arg.Unit (fun () -> flag_verbose := true),
- "Make output verbose" ]
+ "Make output verbose";
+ "-camltk", Arg.Unit (fun () -> Flags.camltk := true),
+ "Make CamlTk interface";
+ "-outdir", Arg.String (fun s -> output_dir := s),
+ "output directory";
+ "-debugpp", Arg.Unit (fun () -> Ppexec.debug := true),
+ "debug preprocessor"
+ ]
(fun filename -> input_name := filename)
"Usage: tkcompiler <source file>" ;
+ if !output_dir = "" then begin
+ prerr_endline "specify -outdir option";
+ exit 1
+ end;
try
verbose_endline "Parsing...";
parse_file !input_name;
diff --git a/otherlibs/labltk/compiler/parser.mly b/otherlibs/labltk/compiler/parser.mly
index a22f2f4ab..d338a037c 100644
--- a/otherlibs/labltk/compiler/parser.mly
+++ b/otherlibs/labltk/compiler/parser.mly
@@ -1,3 +1,19 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file ../LICENSE. */
+/* */
+/***********************************************************************/
+
/* $Id$ */
%{
@@ -21,6 +37,7 @@ open Tables
%token RBRACKET /* "]" */
%token LBRACE /* "{" */
%token RBRACE /* "}" */
+%token SLASH /* "/" */
%token TYINT /* "int" */
%token TYFLOAT /* "float" */
@@ -66,9 +83,15 @@ Type0 :
{ UserDefined $1 }
;
+/* Camltk/Labltk types */
+Type0_5:
+ | Type0 SLASH Type0 { if !Flags.camltk then $1 else $3 }
+ | Type0 { $1 }
+;
+
/* with subtypes */
Type1 :
- Type0
+ Type0_5
{ $1 }
| TypeName LPAREN IDENT RPAREN
{ Subtype ($1, $3) }
diff --git a/otherlibs/labltk/compiler/pp.ml b/otherlibs/labltk/compiler/pp.ml
new file mode 100644
index 000000000..5c46766af
--- /dev/null
+++ b/otherlibs/labltk/compiler/pp.ml
@@ -0,0 +1,23 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+let _ =
+ try
+ let code_list = Ppparse.parse_channel stdin in
+ List.iter (Ppexec.exec (fun _ -> ()) print_string) code_list
+ with
+ | Ppparse.Error s -> prerr_endline s; exit 2
+;;
diff --git a/otherlibs/labltk/compiler/ppexec.ml b/otherlibs/labltk/compiler/ppexec.ml
new file mode 100644
index 000000000..6754a6521
--- /dev/null
+++ b/otherlibs/labltk/compiler/ppexec.ml
@@ -0,0 +1,60 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+open Code
+
+let debug = ref false
+let defined = ref []
+let linenum = ref 1
+
+let rec nop = function
+ | Line _ -> incr linenum
+ | Ifdef (_, _, c1, c2o) ->
+ List.iter nop c1;
+ begin match c2o with
+ | Some c2 -> List.iter nop c2
+ | None -> ()
+ end
+ | _ -> ()
+;;
+
+let rec exec lp f = function
+ | Line line ->
+ if !debug then
+ prerr_endline (Printf.sprintf "%03d: %s" !linenum
+ (String.sub line 0 ((String.length line) - 1)));
+ f line; incr linenum
+ | Ifdef (sw, k, c1, c2o) ->
+ if List.mem k !defined = sw then begin
+ List.iter (exec lp f) c1;
+ begin match c2o with
+ | Some c2 -> List.iter nop c2
+ | None -> ()
+ end;
+ lp !linenum
+ end else begin
+ List.iter nop c1;
+ match c2o with
+ | Some c2 ->
+ lp !linenum;
+ List.iter (exec lp f) c2
+ | None -> ()
+ end
+ | Define k -> defined := k :: !defined
+ | Undef k ->
+ defined := List.fold_right (fun k' s ->
+ if k = k' then s else k' :: s) [] !defined
+;;
diff --git a/otherlibs/labltk/compiler/pplex.mli b/otherlibs/labltk/compiler/pplex.mli
new file mode 100644
index 000000000..4eaa183b2
--- /dev/null
+++ b/otherlibs/labltk/compiler/pplex.mli
@@ -0,0 +1,18 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+exception Error of string
+val token : Lexing.lexbuf -> Ppyac.token
diff --git a/otherlibs/labltk/compiler/pplex.mll b/otherlibs/labltk/compiler/pplex.mll
new file mode 100644
index 000000000..d68ee4db6
--- /dev/null
+++ b/otherlibs/labltk/compiler/pplex.mll
@@ -0,0 +1,57 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
+
+{
+open Ppyac
+exception Error of string
+let linenum = ref 1
+}
+
+let blank = [' ' '\013' '\009' '\012']
+let identchar =
+ ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9']
+let lowercase = ['a'-'z' '\223'-'\246' '\248'-'\255' '_']
+let uppercase = ['A'-'Z' '\192'-'\214' '\216'-'\222']
+
+rule token = parse
+ blank + { token lexbuf }
+| "##" [' ' '\t']* { directive lexbuf }
+| ("#")? [^ '#' '\n']* '\n'? {
+ begin
+ let str = Lexing.lexeme lexbuf in
+ let line = !linenum in
+ if String.length str <> 0 && str.[String.length str - 1] = '\n' then
+ begin
+ incr linenum
+ end;
+ OTHER (str)
+ end
+ }
+| eof { EOF }
+
+and directive = parse
+| "ifdef" [' ' '\t']+ { IFDEF (ident lexbuf)}
+| "ifndef" [' ' '\t']+ { IFNDEF (ident lexbuf)}
+| "else" { ELSE }
+| "endif" { ENDIF }
+| "define" [' ' '\t']+* { DEFINE (ident lexbuf)}
+| "undef" [' ' '\t']+ { UNDEF (ident lexbuf)}
+| _ { raise (Error (Printf.sprintf "unknown directive at line %d" !linenum))}
+
+and ident = parse
+| lowercase identchar* | uppercase identchar*
+ { Lexing.lexeme lexbuf }
+| _ { raise (Error (Printf.sprintf "illegal identifier at line %d" !linenum)) }
diff --git a/otherlibs/labltk/compiler/ppparse.ml b/otherlibs/labltk/compiler/ppparse.ml
new file mode 100644
index 000000000..91287d34a
--- /dev/null
+++ b/otherlibs/labltk/compiler/ppparse.ml
@@ -0,0 +1,36 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+exception Error of string
+
+let parse_channel ic =
+ let lexbuf = Lexing.from_channel ic in
+ try
+ Ppyac.code_list Pplex.token lexbuf
+ with
+ | Pplex.Error s ->
+ let loc_start = Lexing.lexeme_start lexbuf
+ and loc_end = Lexing.lexeme_end lexbuf
+ in
+ raise (Error (Printf.sprintf "parse error at char %d, %d: %s"
+ loc_start loc_end s))
+ | Parsing.Parse_error ->
+ let loc_start = Lexing.lexeme_start lexbuf
+ and loc_end = Lexing.lexeme_end lexbuf
+ in
+ raise (Error (Printf.sprintf "parse error at char %d, %d"
+ loc_start loc_end))
+;;
diff --git a/otherlibs/labltk/compiler/ppyac.mly b/otherlibs/labltk/compiler/ppyac.mly
new file mode 100644
index 000000000..da7ee681f
--- /dev/null
+++ b/otherlibs/labltk/compiler/ppyac.mly
@@ -0,0 +1,52 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file ../LICENSE. */
+/* */
+/***********************************************************************/
+
+%{
+open Code
+%}
+
+%token <string> IFDEF
+%token <string> IFNDEF
+%token ELSE
+%token ENDIF
+%token <string> DEFINE
+%token <string> UNDEF
+%token <string> OTHER
+%token EOF
+
+/* entry */
+
+%start code_list
+%type <Code.code list> code_list
+
+%%
+
+code_list:
+ /* empty */ { [] }
+ | code code_list { $1 :: $2 }
+;
+
+code:
+ | DEFINE { Define $1 }
+ | UNDEF { Undef $1 }
+ | IFDEF code_list ELSE code_list ENDIF { Ifdef (true, $1, $2, Some ($4)) }
+ | IFNDEF code_list ELSE code_list ENDIF { Ifdef (false, $1, $2, Some ($4)) }
+ | IFDEF code_list ENDIF { Ifdef (true, $1, $2, None) }
+ | IFNDEF code_list ENDIF { Ifdef (false, $1, $2, None) }
+ | OTHER { Line $1 }
+;
+
+%%
diff --git a/otherlibs/labltk/compiler/printer.ml b/otherlibs/labltk/compiler/printer.ml
index e4daa173a..60362d17f 100644
--- a/otherlibs/labltk/compiler/printer.ml
+++ b/otherlibs/labltk/compiler/printer.ml
@@ -1,16 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 2000 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
open Tables;;
diff --git a/otherlibs/labltk/compiler/tables.ml b/otherlibs/labltk/compiler/tables.ml
index 77c4f50b4..0d395cdc2 100644
--- a/otherlibs/labltk/compiler/tables.ml
+++ b/otherlibs/labltk/compiler/tables.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -56,8 +56,8 @@ type component_type =
(* Full definition of a component *)
type fullcomponent = {
component : component_type;
- ml_name : string; (* may be no longer useful *)
- var_name : string;
+ ml_name : string; (* used for camltk *)
+ var_name : string; (* used just for labltk *)
template : template;
result : mltype;
safe : bool
@@ -157,7 +157,7 @@ let new_type typname arity =
subtypes = [];
requires_widget_context = false;
variant = false} in
- Hashtbl'.add types_table ~key:typname ~data:typdef;
+ Hashtbl.add types_table typname typdef;
typdef
@@ -395,10 +395,11 @@ let enter_widget name components =
try List.assoc External sorted_components
with Not_found -> []
in
- Hashtbl'.add module_table ~key:name
- ~data:{module_type = Widget; commands = commands; externals = externals}
+ Hashtbl.add module_table name
+ {module_type = Widget; commands = commands; externals = externals}
(******************** Functions ********************)
+
let enter_function comp =
enter_component_types comp;
function_table := comp :: !function_table
@@ -422,5 +423,5 @@ let enter_module name components =
try List.assoc External sorted_components
with Not_found -> []
in
- Hashtbl'.add module_table ~key:name
- ~data:{module_type = Family; commands = commands; externals = externals}
+ Hashtbl.add module_table name
+ {module_type = Family; commands = commands; externals = externals}
diff --git a/otherlibs/labltk/compiler/tsort.ml b/otherlibs/labltk/compiler/tsort.ml
index 517d72497..a174fb3da 100644
--- a/otherlibs/labltk/compiler/tsort.ml
+++ b/otherlibs/labltk/compiler/tsort.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/examples_camltk/.cvsignore b/otherlibs/labltk/examples_camltk/.cvsignore
new file mode 100644
index 000000000..801812fd3
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/.cvsignore
@@ -0,0 +1,8 @@
+addition
+eyes
+fileinput
+fileopen
+helloworld
+tetris
+winskel
+mytext
diff --git a/otherlibs/labltk/examples_camltk/Makefile b/otherlibs/labltk/examples_camltk/Makefile
new file mode 100644
index 000000000..42613054b
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/Makefile
@@ -0,0 +1,52 @@
+include ../support/Makefile.common
+
+# We are using the non-installed library !
+COMPFLAGS=-I ../lib -I ../camltk -I ../support -I $(OTHERS)/unix -w s -dllpath ../support
+
+
+all: addition$(EXE) helloworld$(EXE) winskel$(EXE) fileinput$(EXE) \
+ eyes$(EXE) tetris$(EXE) mytext$(EXE) fileopen$(EXE)
+
+addition$(EXE): addition.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ $(LIBNAME).cma addition.cmo
+
+helloworld$(EXE): helloworld.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ $(LIBNAME).cma helloworld.cmo
+
+winskel$(EXE): winskel.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ $(LIBNAME).cma winskel.cmo
+
+fileinput$(EXE): fileinput.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ unix.cma $(LIBNAME).cma fileinput.cmo
+
+socketinput$(EXE): socketinput.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ unix.cma $(LIBNAME).cma socketinput.cmo
+
+eyes$(EXE): eyes.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ unix.cma $(LIBNAME).cma eyes.cmo
+
+tetris$(EXE): tetris.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ unix.cma $(LIBNAME).cma tetris.cmo
+
+mytext$(EXE): mytext.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ unix.cma $(LIBNAME).cma mytext.cmo
+
+# graph$(EXE): graphics.cmo graphics_test.cmo
+# $(CAMLC) -o $@ graphics.cmo graphics_test.cmo
+#
+# graphics_test.cmo: graphics.cmo
+
+fileopen$(EXE): fileopen.cmo
+ $(CAMLC) $(COMPFLAGS) -o $@ $(LIBNAME).cma fileopen.cmo
+
+clean :
+ rm -f *.cm? $(EXECS) addition eyes fileinput fileopen helloworld jptest mytext tetris winskel
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
diff --git a/otherlibs/labltk/examples_camltk/Makefile.nt b/otherlibs/labltk/examples_camltk/Makefile.nt
new file mode 100644
index 000000000..7b6b8f24b
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/Makefile.nt
@@ -0,0 +1,38 @@
+!include ..\support\Makefile.common.nt
+
+# We are using the non-installed library !
+COMPFLAGS= -I ../lib -I ../camltk -I ../support
+LINKFLAGS= -I ../lib -I ../camltk -I ../support
+
+# Use pieces of Makefile.config
+TKLINKOPT=$(LIBNAME).cma $(TKLIBS)
+
+all: addition.exe helloworld.exe winskel.exe socketinput.exe
+
+addition.exe: addition.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ addition.cmo
+
+helloworld.exe: helloworld.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ helloworld.cmo
+
+winskel.exe: winskel.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ winskel.cmo
+
+socketinput.exe: socketinput.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) unix.cma \
+ -o $@ socketinput.cmo
+
+clean :
+ rm -f *.cm? *.exe
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
diff --git a/otherlibs/labltk/examples_camltk/addition.ml b/otherlibs/labltk/examples_camltk/addition.ml
new file mode 100644
index 000000000..8f9365bdb
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/addition.ml
@@ -0,0 +1,53 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let main () =
+ let top = opentk () in
+ (* The widgets. They all have "top" as parent widget. *)
+ let en1 = Entry.create top [TextWidth 6; Relief Sunken] in
+ let lab1 = Label.create top [Text "plus"] in
+ let en2 = Entry.create top [TextWidth 6 ; Relief Sunken] in
+ let lab2 = Label.create top [Text "="] in
+ let result_display = Label.create top [] in
+ (* References holding values of entry widgets *)
+ let n1 = ref 0
+ and n2 = ref 0 in
+ (* Refresh result *)
+ let refresh () =
+ Label.configure result_display [Text (string_of_int (!n1 + !n2))] in
+ (* Electric *)
+ let get_and_refresh (w,r) =
+ fun _ _ ->
+ try
+ r := int_of_string (Entry.get w);
+ refresh ()
+ with
+ Failure "int_of_string" ->
+ Label.configure result_display [Text "error"]
+ in
+ (* Set the callbacks *)
+ Entry.configure en1 [XScrollCommand (get_and_refresh (en1,n1)) ];
+ Entry.configure en2 [XScrollCommand (get_and_refresh (en2,n2)) ];
+ (* Map the widgets *)
+ pack [en1;lab1;en2;lab2;result_display] [];
+ (* Make the window resizable *)
+ Wm.minsize_set top 1 1;
+ (* Start interaction (event-driven program) *)
+ mainLoop ()
+;;
+
+let _ = Printexc.catch main () ;;
diff --git a/otherlibs/labltk/examples_camltk/eyes.ml b/otherlibs/labltk/examples_camltk/eyes.ml
new file mode 100644
index 000000000..5666c69c5
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/eyes.ml
@@ -0,0 +1,67 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* The eyes of Caml (CamlTk) *)
+
+open Camltk;;
+
+let _ =
+ let top = opentk () in
+
+ let fw = Frame.create top [] in
+ pack [fw] [];
+ let c = Canvas.create fw [Width (Pixels 200); Height (Pixels 200)] in
+ let create_eye cx cy wx wy ewx ewy bnd =
+ let o2 =
+ Canvas.create_oval c
+ (Pixels (cx - wx)) (Pixels (cy - wy))
+ (Pixels (cx + wx)) (Pixels (cy + wy))
+ [Outline (NamedColor "black"); Width (Pixels 7);
+ FillColor (NamedColor "white")]
+ and o =
+ Canvas.create_oval c
+ (Pixels (cx - ewx)) (Pixels (cy - ewy))
+ (Pixels (cx + ewx)) (Pixels (cy + ewy))
+ [FillColor (NamedColor "black")] in
+ let curx = ref cx
+ and cury = ref cy in
+ bind c [[], Motion]
+ (BindExtend ([Ev_MouseX; Ev_MouseY],
+ (fun e ->
+ let nx, ny =
+ let xdiff = e.ev_MouseX - cx
+ and ydiff = e.ev_MouseY - cy in
+ let diff = sqrt ((float xdiff /. (float wx *. bnd)) ** 2.0 +.
+ (float ydiff /. (float wy *. bnd)) ** 2.0) in
+ if diff > 1.0 then
+ truncate ((float xdiff) *. (1.0 /. diff)) + cx,
+ truncate ((float ydiff) *. (1.0 /. diff)) + cy
+ else
+ e.ev_MouseX, e.ev_MouseY
+ in
+ Canvas.move c o (Pixels (nx - !curx)) (Pixels (ny - !cury));
+ curx := nx;
+ cury := ny)))
+ in
+ create_eye 60 100 30 40 5 6 0.6;
+ create_eye 140 100 30 40 5 6 0.6;
+ pack [c] []
+
+let _ = Printexc.print mainLoop ()
+
+
+
+
diff --git a/otherlibs/labltk/examples_camltk/fileinput.ml b/otherlibs/labltk/examples_camltk/fileinput.ml
new file mode 100644
index 000000000..35e7e8358
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/fileinput.ml
@@ -0,0 +1,35 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk ;;
+
+let top_w = opentk () ;;
+let buffer = String.create 256 ;;
+let (fd_in, fd_out) = Unix.pipe () ;;
+let text0_w = Text.create top_w [] ;;
+let entry0_w = Entry.create top_w [] ;;
+let button0_w = Button.create top_w [Text "Quit"; Command (fun _ -> exit 0)] ;;
+Fileevent.add_fileinput fd_in (fun _ ->
+ let n = Unix.read fd_in buffer 0 (String.length buffer) in
+ let txt = String.sub buffer 0 n in
+ Text.insert text0_w (TextIndex (End, [])) txt []) ;;
+let send _ =
+ let txt = Entry.get entry0_w ^ "\n" in
+ Entry.delete_range entry0_w (At 0) End ;
+ ignore (Unix.write fd_out txt 0 (String.length txt));;
+
+bind entry0_w [([], KeyPressDetail "Return")] (BindSet ([], send)) ;
+pack [text0_w; entry0_w; button0_w][Side Side_Top; Fill Fill_X; Expand true] ;;
+mainLoop () ;;
diff --git a/otherlibs/labltk/examples_camltk/fileopen.ml b/otherlibs/labltk/examples_camltk/fileopen.ml
new file mode 100644
index 000000000..b7bd163f3
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/fileopen.ml
@@ -0,0 +1,56 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk;;
+
+let win = opentk();;
+
+let cvs = Canvas.create win [];;
+
+let t = Label.create cvs [Text "File name"];;
+
+let b =
+ Button.create cvs
+ [Text "Save";
+ Command
+ (function _ ->
+ let s =
+ getSaveFile
+ [Title "SAVE FILE TEST";
+ DefaultExtension ".foo";
+ FileTypes [ { typename= "just test";
+ extensions= [".foo"; ".test"];
+ mactypes= ["FOOO"; "BARR"] } ];
+ InitialDir "/tmp";
+ InitialFile "hogehoge" ] in
+ Label.configure t [Text s])];;
+
+let bb =
+ Button.create cvs
+ [Text "Open";
+ Command
+ (function _ ->
+ let s = getOpenFile [] in
+ Label.configure t [Text s])];;
+
+let q =
+ Button.create cvs
+ [Text "Quit";
+ Command
+ (function _ -> closeTk (); exit 0)];;
+
+pack [cvs; q; bb; b; t] [];;
+
+mainLoop ();;
diff --git a/otherlibs/labltk/examples_camltk/helloworld.ml b/otherlibs/labltk/examples_camltk/helloworld.ml
new file mode 100644
index 000000000..b32b515ae
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/helloworld.ml
@@ -0,0 +1,37 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk;; (* Make interface functions available *)
+
+let top = opentk ();; (* Initialisation of the interface *)
+(* top is now the toplevel widget *)
+
+(* Widget initialisation *)
+let b = Button.create top
+ [Text "foobar";
+ Command (function () ->
+ print_string "foobar";
+ print_newline();
+ flush stdout)];;
+(* b exists but is not yet visible *)
+
+let q = Button.create top
+ [Text "quit";
+ Command closeTk];;
+(* q exists but is not yet visible *)
+
+pack [b; q][] ;; (* Make b visible *)
+mainLoop() ;; (* User interaction*)
+(* You can quit this program by deleting its main window *)
diff --git a/otherlibs/labltk/examples_camltk/images/CamlBook.gif b/otherlibs/labltk/examples_camltk/images/CamlBook.gif
new file mode 100644
index 000000000..fb7e52b10
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/images/CamlBook.gif
Binary files differ
diff --git a/otherlibs/labltk/examples_camltk/images/Lambda2.back.gif b/otherlibs/labltk/examples_camltk/images/Lambda2.back.gif
new file mode 100644
index 000000000..fdd1f078f
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/images/Lambda2.back.gif
Binary files differ
diff --git a/otherlibs/labltk/examples_camltk/images/dojoji.back.gif b/otherlibs/labltk/examples_camltk/images/dojoji.back.gif
new file mode 100644
index 000000000..d4e07fdd7
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/images/dojoji.back.gif
Binary files differ
diff --git a/otherlibs/labltk/examples_camltk/jptest.ml b/otherlibs/labltk/examples_camltk/jptest.ml
new file mode 100644
index 000000000..38d9694c3
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/jptest.ml
@@ -0,0 +1,23 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Tk
+
+let win = opentk();;
+
+let b = Button.create win [ Text "�������" ];;
+let _ = pack [b] [];;
+
+mainLoop();;
diff --git a/otherlibs/labltk/examples_camltk/mytext.ml b/otherlibs/labltk/examples_camltk/mytext.ml
new file mode 100644
index 000000000..0695d931a
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/mytext.ml
@@ -0,0 +1,63 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let top = opentk ()
+
+let scroll_link sb tx =
+ Text.configure tx [YScrollCommand (Scrollbar.set sb)];
+ Scrollbar.configure sb [ScrollCommand (Text.yview tx)]
+
+let f = Frame.create top []
+let text = Text.create f []
+let scrollbar = Scrollbar.create f []
+
+(* kill buffer *)
+let buffer = ref ""
+
+(* Note: for the text widgets, the insertion cursor is
+ not TextIndex(Insert, []),
+ but TextIndex(Mark "insert", [])
+*)
+let insertMark = TextIndex(Mark "insert", [])
+let eol_insertMark = TextIndex(Mark "insert", [LineEnd])
+
+let kill () =
+ buffer :=
+ Text.get text insertMark eol_insertMark;
+ prerr_endline ("Killed: " ^ !buffer);
+ Text.delete text insertMark eol_insertMark
+;;
+
+let yank () =
+ Text.insert text insertMark !buffer [];
+ prerr_endline ("Yanked: " ^ !buffer)
+;;
+
+let _ =
+ scroll_link scrollbar text;
+
+ pack [text; scrollbar][Side Side_Left; Fill Fill_Y];
+ pack [f][];
+
+ bind text [[Control], KeyPressDetail "y"]
+ (BindSet ([], fun _ -> yank () ));
+ bind text [[Control], KeyPressDetail "k"]
+ (BindSet ([], fun _ -> kill () ));
+
+ mainLoop ()
+;;
+
diff --git a/otherlibs/labltk/examples_camltk/socketinput.ml b/otherlibs/labltk/examples_camltk/socketinput.ml
new file mode 100644
index 000000000..d23b8fd5e
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/socketinput.ml
@@ -0,0 +1,43 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let _ =
+ let top_w = opentk () in
+ let text0_w = Text.create top_w [] in
+ let entry0_w = Entry.create top_w [] in
+ let button0_w = Button.create top_w
+ [Text "Quit"; Command (fun _ -> exit 0)] in
+ let buffer = String.create 256 in
+ let master_socket = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
+ Unix.bind master_socket (Unix.ADDR_INET(Unix.inet_addr_any, 6789));
+ Unix.listen master_socket 3;
+ print_string "Please connect to port 6789..."; print_newline();
+ let (sock, _) = Unix.accept master_socket in
+ Fileevent.add_fileinput sock
+ (fun _ ->
+ let n = Unix.recv sock buffer 0 (String.length buffer) [] in
+ let txt = String.sub buffer 0 n in
+ Text.insert text0_w (TextIndex (End, [])) txt []);
+ let send _ =
+ let txt = Entry.get entry0_w ^ "\n" in
+ Entry.delete_range entry0_w (At 0) End ;
+ Unix.send sock txt 0 (String.length txt) [];
+ () in
+ bind entry0_w [([], KeyPressDetail "Return")] (BindSet ([], send));
+ pack [text0_w; entry0_w; button0_w][Side Side_Top; Fill Fill_X; Expand true];
+ mainLoop ()
+
diff --git a/otherlibs/labltk/examples_camltk/taddition.ml b/otherlibs/labltk/examples_camltk/taddition.ml
new file mode 100644
index 000000000..b4745d6c0
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/taddition.ml
@@ -0,0 +1,53 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Tk
+
+let main () =
+ let top = opentk () in
+ (* The widgets. They all have "top" as parent widget. *)
+ let en1 = Entry.create top [TextWidth 6; Relief Sunken] in
+ let lab1 = Label.create top [Text "plus"] in
+ let en2 = Entry.create top [TextWidth 6 ; Relief Sunken] in
+ let lab2 = Label.create top [Text "="] in
+ let result_display = Label.create top [] in
+ (* References holding values of entry widgets *)
+ let n1 = ref 0
+ and n2 = ref 0 in
+ (* Refresh result *)
+ let refresh () =
+ Label.configure result_display [Text (string_of_int (!n1 + !n2))] in
+ (* Electric *)
+ let get_and_refresh (w,r) =
+ fun _ _ ->
+ try
+ r := int_of_string (Entry.get w);
+ refresh ()
+ with
+ Failure "int_of_string" ->
+ Label.configure result_display [Text "error"]
+ in
+ (* Set the callbacks *)
+ Entry.configure en1 [XScrollCommand (get_and_refresh (en1,n1)) ];
+ Entry.configure en2 [XScrollCommand (get_and_refresh (en2,n2)) ];
+ (* Map the widgets *)
+ pack [en1;lab1;en2;lab2;result_display] [];
+ (* Make the window resizable *)
+ Wm.minsize_set top 1 1;
+ (* Start interaction (event-driven program) *)
+ Threadtk.mainLoop ()
+;;
+
+let _ = Printexc.catch main () ;;
diff --git a/otherlibs/labltk/examples_camltk/tetris.ml b/otherlibs/labltk/examples_camltk/tetris.ml
new file mode 100644
index 000000000..f4239a804
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/tetris.ml
@@ -0,0 +1,685 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* A Tetris game for CamlTk *)
+(* written by Jun P. Furuse *)
+
+open Camltk
+
+exception Done
+
+type cell = {mutable color : int;
+ tag : tagOrId * tagOrId * tagOrId}
+
+type falling_block = {
+ mutable pattern: int array list;
+ mutable bcolor: int;
+ mutable x: int;
+ mutable y: int;
+ mutable d: int;
+ mutable alive: bool
+}
+
+let stop_a_bit = 300
+
+let colors = [|
+ NamedColor "red";
+ NamedColor "yellow";
+
+ NamedColor "blue";
+ NamedColor "orange";
+
+ NamedColor "magenta";
+ NamedColor "green";
+
+ NamedColor "cyan"
+|]
+
+let baseurl = "images/"
+
+let backgrounds =
+ List.map (fun s -> baseurl ^ s)
+ [ "dojoji.back.gif";
+ "Lambda2back.gif";
+ "CamlBook.gif";
+ ]
+
+(* blocks *)
+let block_size = 16
+let cell_border = 2
+
+let blocks = [
+ [ [|"0000";
+ "0000";
+ "1111";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0010";
+ "0010" |];
+
+ [|"0000";
+ "0000";
+ "1111";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0010";
+ "0010" |] ];
+
+ [ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0111";
+ "0100";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0010";
+ "0010" |];
+
+ [|"0000";
+ "0010";
+ "1110";
+ "0000" |];
+
+ [|"0100";
+ "0100";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0100";
+ "0111";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0100";
+ "0100" |];
+
+ [|"0000";
+ "1110";
+ "0010";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "1100";
+ "0110";
+ "0000" |];
+
+ [|"0010";
+ "0110";
+ "0100";
+ "0000" |];
+
+ [|"0000";
+ "1100";
+ "0110";
+ "0000" |];
+
+ [|"0010";
+ "0110";
+ "0100";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0011";
+ "0110";
+ "0000" |];
+
+ [|"0100";
+ "0110";
+ "0010";
+ "0000" |];
+
+ [|"0000";
+ "0011";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0100";
+ "0110";
+ "0010" |] ];
+
+ [ [|"0000";
+ "0000";
+ "1110";
+ "0100" |];
+
+ [|"0000";
+ "0100";
+ "1100";
+ "0100" |];
+
+ [|"0000";
+ "0100";
+ "1110";
+ "0000" |];
+
+ [|"0000";
+ "0100";
+ "0110";
+ "0100" |] ]
+
+]
+
+let line_empty = int_of_string "0b1110000000000111"
+let line_full = int_of_string "0b1111111111111111"
+
+let decode_block dvec =
+ let btoi d = int_of_string ("0b"^d) in
+ Array.map btoi dvec
+
+let init fw =
+ let scorev = Textvariable.create ()
+ and linev = Textvariable.create ()
+ and levv = Textvariable.create ()
+ and namev = Textvariable.create ()
+ in
+ let f = Frame.create fw [BorderWidth (Pixels 2)] in
+ let c = Canvas.create f [Width (Pixels (block_size * 10));
+ Height (Pixels (block_size * 20));
+ BorderWidth (Pixels cell_border);
+ Relief Sunken;
+ Background Black]
+ and r = Frame.create f []
+ and r' = Frame.create f [] in
+
+ let nl = Label.create r [Text "Next"; Font "variable"] in
+ let nc = Canvas.create r [Width (Pixels (block_size * 4));
+ Height (Pixels (block_size * 4));
+ BorderWidth (Pixels cell_border);
+ Relief Sunken;
+ Background Black] in
+ let scl = Label.create r [Text "Score"; Font "variable"] in
+ let sc = Label.create r [TextVariable scorev; Font "variable"] in
+ let lnl = Label.create r [Text "Lines"; Font "variable"] in
+ let ln = Label.create r [TextVariable linev; Font "variable"] in
+ let levl = Label.create r [Text "Level"; Font "variable"] in
+ let lev = Label.create r [TextVariable levv; Font "Variable"] in
+ let newg = Button.create r [Text "New Game"; Font "variable"] in
+ let exitg = Button.create r [Text "Quit"; Font "variable"] in
+
+ pack [f] [];
+ pack [c; r; r'] [Side Side_Left; Fill Fill_Y];
+ pack [nl; nc] [Side Side_Top];
+ pack [scl; sc; lnl; ln; levl; lev; newg; exitg] [Side Side_Top];
+
+ let cells_src = Array.create 20 (Array.create 10 ()) in
+ let cells = Array.map (Array.map (fun () ->
+ {tag=
+ (let t1, t2, t3 =
+ Canvas.create_rectangle c
+ (Pixels (-block_size - 8)) (Pixels (-block_size - 8))
+ (Pixels (-9)) (Pixels (-9)) [],
+ Canvas.create_rectangle c
+ (Pixels (-block_size - 10)) (Pixels (-block_size - 10))
+ (Pixels (-11)) (Pixels (-11)) [],
+ Canvas.create_rectangle c
+ (Pixels (-block_size - 12)) (Pixels (-block_size - 12))
+ (Pixels (-13)) (Pixels (-13)) []
+ in
+ Canvas.raise_top c t1;
+ Canvas.raise_top c t2;
+ Canvas.lower_bot c t3;
+ t1,t2,t3);
+ color= 0})) cells_src
+ in
+ let nexts_src = Array.create 4 (Array.create 4 ()) in
+ let nexts =
+ Array.map (Array.map (fun () ->
+ {tag=
+ (let t1, t2, t3 =
+ Canvas.create_rectangle nc
+ (Pixels (-block_size - 8)) (Pixels (-block_size - 8))
+ (Pixels (-9)) (Pixels (-9)) [],
+ Canvas.create_rectangle nc
+ (Pixels (-block_size - 10)) (Pixels (-block_size - 10))
+ (Pixels (-11)) (Pixels (-11)) [],
+ Canvas.create_rectangle nc
+ (Pixels (-block_size - 12)) (Pixels (-block_size - 12))
+ (Pixels (-13)) (Pixels (-13)) []
+ in
+ Canvas.raise_top nc t1;
+ Canvas.raise_top nc t2;
+ Canvas.lower_bot nc t3;
+ t1, t2, t3);
+ color= 0})) nexts_src in
+ let game_over () = ()
+ in
+ [f; c; r; nl; nc; scl; sc; levl; lev; lnl; ln], newg, exitg,
+ (c, cells), (nc, nexts), scorev, linev, levv, game_over
+
+let cell_get (c, cf) x y =
+ (Array.get (Array.get cf y) x).color
+
+let cell_set (c, cf) x y col =
+ let cur = Array.get (Array.get cf y) x in
+ let t1,t2,t3 = cur.tag in
+ if cur.color = col then ()
+ else
+ if cur.color <> 0 && col = 0 then
+ begin
+ Canvas.move c t1
+ (Pixels (- block_size * (x + 1) -10 - cell_border * 2))
+ (Pixels (- block_size * (y + 1) -10 - cell_border * 2));
+ Canvas.move c t2
+ (Pixels (- block_size * (x + 1) -10 - cell_border * 2))
+ (Pixels (- block_size * (y + 1) -10 - cell_border * 2));
+ Canvas.move c t3
+ (Pixels (- block_size * (x + 1) -10 - cell_border * 2))
+ (Pixels (- block_size * (y + 1) -10 - cell_border * 2))
+ end
+ else
+ begin
+ Canvas.configure_rectangle c t2
+ [FillColor (Array.get colors (col - 1));
+ Outline (Array.get colors (col - 1))];
+ Canvas.configure_rectangle c t1
+ [FillColor Black;
+ Outline Black];
+ Canvas.configure_rectangle c t3
+ [FillColor (NamedColor "light gray");
+ Outline (NamedColor "light gray")];
+ if cur.color = 0 && col <> 0 then
+ begin
+ Canvas.move c t1
+ (Pixels (block_size * (x+1)+10+ cell_border*2))
+ (Pixels (block_size * (y+1)+10+ cell_border*2));
+ Canvas.move c t2
+ (Pixels (block_size * (x+1)+10+ cell_border*2))
+ (Pixels (block_size * (y+1)+10+ cell_border*2));
+ Canvas.move c t3
+ (Pixels (block_size * (x+1)+10+ cell_border*2))
+ (Pixels (block_size * (y+1)+10+ cell_border*2))
+ end
+ end;
+ cur.color <- col
+
+let draw_block field col d x y =
+ for iy = 0 to 3 do
+ let base = ref 1 in
+ let xd = Array.get d iy in
+ for ix = 0 to 3 do
+ if xd land !base <> 0 then
+ begin
+ try cell_set field (ix + x) (iy + y) col with _ -> ()
+ end
+ else
+ begin
+ (* cell_set field (ix + x) (iy + y) 0 *) ()
+ end;
+ base := !base lsl 1
+ done
+ done
+
+let timer_ref = (ref None : Timer.t option ref)
+(* I know, this should be timer ref, but I'm not sure what should be
+ the initial value ... *)
+
+let remove_timer () =
+ match !timer_ref with
+ | None -> ()
+ | Some t -> Timer.remove t (* ; prerr_endline "removed!" *)
+
+let do_after milli f =
+ timer_ref := Some (Timer.add milli f)
+
+let copy_block c =
+ { pattern= !c.pattern;
+ bcolor= !c.bcolor;
+ x= !c.x;
+ y= !c.y;
+ d= !c.d;
+ alive= !c.alive }
+
+let _ =
+ let top = opentk () in
+ let lb = Label.create top []
+ and fw = Frame.create top []
+ in
+ let set_message s = Label.configure lb [Text s] in
+ pack [lb; fw] [Side Side_Top];
+ let score = ref 0 in
+ let line = ref 0 in
+ let level = ref 0 in
+ let time = ref 1000 in
+ let blocks = List.map (List.map decode_block) blocks in
+ let field = Array.create 26 0 in
+ let widgets, newg, exitg, cell_field, next_field,
+ scorev, linev, levv, game_over =
+ init fw in
+ let canvas = fst cell_field in
+
+ let init_field () =
+ for i = 0 to 25 do
+ field.(i) <- line_empty
+ done;
+ field.(23) <- line_full;
+ for i = 0 to 19 do
+ for j = 0 to 9 do
+ cell_set cell_field j i 0
+ done
+ done;
+ for i = 0 to 3 do
+ for j = 0 to 3 do
+ cell_set next_field j i 0
+ done
+ done
+ in
+
+ let draw_falling_block fb =
+ draw_block cell_field fb.bcolor
+ (List.nth fb.pattern fb.d) (fb.x - 3) (fb.y - 3)
+
+ and erase_falling_block fb =
+ draw_block cell_field 0 (List.nth fb.pattern fb.d) (fb.x - 3) (fb.y - 3)
+ in
+
+ let stone fb =
+ for i=0 to 3 do
+ let cur = field.(i + fb.y) in
+ field.(i + fb.y) <-
+ cur lor ((List.nth fb.pattern fb.d).(i) lsl fb.x)
+ done;
+ for i=0 to 2 do
+ field.(i) <- line_empty
+ done
+
+ and clear fb =
+ let l = ref 0 in
+ for i = 0 to 3 do
+ if i + fb.y >= 3 && i + fb.y <= 22 then
+ if field.(i + fb.y) = line_full then
+ begin
+ incr l;
+ field.(i + fb.y) <- line_empty;
+ for j = 0 to 9 do
+ cell_set cell_field j (i + fb.y - 3) 0
+ done
+ end
+ done;
+ !l
+
+ and fall_lines () =
+ let eye = ref 22 (* bottom *)
+ and cur = ref 22 (* bottom *)
+ in
+ try
+ while !eye >= 3 do
+ while field.(!eye) = line_empty do
+ decr eye;
+ if !eye = 2 then raise Done
+ done;
+ field.(!cur) <- field.(!eye);
+ for j = 0 to 9 do
+ cell_set cell_field j (!cur-3) (cell_get cell_field j (!eye-3))
+ done;
+ decr eye;
+ decr cur
+ done
+ with Done -> ();
+ for i = 3 to !cur do
+ field.(i) <- line_empty;
+ for j = 0 to 9 do
+ cell_set cell_field j (i-3) 0
+ done
+ done
+ in
+
+ let next = ref 42 (* THE ANSWER *)
+ and current =
+ ref { pattern= [[|0;0;0;0|]]; bcolor=0; x=0; y=0; d=0; alive= false}
+ in
+
+ let draw_next () =
+ draw_block next_field (!next+1) (List.hd (List.nth blocks !next)) 0 0
+
+ and erase_next () =
+ draw_block next_field 0 (List.hd (List.nth blocks !next)) 0 0
+ in
+
+ let set_nextblock () =
+ current :=
+ { pattern= (List.nth blocks !next);
+ bcolor= !next+1;
+ x=6; y= 1; d= 0; alive= true};
+ erase_next ();
+ next := Random.int 7;
+ draw_next ()
+ in
+
+ let death_check fb =
+ try
+ for i=0 to 3 do
+ let cur = field.(i + fb.y) in
+ if cur land ((List.nth fb.pattern fb.d).(i) lsl fb.x) <> 0
+ then raise Done
+ done;
+ false
+ with
+ Done -> true
+ in
+
+ let try_to_move m =
+ if !current.alive then
+ let sub m =
+ if death_check m then false
+ else
+ begin
+ erase_falling_block !current;
+ draw_falling_block m;
+ current := m;
+ true
+ end
+ in
+ if sub m then ()
+ else
+ begin
+ m.x <- m.x + 1;
+ if sub m then ()
+ else
+ begin
+ m.x <- m.x - 2;
+ ignore (sub m)
+ end
+ end
+ else ()
+ in
+
+ let image_load =
+ let i = Canvas.create_image canvas
+ (Pixels (block_size * 5 + block_size / 2))
+ (Pixels (block_size * 10 + block_size / 2))
+ [Anchor Center] in
+ Canvas.lower_bot canvas i;
+ let img = Imagephoto.create [] in
+ fun file ->
+ try
+ Imagephoto.configure img [File file];
+ Canvas.configure_image canvas i [ImagePhoto img]
+ with
+ _ ->
+ begin
+ Printf.eprintf "%s : No such image...\n" file;
+ flush stderr
+ end
+ in
+
+ let add_score l =
+ let pline = !line in
+ if l <> 0 then
+ begin
+ line := !line + l;
+ score := !score + l * l;
+ set_message (Printf.sprintf "%d pts" (1 lsl ((l - 1) * 2)))
+ end;
+ Textvariable.set linev (string_of_int !line);
+ Textvariable.set scorev (string_of_int !score);
+
+ if !line /10 <> pline /10 then
+ (* update the background every 10 lines. *)
+ begin
+ let num_image = List.length backgrounds - 1 in
+ let n = !line/10 in
+ let n = if n > num_image then num_image else n in
+ let file = List.nth backgrounds n in
+ image_load file;
+ (* Future work: We should gain level after an image is put... *)
+ incr level;
+ Textvariable.set levv (string_of_int !level)
+ end
+ in
+
+ let rec newblock () =
+ set_message "TETRIS";
+ set_nextblock ();
+ draw_falling_block !current;
+ if death_check !current then
+ begin
+ !current.alive <- false;
+ set_message "GAME OVER";
+ game_over ()
+ end
+ else
+ begin
+ time := 1100 - (!level / 4 * 300) - ((!level mod 4) * 200);
+ if !time < 60 - !level * 3 then time := 60 - !level * 3;
+ do_after stop_a_bit loop
+ end
+
+ and loop () =
+ let m = copy_block current in
+ m.y <- m.y + 1;
+ if death_check m then
+ begin
+ !current.alive <- false;
+ stone !current;
+ do_after stop_a_bit (fun () ->
+ let l = clear !current in
+ if l > 0 then
+ do_after stop_a_bit (fun () ->
+ fall_lines ();
+ add_score l;
+ do_after stop_a_bit newblock)
+ else
+ newblock ())
+ end
+ else
+ begin
+ erase_falling_block !current;
+ draw_falling_block m;
+ current := m;
+ do_after !time loop
+ end
+ in
+
+ let bind_game w =
+ bind w [([], KeyPress)] (BindSet ([Ev_KeySymString],
+ fun e ->
+ match e.ev_KeySymString with
+ | "h" ->
+ let m = copy_block current in
+ m.x <- m.x - 1;
+ try_to_move m
+ | "j" ->
+ let m = copy_block current in
+ m.d <- m.d + 1;
+ if m.d = List.length m.pattern then m.d <- 0;
+ try_to_move m
+ | "k" ->
+ let m = copy_block current in
+ m.d <- m.d - 1;
+ if m.d < 0 then m.d <- List.length m.pattern - 1;
+ try_to_move m
+ | "l" ->
+ let m = copy_block current in
+ m.x <- m.x + 1;
+ try_to_move m
+ | "m" ->
+ remove_timer ();
+ loop ()
+ | "space" ->
+ if !current.alive then
+ begin
+ let m = copy_block current
+ and n = copy_block current in
+ while
+ m.y <- m.y + 1;
+ if death_check m then false
+ else begin n.y <- m.y; true end
+ do () done;
+ erase_falling_block !current;
+ draw_falling_block n;
+ current := n;
+ remove_timer ();
+ loop ()
+ end
+ | _ -> ()
+ ))
+ in
+
+ let game_init () =
+ (* Game Initialization *)
+ set_message "Initializing ...";
+ remove_timer ();
+ image_load (List.hd backgrounds);
+ time := 1000;
+ score := 0;
+ line := 0;
+ level := 1;
+ add_score 0;
+ init_field ();
+ next := Random.int 7;
+ set_message "Welcome to TETRIS";
+ set_nextblock ();
+ draw_falling_block !current;
+ do_after !time loop
+ in
+ bind_game top;
+ Button.configure newg [Command game_init];
+ Button.configure exitg [Command (fun () -> closeTk (); exit 0)];
+ game_init ()
+
+let _ = Printexc.print mainLoop ()
diff --git a/otherlibs/labltk/examples_camltk/text.ml b/otherlibs/labltk/examples_camltk/text.ml
new file mode 100644
index 000000000..0001ae75a
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/text.ml
@@ -0,0 +1,55 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Tk
+
+let top = opentk ()
+
+let scroll_link sb tx =
+ Text.configure tx [YScrollCommand (Scrollbar.set sb)];
+ Scrollbar.configure sb [ScrollCommand (Text.yview tx)]
+
+let f = Frame.create top []
+let text = Text.create f []
+let scrollbar = Scrollbar.create f []
+
+let buffer = ref ""
+
+let kill () =
+ buffer :=
+ Text.get text (TextIndex (Insert, []))
+ (TextIndex (Insert, [LineEnd]));
+ Text.delete text (TextIndex (Insert, []))
+ (TextIndex (Insert, [LineEnd]))
+;;
+
+let yank () =
+ Text.insert text (TextIndex (Insert, [])) !buffer []
+
+let _ = bind text [[Control], KeyPressDetail "y"] (BindSet ([], fun _ ->
+ yank () ))
+;;
+let _ = bind text [[Control], KeyPressDetail "k"] (BindSet ([], fun _ ->
+ kill () ))
+;;
+
+let _ =
+ scroll_link scrollbar text;
+
+ pack [text;f][];
+ pack [f][];
+ mainLoop ()
+;;
+
diff --git a/otherlibs/labltk/examples_camltk/winskel.ml b/otherlibs/labltk/examples_camltk/winskel.ml
new file mode 100644
index 000000000..2ca1da174
--- /dev/null
+++ b/otherlibs/labltk/examples_camltk/winskel.ml
@@ -0,0 +1,63 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* This examples is based on Ousterhout's book (fig 16.15) *)
+open Camltk
+
+let main () =
+ let top = opentk() in
+ let mbar = Frame.create top [Relief Raised; BorderWidth (Pixels 2)]
+ and dummy =
+ Frame.create top [Width (Centimeters 10.); Height (Centimeters 5.)] in
+ pack [mbar; dummy] [Side Side_Top; Fill Fill_X];
+ let file = Menubutton.create mbar [Text "File"; UnderlinedChar 0]
+ and edit = Menubutton.create mbar [Text "Edit"; UnderlinedChar 0]
+ and graphics = Menubutton.create mbar [Text "Graphics"; UnderlinedChar 0]
+ and text = Menubutton.create mbar [Text "Text"; UnderlinedChar 0]
+ and view = Menubutton.create mbar [Text "View"; UnderlinedChar 0]
+ and help = Menubutton.create mbar [Text "Help"; UnderlinedChar 0] in
+ pack [file;edit;graphics;text;view] [Side Side_Left];
+ pack [help] [Side Side_Right];
+ (* same code as chap16-14 *)
+ let m = Menu.create text [] in
+ let bold = Textvariable.create()
+ and italic = Textvariable.create()
+ and underline = Textvariable.create() in
+ Menu.add_checkbutton m [Label "Bold"; Variable bold];
+ Menu.add_checkbutton m [Label "Italic"; Variable italic];
+ Menu.add_checkbutton m [Label "Underline"; Variable underline];
+ Menu.add_separator m;
+ let font = Textvariable.create() in
+ Menu.add_radiobutton m [Label "Times"; Variable font; Value "times"];
+ Menu.add_radiobutton m [Label "Helvetica"; Variable font; Value "helvetica"]
+;
+ Menu.add_radiobutton m [Label "Courier"; Variable font; Value "courier"];
+ Menu.add_separator m;
+ Menu.add_command m [Label "Insert Bullet";
+ Command (function () ->
+ print_string "Insert Bullet\n";
+ flush stdout)];
+ Menu.add_command m [Label "Margins and Tags...";
+ Command (function () ->
+ print_string "margins\n";
+ flush stdout)];
+ Menubutton.configure text [Menu m];
+
+ mainLoop()
+
+
+
+let _ =
+ Printexc.catch main ()
diff --git a/otherlibs/labltk/examples_labltk/.cvsignore b/otherlibs/labltk/examples_labltk/.cvsignore
new file mode 100644
index 000000000..9b2c11726
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/.cvsignore
@@ -0,0 +1,7 @@
+calc
+clock
+demo
+eyes
+hello
+tetris
+lang
diff --git a/otherlibs/labltk/examples_labltk/Lambda2.back.gif b/otherlibs/labltk/examples_labltk/Lambda2.back.gif
new file mode 100644
index 000000000..fdd1f078f
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/Lambda2.back.gif
Binary files differ
diff --git a/otherlibs/labltk/examples_labltk/Makefile b/otherlibs/labltk/examples_labltk/Makefile
new file mode 100644
index 000000000..11e322b70
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/Makefile
@@ -0,0 +1,50 @@
+include ../support/Makefile.common
+
+COMPFLAGS=-I ../lib -I ../labltk -I ../support -I $(OTHERS)/unix -w s -dllpath ../support
+
+all: hello demo eyes calc clock tetris lang
+
+opt: hello.opt demo.opt eyes.opt calc.opt clock.opt tetris.opt
+
+hello: hello.cmo
+ $(CAMLC) $(COMPFLAGS) -o hello $(LIBNAME).cma hello.cmo
+
+demo: demo.cmo
+ $(CAMLC) $(COMPFLAGS) -o demo $(LIBNAME).cma demo.cmo
+
+eyes: eyes.cmo
+ $(CAMLC) $(COMPFLAGS) -o eyes $(LIBNAME).cma eyes.cmo
+
+calc: calc.cmo
+ $(CAMLC) $(COMPFLAGS) -o calc $(LIBNAME).cma calc.cmo
+
+clock: clock.cmo
+ $(CAMLC) $(COMPFLAGS) -o clock $(LIBNAME).cma unix.cma clock.cmo
+
+clock.opt: clock.cmx
+ $(CAMLOPT) $(COMPFLAGS) -o clock.opt \
+ $(LIBNAME).cmxa unix.cmxa clock.cmx
+
+tetris: tetris.cmo
+ $(CAMLC) $(COMPFLAGS) -o tetris $(LIBNAME).cma tetris.cmo
+
+lang: lang.cmo
+ $(CAMLC) $(COMPFLAGS) -o lang $(LIBNAME).cma lang.cmo
+
+clean:
+ rm -f hello demo eyes calc clock tetris lang *.opt *.o *.cm*
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmx .cmo .opt
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+.cmx.opt:
+ $(CAMLOPT) $(COMPFLAGS) -o $@ $(LIBNAME).cmxa $<
diff --git a/otherlibs/labltk/examples_labltk/Makefile.nt b/otherlibs/labltk/examples_labltk/Makefile.nt
new file mode 100644
index 000000000..fa58ea492
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/Makefile.nt
@@ -0,0 +1,50 @@
+!include ..\support\Makefile.common.nt
+
+# We are using the non-installed library !
+COMPFLAGS= -I ../lib -I ../labltk -I ../support
+LINKFLAGS= -I ../lib -I ../labltk -I ../support
+
+# Use pieces of Makefile.config
+TKLINKOPT=$(LIBNAME).cma $(TKLIBS)
+
+all: hello.exe demo.exe eyes.exe calc.exe clock.exe tetris.exe lang.exe
+
+hello.exe: hello.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ hello.cmo
+
+demo.exe: demo.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ demo.cmo
+
+eyes.exe: eyes.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ eyes.cmo
+
+calc.exe: calc.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ calc.cmo
+
+clock.exe: clock.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) unix.cma \
+ -o $@ clock.cmo
+
+tetris.exe: tetris.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ tetris.cmo
+
+lang.exe: lang.cmo
+ $(CAMLC) -custom $(LINKFLAGS) $(TKLINKOPT) \
+ -o $@ lang.cmo
+
+clean :
+ rm -f *.cm? *.exe
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
diff --git a/otherlibs/labltk/examples_labltk/README b/otherlibs/labltk/examples_labltk/README
new file mode 100644
index 000000000..ec0f20de6
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/README
@@ -0,0 +1,20 @@
+$Id$
+
+Some examples for LablTk.
+They are written in classic mode, except testris.ml which uses label
+commutation.
+You may either compile them here, or just run them as scripts with
+ labltk example.ml
+
+hello.ml A very simple example of CamlTk
+hello.tcl The same programme in Tcl/Tk
+
+demo.ml A demonstration using many widget classes
+
+eyes.ml A "bind" test
+
+calc.ml A little calculator
+
+clock.ml An analog clock (uses unix.cma)
+
+tetris.ml You NEED a game also (uses -labels)
diff --git a/otherlibs/labltk/examples_labltk/calc.ml b/otherlibs/labltk/examples_labltk/calc.ml
new file mode 100644
index 000000000..4f980bec0
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/calc.ml
@@ -0,0 +1,129 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* A simple calculator demonstrating OO programming with O'Labl
+ and LablTk.
+
+ LablTk itself is not OO, but it is good to wrap complex
+ structures in objects. Even if the absence of initializers
+ makes things a little bit awkward.
+*)
+
+open StdLabels
+open Tk
+
+let mem_string ~elt:c s =
+ try
+ for i = 0 to String.length s -1 do
+ if s.[i] = c then raise Exit
+ done; false
+ with Exit -> true
+
+let ops = ['+',(+.); '-',(-.); '*',( *.); '/',(/.)]
+
+(* The abstract calculator class.
+ Does not use Tk (only Textvariable) *)
+
+class calc () = object (calc)
+ val variable = Textvariable.create ()
+ val mutable x = 0.0
+ val mutable op = None
+ val mutable displaying = true
+
+ method set = Textvariable.set variable
+ method get = Textvariable.get variable
+ method insert s = calc#set (calc#get ^ s)
+ method get_float = float_of_string (calc#get)
+
+ method command s =
+ if s <> "" then match s.[0] with
+ '0'..'9' ->
+ if displaying then (calc#set ""; displaying <- false);
+ calc#insert s
+ | '.' ->
+ if displaying then
+ (calc#set "0."; displaying <- false)
+ else
+ if not (mem_string ~elt:'.' calc#get) then calc#insert s
+ | '+'|'-'|'*'|'/' as c ->
+ displaying <- true;
+ begin match op with
+ None ->
+ x <- calc#get_float;
+ op <- Some (List.assoc c ops)
+ | Some f ->
+ x <- f x (calc#get_float);
+ op <- Some (List.assoc c ops);
+ calc#set (string_of_float x)
+ end
+ | '='|'\n'|'\r' ->
+ displaying <- true;
+ begin match op with
+ None -> ()
+ | Some f ->
+ x <- f x (calc#get_float);
+ op <- None;
+ calc#set (string_of_float x)
+ end
+ | 'q' -> closeTk (); exit 0
+ | _ -> ()
+end
+
+(* Buttons for the calculator *)
+
+let m =
+ [|["7";"8";"9";"+"];
+ ["4";"5";"6";"-"];
+ ["1";"2";"3";"*"];
+ ["0";".";"=";"/"]|]
+
+(* The physical calculator. Inherits from the abstract one *)
+
+class calculator ~parent = object
+ inherit calc () as calc
+
+ val label = Label.create ~anchor:`E ~relief:`Sunken ~padx:10 parent
+ val frame = Frame.create parent
+
+ initializer
+ let buttons =
+ Array.map ~f:
+ (List.map ~f:
+ (fun text ->
+ Button.create ~text ~command:(fun () -> calc#command text) frame))
+ m
+ in
+ Label.configure ~textvariable:variable label;
+ calc#set "0";
+ bind ~events:[`KeyPress] ~fields:[`Char]
+ ~action:(fun ev -> calc#command ev.ev_Char)
+ parent;
+ for i = 0 to Array.length m - 1 do
+ Grid.configure ~row:i buttons.(i)
+ done;
+ pack ~side:`Top ~fill:`X [label];
+ pack ~side:`Bottom ~fill:`Both ~expand:true [frame];
+end
+
+(* Finally start everything *)
+
+let top = openTk ()
+
+let applet = new calculator ~parent:top
+
+let _ = mainLoop ()
diff --git a/otherlibs/labltk/examples_labltk/clock.ml b/otherlibs/labltk/examples_labltk/clock.ml
new file mode 100644
index 000000000..57a59b825
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/clock.ml
@@ -0,0 +1,133 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Clock/V, a simple clock.
+ Reverts every time you push the right button.
+ Adapted from ASCII/V May 1997
+
+ Uses Tk and Unix, so you must link with
+ labltklink unix.cma clock.ml -o clock -cclib -lunix
+*)
+
+open Tk
+
+(* pi is not a constant! *)
+let pi = acos (-1.)
+
+(* The main class:
+ * create it with a parent: [new clock parent:top]
+ * initialize with [#init]
+*)
+
+class clock ~parent = object (self)
+
+ (* Instance variables *)
+ val canvas = Canvas.create ~width:100 ~height:100 parent
+ val mutable height = 100
+ val mutable width = 100
+ val mutable rflag = -1
+
+ (* Convert from -1.0 .. 1.0 to actual positions on the canvas *)
+ method x x0 = truncate (float width *. (x0 +. 1.) /. 2.)
+ method y y0 = truncate (float height *. (y0 +. 1.) /. 2.)
+
+ initializer
+ (* Create the oval border *)
+ Canvas.create_oval canvas ~tags:["cadran"]
+ ~x1:1 ~y1:1 ~x2:(width - 2) ~y2:(height - 2)
+ ~width:3 ~outline:`Yellow ~fill:`White;
+ (* Draw the figures *)
+ self#draw_figures;
+ (* Create the arrows with dummy position *)
+ Canvas.create_line canvas
+ ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
+ ~tags:["hours"] ~fill:`Red;
+ Canvas.create_line canvas
+ ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
+ ~tags:["minutes"] ~fill:`Blue;
+ Canvas.create_line canvas
+ ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
+ ~tags:["seconds"] ~fill:`Black;
+ (* Setup a timer every second *)
+ let rec timer () =
+ self#draw_arrows (Unix.localtime (Unix.time ()));
+ Timer.add ~ms:1000 ~callback:timer; ()
+ in timer ();
+ (* Redraw when configured (changes size) *)
+ bind canvas ~events:[`Configure] ~action:
+ begin fun _ ->
+ width <- Winfo.width canvas;
+ height <- Winfo.height canvas;
+ self#redraw
+ end;
+ (* Change direction with right button *)
+ bind canvas ~events:[`ButtonPressDetail 3]
+ ~action:(fun _ -> rflag <- -rflag; self#redraw);
+ (* Pack, expanding in both directions *)
+ pack ~fill:`Both ~expand:true [canvas]
+
+ (* Redraw everything *)
+ method redraw =
+ Canvas.coords_set canvas (`Tag "cadran")
+ ~xys:[ 1, 1; width - 2, height - 2 ];
+ self#draw_figures;
+ self#draw_arrows (Unix.localtime (Unix.time ()))
+
+ (* Delete and redraw the figures *)
+ method draw_figures =
+ Canvas.delete canvas [`Tag "figures"];
+ for i = 1 to 12 do
+ let angle = float (rflag * i - 3) *. pi /. 6. in
+ Canvas.create_text canvas
+ ~x:(self#x (0.8 *. cos angle)) ~y:(self#y (0.8 *. sin angle))
+ ~tags:["figures"]
+ ~text:(string_of_int i) ~font:"variable"
+ ~anchor:`Center
+ done
+
+ (* Resize and reposition the arrows *)
+ method draw_arrows tm =
+ Canvas.configure_line ~width:(min width height / 40)
+ canvas (`Tag "hours");
+ let hangle =
+ float (rflag * (tm.Unix.tm_hour * 60 + tm.Unix.tm_min) - 180)
+ *. pi /. 360. in
+ Canvas.coords_set canvas (`Tag "hours")
+ ~xys:[ self#x 0., self#y 0.;
+ self#x (cos hangle /. 2.), self#y (sin hangle /. 2.) ];
+ Canvas.configure_line ~width:(min width height / 50)
+ canvas (`Tag "minutes");
+ let mangle = float (rflag * tm.Unix.tm_min - 15) *. pi /. 30. in
+ Canvas.coords_set canvas (`Tag "minutes")
+ ~xys:[ self#x 0., self#y 0.;
+ self#x (cos mangle /. 1.5), self#y (sin mangle /. 1.5) ];
+ let sangle = float (rflag * tm.Unix.tm_sec - 15) *. pi /. 30. in
+ Canvas.coords_set canvas (`Tag "seconds")
+ ~xys:[ self#x 0., self#y 0.;
+ self#x (cos sangle /. 1.25), self#y (sin sangle /. 1.25) ]
+end
+
+(* Initialize the Tcl interpreter *)
+let top = openTk ()
+
+(* Create a clock on the main window *)
+let clock =
+ new clock ~parent:top
+
+(* Wait for events *)
+let _ = mainLoop ()
diff --git a/otherlibs/labltk/examples_labltk/demo.ml b/otherlibs/labltk/examples_labltk/demo.ml
new file mode 100644
index 000000000..2ccc448b1
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/demo.ml
@@ -0,0 +1,167 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Some CamlTk4 Demonstration by JPF *)
+
+(* First, open these modules for convenience *)
+open StdLabels
+open Tk
+
+(* Dummy let *)
+let _ =
+
+(* Initialize Tk *)
+let top = openTk () in
+(* Title setting *)
+Wm.title_set top "LablTk demo";
+
+(* Base frame *)
+let base = Frame.create top in
+pack [base];
+
+(* Menu bar *)
+let bar = Frame.create ~borderwidth:2 ~relief:`Raised base in
+pack ~fill:`X [bar];
+
+ (* Menu and Menubutton *)
+ let meb = Menubutton.create ~text:"Menu" bar in
+ let men = Menu.create meb in
+ Menu.add_command ~label:"Quit" ~command:(fun () -> closeTk (); exit 0) men;
+ Menubutton.configure ~menu:men meb;
+
+ (* Frames *)
+ let base2 = Frame.create base in
+ let left = Frame.create base2 in
+ let right = Frame.create base2 in
+ pack [base2];
+ pack ~side:`Left [left; right];
+
+ (* Widgets on left and right *)
+
+ (* Button *)
+ let but = Button.create ~text:"Welcome to LablTk" left in
+
+ (* Canvas *)
+ let can =
+ Canvas.create ~width:100 ~height:100 ~borderwidth:1 ~relief:`Sunken left
+ in
+ let oval = Canvas.create_oval ~x1: 10 ~y1: 10
+ ~x2: 90 ~y2: 90
+ ~fill: `Red
+ can
+ in ignore oval;
+
+ (* Check button *)
+ let che = Checkbutton.create ~text:"Check" left in
+
+ (* Entry *)
+ let ent = Entry.create ~width:10 left in
+
+ (* Label *)
+ let lab = Label.create ~text:"Welcome to LablTk" left in
+
+ (* Listbox *)
+ let lis = Listbox.create left in
+ Listbox.insert lis ~index:`End ~texts:["This"; "is"; "Listbox"];
+
+ (* Message *)
+ let mes = Message.create
+ ~text: "Hello this is a message widget with very long text, but ..."
+ left in
+
+ (* Radio buttons *)
+ let tv = Textvariable.create () in
+ Textvariable.set tv "One";
+ let radf = Frame.create right in
+ let rads = List.map
+ ~f:(fun t -> Radiobutton.create ~text:t ~value:t ~variable:tv radf)
+ ["One"; "Two"; "Three"] in
+
+ (* Scale *)
+ let sca = Scale.create ~label:"Scale" ~length:100 ~showvalue:true right in
+
+ (* Text and scrollbar *)
+ let texf = Frame.create right in
+
+ (* Text *)
+ let tex = Text.create ~width:20 ~height:8 texf in
+ Text.insert ~index:(`End,[]) ~text:"This is a text widget." tex;
+
+ (* Scrollbar *)
+ let scr = Scrollbar.create texf in
+
+ (* Text and Scrollbar widget link *)
+ let scroll_link sb tx =
+ Text.configure ~yscrollcommand:(Scrollbar.set sb) tx;
+ Scrollbar.configure ~command:(Text.yview tx) sb in
+ scroll_link scr tex;
+
+ pack ~side:`Right ~fill:`Y [scr];
+ pack ~side:`Left ~fill:`Both ~expand:true [tex];
+
+ (* Pack them *)
+ pack ~side:`Left [meb];
+ pack [coe but; coe can; coe che; coe ent; coe lab; coe lis; coe mes];
+ pack [coe radf; coe sca; coe texf];
+ pack rads;
+
+ (* Toplevel *)
+ let top2 = Toplevel.create top in
+ Wm.title_set top2 "LablTk demo control";
+ let defcol = `Color "#dfdfdf" in
+ let selcol = `Color "#ffdfdf" in
+ let buttons =
+ List.map ~f:(fun (w, t, c, a) ->
+ let b = Button.create ~text:t ~command:c top2 in
+ bind ~events:[`Enter] ~action:(fun _ -> a selcol) b;
+ bind ~events:[`Leave] ~action:(fun _ -> a defcol) b;
+ b)
+ [coe bar, "Frame", (fun () -> ()),
+ (fun background -> Frame.configure ~background bar);
+ coe meb, "Menubutton", (fun () -> ()),
+ (fun background -> Menubutton.configure ~background meb);
+ coe but, "Button", (fun () -> ()),
+ (fun background -> Button.configure ~background but);
+ coe can, "Canvas", (fun () -> ()),
+ (fun background -> Canvas.configure ~background can);
+ coe che, "CheckButton", (fun () -> ()),
+ (fun background -> Checkbutton.configure ~background che);
+ coe ent, "Entry", (fun () -> ()),
+ (fun background -> Entry.configure ~background ent);
+ coe lab, "Label", (fun () -> ()),
+ (fun background -> Label.configure ~background lab);
+ coe lis, "Listbox", (fun () -> ()),
+ (fun background -> Listbox.configure ~background lis);
+ coe mes, "Message", (fun () -> ()),
+ (fun background -> Message.configure ~background mes);
+ coe radf, "Radiobox", (fun () -> ()),
+ (fun background ->
+ List.iter ~f:(fun b -> Radiobutton.configure ~background b) rads);
+ coe sca, "Scale", (fun () -> ()),
+ (fun background -> Scale.configure ~background sca);
+ coe tex, "Text", (fun () -> ()),
+ (fun background -> Text.configure ~background tex);
+ coe scr, "Scrollbar", (fun () -> ()),
+ (fun background -> Scrollbar.configure ~background scr)
+ ]
+ in
+ pack ~fill:`X buttons;
+
+(* Main Loop *)
+Printexc.print mainLoop ()
+
diff --git a/otherlibs/labltk/examples_labltk/eyes.ml b/otherlibs/labltk/examples_labltk/eyes.ml
new file mode 100644
index 000000000..ce62159db
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/eyes.ml
@@ -0,0 +1,65 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Tk
+
+let _ =
+ let top = openTk () in
+ let fw = Frame.create top in
+ pack [fw];
+ let c = Canvas.create ~width: 200 ~height: 200 fw in
+ let create_eye cx cy wx wy ewx ewy bnd =
+ let o2 = Canvas.create_oval
+ ~x1:(cx - wx) ~y1:(cy - wy)
+ ~x2:(cx + wx) ~y2:(cy + wy)
+ ~outline: `Black ~width: 7
+ ~fill: `White
+ c
+ and o = Canvas.create_oval
+ ~x1:(cx - ewx) ~y1:(cy - ewy)
+ ~x2:(cx + ewx) ~y2:(cy + ewy)
+ ~fill:`Black
+ c in
+ let curx = ref cx
+ and cury = ref cy in
+ bind ~events:[`Motion] ~extend:true ~fields:[`MouseX; `MouseY]
+ ~action:(fun e ->
+ let nx, ny =
+ let xdiff = e.ev_MouseX - cx
+ and ydiff = e.ev_MouseY - cy in
+ let diff = sqrt ((float xdiff /. (float wx *. bnd)) ** 2.0 +.
+ (float ydiff /. (float wy *. bnd)) ** 2.0) in
+ if diff > 1.0 then
+ truncate ((float xdiff) *. (1.0 /. diff)) + cx,
+ truncate ((float ydiff) *. (1.0 /. diff)) + cy
+ else
+ e.ev_MouseX, e.ev_MouseY
+ in
+ Canvas.move c o ~x: (nx - !curx) ~y: (ny - !cury);
+ curx := nx;
+ cury := ny)
+ c
+ in
+ create_eye 60 100 30 40 5 6 0.6;
+ create_eye 140 100 30 40 5 6 0.6;
+ pack [c]
+
+let _ = Printexc.print mainLoop ()
+
+
+
diff --git a/otherlibs/labltk/examples_labltk/hello.ml b/otherlibs/labltk/examples_labltk/hello.ml
new file mode 100644
index 000000000..4a89d4806
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/hello.ml
@@ -0,0 +1,38 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* LablTk4 Demonstration by JPF *)
+
+(* First, open this modules for convenience *)
+open Tk
+
+(* initialization of Tk --- the result is a toplevel widget *)
+let top = openTk ()
+
+(* create a button on top *)
+(* Button.create : use of create function defined in button.ml *)
+(* But you shouldn't open Button module for other widget class modules use *)
+let b = Button.create ~text: "Hello, LablTk!" top
+
+(* Lack of toplevel expressions in lsl, you must use dummy let exp. *)
+let _ = pack [coe b]
+
+(* Last, you must call mainLoop *)
+(* You can write just let _ = mainLoop () *)
+(* But Printexc.print will help you *)
+let _ = Printexc.print mainLoop ()
diff --git a/otherlibs/labltk/examples_labltk/hello.tcl b/otherlibs/labltk/examples_labltk/hello.tcl
new file mode 100755
index 000000000..9e9985c15
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/hello.tcl
@@ -0,0 +1,5 @@
+#!/usr/local/bin/wish4.0
+
+button .hello -text "Hello, TclTk!"
+
+pack .hello
diff --git a/otherlibs/labltk/examples_labltk/lang.ml b/otherlibs/labltk/examples_labltk/lang.ml
new file mode 100644
index 000000000..53d2d5e51
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/lang.ml
@@ -0,0 +1,75 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* language encoding using UTF-8 *)
+open Tk
+
+let top = opentk ()
+
+(* declare Tk that we use utf-8 to communicate *)
+(* problem: Text display is highly dependent on your font installation
+ and configulation. The fonts with no-scale setting are selected
+ only if the point sizes are exactly same???
+*)
+let _ =
+ Encoding.system_set "utf-8";
+ let l = Label.create top ~text: "???" in
+ pack [l];
+ let t = Text.create top in
+ pack [t];
+
+ let create_hello lang hello =
+ let b = Button.create t ~text: lang ~command: (fun () ->
+ Label.configure l ~text: hello)
+ in
+ Text.window_create t ~index: (`End,[]) ~window: b
+ in
+ List.iter (fun (lang, hello) -> create_hello lang hello)
+ ["Amharic(አማርኛ)", "ሠላም";
+ "Arabic", "�����������";
+ "Croatian (Hrvatski)", "Bog (Bok), Dobar dan";
+ "Czech (česky)", "Dobrý den";
+ "Danish (Dansk)", "Hej, Goddag";
+ "English", "Hello";
+ "Esperanto", "Saluton";
+ "Estonian", "Tere, Tervist";
+ "FORTRAN", "PROGRAM";
+ "Finnish (Suomi)", "Hei";
+ "French (Français)", "Bonjour, Salut";
+ "German (Deutsch Nord)", "Guten Tag";
+ "German (Deutsch Süd)", "Grüß Gott";
+ "Greek (Ελληνικά)", "Γειά σας";
+ "Hebrew", "שלום";
+ "Italiano", "Ciao, Buon giorno";
+ "Maltese", "Ciao";
+ "Nederlands, Vlaams", "Hallo, Hoi, Goedendag";
+ "Norwegian (Norsk)", "Hei, God dag";
+ "Polish", "Cześć!";
+ "Russian (Русский)", "Здравствуйте!";
+ "Slovak", "Dobrý deň";
+ "Spanish (Español)", "¡Hola!";
+ "Swedish (Svenska)", "Hej, Goddag";
+ "Thai (�������)", "�������, ������";
+ "Tigrigna (ትግርኛ)", "ሰላማት";
+ "Turkish (Türkçe)", "Merhaba";
+ "Vietnamese (Tiếng Việt)", "Chào bạn";
+ "Japanese (日本語)", "こんにちは";
+ "Chinese (中文,普通话,汉语)", "你好";
+ "Cantonese (粵語,廣東話)", "早晨, 你好";
+ "Hangul (한글)", "안녕하세요, 안녕하십니까" ]
+;;
+
+let _ = Printexc.print mainLoop ()
diff --git a/otherlibs/labltk/examples_labltk/taquin.ml b/otherlibs/labltk/examples_labltk/taquin.ml
new file mode 100644
index 000000000..a3bcbb1bf
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/taquin.ml
@@ -0,0 +1,143 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Tk;;
+
+let d�coupe_image img nx ny =
+ let l = Imagephoto.width img
+ and h = Imagephoto.height img in
+ let tx = l / nx and ty = h / ny in
+ let pi�ces = ref [] in
+ for x = 0 to nx - 1 do
+ for y = 0 to ny - 1 do
+ let pi�ce = Imagephoto.create ~width:tx ~height:ty () in
+ Imagephoto.copy ~src:img
+ ~src_area:(x * tx, y * ty, (x + 1) * tx, (y + 1) * ty) pi�ce;
+ pi�ces := pi�ce :: !pi�ces
+ done
+ done;
+ (tx, ty, List.tl !pi�ces);;
+
+let remplir_taquin c nx ny tx ty pi�ces =
+ let trou_x = ref (nx - 1)
+ and trou_y = ref (ny - 1) in
+ let trou =
+ Canvas.create_rectangle
+ ~x1:(!trou_x * tx) ~y1:(!trou_y * ty) ~x2:tx ~y2:ty c in
+ let taquin = Array.make_matrix nx ny trou in
+ let p = ref pi�ces in
+ for x = 0 to nx - 1 do
+ for y = 0 to ny - 1 do
+ match !p with
+ | [] -> ()
+ | pi�ce :: reste ->
+ taquin.(x).(y) <-
+ Canvas.create_image
+ ~x:(x * tx) ~y:(y * ty)
+ ~image:pi�ce ~anchor:`Nw ~tags:["pi�ce"] c;
+ p := reste
+ done
+ done;
+ let d�placer x y =
+ let pi�ce = taquin.(x).(y) in
+ Canvas.coords_set c pi�ce
+ ~xys:[!trou_x * tx, !trou_y * ty];
+ Canvas.coords_set c trou
+ ~xys:[x * tx, y * ty; tx, ty];
+ taquin.(!trou_x).(!trou_y) <- pi�ce;
+ taquin.(x).(y) <- trou;
+ trou_x := x; trou_y := y in
+ let jouer ei =
+ let x = ei.ev_MouseX / tx and y = ei.ev_MouseY / ty in
+ if x = !trou_x && (y = !trou_y - 1 || y = !trou_y + 1)
+ || y = !trou_y && (x = !trou_x - 1 || x = !trou_x + 1)
+ then d�placer x y in
+ Canvas.bind ~events:[`ButtonPress]
+ ~fields:[`MouseX; `MouseY] ~action:jouer c (`Tag "pi�ce");;
+
+let rec permutation = function
+ | [] -> []
+ | l -> let n = Random.int (List.length l) in
+ let (�l�ment, reste) = partage l n in
+ �l�ment :: permutation reste
+
+and partage l n =
+ match l with
+ | [] -> failwith "partage"
+ | t�te :: reste ->
+ if n = 0 then (t�te, reste) else
+ let (�l�ment, reste') = partage reste (n - 1) in
+ (�l�ment, t�te :: reste');;
+
+let create_filled_text parent lines =
+ let lnum = List.length lines
+ and lwidth =
+ List.fold_right
+ (fun line max ->
+ let l = String.length line in
+ if l > max then l else max)
+ lines 1 in
+ let txtw = Text.create ~width:lwidth ~height:lnum parent in
+ List.iter
+ (fun line ->
+ Text.insert ~index:(`End, []) ~text:line txtw;
+ Text.insert ~index:(`End, []) ~text:"\n" txtw)
+ lines;
+ txtw;;
+
+let give_help parent lines () =
+ let help_window = Toplevel.create parent in
+ Wm.title_set help_window "Help";
+
+ let help_frame = Frame.create help_window in
+
+ let help_txtw = create_filled_text help_frame lines in
+
+ let quit_help () = destroy help_window in
+ let ok_button = Button.create ~text:"Ok" ~command:quit_help help_frame in
+
+ pack ~side:`Bottom [help_txtw];
+ pack ~side:`Bottom [ok_button ];
+ pack [help_frame];;
+
+let taquin nom_fichier nx ny =
+ let fp = openTk () in
+ Wm.title_set fp "Taquin";
+ let img = Imagephoto.create ~file:nom_fichier () in
+ let c =
+ Canvas.create ~background:`Black
+ ~width:(Imagephoto.width img)
+ ~height:(Imagephoto.height img) fp in
+ let (tx, ty, pi�ces) = d�coupe_image img nx ny in
+ remplir_taquin c nx ny tx ty (permutation pi�ces);
+ pack [c];
+
+ let quit = Button.create ~text:"Quit" ~command:closeTk fp in
+ let help_lines =
+ ["Pour jouer, cliquer sur une des pi�ces";
+ "entourant le trou";
+ "";
+ "To play, click on a part around the hole"] in
+ let help =
+ Button.create ~text:"Help" ~command:(give_help fp help_lines) fp in
+ pack ~side:`Left ~fill:`X [quit] ;
+ pack ~side:`Left ~fill:`X [help] ;
+ mainLoop ();;
+
+if !Sys.interactive then () else
+begin taquin "Lambda2.back.gif" 4 4; exit 0 end;;
diff --git a/otherlibs/labltk/examples_labltk/tetris.ml b/otherlibs/labltk/examples_labltk/tetris.ml
new file mode 100644
index 000000000..3e3f1e8a4
--- /dev/null
+++ b/otherlibs/labltk/examples_labltk/tetris.ml
@@ -0,0 +1,710 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* A Tetris game for LablTk *)
+(* written by Jun P. Furuse *)
+
+open StdLabels
+open Tk
+
+exception Done
+
+type falling_block = {
+ mutable pattern: int array list;
+ mutable bcolor: int;
+ mutable x: int;
+ mutable y: int;
+ mutable d: int;
+ mutable alive: bool
+ }
+
+let stop_a_bit = 300
+
+let field_width = 10
+let field_height = 20
+
+let colors = [|
+ `Color "red";
+ `Color "yellow";
+
+ `Color "blue";
+ `Color "orange";
+
+ `Color "magenta";
+ `Color "green";
+
+ `Color "cyan"
+|]
+
+(* Put here your favorite image files *)
+let backgrounds = [
+ "Lambda2.back.gif"
+]
+
+(* blocks *)
+let block_size = 16
+let cell_border = 2
+
+let blocks = [
+ [ [|"0000";
+ "0000";
+ "1111";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0010";
+ "0010" |];
+
+ [|"0000";
+ "0000";
+ "1111";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0010";
+ "0010" |] ];
+
+ [ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0111";
+ "0100";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0010";
+ "0010" |];
+
+ [|"0000";
+ "0010";
+ "1110";
+ "0000" |];
+
+ [|"0100";
+ "0100";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0100";
+ "0111";
+ "0000" |];
+
+ [|"0000";
+ "0110";
+ "0100";
+ "0100" |];
+
+ [|"0000";
+ "1110";
+ "0010";
+ "0000" |];
+
+ [|"0010";
+ "0010";
+ "0110";
+ "0000" |] ];
+
+ [ [|"0000";
+ "1100";
+ "0110";
+ "0000" |];
+
+ [|"0010";
+ "0110";
+ "0100";
+ "0000" |];
+
+ [|"0000";
+ "1100";
+ "0110";
+ "0000" |];
+
+ [|"0010";
+ "0110";
+ "0100";
+ "0000" |] ];
+
+ [ [|"0000";
+ "0011";
+ "0110";
+ "0000" |];
+
+ [|"0100";
+ "0110";
+ "0010";
+ "0000" |];
+
+ [|"0000";
+ "0011";
+ "0110";
+ "0000" |];
+
+ [|"0000";
+ "0100";
+ "0110";
+ "0010" |] ];
+
+ [ [|"0000";
+ "0000";
+ "1110";
+ "0100" |];
+
+ [|"0000";
+ "0100";
+ "1100";
+ "0100" |];
+
+ [|"0000";
+ "0100";
+ "1110";
+ "0000" |];
+
+ [|"0000";
+ "0100";
+ "0110";
+ "0100" |] ]
+
+]
+
+let line_empty = int_of_string "0b1110000000000111"
+let line_full = int_of_string "0b1111111111111111"
+
+let decode_block dvec =
+ let btoi d = int_of_string ("0b"^d) in
+ Array.map ~f:btoi dvec
+
+class cell t1 t2 t3 ~canvas ~x ~y = object
+ val mutable color = 0
+ method get = color
+ method set ~color:col =
+ if color = col then () else
+ if color <> 0 && col = 0 then begin
+ Canvas.move canvas t1
+ ~x:(- block_size * (x + 1) -10 - cell_border * 2)
+ ~y:(- block_size * (y + 1) -10 - cell_border * 2);
+ Canvas.move canvas t2
+ ~x:(- block_size * (x + 1) -10 - cell_border * 2)
+ ~y:(- block_size * (y + 1) -10 - cell_border * 2);
+ Canvas.move canvas t3
+ ~x:(- block_size * (x + 1) -10 - cell_border * 2)
+ ~y:(- block_size * (y + 1) -10 - cell_border * 2)
+ end else begin
+ Canvas.configure_rectangle canvas t2
+ ~fill: colors.(col - 1)
+ ~outline: colors.(col - 1);
+ Canvas.configure_rectangle canvas t1
+ ~fill: `Black
+ ~outline: `Black;
+ Canvas.configure_rectangle canvas t3
+ ~fill: (`Color "light gray")
+ ~outline: (`Color "light gray");
+ if color = 0 && col <> 0 then begin
+ Canvas.move canvas t1
+ ~x: (block_size * (x+1)+10+ cell_border*2)
+ ~y: (block_size * (y+1)+10+ cell_border*2);
+ Canvas.move canvas t2
+ ~x: (block_size * (x+1)+10+ cell_border*2)
+ ~y: (block_size * (y+1)+10+ cell_border*2);
+ Canvas.move canvas t3
+ ~x: (block_size * (x+1)+10+ cell_border*2)
+ ~y: (block_size * (y+1)+10+ cell_border*2)
+ end
+ end;
+ color <- col
+end
+
+let cell_get (c, cf) x y = cf.(y).(x) #get
+
+let cell_set (c, cf) ~x ~y ~color =
+ if x >= 0 && y >= 0 && Array.length cf > y && Array.length cf.(y) > x then
+ let cur = cf.(y).(x) in
+ if cur#get = color then () else cur#set ~color
+
+let create_base_matrix ~cols ~rows =
+ let m = Array.create_matrix ~dimx:rows ~dimy:cols (0,0) in
+ for x = 0 to cols - 1 do for y = 0 to rows - 1 do
+ m.(y).(x) <- (x,y)
+ done done;
+ m
+
+let init fw =
+ let scorev = Textvariable.create ()
+ and linev = Textvariable.create ()
+ and levv = Textvariable.create ()
+ and namev = Textvariable.create ()
+ in
+ let f = Frame.create fw ~borderwidth: 2 in
+ let c = Canvas.create f ~width: (block_size * 10)
+ ~height: (block_size * 20)
+ ~borderwidth: cell_border
+ ~relief: `Sunken
+ ~background: `Black
+ and r = Frame.create f
+ and r' = Frame.create f in
+
+ let nl = Label.create r ~text: "Next" ~font: "variable" in
+ let nc = Canvas.create r ~width: (block_size * 4)
+ ~height: (block_size * 4)
+ ~borderwidth: cell_border
+ ~relief: `Sunken
+ ~background: `Black in
+ let scl = Label.create r ~text: "Score" ~font: "variable" in
+ let sc = Label.create r ~textvariable: scorev ~font: "variable" in
+ let lnl = Label.create r ~text: "Lines" ~font: "variable" in
+ let ln = Label.create r ~textvariable: linev ~font: "variable" in
+ let levl = Label.create r ~text: "Level" ~font: "variable" in
+ let lev = Label.create r ~textvariable: levv ~font: "variable" in
+ let newg = Button.create r ~text: "New Game" ~font: "variable" in
+
+ pack [f];
+ pack [coe c; coe r; coe r'] ~side: `Left ~fill: `Y;
+ pack [coe nl; coe nc] ~side: `Top;
+ pack [coe scl; coe sc; coe lnl; coe ln; coe levl; coe lev; coe newg]
+ ~side: `Top;
+
+ let cells_src = create_base_matrix ~cols:field_width ~rows:field_height in
+ let cells =
+ Array.map cells_src ~f:
+ (Array.map ~f:
+ begin fun (x,y) ->
+ let t1 =
+ Canvas.create_rectangle c
+ ~x1:(-block_size - 8) ~y1:(-block_size - 8)
+ ~x2:(-9) ~y2:(-9)
+ and t2 =
+ Canvas.create_rectangle c
+ ~x1:(-block_size - 10) ~y1:(-block_size - 10)
+ ~x2:(-11) ~y2:(-11)
+ and t3 =
+ Canvas.create_rectangle c
+ ~x1:(-block_size - 12) ~y1:(-block_size - 12)
+ ~x2:(-13) ~y2:(-13)
+ in
+ Canvas.raise c t1;
+ Canvas.raise c t2;
+ Canvas.lower c t3;
+ new cell ~canvas:c ~x ~y t1 t2 t3
+ end)
+ in
+ let nexts_src = create_base_matrix ~cols:4 ~rows:4 in
+ let nexts =
+ Array.map nexts_src ~f:
+ (Array.map ~f:
+ begin fun (x,y) ->
+ let t1 =
+ Canvas.create_rectangle nc
+ ~x1:(-block_size - 8) ~y1:(-block_size - 8)
+ ~x2:(-9) ~y2:(-9)
+ and t2 =
+ Canvas.create_rectangle nc
+ ~x1:(-block_size - 10) ~y1:(-block_size - 10)
+ ~x2:(-11) ~y2:(-11)
+ and t3 =
+ Canvas.create_rectangle nc
+ ~x1:(-block_size - 12) ~y1:(-block_size - 12)
+ ~x2:(-13) ~y2:(-13)
+ in
+ Canvas.raise nc t1;
+ Canvas.raise nc t2;
+ Canvas.lower nc t3;
+ new cell ~canvas:nc ~x ~y t1 t2 t3
+ end)
+ in
+ let game_over () = ()
+ in
+ (* What a mess ! *)
+ [ coe f; coe c; coe r; coe nl; coe nc; coe scl; coe sc; coe levl; coe lev;
+ coe lnl; coe ln ],
+ newg, (c, cells), (nc, nexts), scorev, linev, levv, game_over
+
+
+let draw_block field ~color ~block ~x ~y =
+ for iy = 0 to 3 do
+ let base = ref 1 in
+ let xd = block.(iy) in
+ for ix = 0 to 3 do
+ if xd land !base <> 0 then
+ cell_set field ~x:(ix + x) ~y:(iy + y) ~color;
+ base := !base lsl 1
+ done
+ done
+
+let timer_ref = (ref None : Timer.t option ref)
+(* I know, this should be timer ref, but I'm not sure what should be
+ the initial value ... *)
+
+let remove_timer () =
+ match !timer_ref with
+ None -> ()
+ | Some t -> Timer.remove t (* ; prerr_endline "removed!" *)
+
+let do_after ~ms ~callback =
+ timer_ref := Some (Timer.add ~ms ~callback)
+
+let copy_block c =
+ { pattern= !c.pattern;
+ bcolor= !c.bcolor;
+ x= !c.x;
+ y= !c.y;
+ d= !c.d;
+ alive= !c.alive }
+
+let _ =
+ let top = openTk () in
+ let lb = Label.create top
+ and fw = Frame.create top
+ in
+ let set_message s = Label.configure lb ~text:s in
+ pack [coe lb; coe fw] ~side: `Top;
+ let score = ref 0 in
+ let line = ref 0 in
+ let level = ref 0 in
+ let time = ref 1000 in
+ let blocks = List.map ~f:(List.map ~f:decode_block) blocks in
+ let field = Array.create 26 0 in
+ let widgets, button, cell_field, next_field, scorev, linev, levv, game_over
+ = init fw in
+ let canvas = fst cell_field in
+
+ let init_field () =
+ for i = 0 to 25 do
+ field.(i) <- line_empty
+ done;
+ field.(23) <- line_full;
+ for i = 0 to 19 do
+ for j = 0 to 9 do
+ cell_set cell_field ~x:j ~y:i ~color:0
+ done
+ done;
+ for i = 0 to 3 do
+ for j = 0 to 3 do
+ cell_set next_field ~x:j ~y:i ~color:0
+ done
+ done
+ in
+
+ let draw_falling_block fb =
+ draw_block cell_field ~color: fb.bcolor
+ ~block: (List.nth fb.pattern fb.d)
+ ~x: (fb.x - 3)
+ ~y: (fb.y - 3)
+
+ and erase_falling_block fb =
+ draw_block cell_field ~color: 0
+ ~block: (List.nth fb.pattern fb.d)
+ ~x: (fb.x - 3)
+ ~y: (fb.y - 3)
+ in
+
+ let stone fb =
+ for i=0 to 3 do
+ let cur = field.(i + fb.y) in
+ field.(i + fb.y) <-
+ cur lor ((List.nth fb.pattern fb.d).(i) lsl fb.x)
+ done;
+ for i=0 to 2 do
+ field.(i) <- line_empty
+ done
+
+ and clear fb =
+ let l = ref 0 in
+ for i = 0 to 3 do
+ if i + fb.y >= 3 && i + fb.y <= 22 then
+ if field.(i + fb.y) = line_full then
+ begin
+ incr l;
+ field.(i + fb.y) <- line_empty;
+ for j = 0 to 9 do
+ cell_set cell_field ~x:j ~y:(i + fb.y - 3) ~color:0
+ done
+ end
+ done;
+ !l
+
+ and fall_lines () =
+ let eye = ref 22 (* bottom *)
+ and cur = ref 22 (* bottom *)
+ in
+ try
+ while !eye >= 3 do
+ while field.(!eye) = line_empty do
+ decr eye;
+ if !eye = 2 then raise Done
+ done;
+ field.(!cur) <- field.(!eye);
+ for j = 0 to 9 do
+ cell_set cell_field ~x:j ~y:(!cur-3)
+ ~color:(cell_get cell_field j (!eye-3))
+ done;
+ decr eye;
+ decr cur
+ done
+ with Done -> ();
+ for i = 3 to !cur do
+ field.(i) <- line_empty;
+ for j = 0 to 9 do
+ cell_set cell_field ~x:j ~y:(i-3) ~color:0
+ done
+ done
+ in
+
+ let next = ref 42 (* THE ANSWER *)
+ and current =
+ ref { pattern= [[|0;0;0;0|]]; bcolor=0; x=0; y=0; d=0; alive= false}
+ in
+
+ let draw_next () =
+ draw_block next_field ~color: (!next+1)
+ ~block: (List.hd (List.nth blocks !next))
+ ~x: 0 ~y: 0
+
+ and erase_next () =
+ draw_block next_field ~color: 0
+ ~block: (List.hd (List.nth blocks !next))
+ ~x: 0 ~y: 0
+ in
+
+ let set_nextblock () =
+ current :=
+ { pattern= (List.nth blocks !next);
+ bcolor= !next+1;
+ x=6; y= 1; d= 0; alive= true};
+ erase_next ();
+ next := Random.int 7;
+ draw_next ()
+ in
+
+ let death_check fb =
+ try
+ for i=0 to 3 do
+ let cur = field.(i + fb.y) in
+ if cur land ((List.nth fb.pattern fb.d).(i) lsl fb.x) <> 0
+ then raise Done
+ done;
+ false
+ with
+ Done -> true
+ in
+
+ let try_to_move m =
+ if !current.alive then
+ let sub m =
+ if death_check m then false
+ else
+ begin
+ erase_falling_block !current;
+ draw_falling_block m;
+ current := m;
+ true
+ end
+ in
+ if sub m then true
+ else
+ begin
+ m.x <- m.x + 1;
+ if sub m then true
+ else
+ begin
+ m.x <- m.x - 2;
+ sub m
+ end
+ end
+ else false
+ in
+
+ let image_load =
+ let i = Canvas.create_image canvas
+ ~x: (block_size * 5 + block_size / 2)
+ ~y: (block_size * 10 + block_size / 2)
+ ~anchor: `Center in
+ Canvas.lower canvas i;
+ let img = Imagephoto.create () in
+ fun file ->
+ try
+ Imagephoto.configure img ~file: file;
+ Canvas.configure_image canvas i ~image: img
+ with
+ _ ->
+ begin
+ Printf.eprintf "%s : No such image...\n" file;
+ flush stderr
+ end
+ in
+
+ let add_score l =
+ let pline = !line in
+ if l <> 0 then
+ begin
+ line := !line + l;
+ score := !score + l * l;
+ set_message (Printf.sprintf "%d pts" (1 lsl ((l - 1) * 2)))
+ end;
+ Textvariable.set linev (string_of_int !line);
+ Textvariable.set scorev (string_of_int !score);
+
+ if !line /10 <> pline /10 then
+ (* update the background every 10 lines. *)
+ begin
+ let num_image = List.length backgrounds - 1 in
+ let n = !line/10 in
+ let n = if n > num_image then num_image else n in
+ let file = List.nth backgrounds n in
+ image_load file;
+ incr level;
+ Textvariable.set levv (string_of_int !level)
+ end
+ in
+
+ let rec newblock () =
+ set_message "TETRIS";
+ set_nextblock ();
+ draw_falling_block !current;
+ if death_check !current then
+ begin
+ !current.alive <- false;
+ set_message "GAME OVER";
+ game_over ()
+ end
+ else
+ begin
+ time := 1100 - (!level / 4 * 300) - ((!level mod 4) * 200);
+ if !time < 60 - !level * 3 then time := 60 - !level * 3;
+ do_after ~ms:stop_a_bit ~callback:loop
+ end
+
+ and loop () =
+ let m = copy_block current in
+ m.y <- m.y + 1;
+ if death_check m then
+ begin
+ !current.alive <- false;
+ stone !current;
+ do_after ~ms:stop_a_bit ~callback:
+ begin fun () ->
+ let l = clear !current in
+ if l > 0 then
+ do_after ~ms:stop_a_bit ~callback:
+ begin fun () ->
+ fall_lines ();
+ add_score l;
+ do_after ~ms:stop_a_bit ~callback:newblock
+ end
+ else
+ newblock ()
+ end
+ end
+ else
+ begin
+ erase_falling_block !current;
+ draw_falling_block m;
+ current := m;
+ do_after ~ms:!time ~callback:loop
+ end
+ in
+
+ let bind_game w =
+ bind w ~events:[`KeyPress] ~fields:[`KeySymString] ~action:
+ begin fun e ->
+ match e.ev_KeySymString with
+ | "h" ->
+ let m = copy_block current in
+ m.x <- m.x - 1;
+ ignore (try_to_move m)
+ | "j" ->
+ let m = copy_block current in
+ m.d <- m.d + 1;
+ if m.d = List.length m.pattern then m.d <- 0;
+ ignore (try_to_move m)
+ | "k" ->
+ let m = copy_block current in
+ m.d <- m.d - 1;
+ if m.d < 0 then m.d <- List.length m.pattern - 1;
+ ignore (try_to_move m)
+ | "l" ->
+ let m = copy_block current in
+ m.x <- m.x + 1;
+ ignore (try_to_move m)
+ | "m" ->
+ remove_timer ();
+ loop ()
+ | "space" ->
+ if !current.alive then
+ begin
+ let m = copy_block current
+ and n = copy_block current in
+ while
+ m.y <- m.y + 1;
+ if death_check m then false
+ else begin n.y <- m.y; true end
+ do () done;
+ erase_falling_block !current;
+ draw_falling_block n;
+ current := n;
+ remove_timer ();
+ loop ()
+ end
+ | _ -> ()
+ end
+ in
+
+ let game_init () =
+ (* Game Initialization *)
+ set_message "Initializing ...";
+ remove_timer ();
+ image_load (List.hd backgrounds);
+ time := 1000;
+ score := 0;
+ line := 0;
+ level := 1;
+ add_score 0;
+ init_field ();
+ next := Random.int 7;
+ set_message "Welcome to TETRIS";
+ set_nextblock ();
+ draw_falling_block !current;
+ do_after ~ms:!time ~callback:loop
+ in
+ (* As an applet, it was required... *)
+ (* List.iter f: bind_game widgets; *)
+ bind_game top;
+ Button.configure button ~command: game_init;
+ game_init ()
+
+let _ = Printexc.print mainLoop ()
diff --git a/otherlibs/labltk/frx/.depend b/otherlibs/labltk/frx/.depend
new file mode 100644
index 000000000..d815ab0eb
--- /dev/null
+++ b/otherlibs/labltk/frx/.depend
@@ -0,0 +1,38 @@
+frx_after.cmo: frx_after.cmi
+frx_after.cmx: frx_after.cmi
+frx_color.cmo: frx_color.cmi
+frx_color.cmx: frx_color.cmi
+frx_ctext.cmo: frx_fit.cmi frx_text.cmi frx_ctext.cmi
+frx_ctext.cmx: frx_fit.cmx frx_text.cmx frx_ctext.cmi
+frx_dialog.cmo: frx_dialog.cmi
+frx_dialog.cmx: frx_dialog.cmi
+frx_entry.cmo: frx_entry.cmi
+frx_entry.cmx: frx_entry.cmi
+frx_fillbox.cmo: frx_fillbox.cmi
+frx_fillbox.cmx: frx_fillbox.cmi
+frx_fit.cmo: frx_after.cmi frx_fit.cmi
+frx_fit.cmx: frx_after.cmx frx_fit.cmi
+frx_focus.cmo: frx_focus.cmi
+frx_focus.cmx: frx_focus.cmi
+frx_font.cmo: frx_misc.cmi frx_font.cmi
+frx_font.cmx: frx_misc.cmx frx_font.cmi
+frx_lbutton.cmo: frx_lbutton.cmi
+frx_lbutton.cmx: frx_lbutton.cmi
+frx_listbox.cmo: frx_listbox.cmi
+frx_listbox.cmx: frx_listbox.cmi
+frx_mem.cmo: frx_mem.cmi
+frx_mem.cmx: frx_mem.cmi
+frx_misc.cmo: frx_misc.cmi
+frx_misc.cmx: frx_misc.cmi
+frx_req.cmo: frx_entry.cmi frx_listbox.cmi frx_widget.cmi frx_req.cmi
+frx_req.cmx: frx_entry.cmx frx_listbox.cmx frx_widget.cmx frx_req.cmi
+frx_rpc.cmo: frx_rpc.cmi
+frx_rpc.cmx: frx_rpc.cmi
+frx_selection.cmo: frx_selection.cmi
+frx_selection.cmx: frx_selection.cmi
+frx_synth.cmo: frx_synth.cmi
+frx_synth.cmx: frx_synth.cmi
+frx_text.cmo: frx_misc.cmi frx_text.cmi
+frx_text.cmx: frx_misc.cmx frx_text.cmi
+frx_widget.cmo: frx_widget.cmi
+frx_widget.cmx: frx_widget.cmi
diff --git a/otherlibs/labltk/frx/Makefile b/otherlibs/labltk/frx/Makefile
new file mode 100644
index 000000000..226ba129f
--- /dev/null
+++ b/otherlibs/labltk/frx/Makefile
@@ -0,0 +1,51 @@
+include ../support/Makefile.common
+
+COMPFLAGS=-I ../camltk -I ../support -I $(OTHERS)/unix
+
+OBJS= frx_misc.cmo frx_widget.cmo frx_font.cmo frx_entry.cmo frx_text.cmo \
+ frx_listbox.cmo frx_req.cmo frx_fillbox.cmo frx_focus.cmo \
+ frx_dialog.cmo frx_mem.cmo frx_rpc.cmo frx_synth.cmo frx_selection.cmo \
+ frx_after.cmo frx_fit.cmo frx_ctext.cmo frx_color.cmo
+
+OBJSX = $(OBJS:.cmo=.cmx)
+
+all: frxlib.cma
+
+opt: frxlib.cmxa
+
+frxlib.cma: $(OBJS)
+ $(CAMLLIBR) -o frxlib.cma $(OBJS)
+
+frxlib.cmxa: $(OBJSX)
+ $(CAMLOPTLIBR) -o frxlib.cmxa $(OBJSX)
+
+install: frxlib.cma
+ cp *.cmi *.mli frxlib.cma $(INSTALLDIR)
+
+installopt: frxlib.cmxa
+ cp frxlib.cmxa frxlib.a $(INSTALLDIR)
+
+clean:
+ rm -f *.cm* *.o *.a
+
+$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma
+
+$(OBJSX): ../lib/$(LIBNAME).cmxa
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo .cmx
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+
+depend:
+ $(CAMLDEP) *.mli *.ml > .depend
+
+include .depend
diff --git a/otherlibs/labltk/frx/Makefile.nt b/otherlibs/labltk/frx/Makefile.nt
new file mode 100644
index 000000000..bf624ee16
--- /dev/null
+++ b/otherlibs/labltk/frx/Makefile.nt
@@ -0,0 +1,53 @@
+!include ..\support\Makefile.common.nt
+
+COMPFLAGS=-I ../camltk -I ../support
+
+OBJS= frx_misc.cmo frx_widget.cmo frx_font.cmo frx_entry.cmo frx_text.cmo \
+ frx_listbox.cmo frx_req.cmo frx_fillbox.cmo frx_focus.cmo \
+ frx_dialog.cmo frx_mem.cmo frx_rpc.cmo frx_synth.cmo frx_selection.cmo \
+ frx_after.cmo frx_fit.cmo frx_ctext.cmo frx_color.cmo
+
+OBJSX = $(OBJS:.cmo=.cmx)
+
+all: libfrx.cma
+
+opt: libfrx.cmxa
+
+libfrx.cma: $(OBJS)
+ $(CAMLLIBR) -o libfrx.cma $(OBJS)
+
+libfrx.cmxa: $(OBJSX)
+ $(CAMLOPTLIBR) -o libfrx.cmxa $(OBJSX)
+
+
+install: libfrx.cma
+ cp *.cmi *.mli libfrx.cma $(INSTALLDIR)
+
+installopt: libfrx.cmxa
+ cp libfrx.cmxa libfrx.lib $(INSTALLDIR)
+
+
+clean:
+ rm -f *.cm* *.obj *.a *~ *test *.lib
+
+$(OBJS) $(OBJS:.cmo=.cmi): ..\lib\$(LIBNAME).cma
+
+$(OBJSX): ..\lib\$(LIBNAME).cmxa
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo .cmx
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+
+depend:
+ $(CAMLDEP) *.mli *.ml > .depend
+
+!include .depend
diff --git a/otherlibs/labltk/frx/README b/otherlibs/labltk/frx/README
new file mode 100644
index 000000000..b86f8dcd8
--- /dev/null
+++ b/otherlibs/labltk/frx/README
@@ -0,0 +1,2 @@
+This is Francois Rouaix's widget set library, Frx.
+It uses CamlTk API. \ No newline at end of file
diff --git a/otherlibs/labltk/frx/frx_after.ml b/otherlibs/labltk/frx/frx_after.ml
new file mode 100644
index 000000000..955f1cb48
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_after.ml
@@ -0,0 +1,24 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Protocol
+let idle f =
+ let id = new_function_id () in
+ let wrapped _ =
+ clear_callback id; (* do it first in case f raises exception *)
+ f() in
+ Hashtbl.add callback_naming_table id wrapped;
+ tkCommand [| TkToken "after"; TkToken "idle";
+ TkToken ("camlcb "^ string_of_cbid id) |]
diff --git a/otherlibs/labltk/frx/frx_after.mli b/otherlibs/labltk/frx/frx_after.mli
new file mode 100644
index 000000000..73c07f7bb
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_after.mli
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val idle : (unit -> unit) -> unit
+ (* [idle f] is equivalent to Tk "after idle {camlcb f}" *)
diff --git a/otherlibs/labltk/frx/frx_color.ml b/otherlibs/labltk/frx/frx_color.ml
new file mode 100644
index 000000000..4df3eb6b4
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_color.ml
@@ -0,0 +1,35 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Protocol
+
+module StringSet = Set.Make(struct type t = string let compare = compare end)
+
+(* should we keep a negative cache ? *)
+let available_colors = ref (StringSet.empty)
+
+let check s =
+ if StringSet.mem s !available_colors then true
+ else begin
+ try
+ let f = Frame.create_named Widget.default_toplevel "frxcolorcheck"
+ [Background (NamedColor s)] in
+ available_colors := StringSet.add s !available_colors;
+ destroy f;
+ true
+ with
+ TkError _ -> false
+ end
diff --git a/otherlibs/labltk/frx/frx_color.mli b/otherlibs/labltk/frx/frx_color.mli
new file mode 100644
index 000000000..513cb0839
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_color.mli
@@ -0,0 +1,16 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val check : string -> bool
diff --git a/otherlibs/labltk/frx/frx_ctext.ml b/otherlibs/labltk/frx/frx_ctext.ml
new file mode 100644
index 000000000..01ede5457
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_ctext.ml
@@ -0,0 +1,66 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* A trick by Steve Ball to do pixel scrolling on text widgets *)
+(* USES frx_fit *)
+open Camltk
+
+let create top opts navigation =
+ let f = Frame.create top [BorderWidth (Pixels 2); Relief Raised] in
+ let lf = Frame.create f [] in
+ let rf = Frame.create f [] in
+ let c = Canvas.create lf [BorderWidth (Pixels 0)]
+ and xscroll = Scrollbar.create lf [Orient Horizontal]
+ and yscroll = Scrollbar.create rf [Orient Vertical]
+ and secret = Frame.create_named rf "secret" []
+ in
+ let t = Text.create c (BorderWidth(Pixels 0) :: opts) in
+ if navigation then Frx_text.navigation_keys t;
+
+ (* Make the text widget an embedded canvas object *)
+ ignore
+ (Canvas.create_window c (Pixels 0) (Pixels 0)
+ [Anchor NW; Window t; Tags [Tag "main"]]);
+ Canvas.focus c (Tag "main");
+ (*
+ Canvas.configure c [Width (Pixels (Winfo.reqwidth t));
+ Height(Pixels (Winfo.reqheight t))];
+ *)
+ Canvas.configure c [YScrollCommand (Scrollbar.set yscroll)];
+ (* The horizontal scrollbar is directly attached to the
+ * text widget, because h scrolling works properly *)
+ Scrollbar.configure xscroll [ScrollCommand (Text.xview t)];
+ (* But vertical scroll is attached to the canvas *)
+ Scrollbar.configure yscroll [ScrollCommand (Canvas.yview c)];
+ let scroll, check = Frx_fit.vert t in
+ Text.configure t [
+ XScrollCommand (Scrollbar.set xscroll);
+ YScrollCommand (fun first last ->
+ scroll first last;
+ let x,y,w,h = Canvas.bbox c [Tag "main"] in
+ Canvas.configure c
+ [ScrollRegion (Pixels x, Pixels y, Pixels w, Pixels h)])
+ ];
+
+ bind c [[],Configure] (BindSet ([Ev_Width], (fun ei ->
+ Canvas.configure_window c (Tag "main") [Width (Pixels ei.ev_Width)])));
+
+ pack [rf] [Side Side_Right; Fill Fill_Y];
+ pack [lf] [Side Side_Left; Fill Fill_Both; Expand true];
+ pack [secret] [Side Side_Bottom];
+ pack [yscroll] [Side Side_Top; Fill Fill_Y; Expand true];
+ pack [xscroll] [Side Side_Bottom; Fill Fill_X];
+ pack [c] [Side Side_Left; Fill Fill_Both; Expand true];
+ f, t
diff --git a/otherlibs/labltk/frx/frx_ctext.mli b/otherlibs/labltk/frx/frx_ctext.mli
new file mode 100644
index 000000000..157c0cad1
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_ctext.mli
@@ -0,0 +1,25 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+val create :
+ Widget.widget -> Camltk.options list -> bool -> Widget.widget * Widget.widget
+ (* [create parent opts nav_keys] creates a text widget
+ with "pixel scrolling". Based on a trick learned from Steve Ball.
+ Returns (frame widget, text widget).
+ *)
+
+
diff --git a/otherlibs/labltk/frx/frx_dialog.ml b/otherlibs/labltk/frx/frx_dialog.ml
new file mode 100644
index 000000000..440278586
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_dialog.ml
@@ -0,0 +1,115 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Protocol
+
+let rec mapi f n l =
+ match l with
+ [] -> []
+ | x::l -> let v = f n x in v::(mapi f (succ n) l)
+
+(* Same as tk_dialog, but not sharing the tkwait variable *)
+(* w IS the parent widget *)
+let f w name title mesg bitmap def buttons =
+ let t = Toplevel.create_named w name [Class "Dialog"] in
+ Wm.title_set t title;
+ Wm.iconname_set t "Dialog";
+ Wm.protocol_set t "WM_DELETE_WINDOW" (function () -> ());
+ (* Wm.transient_set t (Winfo.toplevel w); *)
+ let ftop =
+ Frame.create_named t "top" [Relief Raised; BorderWidth (Pixels 1)]
+ and fbot =
+ Frame.create_named t "bot" [Relief Raised; BorderWidth (Pixels 1)]
+ in
+ pack [ftop][Side Side_Top; Fill Fill_Both];
+ pack [fbot][Side Side_Bottom; Fill Fill_Both];
+
+ let l =
+ Label.create_named ftop "msg"
+ [Justify Justify_Left; Text mesg; WrapLength (Pixels 600)] in
+ pack [l][Side Side_Right; Expand true; Fill Fill_Both;
+ PadX (Millimeters 3.0); PadY (Millimeters 3.0)];
+ begin match bitmap with
+ Predefined "" -> ()
+ | _ ->
+ let b =
+ Label.create_named ftop "bitmap" [Bitmap bitmap] in
+ pack [b][Side Side_Left; PadX (Millimeters 3.0); PadY (Millimeters 3.0)]
+ end;
+
+ let waitv = Textvariable.create_temporary t in
+
+ let buttons =
+ mapi (fun i bname ->
+ let b = Button.create t
+ [Text bname;
+ Command (fun () -> Textvariable.set waitv (string_of_int i))] in
+ if i = def then begin
+ let f = Frame.create_named fbot "default"
+ [Relief Sunken; BorderWidth (Pixels 1)] in
+ raise_window_above b f;
+ pack [f][Side Side_Left; Expand true;
+ PadX (Millimeters 3.0); PadY (Millimeters 2.0)];
+ pack [b][In f; PadX (Millimeters 2.0); PadY (Millimeters 2.0)];
+ bind t [[], KeyPressDetail "Return"]
+ (BindSet ([], (fun _ -> Button.flash b; Button.invoke b)))
+ end
+ else
+ pack [b][In fbot; Side Side_Left; Expand true;
+ PadX (Millimeters 3.0); PadY (Millimeters 2.0)];
+ b
+ )
+ 0 buttons in
+
+ Wm.withdraw t;
+ update_idletasks();
+ let x = (Winfo.screenwidth t)/2 - (Winfo.reqwidth t)/2 -
+ (Winfo.vrootx (Winfo.parent t))
+ and y = (Winfo.screenheight t)/2 - (Winfo.reqheight t)/2 -
+ (Winfo.vrooty (Winfo.parent t)) in
+ Wm.geometry_set t (Printf.sprintf "+%d+%d" x y);
+ Wm.deiconify t;
+
+ let oldfocus = try Some (Focus.get()) with _ -> None
+ and oldgrab = Grab.current ~displayof: t ()
+ and grabstatus = ref None in
+ begin match oldgrab with
+ [] -> ()
+ | x::l -> grabstatus := Some(Grab.status x)
+ end;
+
+ (* avoid errors here because it makes the entire app useless *)
+ (try Grab.set t with TkError _ -> ());
+ Tkwait.visibility t;
+ Focus.set (if def >= 0 then List.nth buttons def else t);
+
+ Tkwait.variable waitv;
+ begin match oldfocus with
+ None -> ()
+ | Some w -> try Focus.set w with _ -> ()
+ end;
+ destroy t;
+ begin match oldgrab with
+ [] -> ()
+ | x::l ->
+ try
+ match !grabstatus with
+ Some(GrabGlobal) -> Grab.set_global x
+ | _ -> Grab.set x
+ with TkError _ -> ()
+ end;
+
+ int_of_string (Textvariable.get waitv)
diff --git a/otherlibs/labltk/frx/frx_dialog.mli b/otherlibs/labltk/frx/frx_dialog.mli
new file mode 100644
index 000000000..2124150ca
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_dialog.mli
@@ -0,0 +1,22 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+val f :
+ Widget.widget ->
+ string -> string -> string -> Camltk.bitmap -> int -> string list -> int
+ (* same as Dialog.create_named, but with a local variable for
+ synchronisation. Makes it possible to have several dialogs
+ simultaneously *)
diff --git a/otherlibs/labltk/frx/frx_entry.ml b/otherlibs/labltk/frx/frx_entry.ml
new file mode 100644
index 000000000..eea7362d6
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_entry.ml
@@ -0,0 +1,42 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let version = "$Id$"
+
+(*
+ * Tk 4.0 has emacs bindings for entry widgets
+ *)
+
+let new_label_entry parent txt action =
+ let f = Frame.create parent [] in
+ let m = Label.create f [Text txt]
+ and e = Entry.create f [Relief Sunken; TextWidth 0] in
+ Camltk.bind e [[], KeyPressDetail "Return"]
+ (BindSet ([], fun _ -> action(Entry.get e)));
+ pack [m][Side Side_Left];
+ pack [e][Side Side_Right; Fill Fill_X; Expand true];
+ f,e
+
+let new_labelm_entry parent txt memo =
+ let f = Frame.create parent [] in
+ let m = Label.create f [Text txt]
+ and e = Entry.create f [Relief Sunken; TextVariable memo; TextWidth 0] in
+ pack [m][Side Side_Left];
+ pack [e][Side Side_Right; Fill Fill_X; Expand true];
+ f,e
+
+
diff --git a/otherlibs/labltk/frx/frx_entry.mli b/otherlibs/labltk/frx/frx_entry.mli
new file mode 100644
index 000000000..2f34a7e64
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_entry.mli
@@ -0,0 +1,31 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+val new_label_entry :
+ Widget.widget ->
+ string -> (string -> unit) -> Widget.widget * Widget.widget
+ (* [new_label_entry parent label action]
+ creates a "labelled" entry widget where [action] will be invoked
+ when the user types Return in the widget.
+ Returns (frame widget, entry widget)
+ *)
+val new_labelm_entry :
+ Widget.widget ->
+ string -> Textvariable.textVariable -> Widget.widget * Widget.widget
+ (* [new_labelm_entry parent label variable]
+ creates a "labelled" entry widget whose contents is [variable].
+ Returns (frame widget, entry widget)
+ *)
diff --git a/otherlibs/labltk/frx/frx_fileinput.ml b/otherlibs/labltk/frx/frx_fileinput.ml
new file mode 100644
index 000000000..cf59d1303
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_fileinput.ml
@@ -0,0 +1,40 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let version = "$Id$"
+
+(*
+ * Simple spooling for fileinput callbacks
+ *)
+
+let waiting_list = Queue. new()
+and waiting = ref 0
+and max_open = ref 10
+and cur_open = ref 0
+
+let add fd f =
+ if !cur_open < !max_open then begin
+ incr cur_open;
+ add_fileinput fd f
+ end
+ else begin
+ incr waiting;
+ Queue.add (fd,f) waiting_list
+ end
+
+let remove fd =
+
diff --git a/otherlibs/labltk/frx/frx_fillbox.ml b/otherlibs/labltk/frx/frx_fillbox.ml
new file mode 100644
index 000000000..f0a45f0b7
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_fillbox.ml
@@ -0,0 +1,65 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+(*
+ * Progress indicators
+ *)
+let okcolor = NamedColor "#3cb371"
+and kocolor = NamedColor "#dc5c5c"
+
+
+let new_vertical parent w h =
+ let c = Canvas.create_named parent "fillbox"
+ [Width (Pixels w); Height (Pixels h); BorderWidth (Pixels 1);
+ Relief Sunken]
+ in
+ let i = Canvas.create_rectangle c (Pixels 0) (Pixels 0) (Pixels w) (Pixels 0)
+ [FillColor okcolor; Outline okcolor]
+ in
+ c, (function
+ 0 -> Canvas.configure_rectangle c i [FillColor okcolor;
+ Outline okcolor];
+ Canvas.coords_set c i [Pixels 0; Pixels 0;
+ Pixels w; Pixels 0]
+ | -1 -> Canvas.configure_rectangle c i [FillColor kocolor;
+ Outline kocolor]
+ | n ->
+ let percent = if n > 100 then 100 else n in
+ let hf = percent*h/100 in
+ Canvas.coords_set c i [Pixels 0; Pixels 0;
+ Pixels w; Pixels hf])
+
+let new_horizontal parent w h =
+ let c = Canvas.create_named parent "fillbox"
+ [Width (Pixels w); Height (Pixels h); BorderWidth (Pixels 1);
+ Relief Sunken]
+ in
+ let i = Canvas.create_rectangle c (Pixels 0) (Pixels 0) (Pixels 0) (Pixels h)
+ [FillColor okcolor; Outline okcolor]
+ in
+ c, (function
+ 0 -> Canvas.configure_rectangle c i [FillColor okcolor;
+ Outline okcolor];
+ Canvas.coords_set c i [Pixels 0; Pixels 0;
+ Pixels 0; Pixels h]
+ | -1 -> Canvas.configure_rectangle c i [FillColor kocolor;
+ Outline kocolor]
+ | n ->
+ let percent = if n > 100 then 100 else n in
+ let wf = percent*w/100 in
+ Canvas.coords_set c i [Pixels 0; Pixels 0;
+ Pixels wf; Pixels h])
diff --git a/otherlibs/labltk/frx/frx_fillbox.mli b/otherlibs/labltk/frx/frx_fillbox.mli
new file mode 100644
index 000000000..a825524cd
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_fillbox.mli
@@ -0,0 +1,31 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+val new_vertical :
+ Widget.widget -> int -> int -> Widget.widget * (int -> unit)
+ (* [new_vertical parent width height]
+ creates a vertical fillbox of [width] and [height].
+ Returns a frame widget and a function to set the current value of
+ the fillbox. The value can be
+ n < 0 : the fillbox changes color (reddish)
+ 0 <= n <= 100: the fillbox fills up to n percent
+ 100 <= n : the fillbox fills up to 95%
+ *)
+
+val new_horizontal :
+ Widget.widget -> int -> int -> Widget.widget * (int -> unit)
+ (* save as above, except the widget is horizontal *)
diff --git a/otherlibs/labltk/frx/frx_fit.ml b/otherlibs/labltk/frx/frx_fit.ml
new file mode 100644
index 000000000..71e5b1979
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_fit.ml
@@ -0,0 +1,83 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let debug = ref false
+
+let vert wid =
+ let newsize = ref 0
+ and pending_resize = ref false
+ and last_last = ref 0.0 in
+ let rec resize () =
+ pending_resize := false;
+ if !debug then
+ (Printf.eprintf "%s Resize %d\n"
+ (Widget.name wid) !newsize; flush stderr);
+ Text.configure wid [TextHeight !newsize];
+ ()
+ and check () =
+ let first, last = Text.yview_get wid in
+ check1 first last
+
+ and check1 first last =
+ let curheight = int_of_string (cget wid CHeight) in
+ if !debug then begin
+ Printf.eprintf "%s C %d %f %f\n"
+ (Widget.name wid) curheight first last;
+ flush stderr
+ end;
+ if first = 0.0 && last = 1.0 then ()
+ (* Don't attempt anything if widget is not visible *)
+ else if not (Winfo.viewable wid) then begin
+ if !debug then
+ (Printf.eprintf "%s C notviewable\n" (Widget.name wid);
+ flush stderr);
+ (* Try again later *)
+ bind wid [[], Expose] (BindSet ([], fun _ ->
+ bind wid [[], Expose] BindRemove;
+ check()))
+ end
+ else begin
+ let delta =
+ if last = 0.0 then 1
+ else if last = !last_last then
+ (* it didn't change since our last resize ! *)
+ 1
+ else begin
+ last_last := last;
+ (* never to more than double *)
+ let visible = max 0.5 (last -. first) in
+ max 1 (truncate (float curheight *. (1. -. visible)))
+ end in
+ newsize := max (curheight + delta) !newsize;
+ if !debug then
+ (Printf.eprintf "%s newsize: %d\n" (Widget.name wid) !newsize;
+ flush stderr);
+ if !pending_resize then ()
+ else begin
+ pending_resize := true;
+ Timer.set 300 (fun () -> Frx_after.idle resize)
+ end
+ end
+
+ and scroll first last =
+ if !debug then
+ (Printf.eprintf "%s V %f %f\n" (Widget.name wid) first last;
+ flush stderr);
+ if first = 0.0 && last = 1.0 then ()
+ else check1 first last
+ in
+ scroll, check
diff --git a/otherlibs/labltk/frx/frx_fit.mli b/otherlibs/labltk/frx/frx_fit.mli
new file mode 100644
index 000000000..29479d801
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_fit.mli
@@ -0,0 +1,29 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+
+val debug: bool ref
+val vert: widget -> (float -> float -> unit) * (unit -> unit)
+
+(* [vert widget]
+ can be applied to a text widget so that it expands to show its full
+ contents. Returns [scroll] and [check]. [scroll] must be used as
+ the YScrollCommand of the widget. [check] can be called when some
+ modification occurs in the content of the widget (such as a size change
+ in some embedded windows.
+ This feature is a terrible hack and should be used with extreme caution.
+ *)
diff --git a/otherlibs/labltk/frx/frx_focus.ml b/otherlibs/labltk/frx/frx_focus.ml
new file mode 100644
index 000000000..f33b9e6df
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_focus.ml
@@ -0,0 +1,26 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+(* Temporary focus *)
+
+(* ? use bind tag ? how about the global reference then *)
+let auto w =
+ let old_focus = ref w in
+ bind w [[],Enter]
+ (BindSet([], fun _ -> old_focus := Focus.get (); Focus.set w));
+ bind w [[],Leave]
+ (BindSet([], fun _ -> Focus.set !old_focus))
diff --git a/otherlibs/labltk/frx/frx_focus.mli b/otherlibs/labltk/frx/frx_focus.mli
new file mode 100644
index 000000000..919f70475
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_focus.mli
@@ -0,0 +1,18 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+val auto : Widget.widget -> unit
+ (* *)
diff --git a/otherlibs/labltk/frx/frx_font.ml b/otherlibs/labltk/frx/frx_font.ml
new file mode 100644
index 000000000..2f93c4dbd
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_font.ml
@@ -0,0 +1,51 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+
+let version = "$Id$"
+
+(*
+ * Finding fonts. Inspired by code in Ical by Sanjay Ghemawat.
+ * Possibly bogus because some families use "i" for italic where others
+ * use "o".
+ * wght: bold, medium
+ * slant: i, o, r
+ * pxlsz: 8, 10, ...
+*)
+module StringSet = Set.Make(struct type t = string let compare = compare end)
+
+let available_fonts = ref (StringSet.empty)
+
+let get_canvas =
+ Frx_misc.autodef (fun () -> Canvas.create Widget.default_toplevel [])
+
+
+let find fmly wght slant pxlsz =
+ let fontspec =
+ "-*-"^fmly^"-"^wght^"-"^slant^"-normal-*-"^string_of_int pxlsz^"-*-*-*-*-*-iso8859-1" in
+ if StringSet.mem fontspec !available_fonts then fontspec
+ else
+ let c = get_canvas() in
+ try
+ let tag = Canvas.create_text c (Pixels 0) (Pixels 0)
+ [Text "foo"; Font fontspec] in
+ Canvas.delete c [tag];
+ available_fonts := StringSet.add fontspec !available_fonts;
+ fontspec
+ with
+ _ -> raise (Invalid_argument fontspec)
+
diff --git a/otherlibs/labltk/frx/frx_font.mli b/otherlibs/labltk/frx/frx_font.mli
new file mode 100644
index 000000000..c0b7e6806
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_font.mli
@@ -0,0 +1,20 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val find : string -> string -> string -> int -> string
+ (* [find family weight slant pxlsz] returns the X11 full name of
+ the font required font, if available.
+ Raises Invalid_argument fullname otherwise.
+ *)
diff --git a/otherlibs/labltk/frx/frx_group.ml b/otherlibs/labltk/frx/frx_group.ml
new file mode 100644
index 000000000..17c8a0310
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_group.ml
@@ -0,0 +1,22 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let vgroup top l =
+ let f = Frame.create top [] in
+ Pack.forget l;
+ Pack.configure l [In f];
+ f
diff --git a/otherlibs/labltk/frx/frx_lbutton.ml b/otherlibs/labltk/frx/frx_lbutton.ml
new file mode 100644
index 000000000..c4d51f7b5
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_lbutton.ml
@@ -0,0 +1,50 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+open Widget
+
+
+let version = "$Id$"
+
+(*
+ * Simulate a button with a bitmap AND a label
+ *)
+
+let rec sort_options but lab com = function
+ [] -> but,lab,com
+ |(Command f as o)::l -> sort_options (o::but) lab com l
+ |(Bitmap b as o)::l -> sort_options (o::but) lab com l
+ |(Text t as o)::l -> sort_options but (o::lab) com l
+ |o::l -> sort_options but lab (o::com) l
+
+let create parent options =
+ let but,lab,com = sort_options [] [] [] options in
+ let f = Frame.create parent com in
+ let b = Button.create f (but@com)
+ and l = Label.create f (lab@com) in
+ pack [b;l][];
+ bind l [[],ButtonPressDetail 1] (BindSet ([],(function _ -> Button.invoke b)));
+ f
+
+let configure f options =
+ let but,lab,com = sort_options [] [] [] options in
+ match Pack.slaves f with
+ [b;l] ->
+ Frame.configure f com;
+ Button.configure b (but@com);
+ Label.configure l (lab@com)
+ | _ -> raise (Invalid_argument "lbutton configure")
diff --git a/otherlibs/labltk/frx/frx_lbutton.mli b/otherlibs/labltk/frx/frx_lbutton.mli
new file mode 100644
index 000000000..d79431f34
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_lbutton.mli
@@ -0,0 +1,24 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Widget
+open Camltk
+
+
+val version : string
+
+val create : Widget -> option list -> Widget
+and configure : Widget -> option list -> unit
+
diff --git a/otherlibs/labltk/frx/frx_listbox.ml b/otherlibs/labltk/frx/frx_listbox.ml
new file mode 100644
index 000000000..332dca5d5
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_listbox.ml
@@ -0,0 +1,92 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let version = "$Id$"
+
+(*
+ * Link a scrollbar and a listbox
+ *)
+let scroll_link sb lb =
+ Listbox.configure lb
+ [YScrollCommand (Scrollbar.set sb)];
+ Scrollbar.configure sb
+ [ScrollCommand (Listbox.yview lb)]
+
+(*
+ * Completion for listboxes, Macintosh style.
+ * As long as you type fast enough, the listbox is repositioned to the
+ * first entry "greater" than the typed prefix.
+ * assumes:
+ * sorted list (otherwise it's stupid)
+ * fixed size, because we don't recompute size at each callback invocation
+ *)
+
+let add_completion lb action =
+ let prefx = ref "" (* current match prefix *)
+ and maxi = Listbox.size lb - 1 (* maximum index (doesn't matter actually) *)
+ and current = ref 0 (* current position *)
+ and lastevent = ref 0 in
+
+ let rec move_forward () =
+ if Listbox.get lb (Number !current) < !prefx then
+ if !current < maxi then begin incr current; move_forward() end
+
+ and recenter () =
+ let element = Number !current in
+ (* Clean the selection *)
+ Listbox.selection_clear lb (Number 0) End;
+ (* Set it to our unique element *)
+ Listbox.selection_set lb element element;
+ (* Activate it, to keep consistent with Up/Down.
+ You have to be in Extended or Browse mode *)
+ Listbox.activate lb element;
+ Listbox.selection_anchor lb element;
+ Listbox.see lb element in
+
+ let complete time s =
+ if time - !lastevent < 500 then (* sorry, hard coded limit *)
+ prefx := !prefx ^ s
+ else begin (* reset *)
+ current := 0;
+ prefx := s
+ end;
+ lastevent := time;
+ move_forward();
+ recenter() in
+
+
+ bind lb [[], KeyPress]
+ (BindSet([Ev_Char; Ev_Time],
+ (function ev ->
+ (* consider only keys producing characters. The callback is called
+ * even if you press Shift.
+ *)
+ if ev.ev_Char <> "" then complete ev.ev_Time ev.ev_Char)));
+ (* Key specific bindings override KeyPress *)
+ bind lb [[], KeyPressDetail "Return"] (BindSet([], action));
+ (* Finally, we have to set focus, otherwise events dont get through *)
+ Focus.set lb;
+ recenter() (* so that first item is selected *)
+
+let new_scrollable_listbox top options =
+ let f = Frame.create top [] in
+ let lb = Listbox.create f options
+ and sb = Scrollbar.create f [] in
+ scroll_link sb lb;
+ pack [lb] [Side Side_Left; Fill Fill_Both; Expand true];
+ pack [sb] [Side Side_Left; Fill Fill_Y];
+ f, lb
diff --git a/otherlibs/labltk/frx/frx_listbox.mli b/otherlibs/labltk/frx/frx_listbox.mli
new file mode 100644
index 000000000..b44b6ee9d
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_listbox.mli
@@ -0,0 +1,32 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+val scroll_link : Widget.widget -> Widget.widget -> unit
+ (* [scroll_link scrollbar listbox] links [scrollbar] and [listbox]
+ as expected.
+ *)
+
+val add_completion : Widget.widget -> (eventInfo -> unit) -> unit
+ (* [add_completion listbox action] adds Macintosh like electric navigation
+ in the listbox when characters are typed in.
+ [action] is invoked if Return is pressed
+ *)
+
+val new_scrollable_listbox :
+ Widget.widget -> options list -> Widget.widget * Widget.widget
+ (* [new_scrollable_listbox parent options] makes a scrollable listbox and
+ returns (frame, listbox)
+ *)
diff --git a/otherlibs/labltk/frx/frx_mem.ml b/otherlibs/labltk/frx/frx_mem.ml
new file mode 100644
index 000000000..c3f041d00
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_mem.ml
@@ -0,0 +1,89 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Memory gauge *)
+open Camltk
+open Gc
+
+let inited = ref None
+let w = ref 300
+let delay = ref 5 (* in seconds *)
+let wordsize = (* officially approved *)
+ if 1 lsl 31 = 0 then 4 else 8
+
+
+let init () =
+ let top = Toplevel.create Widget.default_toplevel [Class "CamlGC"] in
+ let name = Camltk.appname_get () in
+ Wm.title_set top (name ^ " Memory Gauge");
+ Wm.withdraw top;
+ inited := Some top;
+ (* this should be executed before the internal "all" binding *)
+ bind top [[], Destroy] (BindSet ([], (fun _ -> inited := None)));
+ let fminors = Frame.create top [] in
+ let lminors = Label.create fminors [Text "Minor collections"]
+ and vminors = Label.create fminors [] in
+ pack [lminors][Side Side_Left];
+ pack [vminors][Side Side_Right; Fill Fill_X; Expand true];
+ let fmajors = Frame.create top [] in
+ let lmajors = Label.create fmajors [Text "Major collections"]
+ and vmajors = Label.create fmajors [] in
+ pack [lmajors][Side Side_Left];
+ pack [vmajors][Side Side_Right; Fill Fill_X; Expand true];
+ let fcompacts = Frame.create top [] in
+ let lcompacts = Label.create fcompacts [Text "Compactions"]
+ and vcompacts = Label.create fcompacts [] in
+ pack [lcompacts][Side Side_Left];
+ pack [vcompacts][Side Side_Right; Fill Fill_X; Expand true];
+ let fsize = Frame.create top [] in
+ let lsize = Label.create fsize [Text "Heap size (bytes)"]
+ and vsize = Label.create fsize [] in
+ pack [lsize][Side Side_Left];
+ pack [vsize][Side Side_Right; Fill Fill_X; Expand true];
+ let fheap = Frame.create top [Width (Pixels !w); Height (Pixels 10)] in
+ let flive = Frame.create fheap [Background Red]
+ and ffree = Frame.create fheap [Background Green]
+ and fdead = Frame.create fheap [Background Black] in
+ pack [fminors; fmajors; fcompacts; fsize; fheap][Fill Fill_X];
+
+ let display () =
+ let st = Gc.stat() in
+ Label.configure vminors [Text (string_of_int st.minor_collections)];
+ Label.configure vmajors [Text (string_of_int st.major_collections)];
+ Label.configure vcompacts [Text (string_of_int st.compactions)];
+ Label.configure vsize [Text (string_of_int (wordsize * st.heap_words))];
+ let liver = (float st.live_words) /. (float st.heap_words)
+ and freer = (float st.free_words) /. (float st.heap_words) in
+ Place.configure flive [X (Pixels 0); Y (Pixels 0);
+ RelWidth liver; RelHeight 1.0];
+ Place.configure ffree [RelX liver; Y (Pixels 0);
+ RelWidth freer; RelHeight 1.0];
+ Place.configure fdead [RelX (liver +. freer); Y (Pixels 0);
+ RelWidth (1.0 -. freer -. liver); RelHeight 1.0]
+
+ in
+ let rec tim () =
+ if Winfo.exists top then begin
+ display();
+ Timer.set (!delay * 1000) tim
+ end
+ in
+ tim()
+
+
+let rec f () =
+ match !inited with
+ Some w -> Wm.deiconify w
+ | None -> init (); f()
diff --git a/otherlibs/labltk/frx/frx_mem.mli b/otherlibs/labltk/frx/frx_mem.mli
new file mode 100644
index 000000000..f3069ec28
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_mem.mli
@@ -0,0 +1,22 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* A Garbage Collector Gauge for Caml *)
+
+val init : unit -> unit
+ (* [init ()] creates the gauge and its updater, but keeps it iconified *)
+
+val f : unit -> unit
+ (* [f ()] makes the gauge visible if it has not been destroyed *)
diff --git a/otherlibs/labltk/frx/frx_misc.ml b/otherlibs/labltk/frx/frx_misc.ml
new file mode 100644
index 000000000..38d27fda1
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_misc.ml
@@ -0,0 +1,69 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Delayed global, a.k.a cache&carry *)
+let autodef f =
+ let v = ref None in
+ (function () ->
+ match !v with
+ None ->
+ let x = f() in
+ v := Some x;
+ x
+ | Some x -> x)
+
+open Camltk
+
+(* allows Data in options *)
+let create_photo options =
+ let hasopt = ref None in
+ (* Check options *)
+ List.iter (function
+ Data s ->
+ begin match !hasopt with
+ None -> hasopt := Some (Data s)
+ | Some _ -> raise (Protocol.TkError "two data sources in options")
+ end
+ | File f ->
+ begin match !hasopt with
+ None -> hasopt := Some (File f)
+ | Some _ -> raise (Protocol.TkError "two data sources in options")
+ end
+ | o -> ())
+ options;
+ match !hasopt with
+ None -> raise (Protocol.TkError "no data source in options")
+ | Some (Data s) ->
+ begin
+ let tmpfile = Filename.temp_file "img" "" in
+ let oc = open_out_bin tmpfile in
+ output_string oc s;
+ close_out oc;
+ let newopts =
+ List.map (function
+ | Data s -> File tmpfile
+ | o -> o)
+ options in
+ try
+ let i = Imagephoto.create newopts in
+ (try Sys.remove tmpfile with Sys_error _ -> ());
+ i
+ with
+ e ->
+ (try Sys.remove tmpfile with Sys_error _ -> ());
+ raise e
+ end
+ | Some (File s) -> Imagephoto.create options
+ | _ -> assert false
diff --git a/otherlibs/labltk/frx/frx_misc.mli b/otherlibs/labltk/frx/frx_misc.mli
new file mode 100644
index 000000000..2df8ce3d2
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_misc.mli
@@ -0,0 +1,21 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+val autodef : (unit -> 'a) -> (unit -> 'a)
+ (* [autodef make] is a pleasant wrapper around 'a option ref *)
+
+val create_photo : Camltk.options list -> Camltk.imagePhoto
+ (* [create_photo options] allows Data in options (by saving to tmp file) *)
diff --git a/otherlibs/labltk/frx/frx_req.ml b/otherlibs/labltk/frx/frx_req.ml
new file mode 100644
index 000000000..088977d59
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_req.ml
@@ -0,0 +1,198 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+(*
+ * Some standard requesters (in Amiga techspeak) or dialog boxes (in Apple
+ * jargon).
+*)
+
+let version = "$Id$"
+
+(*
+ * Simple requester
+ * an entry field, unrestricted, with emacs-like bindings
+ * Note: grabs focus, thus always unique at one given moment, and we
+ * shouldn't have to worry about toplevel widget name.
+ * We add a title widget in case the window manager does not decorate
+ * toplevel windows.
+*)
+
+let open_simple title action notaction memory =
+ let t = Toplevel.create Widget.default_toplevel [Class "Dialog"] in
+ Focus.set t;
+ Wm.title_set t title;
+ let tit = Label.create t [Text title] in
+ let len = max 40 (String.length (Textvariable.get memory)) in
+ let e =
+ Entry.create t [Relief Sunken; TextVariable memory; TextWidth len] in
+
+ let activate _ =
+ let v = Entry.get e in
+ Grab.release t; (* because of wm *)
+ destroy t; (* so action can call open_simple *)
+ action v in
+
+ bind e [[], KeyPressDetail "Return"] (BindSet ([], activate));
+
+ let f = Frame.create t [] in
+ let bok = Button.create f [Text "Ok"; Command activate] in
+ let bcancel = Button.create f
+ [Text "Cancel";
+ Command (fun () -> notaction(); Grab.release t; destroy t)] in
+
+ bind e [[], KeyPressDetail "Escape"]
+ (BindSet ([], (fun _ -> Button.invoke bcancel)));
+ pack [bok] [Side Side_Left; Expand true];
+ pack [bcancel] [Side Side_Right; Expand true];
+ pack [tit;e] [Fill Fill_X];
+ pack [f] [Side Side_Bottom; Fill Fill_X];
+ Frx_widget.resizeable t;
+ Focus.set e;
+ Tkwait.visibility t;
+ Grab.set t
+
+(* A synchronous version *)
+let open_simple_synchronous title memory =
+ let t = Toplevel.create Widget.default_toplevel [Class "Dialog"] in
+ Focus.set t;
+ Wm.title_set t title;
+ let tit = Label.create t [Text title] in
+ let len = max 40 (String.length (Textvariable.get memory)) in
+ let e =
+ Entry.create t [Relief Sunken; TextVariable memory; TextWidth len] in
+
+ let waiting = Textvariable.create_temporary t in
+
+ let activate _ =
+ Grab.release t; (* because of wm *)
+ destroy t; (* so action can call open_simple *)
+ Textvariable.set waiting "1" in
+
+ bind e [[], KeyPressDetail "Return"] (BindSet ([], activate));
+
+ let f = Frame.create t [] in
+ let bok = Button.create f [Text "Ok"; Command activate] in
+ let bcancel =
+ Button.create f
+ [Text "Cancel";
+ Command (fun () ->
+ Grab.release t; destroy t; Textvariable.set waiting "0")] in
+
+ bind e [[], KeyPressDetail "Escape"]
+ (BindSet ([], (fun _ -> Button.invoke bcancel)));
+ pack [bok] [Side Side_Left; Expand true];
+ pack [bcancel] [Side Side_Right; Expand true];
+ pack [tit;e] [Fill Fill_X];
+ pack [f] [Side Side_Bottom; Fill Fill_X];
+ Frx_widget.resizeable t;
+ Focus.set e;
+ Tkwait.visibility t;
+ Grab.set t;
+ Tkwait.variable waiting;
+ begin match Textvariable.get waiting with
+ "1" -> true
+ | _ -> false
+ end
+
+(*
+ * Simple list requester
+ * Same remarks as in open_simple.
+ * focus seems to be in the listbox automatically
+ *)
+let open_list title elements action notaction =
+ let t = Toplevel.create Widget.default_toplevel [Class "Dialog"] in
+ Wm.title_set t title;
+
+ let tit = Label.create t [Text title] in
+ let fls = Frame.create t [Relief Sunken; BorderWidth (Pixels 2)] in
+ let lb = Listbox.create fls [SelectMode Extended] in
+ let sb = Scrollbar.create fls [] in
+ Frx_listbox.scroll_link sb lb;
+ Listbox.insert lb End elements;
+
+ (* activation: we have to break() because we destroy the requester *)
+ let activate _ =
+ let l = List.map (Listbox.get lb) (Listbox.curselection lb) in
+ Grab.release t;
+ destroy t;
+ List.iter action l;
+ break() in
+
+
+ bind lb [[Double], ButtonPressDetail 1] (BindSetBreakable ([], activate));
+
+ Frx_listbox.add_completion lb activate;
+
+ let f = Frame.create t [] in
+ let bok = Button.create f [Text "Ok"; Command activate] in
+ let bcancel = Button.create f
+ [Text "Cancel";
+ Command (fun () -> notaction(); Grab.release t; destroy t)] in
+
+ pack [bok; bcancel] [Side Side_Left; Fill Fill_X; Expand true];
+ pack [lb] [Side Side_Left; Fill Fill_Both; Expand true];
+ pack [sb] [Side Side_Right; Fill Fill_Y];
+ pack [tit] [Fill Fill_X];
+ pack [fls] [Fill Fill_Both; Expand true];
+ pack [f] [Side Side_Bottom; Fill Fill_X];
+ Frx_widget.resizeable t;
+ Tkwait.visibility t;
+ Grab.set t
+
+
+(* Synchronous *)
+let open_passwd title =
+ let username = ref ""
+ and password = ref ""
+ and cancelled = ref false in
+ let t = Toplevel.create Widget.default_toplevel [Class "Dialog"] in
+ Focus.set t;
+ Wm.title_set t title;
+ let tit = Label.create t [Text title]
+ and fu,eu = Frx_entry.new_label_entry t "Username" (fun s -> ())
+ and fp,ep = Frx_entry.new_label_entry t "Password" (fun s -> ())
+ in
+ let fb = Frame.create t [] in
+ let bok = Button.create fb
+ [Text "Ok"; Command (fun _ ->
+ username := Entry.get eu;
+ password := Entry.get ep;
+ Grab.release t; (* because of wm *)
+ destroy t)] (* will return from tkwait *)
+ and bcancel = Button.create fb
+ [Text "Cancel"; Command (fun _ ->
+ cancelled := true;
+ Grab.release t; (* because of wm *)
+ destroy t)] (* will return from tkwait *)
+ in
+ Entry.configure ep [Show '*'];
+ bind eu [[], KeyPressDetail "Return"]
+ (BindSetBreakable ([], (fun _ -> Focus.set ep; break())));
+ bind ep [[], KeyPressDetail "Return"]
+ (BindSetBreakable ([], (fun _ -> Button.flash bok;
+ Button.invoke bok;
+ break())));
+
+ pack [bok] [Side Side_Left; Expand true];
+ pack [bcancel] [Side Side_Right; Expand true];
+ pack [tit;fu;fp;fb] [Fill Fill_X];
+ Tkwait.visibility t;
+ Focus.set eu;
+ Grab.set t;
+ Tkwait.window t;
+ if !cancelled then failwith "cancelled"
+ else (!username, !password)
diff --git a/otherlibs/labltk/frx/frx_req.mli b/otherlibs/labltk/frx/frx_req.mli
new file mode 100644
index 000000000..815b28459
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_req.mli
@@ -0,0 +1,43 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Various dialog boxes *)
+val open_simple :
+ string ->
+ (string -> unit) -> (unit -> 'a) -> Textvariable.textVariable -> unit
+ (* [open_simple title action cancelled memory]
+ A dialog with a message and an entry field (with memory between
+ invocations). Either [action] or [cancelled] is called when the user
+ answers to the dialog (with Ok or Cancel)
+ *)
+
+val open_simple_synchronous : string -> Textvariable.textVariable -> bool
+ (* [open_simple_synchronous title memory]
+ A synchronous dialog with a message and an entry field (with
+ memory between invocations). Returns true if the user clicks Ok
+ or false if the user clicks Cancel.
+ *)
+val open_list :
+ string -> string list -> (string -> unit) -> (unit -> unit) -> unit
+ (* [open_list title elements action cancelled]
+ A dialog for selecting from a list of elements. [action] is called
+ on each selected element, or [cancelled] is called if the user clicks
+ Cancel.
+ *)
+
+val open_passwd : string -> string * string
+ (* [open_passwd title] pops up a username/password dialog and returns
+ (username, password).
+ *)
diff --git a/otherlibs/labltk/frx/frx_rpc.ml b/otherlibs/labltk/frx/frx_rpc.ml
new file mode 100644
index 000000000..23ccd2526
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_rpc.ml
@@ -0,0 +1,55 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Some notion of RPC *)
+open Camltk
+open Protocol
+
+(* A RPC is just a callback with a particular name, plus a Tcl procedure *)
+let register name f =
+ let id = new_function_id() in
+ Hashtbl.add callback_naming_table id f;
+ (* For rpc_info *)
+ Textvariable.set (Textvariable.coerce ("camltkrpc("^name^")"))
+ (string_of_cbid id);
+ tkCommand [| TkToken "proc"; TkToken name; TkToken "args";
+ TkToken ("camlcb "^(string_of_cbid id)^" $args") |]
+
+(* RPC *)
+let invoke interp f args =
+ tkEval [|
+ TkToken "send";
+ TkToken interp;
+ TkToken f;
+ TkTokenList (List.map (fun s -> TkToken s) args)
+ |]
+
+let async_invoke interp f args =
+ tkCommand [|
+ TkToken "send";
+ TkToken "-async";
+ TkToken interp;
+ TkToken f;
+ TkTokenList (List.map (fun s -> TkToken s) args)
+ |]
+
+let rpc_info interp =
+ tkEval [|
+ TkToken "send";
+ TkToken interp;
+ TkToken "array";
+ TkToken "names";
+ TkToken "camltkrpc"
+ |]
diff --git a/otherlibs/labltk/frx/frx_rpc.mli b/otherlibs/labltk/frx/frx_rpc.mli
new file mode 100644
index 000000000..808fe87c7
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_rpc.mli
@@ -0,0 +1,25 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Some notion of RPC *)
+
+val register : string -> (string list -> unit) -> unit
+ (* [register external_name f] *)
+val invoke : string -> string -> string list -> string
+ (* [invoke interp name args] *)
+val async_invoke : string -> string -> string list -> unit
+ (* [async_invoke interp name args] *)
+val rpc_info : string -> string
+ (* [rpc_info interp] *)
diff --git a/otherlibs/labltk/frx/frx_selection.ml b/otherlibs/labltk/frx/frx_selection.ml
new file mode 100644
index 000000000..7ef64ce86
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_selection.ml
@@ -0,0 +1,45 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* A selection handler *)
+open Widget
+open Protocol
+open Camltk
+
+let frame = ref None
+let selection = ref ""
+
+let read ofs n =
+ let res =
+ if ofs < 0 then ""
+ else if ofs + n > String.length !selection
+ then String.sub !selection ofs (String.length !selection - ofs)
+ else String.sub !selection ofs n in
+ tkreturn res
+
+(* As long as we don't loose the selection, we keep the widget *)
+(* Calling this function means that we own the selection *)
+(* When we loose the selection, both cb are destroyed *)
+let own () =
+ match !frame with
+ None ->
+ let f = Frame.create_named Widget.default_toplevel "frx_selection" [] in
+ let lost () = selection := ""; destroy f; frame := None in
+ Selection.own_set [Selection "PRIMARY"; LostCommand lost] f;
+ Selection.handle_set [Selection "PRIMARY"; ICCCMType "STRING"] f read;
+ frame := Some f
+ | Some f -> ()
+
+let set s = own(); selection := s
diff --git a/otherlibs/labltk/frx/frx_selection.mli b/otherlibs/labltk/frx/frx_selection.mli
new file mode 100644
index 000000000..dfb27ee24
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_selection.mli
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val set : string -> unit
+ (* [set s] sets the X PRIMARY selection to [s] *)
diff --git a/otherlibs/labltk/frx/frx_synth.ml b/otherlibs/labltk/frx/frx_synth.ml
new file mode 100644
index 000000000..5ce23b1d4
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_synth.ml
@@ -0,0 +1,88 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Some notion of synthetic events *)
+open Camltk
+open Widget
+open Protocol
+
+(* To each event is associated a table of (widget, callback) *)
+let events = Hashtbl.create 37
+
+(* Notes:
+ * "cascading" events (on the same event) are not supported
+ * Only one binding active at a time for each event on each widget.
+ *)
+
+(* Get the callback table associated with <name>. Initializes if required *)
+let get_event name =
+ try Hashtbl.find events name
+ with
+ Not_found ->
+ let h = Hashtbl.create 37 in
+ Hashtbl.add events name h;
+ (* Initialize the callback invocation mechanism, based on
+ variable trace
+ *)
+ let var = "camltk_events(" ^ name ^")" in
+ let tkvar = Textvariable.coerce var in
+ let rec set () =
+ Textvariable.handle tkvar
+ (fun () ->
+ begin match Textvariable.get tkvar with
+ "all" -> (* Invoke all callbacks *)
+ Hashtbl.iter
+ (fun p f ->
+ try
+ f (cTKtoCAMLwidget p)
+ with _ -> ())
+ h
+ | p -> (* Invoke callback for p *)
+ try
+ let w = cTKtoCAMLwidget p
+ and f = Hashtbl.find h p in
+ f w
+ with
+ _ -> ()
+ end;
+ set ()(* reactivate the callback *)
+ ) in
+ set();
+ h
+
+(* Remove binding for event <name> on widget <w> *)
+let remove w name =
+ Hashtbl.remove (get_event name) (Widget.name w)
+
+(* Adds <f> as callback for widget <w> on event <name> *)
+let bind w name f =
+ remove w name;
+ Hashtbl.add (get_event name) (Widget.name w) f
+
+(* Sends event <name> to all widgets *)
+let broadcast name =
+ Textvariable.set (Textvariable.coerce ("camltk_events(" ^ name ^")")) "all"
+
+(* Sends event <name> to widget <w> *)
+let send name w =
+ Textvariable.set (Textvariable.coerce ("camltk_events(" ^ name ^")"))
+ (Widget.name w)
+
+(* Remove all callbacks associated to widget <w> *)
+let remove_callbacks w =
+ Hashtbl.iter (fun _ h -> Hashtbl.remove h (Widget.name w)) events
+
+let _ =
+ add_destroy_hook remove_callbacks
diff --git a/otherlibs/labltk/frx/frx_synth.mli b/otherlibs/labltk/frx/frx_synth.mli
new file mode 100644
index 000000000..0b8d85d85
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_synth.mli
@@ -0,0 +1,31 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* Synthetic events *)
+open Camltk
+open Widget
+
+
+val send : string -> widget -> unit
+ (* [send event_name widget] *)
+
+val broadcast : string -> unit
+ (* [broadcase event_name] *)
+
+val bind : widget -> string -> (widget -> unit) -> unit
+ (* [bind event_name callback] *)
+
+val remove : widget -> string -> unit
+ (* [remove widget event_name] *)
diff --git a/otherlibs/labltk/frx/frx_text.ml b/otherlibs/labltk/frx/frx_text.ml
new file mode 100644
index 000000000..cd405baab
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_text.ml
@@ -0,0 +1,229 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+let version = "$Id$"
+
+(*
+ * convert an integer to an absolute index
+*)
+let abs_index n =
+ TextIndex (LineChar(0,0), [CharOffset n])
+
+let insertMark =
+ TextIndex(Mark "insert", [])
+
+let currentMark =
+ TextIndex(Mark "current", [])
+
+let textEnd =
+ TextIndex(End, [])
+
+let textBegin =
+ TextIndex (LineChar(0,0), [])
+
+(*
+ * Link a scrollbar and a text widget
+*)
+let scroll_link sb tx =
+ Text.configure tx [YScrollCommand (Scrollbar.set sb)];
+ Scrollbar.configure sb [ScrollCommand (Text.yview tx)]
+
+
+(*
+ * Tk 4.0 has navigation in Text widgets, sometimes using scrolling
+ * sometimes using the insertion mark. It is a pain to add more
+ * compatible bindings. We do our own.
+ *)
+let page_up tx = Text.yview tx (ScrollPage (-1))
+and page_down tx = Text.yview tx (ScrollPage 1)
+and line_up tx = Text.yview tx (ScrollUnit (-1))
+and line_down tx = Text.yview tx (ScrollUnit 1)
+and top tx = Text.yview_index tx textBegin
+and bottom tx = Text.yview_index tx textEnd
+
+let navigation_keys tx =
+ let tags = bindtags_get tx in
+ match tags with
+ (WidgetBindings t)::l when t = tx ->
+ bindtags tx ((WidgetBindings tx) :: (TagBindings "TEXT_RO") :: l)
+ | _ -> ()
+
+let new_scrollable_text top options navigation =
+ let f = Frame.create top [] in
+ let tx = Text.create f options
+ and sb = Scrollbar.create f [] in
+ scroll_link sb tx;
+ (* IN THIS ORDER -- RESIZING *)
+ pack [sb] [Side Side_Right; Fill Fill_Y];
+ pack [tx] [Side Side_Left; Fill Fill_Both; Expand true];
+ if navigation then navigation_keys tx;
+ f, tx
+
+(*
+ * Searching
+ *)
+let patternv = Frx_misc.autodef Textvariable.create
+and casev = Frx_misc.autodef Textvariable.create
+
+let topsearch t =
+ (* The user interface *)
+ let top = Toplevel.create t [Class "TextSearch"] in
+ Wm.title_set top "Text search";
+ let f = Frame.create_named top "fpattern" [] in
+ let m = Label.create_named f "search" [Text "Search pattern"]
+ and e = Entry.create_named f "pattern"
+ [Relief Sunken; TextVariable (patternv()) ] in
+ let hgroup = Frame.create top []
+ and bgroup = Frame.create top [] in
+ let fdir = Frame.create hgroup []
+ and fmisc = Frame.create hgroup [] in
+ let direction = Textvariable.create_temporary fdir
+ and exactv = Textvariable.create_temporary fdir
+ in
+ let forw = Radiobutton.create_named fdir "forward"
+ [Text "Forward"; Variable direction; Value "f"]
+ and backw = Radiobutton.create_named fdir "backward"
+ [Text "Backward"; Variable direction; Value "b"]
+ and exact = Checkbutton.create_named fmisc "exact"
+ [Text "Exact match"; Variable exactv]
+ and case = Checkbutton.create_named fmisc "case"
+ [Text "Fold Case"; Variable (casev())]
+ and searchb = Button.create_named bgroup "search" [Text "Search"]
+ and contb = Button.create_named bgroup "continue" [Text "Continue"]
+ and dismissb = Button.create_named bgroup "dismiss"
+ [Text "Dismiss";
+ Command (fun () -> Text.tag_delete t ["search"]; destroy top)] in
+
+ Radiobutton.invoke forw;
+ pack [m][Side Side_Left];
+ pack [e][Side Side_Right; Fill Fill_X; Expand true];
+ pack [forw; backw] [Anchor W];
+ pack [exact; case] [Anchor W];
+ pack [fdir; fmisc] [Side Side_Left; Anchor Center];
+ pack [searchb; contb; dismissb] [Side Side_Left; Fill Fill_X];
+ pack [f;hgroup;bgroup] [Fill Fill_X; Expand true];
+
+ let current_index = ref textBegin in
+
+ let search cont = fun () ->
+ let opts = ref [] in
+ if Textvariable.get direction = "f" then
+ opts := Forwards :: !opts
+ else opts := Backwards :: !opts ;
+ if Textvariable.get exactv = "1" then
+ opts := Exact :: !opts;
+ if Textvariable.get (casev()) = "1" then
+ opts := Nocase :: !opts;
+ try
+ let forward = Textvariable.get direction = "f" in
+ let i = Text.search t !opts (Entry.get e)
+ (if cont then !current_index
+ else if forward then textBegin
+ else TextIndex(End, [CharOffset (-1)])) (* does not work with end *)
+ (if forward then textEnd
+ else textBegin) in
+ let found = TextIndex (i, []) in
+ current_index :=
+ TextIndex(i, [CharOffset (if forward then 1 else (-1))]);
+ Text.tag_delete t ["search"];
+ Text.tag_add t "search" found (TextIndex (i, [WordEnd]));
+ Text.tag_configure t "search"
+ [Relief Raised; BorderWidth (Pixels 1);
+ Background Red];
+ Text.see t found
+ with
+ Invalid_argument _ -> Bell.ring() in
+
+ bind e [[], KeyPressDetail "Return"]
+ (BindSet ([], fun _ -> search false ()));
+ Button.configure searchb [Command (search false)];
+ Button.configure contb [Command (search true)];
+ Tkwait.visibility top;
+ Focus.set e
+
+let addsearch tx =
+ let tags = bindtags_get tx in
+ match tags with
+ (WidgetBindings t)::l when t = tx ->
+ bindtags tx ((WidgetBindings tx) :: (TagBindings "SEARCH") :: l)
+ | _ -> ()
+
+(* We use Mod1 instead of Meta or Alt *)
+let init () =
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> page_up ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "BackSpace"];
+ [[], KeyPressDetail "Delete"];
+ [[], KeyPressDetail "Prior"];
+ [[], KeyPressDetail "b"];
+ [[Mod1], KeyPressDetail "v"]
+ ];
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> page_down ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "space"];
+ [[], KeyPressDetail "Next"];
+ [[Control], KeyPressDetail "v"]
+ ];
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> line_up ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "Up"];
+ [[Mod1], KeyPressDetail "z"]
+ ];
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> line_down ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "Down"];
+ [[Control], KeyPressDetail "z"]
+ ];
+
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> top ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "Home"];
+ [[Mod1], KeyPressDetail "less"]
+ ];
+
+ List.iter (function ev ->
+ tag_bind "TEXT_RO" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> bottom ei.ev_Widget; break()))))
+ [
+ [[], KeyPressDetail "End"];
+ [[Mod1], KeyPressDetail "greater"]
+ ];
+
+ List.iter (function ev ->
+ tag_bind "SEARCH" ev
+ (BindSetBreakable ([Ev_Widget],
+ (fun ei -> topsearch ei.ev_Widget; break()))))
+ [
+ [[Control], KeyPressDetail "s"]
+ ]
+
diff --git a/otherlibs/labltk/frx/frx_text.mli b/otherlibs/labltk/frx/frx_text.mli
new file mode 100644
index 000000000..ac0384432
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_text.mli
@@ -0,0 +1,46 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+
+val abs_index : int -> textIndex
+ (* [abs_index offs] returns the corresponding TextIndex *)
+
+val insertMark : textIndex
+val currentMark : textIndex
+val textEnd : textIndex
+val textBegin : textIndex
+ (* shortcuts for various positions in a text widget *)
+
+val scroll_link : Widget.widget -> Widget.widget -> unit
+ (* [scroll_link scrollbar text] links a scrollbar and a text widget
+ as expected
+ *)
+
+val new_scrollable_text :
+ Widget.widget -> options list -> bool -> Widget.widget * Widget.widget
+ (* [new_scrollable_text parent opts nav_keys] makes a scrollable text
+ widget with optional navigation keys. Returns frame and text widget.
+ *)
+val addsearch : Widget.widget -> unit
+ (* [addsearch textw] adds a search dialog bound on [Control-s]
+ on the text widget
+ *)
+
+val navigation_keys : Widget.widget -> unit
+ (* [navigation_keys textw] adds common navigations functions to [textw] *)
+
+val init : unit -> unit
+ (* [init ()] must be called before any of the above features is used *)
diff --git a/otherlibs/labltk/frx/frx_toplevel.mli b/otherlibs/labltk/frx/frx_toplevel.mli
new file mode 100644
index 000000000..3608e1e57
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_toplevel.mli
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Widget
+val make_visible : Widget -> unit
diff --git a/otherlibs/labltk/frx/frx_widget.ml b/otherlibs/labltk/frx/frx_widget.ml
new file mode 100644
index 000000000..ab7d26112
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_widget.ml
@@ -0,0 +1,24 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+
+let version = "$Id$"
+(* Make a window (toplevel widget) resizeable *)
+let resizeable t =
+ update_idletasks(); (* wait until layout is computed *)
+ Wm.minsize_set t (Winfo.width t) (Winfo.height t)
+
diff --git a/otherlibs/labltk/frx/frx_widget.mli b/otherlibs/labltk/frx/frx_widget.mli
new file mode 100644
index 000000000..ff26749ca
--- /dev/null
+++ b/otherlibs/labltk/frx/frx_widget.mli
@@ -0,0 +1,18 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+val resizeable : widget -> unit
diff --git a/otherlibs/labltk/jpf/Makefile b/otherlibs/labltk/jpf/Makefile
index 1286c177b..1c499356d 100644
--- a/otherlibs/labltk/jpf/Makefile
+++ b/otherlibs/labltk/jpf/Makefile
@@ -1,56 +1,60 @@
include ../support/Makefile.common
-COMPFLAGS=-I ../lib -I ../support -I $(OTHERS)/unix -I $(OTHERS)/str
+COMPFLAGS=-I ../labltk -I ../support -I $(OTHERS)/unix -I $(OTHERS)/str
-OBJS= fileselect.cmo balloon.cmo
+OBJS= fileselect.cmo balloon.cmo shell.cmo jpf_font.cmo
OBJSX = $(OBJS:.cmo=.cmx)
-all: libjpf.cma
+all: jpflib.cma
-opt: libjpf.cmxa
+opt: jpflib.cmxa
test: balloontest
testopt: balloontest.opt
-libjpf.cma: $(OBJS)
- $(LABLLIBR) -o libjpf.cma $(OBJS)
+jpflib.cma: $(OBJS)
+ $(CAMLLIBR) -o jpflib.cma $(OBJS)
-libjpf.cmxa: $(OBJSX)
- $(CAMLOPTLIBR) -o libjpf.cmxa $(OBJSX)
+jpflib.cmxa: $(OBJSX)
+ $(CAMLOPTLIBR) -o jpflib.cmxa $(OBJSX)
-install: libjpf.cma
- cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) libjpf.cma $(LABLTKDIR)
+install: jpflib.cma
+ cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) jpflib.cma $(INSTALLDIR)
-installopt: libjpf.cmxa
- cp libjpf.cmxa libjpf.a $(OBJS:.cmo=.cmx) $(LABLTKDIR)
+installopt: jpflib.cmxa
+ cp jpflib.cmxa jpflib.a $(OBJS:.cmo=.cmx) $(INSTALLDIR)
clean:
rm -f *.cm* *.o *.a *~ *test
+$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma
+
+$(OBJSX): ../lib/$(LIBNAME).cmxa
+
### Tests
balloontest: balloontest.cmo
- $(LABLC) -o balloontest -I ../support -I ../lib \
- -custom labltk.cma libjpf.cma balloontest.cmo
+ $(CAMLC) -o balloontest -I ../support -I ../lib \
+ -custom $(LIBNAME).cma jpflib.cma balloontest.cmo
balloontest.opt: balloontest.cmx
$(CAMLOPT) -o balloontest.opt -I ../support -I ../lib \
- labltk.cmxa libjpf.cmxa balloontest.cmx
+ $(LIBNAME).cmxa jpflib.cmxa balloontest.cmx
-balloontest.cmo : balloon.cmo libjpf.cma
+balloontest.cmo : balloon.cmo jpflib.cma
-balloontest.cmx : balloon.cmx libjpf.cmxa
+balloontest.cmx : balloon.cmx jpflib.cmxa
.SUFFIXES :
.SUFFIXES : .mli .ml .cmi .cmx .cmo
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmx:
$(CAMLOPT) -c $(COMPFLAGS) $<
@@ -58,14 +62,16 @@ balloontest.cmx : balloon.cmx libjpf.cmxa
depend:
mv Makefile Makefile.bak
(sed -n -e '1,/^### DO NOT DELETE THIS LINE/p' Makefile.bak; \
- $(LABLDEP) *.mli *.ml) > Makefile
+ $(CAMLDEP) *.mli *.ml) > Makefile
### EVERYTHING THAT GOES BEYOND THIS COMMENT IS GENERATED
### DO NOT DELETE THIS LINE
balloon.cmo: balloon.cmi
balloon.cmx: balloon.cmi
-balloontest.cmo: balloon.cmi
-balloontest.cmx: balloon.cmx
fileselect.cmo: fileselect.cmi
fileselect.cmx: fileselect.cmi
+jpf_font.cmo: shell.cmi jpf_font.cmi
+jpf_font.cmx: shell.cmx jpf_font.cmi
+shell.cmo: shell.cmi
+shell.cmx: shell.cmi
diff --git a/otherlibs/labltk/jpf/Makefile.nt b/otherlibs/labltk/jpf/Makefile.nt
index 8a0f58cb8..cccd58436 100644
--- a/otherlibs/labltk/jpf/Makefile.nt
+++ b/otherlibs/labltk/jpf/Makefile.nt
@@ -1,6 +1,6 @@
!include ..\support\Makefile.common.nt
-COMPFLAGS=-I ../lib -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/str
+COMPFLAGS=-I ../labltk -I ../support -I $(OTHERS)/win32unix -I $(OTHERS)/str
OBJS= fileselect.cmo balloon.cmo
@@ -15,29 +15,33 @@ test: balloontest
testopt: balloontest.opt
libjpf.cma: $(OBJS)
- $(LABLLIBR) -o libjpf.cma $(OBJS)
+ $(CAMLLIBR) -o libjpf.cma $(OBJS)
libjpf.cmxa: $(OBJSX)
$(CAMLOPTLIBR) -o libjpf.cmxa $(OBJSX)
install: libjpf.cma
- cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) libjpf.cma $(LABLTKDIR)
+ cp $(OBJS:.cmo=.cmi) $(OBJS:.cmo=.mli) libjpf.cma $(INSTALLDIR)
installopt: libjpf.cmxa
- cp libjpf.cmxa libjpf.lib $(LABLTKDIR)
+ cp libjpf.cmxa libjpf.lib $(INSTALLDIR)
clean:
- rm -f *.cm* *.o *.a *~ *test
+ rm -f *.cm* *.obj *.a *~ *test *.lib
+
+$(OBJS) $(OBJS:.cmo=.cmi): ..\lib\$(LIBNAME).cma
+
+$(OBJSX): ..\lib\$(LIBNAME).cmxa
### Tests
balloontest: balloontest.cmo
- $(LABLC) -o balloontest -I ../support -I ../lib \
- -custom labltk.cma libjpf.cma balloontest.cmo $(TKLINKOPT)
+ $(CAMLC) -o balloontest -I ../support -I ../labltk -I ../lib \
+ -custom $(LIBNAME).cma libjpf.cma balloontest.cmo $(TKLINKOPT)
balloontest.opt: balloontest.cmx
- $(CAMLOPT) -o balloontest.opt -I ../support -I ../lib \
- labltk.cmxa libjpf.cmxa balloontest.cmx $(TKLINKOPT)
+ $(CAMLOPT) -o balloontest.opt -I ../support -I ../labltk -I ../lib \
+ $(LIBNAME).cmxa libjpf.cmxa balloontest.cmx $(TKLINKOPT)
balloontest.cmo : balloon.cmo libjpf.cma
@@ -47,10 +51,10 @@ balloontest.cmx : balloon.cmx libjpf.cmxa
.SUFFIXES : .mli .ml .cmi .cmx .cmo
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmx:
$(CAMLOPT) -c $(COMPFLAGS) $<
@@ -58,7 +62,7 @@ balloontest.cmx : balloon.cmx libjpf.cmxa
depend:
mv Makefile Makefile.bak
(sed -n -e '1,/^### DO NOT DELETE THIS LINE/p' Makefile.bak; \
- $(LABLDEP) *.mli *.ml) > Makefile
+ $(CAMLDEP) *.mli *.ml) > Makefile
### EVERYTHING THAT GOES BEYOND THIS COMMENT IS GENERATED
diff --git a/otherlibs/labltk/jpf/README b/otherlibs/labltk/jpf/README
new file mode 100644
index 000000000..275c2d780
--- /dev/null
+++ b/otherlibs/labltk/jpf/README
@@ -0,0 +1,2 @@
+This is Jun Furuse's widget set library, Jpf.
+It uses LablTk API.
diff --git a/otherlibs/labltk/jpf/balloon.ml b/otherlibs/labltk/jpf/balloon.ml
index 818a48881..6b2f36d20 100644
--- a/otherlibs/labltk/jpf/balloon.ml
+++ b/otherlibs/labltk/jpf/balloon.ml
@@ -1,16 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -94,7 +96,7 @@ let init () =
begin fun w ->
try Hashtbl.find t w.ev_Widget
with Not_found ->
- Hashtbl'.add t ~key:w.ev_Widget ~data: ();
+ Hashtbl.add t w.ev_Widget ();
let x = Option.get w.ev_Widget ~name: "balloon" ~clas: "Balloon" in
if x <> "" then put ~on: w.ev_Widget ~ms: 1000 x
end
diff --git a/otherlibs/labltk/jpf/balloon.mli b/otherlibs/labltk/jpf/balloon.mli
index cae6e5bb3..633796ce6 100644
--- a/otherlibs/labltk/jpf/balloon.mli
+++ b/otherlibs/labltk/jpf/balloon.mli
@@ -1,16 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/jpf/balloontest.ml b/otherlibs/labltk/jpf/balloontest.ml
index 63e86c169..36e6c8dbf 100644
--- a/otherlibs/labltk/jpf/balloontest.ml
+++ b/otherlibs/labltk/jpf/balloontest.ml
@@ -1,16 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -22,9 +24,9 @@ open Protocol
let _ =
let t = openTk () in
Balloon.init ();
- let b = Button.create t text: "hello" in
- Button.configure b command: (fun () -> destroy b);
+ let b = Button.create t ~text: "hello" in
+ Button.configure b ~command: (fun () -> destroy b);
pack [b];
- Balloon.put on: b ms: 1000 "Balloon";
+ Balloon.put ~on: b ~ms: 1000 "Balloon";
Printexc.catch mainLoop ()
diff --git a/otherlibs/labltk/jpf/fileselect.ml b/otherlibs/labltk/jpf/fileselect.ml
index 28d2349ea..ec0e7749f 100644
--- a/otherlibs/labltk/jpf/fileselect.ml
+++ b/otherlibs/labltk/jpf/fileselect.ml
@@ -1,21 +1,26 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
(* file selection box *)
+(* This file selecter works only under the OS with the full unix support.
+ For the portability, Tk.getOpenFile and Tk.getSaveFile are recommended. *)
+
open StdLabels
open UnixLabels
open Str
diff --git a/otherlibs/labltk/jpf/fileselect.mli b/otherlibs/labltk/jpf/fileselect.mli
index 1948ad772..79dc828f9 100644
--- a/otherlibs/labltk/jpf/fileselect.mli
+++ b/otherlibs/labltk/jpf/fileselect.mli
@@ -1,19 +1,24 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
+(* This file selecter works only under the OS with the full unix support.
+ For the portability, Tk.getOpenFile and Tk.getSaveFile are recommended. *)
+
open Support
val f :
diff --git a/otherlibs/labltk/jpf/jpf_font.ml b/otherlibs/labltk/jpf/jpf_font.ml
new file mode 100644
index 000000000..93deab643
--- /dev/null
+++ b/otherlibs/labltk/jpf/jpf_font.ml
@@ -0,0 +1,218 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+(* find font information *)
+
+let debug = ref false
+let log s =
+ if !debug then try prerr_endline s with _ -> ()
+
+type ('s, 'i) xlfd = {
+ (* some of them are currently not interesting for me *)
+ mutable foundry: 's;
+ mutable family: 's;
+ mutable weight: 's;
+ mutable slant: 's;
+ mutable setWidth: 's;
+ mutable addStyle: 's;
+ mutable pixelSize: 'i;
+ mutable pointSize: 'i;
+ mutable resolutionX: 'i;
+ mutable resolutionY: 'i;
+ mutable spacing: 's;
+ mutable averageWidth: 'i;
+ mutable registry: 's;
+ mutable encoding: 's
+ }
+
+let copy xlfd = {xlfd with foundry= xlfd.foundry}
+
+let string_of_xlfd s i xlfd =
+ let foundry= s xlfd.foundry
+ and family= s xlfd.family
+ and weight= s xlfd.weight
+ and slant= s xlfd.slant
+ and setWidth = s xlfd.setWidth
+ and addStyle = s xlfd.addStyle
+ and pixelSize= i xlfd.pixelSize
+ and pointSize = i xlfd.pointSize
+ and resolutionX = i xlfd.resolutionX
+ and resolutionY = i xlfd.resolutionY
+ and spacing= s xlfd.spacing
+ and averageWidth = i xlfd.averageWidth
+ and registry= s xlfd.registry
+ and encoding = s xlfd.encoding in
+
+ "-"^foundry^
+ "-"^family^
+ "-"^weight^
+ "-"^slant^
+ "-"^setWidth ^
+ "-"^addStyle ^
+ "-"^pixelSize^
+ "-"^pointSize ^
+ "-"^resolutionX ^
+ "-"^resolutionY ^
+ "-"^spacing^
+ "-"^averageWidth ^
+ "-"^registry^
+ "-"^encoding
+
+exception Parse_Xlfd_Failure of string
+
+let parse_xlfd xlfd_string =
+ (* this must not be a pattern *)
+ let split_str char_sep str =
+ let len = String.length str in
+ let rec split beg cur =
+ if cur >= len then [String.sub str beg (len - beg)]
+ else if char_sep (String.get str cur)
+ then
+ let nextw = succ cur in
+ (String.sub str beg (cur - beg))
+ ::(split nextw nextw)
+ else split beg (succ cur) in
+ split 0 0
+ in
+ match split_str (function '-' -> true | _ -> false) xlfd_string with
+ | [ _; foundry; family; weight; slant; setWidth; addStyle; pixelSize;
+ pointSize; resolutionX; resolutionY; spacing; averageWidth;
+ registry; encoding ] ->
+ { foundry= foundry;
+ family= family;
+ weight= weight;
+ slant= slant;
+ setWidth= setWidth;
+ addStyle= addStyle;
+ pixelSize= int_of_string pixelSize;
+ pointSize= int_of_string pointSize;
+ resolutionX= int_of_string resolutionX;
+ resolutionY= int_of_string resolutionY;
+ spacing= spacing;
+ averageWidth= int_of_string averageWidth;
+ registry= registry;
+ encoding= encoding;
+ }
+ | _ -> raise (Parse_Xlfd_Failure xlfd_string)
+
+type valid_xlfd = (string, int) xlfd
+
+let string_of_valid_xlfd = string_of_xlfd (fun x -> x) string_of_int
+
+type pattern = (string option, int option) xlfd
+
+let empty_pattern =
+ { foundry= None;
+ family= None;
+ weight= None;
+ slant= None;
+ setWidth= None;
+ addStyle= None;
+ pixelSize= None;
+ pointSize= None;
+ resolutionX= None;
+ resolutionY= None;
+ spacing= None;
+ averageWidth= None;
+ registry= None;
+ encoding= None;
+ }
+
+let string_of_pattern =
+ let pat f = function
+ Some x -> f x
+ | None -> "*"
+ in
+ let pat_string = pat (fun x -> x) in
+ let pat_int = pat string_of_int in
+ string_of_xlfd pat_string pat_int
+
+let is_vector_font xlfd =
+ (xlfd.pixelSize = 0 && xlfd.resolutionX = 0 && xlfd.resolutionY = 0) ||
+ xlfd.spacing <> "c"
+
+let list_fonts dispname pattern =
+ let dispopt = match dispname with
+ None -> ""
+ | Some x -> "-display " ^ x
+ in
+ let result = List.map parse_xlfd
+ (Shell.subshell ("xlsfonts "^dispopt^" -fn "^string_of_pattern pattern))
+ in
+ if result = [] then raise Not_found
+ else result
+
+let available_pixel_size_aux dispname pattern =
+ (* return available pixel size without font resizing *)
+ (* to obtain good result, *)
+ (* the pattern should contain as many information as possible *)
+ let pattern = copy pattern in
+ pattern.pixelSize <- None;
+ let xlfds = list_fonts dispname pattern in
+ let pxszs = Hashtbl.create 107 in
+ List.iter (fun xlfd ->
+ Hashtbl.add pxszs xlfd.pixelSize xlfd) xlfds;
+ pxszs
+
+let extract_size_font_hash tbl =
+ let keys = ref [] in
+ Hashtbl.iter (fun k _ ->
+ if not (List.mem k !keys) then keys := k :: !keys) tbl;
+ Sort.list (fun (k1,_) (k2,_) -> k1 < k2)
+ (List.map (fun k -> k, Hashtbl.find_all tbl k) !keys)
+
+let available_pixel_size dispname pattern =
+ let pxszs = available_pixel_size_aux dispname pattern in
+ extract_size_font_hash pxszs
+
+let nearest_pixel_size dispname vector_ok pattern =
+ (* find the font with the nearest pixel size *)
+ log ("\n*** "^string_of_pattern pattern);
+ let pxlsz =
+ match pattern.pixelSize with
+ None -> raise (Failure "invalid pixelSize pattern")
+ | Some x -> x
+ in
+ let tbl = available_pixel_size_aux dispname pattern in
+ let newtbl = Hashtbl.create 107 in
+ Hashtbl.iter (fun s xlfd ->
+ if vector_ok then
+ if s = 0 then begin
+ if is_vector_font xlfd then begin
+ log (Printf.sprintf "%s is vector" (string_of_valid_xlfd xlfd));
+ xlfd.pixelSize <- pxlsz;
+ Hashtbl.add newtbl pxlsz xlfd
+ end
+ end else Hashtbl.add newtbl s xlfd
+ else if not (is_vector_font xlfd) && s <> 0 then
+ Hashtbl.add newtbl s xlfd) tbl;
+
+ let size_font_table = extract_size_font_hash newtbl in
+
+ let diff = ref 10000 in
+ let min = ref None in
+ List.iter (fun (s,xlfds) ->
+ let d = abs(s - pxlsz) in
+ if d < !diff then begin
+ min := Some (s,xlfds);
+ diff := d
+ end) size_font_table;
+ (* if it contains more than one font, just return the first *)
+ match !min with
+ | None -> raise Not_found
+ | Some(s, xlfds) ->
+ log (Printf.sprintf "Size %d is selected" s);
+ List.iter (fun xlfd -> log (string_of_valid_xlfd xlfd)) xlfds;
+ List.hd xlfds
diff --git a/otherlibs/labltk/jpf/jpf_font.mli b/otherlibs/labltk/jpf/jpf_font.mli
new file mode 100644
index 000000000..cd1e21229
--- /dev/null
+++ b/otherlibs/labltk/jpf/jpf_font.mli
@@ -0,0 +1,54 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val debug : bool ref
+
+type ('a, 'b) xlfd =
+ { mutable foundry: 'a;
+ mutable family: 'a;
+ mutable weight: 'a;
+ mutable slant: 'a;
+ mutable setWidth: 'a;
+ mutable addStyle: 'a;
+ mutable pixelSize: 'b;
+ mutable pointSize: 'b;
+ mutable resolutionX: 'b;
+ mutable resolutionY: 'b;
+ mutable spacing: 'a;
+ mutable averageWidth: 'b;
+ mutable registry: 'a;
+ mutable encoding: 'a }
+
+exception Parse_Xlfd_Failure of string
+
+type valid_xlfd = (string, int) xlfd
+type pattern = (string option, int option) xlfd
+
+val empty_pattern : pattern
+
+val copy : ('a, 'b) xlfd -> ('a, 'b) xlfd
+
+val string_of_valid_xlfd : valid_xlfd -> string
+val string_of_pattern : pattern -> string
+
+val is_vector_font : valid_xlfd -> bool
+
+val list_fonts : string option -> pattern -> valid_xlfd list
+
+val available_pixel_size :
+ string option -> pattern -> (int * valid_xlfd list) list
+
+val nearest_pixel_size :
+ string option -> bool -> pattern -> valid_xlfd
diff --git a/otherlibs/labltk/jpf/shell.ml b/otherlibs/labltk/jpf/shell.ml
new file mode 100644
index 000000000..45b342258
--- /dev/null
+++ b/otherlibs/labltk/jpf/shell.ml
@@ -0,0 +1,36 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Unix
+
+(************************************************************* Subshell call *)
+
+let subshell cmd =
+ let r,w = pipe () in
+ match fork () with
+ 0 -> close r; dup2 w stdout;
+ close stderr;
+ execv "/bin/sh" [| "/bin/sh"; "-c"; cmd |]; exit 127
+ | id ->
+ close w;
+ let rc = in_channel_of_descr r in
+ let rec it () = try
+ let x = input_line rc in x:: it ()
+ with _ -> []
+ in
+ let answer = it() in
+ close_in rc; (* because of finalize_channel *)
+ let p, st = waitpid [] id in answer
+
diff --git a/otherlibs/labltk/jpf/shell.mli b/otherlibs/labltk/jpf/shell.mli
new file mode 100644
index 000000000..be93f5f1a
--- /dev/null
+++ b/otherlibs/labltk/jpf/shell.mli
@@ -0,0 +1,17 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+val subshell : string -> string list
+
diff --git a/otherlibs/labltk/labltk/.cvsignore b/otherlibs/labltk/labltk/.cvsignore
new file mode 100644
index 000000000..585067641
--- /dev/null
+++ b/otherlibs/labltk/labltk/.cvsignore
@@ -0,0 +1,3 @@
+*.ml *.mli labltktop labltk
+modules
+.depend
diff --git a/otherlibs/labltk/labltk/Makefile b/otherlibs/labltk/labltk/Makefile
new file mode 100644
index 000000000..423a67e80
--- /dev/null
+++ b/otherlibs/labltk/labltk/Makefile
@@ -0,0 +1,45 @@
+include ../support/Makefile.common
+
+COMPFLAGS= -I ../support
+
+all: labltkobjs
+
+opt: labltkobjsx
+
+include ./modules
+
+LABLTKOBJS = $(WIDGETOBJS) tk.cmo labltk.cmo
+LABLTKOBJSX = $(LABLTKOBJS:.cmo=.cmx)
+
+labltkobjs: $(LABLTKOBJS)
+
+labltkobjsx: $(LABLTKOBJSX)
+
+# All .{ml,mli} files are generated in this directory
+clean:
+ rm -f *.cm* *.ml *.mli *.o *.a
+ $(MAKE) -f Makefile.gen clean
+
+install: $(LABLTKOBJS)
+ if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(LABLTKOBJS:.cmo=.cmi) $(WIDGETOBJS:.cmo=.mli) $(INSTALLDIR)
+ chmod 644 $(INSTALLDIR)/*.cmi
+
+installopt: $(LABLTKOBJSX)
+ @if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(LABLTKOBJSX) $(INSTALLDIR)
+ chmod 644 $(INSTALLDIR)/*.cmx
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+include .depend
diff --git a/otherlibs/labltk/labltk/Makefile.gen b/otherlibs/labltk/labltk/Makefile.gen
new file mode 100644
index 000000000..08b91a032
--- /dev/null
+++ b/otherlibs/labltk/labltk/Makefile.gen
@@ -0,0 +1,42 @@
+include ../support/Makefile.common
+
+all: tk.ml labltk.ml .depend
+
+_tkgen.ml: ../Widgets.src ../compiler/tkcompiler
+ cd ..; ../../boot/ocamlrun compiler/tkcompiler -outdir labltk
+
+# dependencies are broken: wouldn't work with gmake 3.77
+
+tk.ml labltk.ml .depend: _tkgen.ml ../builtin/report.ml ../compiler/pp #../builtin/builtin_*.ml
+ (echo 'open StdLabels'; \
+ echo 'open Widget'; \
+ echo 'open Protocol'; \
+ echo 'open Support'; \
+ echo 'open Textvariable'; \
+ cat ../builtin/report.ml; \
+ cat ../builtin/builtin_*.ml; \
+ cat _tkgen.ml; \
+ echo ; \
+ echo ; \
+ echo 'module Tkintf = struct'; \
+ cat ../builtin/builtini_*.ml; \
+ cat _tkigen.ml; \
+ echo 'end (* module Tkintf *)'; \
+ echo ; \
+ echo ; \
+ echo 'open Tkintf' ;\
+ echo ; \
+ echo ; \
+ cat ../builtin/builtinf_*.ml; \
+ cat _tkfgen.ml; \
+ echo ; \
+ ) > _tk.ml
+ ../../../boot/ocamlrun ../compiler/pp < _tk.ml > tk.ml
+ rm -f _tk.ml
+ $(CAMLDEP) -I ../support [a-z]*.mli [a-z]*.ml > .depend
+
+../compiler/pp:
+ cd ../compiler; $(MAKE) pp
+
+clean:
+ rm -f modules .depend
diff --git a/otherlibs/labltk/labltk/Makefile.gen.nt b/otherlibs/labltk/labltk/Makefile.gen.nt
new file mode 100644
index 000000000..dc0fa9367
--- /dev/null
+++ b/otherlibs/labltk/labltk/Makefile.gen.nt
@@ -0,0 +1,43 @@
+!include ..\support\Makefile.common.nt
+
+all: tk.ml labltk.ml .depend
+
+_tkgen.ml: ..\Widgets.src ..\compiler\tkcompiler.exe
+ cd .. & ..\..\boot\ocamlrun compiler/tkcompiler.exe -outdir labltk
+
+# dependencies are broken: wouldn't work with gmake 3.77
+
+tk.ml labltk.ml .depend: _tkgen.ml ..\builtin\report.ml ..\compiler\pp.exe #../builtin/builtin_*.ml
+ type << > _tk.ml
+open StdLabels
+open Widget
+open Protocol
+open Support
+open Textvariable
+<<
+ type ..\builtin\report.ml >> _tk.ml
+ type ..\builtin\builtin_*.ml >> _tk.ml
+ type _tkgen.ml >> _tk.ml
+ type << >> _tk.ml
+
+
+module Tkintf = struct
+<<
+ type ..\builtin\builtini_*.ml >> _tk.ml
+ type _tkigen.ml >> _tk.ml
+ type << >> _tk.ml
+end (* module Tkintf *)
+
+
+open Tkintf
+
+
+<<
+ type ..\builtin\builtinf_*.ml >> _tk.ml
+ type _tkfgen.ml >> _tk.ml
+ ..\..\..\boot\ocamlrun ..\compiler\pp.exe < _tk.ml > tk.ml
+ rm -f _tk.ml
+ $(CAMLDEP) -I ../support *.mli *.ml > .depend
+
+clean:
+ rm -f modules .depend
diff --git a/otherlibs/labltk/labltk/Makefile.nt b/otherlibs/labltk/labltk/Makefile.nt
new file mode 100644
index 000000000..12582b807
--- /dev/null
+++ b/otherlibs/labltk/labltk/Makefile.nt
@@ -0,0 +1,43 @@
+!include ..\support\Makefile.common.nt
+
+COMPFLAGS= -I ../support
+
+all: labltkobjs
+
+opt: labltkobjsx
+
+# All .{ml,mli} files are generated in this directory
+clean :
+ rm -f *.cm* *.ml *.mli *.a *.obj
+ $(MAKE) -f Makefile.gen.nt clean
+
+!include .\modules
+
+LABLTKOBJS = $(WIDGETOBJS) tk.cmo labltk.cmo
+LABLTKOBJSX = $(LABLTKOBJS:.cmo=.cmx)
+
+labltkobjs: $(LABLTKOBJS)
+
+labltkobjsx: $(LABLTKOBJSX)
+
+install: $(LABLTKOBJS)
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp *.cmi [a-z]*.mli $(INSTALLDIR)
+
+installopt: $(LABLTKOBJSX)
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp $(LABLTKOBJSX) $(INSTALLDIR)
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+!include .depend
diff --git a/otherlibs/labltk/lib/.cvsignore b/otherlibs/labltk/lib/.cvsignore
index 585067641..3a756bb7a 100644
--- a/otherlibs/labltk/lib/.cvsignore
+++ b/otherlibs/labltk/lib/.cvsignore
@@ -1,3 +1,3 @@
-*.ml *.mli labltktop labltk
+*.ml *.mli labltktop labltk mltktop mltk
modules
.depend
diff --git a/otherlibs/labltk/lib/Makefile b/otherlibs/labltk/lib/Makefile
index ec1e04cd3..9a1e1003f 100644
--- a/otherlibs/labltk/lib/Makefile
+++ b/otherlibs/labltk/lib/Makefile
@@ -1,83 +1,69 @@
include ../support/Makefile.common
-COMPFLAGS= -I ../support
+all: $(LIBNAME).cma $(LIBNAME)top$(EXE) $(LIBNAME)
-SUPPORT=../support/support.cmo ../support/widget.cmo ../support/protocol.cmo \
- ../support/textvariable.cmo ../support/timer.cmo \
- ../support/fileevent.cmo
+opt: $(LIBNAME).cmxa
-SUPPORTX = $(SUPPORT:.cmo=.cmx)
+clean:
+ rm -f $(LIBNAME).cma $(LIBNAME).cmxa $(LIBNAME)top$(EXE) $(LIBNAME) *.a
-TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo
+include ../labltk/modules
+LABLTKOBJS=tk.cmo $(WIDGETOBJS)
-all : labltk.cma labltktop$(EXE) labltk
+include ../camltk/modules
+CAMLTKOBJS=cTk.cmo $(CWIDGETOBJS) labltk.cmo camltk.cmo
+
+SUPPORT=../support/support.cmo ../support/rawwidget.cmo \
+ ../support/widget.cmo ../support/protocol.cmo \
+ ../support/textvariable.cmo ../support/timer.cmo \
+ ../support/fileevent.cmo ../support/camltkwrap.cmo
-opt : labltk.cmxa
+TKOBJS=$(SUPPORT) $(LABLTKOBJS) $(CAMLTKOBJS)
-include ./modules
-WIDGETOBJSX = $(WIDGETOBJS:.cmo=.cmx)
+TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo
-labltk.cma : $(SUPPORT) $(WIDGETOBJS) tk.cmo
- $(MKLIB) -ocamlc '$(LABLC)' -o labltk -oc labltk41 \
- $(SUPPORT) tk.cmo $(WIDGETOBJS) \
+$(LIBNAME).cma: $(SUPPORT)
+ cd ../labltk; $(MAKE)
+ cd ../camltk; $(MAKE)
+ $(MKLIB) -ocamlc '$(CAMLC)' -o $(LIBNAME) -oc $(LIBNAME) \
+ -I ../labltk -I ../camltk $(TKOBJS) \
$(TK_LINK) $(X11_LINK)
-labltk.cmxa : $(SUPPORTX) $(WIDGETOBJSX) tk.cmx
- $(MKLIB) -ocamlopt '$(CAMLOPT)' -o labltk -oc labltk41 \
- $(SUPPORTX) tk.cmx $(WIDGETOBJSX) \
+$(LIBNAME).cmxa: $(SUPPORT:.cmo=.cmx)
+ cd ../labltk; $(MAKE) opt
+ cd ../camltk; $(MAKE) opt
+ $(MKLIB) -ocamlopt '$(CAMLOPT)' -o $(LIBNAME) -oc $(LIBNAME) \
+ -I ../labltk -I ../camltk $(TKOBJS:.cmo=.cmx) \
$(TK_LINK) $(X11_LINK)
-labltktop$(EXE) : $(TOPDEPS) $(WIDGETOBJS) $(SUPPORT) ../support/liblabltk41.a
- $(LABLC) -linkall -o labltktop$(EXE) -I ../support \
- -I $(TOPDIR)/toplevel toplevellib.cma labltk.cma \
+$(LIBNAME)top$(EXE) : $(TOPDEPS) $(LIBNAME).cma ../support/lib$(LIBNAME).a
+ $(CAMLC) -linkall -o $(LIBNAME)top$(EXE) -I ../support \
+ -I $(TOPDIR)/toplevel toplevellib.cma \
+ -I ../labltk -I ../camltk $(LIBNAME).cma \
-I $(OTHERS)/unix unix.cma \
-I $(OTHERS)/str str.cma \
$(DLLPATH) \
topmain.cmo
-labltk: Makefile $(TOPDIR)/config/Makefile
+$(LIBNAME): Makefile $(TOPDIR)/config/Makefile
@echo Generate $@
@echo "#!/bin/sh" > $@
- @echo 'exec $(LABLTKDIR)/labltktop$(EXE) -I $(LABLTKDIR) $$*' >> $@
-
-# All .{ml,mli} files are generated in this directory
-clean :
- rm -f *.cm* *.ml *.mli *.o *.a labltktop$(EXE)
-
-install: labltk.cma labltktop$(EXE) labltk
- if test -d $(LABLTKDIR); then : ; else mkdir $(LABLTKDIR); fi
- if test `grep -s -c '^$(LABLTKDIR)$$' $(LIBDIR)/ld.conf || :` = 0; \
- then echo $(LABLTKDIR) >> $(LIBDIR)/ld.conf; fi
- cp $(WIDGETOBJS:.cmo=.cmi) tk.cmi $(LABLTKDIR)
- cp labltk.cma labltktop$(EXE) $(LABLTKDIR)
- chmod 644 $(LABLTKDIR)/*.cmi
- chmod 644 $(LABLTKDIR)/labltk.cma
- chmod 755 $(LABLTKDIR)/labltktop$(EXE)
+ @echo 'exec $(INSTALLDIR)/$(LIBNAME)top$(EXE) -I $(INSTALLDIR) $$*' >> $@
+
+install: all
+ if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ if test `grep -s -c '^$(INSTALLDIR)$$' $(LIBDIR)/ld.conf || :` = 0; \
+ then echo $(INSTALLDIR) >> $(LIBDIR)/ld.conf; fi
+ cp $(LIBNAME).cma $(LIBNAME)top$(EXE) $(INSTALLDIR)
+ chmod 644 $(INSTALLDIR)/$(LIBNAME).cma
+ chmod 755 $(INSTALLDIR)/$(LIBNAME)top$(EXE)
@if test -d $(BINDIR); then : ; else mkdir $(BINDIR); fi
- cp labltk $(BINDIR)
- chmod 755 $(BINDIR)/labltk
-
-
-installopt: labltk.cmxa
- @if test -d $(LABLTKDIR); then : ; else mkdir $(LABLTKDIR); fi
- cp $(SUPPORTX) $(WIDGETOBJSX) tk.cmx $(LABLTKDIR)
- cp labltk.cmxa labltk.a $(LABLTKDIR)
- cd $(LABLTKDIR); $(RANLIB) labltk.a
- chmod 644 $(LABLTKDIR)/*.cmx
- chmod 644 $(LABLTKDIR)/labltk.cmxa
- chmod 644 $(LABLTKDIR)/labltk.a
- @if test -d $(BINDIR); then : ; else mkdir $(BINDIR); fi
-
-.SUFFIXES :
-.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
-
-.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
-
-.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
-
-.ml.cmx:
- $(CAMLOPT) -c $(COMPFLAGS) $<
-
-include .depend
+ cp $(LIBNAME) $(BINDIR)
+ chmod 755 $(BINDIR)/$(LIBNAME)
+
+installopt: opt
+ @if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(LIBNAME).cmxa $(LIBNAME).a $(INSTALLDIR)
+ cd $(INSTALLDIR); $(RANLIB) $(LIBNAME).a
+ chmod 644 $(INSTALLDIR)/$(LIBNAME).cmxa
+ chmod 644 $(INSTALLDIR)/$(LIBNAME).a
diff --git a/otherlibs/labltk/lib/Makefile.gen.nt b/otherlibs/labltk/lib/Makefile.gen.nt
deleted file mode 100644
index 43ad1ebe5..000000000
--- a/otherlibs/labltk/lib/Makefile.gen.nt
+++ /dev/null
@@ -1,38 +0,0 @@
-!include ..\support\Makefile.common.nt
-
-all: tk.ml .depend
-
-tkgen.ml: ..\Widgets.src ..\compiler\tkcompiler
- cd .. & ..\..\boot\ocamlrun compiler/tkcompiler
-
-# dependencies are broken: wouldn't work with gmake 3.77
-
-tk.ml .depend: tkgen.ml ..\builtin\report.ml #../builtin/builtin_*.ml
- type << > tk.ml
-open StdLabels
-open Widget
-open Protocol
-open Support
-open Textvariable
-<<
- type ..\builtin\report.ml >> tk.ml
- type ..\builtin\builtin_*.ml >> tk.ml
- type tkgen.ml >> tk.ml
- type << >> tk.ml
-
-
-module Tkintf = struct
-<<
- type ..\builtin\builtini_*.ml >> tk.ml
- type tkigen.ml >> tk.ml
- type << >> tk.ml
-end (* module Tkintf *)
-
-
-open Tkintf
-
-
-<<
- type ..\builtin\builtinf_*.ml >> tk.ml
- type tkfgen.ml >> tk.ml
- $(LABLDEP) *.mli *.ml > .depend
diff --git a/otherlibs/labltk/lib/Makefile.nt b/otherlibs/labltk/lib/Makefile.nt
index d3dfffa5f..99176c73e 100644
--- a/otherlibs/labltk/lib/Makefile.nt
+++ b/otherlibs/labltk/lib/Makefile.nt
@@ -1,60 +1,59 @@
!include ..\support\Makefile.common.nt
-COMPFLAGS= -I ../support
+all: $(LIBNAME).cma
-SUPPORT=../support/support.cmo ../support/widget.cmo ../support/protocol.cmo \
- ../support/textvariable.cmo ../support/timer.cmo \
- ../support/fileevent.cmo
-
-SUPPORTX = $(SUPPORT:.cmo=.cmx)
-
-TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo
-
-all : labltk.cma
-
-opt : labltk.cmxa
-
-include ./modules
-WIDGETOBJSX = $(WIDGETOBJS:.cmo=.cmx)
+opt: $(LIBNAME).cmxa
-labltk.cma : $(SUPPORT) $(WIDGETOBJS) tk.cmo
- $(LABLLIBR) -o labltk.cma $(SUPPORT) tk.cmo $(WIDGETOBJS) \
- -dllib -llabltk41 -cclib -llabltk41 $(TK_LINK)
+clean:
+ rm -f $(LIBNAME).cma $(LIBNAME).cmxa *.lib
-labltk.cmxa : $(SUPPORTX) $(WIDGETOBJSX) tk.cmx
- $(CAMLOPTLIBR) -o labltk.cmxa $(SUPPORTX) tk.cmx $(WIDGETOBJSX) \
- -cclib -llabltk41 $(TK_LINK)
+!include ..\labltk\modules
+LABLTKOBJS=tk.cmo $(WIDGETOBJS)
-#labltk : $(TOPDEPS) $(WIDGETOBJS) $(SUPPORT)
-# $(LABLC) -linkall -o $@ -I ../support $(TKLINKOPT) \
-# -I $(TOPDIR)/toplevel toplevellib.cma labltk.cma \
-# -I $(OTHERS)/win32unix unix.cma -I $(OTHERS)/str str.cma \
-# topmain.cmo
+!include ..\camltk\modules
+CAMLTKOBJS=cTk.cmo $(CWIDGETOBJS) labltk.cmo camltk.cmo
-# All .{ml,mli} files are generated in this directory
-clean :
- rm -f *.cm* *.ml *.mli *.o *.a labltktop
-
-install: labltk.cma #labltk
- @if not exist $(LABLTKDIR) mkdir $(LABLTKDIR)
- cp *.cmi labltk.cma $(LABLTKDIR)
-# @if not exist $(BINDIR) mkdir $(BINDIR)
-# cp labltk.exe $(BINDIR)
-
-installopt: labltk.cmxa
- @if not exist $(LABLTKDIR) mkdir $(LABLTKDIR)
- cp labltk.cmxa labltk.lib $(LABLTKDIR)
-
-.SUFFIXES :
-.SUFFIXES : .mli .ml .cmi .cmx .cmo .mlp
-
-.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
+SUPPORT=../support/support.cmo ../support/rawwidget.cmo \
+ ../support/widget.cmo ../support/protocol.cmo \
+ ../support/textvariable.cmo ../support/timer.cmo \
+ ../support/fileevent.cmo ../support/camltkwrap.cmo
-.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
+TKOBJS=$(SUPPORT) $(LABLTKOBJS) $(CAMLTKOBJS)
-.ml.cmx:
- $(CAMLOPT) -c $(COMPFLAGS) $<
+TOPDEPS = $(TOPDIR)/toplevel/toplevellib.cma $(TOPDIR)/toplevel/topmain.cmo
-!include .depend
+$(LIBNAME).cma: $(SUPPORT)
+ cd ..\labltk & $(MAKEREC)
+ cd ..\camltk & $(MAKEREC)
+ $(CAMLLIBR) -o $(LIBNAME).cma -I ../labltk -I ../camltk $(TKOBJS) \
+ -dllib -l$(LIBNAME) -cclib -l$(LIBNAME) $(TK_LINK)
+
+$(LIBNAME).cmxa: $(SUPPORT:.cmo=.cmx)
+ cd ../labltk; $(MAKEREC) opt
+ cd ../camltk; $(MAKEREC) opt
+ $(CAMLOPTLIBR) -o $(LIBNAME).cmxa -I ../labltk -I ../camltk \
+ $(TKOBJS:.cmo=.cmx) -cclib -l$(LIBNAME) $(TK_LINK)
+
+# $(LIBNAME)top$(EXE) : $(TOPDEPS) $(LIBNAME).cma ../support/lib$(LIBNAME).a
+# $(CAMLC) -linkall -o $(LIBNAME)top$(EXE) -I ../support \
+# -I $(TOPDIR)/toplevel toplevellib.cma \
+# -I ../labltk -I ../camltk $(LIBNAME).cma \
+# -I $(OTHERS)/unix unix.cma \
+# -I $(OTHERS)/str str.cma \
+# $(DLLPATH) \
+# topmain.cmo
+#
+# $(LIBNAME): Makefile $(TOPDIR)/config/Makefile
+# @echo Generate $@
+# @echo "#!/bin/sh" > $@
+# @echo 'exec $(INSTALLDIR)/$(LIBNAME)top$(EXE) -I $(INSTALLDIR) $$*' >> $@
+
+install: all
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp $(LIBNAME).cma $(INSTALLDIR)
+# @if test -d $(BINDIR); then : ; else mkdir $(BINDIR); fi
+# cp $(LIBNAME) $(BINDIR)
+
+installopt: opt
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp $(LIBNAME).cmxa $(LIBNAME).lib $(INSTALLDIR)
diff --git a/otherlibs/labltk/support/.depend b/otherlibs/labltk/support/.depend
index c10b37a92..0abefc892 100644
--- a/otherlibs/labltk/support/.depend
+++ b/otherlibs/labltk/support/.depend
@@ -1,9 +1,17 @@
+camltkwrap.cmi: protocol.cmi textvariable.cmi timer.cmi widget.cmi
protocol.cmi: widget.cmi
textvariable.cmi: protocol.cmi widget.cmi
+widget.cmi: rawwidget.cmi
+camltkwrap.cmo: fileevent.cmi protocol.cmi rawwidget.cmi textvariable.cmi \
+ timer.cmi camltkwrap.cmi
+camltkwrap.cmx: fileevent.cmx protocol.cmx rawwidget.cmx textvariable.cmx \
+ timer.cmx camltkwrap.cmi
fileevent.cmo: protocol.cmi support.cmi fileevent.cmi
fileevent.cmx: protocol.cmx support.cmx fileevent.cmi
protocol.cmo: support.cmi widget.cmi protocol.cmi
protocol.cmx: support.cmx widget.cmx protocol.cmi
+rawwidget.cmo: support.cmi rawwidget.cmi
+rawwidget.cmx: support.cmx rawwidget.cmi
slave.cmo: widget.cmi
slave.cmx: widget.cmx
support.cmo: support.cmi
@@ -12,5 +20,5 @@ textvariable.cmo: protocol.cmi support.cmi widget.cmi textvariable.cmi
textvariable.cmx: protocol.cmx support.cmx widget.cmx textvariable.cmi
timer.cmo: protocol.cmi support.cmi timer.cmi
timer.cmx: protocol.cmx support.cmx timer.cmi
-widget.cmo: support.cmi widget.cmi
-widget.cmx: support.cmx widget.cmi
+widget.cmo: rawwidget.cmi widget.cmi
+widget.cmx: rawwidget.cmx widget.cmi
diff --git a/otherlibs/labltk/support/Makefile b/otherlibs/labltk/support/Makefile
index dff07f26a..06ef541c8 100644
--- a/otherlibs/labltk/support/Makefile
+++ b/otherlibs/labltk/support/Makefile
@@ -1,49 +1,50 @@
include Makefile.common
-all: support.cmo widget.cmo protocol.cmo \
- textvariable.cmo timer.cmo fileevent.cmo \
- liblabltk41.a
+all: support.cmo rawwidget.cmo widget.cmo protocol.cmo \
+ textvariable.cmo timer.cmo fileevent.cmo camltkwrap.cmo \
+ lib$(LIBNAME).a
-opt: support.cmx widget.cmx protocol.cmx \
- textvariable.cmx timer.cmx fileevent.cmx \
- liblabltk41.a
+opt: support.cmx rawwidget.cmx widget.cmx protocol.cmx \
+ textvariable.cmx timer.cmx fileevent.cmx camltkwrap.cmx \
+ lib$(LIBNAME).a
-COBJS=cltkCaml.o cltkEval.o cltkEvent.o cltkFile.o cltkMain.o \
- cltkMisc.o cltkTimer.o cltkVar.o cltkWait.o
+COBJS=cltkCaml.o cltkUtf.o cltkEval.o cltkEvent.o cltkFile.o cltkMain.o \
+ cltkMisc.o cltkTimer.o cltkVar.o cltkWait.o cltkImg.o
CCFLAGS=-I../../../byterun $(TK_DEFS) $(X11_INCLUDES) $(SHAREDCCCOMPOPTS)
COMPFLAGS=-I $(OTHERS)/unix
-liblabltk41.a : $(COBJS)
- $(MKLIB) -o labltk41 $(COBJS) $(TK_LINK) $(X11_LINK)
+lib$(LIBNAME).a : $(COBJS)
+ $(MKLIB) -o $(LIBNAME) $(COBJS) $(TK_LINK) $(X11_LINK)
PUB=fileevent.cmi fileevent.mli \
protocol.cmi protocol.mli \
textvariable.cmi textvariable.mli \
timer.cmi timer.mli \
+ rawwidget.cmi rawwidget.mli \
widget.cmi widget.mli
-install: liblabltk41.a $(PUB)
- if test -d $(LABLTKDIR); then : ; else mkdir $(LABLTKDIR); fi
- cp $(PUB) liblabltk41.a $(LABLTKDIR)
- cd $(LABLTKDIR); $(RANLIB) liblabltk41.a
- cd $(LABLTKDIR); chmod 644 $(PUB) liblabltk41.a
- if test -f dlllabltk41.so; then \
- cp dlllabltk41.so $(LABLTKDIR)/dlllabltk41.so; \
- chmod 644 $(LABLTKDIR)/dlllabltk41.so; fi
+install: lib$(LIBNAME).a $(PUB)
+ if test -d $(INSTALLDIR); then : ; else mkdir $(INSTALLDIR); fi
+ cp $(PUB) lib$(LIBNAME).a $(INSTALLDIR)
+ cd $(INSTALLDIR); $(RANLIB) lib$(LIBNAME).a
+ cd $(INSTALLDIR); chmod 644 $(PUB) lib$(LIBNAME).a
+ if test -f dll$(LIBNAME).so; then \
+ cp dll$(LIBNAME).so $(INSTALLDIR)/dll$(LIBNAME).so; \
+ chmod 644 $(INSTALLDIR)/dll$(LIBNAME).so; fi
clean :
- rm -f *.cm* *.o *.a
+ rm -f *.cm* *.o *.a *.so
.SUFFIXES :
.SUFFIXES : .mli .ml .cmi .cmo .cmx .mlp .c .o
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmx:
$(CAMLOPT) -c $(COMPFLAGS) $<
@@ -52,7 +53,7 @@ clean :
$(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $<
depend:
- $(LABLDEP) *.mli *.ml > .depend
+ $(CAMLDEP) *.mli *.ml > .depend
$(COBJS): $(TOPDIR)/config/Makefile camltk.h
diff --git a/otherlibs/labltk/support/Makefile.common b/otherlibs/labltk/support/Makefile.common
index f50adf886..85cfbaf2c 100644
--- a/otherlibs/labltk/support/Makefile.common
+++ b/otherlibs/labltk/support/Makefile.common
@@ -4,22 +4,24 @@ TOPDIR=../../..
## Path to the otherlibs subdirectory
OTHERS=../..
+LIBNAME=labltk
+
include $(TOPDIR)/config/Makefile
-LABLTKDIR=$(LIBDIR)/labltk
+INSTALLDIR=$(LIBDIR)/$(LIBNAME)
## Tools from the Objective Caml distribution
CAMLRUN=$(TOPDIR)/boot/ocamlrun
-LABLC=$(CAMLRUN) $(TOPDIR)/ocamlc -I $(TOPDIR)/stdlib
-LABLCOMP=$(LABLC) -c -warn-error A
-LABLYACC=$(TOPDIR)/boot/ocamlyacc -v
-LABLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex
-LABLLIBR=$(LABLC) -a
-LABLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep
+CAMLC=$(CAMLRUN) $(TOPDIR)/ocamlc -I $(TOPDIR)/stdlib
+CAMLCOMP=$(CAMLC) -c -warn-error A
+CAMLYACC=$(TOPDIR)/boot/ocamlyacc -v
+CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex
+CAMLLIBR=$(CAMLC) -a
+CAMLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep
COMPFLAGS=
LINKFLAGS=
-DLLPATH=`if $(SUPPORTS_SHARED_LIBRARIES); then echo -dllpath $(LABLTKDIR); fi`
+DLLPATH=`if $(SUPPORTS_SHARED_LIBRARIES); then echo -dllpath $(INSTALLDIR); fi`
CAMLOPT=$(CAMLRUN) $(TOPDIR)/ocamlopt -I $(TOPDIR)/stdlib
CAMLOPTLIBR=$(CAMLOPT) -a
diff --git a/otherlibs/labltk/support/Makefile.common.nt b/otherlibs/labltk/support/Makefile.common.nt
index 98f30283e..f2f22110c 100644
--- a/otherlibs/labltk/support/Makefile.common.nt
+++ b/otherlibs/labltk/support/Makefile.common.nt
@@ -7,20 +7,22 @@ EXEDIR=$(TOPDIRNT)
## Path to the otherlibs subdirectory
OTHERS=../..
+LIBNAME=mltk
+
!include $(TOPDIRNT)\config\Makefile.nt
-LABLTKDIR=$(LIBDIR)\labltk
+INSTALLDIR=$(LIBDIR)\$(LIBNAME)
TKLINKOPT=$(STATIC)
## Tools from the Objective Caml distribution
CAMLRUN=$(EXEDIR)\boot\ocamlrun
-LABLC=$(CAMLRUN) $(TOPDIR)/ocamlc -I $(TOPDIR)/stdlib
-LABLCOMP=$(LABLC) -labels -c
-LABLYACC=$(EXEDIR)\boot\ocamlyacc -v
-LABLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex
-LABLLIBR=$(LABLC) -a
-LABLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep
+CAMLC=$(CAMLRUN) $(TOPDIR)/ocamlc -I $(TOPDIR)/stdlib
+CAMLCOMP=$(CAMLC) -labels -c
+CAMLYACC=$(EXEDIR)\boot\ocamlyacc -v
+CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex
+CAMLLIBR=$(CAMLC) -a
+CAMLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep
COMPFLAGS=
LINKFLAGS=
diff --git a/otherlibs/labltk/support/Makefile.nt b/otherlibs/labltk/support/Makefile.nt
index cff71b45e..acc3071dc 100644
--- a/otherlibs/labltk/support/Makefile.nt
+++ b/otherlibs/labltk/support/Makefile.nt
@@ -1,53 +1,53 @@
!include Makefile.common.nt
-all: support.cmo widget.cmo protocol.cmo \
- textvariable.cmo timer.cmo fileevent.cmo \
- dlllabltk41.dll liblabltk41.lib
+all: support.cmo rawwidget.cmo widget.cmo protocol.cmo \
+ textvariable.cmo timer.cmo fileevent.cmo camltkwrap.cmo \
+ dll$(LIBNAME).dll lib$(LIBNAME).lib
-opt: support.cmx widget.cmx protocol.cmx \
- textvariable.cmx timer.cmx fileevent.cmx \
- liblabltk41.lib
+opt: support.cmx rawwidget.cmx widget.cmx protocol.cmx \
+ textvariable.cmx timer.cmx fileevent.cmx camltkwrap.cmx \
+ lib$(LIBNAME).lib
-COBJS=cltkCaml.obj cltkEval.obj cltkEvent.obj cltkFile.obj cltkMain.obj \
- cltkMisc.obj cltkTimer.obj cltkVar.obj cltkWait.obj
+COBJS=cltkCaml.obj cltkUtf.obj cltkEval.obj cltkEvent.obj cltkFile.obj \
+ cltkMain.obj cltkMisc.obj cltkTimer.obj cltkVar.obj cltkWait.obj cltkImg.obj
CCFLAGS=-I..\..\..\byterun -I..\..\win32unix $(TK_DEFS)
COMPFLAGS=-I $(OTHERS)/win32unix
-dlllabltk41.dll : $(COBJS:.obj=.dobj)
- link /nologo /dll /out:dlllabltk41.dll /implib:tmp.lib \
+dll$(LIBNAME).dll : $(COBJS:.obj=.dobj)
+ link /nologo /dll /out:dll$(LIBNAME).dll /implib:dll$(LIBNAME).lib \
$(COBJS:.obj=.dobj) ..\..\..\byterun\ocamlrun.lib \
$(TK_LINK) wsock32.lib
- rm tmp.*
-liblabltk41.lib : $(COBJS:.obj=.sobj)
- rm -f liblabltk41.lib
- $(MKLIB)liblabltk41.lib $(COBJS:.obj=.sobj)
+lib$(LIBNAME).lib : $(COBJS:.obj=.sobj)
+ rm -f lib$(LIBNAME).lib
+ $(MKLIB)lib$(LIBNAME).lib $(COBJS:.obj=.sobj)
PUB=fileevent.cmi fileevent.mli \
protocol.cmi protocol.mli \
textvariable.cmi textvariable.mli \
timer.cmi timer.mli \
+ rawwidget.cmi rawwidget.mli \
widget.cmi widget.mli
-install: dlllabltk41.dll liblabltk41.lib $(PUB)
- @if not exist $(LABLTKDIR) mkdir $(LABLTKDIR)
- cp $(PUB) $(LABLTKDIR)
- cp dlllabltk41.dll liblabltk41.lib $(LABLTKDIR)
- echo $(LABLTKDIR)>> $(LIBDIR)\ld.conf
+install: dll$(LIBNAME).dll lib$(LIBNAME).lib $(PUB)
+ @if not exist $(INSTALLDIR) mkdir $(INSTALLDIR)
+ cp $(PUB) $(INSTALLDIR)
+ cp dll$(LIBNAME).dll dll$(LIBNAME).lib lib$(LIBNAME).lib $(INSTALLDIR)
+ echo $(INSTALLDIR)>> $(LIBDIR)\ld.conf
clean :
- rm -f *.cm* *.dobj *.sobj *.dll *.lib
+ rm -f *.cm* *.dobj *.sobj *.dll *.lib *.exp *.obj
.SUFFIXES :
.SUFFIXES : .mli .ml .cmi .cmo .cmx .mlp .c .dobj .sobj
.mli.cmi:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmo:
- $(LABLCOMP) $(COMPFLAGS) $<
+ $(CAMLCOMP) $(COMPFLAGS) $<
.ml.cmx:
$(CAMLOPT) -c $(COMPFLAGS) $<
@@ -61,7 +61,7 @@ clean :
mv $*.obj $*.sobj
depend:
- $(LABLDEP) *.mli *.ml > .depend
+ $(CAMLDEP) *.mli *.ml > .depend
$(COBJS): camltk.h
diff --git a/otherlibs/labltk/support/camltk.h b/otherlibs/labltk/support/camltk.h
index 741a4184e..06505cf71 100644
--- a/otherlibs/labltk/support/camltk.h
+++ b/otherlibs/labltk/support/camltk.h
@@ -20,8 +20,12 @@
/* copy a Caml string to the C heap. Must be deallocated with stat_free */
extern char *string_to_c(value s);
+/* cltkUtf.c */
+extern value tcl_string_to_caml( char * );
+extern char * caml_string_to_tcl( value );
+
/* cltkEval.c */
-extern Tcl_Interp *cltclinterp; /* The Tcl interpretor */
+CAMLprim Tcl_Interp *cltclinterp; /* The Tcl interpretor */
extern value copy_string_list(int argc, char ** argv);
/* cltkCaml.c */
@@ -30,7 +34,7 @@ extern value *tkerror_exn;
extern value *handler_code;
extern int CamlCBCmd(ClientData clientdata, Tcl_Interp *interp,
int argc, char *argv[]);
-extern void tk_error(char * errmsg) Noreturn;
+CAMLprim void tk_error(char * errmsg) Noreturn;
/* cltkMain.c */
extern int signal_events;
diff --git a/otherlibs/labltk/support/camltkwrap.ml b/otherlibs/labltk/support/camltkwrap.ml
new file mode 100644
index 000000000..5afe864df
--- /dev/null
+++ b/otherlibs/labltk/support/camltkwrap.ml
@@ -0,0 +1,77 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+module Widget = struct
+ include Rawwidget
+ type widget = raw_any raw_widget
+
+ let default_toplevel = coe default_toplevel
+end
+
+module Protocol = struct
+ open Widget
+ include Protocol
+
+ let opentk () = coe (opentk ())
+ let opentk_with_args args = coe (opentk_with_args args)
+ let openTk ?display ?clas () = coe (openTk ?display ?clas ())
+
+ let cCAMLtoTKwidget table w =
+ Widget.check_class w table; (* we need run time type check of widgets *)
+ TkToken (Widget.name w)
+
+ (* backward compatibility *)
+ let openTkClass s = coe (openTkClass s)
+ let openTkDisplayClass disp c = coe (openTkDisplayClass disp c)
+end
+
+module Textvariable = struct
+ open Textvariable
+ type textVariable = Textvariable.textVariable
+ let create = create
+ let set = set
+ let get = get
+ let name = name
+ let cCAMLtoTKtextVariable = cCAMLtoTKtextVariable
+ let handle tv cbk = handle tv ~callback:cbk
+ let coerce = coerce
+
+ (*-*)
+ let free = free
+
+ (* backward compatibility *)
+ let create_temporary w = create ~on: w ()
+end
+
+module Fileevent = struct
+ open Fileevent
+ let add_fileinput fd callback = add_fileinput ~fd ~callback
+ let remove_fileinput fd = remove_fileinput ~fd
+ let add_fileoutput fd callback = add_fileoutput ~fd ~callback
+ let remove_fileoutput fd = remove_fileoutput ~fd
+end
+
+module Timer = struct
+ open Timer
+ type t = Timer.t
+ let add ms callback = add ~ms ~callback
+ let set ms callback = set ~ms ~callback
+ let remove = remove
+end
+
+(*
+Not compiled in support
+module Tkwait = Tkwait
+*)
diff --git a/otherlibs/labltk/support/camltkwrap.mli b/otherlibs/labltk/support/camltkwrap.mli
new file mode 100644
index 000000000..914ad0223
--- /dev/null
+++ b/otherlibs/labltk/support/camltkwrap.mli
@@ -0,0 +1,251 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+module Widget : sig
+ type widget = Widget.any Widget.widget
+ (* widget is an abstract type *)
+
+ val default_toplevel : widget
+ (* [default_toplevel] is "." in Tk, the toplevel widget that is
+ always existing during a Tk session. Destroying [default_toplevel]
+ ends the main loop
+ *)
+
+ val atom : parent: widget -> name: string -> widget
+ (* [atom parent name] returns the widget [parent.name]. The widget is
+ not created. Only its name is returned. In a given parent, there may
+ only exist one children for a given name.
+ This function should only be used to check the existence of a widget
+ with a known name. It doesn't add the widget to the internal tables
+ of CamlTk.
+ *)
+
+ val name : widget -> string
+ (* [name w] returns the name (tk "path") of a widget *)
+
+ (*--*)
+ (* The following functions are used internally.
+ There is normally no need for them in users programs
+ *)
+
+ val known_class : widget -> string
+ (* [known_class w] returns the class of a widget (e.g. toplevel, frame),
+ as known by the CamlTk interface.
+ Not equivalent to "winfo w" in Tk.
+ *)
+
+ val dummy : widget
+ (* [dummy] is a widget used as context when we don't have any.
+ It is *not* a real widget.
+ *)
+
+ val new_atom : parent: widget -> ?name: string -> string -> widget
+ (* incompatible with the classic camltk *)
+
+ val get_atom : string -> widget
+ (* [get_atom path] returns the widget with Tk path [path] *)
+
+ val remove : widget -> unit
+ (* [remove w] removes widget from the internal tables *)
+
+ (* Subtypes tables *)
+ val widget_any_table : string list
+ val widget_button_table : string list
+ val widget_canvas_table : string list
+ val widget_checkbutton_table : string list
+ val widget_entry_table : string list
+ val widget_frame_table : string list
+ val widget_label_table : string list
+ val widget_listbox_table : string list
+ val widget_menu_table : string list
+ val widget_menubutton_table : string list
+ val widget_message_table : string list
+ val widget_radiobutton_table : string list
+ val widget_scale_table : string list
+ val widget_scrollbar_table : string list
+ val widget_text_table : string list
+ val widget_toplevel_table : string list
+
+ val chk_sub : string -> 'a list -> 'a -> unit
+ val check_class : widget -> string list -> unit
+ (* Widget subtyping *)
+
+ exception IllegalWidgetType of string
+ (* Raised when widget command applied illegally*)
+
+ (* this function is not used, but introduced for the compatibility
+ with labltk. useless for camltk users *)
+ val coe : 'a Widget.widget -> Widget.any Widget.widget
+end
+
+module Protocol : sig
+ open Widget
+
+ (* Lower level interface *)
+ exception TkError of string
+ (* Raised by the communication functions *)
+
+ val debug : bool ref
+ (* When set to true, displays approximation of intermediate Tcl code *)
+
+ type tkArgs =
+ TkToken of string
+ | TkTokenList of tkArgs list (* to be expanded *)
+ | TkQuote of tkArgs (* mapped to Tcl list *)
+
+
+ (* Misc *)
+ external splitlist : string -> string list
+ = "camltk_splitlist"
+
+ val add_destroy_hook : (widget -> unit) -> unit
+
+
+ (* Opening, closing, and mainloop *)
+ val default_display : unit -> string
+
+ val opentk : unit -> widget
+ (* The basic initialization function. [opentk ()] parses automatically
+ the command line options and use the tk related options in them
+ such as "-display localhost:0" to initialize Tk applications.
+ Consult wish manpage about the supported options. *)
+
+ val keywords : (string * Arg.spec * string) list
+ (* Command line parsing specification for Arg.parse, which contains
+ the standard Tcl/Tk command line options such as "-display" and "-name".
+ These Tk command line options are used by opentk *)
+
+ val opentk_with_args : string list -> widget
+ (* [opentk_with_args argv] invokes [opentk] with the tk related
+ command line options given by [argv] to the executable program. *)
+
+ val openTk : ?display:string -> ?clas:string -> unit -> widget
+ (* [openTk ~display:display ~clas:clas ()] is equivalent to
+ [opentk ["-display"; display; "-name"; clas]] *)
+
+ (* Legacy opentk functions *)
+ val openTkClass: string -> widget
+ (* [openTkClass class] is equivalent to [opentk ["-name"; class]] *)
+ val openTkDisplayClass: string -> string -> widget
+ (* [openTkDisplayClass disp class] is equivalent to
+ [opentk ["-display"; disp; "-name"; class]] *)
+
+ val closeTk : unit -> unit
+ val finalizeTk : unit -> unit
+ (* Finalize tcl/tk before exiting. This function will be automatically
+ called when you call [Pervasives.exit ()] *)
+
+ val mainLoop : unit -> unit
+
+
+ (* Direct evaluation of tcl code *)
+ val tkEval : tkArgs array -> string
+
+ val tkCommand : tkArgs array -> unit
+
+ (* Returning a value from a Tcl callback *)
+ val tkreturn: string -> unit
+
+
+ (* Callbacks: this is private *)
+
+ type cbid = Protocol.cbid
+
+ type callback_buffer = string list
+ (* Buffer for reading callback arguments *)
+
+ val callback_naming_table : (cbid, callback_buffer -> unit) Hashtbl.t
+ (* CAMLTK val callback_memo_table : (widget, cbid) Hashtbl.t *)
+ val callback_memo_table : (widget, cbid) Hashtbl.t
+ (* Exported for debug purposes only. Don't use them unless you
+ know what you are doing *)
+ val new_function_id : unit -> cbid
+ val string_of_cbid : cbid -> string
+ val register_callback : widget -> callback:(callback_buffer -> unit) -> string
+ (* Callback support *)
+ val clear_callback : cbid -> unit
+ (* Remove a given callback from the table *)
+ val remove_callbacks : widget -> unit
+ (* Clean up callbacks associated to widget. Must be used only when
+ the Destroy event is bind by the user and masks the default
+ Destroy event binding *)
+
+ val cTKtoCAMLwidget : string -> widget
+ val cCAMLtoTKwidget : string list -> widget -> tkArgs
+
+ val register : string -> callback:(callback_buffer -> unit) -> unit
+
+ (*-*)
+ val prerr_cbid : cbid -> unit
+end
+
+module Textvariable : sig
+ open Widget
+ open Protocol
+
+ type textVariable = Textvariable.textVariable
+ (* TextVariable is an abstract type *)
+
+ val create : ?on: widget -> unit -> textVariable
+ (* Allocation of a textVariable with lifetime associated to widget
+ if a widget is specified *)
+ val create_temporary : widget -> textVariable
+ (* for backward compatibility
+ [create_temporary w] is equivalent to [create ~on:w ()] *)
+
+ val set : textVariable -> string -> unit
+ (* Setting the val of a textVariable *)
+ val get : textVariable -> string
+ (* Reading the val of a textVariable *)
+ val name : textVariable -> string
+ (* Its tcl name *)
+
+ val cCAMLtoTKtextVariable : textVariable -> tkArgs
+ (* Internal conversion function *)
+
+ val handle : textVariable -> (unit -> unit) -> unit
+ (* Callbacks on variable modifications *)
+
+ val coerce : string -> textVariable
+
+ (*-*)
+ val free : textVariable -> unit
+end
+
+module Fileevent : sig
+ open Unix
+
+ val add_fileinput : file_descr -> (unit -> unit) -> unit
+ val remove_fileinput: file_descr -> unit
+ val add_fileoutput : file_descr -> (unit -> unit) -> unit
+ val remove_fileoutput: file_descr -> unit
+ (* see [tk] module *)
+end
+
+module Timer : sig
+ type t = Timer.t
+
+ val add : int -> (unit -> unit) -> t
+ val set : int -> (unit -> unit) -> unit
+ val remove : t -> unit
+end
+
+(*
+Tkwait exists, but is not used in support
+module Tkwait : sig
+ val internal_tracevis : string -> string -> unit
+ val internal_tracedestroy : string -> string -> unit
+end
+*)
diff --git a/otherlibs/labltk/support/cltkCaml.c b/otherlibs/labltk/support/cltkCaml.c
index f9b9f7406..976c864ef 100644
--- a/otherlibs/labltk/support/cltkCaml.c
+++ b/otherlibs/labltk/support/cltkCaml.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -61,7 +61,7 @@ CAMLprim value camltk_return (value v)
}
/* Note: raise_with_string WILL copy the error message */
-void tk_error(char *errmsg)
+CAMLprim void tk_error(char *errmsg)
{
raise_with_string(*tkerror_exn, errmsg);
}
diff --git a/otherlibs/labltk/support/cltkEval.c b/otherlibs/labltk/support/cltkEval.c
index 40adccf2d..236dc299a 100644
--- a/otherlibs/labltk/support/cltkEval.c
+++ b/otherlibs/labltk/support/cltkEval.c
@@ -1,22 +1,23 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
#include <stdlib.h>
+#include <string.h>
#include <tcl.h>
#include <tk.h>
@@ -29,26 +30,26 @@
#include "camltk.h"
/* The Tcl interpretor */
-Tcl_Interp *cltclinterp = NULL;
+CAMLprim Tcl_Interp *cltclinterp = NULL;
/* Copy a list of strings from the C heap to Caml */
value copy_string_list(int argc, char **argv)
{
- value res;
+ CAMLparam0();
+ CAMLlocal3( res, oldres, str );
int i;
- value oldres = Val_unit, str = Val_unit;
-
- Begin_roots2 (oldres, str);
- res = Val_int(0); /* [] */
- for (i = argc-1; i >= 0; i--) {
- oldres = res;
- str = copy_string(argv[i]);
- res = alloc(2, 0);
- Field(res, 0) = str;
- Field(res, 1) = oldres;
- }
- End_roots();
- return res;
+ oldres = Val_unit;
+ str = Val_unit;
+
+ res = Val_int(0); /* [] */
+ for (i = argc-1; i >= 0; i--) {
+ oldres = res;
+ str = tcl_string_to_caml(argv[i]);
+ res = alloc(2, 0);
+ Field(res, 0) = str;
+ Field(res, 1) = oldres;
+ }
+ CAMLreturn(res);
}
/*
@@ -68,13 +69,13 @@ CAMLprim value camltk_tcl_eval(value str)
* leak
*/
Tcl_ResetResult(cltclinterp);
- cmd = string_to_c(str);
+ cmd = caml_string_to_tcl(str);
code = Tcl_Eval(cltclinterp, cmd);
stat_free(cmd);
switch (code) {
case TCL_OK:
- return copy_string(cltclinterp->result);
+ return tcl_string_to_caml(cltclinterp->result);
case TCL_ERROR:
tk_error(cltclinterp->result);
default: /* TCL_BREAK, TCL_CONTINUE, TCL_RETURN */
@@ -104,7 +105,7 @@ int argv_size(value v)
case 0: /* TkToken */
return 1;
case 1: /* TkTokenList */
- { int n;
+ { int n = 0;
value l;
for (l=Field(v,0), n=0; Is_block(l); l=Field(l,1))
n+=argv_size(Field(l,0));
@@ -112,23 +113,11 @@ int argv_size(value v)
}
case 2: /* TkQuote */
return 1;
- default: /* should not happen */
- Assert(0);
- return 0;
+ default:
+ tk_error("argv_size: illegal tag");
}
}
-/*
- * Memory of allocated Tcl lists.
- * We should not need more than MAX_LIST
- */
-#define MAX_LIST 256
-static char *tcllists[MAX_LIST];
-
-static int startfree = 0;
-/* If size is lower, do not allocate */
-static char *quotedargv[16];
-
/* Fill a preallocated vector arguments, doing expansion and all.
* Assumes Tcl will
* not tamper with our strings
@@ -136,34 +125,35 @@ static char *quotedargv[16];
*/
int fill_args (char **argv, int where, value v)
{
+ value l;
+
switch (Tag_val(v)) {
case 0:
- argv[where] = String_val(Field(v,0));
+ argv[where] = caml_string_to_tcl(Field(v,0)); /* must free by stat_free */
return (where + 1);
case 1:
- { value l;
- for (l=Field(v,0); Is_block(l); l=Field(l,1))
- where = fill_args(argv,where,Field(l,0));
- return where;
- }
+ for (l=Field(v,0); Is_block(l); l=Field(l,1))
+ where = fill_args(argv,where,Field(l,0));
+ return where;
case 2:
{ char **tmpargv;
+ char *merged;
+ int i;
int size = argv_size(Field(v,0));
- if (size < 16)
- tmpargv = &quotedargv[0];
- else
- tmpargv = (char **)stat_alloc((size + 1) * sizeof(char *));
+ tmpargv = (char **)stat_alloc((size + 1) * sizeof(char *));
fill_args(tmpargv,0,Field(v,0));
tmpargv[size] = NULL;
- argv[where] = Tcl_Merge(size,tmpargv);
- tcllists[startfree++] = argv[where]; /* so we can free it later */
- if (size >= 16)
- stat_free((char *)tmpargv);
+ merged = Tcl_Merge(size,tmpargv);
+ for(i = 0 ; i<size; i++){ stat_free(tmpargv[i]); }
+ stat_free((char *)tmpargv);
+ /* must be freed by stat_free */
+ argv[where] = (char*)stat_alloc(strlen(merged)+1);
+ strcpy(argv[where], merged);
+ Tcl_Free(merged);
return (where + 1);
}
- default: /* should not happen */
- Assert(0);
- return 0;
+ default:
+ tk_error("fill_args: illegal tag");
}
}
@@ -172,10 +162,9 @@ CAMLprim value camltk_tcl_direct_eval(value v)
{
int i;
int size; /* size of argv */
- char **argv;
+ char **argv, **allocated;
int result;
Tcl_CmdInfo info;
- int wherewasi,whereami; /* positions in tcllists array */
CheckInit();
@@ -186,76 +175,71 @@ CAMLprim value camltk_tcl_direct_eval(value v)
/* +2: one slot for NULL
one slot for "unknown" if command not found */
argv = (char **)stat_alloc((size + 2) * sizeof(char *));
+ allocated = (char **)stat_alloc(size * sizeof(char *));
- wherewasi = startfree; /* should be zero except when nested calls */
- Assert(startfree < MAX_LIST);
-
- /* Copy */
+ /* Copy -- argv[i] must be freed by stat_free */
{
int where;
- for(i=0, where=0;i<Wosize_val(v);i++)
+ for(i=0, where=0;i<Wosize_val(v);i++){
where = fill_args(argv,where,Field(v,i));
+ }
+ if( size != where ){ tk_error("fill_args error!!! Call the CamlTk maintainer!"); }
+ for(i=0; i<where; i++){ allocated[i] = argv[i]; }
argv[size] = NULL;
argv[size + 1] = NULL;
}
- Begin_roots_block ((value *) argv, size + 2);
-
- whereami = startfree;
-
- /* Eval */
- Tcl_ResetResult(cltclinterp);
- if (Tcl_GetCommandInfo(cltclinterp,argv[0],&info)) { /* command found */
+ /* Eval */
+ Tcl_ResetResult(cltclinterp);
+ if (Tcl_GetCommandInfo(cltclinterp,argv[0],&info)) { /* command found */
#if (TCL_MAJOR_VERSION >= 8)
- /* info.proc might be a NULL pointer
- * We should probably attempt an Obj invocation, but the following quick
- * hack is easier.
- */
- if (info.proc == NULL) {
- Tcl_DString buf;
- char *string;
- Tcl_DStringInit(&buf);
- Tcl_DStringAppend(&buf, argv[0], -1);
- for (i=1; i<size; i++) {
- Tcl_DStringAppend(&buf, " ", -1);
- Tcl_DStringAppend(&buf, argv[i], -1);
- }
- /* fprintf(stderr,"80 compat: %s\n", argv[0]); */
- result = Tcl_Eval(cltclinterp, Tcl_DStringValue(&buf));
- Tcl_DStringFree(&buf);
+ /* info.proc might be a NULL pointer
+ * We should probably attempt an Obj invocation, but the following quick
+ * hack is easier.
+ */
+ if (info.proc == NULL) {
+ Tcl_DString buf;
+ char *string;
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, argv[0], -1);
+ for (i=1; i<size; i++) {
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, argv[i], -1);
}
- else
- result = (*info.proc)(info.clientData,cltclinterp,size,argv);
-#else
+ result = Tcl_Eval(cltclinterp, Tcl_DStringValue(&buf));
+ Tcl_DStringFree(&buf);
+ } else {
result = (*info.proc)(info.clientData,cltclinterp,size,argv);
+ }
+#else
+ result = (*info.proc)(info.clientData,cltclinterp,size,argv);
#endif
- } else {/* implement the autoload stuff */
- if (Tcl_GetCommandInfo(cltclinterp,"unknown",&info)) { /* unknown found */
- for (i = size; i >= 0; i--)
- argv[i+1] = argv[i];
- argv[0] = "unknown";
- result = (*info.proc)(info.clientData,cltclinterp,size+1,argv);
- } else { /* ah, it isn't there at all */
- result = TCL_ERROR;
- Tcl_AppendResult(cltclinterp, "Unknown command \"",
- argv[0], "\"", NULL);
- }
+ } else { /* implement the autoload stuff */
+ if (Tcl_GetCommandInfo(cltclinterp,"unknown",&info)) { /* unknown found */
+ for (i = size; i >= 0; i--)
+ argv[i+1] = argv[i];
+ argv[0] = "unknown";
+ result = (*info.proc)(info.clientData,cltclinterp,size+1,argv);
+ } else { /* ah, it isn't there at all */
+ result = TCL_ERROR;
+ Tcl_AppendResult(cltclinterp, "Unknown command \"",
+ argv[0], "\"", NULL);
}
- End_roots ();
+ }
/* Free the various things we allocated */
+ for(i=0; i< size; i ++){
+ stat_free((char *) allocated[i]);
+ }
stat_free((char *)argv);
- for (i=wherewasi; i<whereami; i++)
- free(tcllists[i]);
- startfree = wherewasi;
+ stat_free((char *)allocated);
switch (result) {
case TCL_OK:
- return copy_string (cltclinterp->result);
+ return tcl_string_to_caml (cltclinterp->result);
case TCL_ERROR:
tk_error(cltclinterp->result);
default: /* TCL_BREAK, TCL_CONTINUE, TCL_RETURN */
tk_error("bad tcl result");
}
}
-
diff --git a/otherlibs/labltk/support/cltkEvent.c b/otherlibs/labltk/support/cltkEvent.c
index e2c24cca6..81c9413f6 100644
--- a/otherlibs/labltk/support/cltkEvent.c
+++ b/otherlibs/labltk/support/cltkEvent.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -26,14 +26,13 @@ CAMLprim value camltk_tk_mainloop(void)
{
CheckInit();
- if (cltk_slave_mode)
- return Val_unit;
+ if (cltk_slave_mode) return Val_unit;
if (!signal_events) {
/* Initialise signal handling */
signal_events = 1;
Tk_CreateTimerHandler(100, invoke_pending_caml_signals, NULL);
- };
+ }
Tk_MainLoop();
return Val_unit;
}
diff --git a/otherlibs/labltk/support/cltkFile.c b/otherlibs/labltk/support/cltkFile.c
index c77ea2198..9ea6004ed 100644
--- a/otherlibs/labltk/support/cltkFile.c
+++ b/otherlibs/labltk/support/cltkFile.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
diff --git a/otherlibs/labltk/support/cltkImg.c b/otherlibs/labltk/support/cltkImg.c
new file mode 100644
index 000000000..f30166ef5
--- /dev/null
+++ b/otherlibs/labltk/support/cltkImg.c
@@ -0,0 +1,111 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
+#include <string.h>
+#include <tcl.h>
+#include <tk.h>
+#include <mlvalues.h>
+#include <memory.h>
+#include <alloc.h>
+#include "camltk.h"
+
+/*
+ * Pixmap manipulation from OCaml : get the pixmap from an arbitrary photo
+ * image, and put it back in some (possibly other) image.
+ * TODO: other blits
+ * We use the same format of "internal" pixmap data as in Tk, that is
+ * 24 bits per pixel
+ */
+
+CAMLprim value camltk_getimgdata (value imgname) /* ML */
+{
+ CAMLparam1(imgname);
+ CAMLlocal1(res);
+ Tk_PhotoHandle ph;
+ Tk_PhotoImageBlock pib;
+ int code,size;
+
+#if (TK_MAJOR_VERSION < 8)
+ if (NULL == (ph = Tk_FindPhoto(String_val(imgname))))
+ tk_error("no such image");
+#else
+ if (NULL == (ph = Tk_FindPhoto(cltclinterp, String_val(imgname))))
+ tk_error("no such image");
+#endif
+
+ code = Tk_PhotoGetImage(ph,&pib); /* never fails ? */
+ size = pib.width * pib.height * pib.pixelSize;
+ res = alloc_string(size);
+
+ /* no holes, default format ? */
+ if ((pib.pixelSize == 3) &&
+ (pib.pitch == (pib.width * pib.pixelSize)) &&
+ (pib.offset[0] == 0) &&
+ (pib.offset[1] == 1) &&
+ (pib.offset[2] == 2)) {
+ memcpy(pib.pixelPtr, String_val(res),size);
+ CAMLreturn(res);
+ } else {
+ int y; /* varies from 0 to height - 1 */
+ int yoffs = 0; /* byte offset of line in src */
+ int yidx = 0; /* byte offset of line in dst */
+ for (y=0; y<pib.height; y++,yoffs+=pib.pitch,yidx+=pib.width * 3) {
+ int x; /* varies from 0 to width - 1 */
+ int xoffs = yoffs; /* byte offset of pxl in src */
+ int xidx = yidx; /* byte offset of pxl in dst */
+ for (x=0; x<pib.width; x++,xoffs+=pib.pixelSize,xidx+=3) {
+ Byte(res, xidx) = pib.pixelPtr[xoffs+pib.offset[0]];
+ Byte(res, xidx + 1) = pib.pixelPtr[xoffs+pib.offset[1]];
+ Byte(res, xidx + 2) = pib.pixelPtr[xoffs+pib.offset[2]];
+ };
+ }
+ CAMLreturn(res);
+ }
+}
+
+CAMLprim void
+camltk_setimgdata_native (value imgname, value pixmap, value x, value y,
+ value w, value h) /* ML */
+{
+ Tk_PhotoHandle ph;
+ Tk_PhotoImageBlock pib;
+ int code;
+
+#if (TK_MAJOR_VERSION < 8)
+ if (NULL == (ph = Tk_FindPhoto(String_val(imgname))))
+ tk_error("no such image");
+#else
+ if (NULL == (ph = Tk_FindPhoto(cltclinterp, String_val(imgname))))
+ tk_error("no such image");
+#endif
+
+ pib.pixelPtr = String_val(pixmap);
+ pib.width = Int_val(w);
+ pib.height = Int_val(h);
+ pib.pitch = pib.width * 3;
+ pib.pixelSize = 3;
+ pib.offset[0] = 0;
+ pib.offset[1] = 1;
+ pib.offset[2] = 2;
+ Tk_PhotoPutBlock(ph,&pib,Int_val(x),Int_val(y),Int_val(w),Int_val(h));
+}
+
+CAMLprim void camltk_setimgdata_bytecode(argv,argn)
+ value *argv;
+ int argn;
+{
+ camltk_setimgdata_native(argv[0], argv[1], argv[2], argv[3],
+ argv[4], argv[5]);
+}
diff --git a/otherlibs/labltk/support/cltkMain.c b/otherlibs/labltk/support/cltkMain.c
index 8512c72b2..6400c4a49 100644
--- a/otherlibs/labltk/support/cltkMain.c
+++ b/otherlibs/labltk/support/cltkMain.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -23,6 +23,7 @@
#include <memory.h>
#include <callback.h>
#include <signals.h>
+#include <fail.h>
#ifdef HAS_UNISTD
#include <unistd.h> /* for R_OK */
#endif
@@ -65,28 +66,62 @@ Tk_Window cltk_mainWindow;
int cltk_slave_mode = 0;
/* Initialisation, based on tkMain.c */
-CAMLprim value camltk_opentk(value display, value name)
+CAMLprim value camltk_opentk(value argv)
{
+ CAMLparam1(argv);
+ CAMLlocal1(tmp);
+ char *argv0;
+
+ /* argv must contain argv[0], the application command name */
+ tmp = Val_unit;
+
+ if ( argv == Val_int(0) ){
+ failwith("camltk_opentk: argv is empty");
+ }
+ argv0 = String_val( Field( argv, 0 ) );
+
if (!cltk_slave_mode) {
/* Create an interpreter, dies if error */
#if TCL_MAJOR_VERSION >= 8
- Tcl_FindExecutable(String_val(name));
+ Tcl_FindExecutable(String_val(argv0));
#endif
cltclinterp = Tcl_CreateInterp();
if (Tcl_Init(cltclinterp) != TCL_OK)
tk_error(cltclinterp->result);
- Tcl_SetVar(cltclinterp, "argv0", String_val (name), TCL_GLOBAL_ONLY);
- { /* Sets display if needed */
- char *args;
- char *tkargv[2];
- if (string_length(display) > 0) {
- Tcl_SetVar(cltclinterp, "argc", "2", TCL_GLOBAL_ONLY);
- tkargv[0] = "-display";
- tkargv[1] = String_val(display);
- args = Tcl_Merge(2, tkargv);
+ Tcl_SetVar(cltclinterp, "argv0", String_val (argv0), TCL_GLOBAL_ONLY);
+
+ { /* Sets argv */
+ int argc = 0;
+
+ tmp = Field(argv, 1); /* starts from argv[1] */
+ while ( tmp != Val_int(0) ) {
+ argc++;
+ tmp = Field(tmp, 1);
+ }
+
+ if( argc != 0 ){
+ int i;
+ char *args;
+ char **tkargv;
+ char argcstr[256]; /* string of argc */
+
+ tkargv = (char**)stat_alloc(sizeof( char* ) * argc );
+ tmp = Field(argv, 1); /* starts from argv[1] */
+ i = 0;
+
+ while ( tmp != Val_int(0) ) {
+ tkargv[i] = String_val(Field(tmp, 0));
+ tmp = Field(tmp, 1);
+ i++;
+ }
+
+ sprintf( argcstr, "%d", argc );
+ Tcl_SetVar(cltclinterp, "argc", argcstr, TCL_GLOBAL_ONLY);
+ args = Tcl_Merge(argc, tkargv); /* args must be freed by Tcl_Free */
Tcl_SetVar(cltclinterp, "argv", args, TCL_GLOBAL_ONLY);
- free(args);
+ Tcl_Free(args);
+ stat_free( tkargv );
}
}
if (Tk_Init(cltclinterp) != TCL_OK)
@@ -129,6 +164,11 @@ CAMLprim value camltk_opentk(value display, value name)
}
}
- return Val_unit;
+ CAMLreturn(Val_unit);
}
+CAMLprim value camltk_finalize(value unit) /* ML */
+{
+ Tcl_Finalize();
+ return Val_unit;
+}
diff --git a/otherlibs/labltk/support/cltkMisc.c b/otherlibs/labltk/support/cltkMisc.c
index 7980e0c8a..a6e823d1d 100644
--- a/otherlibs/labltk/support/cltkMisc.c
+++ b/otherlibs/labltk/support/cltkMisc.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -29,19 +29,24 @@ CAMLprim value camltk_splitlist (value v)
int argc;
char **argv;
int result;
+ char *utf;
CheckInit();
+ utf = caml_string_to_tcl(v);
/* argv is allocated by Tcl, to be freed by us */
- result = Tcl_SplitList(cltclinterp,String_val(v),&argc,&argv);
+ result = Tcl_SplitList(cltclinterp,utf,&argc,&argv);
switch(result) {
case TCL_OK:
{ value res = copy_string_list(argc,argv);
- free((char *)argv); /* only one large block was allocated */
+ Tcl_Free((char *)argv); /* only one large block was allocated */
+ /* argv points into utf: utf must be freed after argv are freed */
+ stat_free( utf );
return res;
}
case TCL_ERROR:
default:
+ stat_free( utf );
tk_error(cltclinterp->result);
}
}
diff --git a/otherlibs/labltk/support/cltkTimer.c b/otherlibs/labltk/support/cltkTimer.c
index 793535bea..21f1b1588 100644
--- a/otherlibs/labltk/support/cltkTimer.c
+++ b/otherlibs/labltk/support/cltkTimer.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
diff --git a/otherlibs/labltk/support/cltkUtf.c b/otherlibs/labltk/support/cltkUtf.c
new file mode 100644
index 000000000..fd01bd15a
--- /dev/null
+++ b/otherlibs/labltk/support/cltkUtf.c
@@ -0,0 +1,89 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <tcl.h>
+#include <tk.h>
+#include <mlvalues.h>
+#include <alloc.h>
+#include <memory.h>
+#ifdef HAS_UNISTD
+#include <unistd.h>
+#endif
+#include "camltk.h"
+
+#if (TCL_MAJOR_VERSION > 8 || \
+ (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)) /* 8.1 */
+# define UTFCONVERSION
+#endif
+
+#ifdef UTFCONVERSION
+
+char *external_to_utf( char *str ){
+ char *res;
+ Tcl_DString dstr;
+ int length;
+
+ Tcl_ExternalToUtfDString(NULL, str, strlen(str), &dstr);
+ length = Tcl_DStringLength(&dstr);
+ res = stat_alloc(length + 1);
+ memmove( res, Tcl_DStringValue(&dstr), length+1);
+ Tcl_DStringFree(&dstr);
+
+ return res;
+}
+
+char *utf_to_external( char *str ){
+ char *res;
+ Tcl_DString dstr;
+ int length;
+
+ Tcl_UtfToExternalDString(NULL, str, strlen(str), &dstr);
+ length = Tcl_DStringLength(&dstr);
+ res = stat_alloc(length + 1);
+ memmove( res, Tcl_DStringValue(&dstr), length+1);
+ Tcl_DStringFree(&dstr);
+
+ return res;
+}
+
+char *caml_string_to_tcl( value s )
+{
+ return external_to_utf( String_val(s) );
+}
+
+value tcl_string_to_caml( char *s )
+{
+ CAMLparam0();
+ CAMLlocal1(res);
+ char *str;
+
+ str = utf_to_external( s );
+ res = copy_string(str);
+ stat_free(str);
+ CAMLreturn(res);
+}
+
+#else
+
+char *caml_string_to_tcl(value s){ return string_to_c(s); }
+value tcl_string_to_caml(char *s){ return copy_string(s); }
+
+#endif
diff --git a/otherlibs/labltk/support/cltkVar.c b/otherlibs/labltk/support/cltkVar.c
index eae7eb12f..971336850 100644
--- a/otherlibs/labltk/support/cltkVar.c
+++ b/otherlibs/labltk/support/cltkVar.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -40,22 +40,28 @@ CAMLprim value camltk_getvar(value var)
if (s == NULL)
tk_error(cltclinterp->result);
else
- return(copy_string(s));
+ return(tcl_string_to_caml(s));
}
CAMLprim value camltk_setvar(value var, value contents)
{
char *s;
char *stable_var = NULL;
+ char *utf_contents;
CheckInit();
/* SetVar makes a copy of the contents. */
/* In case we have write traces in Caml, it's better to make sure that
var doesn't move... */
stable_var = string_to_c(var);
- s = Tcl_SetVar(cltclinterp,stable_var, String_val(contents),
+ utf_contents = caml_string_to_tcl(contents);
+ s = Tcl_SetVar(cltclinterp,stable_var, utf_contents,
TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
stat_free(stable_var);
+ if( s == utf_contents ){
+ tk_error("camltk_setvar: Tcl_SetVar returned strange result. Call the author of mlTk!");
+ }
+ stat_free(utf_contents);
if (s == NULL)
tk_error(cltclinterp->result);
@@ -68,12 +74,12 @@ CAMLprim value camltk_setvar(value var, value contents)
typedef char *(Tcl_VarTraceProc) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, char *part1, char *part2, int flags));
*/
-static char * tracevar(ClientData clientdata, Tcl_Interp *interp,
- char *name1, char *name2, int flags)
- /* Interpreter containing variable. */
- /* Name of variable. */
- /* Second part of variable name. */
- /* Information about what happened. */
+static char * tracevar(clientdata, interp, name1, name2, flags)
+ ClientData clientdata;
+ Tcl_Interp *interp; /* Interpreter containing variable. */
+ char *name1; /* Name of variable. */
+ char *name2; /* Second part of variable name. */
+ int flags; /* Information about what happened. */
{
Tcl_UntraceVar2(interp, name1, name2,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
diff --git a/otherlibs/labltk/support/cltkWait.c b/otherlibs/labltk/support/cltkWait.c
index a39e62519..f562ff6e6 100644
--- a/otherlibs/labltk/support/cltkWait.c
+++ b/otherlibs/labltk/support/cltkWait.c
@@ -1,18 +1,18 @@
-/*************************************************************************/
-/* */
-/* Objective Caml LablTk library */
-/* */
-/* Francois Rouaix, Francois Pessaux and Jun Furuse */
-/* projet Cristal, INRIA Rocquencourt */
-/* Jacques Garrigue, Kyoto University RIMS */
-/* */
-/* Copyright 1999 Institut National de Recherche en Informatique et */
-/* en Automatique and Kyoto University. All rights reserved. */
-/* This file is distributed under the terms of the GNU Library */
-/* General Public License, with the special exception on linking */
-/* described in file ../../../LICENSE. */
-/* */
-/*************************************************************************/
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
/* $Id$ */
@@ -44,8 +44,9 @@ struct WinCBData {
Tk_Window win;
};
-static void WaitVisibilityProc(ClientData clientData, XEvent *eventPtr)
- /* Information about event (not used). */
+static void WaitVisibilityProc(clientData, eventPtr)
+ ClientData clientData;
+ XEvent *eventPtr; /* Information about event (not used). */
{
struct WinCBData *vis = clientData;
value cbid = Val_int(vis->cbid);
diff --git a/otherlibs/labltk/support/fileevent.ml b/otherlibs/labltk/support/fileevent.ml
index 1db7b3a2e..9d985147c 100644
--- a/otherlibs/labltk/support/fileevent.ml
+++ b/otherlibs/labltk/support/fileevent.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -22,11 +22,11 @@ open Protocol
external add_file_input : file_descr -> cbid -> unit
= "camltk_add_file_input"
-external rem_file_input : file_descr -> unit
+external rem_file_input : file_descr -> cbid -> unit
= "camltk_rem_file_input"
external add_file_output : file_descr -> cbid -> unit
= "camltk_add_file_output"
-external rem_file_output : file_descr -> unit
+external rem_file_output : file_descr -> cbid -> unit
= "camltk_rem_file_output"
(* File input handlers *)
@@ -35,8 +35,8 @@ let fd_table = Hashtbl.create 37 (* Avoid space leak in callback table *)
let add_fileinput ~fd ~callback:f =
let id = new_function_id () in
- Hashtbl'.add callback_naming_table ~key:id ~data:(fun _ -> f());
- Hashtbl'.add fd_table ~key:(fd, 'r') ~data:id;
+ Hashtbl.add callback_naming_table id (fun _ -> f());
+ Hashtbl.add fd_table (fd, 'r') id;
if !Protocol.debug then begin
Protocol.prerr_cbid id; prerr_endline " for fileinput"
end;
@@ -52,14 +52,14 @@ let remove_fileinput ~fd =
Protocol.prerr_cbid id;
prerr_endline " for fileinput"
end;
- rem_file_input fd
+ rem_file_input fd id
with
Not_found -> ()
let add_fileoutput ~fd ~callback:f =
let id = new_function_id () in
- Hashtbl'.add callback_naming_table ~key:id ~data:(fun _ -> f());
- Hashtbl'.add fd_table ~key:(fd, 'w') ~data:id;
+ Hashtbl.add callback_naming_table id (fun _ -> f());
+ Hashtbl.add fd_table (fd, 'w') id;
if !Protocol.debug then begin
Protocol.prerr_cbid id; prerr_endline " for fileoutput"
end;
@@ -75,7 +75,7 @@ let remove_fileoutput ~fd =
Protocol.prerr_cbid id;
prerr_endline " for fileoutput"
end;
- rem_file_output fd
+ rem_file_output fd id
with
Not_found -> ()
diff --git a/otherlibs/labltk/support/fileevent.mli b/otherlibs/labltk/support/fileevent.mli
index 8b9af8833..34760f0c7 100644
--- a/otherlibs/labltk/support/fileevent.mli
+++ b/otherlibs/labltk/support/fileevent.mli
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/support/protocol.ml b/otherlibs/labltk/support/protocol.ml
index cb8bcbb33..e6c378504 100644
--- a/otherlibs/labltk/support/protocol.ml
+++ b/otherlibs/labltk/support/protocol.ml
@@ -1,22 +1,21 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
-open StdLabels
open Support
open Widget
@@ -30,7 +29,7 @@ type tkArgs =
type cbid = int
-external opentk : display:string -> clas:string -> unit
+external opentk_low : string list -> unit
= "camltk_opentk"
external tcl_eval : string -> string
= "camltk_tcl_eval"
@@ -44,6 +43,11 @@ external tkreturn : string -> unit
= "camltk_return"
external callback_init : unit -> unit
= "camltk_init"
+external finalizeTk : unit -> unit
+ = "camltk_finalize"
+ (* Finalize tcl/tk before exiting. This function will be automatically
+ called when you call [Pervasives.exit ()] (This is installed at
+ [install_cleanup ()] *)
let tcl_command s = ignore (tcl_eval s);;
@@ -60,10 +64,10 @@ let debug =
let dump_args args =
let rec print_arg = function
TkToken s -> prerr_string s; prerr_string " "
- | TkTokenList l -> List.iter ~f:print_arg l
+ | TkTokenList l -> List.iter print_arg l
| TkQuote a -> prerr_string "{"; print_arg a; prerr_string "} "
in
- Array.iter ~f:print_arg args;
+ Array.iter print_arg args;
prerr_newline()
(*
@@ -86,14 +90,15 @@ let tkCommand args = ignore (tkEval args)
* Callbacks
*)
+(* LablTk only *)
let cCAMLtoTKwidget w =
+ (* Widget.check_class w table; (* with subtyping, it is redundant *) *)
TkToken (Widget.name w)
let cTKtoCAMLwidget = function
"" -> raise (Invalid_argument "cTKtoCAMLwidget")
| s -> Widget.get_atom s
-
let callback_naming_table =
(Hashtbl.create 401 : (int, callback_buffer -> unit) Hashtbl.t)
@@ -110,9 +115,9 @@ let string_of_cbid = string_of_int
(* The callback should be cleared when w is destroyed *)
let register_callback w ~callback:f =
let id = new_function_id () in
- Hashtbl'.add callback_naming_table ~key:id ~data:f;
+ Hashtbl.add callback_naming_table id f;
if (forget_type w) <> (forget_type Widget.dummy) then
- Hashtbl'.add callback_memo_table ~key:(forget_type w) ~data:id;
+ Hashtbl.add callback_memo_table (forget_type w) id;
(string_of_cbid id)
let clear_callback id =
@@ -122,7 +127,7 @@ let clear_callback id =
let remove_callbacks w =
let w = forget_type w in
let cb_ids = Hashtbl.find_all callback_memo_table w in
- List.iter ~f:clear_callback cb_ids;
+ List.iter clear_callback cb_ids;
for i = 1 to List.length cb_ids do
Hashtbl.remove callback_memo_table w
done
@@ -143,13 +148,13 @@ let install_cleanup () =
let call_destroy_hooks = function
[wname] ->
let w = cTKtoCAMLwidget wname in
- List.iter ~f:(fun f -> f w) !destroy_hooks
+ List.iter (fun f -> f w) !destroy_hooks
| _ -> raise (TkError "bad cleanup callback") in
let fid = new_function_id () in
- Hashtbl'.add callback_naming_table ~key:fid ~data:call_destroy_hooks;
+ Hashtbl.add callback_naming_table fid call_destroy_hooks;
(* setup general destroy callback *)
- tcl_command ("bind all <Destroy> {camlcb " ^ (string_of_cbid fid) ^" %W}")
-
+ tcl_command ("bind all <Destroy> {camlcb " ^ (string_of_cbid fid) ^" %W}");
+ at_exit finalizeTk
let prerr_cbid id =
prerr_string "camlcb "; prerr_int id
@@ -158,7 +163,7 @@ let prerr_cbid id =
let dispatch_callback id args =
if !debug then begin
prerr_cbid id;
- List.iter ~f:(fun x -> prerr_string " "; prerr_string x) args;
+ List.iter (fun x -> prerr_string " "; prerr_string x) args;
prerr_newline()
end;
(Hashtbl.find callback_naming_table id) args;
@@ -166,11 +171,16 @@ let dispatch_callback id args =
let protected_dispatch id args =
try
- Printexc.print (dispatch_callback id) args
+ dispatch_callback id args
with
- Out_of_memory -> raise Out_of_memory
- | Sys.Break -> raise Sys.Break
- | e -> flush Pervasives.stderr
+ | e ->
+ try
+ Printf.eprintf "Uncaught exception: %s\n" (Printexc.to_string e);
+ flush stderr;
+ (* raise x *)
+ with
+ Out_of_memory -> raise Out_of_memory
+ | Sys.Break -> raise Sys.Break
let _ = Callback.register "camlcb" protected_dispatch
@@ -178,12 +188,76 @@ let _ = Callback.register "camlcb" protected_dispatch
let _ = callback_init ()
(* Different version of initialisation functions *)
-(* Native opentk is [opentk display class] *)
-let openTk ?(display = "") ?(clas = "LablTk") () =
- opentk ~display ~clas;
+let default_display_name = ref ""
+let default_display () = !default_display_name
+
+let camltk_argv = ref []
+
+(* options for Arg.parse *)
+let keywords = [
+ "-display", Arg.String (fun s ->
+ camltk_argv := "-display" :: s :: !camltk_argv),
+ "<disp> : X server to contact (CamlTk)";
+ "-colormap", Arg.String (fun s ->
+ camltk_argv := "-colormap" :: s :: !camltk_argv),
+ "<colormap> : colormap to use (CamlTk)";
+ "-geometry", Arg.String (fun s ->
+ camltk_argv := "-geometry" :: s :: !camltk_argv),
+ "<geom> : size and position (CamlTk)";
+ "-name", Arg.String (fun s ->
+ camltk_argv := "-name" :: s :: !camltk_argv),
+ "<name> : application class (CamlTk)";
+ "-sync", Arg.Unit (fun () ->
+ camltk_argv := "-sync" :: !camltk_argv),
+ ": sync mode (CamlTk)";
+ "-use", Arg.String (fun s ->
+ camltk_argv := "-use" :: s :: !camltk_argv),
+ "<id> : parent window id (CamlTk)";
+ "-window", Arg.String (fun s ->
+ camltk_argv := "-use" :: s :: !camltk_argv),
+ "<id> : parent window id (CamlTk)";
+ "-visual", Arg.String (fun s ->
+ camltk_argv := "-visual" :: s :: !camltk_argv),
+ "<visual> : visual to use (CamlTk)" ]
+
+let opentk_with_args argv (* = [argv1;..;argvn] *) =
+ (* argv must be command line for wish *)
+ let argv0 = Sys.argv.(0) in
+ let rec find_display = function
+ | "-display" :: s :: xs -> s
+ | "-colormap" :: s :: xs -> find_display xs
+ | "-geometry" :: s :: xs -> find_display xs
+ | "-name" :: s :: xs -> find_display xs
+ | "-sync" :: xs -> find_display xs
+ | "-use" :: s :: xs -> find_display xs
+ | "-window" :: s :: xs -> find_display xs
+ | "-visual" :: s :: xs -> find_display xs
+ | "--" :: _ -> ""
+ | _ :: xs -> find_display xs
+ | [] -> ""
+ in
+ default_display_name := find_display argv;
+ opentk_low (argv0 :: argv);
install_cleanup();
Widget.default_toplevel
+let opentk () =
+ let argv0 = Sys.argv.(0) in
+ Arg.parse keywords (fun _ -> ()) argv0;
+ opentk_with_args !camltk_argv
+
+let openTkClass s = opentk_with_args ["-name"; s]
+let openTkDisplayClass disp cl = opentk_with_args ["-display"; disp; "-name"; cl]
+
+(*JPF CAMLTK/LABLTK? *)
+let openTk ?(display = "") ?(clas = "LablTk") () =
+ let dispopt =
+ match display with
+ | "" -> []
+ | _ -> ["-display"; display]
+ in
+ opentk_with_args (dispopt @ ["-name"; clas])
+
(* Destroy all widgets, thus cleaning up table and exiting the loop *)
let closeTk () =
tcl_command "destroy ."
diff --git a/otherlibs/labltk/support/protocol.mli b/otherlibs/labltk/support/protocol.mli
index c816ba029..c7ce3eaba 100644
--- a/otherlibs/labltk/support/protocol.mli
+++ b/otherlibs/labltk/support/protocol.mli
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -39,18 +39,49 @@ val add_destroy_hook : (any widget -> unit) -> unit
(* Opening, closing, and mainloop *)
-val openTk : ?display:string -> ?clas:string -> unit -> toplevel widget
-val closeTk : unit -> unit
-val mainLoop : unit -> unit
+val default_display : unit -> string
+
+val opentk : unit -> toplevel widget
+ (* The basic initialization function. [opentk ()] parses automatically
+ the command line options and use the tk related options in them
+ such as "-display localhost:0" to initialize Tk applications.
+ Consult wish manpage about the supported options. *)
+
+val keywords : (string * Arg.spec * string) list
+ (* Command line parsing specification for Arg.parse, which contains
+ the standard Tcl/Tk command line options such as "-display" and "-name".
+ These Tk command line options are used by opentk *)
+
+val opentk_with_args : string list -> toplevel widget
+ (* [opentk_with_args argv] invokes [opentk] with the tk related
+ command line options given by [argv] to the executable program. *)
+
+val openTk : ?display:string -> ?clas:string -> unit -> toplevel widget
+ (* [openTk ~display:display ~clas:clas ()] is equivalent to
+ [opentk ["-display"; display; "-name"; clas]] *)
+
+(* Legacy opentk functions *)
+val openTkClass: string -> toplevel widget
+ (* [openTkClass class] is equivalent to [opentk ["-name"; class]] *)
+val openTkDisplayClass: string -> string -> toplevel widget
+ (* [openTkDisplayClass disp class] is equivalent to
+ [opentk ["-display"; disp; "-name"; class]] *)
+
+val closeTk : unit -> unit
+val finalizeTk : unit -> unit
+ (* Finalize tcl/tk before exiting. This function will be automatically
+ called when you call [Pervasives.exit ()] *)
+
+val mainLoop : unit -> unit
(* Direct evaluation of tcl code *)
-val tkEval : tkArgs array -> string
+val tkEval : tkArgs array -> string
-val tkCommand : tkArgs array -> unit
+val tkCommand : tkArgs array -> unit
(* Returning a value from a Tcl callback *)
-val tkreturn: string -> unit
+val tkreturn: string -> unit
(* Callbacks: this is private *)
diff --git a/otherlibs/labltk/support/rawwidget.ml b/otherlibs/labltk/support/rawwidget.ml
new file mode 100644
index 000000000..4ddf1a301
--- /dev/null
+++ b/otherlibs/labltk/support/rawwidget.ml
@@ -0,0 +1,176 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Support
+
+(*
+ * Widgets
+ *)
+
+exception IllegalWidgetType of string
+ (* Raised when widget command applied illegally*)
+
+(***************************************************)
+(* Widgets *)
+(* This 'a raw_widget will be 'a Widget.widget *)
+(***************************************************)
+type 'a raw_widget =
+ Untyped of string
+| Typed of string * string
+
+type raw_any (* will be Widget.any *)
+and button
+and canvas
+and checkbutton
+and entry
+and frame
+and label
+and listbox
+and menu
+and menubutton
+and message
+and radiobutton
+and scale
+and scrollbar
+and text
+and toplevel
+
+let forget_type w = (Obj.magic (w : 'a raw_widget) : raw_any raw_widget)
+let coe = forget_type
+
+(* table of widgets *)
+let table = (Hashtbl.create 401 : (string, raw_any raw_widget) Hashtbl.t)
+
+let name = function
+ Untyped s -> s
+ | Typed (s,_) -> s
+
+(* Normally all widgets are known *)
+(* this is a provision for send commands to external tk processes *)
+let known_class = function
+ Untyped _ -> "unknown"
+ | Typed (_,c) -> c
+
+(* This one is always created by opentk *)
+let default_toplevel =
+ let wname = "." in
+ let w = Typed (wname, "toplevel") in
+ Hashtbl.add table wname w;
+ w
+
+(* Dummy widget to which global callbacks are associated *)
+(* also passed around by camltotkoption when no widget in context *)
+let dummy =
+ Untyped "dummy"
+
+let remove w =
+ Hashtbl.remove table (name w)
+
+(* Retype widgets returned from Tk *)
+(* JPF report: sometime s is "", see Protocol.cTKtoCAMLwidget *)
+let get_atom s =
+ try
+ Hashtbl.find table s
+ with
+ Not_found -> Untyped s
+
+let naming_scheme = [
+ "button", "b";
+ "canvas", "ca";
+ "checkbutton", "cb";
+ "entry", "en";
+ "frame", "f";
+ "label", "l";
+ "listbox", "li";
+ "menu", "me";
+ "menubutton", "mb";
+ "message", "ms";
+ "radiobutton", "rb";
+ "scale", "sc";
+ "scrollbar", "sb";
+ "text", "t";
+ "toplevel", "top" ]
+
+
+let widget_any_table = List.map fst naming_scheme
+(* subtypes *)
+let widget_button_table = [ "button" ]
+and widget_canvas_table = [ "canvas" ]
+and widget_checkbutton_table = [ "checkbutton" ]
+and widget_entry_table = [ "entry" ]
+and widget_frame_table = [ "frame" ]
+and widget_label_table = [ "label" ]
+and widget_listbox_table = [ "listbox" ]
+and widget_menu_table = [ "menu" ]
+and widget_menubutton_table = [ "menubutton" ]
+and widget_message_table = [ "message" ]
+and widget_radiobutton_table = [ "radiobutton" ]
+and widget_scale_table = [ "scale" ]
+and widget_scrollbar_table = [ "scrollbar" ]
+and widget_text_table = [ "text" ]
+and widget_toplevel_table = [ "toplevel" ]
+
+let new_suffix clas n =
+ try
+ (List.assoc clas naming_scheme) ^ (string_of_int n)
+ with
+ Not_found -> "w" ^ (string_of_int n)
+
+(* The function called by generic creation *)
+let counter = ref 0
+let new_atom ~parent ?name:nom clas =
+ let parentpath = name parent in
+ let path =
+ match nom with
+ None ->
+ incr counter;
+ if parentpath = "."
+ then "." ^ (new_suffix clas !counter)
+ else parentpath ^ "." ^ (new_suffix clas !counter)
+ | Some name ->
+ if parentpath = "."
+ then "." ^ name
+ else parentpath ^ "." ^ name
+ in
+ let w = Typed(path,clas) in
+ Hashtbl.add table path w;
+ w
+
+(* Just create a path. Only to check existence of widgets *)
+(* Use with care *)
+let atom ~parent ~name:pathcomp =
+ let parentpath = name parent in
+ let path =
+ if parentpath = "."
+ then "." ^ pathcomp
+ else parentpath ^ "." ^ pathcomp in
+ Untyped path
+
+(* LablTk: Redundant with subtyping of Widget, backward compatibility *)
+let check_class w clas =
+ match w with
+ Untyped _ -> () (* assume run-time check by tk*)
+ | Typed(_,c) ->
+ if List.mem c clas then ()
+ else raise (IllegalWidgetType c)
+
+
+(* Checking membership of constructor in subtype table *)
+let chk_sub errname table c =
+ if List.mem c table then ()
+ else raise (Invalid_argument errname)
diff --git a/otherlibs/labltk/support/rawwidget.mli b/otherlibs/labltk/support/rawwidget.mli
new file mode 100644
index 000000000..7a7857dc7
--- /dev/null
+++ b/otherlibs/labltk/support/rawwidget.mli
@@ -0,0 +1,109 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Support for widget manipulations *)
+
+type 'a raw_widget
+ (* widget is an abstract type *)
+
+type raw_any
+and button
+and canvas
+and checkbutton
+and entry
+and frame
+and label
+and listbox
+and menu
+and menubutton
+and message
+and radiobutton
+and scale
+and scrollbar
+and text
+and toplevel
+
+val forget_type : 'a raw_widget -> raw_any raw_widget
+val coe : 'a raw_widget -> raw_any raw_widget
+
+val default_toplevel : toplevel raw_widget
+ (* [default_toplevel] is "." in Tk, the toplevel widget that is
+ always existing during a Tk session. Destroying [default_toplevel]
+ ends the main loop
+ *)
+
+val atom : parent: 'a raw_widget -> name: string -> raw_any raw_widget
+ (* [atom parent name] returns the widget [parent.name]. The widget is
+ not created. Only its name is returned. In a given parent, there may
+ only exist one children for a given name.
+ This function should only be used to check the existence of a widget
+ with a known name. It doesn't add the widget to the internal tables
+ of CamlTk.
+ *)
+
+val name : 'a raw_widget -> string
+ (* [name w] returns the name (tk "path") of a widget *)
+
+(*--*)
+(* The following functions are used internally.
+ There is normally no need for them in users programs
+ *)
+
+val known_class : 'a raw_widget -> string
+ (* [known_class w] returns the class of a widget (e.g. toplevel, frame),
+ as known by the CamlTk interface.
+ Not equivalent to "winfo w" in Tk.
+ *)
+
+val dummy : raw_any raw_widget
+ (* [dummy] is a widget used as context when we don't have any.
+ It is *not* a real widget.
+ *)
+
+val new_atom : parent:'a raw_widget -> ?name: string -> string -> 'b raw_widget
+
+val get_atom : string -> raw_any raw_widget
+ (* [get_atom path] returns the widget with Tk path [path] *)
+
+val remove : 'a raw_widget -> unit
+ (* [remove w] removes widget from the internal tables *)
+
+(* Subtypes tables *)
+val widget_any_table : string list
+val widget_button_table : string list
+val widget_canvas_table : string list
+val widget_checkbutton_table : string list
+val widget_entry_table : string list
+val widget_frame_table : string list
+val widget_label_table : string list
+val widget_listbox_table : string list
+val widget_menu_table : string list
+val widget_menubutton_table : string list
+val widget_message_table : string list
+val widget_radiobutton_table : string list
+val widget_scale_table : string list
+val widget_scrollbar_table : string list
+val widget_text_table : string list
+val widget_toplevel_table : string list
+
+val chk_sub : string -> 'a list -> 'a -> unit
+val check_class : 'a raw_widget -> string list -> unit
+ (* Widget subtyping *)
+
+exception IllegalWidgetType of string
+ (* Raised when widget command applied illegally*)
diff --git a/otherlibs/labltk/support/slave.ml b/otherlibs/labltk/support/slave.ml
index 8169f1f18..b994fe17e 100644
--- a/otherlibs/labltk/support/slave.ml
+++ b/otherlibs/labltk/support/slave.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/support/support.ml b/otherlibs/labltk/support/support.ml
index b0b028830..c8bebc2fc 100644
--- a/otherlibs/labltk/support/support.ml
+++ b/otherlibs/labltk/support/support.ml
@@ -1,23 +1,21 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
-open StdLabels
-
(* Parsing results of Tcl *)
(* List.split a string according to char_sep predicate *)
let split_str ~pred:char_sep str =
@@ -29,11 +27,11 @@ let split_str ~pred:char_sep str =
let rec split beg cur =
if cur >= len then
if beg = cur then []
- else [String.sub str ~pos:beg ~len:(len - beg)]
+ else [String.sub str beg (len - beg)]
else if char_sep str.[cur]
then
let nextw = skip_sep cur in
- (String.sub str ~pos:beg ~len:(cur - beg))
+ (String.sub str beg (cur - beg))
::(split nextw nextw)
else split beg (succ cur) in
let wstart = skip_sep 0 in
@@ -48,7 +46,3 @@ let maycons f x l =
match x with
Some x -> f x :: l
| None -> l
-
-(* Get some labels on Hashtbl.add *)
-module Hashtbl' =
- struct let add tbl ~key ~data = Hashtbl.add tbl key data end
diff --git a/otherlibs/labltk/support/support.mli b/otherlibs/labltk/support/support.mli
index 92a89ca8f..95a2255cb 100644
--- a/otherlibs/labltk/support/support.mli
+++ b/otherlibs/labltk/support/support.mli
@@ -1,23 +1,21 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
val split_str : pred:(char -> bool) -> string -> string list
val may : ('a -> 'b) -> 'a option -> 'b option
val maycons : ('a -> 'b) -> 'a option -> 'b list -> 'b list
-module Hashtbl' :
- sig val add : ('a, 'b) Hashtbl.t -> key:'a -> data:'b -> unit end
diff --git a/otherlibs/labltk/support/textvariable.ml b/otherlibs/labltk/support/textvariable.ml
index cb3f8c7f7..af272e682 100644
--- a/otherlibs/labltk/support/textvariable.ml
+++ b/otherlibs/labltk/support/textvariable.ml
@@ -1,22 +1,21 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
-open StdLabels
open Support
open Protocol
@@ -39,7 +38,7 @@ let add_handle var cbid =
r := cbid :: !r
with
Not_found ->
- Hashtbl'.add handles var (ref [cbid])
+ Hashtbl.add handles var (ref [cbid])
let exceptq x =
let rec ex acc = function
@@ -64,7 +63,7 @@ let rem_handle var cbid =
let rem_all_handles var =
try
let r = Hashtbl.find handles var in
- List.iter ~f:(internal_untracevar var) !r;
+ List.iter (internal_untracevar var) !r;
Hashtbl.remove handles var
with
Not_found -> ()
@@ -77,7 +76,7 @@ let handle vname ~callback:f =
clear_callback id;
rem_handle vname id;
f() in
- Hashtbl'.add callback_naming_table ~key:id ~data:wrapped;
+ Hashtbl.add callback_naming_table id wrapped;
add_handle vname id;
if !Protocol.debug then begin
prerr_cbid id; prerr_string " for variable "; prerr_endline vname
@@ -97,9 +96,9 @@ let add w v =
try Hashtbl.find memo w
with
Not_found ->
- let r = ref StringSet.empty in
- Hashtbl'.add memo ~key:w ~data:r;
- r in
+ let r = ref StringSet.empty in
+ Hashtbl.add memo w r;
+ r in
r := StringSet.add v !r
(* to be used with care ! *)
diff --git a/otherlibs/labltk/support/textvariable.mli b/otherlibs/labltk/support/textvariable.mli
index 900106e52..09a19148a 100644
--- a/otherlibs/labltk/support/textvariable.mli
+++ b/otherlibs/labltk/support/textvariable.mli
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/support/timer.ml b/otherlibs/labltk/support/timer.ml
index 96fd44474..1d15c1afd 100644
--- a/otherlibs/labltk/support/timer.ml
+++ b/otherlibs/labltk/support/timer.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
@@ -35,7 +35,7 @@ let add ~ms ~callback =
let wrapped _ =
clear_callback id; (* do it first in case f raises exception *)
callback() in
- Hashtbl'.add callback_naming_table ~key:id ~data:wrapped;
+ Hashtbl.add callback_naming_table id wrapped;
if !Protocol.debug then begin
prerr_cbid id; prerr_endline " for timer"
end;
diff --git a/otherlibs/labltk/support/timer.mli b/otherlibs/labltk/support/timer.mli
index 168d6d553..a45e1c9d2 100644
--- a/otherlibs/labltk/support/timer.mli
+++ b/otherlibs/labltk/support/timer.mli
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/support/tkwait.ml b/otherlibs/labltk/support/tkwait.ml
index 3d886c2ed..2574928c0 100644
--- a/otherlibs/labltk/support/tkwait.ml
+++ b/otherlibs/labltk/support/tkwait.ml
@@ -1,18 +1,18 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
diff --git a/otherlibs/labltk/support/widget.ml b/otherlibs/labltk/support/widget.ml
index b9379b146..65e0d26a9 100644
--- a/otherlibs/labltk/support/widget.ml
+++ b/otherlibs/labltk/support/widget.ml
@@ -1,179 +1,23 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
-open StdLabels
-open Support
-
-(*
- * Widgets
- *)
-
-exception IllegalWidgetType of string
- (* Raised when widget command applied illegally*)
-
-(***************************************************)
-(* Widgets *)
-(***************************************************)
-type 'a widget =
- Untyped of string
-| Typed of string * string
-
-type any
-and button
-and canvas
-and checkbutton
-and entry
-and frame
-and label
-and listbox
-and menu
-and menubutton
-and message
-and radiobutton
-and scale
-and scrollbar
-and text
-and toplevel
-
-let forget_type w = (Obj.magic (w : 'a widget) : any widget)
-let coe = forget_type
-
-(* table of widgets *)
-let table = (Hashtbl.create 401 : (string, any widget) Hashtbl.t)
-
-let name = function
- Untyped s -> s
- | Typed (s,_) -> s
-
-(* Normally all widgets are known *)
-(* this is a provision for send commands to external tk processes *)
-let known_class = function
- Untyped _ -> "unknown"
- | Typed (_,c) -> c
-
-(* This one is always created by opentk *)
-let default_toplevel =
- let wname = "." in
- let w = Typed (wname, "toplevel") in
- Hashtbl'.add table ~key:wname ~data:w;
- w
-
-(* Dummy widget to which global callbacks are associated *)
-(* also passed around by camltotkoption when no widget in context *)
-let dummy =
- Untyped "dummy"
-
-let remove w =
- Hashtbl.remove table (name w)
-
-(* Retype widgets returned from Tk *)
-(* JPF report: sometime s is "", see Protocol.cTKtoCAMLwidget *)
-let get_atom s =
- try
- Hashtbl.find table s
- with
- Not_found -> Untyped s
-
-let naming_scheme = [
- "button", "b";
- "canvas", "ca";
- "checkbutton", "cb";
- "entry", "en";
- "frame", "f";
- "label", "l";
- "listbox", "li";
- "menu", "me";
- "menubutton", "mb";
- "message", "ms";
- "radiobutton", "rb";
- "scale", "sc";
- "scrollbar", "sb";
- "text", "t";
- "toplevel", "top" ]
-
-
-let widget_any_table = List.map ~f:fst naming_scheme
-(* subtypes *)
-let widget_button_table = [ "button" ]
-and widget_canvas_table = [ "canvas" ]
-and widget_checkbutton_table = [ "checkbutton" ]
-and widget_entry_table = [ "entry" ]
-and widget_frame_table = [ "frame" ]
-and widget_label_table = [ "label" ]
-and widget_listbox_table = [ "listbox" ]
-and widget_menu_table = [ "menu" ]
-and widget_menubutton_table = [ "menubutton" ]
-and widget_message_table = [ "message" ]
-and widget_radiobutton_table = [ "radiobutton" ]
-and widget_scale_table = [ "scale" ]
-and widget_scrollbar_table = [ "scrollbar" ]
-and widget_text_table = [ "text" ]
-and widget_toplevel_table = [ "toplevel" ]
-
-let new_suffix clas n =
- try
- (List.assoc clas naming_scheme) ^ (string_of_int n)
- with
- Not_found -> "w" ^ (string_of_int n)
-
-
-(* The function called by generic creation *)
-let counter = ref 0
-let new_atom ~parent ?name:nom clas =
- let parentpath = name parent in
- let path =
- match nom with
- None ->
- incr counter;
- if parentpath = "."
- then "." ^ (new_suffix clas !counter)
- else parentpath ^ "." ^ (new_suffix clas !counter)
- | Some name ->
- if parentpath = "."
- then "." ^ (new_suffix clas !counter)
- else parentpath ^ "." ^ name
- in
- let w = Typed(path,clas) in
- Hashtbl'.add table ~key:path ~data:w;
- w
-
-(* Just create a path. Only to check existence of widgets *)
-(* Use with care *)
-let atom ~parent ~name:pathcomp =
- let parentpath = name parent in
- let path =
- if parentpath = "."
- then "." ^ pathcomp
- else parentpath ^ "." ^ pathcomp in
- Untyped path
-
-
-
-(* Redundant with subtyping of Widget, backward compatibility *)
-let check_class w clas =
- match w with
- Untyped _ -> () (* assume run-time check by tk*)
- | Typed(_,c) ->
- if List.mem c clas then ()
- else raise (IllegalWidgetType c)
-
-
-(* Checking membership of constructor in subtype table *)
-let chk_sub errname table c =
- if List.mem c table then ()
- else raise (Invalid_argument errname)
+(* Hack to permit having the different data type with the same name
+ [widget] for CamlTk and LablTk. *)
+include Rawwidget
+type 'a widget = 'a raw_widget
+type any = raw_any
diff --git a/otherlibs/labltk/support/widget.mli b/otherlibs/labltk/support/widget.mli
index 326fc6b04..fd3b461c2 100644
--- a/otherlibs/labltk/support/widget.mli
+++ b/otherlibs/labltk/support/widget.mli
@@ -1,27 +1,27 @@
-(*************************************************************************)
-(* *)
-(* Objective Caml LablTk library *)
-(* *)
-(* Francois Rouaix, Francois Pessaux and Jun Furuse *)
-(* projet Cristal, INRIA Rocquencourt *)
-(* Jacques Garrigue, Kyoto University RIMS *)
-(* *)
-(* Copyright 1999 Institut National de Recherche en Informatique et *)
-(* en Automatique and Kyoto University. All rights reserved. *)
-(* This file is distributed under the terms of the GNU Library *)
-(* General Public License, with the special exception on linking *)
-(* described in file ../../../LICENSE. *)
-(* *)
-(*************************************************************************)
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
(* $Id$ *)
(* Support for widget manipulations *)
-type 'a widget
+type 'a widget = 'a Rawwidget.raw_widget
(* widget is an abstract type *)
-type any
+type any = Rawwidget.raw_any
and button
and canvas
and checkbutton
diff --git a/otherlibs/labltk/tkanim/.depend b/otherlibs/labltk/tkanim/.depend
new file mode 100644
index 000000000..600934779
--- /dev/null
+++ b/otherlibs/labltk/tkanim/.depend
@@ -0,0 +1,2 @@
+tkanim.cmo: tkanim.cmi
+tkanim.cmx: tkanim.cmi
diff --git a/otherlibs/labltk/tkanim/Makefile b/otherlibs/labltk/tkanim/Makefile
new file mode 100644
index 000000000..288712a82
--- /dev/null
+++ b/otherlibs/labltk/tkanim/Makefile
@@ -0,0 +1,65 @@
+include ../support/Makefile.common
+
+COMPFLAGS=-I ../../../byterun -I ../support -I ../camltk -I ../../unix -ccopt "$(TK_DEFS)"
+
+all: tkanim.cma libtkanim.a
+opt: tkanim.cmxa libtkanim.a
+example: gifanimtest
+
+OBJS=tkanim.cmo
+COBJS= cltkaniminit.o tkAnimGIF.o
+
+tkanim.cma: $(OBJS)
+ $(MKLIB) -ocamlc '$(CAMLC)' -o tkanim -oc tkanim \
+ $(OBJS) $(TK_LINK) $(X11_LINK)
+
+tkanim.cmxa: $(OBJS:.cmo=.cmx)
+ $(MKLIB) -ocamlopt '$(CAMLOPT)' -o tkanim -oc tkanim \
+ $(OBJS:.cmo=.cmx) $(TK_LINK) $(X11_LINK)
+
+libtkanim.a: $(COBJS)
+ $(MKLIB) -o tkanim $(COBJS) $(TK_LINK) $(X11_LINK)
+
+gifanimtest: all gifanimtest.cmo
+ $(CAMLC) -o $@ -I ../lib -I ../support -dllpath ../support -dllpath . unix.cma $(LIBNAME).cma tkanim.cma gifanimtest.cmo
+
+animwish: $(TKANIM_LIB) tkAppInit.o
+ $(CC) -o $@ tkAppInit.o $(TK_LINK) $(X11_LINK) \
+ -L. -ltkanim $(LIBS)
+
+$(OBJS) $(OBJS:.cmo=.cmi): ../lib/$(LIBNAME).cma
+
+$(OBJS:.cmo=.cmx): ../lib/$(LIBNAME).cmxa
+
+clean:
+ rm -f *.cm* *.o *.a dlltkanim.so animwish gifanimtest
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo .mlp .cmx .c .o
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+.c.o:
+ $(CAMLCOMP) -c $(X_CFLAGS) $(COMPFLAGS) $(TCLTKINCLUDES) $<
+
+
+install: tkanim.cma
+ cp tkanim.cma *.cmi *.mli libtkanim.a $(INSTALLDIR)
+ if [ -f dlltkanim.so ]; then \
+ cp dlltkanim.so $(INSTALLDIR); \
+ fi
+
+installopt: tkanim.cmxa
+ cp tkanim.cmxa tkanim.a $(INSTALLDIR)
+
+depend: tkanim.ml
+ $(CAMLDEP) *.mli *.ml > .depend
+
+include .depend
diff --git a/otherlibs/labltk/tkanim/Makefile.nt b/otherlibs/labltk/tkanim/Makefile.nt
new file mode 100644
index 000000000..8f2291133
--- /dev/null
+++ b/otherlibs/labltk/tkanim/Makefile.nt
@@ -0,0 +1,76 @@
+!include ..\support\Makefile.common.nt
+
+CCFLAGS=-I..\support -I..\..\..\byterun $(TK_DEFS)
+
+COMPFLAGS=-I $(OTHERS)/win32unix -I ../support -I ../camltk
+
+all: tkanim.cma dlltkanim.dll libtkanim.lib
+opt: tkanim.cmxa libtkanim.lib
+example: gifanimtest.exe
+
+OBJS=tkanim.cmo
+COBJS= cltkaniminit.obj tkAnimGIF.obj
+
+tkanim.cma: $(OBJS)
+ $(CAMLLIBR) -o tkanim.cma $(OBJS) \
+ -dllib -ltkanim -cclib -ltkanim $(TK_LINK)
+
+tkanim.cmxa: $(OBJS:.cmo=.cmx)
+ $(CAMLOPTLIBR) -o tkanim.cmxa $(OBJS:.cmo=.cmx) \
+ -cclib -ltkanim $(TK_LINK)
+
+libtkanim.lib: $(COBJS:.obj=.sobj)
+ rm -f libtkanim.lib
+ $(MKLIB)libtkanim.lib $(COBJS:.obj=.sobj)
+
+dlltkanim.dll: $(COBJS:.obj=.dobj)
+ link /nologo /dll /out:dlltkanim.dll /implib:tmp.lib \
+ $(COBJS:.obj=.dobj) ..\support\dll$(LIBNAME).lib \
+ ..\..\..\byterun\ocamlrun.lib \
+ $(TK_LINK) wsock32.lib
+ rm tmp.*
+
+gifanimtest.exe: all gifanimtest.cmo
+ $(CAMLC) -custom -o $@ -I ../lib -I ../camltk -I ../support unix.cma $(LIBNAME).cma tkanim.cma gifanimtest.cmo
+
+# animwish: $(TKANIM_LIB) tkAppInit.o
+# $(CC) -o $@ tkAppInit.o $(TK_LINK) $(X11_LINK) \
+# -L. -ltkanim $(LIBS)
+
+clean:
+ rm -f *.cm* *.obj *.dobj *.sobj *.lib *.dll gifanimtest.exe
+
+$(OBJS) $(OBJS:.cmo=.cmi): ..\lib\$(LIBNAME).cma
+
+$(OBJS:.cmo=.cmx): ..\lib\$(LIBNAME).cmxa
+
+.SUFFIXES :
+.SUFFIXES : .mli .ml .cmi .cmo .mlp .cmx .c .dobj .sobj
+
+.mli.cmi:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmo:
+ $(CAMLCOMP) $(COMPFLAGS) $<
+
+.ml.cmx:
+ $(CAMLOPT) -c $(COMPFLAGS) $<
+
+.c.dobj:
+ $(BYTECC) $(DLLCCCOMPOPTS) $(CCFLAGS) -c $<
+ mv $*.obj $*.dobj
+
+.c.sobj:
+ $(BYTECC) $(BYTECCCOMPOPTS) $(CCFLAGS) -c $<
+ mv $*.obj $*.sobj
+
+install: tkanim.cma
+ cp tkanim.cma *.cmi *.mli libtkanim.lib dlltkanim.dll $(INSTALLDIR)
+
+installopt: tkanim.cmxa
+ cp tkanim.cmxa $(INSTALLDIR)
+
+depend: tkanim.ml
+ $(CAMLDEP) *.mli *.ml > .depend
+
+!include .depend
diff --git a/otherlibs/labltk/tkanim/README b/otherlibs/labltk/tkanim/README
new file mode 100644
index 000000000..175401f30
--- /dev/null
+++ b/otherlibs/labltk/tkanim/README
@@ -0,0 +1,5 @@
+This ML code is an interface for Tkanim Tcl/Tk extension. Unfortunately
+it is still test implementation. Look example directory for an example.
+
+The codes under this directory are mainly written by Jun Furuse
+(Jun.Furuse@inria.fr).
diff --git a/otherlibs/labltk/tkanim/cltkaniminit.c b/otherlibs/labltk/tkanim/cltkaniminit.c
new file mode 100644
index 000000000..773407f4f
--- /dev/null
+++ b/otherlibs/labltk/tkanim/cltkaniminit.c
@@ -0,0 +1,26 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
+#include <tk.h>
+#include <mlvalues.h>
+#include "camltk.h"
+
+value tkanim_init (rien) /* ML */
+ value rien;
+{
+ if (Tkanim_Init(cltclinterp) != TCL_OK)
+ tk_error ("Can't initialize TkAnim");
+ return Val_unit;
+}
diff --git a/otherlibs/labltk/tkanim/gifanimtest.ml b/otherlibs/labltk/tkanim/gifanimtest.ml
new file mode 100644
index 000000000..acd51c80b
--- /dev/null
+++ b/otherlibs/labltk/tkanim/gifanimtest.ml
@@ -0,0 +1,71 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+open Tkanim
+open Tk
+
+let main () =
+ let file = ref "" in
+ Arg.parse [] (fun s -> file := s)
+ "usage: gifanimtest file (animated gif)\n\
+ \tbutton 1 toggles the animation,\n\
+ \tbutton 2 displays the next frame,\n\
+ \tbutton 3 quits.";
+ let t = openTk () in
+
+ (* First of all, you must initialize the extension. *)
+ Tkanim.init ();
+
+ prerr_endline !file;
+
+ (* Then load the animated gif. *)
+ let anim = Tkanim.create !file in
+ prerr_endline "load done";
+
+ (* Check it is really animated or not. *)
+ match anim with
+ | Still x ->
+ (* Use whatever you want in CamlTk with this ImagePhoto. *)
+ prerr_endline "Sorry, it is not an animated GIF."
+
+ | Animated x ->
+ (* OK, let's animate it. *)
+ let l = Label.create t [] in
+ pack [l] [];
+
+ (* animate returns an interface function. *)
+ let f = animate l x in
+
+ (* Button1 toggles the animation *)
+ bind l [[], ButtonPressDetail 1] (BindSet ([], (fun _ ->
+ f false)));
+
+ (* Button2 displays the next frame. *)
+ bind l [[], ButtonPressDetail 2] (BindSet ([], (fun _ ->
+ f true)));
+
+ (* Button3 quits. *)
+ bind l [[], ButtonPressDetail 3] (BindSet ([], (fun _ ->
+ closeTk ())));
+
+ (* start the animation *)
+ f false;
+
+ (* Go to the main loop. *)
+ mainLoop ()
+
+let _ = Printexc.print main ()
diff --git a/otherlibs/labltk/tkanim/mmm.anim.gif b/otherlibs/labltk/tkanim/mmm.anim.gif
new file mode 100644
index 000000000..daeee00ee
--- /dev/null
+++ b/otherlibs/labltk/tkanim/mmm.anim.gif
Binary files differ
diff --git a/otherlibs/labltk/tkanim/tkAnimGIF.c b/otherlibs/labltk/tkanim/tkAnimGIF.c
new file mode 100644
index 000000000..a606fc40f
--- /dev/null
+++ b/otherlibs/labltk/tkanim/tkAnimGIF.c
@@ -0,0 +1,906 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
+#define TKANIM_VERSION "1.0"
+/* #define TKANIM_DEBUG */
+
+#include <tk.h>
+#include <string.h>
+
+/*
+ * The format record for the Animated GIF file format:
+ */
+
+static int FileMatchGIF _ANSI_ARGS_((FILE *f, char *fileName,
+ char *formatString, int *widthPtr, int *heightPtr));
+static int FileReadGIF _ANSI_ARGS_((Tcl_Interp *interp,
+ FILE *f, char *fileName, char *formatString));
+
+#define INTERLACE 0x40
+#define LOCALCOLORMAP 0x80
+#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
+#define MAXCOLORMAPSIZE 256
+#define CM_RED 0
+#define CM_GREEN 1
+#define CM_BLUE 2
+#define MAX_LWZ_BITS 12
+#define LM_to_uint(a,b) (((b)<<8)|(a))
+#define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
+
+/*
+ * Prototypes for local procedures defined in this file:
+ */
+
+static int DoExtension _ANSI_ARGS_((FILE *fd, int label,
+ int *transparent, int *delay, int *loop));
+static int GetCode _ANSI_ARGS_((FILE *fd, int code_size,
+ int flag));
+static int GetDataBlock _ANSI_ARGS_((FILE *fd,
+ unsigned char *buf));
+static int LWZReadByte _ANSI_ARGS_((FILE *fd, int flag,
+ int input_code_size));
+static int ReadColorMap _ANSI_ARGS_((FILE *fd, int number,
+ unsigned char buffer[3][MAXCOLORMAPSIZE]));
+static int ReadGIFHeader _ANSI_ARGS_((FILE *f, int *widthPtr,
+ int *heightPtr));
+static int ReadImage _ANSI_ARGS_((Tcl_Interp *interp,
+ char *imagePtr, FILE *fd, int len, int height,
+ unsigned char cmap[3][MAXCOLORMAPSIZE],
+ int interlace, int transparent));
+
+static int
+FileMatchGIF(f, fileName, formatString, widthPtr, heightPtr)
+ FILE *f; /* The image file, open for reading. */
+ char *fileName; /* The name of the image file. */
+ char *formatString; /* User-specified format string, or NULL. */
+ int *widthPtr, *heightPtr; /* The dimensions of the image are
+ * returned here if the file is a valid
+ * raw GIF file. */
+{
+ return ReadGIFHeader(f, widthPtr, heightPtr);
+}
+
+static int
+FileReadGIF(interp, f, fileName, formatString)
+ Tcl_Interp *interp; /* Interpreter to use for reporting errors. */
+ FILE *f; /* The image file, open for reading. */
+ char *fileName; /* The name of the image file. */
+ char *formatString; /* User-specified format string, or NULL. */
+{
+ int logicalWidth, logicalHeight;
+ int nBytes;
+ Tk_PhotoImageBlock block;
+ unsigned char buf[100];
+ int bitPixel;
+ unsigned int colorResolution;
+ unsigned int background;
+ unsigned int aspectRatio;
+ unsigned char localColorMap[3][MAXCOLORMAPSIZE];
+ unsigned char colorMap[3][MAXCOLORMAPSIZE];
+ int useGlobalColormap;
+ int transparent = -1;
+ int delay = 0;
+ Tk_Window winPtr;
+ int imageLeftPos, imageTopPos, imageWidth, imageHeight;
+ Tk_PhotoHandle photoHandle;
+
+ char widthbuf[32], heightbuf[32];
+ Tcl_DString resultbuf;
+
+ char newresbuf[640];
+ char *imageName;
+ char *resultptr;
+ int prevpos;
+ int loop = -1;
+
+ if((winPtr = Tk_MainWindow(interp)) == NULL){
+ return TCL_ERROR;
+ }
+
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\t\tHeader check...");
+#endif
+ if (!ReadGIFHeader(f, &logicalWidth, &logicalHeight)) {
+ Tcl_AppendResult(interp, "couldn't read GIF header from file \"",
+ fileName, "\"", NULL);
+ return TCL_ERROR;
+ }
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "done ");
+#endif
+ if ((logicalWidth <= 0) || (logicalHeight <= 0)) {
+ Tcl_AppendResult(interp, "GIF image file \"", fileName,
+ "\" has dimension(s) <= 0", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (fread(buf, 1, 3, f) != 3) {
+ return TCL_OK;
+ }
+ bitPixel = 2<<(buf[0]&0x07);
+ colorResolution = (((buf[0]&0x70)>>3)+1);
+ background = buf[1];
+ aspectRatio = buf[2];
+
+ if (BitSet(buf[0], LOCALCOLORMAP)) { /* Global Colormap */
+ if (!ReadColorMap(f, bitPixel, colorMap)) {
+ Tcl_AppendResult(interp, "error reading color map",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\t\tReading frames ");
+ prevpos = ftell(f);
+#endif
+ sprintf( widthbuf, "%d ", logicalWidth);
+ sprintf( heightbuf, "%d ", logicalHeight);
+
+ Tcl_DStringInit(&resultbuf);
+ Tcl_DStringAppend(&resultbuf, widthbuf, -1);
+ Tcl_DStringAppend(&resultbuf, " ", -1);
+ Tcl_DStringAppend(&resultbuf, heightbuf, -1);
+ Tcl_DStringAppend(&resultbuf, " ", -1);
+ Tcl_DStringAppend(&resultbuf, "{", -1);
+
+ while (1) {
+ if (fread(buf, 1, 1, f) != 1) {
+ /*
+ * Premature end of image. We should really notify
+ * the user, but for now just show garbage.
+ */
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "Premature end of image");
+#endif
+
+ break;
+ }
+
+ if (buf[0] == ';') {
+ /*
+ * GIF terminator.
+ */
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, ";");
+ prevpos = ftell(f);
+#endif
+
+ break;
+ }
+
+ if (buf[0] == '!') {
+ /*
+ * This is a GIF extension.
+ */
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "!");
+ prevpos = ftell(f);
+#endif
+
+ if (fread(buf, 1, 1, f) != 1) {
+ Tcl_AppendResult( interp,
+ "error reading extension function code in GIF image", NULL );
+/*
+ interp->result =
+ "error reading extension function code in GIF image";
+*/
+ goto error;
+ }
+ if (DoExtension(f, buf[0], &transparent, &delay, &loop) < 0) {
+ Tcl_AppendResult( interp,
+ "error reading extension in GIF image", NULL );
+/*
+ interp->result = "error reading extension in GIF image";
+*/ goto error;
+ }
+ continue;
+ }
+
+ if (buf[0] == '\0') {
+ /*
+ * Not a valid start character; ignore it.
+ */
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "0", buf[0]);
+ prevpos = ftell(f);
+#endif
+ continue;
+ }
+
+ if (buf[0] != ',') {
+ /*
+ * Not a valid start character; ignore it.
+ */
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "?(%c)", buf[0]);
+ prevpos = ftell(f);
+#endif
+ continue;
+ }
+
+ if (fread(buf, 1, 9, f) != 9) {
+ Tcl_AppendResult( interp,
+ "couldn't read left/top/width/height in GIF image", NULL );
+/*
+ interp->result = "couldn't read left/top/width/height in GIF image";
+*/
+ goto error;
+ }
+
+ useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
+
+ bitPixel = 1<<((buf[8]&0x07)+1);
+
+ imageLeftPos= LM_to_uint(buf[0], buf[1]);
+ imageTopPos= LM_to_uint(buf[2], buf[3]);
+ imageWidth= LM_to_uint(buf[4], buf[5]);
+ imageHeight= LM_to_uint(buf[6], buf[7]);
+
+ block.width = imageWidth;
+ block.height = imageHeight;
+ block.pixelSize = 3;
+ block.pitch = 3 * imageWidth;
+ block.offset[0] = 0;
+ block.offset[1] = 1;
+ block.offset[2] = 2;
+ block.offset[3] = 3;
+ nBytes = imageHeight * block.pitch;
+ block.pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
+
+ sprintf(widthbuf, "%d", imageWidth);
+ sprintf(heightbuf, "%d", imageHeight);
+
+ /* save result */
+
+ {
+#if (TK_MAJOR_VERSION >= 8 && TK_MINOR_VERSION >= 1)
+ Tcl_Obj *argv[7];
+ int i;
+
+ argv[0] = Tcl_NewStringObj("image", -1);
+ argv[1] = Tcl_NewStringObj("create", -1);
+ argv[2] = Tcl_NewStringObj("photo", -1);
+ argv[3] = Tcl_NewStringObj("-width", -1);
+ argv[4] = Tcl_NewStringObj(widthbuf, -1);
+ argv[5] = Tcl_NewStringObj("-height", -1);
+ argv[6] = Tcl_NewStringObj(heightbuf, -1);
+
+ for(i=0; i<7; i++){ Tcl_IncrRefCount(argv[i]); }
+
+ if( Tk_ImageObjCmd((ClientData) winPtr, interp,
+ /* "image create photo -width <imageWidth>
+ -height <imageHeight>" */
+ 7, argv) == TCL_ERROR ){
+ return TCL_ERROR;
+ }
+
+ for(i=0; i<7; i++){ Tcl_DecrRefCount(argv[i]); }
+
+#else
+ char *argv[7] = {"image", "create", "photo", "-width", widthbuf,
+ "-height", heightbuf};
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\t\timage creation (%s %s %s %s %s %s %s)",
+ argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+#endif
+ if( Tk_ImageCmd((ClientData) winPtr, interp,
+ /* "image create photo -width <imageWidth>
+ -height <imageHeight>" */
+ 7, argv) == TCL_ERROR ){
+ return TCL_ERROR;
+ }
+#endif
+
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, " done ");
+#endif
+ }
+
+ imageName = interp->result;
+#if (TK_MAJOR_VERSION < 8)
+ photoHandle = Tk_FindPhoto(interp->result);
+#else
+ photoHandle = Tk_FindPhoto(interp, interp->result);
+#endif
+ if (!useGlobalColormap) {
+ if (!ReadColorMap(f, bitPixel, localColorMap)) {
+ Tcl_AppendResult(interp, "error reading color map",
+ (char *) NULL);
+ goto error;
+ }
+ if (ReadImage(interp, (char *) block.pixelPtr, f, imageWidth,
+ imageHeight, localColorMap, BitSet(buf[8], INTERLACE),
+ transparent) != TCL_OK) {
+ goto error;
+ }
+ } else {
+ if (ReadImage(interp, (char *) block.pixelPtr, f, imageWidth,
+ imageHeight, colorMap, BitSet(buf[8], INTERLACE),
+ transparent) != TCL_OK) {
+ goto error;
+ }
+ }
+ Tk_PhotoPutBlock(photoHandle, &block, 0, 0,
+ imageWidth, imageHeight);
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, " Retrieving result\n");
+#endif
+ /* retrieve result */
+ sprintf(newresbuf, "{%s %d %d %d %d %d} ",
+ imageName, imageWidth, imageHeight, imageLeftPos, imageTopPos,
+ delay);
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, " newresbuf = %s\n", newresbuf);
+#endif
+ ckfree((char *) block.pixelPtr);
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, " free done (now append result)");
+#endif
+ Tcl_DStringAppend( &resultbuf, newresbuf, -1 );
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\t\tFrame done (%d)", ftell(f) - prevpos);
+ prevpos = ftell(f);
+#endif
+ }
+ sprintf( widthbuf, "%d", loop );
+ Tcl_DStringAppend( &resultbuf, "} ", -1 );
+ resultptr = Tcl_DStringAppend( &resultbuf, widthbuf, -1 );
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\nResult = %s\n", resultptr);
+#endif
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, resultptr, NULL);
+ Tcl_DStringFree(&resultbuf);
+ return TCL_OK;
+
+ error:
+ Tcl_DStringFree(&resultbuf);
+ ckfree((char *) block.pixelPtr);
+ return TCL_ERROR;
+
+}
+
+static int
+DoExtension(fd, label, transparent, delay, loop)
+FILE *fd;
+int label;
+int *transparent;
+int *delay;
+int *loop;
+{
+ static unsigned char buf[256];
+ int count = 0;
+
+ switch (label) {
+ case 0x01: /* Plain Text Extension */
+ break;
+
+ case 0xff: /* Application Extension */
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ if( count < 0){
+ return 1;
+ }
+ if( !strncmp (buf, "NETSCAPE", 8) ) {
+ /* we ignore check of "2.0" */
+ count = GetDataBlock (fd, (unsigned char*) buf);
+ if( count < 0){
+ return 1;
+ }
+ if( buf[0] != 1 ){
+ fprintf(stderr, "??? %d", buf[0]);
+ }
+ *loop = LM_to_uint(buf[1], buf[2]);
+ }
+ do {
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ } while (count > 0);
+ return count;
+ break;
+
+ case 0xfe: /* Comment Extension */
+ do {
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ } while (count > 0);
+ return count;
+
+ case 0xf9: /* Graphic Control Extension */
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ if (count < 0) {
+ return 1;
+ }
+ if ((buf[0] & 0x1) != 0) {
+ *transparent = buf[3];
+ }
+
+ /* Delay time */
+ *delay = LM_to_uint(buf[1],buf[2]);
+
+ do {
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ } while (count > 0);
+ return count;
+ }
+
+ do {
+ count = GetDataBlock(fd, (unsigned char*) buf);
+ } while (count > 0);
+ return count;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReadGIFHeader --
+ *
+ * This procedure reads the GIF header from the beginning of a
+ * GIF file and returns the dimensions of the image.
+ *
+ * Results:
+ * The return value is 1 if file "f" appears to start with
+ * a valid GIF header, 0 otherwise. If the header is valid,
+ * then *widthPtr and *heightPtr are modified to hold the
+ * dimensions of the image.
+ *
+ * Side effects:
+ * The access position in f advances.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReadGIFHeader(f, widthPtr, heightPtr)
+ FILE *f; /* Image file to read the header from */
+ int *widthPtr, *heightPtr; /* The dimensions of the image are
+ * returned here. */
+{
+ unsigned char buf[7];
+
+ if ((fread(buf, 1, 6, f) != 6)
+ || ((strncmp("GIF87a", (char *) buf, 6) != 0)
+ && (strncmp("GIF89a", (char *) buf, 6) != 0))) {
+ return 0;
+ }
+
+ if (fread(buf, 1, 4, f) != 4) {
+ return 0;
+ }
+
+ *widthPtr = LM_to_uint(buf[0],buf[1]);
+ *heightPtr = LM_to_uint(buf[2],buf[3]);
+ return 1;
+}
+
+/*
+ *-----------------------------------------------------------------
+ * The code below is copied from the giftoppm program and modified
+ * just slightly.
+ *-----------------------------------------------------------------
+ */
+
+static int
+ReadColorMap(fd,number,buffer)
+FILE *fd;
+int number;
+unsigned char buffer[3][MAXCOLORMAPSIZE];
+{
+ int i;
+ unsigned char rgb[3];
+
+ for (i = 0; i < number; ++i) {
+ if (! ReadOK(fd, rgb, sizeof(rgb)))
+ return 0;
+
+ buffer[CM_RED][i] = rgb[0] ;
+ buffer[CM_GREEN][i] = rgb[1] ;
+ buffer[CM_BLUE][i] = rgb[2] ;
+ }
+ return 1;
+}
+
+
+
+static int ZeroDataBlock = 0;
+
+static int
+GetDataBlock(fd, buf)
+FILE *fd;
+unsigned char *buf;
+{
+ unsigned char count;
+
+ if (! ReadOK(fd,&count,1)) {
+ return -1;
+ }
+
+ ZeroDataBlock = count == 0;
+
+ if ((count != 0) && (! ReadOK(fd, buf, count))) {
+ return -1;
+ }
+
+ return count;
+}
+
+
+static int
+ReadImage(interp, imagePtr, fd, len, height, cmap, interlace, transparent)
+Tcl_Interp *interp;
+char *imagePtr;
+FILE *fd;
+int len, height;
+unsigned char cmap[3][MAXCOLORMAPSIZE];
+int interlace;
+int transparent;
+{
+ unsigned char c;
+ int v;
+ int xpos = 0, ypos = 0, pass = 0;
+ char *colStr;
+
+
+ /*
+ * Initialize the Compression routines
+ */
+ if (! ReadOK(fd,&c,1)) {
+ Tcl_AppendResult(interp, "error reading GIF image: ",
+ Tcl_PosixError(interp), (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if (LWZReadByte(fd, 1, c) < 0) {
+ interp->result = "format error in GIF image";
+ return TCL_ERROR;
+ }
+
+ if (transparent!=-1 &&
+ (colStr = Tcl_GetVar(interp, "TRANSPARENT_GIF_COLOR", 0L))) {
+ XColor *colorPtr;
+ colorPtr = Tk_GetColor(interp, Tk_MainWindow(interp),
+ Tk_GetUid(colStr));
+ if (colorPtr) {
+/*
+ printf("color is %d %d %d\n",
+ colorPtr->red >> 8,
+ colorPtr->green >> 8,
+ colorPtr->blue >> 8);
+*/
+ cmap[CM_RED][transparent] = colorPtr->red >> 8;
+ cmap[CM_GREEN][transparent] = colorPtr->green >> 8;
+ cmap[CM_BLUE][transparent] = colorPtr->blue >> 8;
+ Tk_FreeColor(colorPtr);
+ }
+ }
+
+ while ((v = LWZReadByte(fd,0,c)) >= 0 ) {
+
+ imagePtr[ (xpos*3) + (ypos *len*3)] = cmap[CM_RED][v];
+ imagePtr[ (xpos*3) + (ypos *len*3) +1] = cmap[CM_GREEN][v];
+ imagePtr[ (xpos*3) + (ypos *len*3) +2] = cmap[CM_BLUE][v];
+
+ ++xpos;
+ if (xpos == len) {
+ xpos = 0;
+ if (interlace) {
+ switch (pass) {
+ case 0:
+ case 1:
+ ypos += 8; break;
+ case 2:
+ ypos += 4; break;
+ case 3:
+ ypos += 2; break;
+ }
+
+ if (ypos >= height) {
+ ++pass;
+ switch (pass) {
+ case 1:
+ ypos = 4; break;
+ case 2:
+ ypos = 2; break;
+ case 3:
+ ypos = 1; break;
+ default:
+ return TCL_OK;
+ }
+ }
+ } else {
+ ++ypos;
+ }
+ }
+ if (ypos >= height)
+ break;
+ }
+ return TCL_OK;
+}
+
+static int
+LWZReadByte(fd, flag, input_code_size)
+FILE *fd;
+int flag;
+int input_code_size;
+{
+ static int fresh = 0;
+ int code, incode;
+ static int code_size, set_code_size;
+ static int max_code, max_code_size;
+ static int firstcode, oldcode;
+ static int clear_code, end_code;
+ static int table[2][(1<< MAX_LWZ_BITS)];
+ static int stack[(1<<(MAX_LWZ_BITS))*2], *sp;
+ register int i;
+
+
+ if (flag) {
+
+ set_code_size = input_code_size;
+ code_size = set_code_size+1;
+ clear_code = 1 << set_code_size ;
+ end_code = clear_code + 1;
+ max_code_size = 2*clear_code;
+ max_code = clear_code+2;
+
+ GetCode(fd, 0, 1);
+
+ fresh = 1;
+
+ for (i = 0; i < clear_code; ++i) {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+ for (; i < (1<<MAX_LWZ_BITS); ++i) {
+ table[0][i] = table[1][0] = 0;
+ }
+
+ sp = stack;
+
+ return 0;
+
+ } else if (fresh) {
+
+ fresh = 0;
+ do {
+ firstcode = oldcode = GetCode(fd, code_size, 0);
+ } while (firstcode == clear_code);
+ return firstcode;
+ }
+
+ if (sp > stack)
+ return *--sp;
+
+ while ((code = GetCode(fd, code_size, 0)) >= 0) {
+ if (code == clear_code) {
+ for (i = 0; i < clear_code; ++i) {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+
+ for (; i < (1<<MAX_LWZ_BITS); ++i) {
+ table[0][i] = table[1][i] = 0;
+ }
+
+ code_size = set_code_size+1;
+ max_code_size = 2*clear_code;
+ max_code = clear_code+2;
+ sp = stack;
+ firstcode = oldcode = GetCode(fd, code_size, 0);
+ return firstcode;
+
+ } else if (code == end_code) {
+ int count;
+ unsigned char buf[260];
+
+ if (ZeroDataBlock)
+ return -2;
+
+ while ((count = GetDataBlock(fd, buf)) > 0)
+ ;
+
+ if (count != 0)
+ return -2;
+ }
+
+ incode = code;
+
+ if (code >= max_code) {
+ *sp++ = firstcode;
+ code = oldcode;
+ }
+
+ while (code >= clear_code) {
+ *sp++ = table[1][code];
+ if (code == table[0][code]) {
+ return -2;
+
+ fprintf(stderr, "circular table entry BIG ERROR\n");
+ /*
+ * Used to be this instead, Steve Ball suggested
+ * the change to just return.
+
+ printf("circular table entry BIG ERROR\n");
+ */
+ }
+ code = table[0][code];
+ }
+
+ *sp++ = firstcode = table[1][code];
+
+ if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
+
+ table[0][code] = oldcode;
+ table[1][code] = firstcode;
+ ++max_code;
+ if ((max_code>=max_code_size) && (max_code_size < (1<<MAX_LWZ_BITS))) {
+ max_code_size *= 2;
+ ++code_size;
+ }
+ }
+
+ oldcode = incode;
+
+ if (sp > stack)
+ return *--sp;
+ }
+ return code;
+}
+
+
+static int
+GetCode(fd, code_size, flag)
+FILE *fd;
+int code_size;
+int flag;
+{
+ static unsigned char buf[280];
+ static int curbit, lastbit, done, last_byte;
+ int i, j, ret;
+ unsigned char count;
+
+ if (flag) {
+ curbit = 0;
+ lastbit = 0;
+ done = 0;
+ return 0;
+ }
+
+
+ if ( (curbit+code_size) >= lastbit) {
+ if (done) {
+ /* ran off the end of my bits */
+ return -1;
+ }
+ buf[0] = buf[last_byte-2];
+ buf[1] = buf[last_byte-1];
+
+ if ((count = GetDataBlock(fd, &buf[2])) == 0)
+ done = 1;
+
+ last_byte = 2 + count;
+ curbit = (curbit - lastbit) + 16;
+ lastbit = (2+count)*8 ;
+ }
+
+ ret = 0;
+ for (i = curbit, j = 0; j < code_size; ++i, ++j)
+ ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+
+
+ curbit += code_size;
+
+ return ret;
+}
+
+int Tk_AnimationCmd(clientData, interp, argc, argv)
+ ClientData clientData; /* Main window associated with interpreter. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int argc; /* Number of arguments. */
+ char **argv; /* Argument strings. */
+{
+ char c;
+ int length;
+
+ if (argc < 2) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " option ?arg arg ...?\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ c = argv[1][0];
+ length = strlen(argv[1]);
+ if((c == 'c') && (length >= 2)
+ && (strncmp(argv[1], "create", length) == 0)) {
+
+ char * realFileName;
+ Tcl_DString buffer;
+ FILE *f;
+
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "AnimationCmd => create ");
+#endif
+
+ if ( argc != 3 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " create GifFile\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\tRealFileName = ");
+#endif
+ realFileName = Tcl_TranslateFileName(interp, argv[2],
+ &buffer);
+ if(realFileName == NULL) {
+ Tcl_DStringFree(&buffer);
+ return TCL_ERROR;
+ }
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "%s ", realFileName);
+#endif
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\tOpen ", realFileName);
+#endif
+ f = fopen(realFileName, "rb");
+ Tcl_DStringFree(&buffer);
+ if (f == NULL ){
+ Tcl_AppendResult(interp, "couldn't read image file \"",
+ argv[2], "\": ", Tcl_PosixError(interp),
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "success ", realFileName);
+#endif
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\tRead ", realFileName);
+#endif
+ if( FileReadGIF(interp, f, argv[2], "gif") != TCL_OK ){
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\tRead failed", realFileName);
+#endif
+ return TCL_ERROR;
+ }
+ fclose(f);
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "\n\tRead done", realFileName);
+#endif
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "done\n");
+#endif
+ }
+ return TCL_OK;
+}
+
+void
+TkDeleteTkAnim(clientData)
+ ClientData clientData;
+{
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "TkDeleteTkAnim\n");
+#endif
+}
+
+int Tkanim_Init(interp)
+ Tcl_Interp *interp;
+{
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "Tkanim initialize...");
+#endif
+ Tcl_CreateCommand(interp, "animation", Tk_AnimationCmd,
+ (ClientData) NULL,
+ (Tcl_CmdDeleteProc *) TkDeleteTkAnim);
+#ifdef TKANIM_DEBUG
+ fprintf(stderr, "done\n");
+#endif
+ return Tcl_PkgProvide(interp, "Tkanim", TKANIM_VERSION );
+}
diff --git a/otherlibs/labltk/tkanim/tkAppInit.c b/otherlibs/labltk/tkanim/tkAppInit.c
new file mode 100644
index 000000000..932a37fc1
--- /dev/null
+++ b/otherlibs/labltk/tkanim/tkAppInit.c
@@ -0,0 +1,141 @@
+/***********************************************************************/
+/* */
+/* MLTk, Tcl/Tk interface of Objective Caml */
+/* */
+/* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis */
+/* projet Cristal, INRIA Rocquencourt */
+/* Jacques Garrigue, Kyoto University RIMS */
+/* */
+/* Copyright 2002 Institut National de Recherche en Informatique et */
+/* en Automatique and Kyoto University. All rights reserved. */
+/* This file is distributed under the terms of the GNU Library */
+/* General Public License, with the special exception on linking */
+/* described in file LICENSE found in the Objective Caml source tree. */
+/* */
+/***********************************************************************/
+/*
+ * tkAppInit.c --
+ *
+ * Provides a default version of the Tcl_AppInit procedure for
+ * use in wish and similar Tk-based applications.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#) tkAppInit.c 1.19 95/12/23 17:09:24";
+#endif /* not lint */
+
+#include "tk.h"
+
+int Tkanimation_Init _ANSI_ARGS_ ((Tcl_Interp *interp));
+
+/*
+ * The following variable is a special hack that is needed in order for
+ * Sun shared libraries to be used for Tcl.
+ */
+
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
+#ifdef TK_TEST
+EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif /* TK_TEST */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * This is the main program for the application.
+ *
+ * Results:
+ * None: Tk_Main never returns here, so this procedure never
+ * returns either.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(argc, argv)
+ int argc; /* Number of command-line arguments. */
+ char **argv; /* Values of command-line arguments. */
+{
+ Tk_Main(argc, argv, Tcl_AppInit);
+ return 0; /* Needed only to prevent compiler warning. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
+ *
+ * Results:
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in interp->result if an error occurs.
+ *
+ * Side effects:
+ * Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppInit(interp)
+ Tcl_Interp *interp; /* Interpreter for application. */
+{
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ if (Tk_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
+#ifdef TK_TEST
+ if (Tktest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+#endif /* TK_TEST */
+
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) {
+ * return TCL_ERROR;
+ * }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ if (Tkanim_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is deleted
+ * then no user-specific startup file will be run under any conditions.
+ */
+
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.tkanimationrc", TCL_GLOBAL_ONLY);
+ return TCL_OK;
+}
diff --git a/otherlibs/labltk/tkanim/tkanim.ml b/otherlibs/labltk/tkanim/tkanim.ml
new file mode 100644
index 000000000..cc859e1cf
--- /dev/null
+++ b/otherlibs/labltk/tkanim/tkanim.ml
@@ -0,0 +1,230 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+open Support
+open Protocol
+open Tkintf
+
+external init : unit -> unit = "tkanim_init"
+
+type gifFrame = {
+ imagephoto : imagePhoto;
+ frameWidth : int;
+ frameHeight : int;
+ left : int;
+ top : int;
+ delay : int
+ }
+
+type animatedGif = {
+ frames : gifFrame list;
+ animWidth : int;
+ animHeight : int;
+ loop : int
+}
+
+type imageType =
+ | Still of Tk.options
+ | Animated of animatedGif
+
+let debug = ref false
+
+let cTKtoCAMLgifFrame s =
+ match splitlist s with
+ | [photo; width; height; left; top; delay] ->
+ {imagephoto = cTKtoCAMLimagePhoto photo;
+ frameWidth = int_of_string width;
+ frameHeight = int_of_string height;
+ left = int_of_string left;
+ top = int_of_string top;
+ delay = int_of_string delay}
+ | _ -> raise (Invalid_argument ("cTKtoCAMLgifFrame: " ^ s))
+
+let cTKtoCAMLanimatedGif s =
+ match splitlist s with
+ | [width; height; frames; loop] ->
+ {frames = List.map cTKtoCAMLgifFrame (splitlist frames);
+ animWidth = int_of_string width;
+ animHeight = int_of_string height;
+ loop = int_of_string loop}
+ | _ -> raise (Invalid_argument ("cTKtoCAMLgifFrame: " ^ s))
+
+(* check Tkanim package is in the interpreter *)
+let available () =
+ let packages =
+ splitlist (Protocol.tkEval [| TkToken "package";
+ TkToken "names" |])
+ in
+ List.mem "Tkanim" packages
+
+let create file =
+ let s =
+ Protocol.tkEval [| TkToken "animation";
+ TkToken "create";
+ TkToken file |]
+ in
+ let anmgif = cTKtoCAMLanimatedGif s in
+ match anmgif.frames with
+ | [] -> raise (TkError "Null frame in a gif ?")
+ | [x] -> Still (ImagePhoto x.imagephoto)
+ | _ -> Animated anmgif
+
+let delete anim =
+ List.iter (fun {imagephoto = i} -> Imagephoto.delete i) anim.frames
+
+let width anm = anm.animWidth
+let height anm = anm.animHeight
+let images anm = List.map (fun x -> x.imagephoto) anm.frames
+
+let image_existence_check img =
+ (* I found there is a bug in Tk (even v8.0a2). *)
+ (* We can copy from deleted images, Tk never says "it doesn't exist", *)
+ (* But just do some operation. And sometimes it causes Seg-fault. *)
+ (* So, before using Imagephoto.copy, I should check the source image *)
+ (* really exists. *)
+ try ignore (Imagephoto.height img) with
+ TkError s -> prerr_endline ("tkanim: " ^ s); raise (TkError s)
+
+let imagephoto_copy dst src opts =
+ image_existence_check src;
+ Imagephoto.copy dst src opts
+
+let animate_gen w i anim =
+ let length = List.length anim.frames in
+ let frames = Array.of_list anim.frames in
+ let current = ref 0 in
+ let loop = ref anim.loop in
+ let f = frames.(!current) in
+ imagephoto_copy i f.imagephoto
+ [ImgTo (f.left, f.top, f.left + f.frameWidth,
+ f.top + f.frameHeight)];
+ let visible = ref true in
+ let animated = ref false in
+ let timer = ref None in
+ (* Loop *)
+ let display_current () =
+ let f = frames.(!current) in
+ imagephoto_copy i f.imagephoto
+ [ImgTo (f.left, f.top,
+ f.left + f.frameWidth, f.top + f.frameHeight)]
+ in
+ let rec tick () =
+ if not (Winfo.exists w && Winfo.viewable w) then begin
+ (* the widget is invisible. stop animation for efficiency *)
+ if !debug then prerr_endline "Stopped (Visibility)";
+ visible := false;
+ end else
+ begin
+ display_current ();
+ let t =
+ Timer.add (if f.delay = 0 then 100 else f.delay * 10)
+ (fun () ->
+ incr current;
+ if !current = length then begin
+ current := 0;
+ (* loop check *)
+ if !loop > 1 then begin
+ decr loop;
+ if !loop = 0 then begin
+ if !debug then prerr_endline "Loop end";
+ (* stop *)
+ loop := anim.loop;
+ timer := None
+ end
+ end
+ end;
+ tick ())
+ in
+ timer := Some t
+ end
+ in
+ let start () =
+ animated := true;
+ tick ()
+ in
+ let stop () =
+ match !timer with
+ | Some t ->
+ Timer.remove t;
+ timer := None;
+ animated := false
+ | None -> ()
+ in
+ let next () =
+ if !timer = None then begin
+ incr current;
+ if !current = length then current := 0;
+ display_current ()
+ end
+ in
+ (* We shouldn't delete the animation here. *)
+(*
+ bind w [[], Destroy]
+ (BindSet ([], (fun _ -> Imagephoto.delete i)));
+*)
+ bind w [[], Visibility]
+ (BindSet ([], (fun _ ->
+ if not !visible then begin
+ visible := true;
+ if !animated then start ()
+ end)));
+ (function
+ | false ->
+ if !animated then stop () else start ()
+ | true -> next ())
+
+let animate label anim =
+ (* prerr_endline "animate"; *)
+ let i = Imagephoto.create [Width (Pixels anim.animWidth);
+ Height (Pixels anim.animHeight)]
+ in
+ bind label [[], Destroy] (BindExtend ([], (fun _ ->
+ Imagephoto.delete i)));
+ Label.configure label [ImagePhoto i];
+ animate_gen label i anim
+
+let animate_canvas_item canvas tag anim =
+(* prerr_endline "animate"; *)
+ let i = Imagephoto.create [Width (Pixels anim.animWidth);
+ Height (Pixels anim.animHeight)]
+ in
+ bind canvas [[], Destroy] (BindExtend ([], (fun _ ->
+ Imagephoto.delete i)));
+ Canvas.configure_image canvas tag [ImagePhoto i];
+ animate_gen canvas i anim
+
+let gifdata s =
+ let tmp_dir = ref "/tmp" in
+ let mktemp =
+ let cnter = ref 0
+ and pid = Unix.getpid() in
+ (function prefx ->
+ incr cnter;
+ (Filename.concat !tmp_dir
+ (prefx ^ string_of_int pid ^ "." ^ string_of_int !cnter)))
+ in
+ let fname = mktemp "gifdata" in
+ let oc = open_out_bin fname in
+ try
+ output_string oc s;
+ close_out oc;
+ let anim = create fname in
+ Unix.unlink fname;
+ anim
+ with
+ e -> begin Unix.unlink fname; raise e end
+
diff --git a/otherlibs/labltk/tkanim/tkanim.mli b/otherlibs/labltk/tkanim/tkanim.mli
new file mode 100644
index 000000000..26f425035
--- /dev/null
+++ b/otherlibs/labltk/tkanim/tkanim.mli
@@ -0,0 +1,95 @@
+(***********************************************************************)
+(* *)
+(* MLTk, Tcl/Tk interface of Objective Caml *)
+(* *)
+(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
+(* projet Cristal, INRIA Rocquencourt *)
+(* Jacques Garrigue, Kyoto University RIMS *)
+(* *)
+(* Copyright 2002 Institut National de Recherche en Informatique et *)
+(* en Automatique and Kyoto University. All rights reserved. *)
+(* This file is distributed under the terms of the GNU Library *)
+(* General Public License, with the special exception on linking *)
+(* described in file LICENSE found in the Objective Caml source tree. *)
+(* *)
+(***********************************************************************)
+open Camltk
+open Widget
+open Support
+
+(*** Data types ***)
+
+type animatedGif
+
+ (* This data type contains all the information of an animation of
+ gif89a format. It is still test implementation, so I should
+ keep it abstract. --- JPF *)
+
+type imageType =
+ | Still of Tk.options
+ | Animated of animatedGif
+
+ (* This data type is required to distinguish normal still images
+ and animated gifs. Usually objects typed imagePhoto or
+ imageBitmap are used for Still. *)
+
+(*** Flags ***)
+
+val debug : bool ref
+
+(*** Library availability check ***)
+
+val init : unit -> unit
+
+ (* This function calls the initialization function for Tkanim
+ Tcl/Tk extension. *)
+
+val available : unit -> bool
+
+ (* [available ()] returns true if there is Tkanim Tcl/Tk
+ extension linked statically/dynamically in Tcl/Tk
+ interpreter. Otherwise, return false. *)
+
+(*** User interface ***)
+
+(* create is unsafe *)
+val create : string -> imageType
+
+ (* [create file] loads a gif87 or gif89 image file and parse it,
+ and returns [Animated animated_gif] if the image file has
+ more than one images. Otherwise, it returns
+ [Still (ImagePhoto image_photo)] *)
+
+val delete : animatedGif -> unit
+
+ (* [delete anim] deletes all the images in anim. Usually
+ animatedGifs contain many images, so you must not forget to
+ use this function to free the memory. *)
+
+val width : animatedGif -> int
+val height : animatedGif -> int
+ (* [width anim] and [height anim] return the width and height of
+ given animated gif. *)
+
+val images : animatedGif -> imagePhoto list
+ (* [images anim] returns the list of still images used in the
+ animation *)
+
+val animate : widget -> animatedGif -> bool -> unit
+val animate_canvas_item : widget -> tagOrId -> animatedGif -> bool -> unit
+ (* The display functions for animated gifs. Since [animatedGif] is
+ an abstract type, you must use those functions to display
+ [animatedGif] images.
+ [animate label anim] and [animate_canvas_item canvas tag anim]
+ display animation [anim] on a label widget [label] or an
+ image tag [tag] on a canvas widget [canvas] respectively.
+
+ Note that animation is stopped by default.
+ These functions return interface functions, say, [inter :
+ bool -> unit]. Currently, [inter false] toggles start/stop of
+ the animation, and [inter true] displays the next frame of
+ the animation if the animation is stopped. *)
+
+val gifdata : string -> imageType
+ (* [gifdata data] reads [data] as a row data of a gif file and
+ decodes it. *)