Browse Source

Plan 9 from Bell Labs 2004-07-03

David du Colombier 20 years ago
parent
commit
7d9b2e1e00

+ 38 - 42
dist/replica/_plan9.db

@@ -5,19 +5,19 @@
 29000/lib - 20000000775 sys sys 948037563 0
 29000/mkfile - 664 sys sys 948141302 46
 386 - 20000000775 sys sys 1010957353 0
-386/9load - 775 sys sys 1088089726 187660
-386/9loaddebug - 775 sys sys 1088263706 270580
-386/9loadlite - 775 sys sys 1088089727 124624
-386/9loadlitedebug - 775 sys sys 1088263706 183691
-386/9pc - 775 sys sys 1087618546 1811884
+386/9load - 775 sys sys 1088798345 188040
+386/9loaddebug - 775 sys sys 1088798347 271141
+386/9loadlite - 775 sys sys 1088798346 125004
+386/9loadlitedebug - 775 sys sys 1088798347 184248
+386/9pc - 775 sys sys 1088739249 1812521
 386/9pc.gz - 664 sys sys 1077049336 635727
-386/9pccpu - 775 sys sys 1087618551 1466062
+386/9pccpu - 775 sys sys 1088739251 1466693
 386/9pccpu.gz - 664 sys sys 1077049387 519909
-386/9pcdisk - 775 sys sys 1087618555 2014334
+386/9pcdisk - 775 sys sys 1088739255 2014971
 386/9pcdisk.gz - 664 sys sys 1040006345 703136
-386/9pcf - 775 sys sys 1087618560 2346321
+386/9pcf - 775 sys sys 1088739259 2346958
 386/9pcf.gz - 664 sys sys 1077049490 872650
-386/9pxeload - 775 sys sys 1088089727 187660
+386/9pxeload - 775 sys sys 1088798346 188040
 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin/1c - 775 sys sys 1063639729 306762
@@ -26,7 +26,7 @@
 386/bin/8l - 775 sys sys 1087527915 106966
 386/bin/9660srv - 775 sys sys 1085076971 101995
 386/bin/aan - 775 sys sys 1085076971 128820
-386/bin/acid - 775 sys sys 1085076972 371882
+386/bin/acid - 775 sys sys 1088739242 371928
 386/bin/acme - 775 sys sys 1086836655 424880
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1087442501 132681
@@ -191,7 +191,7 @@
 386/bin/cpu - 775 sys sys 1085077026 135690
 386/bin/crop - 775 sys sys 1085077026 115107
 386/bin/date - 775 sys sys 1085077026 43216
-386/bin/db - 775 sys sys 1085077028 318180
+386/bin/db - 775 sys sys 1088739242 318226
 386/bin/dc - 775 sys sys 1085077028 96997
 386/bin/dd - 775 sys sys 1085077028 45322
 386/bin/deroff - 775 sys sys 1085077029 72249
@@ -301,8 +301,8 @@
 386/bin/join - 775 sys sys 1085077074 114267
 386/bin/jpg - 775 sys sys 1085077075 172573
 386/bin/kbmap - 775 sys sys 1085077075 140375
-386/bin/kprof - 775 sys sys 1085077075 99239
-386/bin/ktrace - 775 sys sys 1085077076 113171
+386/bin/kprof - 775 sys sys 1088739243 99266
+386/bin/ktrace - 775 sys sys 1088739243 113198
 386/bin/lens - 775 sys sys 1085077076 122322
 386/bin/lex - 775 sys sys 1085077076 96662
 386/bin/lnfs - 775 sys sys 1085077076 97466
@@ -335,7 +335,7 @@
 386/bin/netstat - 775 sys sys 1085077084 81935
 386/bin/news - 775 sys sys 1085077084 69654
 386/bin/nfs - 775 sys sys 1086923029 313626
-386/bin/nm - 775 sys sys 1085077085 119507
+386/bin/nm - 775 sys sys 1088739243 119534
 386/bin/nntpfs - 775 sys sys 1086923029 159031
 386/bin/ns - 775 sys sys 1085077086 63226
 386/bin/p - 775 sys sys 1085077086 62948
@@ -353,7 +353,7 @@
 386/bin/ppm - 775 sys sys 1085077089 147104
 386/bin/pr - 775 sys sys 1085077089 75383
 386/bin/primes - 775 sys sys 1085077090 38765
-386/bin/prof - 775 sys sys 1085077090 103992
+386/bin/prof - 775 sys sys 1088739243 104019
 386/bin/proof - 775 sys sys 1085077090 175785
 386/bin/ps - 775 sys sys 1085077090 63831
 386/bin/pwd - 775 sys sys 1085077091 36869
@@ -386,8 +386,8 @@
 386/bin/sha1sum - 775 sys sys 1085077096 59101
 386/bin/size - 775 sys sys 1085077097 74163
 386/bin/sleep - 775 sys sys 1085077097 3413
-386/bin/snap - 775 sys sys 1085077097 285793
-386/bin/snapfs - 775 sys sys 1086923030 354625
+386/bin/snap - 775 sys sys 1088739244 285839
+386/bin/snapfs - 775 sys sys 1088739245 354671
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/snoopy - 775 sys sys 1085077098 152766
 386/bin/sort - 775 sys sys 1085077099 80213
@@ -420,7 +420,7 @@
 386/bin/topng - 775 sys sys 1085077107 137101
 386/bin/toppm - 775 sys sys 1085077107 164405
 386/bin/touch - 775 sys sys 1085077107 61742
-386/bin/tprof - 775 sys sys 1085077108 271255
+386/bin/tprof - 775 sys sys 1088739246 271301
 386/bin/tr - 775 sys sys 1085077108 60009
 386/bin/trace - 775 sys sys 1085077109 178355
 386/bin/troff - 775 sys sys 1088263705 357256
@@ -511,7 +511,7 @@
 386/include/u.h - 664 sys sys 1042604326 1450
 386/include/ureg.h - 664 sys sys 944946012 523
 386/init - 775 sys sys 1085077133 98033
-386/ld.com - 775 sys sys 1088089728 64448
+386/ld.com - 775 sys sys 1088798347 64480
 386/lib - 20000000775 sys sys 1016826328 0
 386/lib/ape - 20000000775 sys sys 944969312 0
 386/lib/ape/lib9.a - 664 sys sys 1038237538 6378
@@ -532,7 +532,7 @@
 386/lib/libbio.a - 664 sys sys 1085077139 26078
 386/lib/libc.a - 664 sys sys 1085077140 495150
 386/lib/libcomplete.a - 664 sys sys 1076817073 6312
-386/lib/libcontrol.a - 664 sys sys 1085077141 242500
+386/lib/libcontrol.a - 664 sys sys 1088784892 276608
 386/lib/libdisk.a - 664 sys sys 1085077141 42290
 386/lib/libdraw.a - 664 sys sys 1085077142 372618
 386/lib/libflate.a - 664 sys sys 1085077142 77178
@@ -542,7 +542,7 @@
 386/lib/libhttpd.a - 664 sys sys 1085077143 99392
 386/lib/libip.a - 664 sys sys 1085077143 34002
 386/lib/libl.a - 664 sys sys 1085077143 5384
-386/lib/libmach.a - 664 sys sys 1085077145 735256
+386/lib/libmach.a - 664 sys sys 1088739261 735540
 386/lib/libmemdraw.a - 664 sys sys 1085077145 287684
 386/lib/libmemlayer.a - 664 sys sys 1085077145 47360
 386/lib/libmp.a - 664 sys sys 1085713909 80458
@@ -5401,7 +5401,7 @@ sys/src/9/pc/screen.h - 664 sys sys 1060267144 3797
 sys/src/9/pc/sd53c8xx.c - 664 sys sys 1086987325 52219
 sys/src/9/pc/sd53c8xx.i - 664 sys sys 1045063730 27355
 sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
-sys/src/9/pc/sdata.c - 664 sys sys 1071615236 50538
+sys/src/9/pc/sdata.c - 664 sys sys 1088795302 50581
 sys/src/9/pc/sdmylex.c - 664 sys sys 1071245460 27812
 sys/src/9/pc/sdscsi.c - 664 sys sys 1077033661 7487
 sys/src/9/pc/trap.c - 664 sys sys 1084475212 20378
@@ -6472,7 +6472,7 @@ sys/src/boot/pc/devpccard.c - 664 sys sys 1019533020 41357
 sys/src/boot/pc/devsd.c - 664 sys sys 1077033681 11262
 sys/src/boot/pc/dma.c - 664 sys sys 1015007949 4972
 sys/src/boot/pc/donprint.c - 664 sys sys 1019240172 4212
-sys/src/boot/pc/dosboot.c - 664 sys sys 1032215912 11014
+sys/src/boot/pc/dosboot.c - 664 sys sys 1088798342 11096
 sys/src/boot/pc/dosfs.h - 664 sys sys 1032215924 1467
 sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
@@ -6505,8 +6505,8 @@ sys/src/boot/pc/kbd.c - 664 sys sys 1015007952 10188
 sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1063855535 13012
-sys/src/boot/pc/lib.h - 664 sys sys 1015007952 3485
-sys/src/boot/pc/load.c - 664 sys sys 1056087197 7987
+sys/src/boot/pc/lib.h - 664 sys sys 1088798344 2089
+sys/src/boot/pc/load.c - 664 sys sys 1088798343 8358
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1015007953 3407
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
@@ -11835,22 +11835,23 @@ sys/src/libcomplete/complete.c - 664 sys sys 1076789202 2726
 sys/src/libcomplete/mkfile - 664 sys sys 1072904881 208
 sys/src/libcontrol - 20000000775 sys sys 1016857569 0
 sys/src/libcontrol/box.c - 664 sys sys 1015095043 3276
-sys/src/libcontrol/button.c - 664 sys sys 1015095044 4508
+sys/src/libcontrol/button.c - 664 sys sys 1088784890 5223
 sys/src/libcontrol/cache.c - 664 sys sys 1015095044 2621
-sys/src/libcontrol/control.c - 664 sys sys 1040447292 15340
+sys/src/libcontrol/control.c - 664 sys sys 1088784890 15536
 sys/src/libcontrol/entry.c - 664 sys sys 1040447293 6645
-sys/src/libcontrol/group.c - 664 sys sys 1016731563 17710
-sys/src/libcontrol/group.h - 664 sys sys 1015095045 311
+sys/src/libcontrol/group.c - 664 sys sys 1088784890 19210
+sys/src/libcontrol/group.h - 664 sys sys 1088784890 326
 sys/src/libcontrol/keyboard.c - 664 sys sys 1040447293 10894
 sys/src/libcontrol/label.c - 664 sys sys 1040447294 3986
 sys/src/libcontrol/menu.c - 664 sys sys 1040447294 7575
-sys/src/libcontrol/mkfile - 664 sys sys 1035389777 473
+sys/src/libcontrol/mkfile - 664 sys sys 1088784889 490
 sys/src/libcontrol/radiobutton.c - 664 sys sys 1015095046 3742
 sys/src/libcontrol/scribble.c - 664 sys sys 1015095047 6071
 sys/src/libcontrol/slider.c - 664 sys sys 1015095047 6411
 sys/src/libcontrol/tabs.c - 644 sys sys 1017166331 5521
-sys/src/libcontrol/text.c - 664 sys sys 1040447295 9070
-sys/src/libcontrol/textbutton.c - 664 sys sys 1040447296 6643
+sys/src/libcontrol/text.c - 664 sys sys 1088784891 12316
+sys/src/libcontrol/textbutton.c - 664 sys sys 1088784891 7486
+sys/src/libcontrol/textbutton3.c - 664 sys sys 1088784891 9104
 sys/src/libdisk - 20000000775 sys sys 969512501 0
 sys/src/libdisk/disk.c - 664 sys sys 1032061278 6662
 sys/src/libdisk/mkfile - 664 sys sys 1035389777 269
@@ -12431,13 +12432,8 @@ usr/glenda/lib/profile - 664 glenda glenda 1021580005 847
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
-386/bin/acid - 775 sys sys 1088737562 371928
-386/bin/db - 775 sys sys 1088737563 318226
-386/bin/snap - 775 sys sys 1088737564 285839
-386/bin/snapfs - 775 sys sys 1088737565 354671
-386/bin/kprof - 775 sys sys 1088737563 99266
-386/bin/ktrace - 775 sys sys 1088737563 113198
-386/bin/nm - 775 sys sys 1088737563 119534
-386/bin/prof - 775 sys sys 1088737564 104019
-386/bin/tprof - 775 sys sys 1088737566 271301
-386/lib/libmach.a - 664 sys sys 1088737568 735540
+386/bin/bitsy/keyboard - 775 sys sys 1088823722 303870
+386/bin/bitsy/prompter - 775 sys sys 1088823722 283924
+386/bin/ls - 775 sys sys 1088823722 80345
+386/bin/auth/fgui - 775 sys sys 1088823721 216032
+386/lib/libcontrol.a - 664 sys sys 1088823723 276608

+ 37 - 36
dist/replica/plan9.db

@@ -5,19 +5,19 @@
 29000/lib - 20000000775 sys sys 948037563 0
 29000/mkfile - 664 sys sys 948141302 46
 386 - 20000000775 sys sys 1010957353 0
-386/9load - 775 sys sys 1088089726 187660
-386/9loaddebug - 775 sys sys 1088263706 270580
-386/9loadlite - 775 sys sys 1088089727 124624
-386/9loadlitedebug - 775 sys sys 1088263706 183691
-386/9pc - 775 sys sys 1087618546 1811884
+386/9load - 775 sys sys 1088798345 188040
+386/9loaddebug - 775 sys sys 1088798347 271141
+386/9loadlite - 775 sys sys 1088798346 125004
+386/9loadlitedebug - 775 sys sys 1088798347 184248
+386/9pc - 775 sys sys 1088739249 1812521
 386/9pc.gz - 664 sys sys 1077049336 635727
-386/9pccpu - 775 sys sys 1087618551 1466062
+386/9pccpu - 775 sys sys 1088739251 1466693
 386/9pccpu.gz - 664 sys sys 1077049387 519909
-386/9pcdisk - 775 sys sys 1087618555 2014334
+386/9pcdisk - 775 sys sys 1088739255 2014971
 386/9pcdisk.gz - 664 sys sys 1040006345 703136
-386/9pcf - 775 sys sys 1087618560 2346321
+386/9pcf - 775 sys sys 1088739259 2346958
 386/9pcf.gz - 664 sys sys 1077049490 872650
-386/9pxeload - 775 sys sys 1088089727 187660
+386/9pxeload - 775 sys sys 1088798346 188040
 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin/1c - 775 sys sys 1063639729 306762
@@ -26,7 +26,7 @@
 386/bin/8l - 775 sys sys 1087527915 106966
 386/bin/9660srv - 775 sys sys 1085076971 101995
 386/bin/aan - 775 sys sys 1085076971 128820
-386/bin/acid - 775 sys sys 1088737562 371928
+386/bin/acid - 775 sys sys 1088739242 371928
 386/bin/acme - 775 sys sys 1086836655 424880
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1087442501 132681
@@ -61,7 +61,7 @@
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/enable - 775 sys sys 1020319057 134
 386/bin/auth/factotum - 775 sys sys 1087873350 307151
-386/bin/auth/fgui - 775 sys sys 1085076980 212283
+386/bin/auth/fgui - 775 sys sys 1088823721 216032
 386/bin/auth/guard.srv - 775 sys sys 1085076980 140340
 386/bin/auth/iam - 775 sys sys 1085076981 50791
 386/bin/auth/keyfs - 775 sys sys 1085076981 113215
@@ -164,11 +164,11 @@
 386/bin/bind - 775 sys sys 1085077012 57577
 386/bin/bitsy - 20000000775 sys sys 1018721039 0
 386/bin/bitsy/bitsyload - 775 sys sys 1085077012 61374
-386/bin/bitsy/keyboard - 775 sys sys 1085077013 301712
+386/bin/bitsy/keyboard - 775 sys sys 1088823722 303870
 386/bin/bitsy/light - 775 sys sys 1020319072 242
 386/bin/bitsy/params - 775 sys sys 1085077013 56744
 386/bin/bitsy/pencal - 775 sys sys 1085077014 115252
-386/bin/bitsy/prompter - 775 sys sys 1085077015 283770
+386/bin/bitsy/prompter - 775 sys sys 1088823722 283924
 386/bin/bmp - 775 sys sys 1085077015 155439
 386/bin/bunzip2 - 775 sys sys 1085077016 95409
 386/bin/bzip2 - 775 sys sys 1085077016 111665
@@ -191,7 +191,7 @@
 386/bin/cpu - 775 sys sys 1085077026 135690
 386/bin/crop - 775 sys sys 1085077026 115107
 386/bin/date - 775 sys sys 1085077026 43216
-386/bin/db - 775 sys sys 1088737563 318226
+386/bin/db - 775 sys sys 1088739242 318226
 386/bin/dc - 775 sys sys 1085077028 96997
 386/bin/dd - 775 sys sys 1085077028 45322
 386/bin/deroff - 775 sys sys 1085077029 72249
@@ -301,13 +301,13 @@
 386/bin/join - 775 sys sys 1085077074 114267
 386/bin/jpg - 775 sys sys 1085077075 172573
 386/bin/kbmap - 775 sys sys 1085077075 140375
-386/bin/kprof - 775 sys sys 1088737563 99266
-386/bin/ktrace - 775 sys sys 1088737563 113198
+386/bin/kprof - 775 sys sys 1088739243 99266
+386/bin/ktrace - 775 sys sys 1088739243 113198
 386/bin/lens - 775 sys sys 1085077076 122322
 386/bin/lex - 775 sys sys 1085077076 96662
 386/bin/lnfs - 775 sys sys 1085077076 97466
 386/bin/look - 775 sys sys 1085077077 63516
-386/bin/ls - 775 sys sys 1085077077 80331
+386/bin/ls - 775 sys sys 1088823722 80345
 386/bin/mc - 775 sys sys 1085077077 130848
 386/bin/md5sum - 775 sys sys 1085077077 59233
 386/bin/mk - 775 sys sys 1085077078 141902
@@ -335,7 +335,7 @@
 386/bin/netstat - 775 sys sys 1085077084 81935
 386/bin/news - 775 sys sys 1085077084 69654
 386/bin/nfs - 775 sys sys 1086923029 313626
-386/bin/nm - 775 sys sys 1088737563 119534
+386/bin/nm - 775 sys sys 1088739243 119534
 386/bin/nntpfs - 775 sys sys 1086923029 159031
 386/bin/ns - 775 sys sys 1085077086 63226
 386/bin/p - 775 sys sys 1085077086 62948
@@ -353,7 +353,7 @@
 386/bin/ppm - 775 sys sys 1085077089 147104
 386/bin/pr - 775 sys sys 1085077089 75383
 386/bin/primes - 775 sys sys 1085077090 38765
-386/bin/prof - 775 sys sys 1088737564 104019
+386/bin/prof - 775 sys sys 1088739243 104019
 386/bin/proof - 775 sys sys 1085077090 175785
 386/bin/ps - 775 sys sys 1085077090 63831
 386/bin/pwd - 775 sys sys 1085077091 36869
@@ -386,8 +386,8 @@
 386/bin/sha1sum - 775 sys sys 1085077096 59101
 386/bin/size - 775 sys sys 1085077097 74163
 386/bin/sleep - 775 sys sys 1085077097 3413
-386/bin/snap - 775 sys sys 1088737564 285839
-386/bin/snapfs - 775 sys sys 1088737565 354671
+386/bin/snap - 775 sys sys 1088739244 285839
+386/bin/snapfs - 775 sys sys 1088739245 354671
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/snoopy - 775 sys sys 1085077098 152766
 386/bin/sort - 775 sys sys 1085077099 80213
@@ -420,7 +420,7 @@
 386/bin/topng - 775 sys sys 1085077107 137101
 386/bin/toppm - 775 sys sys 1085077107 164405
 386/bin/touch - 775 sys sys 1085077107 61742
-386/bin/tprof - 775 sys sys 1088737566 271301
+386/bin/tprof - 775 sys sys 1088739246 271301
 386/bin/tr - 775 sys sys 1085077108 60009
 386/bin/trace - 775 sys sys 1085077109 178355
 386/bin/troff - 775 sys sys 1088263705 357256
@@ -511,7 +511,7 @@
 386/include/u.h - 664 sys sys 1042604326 1450
 386/include/ureg.h - 664 sys sys 944946012 523
 386/init - 775 sys sys 1085077133 98033
-386/ld.com - 775 sys sys 1088089728 64448
+386/ld.com - 775 sys sys 1088798347 64480
 386/lib - 20000000775 sys sys 1016826328 0
 386/lib/ape - 20000000775 sys sys 944969312 0
 386/lib/ape/lib9.a - 664 sys sys 1038237538 6378
@@ -532,7 +532,7 @@
 386/lib/libbio.a - 664 sys sys 1085077139 26078
 386/lib/libc.a - 664 sys sys 1085077140 495150
 386/lib/libcomplete.a - 664 sys sys 1076817073 6312
-386/lib/libcontrol.a - 664 sys sys 1085077141 242500
+386/lib/libcontrol.a - 664 sys sys 1088823723 276608
 386/lib/libdisk.a - 664 sys sys 1085077141 42290
 386/lib/libdraw.a - 664 sys sys 1085077142 372618
 386/lib/libflate.a - 664 sys sys 1085077142 77178
@@ -542,7 +542,7 @@
 386/lib/libhttpd.a - 664 sys sys 1085077143 99392
 386/lib/libip.a - 664 sys sys 1085077143 34002
 386/lib/libl.a - 664 sys sys 1085077143 5384
-386/lib/libmach.a - 664 sys sys 1088737568 735540
+386/lib/libmach.a - 664 sys sys 1088739261 735540
 386/lib/libmemdraw.a - 664 sys sys 1085077145 287684
 386/lib/libmemlayer.a - 664 sys sys 1085077145 47360
 386/lib/libmp.a - 664 sys sys 1085713909 80458
@@ -5401,7 +5401,7 @@ sys/src/9/pc/screen.h - 664 sys sys 1060267144 3797
 sys/src/9/pc/sd53c8xx.c - 664 sys sys 1086987325 52219
 sys/src/9/pc/sd53c8xx.i - 664 sys sys 1045063730 27355
 sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
-sys/src/9/pc/sdata.c - 664 sys sys 1071615236 50538
+sys/src/9/pc/sdata.c - 664 sys sys 1088795302 50581
 sys/src/9/pc/sdmylex.c - 664 sys sys 1071245460 27812
 sys/src/9/pc/sdscsi.c - 664 sys sys 1077033661 7487
 sys/src/9/pc/trap.c - 664 sys sys 1084475212 20378
@@ -6472,7 +6472,7 @@ sys/src/boot/pc/devpccard.c - 664 sys sys 1019533020 41357
 sys/src/boot/pc/devsd.c - 664 sys sys 1077033681 11262
 sys/src/boot/pc/dma.c - 664 sys sys 1015007949 4972
 sys/src/boot/pc/donprint.c - 664 sys sys 1019240172 4212
-sys/src/boot/pc/dosboot.c - 664 sys sys 1032215912 11014
+sys/src/boot/pc/dosboot.c - 664 sys sys 1088798342 11096
 sys/src/boot/pc/dosfs.h - 664 sys sys 1032215924 1467
 sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
@@ -6505,8 +6505,8 @@ sys/src/boot/pc/kbd.c - 664 sys sys 1015007952 10188
 sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1063855535 13012
-sys/src/boot/pc/lib.h - 664 sys sys 1015007952 3485
-sys/src/boot/pc/load.c - 664 sys sys 1056087197 7987
+sys/src/boot/pc/lib.h - 664 sys sys 1088798344 2089
+sys/src/boot/pc/load.c - 664 sys sys 1088798343 8358
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1015007953 3407
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272
@@ -11835,22 +11835,23 @@ sys/src/libcomplete/complete.c - 664 sys sys 1076789202 2726
 sys/src/libcomplete/mkfile - 664 sys sys 1072904881 208
 sys/src/libcontrol - 20000000775 sys sys 1016857569 0
 sys/src/libcontrol/box.c - 664 sys sys 1015095043 3276
-sys/src/libcontrol/button.c - 664 sys sys 1015095044 4508
+sys/src/libcontrol/button.c - 664 sys sys 1088784890 5223
 sys/src/libcontrol/cache.c - 664 sys sys 1015095044 2621
-sys/src/libcontrol/control.c - 664 sys sys 1040447292 15340
+sys/src/libcontrol/control.c - 664 sys sys 1088784890 15536
 sys/src/libcontrol/entry.c - 664 sys sys 1040447293 6645
-sys/src/libcontrol/group.c - 664 sys sys 1016731563 17710
-sys/src/libcontrol/group.h - 664 sys sys 1015095045 311
+sys/src/libcontrol/group.c - 664 sys sys 1088784890 19210
+sys/src/libcontrol/group.h - 664 sys sys 1088784890 326
 sys/src/libcontrol/keyboard.c - 664 sys sys 1040447293 10894
 sys/src/libcontrol/label.c - 664 sys sys 1040447294 3986
 sys/src/libcontrol/menu.c - 664 sys sys 1040447294 7575
-sys/src/libcontrol/mkfile - 664 sys sys 1035389777 473
+sys/src/libcontrol/mkfile - 664 sys sys 1088784889 490
 sys/src/libcontrol/radiobutton.c - 664 sys sys 1015095046 3742
 sys/src/libcontrol/scribble.c - 664 sys sys 1015095047 6071
 sys/src/libcontrol/slider.c - 664 sys sys 1015095047 6411
 sys/src/libcontrol/tabs.c - 644 sys sys 1017166331 5521
-sys/src/libcontrol/text.c - 664 sys sys 1040447295 9070
-sys/src/libcontrol/textbutton.c - 664 sys sys 1040447296 6643
+sys/src/libcontrol/text.c - 664 sys sys 1088784891 12316
+sys/src/libcontrol/textbutton.c - 664 sys sys 1088784891 7486
+sys/src/libcontrol/textbutton3.c - 664 sys sys 1088784891 9104
 sys/src/libdisk - 20000000775 sys sys 969512501 0
 sys/src/libdisk/disk.c - 664 sys sys 1032061278 6662
 sys/src/libdisk/mkfile - 664 sys sys 1035389777 269

+ 38 - 0
dist/replica/plan9.log

@@ -15781,3 +15781,41 @@
 1088739113 7 c 386/bin/prof - 775 sys sys 1088737564 104019
 1088739113 8 c 386/bin/tprof - 775 sys sys 1088737566 271301
 1088739113 9 c 386/lib/libmach.a - 664 sys sys 1088737568 735540
+1088740914 0 c 386/9pc - 775 sys sys 1088739249 1812521
+1088740914 1 c 386/9pccpu - 775 sys sys 1088739251 1466693
+1088740914 2 c 386/9pcdisk - 775 sys sys 1088739255 2014971
+1088740914 3 c 386/9pcf - 775 sys sys 1088739259 2346958
+1088740914 4 c 386/bin/acid - 775 sys sys 1088739242 371928
+1088740914 5 c 386/bin/db - 775 sys sys 1088739242 318226
+1088740914 6 c 386/bin/snap - 775 sys sys 1088739244 285839
+1088740914 7 c 386/bin/snapfs - 775 sys sys 1088739245 354671
+1088740914 8 c 386/bin/kprof - 775 sys sys 1088739243 99266
+1088740914 9 c 386/bin/ktrace - 775 sys sys 1088739243 113198
+1088740914 10 c 386/bin/nm - 775 sys sys 1088739243 119534
+1088740914 11 c 386/bin/prof - 775 sys sys 1088739243 104019
+1088740914 12 c 386/bin/tprof - 775 sys sys 1088739246 271301
+1088740914 13 c 386/lib/libmach.a - 664 sys sys 1088739261 735540
+1088785923 0 c 386/lib/libcontrol.a - 664 sys sys 1088784892 276608
+1088785923 1 c sys/src/libcontrol/button.c - 664 sys sys 1088784890 5223
+1088785923 2 c sys/src/libcontrol/control.c - 664 sys sys 1088784890 15536
+1088785923 3 c sys/src/libcontrol/group.c - 664 sys sys 1088784890 19210
+1088785923 4 c sys/src/libcontrol/group.h - 664 sys sys 1088784890 326
+1088785923 5 c sys/src/libcontrol/mkfile - 664 sys sys 1088784889 490
+1088785923 6 c sys/src/libcontrol/text.c - 664 sys sys 1088784891 12316
+1088785923 7 c sys/src/libcontrol/textbutton.c - 664 sys sys 1088784891 7486
+1088785923 8 a sys/src/libcontrol/textbutton3.c - 664 sys sys 1088784891 9104
+1088796610 0 c sys/src/9/pc/sdata.c - 664 sys sys 1088795302 50581
+1088798415 0 c 386/9load - 775 sys sys 1088798345 188040
+1088798415 1 c 386/9loaddebug - 775 sys sys 1088798347 271141
+1088798415 2 c 386/9loadlite - 775 sys sys 1088798346 125004
+1088798415 3 c 386/9loadlitedebug - 775 sys sys 1088798347 184248
+1088798415 4 c 386/9pxeload - 775 sys sys 1088798346 188040
+1088798415 5 c 386/ld.com - 775 sys sys 1088798347 64480
+1088798415 6 c sys/src/boot/pc/dosboot.c - 664 sys sys 1088798342 11096
+1088798415 7 c sys/src/boot/pc/lib.h - 664 sys sys 1088798344 2089
+1088798415 8 c sys/src/boot/pc/load.c - 664 sys sys 1088798343 8358
+1088825410 0 c 386/bin/bitsy/keyboard - 775 sys sys 1088823722 303870
+1088825410 1 c 386/bin/bitsy/prompter - 775 sys sys 1088823722 283924
+1088825410 2 c 386/bin/ls - 775 sys sys 1088823722 80345
+1088825410 3 c 386/bin/auth/fgui - 775 sys sys 1088823721 216032
+1088825410 4 c 386/lib/libcontrol.a - 664 sys sys 1088823723 276608

+ 1 - 0
sys/src/9/pc/sdata.c

@@ -1890,6 +1890,7 @@ atapnp(void)
 			pcicfgw8(p, 0x44, r|0x08);
 			r = pcicfgr8(p, 0x46);
 			pcicfgw8(p, 0x46, (r & 0x0C)|0xF0);
+		case (0x7469<<16)|0x1022:	/* AMD 3111 */
 			break;
 		case (0x0646<<16)|0x1095:	/* CMD 646 */
 		case (0x0571<<16)|0x1106:	/* VIA 82C686 */

+ 14 - 10
sys/src/boot/pc/dosboot.c

@@ -430,6 +430,7 @@ chat("dosinit0a\n");
 		bootdump(b);
 
 	if(b->clustsize == 0) {
+badclustsize:
 		print("dos file system has incorrect cluster size\n");
 		for(i=0; i<3+8+2+1; i++)
 			print(" %.2ux", p->iobuf[i]);
@@ -480,6 +481,9 @@ chat("dosinit1\n");
 	}
 	dos->freeptr = 2;
 
+	if(dos->clustbytes < 512 || dos->clustbytes > 64*1024)
+		goto badclustsize;
+
 chat("dosinit2\n");
 
 	/*
@@ -507,20 +511,20 @@ bootdump(Dosboot *b)
 {
 	if(chatty == 0)
 		return;
-	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x\n",
+	print("magic: 0x%2.2x 0x%2.2x 0x%2.2x ",
 		b->magic[0], b->magic[1], b->magic[2]);
 	print("version: \"%8.8s\"\n", (char*)b->version);
-	print("sectsize: %d\n", GSHORT(b->sectsize));
-	print("allocsize: %d\n", b->clustsize);
-	print("nresrv: %d\n", GSHORT(b->nresrv));
+	print("sectsize: %d ", GSHORT(b->sectsize));
+	print("allocsize: %d ", b->clustsize);
+	print("nresrv: %d ", GSHORT(b->nresrv));
 	print("nfats: %d\n", b->nfats);
-	print("rootsize: %d\n", GSHORT(b->rootsize));
-	print("volsize: %d\n", GSHORT(b->volsize));
+	print("rootsize: %d ", GSHORT(b->rootsize));
+	print("volsize: %d ", GSHORT(b->volsize));
 	print("mediadesc: 0x%2.2x\n", b->mediadesc);
-	print("fatsize: %d\n", GSHORT(b->fatsize));
-	print("trksize: %d\n", GSHORT(b->trksize));
-	print("nheads: %d\n", GSHORT(b->nheads));
-	print("nhidden: %d\n", GLONG(b->nhidden));
+	print("fatsize: %d ", GSHORT(b->fatsize));
+	print("trksize: %d ", GSHORT(b->trksize));
+	print("nheads: %d ", GSHORT(b->nheads));
+	print("nhidden: %d ", GLONG(b->nhidden));
 	print("bigvolsize: %d\n", GLONG(b->bigvolsize));
 /*
 	print("driveno: %d\n", b->driveno);

+ 1 - 60
sys/src/boot/pc/lib.h

@@ -27,11 +27,7 @@ extern	char*	strstr(char*, char*);
 
 /*
  * print routines
- * 	Fconv isn't used but is defined to satisfy prototypes in libg.h
- *	that are never called.
  */
-typedef	struct Fconv Fconv;
-
 extern	char*	donprint(char*, char*, char*, void*);
 extern	int	sprint(char*, char*, ...);
 extern 	int	snprint(char*, int, char*, ...);
@@ -75,64 +71,9 @@ extern	int	print(char*, ...);
  * one-of-a-kind
  */
 extern	int	atoi(char*);
+extern	ulong	getcallerpc(void*);
 extern	long	strtol(char*, char**, int);
 extern	ulong	strtoul(char*, char**, int);
 extern	long	end;
 
-/*
- * Syscall data structures
- */
-
-#define	MORDER	0x0003	/* mask for bits defining order of mounting */
-#define	MREPL	0x0000	/* mount replaces object */
-#define	MBEFORE	0x0001	/* mount goes before others in union directory */
-#define	MAFTER	0x0002	/* mount goes after others in union directory */
-#define	MCREATE	0x0004	/* permit creation in mounted directory */
-#define	MMASK	0x0007	/* all bits on */
-
-#define	OREAD	0	/* open for read */
-#define	OWRITE	1	/* write */
-#define	ORDWR	2	/* read and write */
-#define	OEXEC	3	/* execute, == read but check execute permission */
-#define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
-#define	OCEXEC	32	/* or'ed in, close on exec */
-#define	ORCLOSE	64	/* or'ed in, remove on close */
-
-#define	NCONT	0	/* continue after note */
-#define	NDFLT	1	/* terminate after note */
-
-typedef struct Qid	Qid;
-typedef struct Dir	Dir;
-typedef struct Waitmsg	Waitmsg;
-
-#define	ERRLEN	64
-#define	DIRLEN	116
 #define	NAMELEN	28
-
-struct Qid
-{
-	ulong	path;
-	ulong	vers;
-};
-
-struct Dir
-{
-	char	name[NAMELEN];
-	char	uid[NAMELEN];
-	char	gid[NAMELEN];
-	Qid	qid;
-	ulong	mode;
-	long	atime;
-	long	mtime;
-	vlong	length;
-	short	type;
-	short	dev;
-};
-
-struct Waitmsg
-{
-	int	pid;		/* of loved one */
-	int	status;		/* unused; a placeholder */
-	ulong	time[3];	/* of loved one */
-	char	msg[ERRLEN];
-};

+ 15 - 5
sys/src/boot/pc/load.c

@@ -409,18 +409,17 @@ cistrncmp(char *a, char *b, int n)
 	return 0;
 }
 
-extern void diff(char*);
+#define PSTART		(12*1024*1024)
+#define PEND		(16*1024*1024)
+
+ulong palloc = PSTART;
 
-ulong palloc;
 void*
 ialloc(ulong n, int align)
 {
 	ulong p;
 	int a;
 
-	if(palloc == 0)
-		palloc = 12*1024*1024;
-
 	p = palloc;
 	if(align <= 0)
 		align = 4;
@@ -429,7 +428,11 @@ ialloc(ulong n, int align)
 	if(a = p % align)
 		p += align - a;
 
+
 	palloc = p+n;
+	if(palloc > PEND)
+		panic("ialloc(%lud, %d) called from 0x%lux\n",
+			n, align, getcallerpc(&n));
 	return memset((void*)(p|KZERO), 0, n);
 }
 
@@ -438,6 +441,10 @@ xspanalloc(ulong size, int align, ulong span)
 {
 	ulong a, v;
 
+	if((palloc + (size+align+span)) > PEND)
+		panic("xspanalloc(%lud, %d, 0x%lux) called from 0x%lux\n",
+			size, align, span, getcallerpc(&size));
+
 	a = (ulong)ialloc(size+align+span, 0);
 
 	if(span > 2)
@@ -468,6 +475,9 @@ allocb(int size)
 		lbp = &bp->next;
 	}
 	if(bp == 0){
+		if((palloc + (sizeof(Block)+size+64)) > PEND)
+			panic("allocb(%d) called from 0x%lux\n",
+				size, getcallerpc(&size));
 		bp = ialloc(sizeof(Block)+size+64, 0);
 		addr = (ulong)bp;
 		addr = ROUNDUP(addr + sizeof(Block), 8);

+ 38 - 2
sys/src/libcontrol/button.c

@@ -14,12 +14,15 @@ struct Button
 	CImage	*image;
 	CImage	*mask;
 	CImage	*light;
+	CImage	*pale;
 	CImage	*bordercolor;
 	int		pressed;
 	int		lastbut;
 	int		lastshow;
 	int		border;
 	int		align;
+	int		off;
+	int		prepress;
 };
 
 enum{
@@ -32,6 +35,7 @@ enum{
 	EImage,
 	ELight,
 	EMask,
+	EPale,
 	ERect,
 	EReveal,
 	EShow,
@@ -49,6 +53,7 @@ static char *cmds[] = {
 	[EImage] =	"image",
 	[ELight] =		"light",
 	[EMask] =		"mask",
+	[EPale] =		"pale",
 	[ERect] =		"rect",
 	[EReveal] =	"reveal",
 	[EShow] =		"show",
@@ -66,6 +71,7 @@ buttonfree(Control *c)
 	_putctlimage(b->image);
 	_putctlimage(b->mask);
 	_putctlimage(b->light);
+	_putctlimage(b->pale);
 	_putctlimage(b->bordercolor);
 }
 
@@ -82,7 +88,9 @@ buttonshow(Button *b)
 		r = insetrect(b->rect, b->border);
 	}
 	draw(b->screen, r, b->image->image, nil, b->image->image->r.min);
-	if(b->pressed)
+	if(b->off)
+		draw(b->screen, r, b->pale->image, b->mask->image, b->mask->image->r.min);
+	else if(b->pressed)
 		draw(b->screen, r, b->light->image, b->mask->image, b->mask->image->r.min);
 	b->lastshow = b->pressed;
 	flushimage(display, 1);
@@ -95,15 +103,35 @@ buttonmouse(Control *c, Mouse *m)
 
 	b = (Button*)c;
 
+	if(m->buttons&7) {
+		if (ptinrect(m->xy,b->rect)) {
+			if (b->off) {
+				b->off = 0;
+				buttonshow(b);
+			}
+		} else {
+			if (!b->off) {
+				b->off = 1;
+				buttonshow(b);
+			}
+		}
+	}
 	if((m->buttons&7) != b->lastbut){
 		if(m->buttons & 7){
+			b->prepress = b->pressed;
 			if (b->pressed)
 				b->pressed = 0;
 			else
 				b->pressed = m->buttons & 7;
 			buttonshow(b);
 		}else	/* generate event on button up */
-			chanprint(b->event, b->format, b->name, b->pressed);
+			if (ptinrect(m->xy,b->rect))
+				chanprint(b->event, b->format, b->name, b->pressed);
+			else {
+				b->off = 0;
+				b->pressed = b->prepress;
+				buttonshow(b);
+			}
 	}
 	b->lastbut = m->buttons & 7;
 }
@@ -162,6 +190,11 @@ buttonctl(Control *c, CParse *cp)
 		_setctlimage(b, &b->mask, cp->args[1]);
 		b->lastshow = -1;	/* force redraw */
 		break;
+	case EPale:
+		_ctlargcount(b, cp, 2);
+		_setctlimage(b, &b->pale, cp->args[1]);
+		b->lastshow = -1;	/* force redraw */
+		break;
 	case ERect:
 		_ctlargcount(b, cp, 5);
 		r.min.x = cp->iargs[1];
@@ -215,6 +248,7 @@ createbutton(Controlset *cs, char *name)
 	b->image = _getctlimage("white");
 	b->mask = _getctlimage("opaque");
 	b->light = _getctlimage("yellow");
+	b->pale = _getctlimage("paleyellow");
 	b->bordercolor = _getctlimage("black");
 	b->format = ctlstrdup("%q: value %d");
 	b->lastshow = -1;
@@ -224,5 +258,7 @@ createbutton(Controlset *cs, char *name)
 	b->mouse = buttonmouse;
 	b->key = nil;
 	b->exit = buttonfree;
+	b->off = 0;
+	b->prepress = 0;
 	return (Control*)b;
 }

+ 11 - 4
sys/src/libcontrol/control.c

@@ -6,6 +6,8 @@
 #include <keyboard.h>
 #include <control.h>
 
+static int debug = 0;
+
 enum	/* alts */
 {
 	AKey,
@@ -45,6 +47,7 @@ char *ctltypenames[Ntypes] = {
 	[Ctltabs] =			"tabs",
 	[Ctltext] =			"text",
 	[Ctltextbutton] =	"textbutton",
+	[Ctltextbutton3] =	"textbutton3",
 	[Ctlgroup] =		"group",		// divider between controls and metacontrols
 	[Ctlboxbox] =		"boxbox",
 	[Ctlcolumn] =		"column",
@@ -111,8 +114,8 @@ _ctllookup(char *s, char *tab[], int ntab)
 {
 	int i;
 
-	for(i=0; i<ntab && tab[i] != nil; i++)
-		if(strcmp(s, tab[i]) == 0)
+	for(i=0; i<ntab; i++)
+		if(tab[i] != nil && strcmp(s, tab[i]) == 0)
 			return i;
 	return -1;
 }
@@ -217,13 +220,17 @@ controlsetthread(void *v)
 				if(f->hidden == 0 && f->mouse && ptinrect(mouse.xy, f->rect)){
 					cs->focus = f;
 					_ctlprint(f, "focus 1");
-					if (f->mouse)
+					if (f->mouse) {
+						if (debug) fprint(2, "f->mouse %s\n", f->name);
 						f->mouse(f, &mouse);
+					}
 					break;
 				}
 		Send:
-			if(cs->focus && cs->focus->mouse)
+			if(cs->focus && cs->focus->mouse) {
+				if (debug) fprint(2, "cs->focus->mouse %s\n", cs->focus->name);
 				cs->focus->mouse(cs->focus, &mouse);
+			}
 			prevbut=mouse.buttons;
 			break;
 		case ACtl:

+ 41 - 10
sys/src/libcontrol/group.c

@@ -8,6 +8,8 @@
 #include "group.h"
 
 static int debug = 0;
+static int debugm = 0;
+static int debugr = 0;
 
 enum{
 	EAdd,
@@ -58,6 +60,7 @@ groupinit(Group *g)
 	g->mansize = 0;
 	g->separation = 0;
 	g->selected = -1;
+	g->lastkid = -1;
 	g->kids = nil;
 	g->separators = nil;
 	g->nkids = 0;
@@ -152,7 +155,7 @@ groupctl(Control *c, CParse *cp)
 		break;
 	case EReveal:
 		g->hidden = 0;
-		if (debug) fprint(2, "reveal %s\n", g->name);
+		if (debugr) fprint(2, "reveal %s\n", g->name);
 		if (g->type == Ctlstack){
 			if (cp->nargs == 2){
 				if (cp->iargs[1] < 0 || cp->iargs[1] >= g->nkids)
@@ -163,10 +166,10 @@ groupctl(Control *c, CParse *cp)
 			for (i = 0; i < g->nkids; i++)
 				if (g->kids[i]->ctl){
 					if (g->selected == i){
-						if (debug) fprint(2, "reveal %s: reveal kid %s\n", g->name, g->kids[i]->name);
+						if (debugr) fprint(2, "reveal %s: reveal kid %s\n", g->name, g->kids[i]->name);
 						_ctlprint(g->kids[i], "reveal");
 					}else{
-						if (debug) fprint(2, "reveal %s: hide kid %s\n", g->name, g->kids[i]->name);
+						if (debugr) fprint(2, "reveal %s: hide kid %s\n", g->name, g->kids[i]->name);
 						_ctlprint(g->kids[i], "hide");
 					}
 				}
@@ -256,22 +259,50 @@ static void
 groupmouse(Control *c, Mouse *m)
 {
 	Group *g;
-	int i;
+	int i, lastkid;
 
 	g = (Group*)c;
 	if (g->type == Ctlstack){
-		if (g->selected >= 0 && ptinrect(m->xy, g->kids[g->selected]->rect) && g->kids[g->selected]->mouse){
-			(g->kids[g->selected]->mouse)(g->kids[g->selected], m);
-			return;
+		i = g->selected;
+		if (i >= 0 && g->kids[i]->mouse &&
+                        ( ( ((m->buttons == 0) || (g->lastbut == 0)) &&
+                           ptinrect(m->xy, g->kids[i]->rect) ) ||
+                         ( ((m->buttons != 0) || (g->lastbut != 0)) &&
+		         (g->lastkid == i) ) ) ) {
+			if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",
+						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,
+						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);
+			(g->kids[i]->mouse)(g->kids[i], m);
+			g->lastkid = i;
+			g->lastbut = m->buttons;
+		} else {
+			if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",
+						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,
+						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);
 		}
 		return;
 	}
 
-	for(i=0; i<g->nkids; i++)
-		if(ptinrect(m->xy, g->kids[i]->rect) && g->kids[i]->mouse){
+	lastkid = -1;
+	for(i=0; i<g->nkids; i++) {
+		if(g->kids[i]->mouse &&
+                      ( ( ((m->buttons == 0) || (g->lastbut == 0)) &&
+                           ptinrect(m->xy, g->kids[i]->rect) ) ||
+                        ( ((m->buttons != 0) || (g->lastbut != 0)) &&
+		         (g->lastkid == i) ) ) ) {
+			if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",
+						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,
+						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);
 			(g->kids[i]->mouse)(g->kids[i], m);
-			return;
+			lastkid = i;
+		} else {
+			if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n",
+						g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut,
+						ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0);
 		}
+	}
+	g->lastkid = lastkid;
+	g->lastbut = m->buttons;
 
 #ifdef notdef
 	if(m->buttons == 0){

+ 1 - 0
sys/src/libcontrol/group.h

@@ -8,6 +8,7 @@ struct Group {
 	int		mansize;		/* size was set manually */
 	int		separation;
 	int		selected;
+	int		lastkid;
 	CImage	*bordercolor;
 	CImage	*image;
 	int		nkids;

+ 1 - 0
sys/src/libcontrol/mkfile

@@ -18,6 +18,7 @@ OFILES=\
 	tabs.$O\
 	text.$O\
 	textbutton.$O\
+	textbutton3.$O\
 
 HFILES=/sys/include/draw.h\
 	/sys/include/mouse.h\

+ 113 - 6
sys/src/libcontrol/text.c

@@ -6,6 +6,8 @@
 #include <keyboard.h>
 #include <control.h>
 
+static int debug = 0;
+
 typedef struct Text Text;
 
 struct Text
@@ -21,17 +23,25 @@ struct Text
 	CImage	*textcolor;
 	CImage	*bordercolor;
 	CImage	*selectcolor;
+	CImage	*selectingcolor;
 	Rune		**line;
-	int		selectmode;
+	int		selectmode;	// Selsingle, Selmulti
+	int		selectstyle;	// Seldown, Selup (use Selup only with Selsingle)
 	uchar	*selected;
 	int		nline;
+	int		warp;
 	int		align;
+	int		sel;		// line nr of selection made by last button down
+	int		but;		// last button down (still being hold)
+	int		offsel;	// we are on selection
 };
 
 enum
 {
 	Selsingle,
 	Selmulti,
+	Seldown,
+	Selup,
 };
 
 enum{
@@ -52,12 +62,15 @@ enum{
 	EScroll,
 	ESelect,
 	ESelectcolor,
+	ESelectingcolor,
 	ESelectmode,
+	ESelectstyle,
 	EShow,
 	ESize,
 	ETextcolor,
 	ETopline,
 	EValue,
+	EWarp,
 };
 
 static char *cmds[] = {
@@ -78,17 +91,21 @@ static char *cmds[] = {
 	[EScroll] =			"scroll",
 	[ESelect] =		"select",
 	[ESelectcolor] =	"selectcolor",
+	[ESelectingcolor] =	"selectingcolor",
 	[ESelectmode] =	"selectmode",
+	[ESelectstyle] =		"selectstyle",
 	[EShow] =			"show",
 	[ESize] =			"size",
 	[ETextcolor] =		"textcolor",
 	[ETopline] =		"topline",
 	[EValue] =			"value",
+	[EWarp] =			"warp",
 	nil
 };
 
 static void	textshow(Text*);
 static void	texttogglei(Text*, int);
+static int	textline(Text*, Point);
 static int	texttoggle(Text*, Point);
 
 static void
@@ -98,12 +115,61 @@ textmouse(Control *c, Mouse *m)
 	int sel;
 
 	t = (Text*)c;
+	if (debug) fprint(2, "textmouse %s t->lastbut %d; m->buttons %d\n", t->name, t->lastbut, m->buttons);
+	if (t->warp >= 0)
+		return;
+	if ((t->selectstyle == Selup) && (m->buttons&7)) {
+		sel = textline(t, m->xy);
+		if (t->sel >= 0) {
+//			if (debug) fprint(2, "textmouse Selup %q sel=%d t->sel=%d t->but=%d\n",
+//						t->name, sel, t->sel, t->but);
+			t->offsel = (sel == t->sel) ? 0 : 1;
+			if ((sel == t->sel &&
+				    ((t->selected[t->sel] && !t->but) ||
+				     ((!t->selected[t->sel]) && t->but))) ||
+			    (sel != t->sel &&
+				     ((t->selected[t->sel] && t->but) ||
+                                         ((!t->selected[t->sel]) && (!t->but))))) {
+				texttogglei(t, t->sel);
+			}
+		}
+	}
 	if(t->lastbut != (m->buttons&7)){
 		if(m->buttons & 7){
 			sel = texttoggle(t, m->xy);
-			if(sel >= 0)
+			if(sel >= 0) {
+				if (t->selectstyle == Seldown) {
+					chanprint(t->event, "%q: select %d %d",
+						t->name, sel, t->selected[sel] ? (m->buttons & 7) : 0);
+					if (debug) fprint(2, "textmouse Seldown event %q: select %d %d\n",
+						t->name, sel, t->selected[sel] ? (m->buttons & 7) : 0);
+				} else {
+					if (debug) fprint(2, "textmouse Selup no event yet %q: select %d %d\n",
+						t->name, sel, t->selected[sel] ? (m->buttons & 7) : 0);
+					t->sel = sel;
+					t->but =  t->selected[sel] ? (m->buttons & 7) : 0;
+				}
+			}
+		} else if (t->selectstyle == Selup) {
+			sel = textline(t, m->xy);
+			t->offsel = 0;
+			if ((sel >= 0) && (sel == t->sel)) {
 				chanprint(t->event, "%q: select %d %d",
-					t->name, sel, t->selected[sel] ? (m->buttons & 7) : 0);
+					t->name, sel, t->but);
+				if (debug) fprint(2, "textmouse Selup event %q: select %d %d\n",
+					t->name, sel, t->but);
+			} else if (sel != t->sel) {
+				if  ((t->selected[t->sel] && t->but) ||
+                                         ((!t->selected[t->sel]) && (!t->but))) {
+					texttogglei(t, t->sel);
+				} else {
+					textshow(t);
+				}
+				if (debug) fprint(2, "textmouse Selup cancel %q: select %d %d\n",
+					t->name, sel, t->but);
+			}
+			t->sel = -1;
+			t->but = 0;
 		}
 		t->lastbut = m->buttons & 7;
 	}
@@ -121,6 +187,7 @@ textfree(Control *c)
 	_putctlimage(t->textcolor);
 	_putctlimage(t->bordercolor);
 	_putctlimage(t->selectcolor);
+	_putctlimage(t->selectingcolor);
 	for(i=0; i<t->nline; i++)
 		free(t->line[i]);
 	free(t->line);
@@ -151,11 +218,20 @@ textshow(Text *t)
 		text = t->line[i];
 		ntext = runestrlen(text);
 		r.max.y = r.min.y+f->height;
-		if(t->selected[i])
+		if(t->sel == i && t->offsel)
+			draw(t->screen, r, t->selectingcolor->image, nil, ZP);
+		else if(t->selected[i])
 			draw(t->screen, r, t->selectcolor->image, nil, ZP);
 		p = _ctlalignpoint(r,
 			runestringnwidth(f, text, ntext),
 			f->height, t->align);
+		if(t->warp == i) {
+			Point p2;
+			 p2.x = p.x + 0.5*runestringnwidth(f, text, ntext);
+			 p2.y = p.y + 0.5*f->height;
+			moveto(t->controlset->mousectl, p2);
+			t->warp = -1;
+		}
 		_string(t->screen, p, t->textcolor->image,
 			ZP, f, nil, text, ntext, tr,
 			nil, ZP, SoverD);
@@ -291,6 +367,13 @@ textctl(Control *c, CParse *cp)
 		else if(strncmp(cp->args[1], "multi", 5) == 0)
 			t->selectmode = Selmulti;
 		break;
+	case ESelectstyle:
+		_ctlargcount(t, cp, 2);
+		 if(strcmp(cp->args[1], "down") == 0)
+			t->selectstyle = Seldown;
+		else if(strcmp(cp->args[1], "up") == 0)
+			t->selectstyle = Selup;
+		break;
 	case EShow:
 		_ctlargcount(t, cp, 1);
 		textshow(t);
@@ -371,6 +454,14 @@ textctl(Control *c, CParse *cp)
 			if(t->scroll || t->nline<=t->topline+t->nvis)
 				textshow(t);
 		break;
+	case EWarp:
+		_ctlargcount(t, cp, 2);
+		if(cp->iargs[1]<0 || cp->iargs[1]>=t->nline)
+			ctlerror("%q: selection index out of range (nline %d): %s", t->name, t->nline, cp->str);
+		t->warp = cp->iargs[1];
+		textshow(t);
+		t->warp = -1;
+		break;
 	}
 }
 
@@ -390,7 +481,7 @@ texttogglei(Text *t, int i)
 }
 
 static int
-texttoggle(Text *t, Point p)
+textline(Text *t, Point p)
 {
 	Rectangle r;
 	int i;
@@ -404,7 +495,17 @@ texttoggle(Text *t, Point p)
 	i += t->topline;
 	if(i >= t->nline)
 		return -1;
-	texttogglei(t, i);
+	return i;
+}
+
+static int
+texttoggle(Text *t, Point p)
+{
+	int i;
+
+	i = textline(t, p);
+	if (i >= 0)
+		texttogglei(t, i);
 	return i;
 }
 
@@ -421,11 +522,17 @@ createtext(Controlset *cs, char *name)
 	t->textcolor = _getctlimage("black");
 	t->bordercolor = _getctlimage("black");
 	t->selectcolor = _getctlimage("yellow");
+	t->selectingcolor = _getctlimage("paleyellow");
 	t->font = _getctlfont("font");
 	t->selectmode = Selsingle;
+	t->selectstyle = Selup; // Seldown;
 	t->lastbut = 0;
 	t->mouse = textmouse;
 	t->ctl = textctl;
 	t->exit = textfree;
+	t->warp = -1;
+	t->sel = -1;
+	t->offsel = 0;
+	t->but = 0;
 	return (Control *)t;
 }

+ 43 - 4
sys/src/libcontrol/textbutton.c

@@ -18,6 +18,7 @@ struct Textbutton
 	CImage	*bordercolor;
 	CImage	*textcolor;
 	CImage	*pressedtextcolor;
+	CImage	*paletextcolor;
 	int		pressed;
 	int		lastbut;
 	int		lastshow;
@@ -25,6 +26,9 @@ struct Textbutton
 	int		nline;
 	int		align;
 	int		border;
+	int		off;
+	int		showoff;
+	int		prepress;
 };
 
 enum{
@@ -38,6 +42,7 @@ enum{
 	EImage,
 	ELight,
 	EMask,
+	EPaletextcolor,
 	EPressedtextcolor,
 	ERect,
 	EReveal,
@@ -59,6 +64,7 @@ static char *cmds[] = {
 	[EImage] =		"image",
 	[ELight] =			"light",
 	[EMask] =			"mask",
+	[EPaletextcolor] ="paletextcolor",
 	[EPressedtextcolor] ="pressedtextcolor",
 	[ERect] =			"rect",
 	[EReveal] =		"reveal",
@@ -78,15 +84,35 @@ textbuttonmouse(Control *c, Mouse *m)
 	Textbutton *t;
 
 	t = (Textbutton *)c;
+	if(m->buttons&7) {
+		if (ptinrect(m->xy,t->rect)) {
+			if (t->off) {
+				t->off = 0;
+				textbuttonshow(t);
+			}
+		} else {
+			if (!t->off) {
+				t->off = 1;
+				textbuttonshow(t);
+			}
+		}
+	}
 	if((m->buttons&7) != t->lastbut){
 		if(m->buttons & 7){
+			t->prepress = t->pressed;
 			if (t->pressed)
 				t->pressed = 0;
 			else
 				t->pressed = 1;
 			textbuttonshow(t);
 		}else{	/* generate event on button up */
-			chanprint(t->event, t->format, t->name, t->pressed);
+			if (ptinrect(m->xy,t->rect))
+				chanprint(t->event, t->format, t->name, t->pressed);
+			else {
+				t->off = 0;
+				t->pressed = t->prepress;
+				textbuttonshow(t);
+			}
 		}
 	}
 	t->lastbut = m->buttons & 7;
@@ -105,6 +131,7 @@ textbuttonfree(Control *c)
 	_putctlimage(t->mask);
 	_putctlimage(t->textcolor);
 	_putctlimage(t->bordercolor);
+	_putctlimage(t->paletextcolor);
 	_putctlimage(t->pressedtextcolor);
 	for(i=0; i<t->nline; i++)
 		free(t->line[i]);
@@ -120,7 +147,7 @@ textbuttonshow(Textbutton *t)
 	Point p, q;
 	Image *im;
 
-	if(t->hidden || t->lastshow == t->pressed)
+	if(t->hidden || (t->lastshow == t->pressed && t->showoff == t->off))
 		return;
 	f = t->font->font;
 	draw(t->screen, t->rect, t->image->image, nil, t->image->image->r.min);
@@ -137,7 +164,9 @@ textbuttonshow(Textbutton *t)
 	clipr = insetrect(t->rect, t->border);
 	p = _ctlalignpoint(clipr, dx, dy, t->align);
 	im = t->textcolor->image;
-	if(t->pressed)
+	if(t->off)
+		im = t->paletextcolor->image;
+	else if(t->pressed)
 		im = t->pressedtextcolor->image;
 	for(i=0; i<t->nline; i++){
 		r.min = p;
@@ -149,9 +178,10 @@ textbuttonshow(Textbutton *t)
 			clipr, nil, ZP, SoverD);
 		p.y += f->height;
 	}
-	if(t->pressed)
+	if(t->off || t->pressed)
 		draw(t->screen, t->rect, t->light->image, t->mask->image, t->mask->image->r.min);
 	t->lastshow = t->pressed;
+	t->showoff = t->off;
 	flushimage(display, 1);
 }
 
@@ -213,6 +243,11 @@ textbuttonctl(Control *c, CParse *cp)
 		_setctlimage(t, &t->mask, cp->args[1]);
 		t->lastshow = -1;	/* force redraw */
 		break;
+	case EPaletextcolor:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->paletextcolor, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
 	case EPressedtextcolor:
 		_ctlargcount(t, cp, 2);
 		_setctlimage(t, &t->pressedtextcolor, cp->args[1]);
@@ -295,11 +330,15 @@ createtextbutton(Controlset *cs, char *name)
 	t->bordercolor = _getctlimage("black");
 	t->textcolor = _getctlimage("black");
 	t->pressedtextcolor = _getctlimage("black");
+	t->paletextcolor = _getctlimage("paleyellow");
 	t->font = _getctlfont("font");
 	t->format = ctlstrdup("%q: value %d");
 	t->lastshow = -1;
 	t->mouse = textbuttonmouse;
 	t->ctl = textbuttonctl;
 	t->exit = textbuttonfree;
+	t->prepress = 0;
+	t->off = 0;
+	t->showoff = -1;
 	return (Control *)t;
 }

+ 393 - 0
sys/src/libcontrol/textbutton3.c

@@ -0,0 +1,393 @@
+/* use button 3 for a proper function to the application, that is not for plumber
+ *  as default control(2) supposes.
+ *  codes are mostly from /sys/src/libcontrol/textbutton.c
+ */
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <control.h>
+
+typedef struct Textbutton3 Textbutton3;
+
+struct Textbutton3
+{
+	Control;
+	CFont	*font;
+	CImage	*image;
+	CImage	*mask;
+	CImage	*light;
+	CImage	*bordercolor;
+	CImage	*textcolor;
+	CImage	*pressedtextcolor;
+	int		pressed;
+	int		lastbut;
+	int		lastshow;
+	char		**line;
+	int		nline;
+	int		align;
+	int		border;
+	int		left;
+	int		middle;
+	int		right;
+	int		toggle;
+	int		gettextflg;
+};
+
+enum{
+	EAlign,
+	EBorder,
+	EBordercolor,
+	EFocus,
+	EFont,
+	EFormat,
+	EHide,
+	EImage,
+	ELight,
+	EMask,
+	EPressedtextcolor,
+	ERect,
+	EReveal,
+	EShow,
+	ESize,
+	EText,
+	ETextcolor,
+	EEnable,
+	EDisable,
+	EToggle,
+	EGettext,
+	EValue,
+};
+
+static char *cmds[] = {
+	[EAlign] =			"align",
+	[EBorder] =		"border",
+	[EBordercolor] = 	"bordercolor",
+	[EFocus] = 		"focus",
+	[EFont] =			"font",
+	[EFormat] = 		"format",
+	[EHide] =			"hide",
+	[EImage] =		"image",
+	[ELight] =			"light",
+	[EMask] =			"mask",
+	[EPressedtextcolor] ="pressedtextcolor",
+	[ERect] =			"rect",
+	[EReveal] =		"reveal",
+	[EShow] =			"show",
+	[ESize] =			"size",
+	[EText] =			"text",
+	[ETextcolor] =		"textcolor",
+	[EEnable] =		"enable",
+	[EDisable] =		"disable",
+	[EToggle] =		"toggle",
+	[EGettext] =		"gettext",
+	[EValue] =			"value",
+	nil
+};
+
+static void	textbutton3show(Textbutton3 *);
+
+static void
+textbutton3mouse(Control *c, Mouse *m)
+{
+	Textbutton3 *t;
+
+	t = (Textbutton3 *)c;
+	if(t->left == 1) {
+		if((m->buttons&1) == 1 && (t->lastbut&1) == 0){
+			t->pressed ^= 1;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 1;
+		}else if((m->buttons&1) == 0 && (t->lastbut&1) == 1){
+			if(t->gettextflg == 0)
+				chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
+			else
+				chanprint(t->event, "%q: value %q", t->name, t->line[0]);
+			t->pressed ^= 1;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 1;
+		}
+	}
+	if(t->middle == 1) {
+		if((m->buttons&2) == 2 && (t->lastbut&2) == 0){
+			t->pressed ^= 2;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 2;
+		}else if((m->buttons&2) == 0 && (t->lastbut&2) == 2){
+			if(t->gettextflg == 0)
+				chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
+			else
+				chanprint(t->event, "%q: value %q", t->name, t->line[0]);
+			t->pressed ^= 2;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 2;
+		}
+	}
+	if(t->right == 1) {
+		if((m->buttons&4) == 4 && (t->lastbut&4) == 0){
+			t->pressed ^= 4;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 4;
+		}else if((m->buttons&4) == 0 && (t->lastbut&4) == 4){
+			if(t->gettextflg == 0)
+				chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
+			else
+				chanprint(t->event, "%q: value %q", t->name, t->line[0]);
+			t->pressed ^= 4;
+			textbutton3show(t);
+			t->lastbut = m->buttons & 4;
+		}
+	}
+}
+
+static void
+textbutton3free(Control *c)
+{
+	int i;
+	Textbutton3 *t;
+
+	t = (Textbutton3*)c;
+	_putctlfont(t->font);
+	_putctlimage(t->image);
+	_putctlimage(t->light);
+	_putctlimage(t->mask);
+	_putctlimage(t->textcolor);
+	_putctlimage(t->bordercolor);
+	_putctlimage(t->pressedtextcolor);
+	for(i=0; i<t->nline; i++)
+		free(t->line[i]);
+	free(t->line);
+}
+
+static void
+textbutton3show(Textbutton3 *t)
+{
+	Rectangle r, clipr;
+	int i, dx, dy, w;
+	Font *f;
+	Point p, q;
+	Image *im;
+
+	if(t->hidden || t->lastshow == t->pressed)
+		return;
+	f = t->font->font;
+	draw(t->screen, t->rect, t->image->image, nil, t->image->image->r.min);
+	if(t->pressed || t->toggle)
+		draw(t->screen, t->rect, t->light->image, t->mask->image, t->mask->image->r.min);
+	if(t->border > 0)
+		border(t->screen, t->rect, t->border, t->bordercolor->image, ZP);
+	/* text goes here */
+	dx = 0;
+	for(i=0; i<t->nline; i++){
+		w = stringwidth(f, t->line[i]);		/*****/
+		if(dx < w)
+			dx = w;
+	}
+	dy = t->nline*f->height;
+	clipr = insetrect(t->rect, t->border);
+	p = _ctlalignpoint(clipr, dx, dy, t->align);
+	im = t->textcolor->image;
+	if(t->pressed)
+		im = t->pressedtextcolor->image;
+	for(i=0; i<t->nline; i++){
+		r.min = p;
+		r.max.x = p.x+dx;
+		r.max.y = p.y+f->height;
+		q = _ctlalignpoint(r, stringwidth(f, t->line[i]), f->height, t->align%3);
+		_string(t->screen, q, im,
+			ZP, f, t->line[i], nil, strlen(t->line[i]),
+			clipr, nil, ZP, SoverD);
+		p.y += f->height;
+	}
+	t->lastshow = t->pressed;
+	flushimage(display, 1);
+}
+
+static void
+textbutton3ctl(Control *c, CParse *cp)
+{
+	int cmd, i;
+	Rectangle r;
+	Textbutton3 *t;
+
+	t = (Textbutton3*)c;
+	cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
+	switch(cmd){
+	default:
+		ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
+		break;
+	case EAlign:
+		_ctlargcount(t, cp, 2);
+		t->align = _ctlalignment(cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EBorder:
+		_ctlargcount(t, cp, 2);
+		t->border = cp->iargs[1];
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EBordercolor:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->bordercolor, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EFocus:
+		break;
+	case EFont:
+		_ctlargcount(t, cp, 2);
+		_setctlfont(t, &t->font, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EFormat:
+		_ctlargcount(t, cp, 2);
+		t->format = ctlstrdup(cp->args[1]);
+		break;
+	case EHide:
+		_ctlargcount(t, cp, 1);
+		t->hidden = 1;
+		break;
+	case EImage:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->image, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case ELight:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->light, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EMask:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->mask, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EPressedtextcolor:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->pressedtextcolor, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case ERect:
+		_ctlargcount(t, cp, 5);
+		r.min.x = cp->iargs[1];
+		r.min.y = cp->iargs[2];
+		r.max.x = cp->iargs[3];
+		r.max.y = cp->iargs[4];
+		if(Dx(r)<=0 || Dy(r)<=0)
+			ctlerror("%q: bad rectangle: %s", t->name, cp->str);
+		t->rect = r;
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EReveal:
+		_ctlargcount(t, cp, 1);
+		t->hidden = 0;
+		t->lastshow = -1;	/* force redraw */
+		textbutton3show(t);
+		break;
+	case EShow:
+		_ctlargcount(t, cp, 1);
+		t->lastshow = -1;	/* force redraw */
+		textbutton3show(t);
+		break;
+	case ESize:
+		if (cp->nargs == 3)
+			r.max = Pt(0x7fffffff, 0x7fffffff);
+		else{
+			_ctlargcount(t, cp, 5);
+			r.max.x = cp->iargs[3];
+			r.max.y = cp->iargs[4];
+		}
+		r.min.x = cp->iargs[1];
+		r.min.y = cp->iargs[2];
+		if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
+			ctlerror("%q: bad sizes: %s", t->name, cp->str);
+		t->size.min = r.min;
+		t->size.max = r.max;
+		break;
+	case EText:
+		/* free existing text */
+		for(i=0; i<t->nline; i++)
+			free(t->line[i]);
+		t->nline = cp->nargs-1;
+		t->line = ctlrealloc(t->line, t->nline*sizeof(char*));
+		for(i=0; i<t->nline; i++)
+			t->line[i] = ctlstrdup(cp->args[i+1]);
+		t->lastshow = -1;	/* force redraw */
+		textbutton3show(t);
+		break;
+	case ETextcolor:
+		_ctlargcount(t, cp, 2);
+		_setctlimage(t, &t->textcolor, cp->args[1]);
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EEnable:
+		_ctlargcount(t, cp, 2);
+		if(strcmp(cp->args[1], "left") == 0)
+				t->left = 1;
+		else if(strcmp(cp->args[1], "middle") == 0)
+				t->middle = 1;
+		else if(strcmp(cp->args[1], "right") == 0)
+				t->right = 1;
+		break;
+	case EDisable:
+		_ctlargcount(t, cp, 2);
+		if(strcmp(cp->args[1], "left") == 0)
+			t->left = 0;
+		else if(strcmp(cp->args[1], "middle") == 0)
+			t->middle = 0;
+		else if(strcmp(cp->args[1], "right") == 0)
+			t->right = 0;
+		break;
+	case EToggle:
+		_ctlargcount(t, cp, 2);
+		if(strcmp(cp->args[1], "on") == 0)
+			t->toggle = 1;
+		else if(strcmp(cp->args[1], "off") == 0)
+			t->toggle = 0;
+		t->lastshow = -1;	/* force redraw */
+		break;
+	case EGettext:
+		_ctlargcount(t, cp, 2);
+		if(strcmp(cp->args[1], "on") == 0)
+			t->gettextflg = 1;
+		else if(strcmp(cp->args[1], "off") == 0)
+			t->gettextflg = 0;
+		break;
+	case EValue:
+		_ctlargcount(t, cp, 2);
+		if((cp->iargs[1]!=0) != t->pressed){
+			t->pressed ^= 1;
+			textbutton3show(t);
+		}
+		break;
+	}
+}
+
+Control*
+createtextbutton3(Controlset *cs, char *name)
+{
+	Textbutton3 *t;
+
+	t = (Textbutton3 *)_createctl(cs, "textbutton3", sizeof(Textbutton3), name);
+	t->line = ctlmalloc(sizeof(char*));
+	t->nline = 0;
+	t->image = _getctlimage("white");
+	t->light = _getctlimage("yellow");
+	t->mask = _getctlimage("opaque");
+	t->bordercolor = _getctlimage("black");
+	t->textcolor = _getctlimage("black");
+	t->pressedtextcolor = _getctlimage("black");
+	t->font = _getctlfont("font");
+	t->format = ctlstrdup("%q: value %d %d %d");
+	t->lastshow = -1;
+	t->mouse = textbutton3mouse;
+	t->ctl = textbutton3ctl;
+	t->exit = textbutton3free;
+	t->left = 1;
+	t->middle = 1;
+	t->right = 1;
+	t->toggle = 0;
+	t->gettextflg = 0;
+	return (Control *)t;
+}