tk_as_gem 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (345) hide show
  1. data/README +22 -0
  2. data/Rakefile +11 -0
  3. data/VERSION +1 -0
  4. data/ext/ChangeLog.tkextlib +935 -0
  5. data/ext/MANUAL_tcltklib.eng +469 -0
  6. data/ext/MANUAL_tcltklib.eucj +579 -0
  7. data/ext/README.1st +19 -0
  8. data/ext/README.ActiveTcl +49 -0
  9. data/ext/README.fork +34 -0
  10. data/ext/README.macosx-aqua +67 -0
  11. data/ext/README.tcltklib +85 -0
  12. data/ext/depend +2 -0
  13. data/ext/extconf.rb +451 -0
  14. data/ext/lib/README +30 -0
  15. data/ext/lib/multi-tk.rb +3491 -0
  16. data/ext/lib/remote-tk.rb +530 -0
  17. data/ext/lib/tcltk.rb +367 -0
  18. data/ext/lib/tk.rb +5584 -0
  19. data/ext/lib/tk/after.rb +6 -0
  20. data/ext/lib/tk/autoload.rb +414 -0
  21. data/ext/lib/tk/bgerror.rb +29 -0
  22. data/ext/lib/tk/bindtag.rb +138 -0
  23. data/ext/lib/tk/button.rb +30 -0
  24. data/ext/lib/tk/canvas.rb +789 -0
  25. data/ext/lib/tk/canvastag.rb +434 -0
  26. data/ext/lib/tk/checkbutton.rb +30 -0
  27. data/ext/lib/tk/clipboard.rb +75 -0
  28. data/ext/lib/tk/clock.rb +71 -0
  29. data/ext/lib/tk/composite.rb +458 -0
  30. data/ext/lib/tk/console.rb +52 -0
  31. data/ext/lib/tk/dialog.rb +326 -0
  32. data/ext/lib/tk/encodedstr.rb +187 -0
  33. data/ext/lib/tk/entry.rb +119 -0
  34. data/ext/lib/tk/event.rb +542 -0
  35. data/ext/lib/tk/font.rb +2344 -0
  36. data/ext/lib/tk/frame.rb +131 -0
  37. data/ext/lib/tk/grid.rb +279 -0
  38. data/ext/lib/tk/image.rb +275 -0
  39. data/ext/lib/tk/itemconfig.rb +1215 -0
  40. data/ext/lib/tk/itemfont.rb +327 -0
  41. data/ext/lib/tk/kinput.rb +71 -0
  42. data/ext/lib/tk/label.rb +21 -0
  43. data/ext/lib/tk/labelframe.rb +29 -0
  44. data/ext/lib/tk/listbox.rb +282 -0
  45. data/ext/lib/tk/macpkg.rb +78 -0
  46. data/ext/lib/tk/menu.rb +681 -0
  47. data/ext/lib/tk/menubar.rb +131 -0
  48. data/ext/lib/tk/menuspec.rb +275 -0
  49. data/ext/lib/tk/message.rb +22 -0
  50. data/ext/lib/tk/mngfocus.rb +33 -0
  51. data/ext/lib/tk/msgcat.rb +296 -0
  52. data/ext/lib/tk/namespace.rb +551 -0
  53. data/ext/lib/tk/optiondb.rb +377 -0
  54. data/ext/lib/tk/optionobj.rb +212 -0
  55. data/ext/lib/tk/pack.rb +107 -0
  56. data/ext/lib/tk/package.rb +143 -0
  57. data/ext/lib/tk/palette.rb +55 -0
  58. data/ext/lib/tk/panedwindow.rb +258 -0
  59. data/ext/lib/tk/place.rb +128 -0
  60. data/ext/lib/tk/radiobutton.rb +71 -0
  61. data/ext/lib/tk/root.rb +95 -0
  62. data/ext/lib/tk/scale.rb +111 -0
  63. data/ext/lib/tk/scrollable.rb +82 -0
  64. data/ext/lib/tk/scrollbar.rb +177 -0
  65. data/ext/lib/tk/scrollbox.rb +39 -0
  66. data/ext/lib/tk/selection.rb +86 -0
  67. data/ext/lib/tk/spinbox.rb +119 -0
  68. data/ext/lib/tk/tagfont.rb +43 -0
  69. data/ext/lib/tk/text.rb +1596 -0
  70. data/ext/lib/tk/textimage.rb +88 -0
  71. data/ext/lib/tk/textmark.rb +204 -0
  72. data/ext/lib/tk/texttag.rb +318 -0
  73. data/ext/lib/tk/textwindow.rb +154 -0
  74. data/ext/lib/tk/timer.rb +669 -0
  75. data/ext/lib/tk/toplevel.rb +262 -0
  76. data/ext/lib/tk/ttk_selector.rb +76 -0
  77. data/ext/lib/tk/txtwin_abst.rb +39 -0
  78. data/ext/lib/tk/validation.rb +397 -0
  79. data/ext/lib/tk/variable.rb +1765 -0
  80. data/ext/lib/tk/virtevent.rb +139 -0
  81. data/ext/lib/tk/winfo.rb +392 -0
  82. data/ext/lib/tk/winpkg.rb +153 -0
  83. data/ext/lib/tk/wm.rb +552 -0
  84. data/ext/lib/tk/xim.rb +122 -0
  85. data/ext/lib/tkafter.rb +4 -0
  86. data/ext/lib/tkbgerror.rb +4 -0
  87. data/ext/lib/tkcanvas.rb +4 -0
  88. data/ext/lib/tkclass.rb +47 -0
  89. data/ext/lib/tkconsole.rb +4 -0
  90. data/ext/lib/tkdialog.rb +4 -0
  91. data/ext/lib/tkentry.rb +4 -0
  92. data/ext/lib/tkextlib/ICONS.rb +13 -0
  93. data/ext/lib/tkextlib/ICONS/icons.rb +129 -0
  94. data/ext/lib/tkextlib/ICONS/setup.rb +8 -0
  95. data/ext/lib/tkextlib/SUPPORT_STATUS +196 -0
  96. data/ext/lib/tkextlib/blt.rb +187 -0
  97. data/ext/lib/tkextlib/blt/barchart.rb +79 -0
  98. data/ext/lib/tkextlib/blt/bitmap.rb +112 -0
  99. data/ext/lib/tkextlib/blt/busy.rb +82 -0
  100. data/ext/lib/tkextlib/blt/component.rb +2145 -0
  101. data/ext/lib/tkextlib/blt/container.rb +28 -0
  102. data/ext/lib/tkextlib/blt/cutbuffer.rb +23 -0
  103. data/ext/lib/tkextlib/blt/dragdrop.rb +268 -0
  104. data/ext/lib/tkextlib/blt/eps.rb +32 -0
  105. data/ext/lib/tkextlib/blt/graph.rb +67 -0
  106. data/ext/lib/tkextlib/blt/htext.rb +111 -0
  107. data/ext/lib/tkextlib/blt/setup.rb +8 -0
  108. data/ext/lib/tkextlib/blt/spline.rb +23 -0
  109. data/ext/lib/tkextlib/blt/stripchart.rb +74 -0
  110. data/ext/lib/tkextlib/blt/table.rb +399 -0
  111. data/ext/lib/tkextlib/blt/tabnotebook.rb +110 -0
  112. data/ext/lib/tkextlib/blt/tabset.rb +500 -0
  113. data/ext/lib/tkextlib/blt/ted.rb +65 -0
  114. data/ext/lib/tkextlib/blt/tile.rb +21 -0
  115. data/ext/lib/tkextlib/blt/tile/button.rb +16 -0
  116. data/ext/lib/tkextlib/blt/tile/checkbutton.rb +17 -0
  117. data/ext/lib/tkextlib/blt/tile/frame.rb +16 -0
  118. data/ext/lib/tkextlib/blt/tile/label.rb +16 -0
  119. data/ext/lib/tkextlib/blt/tile/radiobutton.rb +17 -0
  120. data/ext/lib/tkextlib/blt/tile/scrollbar.rb +16 -0
  121. data/ext/lib/tkextlib/blt/tile/toplevel.rb +16 -0
  122. data/ext/lib/tkextlib/blt/tree.rb +1058 -0
  123. data/ext/lib/tkextlib/blt/treeview.rb +1272 -0
  124. data/ext/lib/tkextlib/blt/unix_dnd.rb +135 -0
  125. data/ext/lib/tkextlib/blt/vector.rb +256 -0
  126. data/ext/lib/tkextlib/blt/watch.rb +175 -0
  127. data/ext/lib/tkextlib/blt/win_printer.rb +61 -0
  128. data/ext/lib/tkextlib/blt/winop.rb +107 -0
  129. data/ext/lib/tkextlib/bwidget.rb +151 -0
  130. data/ext/lib/tkextlib/bwidget/arrowbutton.rb +21 -0
  131. data/ext/lib/tkextlib/bwidget/bitmap.rb +21 -0
  132. data/ext/lib/tkextlib/bwidget/button.rb +31 -0
  133. data/ext/lib/tkextlib/bwidget/buttonbox.rb +90 -0
  134. data/ext/lib/tkextlib/bwidget/combobox.rb +51 -0
  135. data/ext/lib/tkextlib/bwidget/dialog.rb +182 -0
  136. data/ext/lib/tkextlib/bwidget/dragsite.rb +31 -0
  137. data/ext/lib/tkextlib/bwidget/dropsite.rb +39 -0
  138. data/ext/lib/tkextlib/bwidget/dynamichelp.rb +63 -0
  139. data/ext/lib/tkextlib/bwidget/entry.rb +43 -0
  140. data/ext/lib/tkextlib/bwidget/label.rb +41 -0
  141. data/ext/lib/tkextlib/bwidget/labelentry.rb +80 -0
  142. data/ext/lib/tkextlib/bwidget/labelframe.rb +52 -0
  143. data/ext/lib/tkextlib/bwidget/listbox.rb +358 -0
  144. data/ext/lib/tkextlib/bwidget/mainframe.rb +128 -0
  145. data/ext/lib/tkextlib/bwidget/messagedlg.rb +192 -0
  146. data/ext/lib/tkextlib/bwidget/notebook.rb +166 -0
  147. data/ext/lib/tkextlib/bwidget/pagesmanager.rb +73 -0
  148. data/ext/lib/tkextlib/bwidget/panedwindow.rb +37 -0
  149. data/ext/lib/tkextlib/bwidget/panelframe.rb +57 -0
  150. data/ext/lib/tkextlib/bwidget/passwddlg.rb +44 -0
  151. data/ext/lib/tkextlib/bwidget/progressbar.rb +20 -0
  152. data/ext/lib/tkextlib/bwidget/progressdlg.rb +58 -0
  153. data/ext/lib/tkextlib/bwidget/scrollableframe.rb +40 -0
  154. data/ext/lib/tkextlib/bwidget/scrolledwindow.rb +38 -0
  155. data/ext/lib/tkextlib/bwidget/scrollview.rb +25 -0
  156. data/ext/lib/tkextlib/bwidget/selectcolor.rb +73 -0
  157. data/ext/lib/tkextlib/bwidget/selectfont.rb +86 -0
  158. data/ext/lib/tkextlib/bwidget/separator.rb +20 -0
  159. data/ext/lib/tkextlib/bwidget/setup.rb +8 -0
  160. data/ext/lib/tkextlib/bwidget/spinbox.rb +98 -0
  161. data/ext/lib/tkextlib/bwidget/statusbar.rb +52 -0
  162. data/ext/lib/tkextlib/bwidget/titleframe.rb +33 -0
  163. data/ext/lib/tkextlib/bwidget/tree.rb +453 -0
  164. data/ext/lib/tkextlib/bwidget/widget.rb +129 -0
  165. data/ext/lib/tkextlib/itcl.rb +13 -0
  166. data/ext/lib/tkextlib/itcl/incr_tcl.rb +178 -0
  167. data/ext/lib/tkextlib/itcl/setup.rb +13 -0
  168. data/ext/lib/tkextlib/itk.rb +13 -0
  169. data/ext/lib/tkextlib/itk/incr_tk.rb +446 -0
  170. data/ext/lib/tkextlib/itk/setup.rb +13 -0
  171. data/ext/lib/tkextlib/iwidgets.rb +94 -0
  172. data/ext/lib/tkextlib/iwidgets/buttonbox.rb +120 -0
  173. data/ext/lib/tkextlib/iwidgets/calendar.rb +125 -0
  174. data/ext/lib/tkextlib/iwidgets/canvasprintbox.rb +53 -0
  175. data/ext/lib/tkextlib/iwidgets/canvasprintdialog.rb +38 -0
  176. data/ext/lib/tkextlib/iwidgets/checkbox.rb +129 -0
  177. data/ext/lib/tkextlib/iwidgets/combobox.rb +104 -0
  178. data/ext/lib/tkextlib/iwidgets/dateentry.rb +20 -0
  179. data/ext/lib/tkextlib/iwidgets/datefield.rb +58 -0
  180. data/ext/lib/tkextlib/iwidgets/dialog.rb +20 -0
  181. data/ext/lib/tkextlib/iwidgets/dialogshell.rb +120 -0
  182. data/ext/lib/tkextlib/iwidgets/disjointlistbox.rb +50 -0
  183. data/ext/lib/tkextlib/iwidgets/entryfield.rb +185 -0
  184. data/ext/lib/tkextlib/iwidgets/extbutton.rb +40 -0
  185. data/ext/lib/tkextlib/iwidgets/extfileselectionbox.rb +46 -0
  186. data/ext/lib/tkextlib/iwidgets/extfileselectiondialog.rb +33 -0
  187. data/ext/lib/tkextlib/iwidgets/feedback.rb +35 -0
  188. data/ext/lib/tkextlib/iwidgets/fileselectionbox.rb +46 -0
  189. data/ext/lib/tkextlib/iwidgets/fileselectiondialog.rb +33 -0
  190. data/ext/lib/tkextlib/iwidgets/finddialog.rb +42 -0
  191. data/ext/lib/tkextlib/iwidgets/hierarchy.rb +365 -0
  192. data/ext/lib/tkextlib/iwidgets/hyperhelp.rb +50 -0
  193. data/ext/lib/tkextlib/iwidgets/labeledframe.rb +39 -0
  194. data/ext/lib/tkextlib/iwidgets/labeledwidget.rb +45 -0
  195. data/ext/lib/tkextlib/iwidgets/mainwindow.rb +67 -0
  196. data/ext/lib/tkextlib/iwidgets/menubar.rb +211 -0
  197. data/ext/lib/tkextlib/iwidgets/messagebox.rb +92 -0
  198. data/ext/lib/tkextlib/iwidgets/messagedialog.rb +20 -0
  199. data/ext/lib/tkextlib/iwidgets/notebook.rb +174 -0
  200. data/ext/lib/tkextlib/iwidgets/optionmenu.rb +92 -0
  201. data/ext/lib/tkextlib/iwidgets/panedwindow.rb +133 -0
  202. data/ext/lib/tkextlib/iwidgets/promptdialog.rb +131 -0
  203. data/ext/lib/tkextlib/iwidgets/pushbutton.rb +35 -0
  204. data/ext/lib/tkextlib/iwidgets/radiobox.rb +120 -0
  205. data/ext/lib/tkextlib/iwidgets/scopedobject.rb +24 -0
  206. data/ext/lib/tkextlib/iwidgets/scrolledcanvas.rb +353 -0
  207. data/ext/lib/tkextlib/iwidgets/scrolledframe.rb +59 -0
  208. data/ext/lib/tkextlib/iwidgets/scrolledhtml.rb +58 -0
  209. data/ext/lib/tkextlib/iwidgets/scrolledlistbox.rb +207 -0
  210. data/ext/lib/tkextlib/iwidgets/scrolledtext.rb +564 -0
  211. data/ext/lib/tkextlib/iwidgets/scrolledwidget.rb +20 -0
  212. data/ext/lib/tkextlib/iwidgets/selectionbox.rb +102 -0
  213. data/ext/lib/tkextlib/iwidgets/selectiondialog.rb +92 -0
  214. data/ext/lib/tkextlib/iwidgets/setup.rb +8 -0
  215. data/ext/lib/tkextlib/iwidgets/shell.rb +38 -0
  216. data/ext/lib/tkextlib/iwidgets/spindate.rb +48 -0
  217. data/ext/lib/tkextlib/iwidgets/spinint.rb +30 -0
  218. data/ext/lib/tkextlib/iwidgets/spinner.rb +169 -0
  219. data/ext/lib/tkextlib/iwidgets/spintime.rb +48 -0
  220. data/ext/lib/tkextlib/iwidgets/tabnotebook.rb +180 -0
  221. data/ext/lib/tkextlib/iwidgets/tabset.rb +144 -0
  222. data/ext/lib/tkextlib/iwidgets/timeentry.rb +25 -0
  223. data/ext/lib/tkextlib/iwidgets/timefield.rb +58 -0
  224. data/ext/lib/tkextlib/iwidgets/toolbar.rb +112 -0
  225. data/ext/lib/tkextlib/iwidgets/watch.rb +56 -0
  226. data/ext/lib/tkextlib/pkg_checker.rb +184 -0
  227. data/ext/lib/tkextlib/setup.rb +8 -0
  228. data/ext/lib/tkextlib/tcllib.rb +90 -0
  229. data/ext/lib/tkextlib/tcllib/README +135 -0
  230. data/ext/lib/tkextlib/tcllib/autoscroll.rb +158 -0
  231. data/ext/lib/tkextlib/tcllib/ctext.rb +160 -0
  232. data/ext/lib/tkextlib/tcllib/cursor.rb +97 -0
  233. data/ext/lib/tkextlib/tcllib/datefield.rb +57 -0
  234. data/ext/lib/tkextlib/tcllib/dialog.rb +84 -0
  235. data/ext/lib/tkextlib/tcllib/getstring.rb +134 -0
  236. data/ext/lib/tkextlib/tcllib/history.rb +73 -0
  237. data/ext/lib/tkextlib/tcllib/ico.rb +116 -0
  238. data/ext/lib/tkextlib/tcllib/ip_entry.rb +66 -0
  239. data/ext/lib/tkextlib/tcllib/panelframe.rb +72 -0
  240. data/ext/lib/tkextlib/tcllib/plotchart.rb +886 -0
  241. data/ext/lib/tkextlib/tcllib/ruler.rb +65 -0
  242. data/ext/lib/tkextlib/tcllib/screenruler.rb +68 -0
  243. data/ext/lib/tkextlib/tcllib/scrollwin.rb +61 -0
  244. data/ext/lib/tkextlib/tcllib/setup.rb +8 -0
  245. data/ext/lib/tkextlib/tcllib/style.rb +61 -0
  246. data/ext/lib/tkextlib/tcllib/superframe.rb +51 -0
  247. data/ext/lib/tkextlib/tcllib/swaplist.rb +150 -0
  248. data/ext/lib/tkextlib/tcllib/tablelist.rb +27 -0
  249. data/ext/lib/tkextlib/tcllib/tablelist_core.rb +782 -0
  250. data/ext/lib/tkextlib/tcllib/tablelist_tile.rb +25 -0
  251. data/ext/lib/tkextlib/tcllib/tkpiechart.rb +314 -0
  252. data/ext/lib/tkextlib/tcllib/tooltip.rb +95 -0
  253. data/ext/lib/tkextlib/tcllib/widget.rb +48 -0
  254. data/ext/lib/tkextlib/tclx.rb +13 -0
  255. data/ext/lib/tkextlib/tclx/setup.rb +8 -0
  256. data/ext/lib/tkextlib/tclx/tclx.rb +74 -0
  257. data/ext/lib/tkextlib/tile.rb +419 -0
  258. data/ext/lib/tkextlib/tile/dialog.rb +96 -0
  259. data/ext/lib/tkextlib/tile/setup.rb +8 -0
  260. data/ext/lib/tkextlib/tile/sizegrip.rb +29 -0
  261. data/ext/lib/tkextlib/tile/style.rb +316 -0
  262. data/ext/lib/tkextlib/tile/tbutton.rb +33 -0
  263. data/ext/lib/tkextlib/tile/tcheckbutton.rb +36 -0
  264. data/ext/lib/tkextlib/tile/tcombobox.rb +54 -0
  265. data/ext/lib/tkextlib/tile/tentry.rb +48 -0
  266. data/ext/lib/tkextlib/tile/tframe.rb +33 -0
  267. data/ext/lib/tkextlib/tile/tlabel.rb +33 -0
  268. data/ext/lib/tkextlib/tile/tlabelframe.rb +36 -0
  269. data/ext/lib/tkextlib/tile/tmenubutton.rb +36 -0
  270. data/ext/lib/tkextlib/tile/tnotebook.rb +139 -0
  271. data/ext/lib/tkextlib/tile/tpaned.rb +231 -0
  272. data/ext/lib/tkextlib/tile/tprogressbar.rb +56 -0
  273. data/ext/lib/tkextlib/tile/tradiobutton.rb +36 -0
  274. data/ext/lib/tkextlib/tile/treeview.rb +1239 -0
  275. data/ext/lib/tkextlib/tile/tscale.rb +53 -0
  276. data/ext/lib/tkextlib/tile/tscrollbar.rb +54 -0
  277. data/ext/lib/tkextlib/tile/tseparator.rb +33 -0
  278. data/ext/lib/tkextlib/tile/tsquare.rb +30 -0
  279. data/ext/lib/tkextlib/tkDND.rb +18 -0
  280. data/ext/lib/tkextlib/tkDND/setup.rb +8 -0
  281. data/ext/lib/tkextlib/tkDND/shape.rb +125 -0
  282. data/ext/lib/tkextlib/tkDND/tkdnd.rb +182 -0
  283. data/ext/lib/tkextlib/tkHTML.rb +13 -0
  284. data/ext/lib/tkextlib/tkHTML/htmlwidget.rb +453 -0
  285. data/ext/lib/tkextlib/tkHTML/setup.rb +8 -0
  286. data/ext/lib/tkextlib/tkimg.rb +36 -0
  287. data/ext/lib/tkextlib/tkimg/README +26 -0
  288. data/ext/lib/tkextlib/tkimg/bmp.rb +33 -0
  289. data/ext/lib/tkextlib/tkimg/gif.rb +33 -0
  290. data/ext/lib/tkextlib/tkimg/ico.rb +33 -0
  291. data/ext/lib/tkextlib/tkimg/jpeg.rb +33 -0
  292. data/ext/lib/tkextlib/tkimg/pcx.rb +33 -0
  293. data/ext/lib/tkextlib/tkimg/pixmap.rb +44 -0
  294. data/ext/lib/tkextlib/tkimg/png.rb +33 -0
  295. data/ext/lib/tkextlib/tkimg/ppm.rb +33 -0
  296. data/ext/lib/tkextlib/tkimg/ps.rb +33 -0
  297. data/ext/lib/tkextlib/tkimg/setup.rb +8 -0
  298. data/ext/lib/tkextlib/tkimg/sgi.rb +33 -0
  299. data/ext/lib/tkextlib/tkimg/sun.rb +33 -0
  300. data/ext/lib/tkextlib/tkimg/tga.rb +33 -0
  301. data/ext/lib/tkextlib/tkimg/tiff.rb +33 -0
  302. data/ext/lib/tkextlib/tkimg/window.rb +33 -0
  303. data/ext/lib/tkextlib/tkimg/xbm.rb +33 -0
  304. data/ext/lib/tkextlib/tkimg/xpm.rb +33 -0
  305. data/ext/lib/tkextlib/tktable.rb +14 -0
  306. data/ext/lib/tkextlib/tktable/setup.rb +8 -0
  307. data/ext/lib/tkextlib/tktable/tktable.rb +957 -0
  308. data/ext/lib/tkextlib/tktrans.rb +14 -0
  309. data/ext/lib/tkextlib/tktrans/setup.rb +8 -0
  310. data/ext/lib/tkextlib/tktrans/tktrans.rb +64 -0
  311. data/ext/lib/tkextlib/treectrl.rb +13 -0
  312. data/ext/lib/tkextlib/treectrl/setup.rb +8 -0
  313. data/ext/lib/tkextlib/treectrl/tktreectrl.rb +2461 -0
  314. data/ext/lib/tkextlib/trofs.rb +13 -0
  315. data/ext/lib/tkextlib/trofs/setup.rb +8 -0
  316. data/ext/lib/tkextlib/trofs/trofs.rb +51 -0
  317. data/ext/lib/tkextlib/version.rb +6 -0
  318. data/ext/lib/tkextlib/vu.rb +48 -0
  319. data/ext/lib/tkextlib/vu/bargraph.rb +61 -0
  320. data/ext/lib/tkextlib/vu/charts.rb +53 -0
  321. data/ext/lib/tkextlib/vu/dial.rb +102 -0
  322. data/ext/lib/tkextlib/vu/pie.rb +282 -0
  323. data/ext/lib/tkextlib/vu/setup.rb +8 -0
  324. data/ext/lib/tkextlib/vu/spinbox.rb +22 -0
  325. data/ext/lib/tkextlib/winico.rb +14 -0
  326. data/ext/lib/tkextlib/winico/setup.rb +8 -0
  327. data/ext/lib/tkextlib/winico/winico.rb +224 -0
  328. data/ext/lib/tkfont.rb +4 -0
  329. data/ext/lib/tkmacpkg.rb +4 -0
  330. data/ext/lib/tkmenubar.rb +4 -0
  331. data/ext/lib/tkmngfocus.rb +4 -0
  332. data/ext/lib/tkpalette.rb +4 -0
  333. data/ext/lib/tkscrollbox.rb +4 -0
  334. data/ext/lib/tktext.rb +4 -0
  335. data/ext/lib/tkvirtevent.rb +4 -0
  336. data/ext/lib/tkwinpkg.rb +4 -0
  337. data/ext/old-README.tcltklib.eucj +159 -0
  338. data/ext/stubs.c +531 -0
  339. data/ext/stubs.h +33 -0
  340. data/ext/tcltklib.c +10155 -0
  341. data/ext/tkutil/.cvsignore +3 -0
  342. data/ext/tkutil/depend +1 -0
  343. data/ext/tkutil/extconf.rb +14 -0
  344. data/ext/tkutil/tkutil.c +1789 -0
  345. metadata +418 -0
data/ext/lib/README ADDED
@@ -0,0 +1,30 @@
1
+ README this file
2
+ multi-tk.rb multiple Tk interpreter (included safe-Tk) support
3
+ remotei-tk.rb control remote Tk interpreter on the other process support
4
+ tk.rb Tk interface
5
+
6
+ tk/ library files construct Ruby/Tk
7
+
8
+ tkextlib/ non-standard Tcl/Tk extension support libraries
9
+
10
+ *********************************************************************
11
+ *** The followings exists for backward compatibility only.
12
+ *** The only thing which they work is that requires current
13
+ *** library files ( tk/*.rb ).
14
+ *********************************************************************
15
+ tkafter.rb handles Tcl after
16
+ tkbgerror.rb Tk error module
17
+ tkcanvas.rb Tk canvas interface
18
+ tkclass.rb provides generic names for Tk classes
19
+ tkconsole.rb console command support
20
+ tkdialog.rb Tk dialog class
21
+ tkentry.rb Tk entry class
22
+ tkfont.rb Tk font support
23
+ tkmacpkg.rb Mac resource support
24
+ tkmenubar.rb TK menubar utility
25
+ tkmngfocus.rb focus manager
26
+ tkpalette.rb pallete support
27
+ tkscrollbox.rb scroll box, also example of compound widget
28
+ tktext.rb text classes
29
+ tkvirtevent.rb virtual event support
30
+ tkwinpkg.rb Win DDE and registry support
@@ -0,0 +1,3491 @@
1
+ #
2
+ # multi-tk.rb - supports multi Tk interpreters
3
+ # by Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
4
+
5
+ require 'tcltklib'
6
+ require 'tkutil'
7
+ require 'thread'
8
+
9
+ if defined? Tk
10
+ fail RuntimeError,"'multi-tk' library must be required before requiring 'tk'"
11
+ end
12
+
13
+ ################################################
14
+ # ignore exception on the mainloop?
15
+
16
+ TclTkLib.mainloop_abort_on_exception = true
17
+ # TclTkLib.mainloop_abort_on_exception = false
18
+ # TclTkLib.mainloop_abort_on_exception = nil
19
+
20
+
21
+ ################################################
22
+ # add ThreadGroup check to TclTkIp.new
23
+ class << TclTkIp
24
+ alias __new__ new
25
+ private :__new__
26
+
27
+ def new(*args)
28
+ if Thread.current.group != ThreadGroup::Default
29
+ raise SecurityError, 'only ThreadGroup::Default can call TclTkIp.new'
30
+ end
31
+ obj = __new__(*args)
32
+ obj.instance_eval{
33
+ @force_default_encoding ||= [false].taint
34
+ @encoding ||= [nil].taint
35
+ def @encoding.to_s; self.join(nil); end
36
+ }
37
+ obj
38
+ end
39
+ end
40
+
41
+
42
+ ################################################
43
+ # use pseudo-toplevel feature of MultiTkIp ?
44
+ if (!defined?(Use_PseudoToplevel_Feature_of_MultiTkIp) ||
45
+ Use_PseudoToplevel_Feature_of_MultiTkIp)
46
+ module MultiTkIp_PseudoToplevel_Evaluable
47
+ #def pseudo_toplevel_eval(body = Proc.new)
48
+ # Thread.current[:TOPLEVEL] = self
49
+ # begin
50
+ # body.call
51
+ # ensure
52
+ # Thread.current[:TOPLEVEL] = nil
53
+ # end
54
+ #end
55
+
56
+ def pseudo_toplevel_evaluable?
57
+ @pseudo_toplevel_evaluable
58
+ end
59
+
60
+ def pseudo_toplevel_evaluable=(mode)
61
+ @pseudo_toplevel_evaluable = (mode)? true: false
62
+ end
63
+
64
+ def self.extended(mod)
65
+ mod.__send__(:extend_object, mod)
66
+ mod.instance_variable_set('@pseudo_toplevel_evaluable', true)
67
+ end
68
+ end
69
+
70
+ class Object
71
+ alias __method_missing_alias_for_MultiTkIp__ method_missing
72
+ private :__method_missing_alias_for_MultiTkIp__
73
+
74
+ def method_missing(id, *args)
75
+ begin
76
+ has_top = (top = MultiTkIp.__getip.__pseudo_toplevel) &&
77
+ top.respond_to?(:pseudo_toplevel_evaluable?) &&
78
+ top.pseudo_toplevel_evaluable? &&
79
+ top.respond_to?(id)
80
+ rescue Exception => e
81
+ has_top = false
82
+ end
83
+
84
+ if has_top
85
+ top.__send__(id, *args)
86
+ else
87
+ __method_missing_alias_for_MultiTkIp__(id, *args)
88
+ end
89
+ end
90
+ end
91
+ else
92
+ # dummy
93
+ module MultiTkIp_PseudoToplevel_Evaluable
94
+ def pseudo_toplevel_evaluable?
95
+ false
96
+ end
97
+ end
98
+ end
99
+
100
+ ################################################
101
+ # exceptiopn to treat the return value from IP
102
+ class MultiTkIp_OK < Exception
103
+ def self.send(thread, ret=nil)
104
+ thread.raise self.new(ret)
105
+ end
106
+
107
+ def initialize(ret=nil)
108
+ super('succeed')
109
+ @return_value = ret
110
+ end
111
+
112
+ attr_reader :return_value
113
+ alias value return_value
114
+ end
115
+ MultiTkIp_OK.freeze
116
+
117
+
118
+ ################################################
119
+ # methods for construction
120
+ class MultiTkIp
121
+ BASE_DIR = File.dirname(__FILE__)
122
+
123
+ WITH_RUBY_VM = Object.const_defined?(:VM) && ::VM.class == Class
124
+ WITH_ENCODING = defined?(::Encoding.default_external)
125
+ #WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
126
+
127
+ (@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint]).instance_eval{
128
+ @mutex = Mutex.new
129
+ def mutex; @mutex; end
130
+ freeze
131
+ }
132
+
133
+ @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)
134
+
135
+ @@INIT_IP_ENV = [].taint unless defined?(@@INIT_IP_ENV) # table of Procs
136
+ @@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]
137
+
138
+ @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST)
139
+
140
+ unless defined?(@@TK_CMD_TBL)
141
+ @@TK_CMD_TBL = Object.new.taint
142
+
143
+ # @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint)
144
+ @@TK_CMD_TBL.instance_variable_set('@tbl', Hash.new{|hash,key|
145
+ fail IndexError,
146
+ "unknown command ID '#{key}'"
147
+ }.taint)
148
+
149
+ class << @@TK_CMD_TBL
150
+ allow = [
151
+ '__send__', '__id__', 'freeze', 'inspect', 'kind_of?', 'object_id',
152
+ '[]', '[]=', 'delete', 'each', 'has_key?'
153
+ ]
154
+ instance_methods.each{|m| undef_method(m) unless allow.index(m.to_s)}
155
+
156
+ def kind_of?(klass)
157
+ @tbl.kind_of?(klass)
158
+ end
159
+
160
+ def inspect
161
+ if Thread.current.group == ThreadGroup::Default
162
+ @tbl.inspect
163
+ else
164
+ ip = MultiTkIp.__getip
165
+ @tbl.reject{|idx, ent| ent.respond_to?(:ip) && ent.ip != ip}.inspect
166
+ end
167
+ end
168
+
169
+ def [](idx)
170
+ return unless (ent = @tbl[idx])
171
+ if Thread.current.group == ThreadGroup::Default
172
+ ent
173
+ elsif ent.respond_to?(:ip)
174
+ (ent.ip == MultiTkIp.__getip)? ent: nil
175
+ else
176
+ ent
177
+ end
178
+ end
179
+
180
+ def []=(idx,val)
181
+ if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default
182
+ fail SecurityError,"cannot change the entried command"
183
+ end
184
+ @tbl[idx] = val
185
+ end
186
+
187
+ def delete(idx, &blk)
188
+ # if gets an entry, is permited to delete
189
+ if self[idx]
190
+ @tbl.delete(idx)
191
+ elsif blk
192
+ blk.call(idx)
193
+ else
194
+ nil
195
+ end
196
+ end
197
+
198
+ def each(&blk)
199
+ if Thread.current.group == ThreadGroup::Default
200
+ @tbl.each(&blk)
201
+ else
202
+ ip = MultiTkIp.__getip
203
+ @tbl.each{|idx, ent|
204
+ blk.call(idx, ent) unless ent.respond_to?(:ip) && ent.ip != ip
205
+ }
206
+ end
207
+ self
208
+ end
209
+
210
+ def has_key?(k)
211
+ @tbl.has_key?(k)
212
+ end
213
+ alias include? has_key?
214
+ alias key? has_key?
215
+ alias member? has_key?
216
+ end
217
+
218
+ @@TK_CMD_TBL.freeze
219
+ end
220
+
221
+ ######################################
222
+
223
+ @@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){
224
+ def initialize(ip, cmd)
225
+ @ip = ip
226
+ @cmd = cmd
227
+ self.freeze
228
+ end
229
+ attr_reader :ip, :cmd
230
+ def inspect
231
+ cmd.inspect
232
+ end
233
+ def call(*args)
234
+ unless @ip.deleted?
235
+ current = Thread.current
236
+ backup_ip = current[:callback_ip]
237
+ current[:callback_ip] = @ip
238
+ begin
239
+ ret = @ip.cb_eval(@cmd, *args)
240
+ fail ret if ret.kind_of?(Exception)
241
+ ret
242
+ rescue TkCallbackBreak, TkCallbackContinue => e
243
+ fail e
244
+ rescue SecurityError => e
245
+ # in 'exit', 'exit!', and 'abort' : security error --> delete IP
246
+ if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/
247
+ @ip.delete
248
+ elsif @ip.safe?
249
+ if @ip.respond_to?(:cb_error)
250
+ @ip.cb_error(e)
251
+ else
252
+ nil # ignore
253
+ end
254
+ else
255
+ fail e
256
+ end
257
+ rescue Exception => e
258
+ fail e if e.message =~ /^TkCallback/
259
+
260
+ if @ip.safe?
261
+ if @ip.respond_to?(:cb_error)
262
+ @ip.cb_error(e)
263
+ else
264
+ nil # ignore
265
+ end
266
+ else
267
+ fail e
268
+ end
269
+ ensure
270
+ current[:callback_ip] = backup_ip
271
+ end
272
+ end
273
+ end
274
+ }.freeze
275
+
276
+ ######################################
277
+
278
+ def _keys2opts(src_keys)
279
+ return nil if src_keys == nil
280
+ keys = {}; src_keys.each{|k, v| keys[k.to_s] = v}
281
+ #keys.collect{|k,v| "-#{k} #{v}"}.join(' ')
282
+ keys.collect{|k,v| "-#{k} #{TclTkLib._conv_listelement(TkComm::_get_eval_string(v))}"}.join(' ')
283
+ end
284
+ private :_keys2opts
285
+
286
+ def _check_and_return(thread, exception, wait=0)
287
+ unless thread
288
+ unless exception.kind_of?(MultiTkIp_OK)
289
+ msg = "#{exception.class}: #{exception.message}"
290
+
291
+ if @interp.deleted?
292
+ warn("Warning (#{self}): " + msg)
293
+ return nil
294
+ end
295
+
296
+ if safe?
297
+ warn("Warning (#{self}): " + msg) if $DEBUG
298
+ return nil
299
+ end
300
+
301
+ begin
302
+ @interp._eval_without_enc(@interp._merge_tklist('bgerror', msg))
303
+ rescue Exception => e
304
+ warn("Warning (#{self}): " + msg)
305
+ end
306
+ end
307
+ return nil
308
+ end
309
+
310
+ if wait == 0
311
+ # no wait
312
+ Thread.pass
313
+ if thread.stop?
314
+ thread.raise exception
315
+ end
316
+ return thread
317
+ end
318
+
319
+ # wait to stop the caller thread
320
+ wait.times{
321
+ if thread.stop?
322
+ # ready to send exception
323
+ thread.raise exception
324
+ return thread
325
+ end
326
+
327
+ # wait
328
+ Thread.pass
329
+ }
330
+
331
+ # unexpected error
332
+ thread.raise RuntimeError, "the thread may not wait for the return value"
333
+ return thread
334
+ end
335
+
336
+ ######################################
337
+
338
+ def set_cb_error(cmd = Proc.new)
339
+ @cb_error_proc[0] = cmd
340
+ end
341
+
342
+ def cb_error(e)
343
+ if @cb_error_proc[0].respond_to?(:call)
344
+ @cb_error_proc[0].call(e)
345
+ end
346
+ end
347
+
348
+ ######################################
349
+
350
+ def set_safe_level(safe)
351
+ if safe > @safe_level[0]
352
+ @safe_level[0] = safe
353
+ @cmd_queue.enq([@system, 'set_safe_level', safe])
354
+ end
355
+ @safe_level[0]
356
+ end
357
+ def safe_level=(safe)
358
+ set_safe_level(safe)
359
+ end
360
+ def self.set_safe_level(safe)
361
+ __getip.set_safe_level(safe)
362
+ end
363
+ def self.safe_level=(safe)
364
+ self.set_safe_level(safe)
365
+ end
366
+ def safe_level
367
+ @safe_level[0]
368
+ end
369
+ def self.safe_level
370
+ __getip.safe_level
371
+ end
372
+
373
+ def wait_on_mainloop?
374
+ @wait_on_mainloop[0]
375
+ end
376
+ def wait_on_mainloop=(bool)
377
+ @wait_on_mainloop[0] = bool
378
+ end
379
+
380
+ def running_mainloop?
381
+ @wait_on_mainloop[1] > 0
382
+ end
383
+
384
+ def _destroy_slaves_of_slaveIP(ip)
385
+ unless ip.deleted?
386
+ # ip._split_tklist(ip._invoke('interp', 'slaves')).each{|name|
387
+ ip._split_tklist(ip._invoke_without_enc('interp', 'slaves')).each{|name|
388
+ name = _fromUTF8(name)
389
+ begin
390
+ # ip._eval_without_enc("#{name} eval {foreach i [after info] {after cancel $i}}")
391
+ after_ids = ip._eval_without_enc("#{name} eval {after info}")
392
+ ip._eval_without_enc("#{name} eval {foreach i {#{after_ids}} {after cancel $i}}")
393
+ rescue Exception
394
+ end
395
+ begin
396
+ # ip._invoke('interp', 'eval', name, 'destroy', '.')
397
+ ip._invoke(name, 'eval', 'destroy', '.')
398
+ rescue Exception
399
+ end
400
+
401
+ # safe_base?
402
+ if ip._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0'
403
+ begin
404
+ ip._eval_without_enc("::safe::interpDelete #{name}")
405
+ rescue Exception
406
+ end
407
+ end
408
+ =begin
409
+ if ip._invoke('interp', 'exists', name) == '1'
410
+ begin
411
+ ip._invoke(name, 'eval', 'exit')
412
+ rescue Exception
413
+ end
414
+ end
415
+ =end
416
+ unless ip.deleted?
417
+ if ip._invoke('interp', 'exists', name) == '1'
418
+ begin
419
+ ip._invoke('interp', 'delete', name)
420
+ rescue Exception
421
+ end
422
+ end
423
+ end
424
+ }
425
+ end
426
+ end
427
+
428
+ def _receiver_eval_proc_core(safe_level, thread, cmd, *args)
429
+ begin
430
+ #ret = proc{$SAFE = safe_level; cmd.call(*args)}.call
431
+ #ret = cmd.call(safe_level, *args)
432
+ normal_ret = false
433
+ ret = catch(:IRB_EXIT) do # IRB hack
434
+ retval = cmd.call(safe_level, *args)
435
+ normal_ret = true
436
+ retval
437
+ end
438
+ unless normal_ret
439
+ # catch IRB_EXIT
440
+ exit(ret)
441
+ end
442
+ ret
443
+ rescue SystemExit => e
444
+ # delete IP
445
+ unless @interp.deleted?
446
+ @slave_ip_tbl.each{|name, subip|
447
+ _destroy_slaves_of_slaveIP(subip)
448
+ begin
449
+ # subip._eval_without_enc("foreach i [after info] {after cancel $i}")
450
+ after_ids = subip._eval_without_enc("after info")
451
+ subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
452
+ rescue Exception
453
+ end
454
+ =begin
455
+ begin
456
+ subip._invoke('destroy', '.') unless subip.deleted?
457
+ rescue Exception
458
+ end
459
+ =end
460
+ # safe_base?
461
+ if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0'
462
+ begin
463
+ @interp._eval_without_enc("::safe::interpDelete #{name}")
464
+ rescue Exception
465
+ else
466
+ next if subip.deleted?
467
+ end
468
+ end
469
+ if subip.respond_to?(:safe_base?) && subip.safe_base? &&
470
+ !subip.deleted?
471
+ # do 'exit' to call the delete_hook procedure
472
+ begin
473
+ subip._eval_without_enc('exit')
474
+ rescue Exception
475
+ end
476
+ else
477
+ begin
478
+ subip.delete unless subip.deleted?
479
+ rescue Exception
480
+ end
481
+ end
482
+ }
483
+
484
+ begin
485
+ # @interp._eval_without_enc("foreach i [after info] {after cancel $i}")
486
+ after_ids = @interp._eval_without_enc("after info")
487
+ @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
488
+ rescue Exception
489
+ end
490
+ begin
491
+ @interp._invoke('destroy', '.') unless @interp.deleted?
492
+ rescue Exception
493
+ end
494
+ if @safe_base && !@interp.deleted?
495
+ # do 'exit' to call the delete_hook procedure
496
+ @interp._eval_without_enc('exit')
497
+ else
498
+ @interp.delete unless @interp.deleted?
499
+ end
500
+ end
501
+
502
+ if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/
503
+ _check_and_return(thread, MultiTkIp_OK.new($3 == 'exit'))
504
+ else
505
+ _check_and_return(thread, MultiTkIp_OK.new(nil))
506
+ end
507
+
508
+ # if master? && !safe? && allow_ruby_exit?
509
+ if !@interp.deleted? && master? && !safe? && allow_ruby_exit?
510
+ =begin
511
+ ObjectSpace.each_object(TclTkIp){|obj|
512
+ obj.delete unless obj.deleted?
513
+ }
514
+ =end
515
+ #exit(e.status)
516
+ fail e
517
+ end
518
+ # break
519
+
520
+ rescue SecurityError => e
521
+ # in 'exit', 'exit!', and 'abort' : security error --> delete IP
522
+ if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/
523
+ ret = ($3 == 'exit')
524
+ unless @interp.deleted?
525
+ @slave_ip_tbl.each{|name, subip|
526
+ _destroy_slaves_of_slaveIP(subip)
527
+ begin
528
+ # subip._eval_without_enc("foreach i [after info] {after cancel $i}")
529
+ after_ids = subip._eval_without_enc("after info")
530
+ subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
531
+ rescue Exception
532
+ end
533
+ =begin
534
+ begin
535
+ subip._invoke('destroy', '.') unless subip.deleted?
536
+ rescue Exception
537
+ end
538
+ =end
539
+ # safe_base?
540
+ if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0'
541
+ begin
542
+ @interp._eval_without_enc("::safe::interpDelete #{name}")
543
+ rescue Exception
544
+ else
545
+ next if subip.deleted?
546
+ end
547
+ end
548
+ if subip.respond_to?(:safe_base?) && subip.safe_base? &&
549
+ !subip.deleted?
550
+ # do 'exit' to call the delete_hook procedure
551
+ begin
552
+ subip._eval_without_enc('exit')
553
+ rescue Exception
554
+ end
555
+ else
556
+ begin
557
+ subip.delete unless subip.deleted?
558
+ rescue Exception
559
+ end
560
+ end
561
+ }
562
+
563
+ begin
564
+ # @interp._eval_without_enc("foreach i [after info] {after cancel $i}")
565
+ after_ids = @interp._eval_without_enc("after info")
566
+ @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
567
+ rescue Exception
568
+ end
569
+ =begin
570
+ begin
571
+ @interp._invoke('destroy', '.') unless @interp.deleted?
572
+ rescue Exception
573
+ end
574
+ =end
575
+ if @safe_base && !@interp.deleted?
576
+ # do 'exit' to call the delete_hook procedure
577
+ @interp._eval_without_enc('exit')
578
+ else
579
+ @interp.delete unless @interp.deleted?
580
+ end
581
+ end
582
+ _check_and_return(thread, MultiTkIp_OK.new(ret))
583
+ # break
584
+
585
+ else
586
+ # raise security error
587
+ _check_and_return(thread, e)
588
+ end
589
+
590
+ rescue Exception => e
591
+ # raise exception
592
+ begin
593
+ bt = _toUTF8(e.backtrace.join("\n"))
594
+ if MultiTkIp::WITH_ENCODING
595
+ bt.force_encoding('utf-8')
596
+ else
597
+ bt.instance_variable_set(:@encoding, 'utf-8')
598
+ end
599
+ rescue Exception
600
+ bt = e.backtrace.join("\n")
601
+ end
602
+ begin
603
+ @interp._set_global_var('errorInfo', bt)
604
+ rescue Exception
605
+ end
606
+ _check_and_return(thread, e)
607
+
608
+ else
609
+ # no exception
610
+ _check_and_return(thread, MultiTkIp_OK.new(ret))
611
+ end
612
+ end
613
+
614
+ def _receiver_eval_proc(last_thread, safe_level, thread, cmd, *args)
615
+ if thread
616
+ Thread.new{
617
+ last_thread.join if last_thread
618
+ unless @interp.deleted?
619
+ _receiver_eval_proc_core(safe_level, thread, cmd, *args)
620
+ end
621
+ }
622
+ else
623
+ Thread.new{
624
+ unless @interp.deleted?
625
+ _receiver_eval_proc_core(safe_level, thread, cmd, *args)
626
+ end
627
+ }
628
+ last_thread
629
+ end
630
+ end
631
+
632
+ private :_receiver_eval_proc, :_receiver_eval_proc_core
633
+
634
+ def _receiver_mainloop(check_root)
635
+ if @evloop_thread[0] && @evloop_thread[0].alive?
636
+ @evloop_thread[0]
637
+ else
638
+ @evloop_thread[0] = Thread.new{
639
+ while !@interp.deleted?
640
+ #if check_root
641
+ # inf = @interp._invoke_without_enc('info', 'command', '.')
642
+ # break if !inf.kind_of?(String) || inf != '.'
643
+ #end
644
+ break if check_root && !@interp.has_mainwindow?
645
+ sleep 0.5
646
+ end
647
+ }
648
+ @evloop_thread[0]
649
+ end
650
+ end
651
+
652
+ def _create_receiver_and_watchdog(lvl = $SAFE)
653
+ lvl = $SAFE if lvl < $SAFE
654
+
655
+ # command-procedures receiver
656
+ receiver = Thread.new(lvl){|safe_level|
657
+ last_thread = {}
658
+
659
+ loop do
660
+ break if @interp.deleted?
661
+ thread, cmd, *args = @cmd_queue.deq
662
+ if thread == @system
663
+ # control command
664
+ case cmd
665
+ when 'set_safe_level'
666
+ begin
667
+ safe_level = args[0] if safe_level < args[0]
668
+ rescue Exception
669
+ end
670
+ when 'call_mainloop'
671
+ thread = args.shift
672
+ _check_and_return(thread,
673
+ MultiTkIp_OK.new(_receiver_mainloop(*args)))
674
+ else
675
+ # ignore
676
+ end
677
+
678
+ else
679
+ # procedure
680
+ last_thread[thread] = _receiver_eval_proc(last_thread[thread],
681
+ safe_level, thread,
682
+ cmd, *args)
683
+ end
684
+ end
685
+ }
686
+
687
+ # watchdog of receiver
688
+ watchdog = Thread.new{
689
+ begin
690
+ loop do
691
+ sleep 1
692
+ receiver.kill if @interp.deleted?
693
+ break unless receiver.alive?
694
+ end
695
+ rescue Exception
696
+ # ignore all kind of Exception
697
+ end
698
+ # receiver is dead
699
+ loop do
700
+ thread, cmd, *args = @cmd_queue.deq
701
+ next unless thread
702
+ if thread.alive?
703
+ if @interp.deleted?
704
+ thread.raise RuntimeError, 'the interpreter is already deleted'
705
+ else
706
+ thread.raise RuntimeError,
707
+ 'the interpreter no longer receives command procedures'
708
+ end
709
+ end
710
+ end
711
+ }
712
+
713
+ # return threads
714
+ [receiver, watchdog]
715
+ end
716
+ private :_check_and_return, :_create_receiver_and_watchdog
717
+
718
+ ######################################
719
+
720
+ unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
721
+ ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!
722
+ RUN_EVENTLOOP_ON_MAIN_THREAD = false
723
+ end
724
+
725
+ if self.const_defined? :DEFAULT_MASTER_NAME
726
+ name = DEFAULT_MASTER_NAME.to_s
727
+ else
728
+ name = nil
729
+ end
730
+ if self.const_defined?(:DEFAULT_MASTER_OPTS) &&
731
+ DEFAULT_MASTER_OPTS.kind_of?(Hash)
732
+ keys = DEFAULT_MASTER_OPTS
733
+ else
734
+ keys = {}
735
+ end
736
+
737
+ @@DEFAULT_MASTER = self.allocate
738
+ @@DEFAULT_MASTER.instance_eval{
739
+ @tk_windows = {}.taint
740
+
741
+ @tk_table_list = [].taint
742
+
743
+ @slave_ip_tbl = {}.taint
744
+
745
+ @slave_ip_top = {}.taint
746
+
747
+ @evloop_thread = [].taint
748
+
749
+ unless keys.kind_of? Hash
750
+ fail ArgumentError, "expecting a Hash object for the 2nd argument"
751
+ end
752
+
753
+ if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
754
+ @interp = TclTkIp.new(name, _keys2opts(keys))
755
+ else ### Ruby 1.9 !!!!!!!!!!!
756
+ @interp_thread = Thread.new{
757
+ current = Thread.current
758
+ current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))
759
+ #sleep
760
+ current[:mutex] = mutex = Mutex.new
761
+ current[:root_check] = cond_var = ConditionVariable.new
762
+
763
+ status = [nil]
764
+ def status.value
765
+ self[0]
766
+ end
767
+ def status.value=(val)
768
+ self[0] = val
769
+ end
770
+ current[:status] = status
771
+
772
+ begin
773
+ current[:status].value = interp.mainloop(true)
774
+ rescue Exception=>e
775
+ current[:status].value = e
776
+ ensure
777
+ mutex.synchronize{ cond_var.broadcast }
778
+ end
779
+ current[:status].value = interp.mainloop(false)
780
+ }
781
+ until @interp_thread[:interp]
782
+ Thread.pass
783
+ end
784
+ # INTERP_THREAD.run
785
+ @interp = @interp_thread[:interp]
786
+
787
+ def self.mainloop(check_root = true)
788
+ begin
789
+ TclTkLib.set_eventloop_window_mode(true)
790
+ @interp_thread.value
791
+ ensure
792
+ TclTkLib.set_eventloop_window_mode(false)
793
+ end
794
+ end
795
+ end
796
+
797
+ @interp.instance_eval{
798
+ @force_default_encoding ||= [false].taint
799
+ @encoding ||= [nil].taint
800
+ def @encoding.to_s; self.join(nil); end
801
+ }
802
+
803
+ @ip_name = nil
804
+
805
+ @callback_status = [].taint
806
+
807
+ @system = Object.new
808
+
809
+ @wait_on_mainloop = [true, 0].taint
810
+
811
+ @threadgroup = Thread.current.group
812
+
813
+ @safe_base = false
814
+
815
+ @safe_level = [$SAFE]
816
+
817
+ @cmd_queue = Queue.new
818
+
819
+ @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0])
820
+
821
+ @threadgroup.add @cmd_receiver
822
+ @threadgroup.add @receiver_watchdog
823
+
824
+ # NOT enclose @threadgroup for @@DEFAULT_MASTER
825
+
826
+ @@IP_TABLE[ThreadGroup::Default] = self
827
+ @@IP_TABLE[@threadgroup] = self
828
+
829
+ #################################
830
+
831
+ @pseudo_toplevel = [false, nil]
832
+
833
+ def self.__pseudo_toplevel
834
+ Thread.current.group == ThreadGroup::Default &&
835
+ MultiTkIp.__getip == @@DEFAULT_MASTER &&
836
+ self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1]
837
+ end
838
+
839
+ def self.__pseudo_toplevel=(m)
840
+ unless (Thread.current.group == ThreadGroup::Default &&
841
+ MultiTkIp.__getip == @@DEFAULT_MASTER)
842
+ fail SecurityError, "no permission to manipulate"
843
+ end
844
+
845
+ # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?)
846
+ if m.respond_to?(:pseudo_toplevel_evaluable?)
847
+ @pseudo_toplevel[0] = true
848
+ @pseudo_toplevel[1] = m
849
+ else
850
+ fail ArgumentError, 'fail to set pseudo-toplevel'
851
+ end
852
+ self
853
+ end
854
+
855
+ def self.__pseudo_toplevel_evaluable?
856
+ begin
857
+ @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable?
858
+ rescue Exception
859
+ false
860
+ end
861
+ end
862
+
863
+ def self.__pseudo_toplevel_evaluable=(mode)
864
+ unless (Thread.current.group == ThreadGroup::Default &&
865
+ MultiTkIp.__getip == @@DEFAULT_MASTER)
866
+ fail SecurityError, "no permission to manipulate"
867
+ end
868
+
869
+ @pseudo_toplevel[0] = (mode)? true: false
870
+ end
871
+
872
+ #################################
873
+
874
+ @assign_request = Class.new(Exception){
875
+ def self.new(target, ret)
876
+ obj = super()
877
+ obj.target = target
878
+ obj.ret = ret
879
+ obj
880
+ end
881
+ attr_accessor :target, :ret
882
+ }
883
+
884
+ @assign_thread = Thread.new{
885
+ loop do
886
+ begin
887
+ Thread.stop
888
+ rescue @assign_request=>req
889
+ begin
890
+ req.ret[0] = req.target.instance_eval{
891
+ @cmd_receiver, @receiver_watchdog =
892
+ _create_receiver_and_watchdog(@safe_level[0])
893
+ @threadgroup.add @cmd_receiver
894
+ @threadgroup.add @receiver_watchdog
895
+ @threadgroup.enclose
896
+ true
897
+ }
898
+ rescue Exception=>e
899
+ begin
900
+ req.ret[0] = e
901
+ rescue Exception
902
+ # ignore
903
+ end
904
+ end
905
+ rescue Exception
906
+ # ignore
907
+ end
908
+ end
909
+ }
910
+
911
+ def self.assign_receiver_and_watchdog(target)
912
+ ret = [nil]
913
+ @assign_thread.raise(@assign_request.new(target, ret))
914
+ while ret[0] == nil
915
+ unless @assign_thread.alive?
916
+ raise RuntimeError, 'lost the thread to assign a receiver and a watchdog thread'
917
+ end
918
+ end
919
+ if ret[0].kind_of?(Exception)
920
+ raise ret[0]
921
+ else
922
+ ret[0]
923
+ end
924
+ end
925
+
926
+ #################################
927
+
928
+ @init_ip_env_queue = Queue.new
929
+ Thread.new{
930
+ current = Thread.current
931
+ loop {
932
+ mtx, cond, ret, table, script = @init_ip_env_queue.deq
933
+ begin
934
+ ret[0] = table.each{|tg, ip| ip._init_ip_env(script) }
935
+ rescue Exception => e
936
+ ret[0] = e
937
+ ensure
938
+ mtx.synchronize{ cond.signal }
939
+ end
940
+ mtx = cond = ret = table = script = nil # clear variables for GC
941
+ }
942
+ }
943
+
944
+ def self.__init_ip_env__(table, script)
945
+ ret = []
946
+ mtx = (Thread.current[:MultiTk_ip_Mutex] ||= Mutex.new)
947
+ cond = (Thread.current[:MultiTk_ip_CondVar] ||= ConditionVariable.new)
948
+ mtx.synchronize{
949
+ @init_ip_env_queue.enq([mtx, cond, ret, table, script])
950
+ cond.wait(mtx)
951
+ }
952
+ if ret[0].kind_of?(Exception)
953
+ raise ret[0]
954
+ else
955
+ ret[0]
956
+ end
957
+ end
958
+
959
+ #################################
960
+
961
+ class << self
962
+ undef :instance_eval
963
+ end
964
+ }
965
+
966
+ @@DEFAULT_MASTER.freeze # defend against modification
967
+
968
+ ######################################
969
+
970
+ def self.inherited(subclass)
971
+ # trust if on ThreadGroup::Default or @@DEFAULT_MASTER's ThreadGroup
972
+ if @@IP_TABLE[Thread.current.group] == @@DEFAULT_MASTER
973
+ begin
974
+ class << subclass
975
+ self.methods.each{|m|
976
+ name = m.to_s
977
+ begin
978
+ unless name == '__id__' || name == '__send__' || name == 'freeze'
979
+ undef_method(m)
980
+ end
981
+ rescue Exception
982
+ # ignore all exceptions
983
+ end
984
+ }
985
+ end
986
+ ensure
987
+ subclass.freeze
988
+ fail SecurityError,
989
+ "cannot create subclass of MultiTkIp on a untrusted ThreadGroup"
990
+ end
991
+ end
992
+ end
993
+
994
+ ######################################
995
+
996
+ @@SAFE_OPT_LIST = [
997
+ 'accessPath'.freeze,
998
+ 'statics'.freeze,
999
+ 'nested'.freeze,
1000
+ 'deleteHook'.freeze
1001
+ ].freeze
1002
+
1003
+ def _parse_slaveopts(keys)
1004
+ name = nil
1005
+ safe = false
1006
+ safe_opts = {}
1007
+ tk_opts = {}
1008
+
1009
+ keys.each{|k,v|
1010
+ k_str = k.to_s
1011
+ if k_str == 'name'
1012
+ name = v
1013
+ elsif k_str == 'safe'
1014
+ safe = v
1015
+ elsif @@SAFE_OPT_LIST.member?(k_str)
1016
+ safe_opts[k_str] = v
1017
+ else
1018
+ tk_opts[k_str] = v
1019
+ end
1020
+ }
1021
+
1022
+ if keys['without_tk'] || keys[:without_tk]
1023
+ [name, safe, safe_opts, nil]
1024
+ else
1025
+ [name, safe, safe_opts, tk_opts]
1026
+ end
1027
+ end
1028
+ private :_parse_slaveopts
1029
+
1030
+ def _create_slave_ip_name
1031
+ @@SLAVE_IP_ID.mutex.synchronize{
1032
+ name = @@SLAVE_IP_ID.join('')
1033
+ @@SLAVE_IP_ID[1].succ!
1034
+ name.freeze
1035
+ }
1036
+ end
1037
+ private :_create_slave_ip_name
1038
+
1039
+ ######################################
1040
+
1041
+ def __check_safetk_optkeys(optkeys)
1042
+ # based on 'safetk.tcl'
1043
+ new_keys = {}
1044
+ optkeys.each{|k,v| new_keys[k.to_s] = v}
1045
+
1046
+ # check 'display'
1047
+ if !new_keys.key?('display')
1048
+ begin
1049
+ #new_keys['display'] = @interp._invoke('winfo screen .')
1050
+ new_keys['display'] = @interp._invoke('winfo', 'screen', '.')
1051
+ rescue
1052
+ if ENV[DISPLAY]
1053
+ new_keys['display'] = ENV[DISPLAY]
1054
+ elsif !new_keys.key?('use')
1055
+ warn "Warning: no screen info or ENV[DISPLAY], so use ':0.0'"
1056
+ new_keys['display'] = ':0.0'
1057
+ end
1058
+ end
1059
+ end
1060
+
1061
+ # check 'use'
1062
+ if new_keys.key?('use')
1063
+ # given 'use'
1064
+ case new_keys['use']
1065
+ when TkWindow
1066
+ new_keys['use'] = TkWinfo.id(new_keys['use'])
1067
+ #assoc_display = @interp._eval('winfo screen .')
1068
+ assoc_display = @interp._invoke('winfo', 'screen', '.')
1069
+ when /^\..*/
1070
+ new_keys['use'] = @interp._invoke('winfo', 'id', new_keys['use'])
1071
+ assoc_display = @interp._invoke('winfo', 'screen', new_keys['use'])
1072
+ else
1073
+ begin
1074
+ pathname = @interp._invoke('winfo', 'pathname', new_keys['use'])
1075
+ assoc_display = @interp._invoke('winfo', 'screen', pathname)
1076
+ rescue
1077
+ assoc_display = new_keys['display']
1078
+ end
1079
+ end
1080
+
1081
+ # match display?
1082
+ if assoc_display != new_keys['display']
1083
+ if optkeys.key?(:display) || optkeys.key?('display')
1084
+ fail RuntimeError,
1085
+ "conflicting 'display'=>#{new_keys['display']} " +
1086
+ "and display '#{assoc_display}' on 'use'=>#{new_keys['use']}"
1087
+ else
1088
+ new_keys['display'] = assoc_display
1089
+ end
1090
+ end
1091
+ end
1092
+
1093
+ # return
1094
+ new_keys
1095
+ end
1096
+ private :__check_safetk_optkeys
1097
+
1098
+ def __create_safetk_frame(slave_ip, slave_name, app_name, keys)
1099
+ # display option is used by ::safe::loadTk
1100
+ loadTk_keys = {}
1101
+ loadTk_keys['display'] = keys['display']
1102
+ dup_keys = keys.dup
1103
+
1104
+ # keys for toplevel : allow followings
1105
+ toplevel_keys = {}
1106
+ ['height', 'width', 'background', 'menu'].each{|k|
1107
+ toplevel_keys[k] = dup_keys.delete(k) if dup_keys.key?(k)
1108
+ }
1109
+ toplevel_keys['classname'] = 'SafeTk'
1110
+ toplevel_keys['screen'] = dup_keys.delete('display')
1111
+
1112
+ # other keys used by pack option of container frame
1113
+
1114
+ # create toplevel widget
1115
+ begin
1116
+ top = TkToplevel.new(toplevel_keys)
1117
+ rescue NameError => e
1118
+ fail e unless @interp.safe?
1119
+ fail SecurityError, "unable create toplevel on the safe interpreter"
1120
+ end
1121
+ msg = "Untrusted Ruby/Tk applet (#{slave_name})"
1122
+ if app_name.kind_of?(String)
1123
+ top.title "#{app_name} (#{slave_name})"
1124
+ else
1125
+ top.title msg
1126
+ end
1127
+
1128
+ # procedure to delete slave interpreter
1129
+ slave_delete_proc = proc{
1130
+ unless slave_ip.deleted?
1131
+ #if slave_ip._invoke('info', 'command', '.') != ""
1132
+ # slave_ip._invoke('destroy', '.')
1133
+ #end
1134
+ #slave_ip.delete
1135
+ slave_ip._eval_without_enc('exit')
1136
+ end
1137
+ begin
1138
+ top.destroy if top.winfo_exist?
1139
+ rescue
1140
+ # ignore
1141
+ end
1142
+ }
1143
+ tag = TkBindTag.new.bind('Destroy', slave_delete_proc)
1144
+
1145
+ top.bindtags = top.bindtags.unshift(tag)
1146
+
1147
+ # create control frame
1148
+ TkFrame.new(top, :bg=>'red', :borderwidth=>3, :relief=>'ridge') {|fc|
1149
+ fc.bindtags = fc.bindtags.unshift(tag)
1150
+
1151
+ TkFrame.new(fc, :bd=>0){|f|
1152
+ TkButton.new(f,
1153
+ :text=>'Delete', :bd=>1, :padx=>2, :pady=>0,
1154
+ :highlightthickness=>0, :command=>slave_delete_proc
1155
+ ).pack(:side=>:right, :fill=>:both)
1156
+ f.pack(:side=>:right, :fill=>:both, :expand=>true)
1157
+ }
1158
+
1159
+ TkLabel.new(fc, :text=>msg, :padx=>2, :pady=>0,
1160
+ :anchor=>:w).pack(:side=>:left, :fill=>:both, :expand=>true)
1161
+
1162
+ fc.pack(:side=>:bottom, :fill=>:x)
1163
+ }
1164
+
1165
+ # container frame for slave interpreter
1166
+ dup_keys['fill'] = :both unless dup_keys.key?('fill')
1167
+ dup_keys['expand'] = true unless dup_keys.key?('expand')
1168
+ c = TkFrame.new(top, :container=>true).pack(dup_keys)
1169
+ c.bind('Destroy', proc{top.destroy})
1170
+
1171
+ # return keys
1172
+ loadTk_keys['use'] = TkWinfo.id(c)
1173
+ [loadTk_keys, top.path]
1174
+ end
1175
+ private :__create_safetk_frame
1176
+
1177
+ def __create_safe_slave_obj(safe_opts, app_name, tk_opts)
1178
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1179
+
1180
+ # safe interpreter
1181
+ ip_name = _create_slave_ip_name
1182
+ slave_ip = @interp.create_slave(ip_name, true)
1183
+ slave_ip.instance_eval{
1184
+ @force_default_encoding ||= [false].taint
1185
+ @encoding ||= [nil].taint
1186
+ def @encoding.to_s; self.join(nil); end
1187
+ }
1188
+ @slave_ip_tbl[ip_name] = slave_ip
1189
+ def slave_ip.safe_base?
1190
+ true
1191
+ end
1192
+
1193
+ @interp._eval("::safe::interpInit #{ip_name}")
1194
+
1195
+ slave_ip._invoke('set', 'argv0', app_name) if app_name.kind_of?(String)
1196
+
1197
+ if tk_opts
1198
+ tk_opts = __check_safetk_optkeys(tk_opts)
1199
+ if tk_opts.key?('use')
1200
+ @slave_ip_top[ip_name] = ''
1201
+ else
1202
+ tk_opts, top_path = __create_safetk_frame(slave_ip, ip_name, app_name,
1203
+ tk_opts)
1204
+ @slave_ip_top[ip_name] = top_path
1205
+ end
1206
+ @interp._eval("::safe::loadTk #{ip_name} #{_keys2opts(tk_opts)}")
1207
+ else
1208
+ @slave_ip_top[ip_name] = nil
1209
+ end
1210
+
1211
+ if safe_opts.key?('deleteHook') || safe_opts.key?(:deleteHook)
1212
+ @interp._eval("::safe::interpConfigure #{ip_name} " +
1213
+ _keys2opts(safe_opts))
1214
+ else
1215
+ @interp._eval("::safe::interpConfigure #{ip_name} " +
1216
+ _keys2opts(safe_opts) + '-deleteHook {' +
1217
+ TkComm._get_eval_string(proc{|slave|
1218
+ self._default_delete_hook(slave)
1219
+ }) + '}')
1220
+ end
1221
+
1222
+ [slave_ip, ip_name]
1223
+ end
1224
+
1225
+ def __create_trusted_slave_obj(name, keys)
1226
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1227
+
1228
+ ip_name = _create_slave_ip_name
1229
+ slave_ip = @interp.create_slave(ip_name, false)
1230
+ slave_ip.instance_eval{
1231
+ @force_default_encoding ||= [false].taint
1232
+ @encoding ||= [nil].taint
1233
+ def @encoding.to_s; self.join(nil); end
1234
+ }
1235
+ slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String)
1236
+ slave_ip._invoke('set', 'argv', _keys2opts(keys))
1237
+ @interp._invoke('load', '', 'Tk', ip_name)
1238
+ @slave_ip_tbl[ip_name] = slave_ip
1239
+ [slave_ip, ip_name]
1240
+ end
1241
+
1242
+ ######################################
1243
+
1244
+ def _create_slave_object(keys={})
1245
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1246
+
1247
+ ip = MultiTkIp.new_slave(self, keys={})
1248
+ @slave_ip_tbl[ip.name] = ip
1249
+ end
1250
+
1251
+ ######################################
1252
+
1253
+ def initialize(master, safeip=true, keys={})
1254
+ if $SAFE >= 4
1255
+ fail SecurityError, "cannot create a new interpreter at level #{$SAFE}"
1256
+ end
1257
+
1258
+ if safeip == nil && $SAFE >= 2
1259
+ fail SecurityError, "cannot create a master-ip at level #{$SAFE}"
1260
+ end
1261
+
1262
+ if master.deleted? && safeip == nil
1263
+ fail RuntimeError, "cannot create a slave of a deleted interpreter"
1264
+ end
1265
+
1266
+ if !master.deleted? && !master.master? && master.safe?
1267
+ fail SecurityError, "safe-slave-ip cannot create a new interpreter"
1268
+ end
1269
+
1270
+ if safeip == nil && !master.master?
1271
+ fail SecurityError, "slave-ip cannot create a master-ip"
1272
+ end
1273
+
1274
+ unless keys.kind_of? Hash
1275
+ fail ArgumentError, "expecting a Hash object for the 2nd argument"
1276
+ end
1277
+
1278
+ @tk_windows = {}
1279
+ @tk_table_list = []
1280
+ @slave_ip_tbl = {}
1281
+ @slave_ip_top = {}
1282
+ @cb_error_proc = []
1283
+ @evloop_thread = []
1284
+
1285
+ @tk_windows.taint unless @tk_windows.tainted?
1286
+ @tk_table_list.taint unless @tk_table_list.tainted?
1287
+ @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
1288
+ @slave_ip_top.taint unless @slave_ip_top.tainted?
1289
+ @cb_error_proc.taint unless @cb_error_proc.tainted?
1290
+ @evloop_thread.taint unless @evloop_thread.tainted?
1291
+
1292
+ @callback_status = []
1293
+
1294
+ name, safe, safe_opts, tk_opts = _parse_slaveopts(keys)
1295
+
1296
+ safe = 4 if safe && !safe.kind_of?(Fixnum)
1297
+
1298
+ @safe_base = false
1299
+
1300
+ if safeip == nil
1301
+ # create master-ip
1302
+ unless WITH_RUBY_VM
1303
+ @interp = TclTkIp.new(name, _keys2opts(tk_opts))
1304
+ @interp.instance_eval{
1305
+ @force_default_encoding ||= [false].taint
1306
+ @encoding ||= [nil].taint
1307
+ def @encoding.to_s; self.join(nil); end
1308
+ }
1309
+
1310
+ else ### Ruby 1.9 !!!!!!!!!!!
1311
+ @interp_thread = Thread.new{
1312
+ Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
1313
+ interp.instance_eval{
1314
+ @force_default_encoding ||= [false].taint
1315
+ @encoding ||= [nil].taint
1316
+ def @encoding.to_s; self.join(nil); end
1317
+ }
1318
+
1319
+ #sleep
1320
+ TclTkLib.mainloop(true)
1321
+ }
1322
+ until @interp_thread[:interp]
1323
+ Thread.pass
1324
+ end
1325
+ # INTERP_THREAD.run
1326
+ @interp = @interp_thread[:interp]
1327
+ end
1328
+
1329
+ @ip_name = nil
1330
+ if safe
1331
+ safe = $SAFE if safe < $SAFE
1332
+ @safe_level = [safe]
1333
+ else
1334
+ @safe_level = [$SAFE]
1335
+ end
1336
+ else
1337
+ # create slave-ip
1338
+ if safeip || master.safe?
1339
+ @safe_base = true
1340
+ @interp, @ip_name = master.__create_safe_slave_obj(safe_opts,
1341
+ name, tk_opts)
1342
+ # @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!
1343
+ @interp_thread = nil unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
1344
+ if safe
1345
+ safe = master.safe_level if safe < master.safe_level
1346
+ @safe_level = [safe]
1347
+ else
1348
+ @safe_level = [4]
1349
+ end
1350
+ else
1351
+ @interp, @ip_name = master.__create_trusted_slave_obj(name, tk_opts)
1352
+ # @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!
1353
+ @interp_thread = nil unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
1354
+ if safe
1355
+ safe = master.safe_level if safe < master.safe_level
1356
+ @safe_level = [safe]
1357
+ else
1358
+ @safe_level = [master.safe_level]
1359
+ end
1360
+ end
1361
+ @set_alias_proc = proc{|name|
1362
+ master._invoke('interp', 'alias', @ip_name, name, '', name)
1363
+ }.freeze
1364
+ end
1365
+
1366
+ @system = Object.new
1367
+
1368
+ @wait_on_mainloop = [true, 0].taint
1369
+ # @wait_on_mainloop = [false, 0].taint
1370
+
1371
+ @threadgroup = ThreadGroup.new
1372
+
1373
+ @pseudo_toplevel = [false, nil]
1374
+
1375
+ @cmd_queue = Queue.new
1376
+
1377
+ =begin
1378
+ @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0])
1379
+
1380
+ @threadgroup.add @cmd_receiver
1381
+ @threadgroup.add @receiver_watchdog
1382
+
1383
+ @threadgroup.enclose
1384
+ =end
1385
+ @@DEFAULT_MASTER.assign_receiver_and_watchdog(self)
1386
+
1387
+ @@IP_TABLE[@threadgroup] = self
1388
+ @@TK_TABLE_LIST.size.times{
1389
+ (tbl = {}).tainted? || tbl.taint
1390
+ @tk_table_list << tbl
1391
+ }
1392
+ _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
1393
+
1394
+ class << self
1395
+ undef :instance_eval
1396
+ end
1397
+
1398
+ # dummy call for initialization
1399
+ self.eval_proc{ Tk.tk_call('set', 'tcl_patchLevel') }
1400
+
1401
+ self.freeze # defend against modification
1402
+ end
1403
+
1404
+ ######################################
1405
+
1406
+ def _default_delete_hook(slave)
1407
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1408
+ @slave_ip_tbl.delete(slave)
1409
+ top = @slave_ip_top.delete(slave)
1410
+ if top.kind_of?(String)
1411
+ # call default hook of safetk.tcl (ignore exceptions)
1412
+ if top == ''
1413
+ begin
1414
+ @interp._eval("::safe::disallowTk #{slave}")
1415
+ rescue
1416
+ warn("Waring: fail to call '::safe::disallowTk'") if $DEBUG
1417
+ end
1418
+ else # toplevel path
1419
+ begin
1420
+ @interp._eval("::safe::tkDelete {} #{top} #{slave}")
1421
+ rescue
1422
+ warn("Waring: fail to call '::safe::tkDelete'") if $DEBUG
1423
+ begin
1424
+ @interp._eval("destroy #{top}")
1425
+ rescue
1426
+ warn("Waring: fail to destroy toplevel") if $DEBUG
1427
+ end
1428
+ end
1429
+ end
1430
+ end
1431
+ end
1432
+
1433
+ end
1434
+
1435
+
1436
+ # get target IP
1437
+ class MultiTkIp
1438
+ def self._ip_id_
1439
+ __getip._ip_id_
1440
+ end
1441
+ def _ip_id_
1442
+ # for RemoteTkIp
1443
+ ''
1444
+ end
1445
+
1446
+ def self.__getip
1447
+ current = Thread.current
1448
+ if TclTkLib.mainloop_thread? != false && current[:callback_ip]
1449
+ return current[:callback_ip]
1450
+ end
1451
+ if current.group == ThreadGroup::Default
1452
+ @@DEFAULT_MASTER
1453
+ else
1454
+ ip = @@IP_TABLE[current.group]
1455
+ unless ip
1456
+ fail SecurityError,
1457
+ "cannot call Tk methods on #{Thread.current.inspect}"
1458
+ end
1459
+ ip
1460
+ end
1461
+ end
1462
+ end
1463
+
1464
+
1465
+ # aliases of constructor
1466
+ class << MultiTkIp
1467
+ alias __new new
1468
+ private :__new
1469
+
1470
+ def new_master(safe=nil, keys={})
1471
+ if MultiTkIp::WITH_RUBY_VM
1472
+ #### TODO !!!!!!
1473
+ fail RuntimeError,
1474
+ 'sorry, still not support multiple master-interpreters on Ruby VM'
1475
+ end
1476
+
1477
+ if safe.kind_of?(Hash)
1478
+ keys = safe
1479
+ elsif safe.kind_of?(Integer)
1480
+ raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash)
1481
+ if !keys.key?(:safe) && !keys.key?('safe')
1482
+ keys[:safe] = safe
1483
+ end
1484
+ elsif safe == nil
1485
+ # do nothing
1486
+ else
1487
+ raise ArgumentError, "unexpected argument(s)"
1488
+ end
1489
+
1490
+ ip = __new(__getip, nil, keys)
1491
+ #ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
1492
+ if block_given?
1493
+ Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
1494
+ end
1495
+ ip
1496
+ end
1497
+
1498
+ alias new new_master
1499
+
1500
+ def new_slave(safe=nil, keys={})
1501
+ if safe.kind_of?(Hash)
1502
+ keys = safe
1503
+ elsif safe.kind_of?(Integer)
1504
+ raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash)
1505
+ if !keys.key?(:safe) && !keys.key?('safe')
1506
+ keys[:safe] = safe
1507
+ end
1508
+ elsif safe == nil
1509
+ # do nothing
1510
+ else
1511
+ raise ArgumentError, "unexpected argument(s)"
1512
+ end
1513
+
1514
+ ip = __new(__getip, false, keys)
1515
+ # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
1516
+ if block_given?
1517
+ Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
1518
+ end
1519
+ ip
1520
+ end
1521
+ alias new_trusted_slave new_slave
1522
+
1523
+ def new_safe_slave(safe=4, keys={})
1524
+ if safe.kind_of?(Hash)
1525
+ keys = safe
1526
+ elsif safe.kind_of?(Integer)
1527
+ raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash)
1528
+ if !keys.key?(:safe) && !keys.key?('safe')
1529
+ keys[:safe] = safe
1530
+ end
1531
+ else
1532
+ raise ArgumentError, "unexpected argument(s)"
1533
+ end
1534
+
1535
+ ip = __new(__getip, true, keys)
1536
+ # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
1537
+ if block_given?
1538
+ Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
1539
+ end
1540
+ ip
1541
+ end
1542
+ alias new_safeTk new_safe_slave
1543
+ end
1544
+
1545
+
1546
+ # get info
1547
+ class MultiTkIp
1548
+ def inspect
1549
+ s = self.to_s.chop!
1550
+ if self.manipulable?
1551
+ if master?
1552
+ if @interp.deleted?
1553
+ s << ':deleted-master'
1554
+ else
1555
+ s << ':master'
1556
+ end
1557
+ else
1558
+ if @interp.deleted?
1559
+ s << ':deleted-slave'
1560
+ elsif @interp.safe?
1561
+ s << ':safe-slave'
1562
+ else
1563
+ s << ':trusted-slave'
1564
+ end
1565
+ end
1566
+ end
1567
+ s << '>'
1568
+ end
1569
+
1570
+ def master?
1571
+ if @ip_name
1572
+ false
1573
+ else
1574
+ true
1575
+ end
1576
+ end
1577
+ def self.master?
1578
+ __getip.master?
1579
+ end
1580
+
1581
+ def slave?
1582
+ not master?
1583
+ end
1584
+ def self.slave?
1585
+ not self.master?
1586
+ end
1587
+
1588
+ def alive?
1589
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1590
+ begin
1591
+ return false unless @cmd_receiver.alive?
1592
+ return false if @interp.deleted?
1593
+ return false if @interp._invoke('interp', 'exists', '') == '0'
1594
+ rescue Exception
1595
+ return false
1596
+ end
1597
+ true
1598
+ end
1599
+ def self.alive?
1600
+ __getip.alive?
1601
+ end
1602
+
1603
+ def path
1604
+ @ip_name || ''
1605
+ end
1606
+ def self.path
1607
+ __getip.path
1608
+ end
1609
+ def ip_name
1610
+ @ip_name || ''
1611
+ end
1612
+ def self.ip_name
1613
+ __getip.ip_name
1614
+ end
1615
+ def to_eval
1616
+ @ip_name || ''
1617
+ end
1618
+ def self.to_eval
1619
+ __getip.to_eval
1620
+ end
1621
+
1622
+ def slaves(all = false)
1623
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1624
+ @interp._invoke('interp','slaves').split.map!{|name|
1625
+ if @slave_ip_tbl.key?(name)
1626
+ @slave_ip_tbl[name]
1627
+ elsif all
1628
+ name
1629
+ else
1630
+ nil
1631
+ end
1632
+ }.compact!
1633
+ end
1634
+ def self.slaves(all = false)
1635
+ __getip.slaves(all)
1636
+ end
1637
+
1638
+ def manipulable?
1639
+ return true if (Thread.current.group == ThreadGroup::Default)
1640
+ ip = MultiTkIp.__getip
1641
+ (ip == self) || ip._is_master_of?(@interp)
1642
+ end
1643
+ def self.manipulable?
1644
+ true
1645
+ end
1646
+
1647
+ def _is_master_of?(tcltkip_obj)
1648
+ tcltkip_obj.slave_of?(@interp)
1649
+ end
1650
+ protected :_is_master_of?
1651
+ end
1652
+
1653
+
1654
+ # instance methods to treat tables
1655
+ class MultiTkIp
1656
+ def _tk_cmd_tbl
1657
+ tbl = {}
1658
+ MultiTkIp.tk_cmd_tbl.each{|id, ent| tbl[id] = ent if ent.ip == self }
1659
+ tbl
1660
+ end
1661
+
1662
+ def _tk_windows
1663
+ @tk_windows
1664
+ end
1665
+
1666
+ def _tk_table_list
1667
+ @tk_table_list
1668
+ end
1669
+
1670
+ def _add_new_tables
1671
+ (@@TK_TABLE_LIST.size - @tk_table_list.size).times{
1672
+ (tbl = {}).tainted? || tbl.taint
1673
+ @tk_table_list << tbl
1674
+ }
1675
+ end
1676
+
1677
+ def _init_ip_env(script)
1678
+ self.eval_proc{script.call(self)}
1679
+ end
1680
+
1681
+ def _add_tk_procs(name, args, body)
1682
+ return if slave?
1683
+ @interp._invoke('proc', name, args, body) if args && body
1684
+ @interp._invoke('interp', 'slaves').split.each{|slave|
1685
+ @interp._invoke('interp', 'alias', slave, name, '', name)
1686
+ }
1687
+ end
1688
+
1689
+ def _remove_tk_procs(*names)
1690
+ return if slave?
1691
+ names.each{|name|
1692
+ name = name.to_s
1693
+
1694
+ return if @interp.deleted?
1695
+ @interp._invoke('rename', name, '')
1696
+
1697
+ return if @interp.deleted?
1698
+ @interp._invoke('interp', 'slaves').split.each{|slave|
1699
+ return if @interp.deleted?
1700
+ @interp._invoke('interp', 'alias', slave, name, '') rescue nil
1701
+ }
1702
+ }
1703
+ end
1704
+
1705
+ def _init_ip_internal(init_ip_env, add_tk_procs)
1706
+ #init_ip_env.each{|script| self.eval_proc{script.call(self)}}
1707
+ init_ip_env.each{|script| self._init_ip_env(script)}
1708
+ add_tk_procs.each{|name, args, body|
1709
+ if master?
1710
+ @interp._invoke('proc', name, args, body) if args && body
1711
+ else
1712
+ @set_alias_proc.call(name)
1713
+ end
1714
+ }
1715
+ end
1716
+ end
1717
+
1718
+
1719
+ # class methods to treat tables
1720
+ class MultiTkIp
1721
+ def self.tk_cmd_tbl
1722
+ @@TK_CMD_TBL
1723
+ end
1724
+ def self.tk_windows
1725
+ __getip._tk_windows
1726
+ end
1727
+ def self.tk_object_table(id)
1728
+ __getip._tk_table_list[id]
1729
+ end
1730
+ def self.create_table
1731
+ if __getip.slave?
1732
+ begin
1733
+ raise SecurityError, "slave-IP has no permission creating a new table"
1734
+ rescue SecurityError => e
1735
+ #p e.backtrace
1736
+ # Is called on a Ruby/Tk library?
1737
+ caller_info = e.backtrace[1]
1738
+ if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\.rb:}
1739
+ # Probably, caller is a Ruby/Tk library --> allow creating
1740
+ else
1741
+ raise e
1742
+ end
1743
+ end
1744
+ end
1745
+
1746
+ id = @@TK_TABLE_LIST.size
1747
+ obj = Object.new
1748
+ @@TK_TABLE_LIST << obj
1749
+ obj.instance_variable_set(:@id, id)
1750
+ obj.instance_variable_set(:@mutex, Mutex.new)
1751
+ obj.instance_eval{
1752
+ def self.mutex
1753
+ @mutex
1754
+ end
1755
+ def self.method_missing(m, *args)
1756
+ MultiTkIp.tk_object_table(@id).__send__(m, *args)
1757
+ end
1758
+ }
1759
+ obj.freeze
1760
+ @@IP_TABLE.each{|tg, ip| ip._add_new_tables }
1761
+ return obj
1762
+ end
1763
+
1764
+ def self.init_ip_env(script = Proc.new)
1765
+ @@INIT_IP_ENV << script
1766
+ if __getip.slave?
1767
+ begin
1768
+ raise SecurityError, "slave-IP has no permission initializing IP env"
1769
+ rescue SecurityError => e
1770
+ #p e.backtrace
1771
+ # Is called on a Ruby/Tk library?
1772
+ caller_info = e.backtrace[1]
1773
+ if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\.rb:}
1774
+ # Probably, caller is a Ruby/Tk library --> allow creating
1775
+ else
1776
+ raise e
1777
+ end
1778
+ end
1779
+ end
1780
+
1781
+ # @@IP_TABLE.each{|tg, ip|
1782
+ # ip._init_ip_env(script)
1783
+ # }
1784
+ @@DEFAULT_MASTER.__init_ip_env__(@@IP_TABLE, script)
1785
+ end
1786
+
1787
+ def self.add_tk_procs(name, args=nil, body=nil)
1788
+ if name.kind_of?(Array) # => an array of [name, args, body]
1789
+ name.each{|param| self.add_tk_procs(*param)}
1790
+ else
1791
+ name = name.to_s
1792
+ @@ADD_TK_PROCS << [name, args, body]
1793
+ @@IP_TABLE.each{|tg, ip|
1794
+ ip._add_tk_procs(name, args, body)
1795
+ }
1796
+ end
1797
+ end
1798
+
1799
+ def self.remove_tk_procs(*names)
1800
+ names.each{|name|
1801
+ name = name.to_s
1802
+ @@ADD_TK_PROCS.delete_if{|elem|
1803
+ elem.kind_of?(Array) && elem[0].to_s == name
1804
+ }
1805
+ }
1806
+ @@IP_TABLE.each{|tg, ip|
1807
+ ip._remove_tk_procs(*names)
1808
+ }
1809
+ end
1810
+
1811
+ def self.init_ip_internal
1812
+ __getip._init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
1813
+ end
1814
+ end
1815
+
1816
+
1817
+ # for callback operation
1818
+ class MultiTkIp
1819
+ def self.cb_entry_class
1820
+ @@CB_ENTRY_CLASS
1821
+ end
1822
+ def self.get_cb_entry(cmd)
1823
+ @@CB_ENTRY_CLASS.new(__getip, cmd).freeze
1824
+ end
1825
+
1826
+ =begin
1827
+ def cb_eval(cmd, *args)
1828
+ #self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }
1829
+ #ret = self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }
1830
+ ret = self.eval_callback(*args){|safe, *params|
1831
+ $SAFE=safe if $SAFE < safe
1832
+ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
1833
+ }
1834
+ if ret.kind_of?(Exception)
1835
+ raise ret
1836
+ end
1837
+ ret
1838
+ end
1839
+ =end
1840
+ def cb_eval(cmd, *args)
1841
+ self.eval_callback(*args){|safe, *params|
1842
+ $SAFE=safe if $SAFE < safe
1843
+ # TkUtil.eval_cmd(cmd, *params)
1844
+ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
1845
+ }
1846
+ end
1847
+ =begin
1848
+ def cb_eval(cmd, *args)
1849
+ @callback_status[0] ||= TkVariable.new
1850
+ @callback_status[1] ||= TkVariable.new
1851
+ st, val = @callback_status
1852
+ th = Thread.new{
1853
+ self.eval_callback(*args){|safe, *params|
1854
+ #p [status, val, safe, *params]
1855
+ $SAFE=safe if $SAFE < safe
1856
+ begin
1857
+ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
1858
+ rescue TkCallbackContinue
1859
+ st.value = 4
1860
+ rescue TkCallbackBreak
1861
+ st.value = 3
1862
+ rescue TkCallbackReturn
1863
+ st.value = 2
1864
+ rescue Exception => e
1865
+ val.value = e.message
1866
+ st.value = 1
1867
+ else
1868
+ st.value = 0
1869
+ end
1870
+ }
1871
+ }
1872
+ begin
1873
+ st.wait
1874
+ status = st.numeric
1875
+ retval = val.value
1876
+ rescue => e
1877
+ fail e
1878
+ end
1879
+
1880
+ if status == 1
1881
+ fail RuntimeError, retval
1882
+ elsif status == 2
1883
+ fail TkCallbackReturn, "Tk callback returns 'return' status"
1884
+ elsif status == 3
1885
+ fail TkCallbackBreak, "Tk callback returns 'break' status"
1886
+ elsif status == 4
1887
+ fail TkCallbackContinue, "Tk callback returns 'continue' status"
1888
+ else
1889
+ ''
1890
+ end
1891
+ end
1892
+ =end
1893
+
1894
+ end
1895
+
1896
+ # pseudo-toplevel operation support
1897
+ class MultiTkIp
1898
+ # instance method
1899
+ def __pseudo_toplevel
1900
+ ip = MultiTkIp.__getip
1901
+ (ip == @@DEFAULT_MASTER || ip == self) &&
1902
+ self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1]
1903
+ end
1904
+
1905
+ def __pseudo_toplevel=(m)
1906
+ unless (Thread.current.group == ThreadGroup::Default &&
1907
+ MultiTkIp.__getip == @@DEFAULT_MASTER)
1908
+ fail SecurityError, "no permission to manipulate"
1909
+ end
1910
+
1911
+ # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?)
1912
+ if m.respond_to?(:pseudo_toplevel_evaluable?)
1913
+ @pseudo_toplevel[0] = true
1914
+ @pseudo_toplevel[1] = m
1915
+ else
1916
+ fail ArgumentError, 'fail to set pseudo-toplevel'
1917
+ end
1918
+ self
1919
+ end
1920
+
1921
+ def __pseudo_toplevel_evaluable?
1922
+ begin
1923
+ @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable?
1924
+ rescue Exception
1925
+ false
1926
+ end
1927
+ end
1928
+
1929
+ def __pseudo_toplevel_evaluable=(mode)
1930
+ unless (Thread.current.group == ThreadGroup::Default &&
1931
+ MultiTkIp.__getip == @@DEFAULT_MASTER)
1932
+ fail SecurityError, "no permission to manipulate"
1933
+ end
1934
+
1935
+ @pseudo_toplevel[0] = (mode)? true: false
1936
+ end
1937
+ end
1938
+
1939
+ # evaluate a procedure on the proper interpreter
1940
+ class MultiTkIp
1941
+ # instance method
1942
+ def eval_proc_core(req_val, cmd, *args)
1943
+ # check
1944
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
1945
+ unless cmd.kind_of?(Proc) || cmd.kind_of?(Method)
1946
+ raise RuntimeError, "A Proc/Method object is expected for the 'cmd' argument"
1947
+ end
1948
+
1949
+ # on IP thread
1950
+ if @cmd_receiver == Thread.current ||
1951
+ (!req_val && TclTkLib.mainloop_thread? != false) # callback
1952
+ begin
1953
+ ret = cmd.call(safe_level, *args)
1954
+ rescue SystemExit => e
1955
+ # exit IP
1956
+ warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG
1957
+ begin
1958
+ self._eval_without_enc('exit')
1959
+ rescue Exception
1960
+ end
1961
+ self.delete
1962
+ ret = nil
1963
+ rescue Exception => e
1964
+ if $DEBUG
1965
+ warn("Warning: " + e.class.inspect +
1966
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
1967
+ " on " + self.inspect)
1968
+ end
1969
+ =begin
1970
+ begin
1971
+ bt = _toUTF8(e.backtrace.join("\n"))
1972
+ bt.instance_variable_set(:@encoding, 'utf-8')
1973
+ rescue Exception
1974
+ bt = e.backtrace.join("\n")
1975
+ end
1976
+ begin
1977
+ @interp._set_global_var('errorInfo', bt)
1978
+ rescue Exception
1979
+ end
1980
+ =end
1981
+ ret = e
1982
+ end
1983
+ return ret
1984
+ end
1985
+
1986
+ # send cmd to the proc-queue
1987
+ unless req_val
1988
+ begin
1989
+ @cmd_queue.enq([nil, cmd, *args])
1990
+ rescue Exception => e
1991
+ # ignore
1992
+ if $DEBUG
1993
+ warn("Warning: " + e.class.inspect +
1994
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
1995
+ " on " + self.inspect)
1996
+ end
1997
+ return e
1998
+ end
1999
+ return nil
2000
+ end
2001
+
2002
+ # send and get return value by exception
2003
+ begin
2004
+ @cmd_queue.enq([Thread.current, cmd, *args])
2005
+ Thread.stop
2006
+ rescue MultiTkIp_OK => ret
2007
+ # return value
2008
+ return ret.value
2009
+ rescue SystemExit => e
2010
+ # exit IP
2011
+ warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
2012
+ begin
2013
+ self._eval_without_enc('exit')
2014
+ rescue Exception
2015
+ end
2016
+ if !self.deleted? && !safe? && allow_ruby_exit?
2017
+ self.delete
2018
+ fail e
2019
+ else
2020
+ self.delete
2021
+ end
2022
+ rescue Exception => e
2023
+ if $DEBUG
2024
+ warn("Warning: " + e.class.inspect +
2025
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
2026
+ " on " + self.inspect)
2027
+ end
2028
+ return e
2029
+ end
2030
+ return nil
2031
+ end
2032
+ private :eval_proc_core
2033
+
2034
+ def eval_callback(*args)
2035
+ if block_given?
2036
+ cmd = Proc.new
2037
+ else
2038
+ cmd = args.shift
2039
+ end
2040
+ current = Thread.current
2041
+ backup_ip = current[:callback_ip]
2042
+ current[:callback_ip] = self
2043
+ begin
2044
+ eval_proc_core(false, cmd, *args)
2045
+ ensure
2046
+ current[:callback_ip] = backup_ip
2047
+ end
2048
+ end
2049
+
2050
+ def eval_proc(*args)
2051
+ # The scope of the eval-block of 'eval_proc' method is different from
2052
+ # the external. If you want to pass local values to the eval-block,
2053
+ # use arguments of eval_proc method. They are passed to block-arguments.
2054
+ if block_given?
2055
+ cmd = Proc.new
2056
+ else
2057
+ unless (cmd = args.shift)
2058
+ fail ArgumentError, "A Proc or Method object is expected for 1st argument"
2059
+ end
2060
+ end
2061
+ if TclTkLib.mainloop_thread? == true
2062
+ # call from eventloop
2063
+ current = Thread.current
2064
+ backup_ip = current[:callback_ip]
2065
+ current[:callback_ip] = self
2066
+ begin
2067
+ eval_proc_core(false,
2068
+ proc{|safe, *params|
2069
+ $SAFE=safe if $SAFE < safe
2070
+ cmd.call(*params)
2071
+ }, *args)
2072
+ ensure
2073
+ current[:callback_ip] = backup_ip
2074
+ end
2075
+ else
2076
+ eval_proc_core(true,
2077
+ proc{|safe, *params|
2078
+ $SAFE=safe if $SAFE < safe
2079
+ Thread.new(*params, &cmd).value
2080
+ },
2081
+ *args)
2082
+ end
2083
+ end
2084
+ alias call eval_proc
2085
+
2086
+ def bg_eval_proc(*args)
2087
+ if block_given?
2088
+ cmd = Proc.new
2089
+ else
2090
+ unless (cmd = args.shift)
2091
+ fail ArgumentError, "A Proc or Method object is expected for 1st argument"
2092
+ end
2093
+ end
2094
+ Thread.new{
2095
+ eval_proc(cmd, *args)
2096
+ =begin
2097
+ eval_proc_core(false,
2098
+ proc{|safe, *params|
2099
+ $SAFE=safe if $SAFE < safe
2100
+ Thread.new(*params, &cmd).value
2101
+ },
2102
+ safe_level, *args)
2103
+ =end
2104
+ }
2105
+ end
2106
+ alias background_eval_proc bg_eval_proc
2107
+ alias thread_eval_proc bg_eval_proc
2108
+ alias bg_call bg_eval_proc
2109
+ alias background_call bg_eval_proc
2110
+
2111
+ def eval_string(cmd, *eval_args)
2112
+ # cmd string ==> proc
2113
+ unless cmd.kind_of?(String)
2114
+ raise RuntimeError, "A String object is expected for the 'cmd' argument"
2115
+ end
2116
+
2117
+ eval_proc_core(true,
2118
+ proc{|safe|
2119
+ Kernel.eval("$SAFE=#{safe} if $SAFE < #{safe};" << cmd,
2120
+ *eval_args)
2121
+ })
2122
+ end
2123
+ alias eval_str eval_string
2124
+
2125
+ def bg_eval_string(cmd, *eval_args)
2126
+ # cmd string ==> proc
2127
+ unless cmd.kind_of?(String)
2128
+ raise RuntimeError, "A String object is expected for the 'cmd' argument"
2129
+ end
2130
+ Thread.new{
2131
+ eval_proc_core(true,
2132
+ proc{|safe|
2133
+ Kernel.eval("$SAFE=#{safe} if $SAFE < #{safe};" << cmd,
2134
+ *eval_args)
2135
+ })
2136
+ }
2137
+ end
2138
+ alias background_eval_string bg_eval_string
2139
+ alias bg_eval_str bg_eval_string
2140
+ alias background_eval_str bg_eval_string
2141
+
2142
+ def eval(*args, &blk)
2143
+ if block_given?
2144
+ eval_proc(*args, &blk)
2145
+ elsif args[0]
2146
+ if args[0].respond_to?(:call)
2147
+ eval_proc(*args)
2148
+ else
2149
+ eval_string(*args)
2150
+ end
2151
+ else
2152
+ fail ArgumentError, "no argument to eval"
2153
+ end
2154
+ end
2155
+
2156
+ def bg_eval(*args, &blk)
2157
+ if block_given?
2158
+ bg_eval_proc(*args, &blk)
2159
+ elsif args[0]
2160
+ if args[0].respond_to?(:call)
2161
+ bg_eval_proc(*args)
2162
+ else
2163
+ bg_eval_string(*args)
2164
+ end
2165
+ else
2166
+ fail ArgumentError, "no argument to eval"
2167
+ end
2168
+ end
2169
+ alias background_eval bg_eval
2170
+ end
2171
+
2172
+ class << MultiTkIp
2173
+ # class method
2174
+ def eval_proc(*args, &blk)
2175
+ # class ==> interp object
2176
+ __getip.eval_proc(*args, &blk)
2177
+ end
2178
+ alias call eval_proc
2179
+
2180
+ def bg_eval_proc(*args, &blk)
2181
+ # class ==> interp object
2182
+ __getip.bg_eval_proc(*args, &blk)
2183
+ end
2184
+ alias background_eval_proc bg_eval_proc
2185
+ alias thread_eval_proc bg_eval_proc
2186
+ alias bg_call bg_eval_proc
2187
+ alias background_call bg_eval_proc
2188
+
2189
+ def eval_string(cmd, *eval_args)
2190
+ # class ==> interp object
2191
+ __getip.eval_string(cmd, *eval_args)
2192
+ end
2193
+ alias eval_str eval_string
2194
+
2195
+ def bg_eval_string(cmd, *eval_args)
2196
+ # class ==> interp object
2197
+ __getip.bg_eval_string(cmd, *eval_args)
2198
+ end
2199
+ alias background_eval_string bg_eval_string
2200
+ alias bg_eval_str bg_eval_string
2201
+ alias background_eval_str bg_eval_string
2202
+
2203
+ def eval(*args, &blk)
2204
+ # class ==> interp object
2205
+ __getip.eval(*args, &blk)
2206
+ end
2207
+ def bg_eval(*args, &blk)
2208
+ # class ==> interp object
2209
+ __getip.bg_eval(*args, &blk)
2210
+ end
2211
+ alias background_eval bg_eval
2212
+ end
2213
+
2214
+
2215
+ # event loop
2216
+ # all master/slave IPs are controled by only one event-loop
2217
+ class MultiTkIp
2218
+ def self.default_master?
2219
+ __getip == @@DEFAULT_MASTER
2220
+ end
2221
+ end
2222
+ class << MultiTkIp
2223
+ def mainloop(check_root = true)
2224
+ __getip.mainloop(check_root)
2225
+ end
2226
+ def mainloop_watchdog(check_root = true)
2227
+ __getip.mainloop_watchdog(check_root)
2228
+ end
2229
+ def do_one_event(flag = TclTkLib::EventFlag::ALL)
2230
+ __getip.do_one_event(flag)
2231
+ end
2232
+ def mainloop_abort_on_exception
2233
+ # __getip.mainloop_abort_on_exception
2234
+ TclTkLib.mainloop_abort_on_exception
2235
+ end
2236
+ def mainloop_abort_on_exception=(mode)
2237
+ # __getip.mainloop_abort_on_exception=(mode)
2238
+ TclTkLib.mainloop_abort_on_exception=(mode)
2239
+ end
2240
+ def set_eventloop_tick(tick)
2241
+ __getip.set_eventloop_tick(tick)
2242
+ end
2243
+ def get_eventloop_tick
2244
+ __getip.get_eventloop_tick
2245
+ end
2246
+ def set_no_event_wait(tick)
2247
+ __getip.set_no_event_wait(tick)
2248
+ end
2249
+ def get_no_event_wait
2250
+ __getip.get_no_event_wait
2251
+ end
2252
+ def set_eventloop_weight(loop_max, no_event_tick)
2253
+ __getip.set_eventloop_weight(loop_max, no_event_tick)
2254
+ end
2255
+ def get_eventloop_weight
2256
+ __getip.get_eventloop_weight
2257
+ end
2258
+ end
2259
+
2260
+ # class methods to delegate to TclTkIp
2261
+ class << MultiTkIp
2262
+ def method_missing(id, *args)
2263
+ __getip.__send__(id, *args)
2264
+ end
2265
+
2266
+ def make_safe
2267
+ __getip.make_safe
2268
+ end
2269
+
2270
+ def safe?
2271
+ __getip.safe?
2272
+ end
2273
+
2274
+ def safe_base?
2275
+ begin
2276
+ __getip.safe_base?
2277
+ rescue
2278
+ false
2279
+ end
2280
+ end
2281
+
2282
+ def allow_ruby_exit?
2283
+ __getip.allow_ruby_exit?
2284
+ end
2285
+
2286
+ def allow_ruby_exit= (mode)
2287
+ __getip.allow_ruby_exit = mode
2288
+ end
2289
+
2290
+ def delete
2291
+ __getip.delete
2292
+ end
2293
+
2294
+ def deleted?
2295
+ __getip.deleted?
2296
+ end
2297
+
2298
+ def has_mainwindow?
2299
+ __getip.has_mainwindow?
2300
+ end
2301
+
2302
+ def invalid_namespace?
2303
+ __getip.invalid_namespace?
2304
+ end
2305
+
2306
+ def abort(msg = nil)
2307
+ __getip.abort(msg)
2308
+ end
2309
+
2310
+ def exit(st = true)
2311
+ __getip.exit(st)
2312
+ end
2313
+
2314
+ def exit!(st = false)
2315
+ __getip.exit!(st)
2316
+ end
2317
+
2318
+ def restart(app_name = nil, keys = {})
2319
+ init_ip_internal
2320
+
2321
+ __getip._invoke('set', 'argv0', app_name) if app_name
2322
+ if keys.kind_of?(Hash)
2323
+ __getip._invoke('set', 'argv', _keys2opts(keys))
2324
+ end
2325
+
2326
+ __getip.restart
2327
+ end
2328
+
2329
+ def _eval(str)
2330
+ __getip._eval(str)
2331
+ end
2332
+
2333
+ def _invoke(*args)
2334
+ __getip._invoke(*args)
2335
+ end
2336
+
2337
+ def _eval_without_enc(str)
2338
+ __getip._eval_without_enc(str)
2339
+ end
2340
+
2341
+ def _invoke_without_enc(*args)
2342
+ __getip._invoke_without_enc(*args)
2343
+ end
2344
+
2345
+ def _eval_with_enc(str)
2346
+ __getip._eval_with_enc(str)
2347
+ end
2348
+
2349
+ def _invoke_with_enc(*args)
2350
+ __getip._invoke_with_enc(*args)
2351
+ end
2352
+
2353
+ def _toUTF8(str, encoding=nil)
2354
+ __getip._toUTF8(str, encoding)
2355
+ end
2356
+
2357
+ def _fromUTF8(str, encoding=nil)
2358
+ __getip._fromUTF8(str, encoding)
2359
+ end
2360
+
2361
+ def _thread_vwait(var)
2362
+ __getip._thread_vwait(var)
2363
+ end
2364
+
2365
+ def _thread_tkwait(mode, target)
2366
+ __getip._thread_tkwait(mode, target)
2367
+ end
2368
+
2369
+ def _return_value
2370
+ __getip._return_value
2371
+ end
2372
+
2373
+ def _get_variable(var, flag)
2374
+ __getip._get_variable(var, flag)
2375
+ end
2376
+ def _get_variable2(var, idx, flag)
2377
+ __getip._get_variable2(var, idx, flag)
2378
+ end
2379
+ def _set_variable(var, value, flag)
2380
+ __getip._set_variable(var, value, flag)
2381
+ end
2382
+ def _set_variable2(var, idx, value, flag)
2383
+ __getip._set_variable2(var, idx, value, flag)
2384
+ end
2385
+ def _unset_variable(var, flag)
2386
+ __getip._unset_variable(var, flag)
2387
+ end
2388
+ def _unset_variable2(var, idx, flag)
2389
+ __getip._unset_variable2(var, idx, flag)
2390
+ end
2391
+
2392
+ def _get_global_var(var)
2393
+ __getip._get_global_var(var)
2394
+ end
2395
+ def _get_global_var2(var, idx)
2396
+ __getip._get_global_var2(var, idx)
2397
+ end
2398
+ def _set_global_var(var, value)
2399
+ __getip._set_global_var(var, value)
2400
+ end
2401
+ def _set_global_var2(var, idx, value)
2402
+ __getip._set_global_var2(var, idx, value)
2403
+ end
2404
+ def _unset_global_var(var)
2405
+ __getip._unset_global_var(var)
2406
+ end
2407
+ def _unset_global_var2(var, idx)
2408
+ __getip._unset_global_var2(var, idx)
2409
+ end
2410
+
2411
+ def _make_menu_embeddable(menu_path)
2412
+ __getip._make_menu_embeddable(menu_path)
2413
+ end
2414
+
2415
+ def _split_tklist(str)
2416
+ __getip._split_tklist(str)
2417
+ end
2418
+ def _merge_tklist(*args)
2419
+ __getip._merge_tklist(*args)
2420
+ end
2421
+ def _conv_listelement(arg)
2422
+ __getip._conv_listelement(arg)
2423
+ end
2424
+
2425
+ def _create_console
2426
+ __getip._create_console
2427
+ end
2428
+ end
2429
+
2430
+
2431
+ # wrap methods on TclTkLib : not permit calling TclTkLib module methods
2432
+ class << TclTkLib
2433
+ def mainloop(check_root = true)
2434
+ MultiTkIp.mainloop(check_root)
2435
+ end
2436
+ def mainloop_watchdog(check_root = true)
2437
+ MultiTkIp.mainloop_watchdog(check_root)
2438
+ end
2439
+ def do_one_event(flag = TclTkLib::EventFlag::ALL)
2440
+ MultiTkIp.do_one_event(flag)
2441
+ end
2442
+ #def mainloop_abort_on_exception
2443
+ # MultiTkIp.mainloop_abort_on_exception
2444
+ #end
2445
+ #def mainloop_abort_on_exception=(mode)
2446
+ # MultiTkIp.mainloop_abort_on_exception=(mode)
2447
+ #end
2448
+ def set_eventloop_tick(tick)
2449
+ MultiTkIp.set_eventloop_tick(tick)
2450
+ end
2451
+ def get_eventloop_tick
2452
+ MultiTkIp.get_eventloop_tick
2453
+ end
2454
+ def set_no_event_wait(tick)
2455
+ MultiTkIp.set_no_event_wait(tick)
2456
+ end
2457
+ def get_no_event_wait
2458
+ MultiTkIp.get_no_event_wait
2459
+ end
2460
+ def set_eventloop_weight(loop_max, no_event_tick)
2461
+ MultiTkIp.set_eventloop_weight(loop_max, no_event_tick)
2462
+ end
2463
+ def get_eventloop_weight
2464
+ MultiTkIp.get_eventloop_weight
2465
+ end
2466
+ def restart(*args)
2467
+ MultiTkIp.restart(*args)
2468
+ end
2469
+
2470
+ def _merge_tklist(*args)
2471
+ MultiTkIp._merge_tklist(*args)
2472
+ end
2473
+ def _conv_listelement(arg)
2474
+ MultiTkIp._conv_listelement(arg)
2475
+ end
2476
+ end
2477
+
2478
+
2479
+ # depend on TclTkIp
2480
+ class MultiTkIp
2481
+ def mainloop(check_root = true, restart_on_dead = true)
2482
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2483
+
2484
+ if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
2485
+ return @interp_thread.value if @interp_thread
2486
+ end
2487
+
2488
+ #return self if self.slave?
2489
+ #return self if self != @@DEFAULT_MASTER
2490
+ if self != @@DEFAULT_MASTER
2491
+ if @wait_on_mainloop[0]
2492
+ begin
2493
+ @wait_on_mainloop[1] += 1
2494
+ if $SAFE >= 4
2495
+ _receiver_mainloop(check_root).join
2496
+ else
2497
+ @cmd_queue.enq([@system, 'call_mainloop',
2498
+ Thread.current, check_root])
2499
+ Thread.stop
2500
+ end
2501
+ rescue MultiTkIp_OK => ret
2502
+ # return value
2503
+ if ret.value.kind_of?(Thread)
2504
+ return ret.value.value
2505
+ else
2506
+ return ret.value
2507
+ end
2508
+ rescue SystemExit => e
2509
+ # exit IP
2510
+ warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
2511
+ begin
2512
+ self._eval_without_enc('exit')
2513
+ rescue Exception
2514
+ end
2515
+ self.delete
2516
+ rescue StandardError => e
2517
+ if $DEBUG
2518
+ warn("Warning: " + e.class.inspect +
2519
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
2520
+ " on " + self.inspect)
2521
+ end
2522
+ return e
2523
+ rescue Exception => e
2524
+ return e
2525
+ ensure
2526
+ @wait_on_mainloop[1] -= 1
2527
+ end
2528
+ end
2529
+ return
2530
+ end
2531
+
2532
+ unless restart_on_dead
2533
+ @wait_on_mainloop[1] += 1
2534
+ =begin
2535
+ begin
2536
+ @interp.mainloop(check_root)
2537
+ rescue StandardError => e
2538
+ if $DEBUG
2539
+ warn("Warning: " + e.class.inspect +
2540
+ ((e.message.length > 0)? ' "' + e.message + '"': '') +
2541
+ " on " + self.inspect)
2542
+ end
2543
+ end
2544
+ =end
2545
+ begin
2546
+ @interp.mainloop(check_root)
2547
+ ensure
2548
+ @wait_on_mainloop[1] -= 1
2549
+ end
2550
+ else
2551
+ loop do
2552
+ break unless self.alive?
2553
+ if check_root
2554
+ begin
2555
+ break if TclTkLib.num_of_mainwindows == 0
2556
+ rescue StandardError
2557
+ break
2558
+ end
2559
+ end
2560
+ break if @interp.deleted?
2561
+ begin
2562
+ @wait_on_mainloop[1] += 1
2563
+ @interp.mainloop(check_root)
2564
+ rescue StandardError => e
2565
+ if TclTkLib.mainloop_abort_on_exception != nil
2566
+ #STDERR.print("Warning: Tk mainloop receives ", $!.class.inspect,
2567
+ # " exception (ignore) : ", $!.message, "\n");
2568
+ if $DEBUG
2569
+ warn("Warning: Tk mainloop receives " << e.class.inspect <<
2570
+ " exception (ignore) : " << e.message);
2571
+ end
2572
+ end
2573
+ #raise e
2574
+ rescue Exception => e
2575
+ =begin
2576
+ if TclTkLib.mainloop_abort_on_exception != nil
2577
+ #STDERR.print("Warning: Tk mainloop receives ", $!.class.inspect,
2578
+ # " exception (ignore) : ", $!.message, "\n");
2579
+ if $DEBUG
2580
+ warn("Warning: Tk mainloop receives " << e.class.inspect <<
2581
+ " exception (ignore) : " << e.message);
2582
+ end
2583
+ end
2584
+ =end
2585
+ raise e
2586
+ ensure
2587
+ @wait_on_mainloop[1] -= 1
2588
+ Thread.pass # avoid eventloop conflict
2589
+ end
2590
+ end
2591
+ end
2592
+ self
2593
+ end
2594
+
2595
+ def make_safe
2596
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2597
+ @interp.make_safe
2598
+ end
2599
+
2600
+ def safe?
2601
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2602
+ @interp.safe?
2603
+ end
2604
+
2605
+ def safe_base?
2606
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2607
+ @safe_base
2608
+ end
2609
+
2610
+ def allow_ruby_exit?
2611
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2612
+ @interp.allow_ruby_exit?
2613
+ end
2614
+
2615
+ def allow_ruby_exit= (mode)
2616
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2617
+ @interp.allow_ruby_exit = mode
2618
+ end
2619
+
2620
+ def delete
2621
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2622
+ @slave_ip_tbl.each{|name, subip|
2623
+ _destroy_slaves_of_slaveIP(subip)
2624
+ =begin
2625
+ begin
2626
+ subip._invoke('destroy', '.') unless subip.deleted?
2627
+ rescue Exception
2628
+ end
2629
+ =end
2630
+ begin
2631
+ # subip._eval_without_enc("foreach i [after info] {after cancel $i}")
2632
+ unless subip.deleted?
2633
+ after_ids = subip._eval_without_enc("after info")
2634
+ subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
2635
+ end
2636
+ rescue Exception
2637
+ end
2638
+
2639
+ # safe_base?
2640
+ if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0'
2641
+ begin
2642
+ @interp._eval_without_enc("::safe::interpDelete #{name}")
2643
+ rescue Exception
2644
+ else
2645
+ next if subip.deleted?
2646
+ end
2647
+ end
2648
+ if subip.respond_to?(:safe_base?) && subip.safe_base? &&
2649
+ !subip.deleted?
2650
+ # do 'exit' to call the delete_hook procedure
2651
+ begin
2652
+ subip._eval_without_enc('exit')
2653
+ rescue Exception
2654
+ end
2655
+ else
2656
+ begin
2657
+ subip.delete unless subip.deleted?
2658
+ rescue Exception
2659
+ end
2660
+ end
2661
+ }
2662
+
2663
+ begin
2664
+ # @interp._eval_without_enc("foreach i [after info] {after cancel $i}")
2665
+ after_ids = @interp._eval_without_enc("after info")
2666
+ @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}")
2667
+ rescue Exception
2668
+ end
2669
+
2670
+ begin
2671
+ @interp._invoke('destroy', '.') unless @interp.deleted?
2672
+ rescue Exception
2673
+ end
2674
+
2675
+ if @safe_base && !@interp.deleted?
2676
+ # do 'exit' to call the delete_hook procedure
2677
+ @interp._eval_without_enc('exit')
2678
+ end
2679
+ @interp.delete
2680
+ self
2681
+ end
2682
+
2683
+ def deleted?
2684
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2685
+ @interp.deleted?
2686
+ end
2687
+
2688
+ def has_mainwindow?
2689
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2690
+ @interp.has_mainwindow?
2691
+ end
2692
+
2693
+ def invalid_namespace?
2694
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2695
+ @interp.invalid_namespace?
2696
+ end
2697
+
2698
+ def abort(msg = nil)
2699
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2700
+ if master? && !safe? && allow_ruby_exit?
2701
+ if msg
2702
+ Kernel.abort(msg)
2703
+ else
2704
+ Kernel.abort
2705
+ end
2706
+ else
2707
+ # ignore msg
2708
+ delete
2709
+ 1
2710
+ end
2711
+ end
2712
+
2713
+ def exit(st = true)
2714
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2715
+ if master? && !safe? && allow_ruby_exit?
2716
+ Kernel.exit(st)
2717
+ else
2718
+ delete
2719
+ st
2720
+ end
2721
+ end
2722
+
2723
+ def exit!(st = false)
2724
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2725
+ if master? && !safe? && allow_ruby_exit?
2726
+ Kernel.exit!(st)
2727
+ else
2728
+ delete
2729
+ st
2730
+ end
2731
+ end
2732
+
2733
+ def restart(app_name = nil, keys = {})
2734
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2735
+
2736
+ _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
2737
+
2738
+ @interp._invoke('set', 'argv0', app_name) if app_name
2739
+ if keys.kind_of?(Hash)
2740
+ @interp._invoke('set', 'argv', _keys2opts(keys))
2741
+ end
2742
+
2743
+ @interp.restart
2744
+ end
2745
+
2746
+ def __eval(str)
2747
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2748
+ @interp.__eval(str)
2749
+ end
2750
+
2751
+ def __invoke(*args)
2752
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2753
+ @interp.__invoke(*args)
2754
+ end
2755
+
2756
+ def _eval(str)
2757
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2758
+ @interp._eval(str)
2759
+ end
2760
+
2761
+ def _invoke(*args)
2762
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2763
+ @interp._invoke(*args)
2764
+ end
2765
+
2766
+ def _eval_without_enc(str)
2767
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2768
+ @interp._eval_without_enc(str)
2769
+ end
2770
+
2771
+ def _invoke_without_enc(*args)
2772
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2773
+ @interp._invoke_without_enc(*args)
2774
+ end
2775
+
2776
+ def _eval_with_enc(str)
2777
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2778
+ @interp._eval_with_enc(str)
2779
+ end
2780
+
2781
+ def _invoke_with_enc(*args)
2782
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2783
+ @interp._invoke_with_enc(*args)
2784
+ end
2785
+
2786
+ def _toUTF8(str, encoding=nil)
2787
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2788
+ @interp._toUTF8(str, encoding)
2789
+ end
2790
+
2791
+ def _fromUTF8(str, encoding=nil)
2792
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2793
+ @interp._fromUTF8(str, encoding)
2794
+ end
2795
+
2796
+ def _thread_vwait(var)
2797
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2798
+ @interp._thread_vwait(var)
2799
+ end
2800
+
2801
+ def _thread_tkwait(mode, target)
2802
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2803
+ @interp._thread_tkwait(mode, target)
2804
+ end
2805
+
2806
+ def _return_value
2807
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2808
+ @interp._return_value
2809
+ end
2810
+
2811
+ def _get_variable(var, flag)
2812
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2813
+ @interp._get_variable(var, flag)
2814
+ end
2815
+ def _get_variable2(var, idx, flag)
2816
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2817
+ @interp._get_variable2(var, idx, flag)
2818
+ end
2819
+ def _set_variable(var, value, flag)
2820
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2821
+ @interp._set_variable(var, value, flag)
2822
+ end
2823
+ def _set_variable2(var, idx, value, flag)
2824
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2825
+ @interp._set_variable2(var, idx, value, flag)
2826
+ end
2827
+ def _unset_variable(var, flag)
2828
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2829
+ @interp._unset_variable(var, flag)
2830
+ end
2831
+ def _unset_variable2(var, idx, flag)
2832
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2833
+ @interp._unset_variable2(var, idx, flag)
2834
+ end
2835
+
2836
+ def _get_global_var(var)
2837
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2838
+ @interp._get_global_var(var)
2839
+ end
2840
+ def _get_global_var2(var, idx)
2841
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2842
+ @interp._get_global_var2(var, idx)
2843
+ end
2844
+ def _set_global_var(var, value)
2845
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2846
+ @interp._set_global_var(var, value)
2847
+ end
2848
+ def _set_global_var2(var, idx, value)
2849
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2850
+ @interp._set_global_var2(var, idx, value)
2851
+ end
2852
+ def _unset_global_var(var)
2853
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2854
+ @interp._unset_global_var(var)
2855
+ end
2856
+ def _unset_global_var2(var, idx)
2857
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2858
+ @interp._unset_global_var2(var, idx)
2859
+ end
2860
+
2861
+ def _make_menu_embeddable(menu_path)
2862
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2863
+ @interp._make_menu_embeddable(menu_path)
2864
+ end
2865
+
2866
+ def _split_tklist(str)
2867
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2868
+ @interp._split_tklist(str)
2869
+ end
2870
+ def _merge_tklist(*args)
2871
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2872
+ @interp._merge_tklist(*args)
2873
+ end
2874
+ def _conv_listelement(arg)
2875
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2876
+ @interp._conv_listelement(arg)
2877
+ end
2878
+ end
2879
+
2880
+
2881
+ # interp command support
2882
+ class MultiTkIp
2883
+ def _lst2ary(str)
2884
+ return [] if str == ""
2885
+ idx = str.index('{')
2886
+ while idx and idx > 0 and str[idx-1] == ?\\
2887
+ idx = str.index('{', idx+1)
2888
+ end
2889
+ return str.split unless idx
2890
+
2891
+ list = str[0,idx].split
2892
+ str = str[idx+1..-1]
2893
+ i = -1
2894
+ brace = 1
2895
+ str.each_byte {|c|
2896
+ c = c.chr
2897
+ i += 1
2898
+ brace += 1 if c == '{'
2899
+ brace -= 1 if c == '}'
2900
+ break if brace == 0
2901
+ }
2902
+ if i == 0
2903
+ list.push ''
2904
+ elsif str[0, i] == ' '
2905
+ list.push ' '
2906
+ else
2907
+ list.push str[0..i-1]
2908
+ end
2909
+ #list += _lst2ary(str[i+1..-1])
2910
+ list.concat(_lst2ary(str[i+1..-1]))
2911
+ list
2912
+ end
2913
+ private :_lst2ary
2914
+
2915
+ def _slavearg(slave)
2916
+ if slave.kind_of?(MultiTkIp)
2917
+ slave.path
2918
+ elsif slave.kind_of?(String)
2919
+ slave
2920
+ else
2921
+ slave.to_s
2922
+ end
2923
+ end
2924
+ private :_slavearg
2925
+
2926
+ def alias_info(slave, cmd_name)
2927
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2928
+ _lst2ary(@interp._invoke('interp', 'alias', _slavearg(slave), cmd_name))
2929
+ end
2930
+ def self.alias_info(slave, cmd_name)
2931
+ __getip.alias_info(slave, cmd_name)
2932
+ end
2933
+
2934
+ def alias_delete(slave, cmd_name)
2935
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2936
+ @interp._invoke('interp', 'alias', _slavearg(slave), cmd_name, '')
2937
+ self
2938
+ end
2939
+ def self.alias_delete(slave, cmd_name)
2940
+ __getip.alias_delete(slave, cmd_name)
2941
+ self
2942
+ end
2943
+
2944
+ def def_alias(slave, new_cmd, org_cmd, *args)
2945
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2946
+ ret = @interp._invoke('interp', 'alias', _slavearg(slave), new_cmd,
2947
+ '', org_cmd, *args)
2948
+ (ret == new_cmd)? self: nil
2949
+ end
2950
+ def self.def_alias(slave, new_cmd, org_cmd, *args)
2951
+ ret = __getip.def_alias(slave, new_cmd, org_cmd, *args)
2952
+ (ret == new_cmd)? self: nil
2953
+ end
2954
+
2955
+ def aliases(slave = '')
2956
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2957
+ _lst2ary(@interp._invoke('interp', 'aliases', _slavearg(slave)))
2958
+ end
2959
+ def self.aliases(slave = '')
2960
+ __getip.aliases(slave)
2961
+ end
2962
+
2963
+ def delete_slaves(*args)
2964
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2965
+ slaves = args.collect{|s| _slavearg(s)}
2966
+ @interp._invoke('interp', 'delete', *slaves) if slaves.size > 0
2967
+ self
2968
+ end
2969
+ def self.delete_slaves(*args)
2970
+ __getip.delete_slaves(*args)
2971
+ self
2972
+ end
2973
+
2974
+ def exist?(slave = '')
2975
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2976
+ ret = @interp._invoke('interp', 'exists', _slavearg(slave))
2977
+ (ret == '1')? true: false
2978
+ end
2979
+ def self.exist?(slave = '')
2980
+ __getip.exist?(slave)
2981
+ end
2982
+
2983
+ def delete_cmd(slave, cmd)
2984
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2985
+ slave_invoke = @interp._invoke('list', 'rename', cmd, '')
2986
+ @interp._invoke('interp', 'eval', _slavearg(slave), slave_invoke)
2987
+ self
2988
+ end
2989
+ def self.delete_cmd(slave, cmd)
2990
+ __getip.delete_cmd(slave, cmd)
2991
+ self
2992
+ end
2993
+
2994
+ def expose_cmd(slave, cmd, aliasname = nil)
2995
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
2996
+ if aliasname
2997
+ @interp._invoke('interp', 'expose', _slavearg(slave), cmd, aliasname)
2998
+ else
2999
+ @interp._invoke('interp', 'expose', _slavearg(slave), cmd)
3000
+ end
3001
+ self
3002
+ end
3003
+ def self.expose_cmd(slave, cmd, aliasname = nil)
3004
+ __getip.expose_cmd(slave, cmd, aliasname)
3005
+ self
3006
+ end
3007
+
3008
+ def hide_cmd(slave, cmd, aliasname = nil)
3009
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3010
+ if aliasname
3011
+ @interp._invoke('interp', 'hide', _slavearg(slave), cmd, aliasname)
3012
+ else
3013
+ @interp._invoke('interp', 'hide', _slavearg(slave), cmd)
3014
+ end
3015
+ self
3016
+ end
3017
+ def self.hide_cmd(slave, cmd, aliasname = nil)
3018
+ __getip.hide_cmd(slave, cmd, aliasname)
3019
+ self
3020
+ end
3021
+
3022
+ def hidden_cmds(slave = '')
3023
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3024
+ _lst2ary(@interp._invoke('interp', 'hidden', _slavearg(slave)))
3025
+ end
3026
+ def self.hidden_cmds(slave = '')
3027
+ __getip.hidden_cmds(slave)
3028
+ end
3029
+
3030
+ def invoke_hidden(slave, cmd, *args)
3031
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3032
+ if args[-1].kind_of?(Hash)
3033
+ keys = _symbolkey2str(args.pop)
3034
+ else
3035
+ keys = []
3036
+ end
3037
+ keys << _slavearg(slave)
3038
+ if Tk::TCL_MAJOR_VERSION > 8 ||
3039
+ (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)
3040
+ keys << '--'
3041
+ end
3042
+ keys << cmd
3043
+ keys.concat(args)
3044
+ @interp._invoke('interp', 'invokehidden', *keys)
3045
+ end
3046
+ def self.invoke_hidden(slave, cmd, *args)
3047
+ __getip.invoke_hidden(slave, cmd, *args)
3048
+ end
3049
+
3050
+ def invoke_hidden_on_global(slave, cmd, *args)
3051
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3052
+ if args[-1].kind_of?(Hash)
3053
+ keys = _symbolkey2str(args.pop)
3054
+ else
3055
+ keys = []
3056
+ end
3057
+ keys << _slavearg(slave)
3058
+ keys << '-global'
3059
+ if Tk::TCL_MAJOR_VERSION > 8 ||
3060
+ (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)
3061
+ keys << '--'
3062
+ end
3063
+ keys << cmd
3064
+ keys.concat(args)
3065
+ @interp._invoke('interp', 'invokehidden', *keys)
3066
+ end
3067
+ def self.invoke_hidden_on_global(slave, cmd, *args)
3068
+ __getip.invoke_hidden_on_global(slave, cmd, *args)
3069
+ end
3070
+
3071
+ def invoke_hidden_on_namespace(slave, ns, cmd, *args)
3072
+ # for Tcl8.5 or later
3073
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3074
+ if args[-1].kind_of?(Hash)
3075
+ keys = _symbolkey2str(args.pop)
3076
+ else
3077
+ keys = []
3078
+ end
3079
+ keys << _slavearg(slave)
3080
+ keys << '-namespace' << TkComm._get_eval_string(ns)
3081
+ keys << '--' << cmd
3082
+ keys.concat(args)
3083
+ @interp._invoke('interp', 'invokehidden', *keys)
3084
+ end
3085
+ def self.invoke_hidden_on_namespace(slave, ns, cmd, *args)
3086
+ __getip.invoke_hidden_on_namespace(slave, ns, cmd, *args)
3087
+ end
3088
+
3089
+ def mark_trusted(slave = '')
3090
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3091
+ @interp._invoke('interp', 'marktrusted', _slavearg(slave))
3092
+ self
3093
+ end
3094
+ def self.mark_trusted(slave = '')
3095
+ __getip.mark_trusted(slave)
3096
+ self
3097
+ end
3098
+
3099
+ def set_bgerror_handler(cmd = Proc.new, slave = nil, &b)
3100
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3101
+
3102
+ unless TkComm._callback_entry?(cmd)
3103
+ if !slave && b
3104
+ slave = cmd
3105
+ cmd = Proc.new(&b)
3106
+ end
3107
+ end
3108
+ slave = '' unless slave
3109
+
3110
+ @interp._invoke('interp', 'bgerror', _slavearg(slave), cmd)
3111
+ end
3112
+ def self.bgerror(cmd = Proc.new, slave = nil, &b)
3113
+ __getip.bgerror(cmd, slave, &b)
3114
+ end
3115
+
3116
+ def get_bgerror_handler(slave = '')
3117
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3118
+ procedure(@interp._invoke('interp', 'bgerror', _slavearg(slave)))
3119
+ end
3120
+ def self.bgerror(slave = '')
3121
+ __getip.bgerror(slave)
3122
+ end
3123
+
3124
+ def set_limit(limit_type, slave = '', opts = {})
3125
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3126
+ @interp._invoke('interp', 'limit', _slavearg(slave), limit_type, opts)
3127
+ end
3128
+ def self.set_limit(limit_type, slave = '', opts = {})
3129
+ __getip.set_limit(limit_type, slave, opts)
3130
+ end
3131
+
3132
+ def get_limit(limit_type, slave = '', slot = nil)
3133
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3134
+
3135
+ if slot
3136
+ num_or_str(@interp._invoke('interp', 'limit', _slavearg(slave),
3137
+ limit_type, slot))
3138
+ else
3139
+ l = @interp._split_tklist(@interp._invoke_without_enc('interp', 'limit',
3140
+ _slavearg(slave),
3141
+ limit_type))
3142
+ l.map!{|s| _fromUTF8(s)}
3143
+ r = {}
3144
+ until l.empty?
3145
+ key = l.shift[1..-1]
3146
+ val = l.shift
3147
+ val = num_or_str(val) if val
3148
+ r[key] = val
3149
+ end
3150
+ r
3151
+ end
3152
+ end
3153
+ def self.get_limit(limit_type, slave = '', slot = nil)
3154
+ __getip.get_limit(limit_type, slave, slot)
3155
+ end
3156
+
3157
+ def recursion_limit(slave = '', limit = None)
3158
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3159
+ number(@interp._invoke('interp', 'recursionlimit',
3160
+ _slavearg(slave), limit))
3161
+ end
3162
+ def self.recursion_limit(slave = '', limit = None)
3163
+ __getip.recursion_limit(slave)
3164
+ end
3165
+
3166
+ def alias_target(aliascmd, slave = '')
3167
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3168
+ @interp._invoke('interp', 'target', _slavearg(slave), aliascmd)
3169
+ end
3170
+ def self.alias_target(aliascmd, slave = '')
3171
+ __getip.alias_target(aliascmd, slave)
3172
+ end
3173
+
3174
+ def share_stdin(dist, src = '')
3175
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3176
+ @interp._invoke('interp', 'share', src, 'stdin', dist)
3177
+ self
3178
+ end
3179
+ def self.share_stdin(dist, src = '')
3180
+ __getip.share_stdin(dist, src)
3181
+ self
3182
+ end
3183
+
3184
+ def share_stdout(dist, src = '')
3185
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3186
+ @interp._invoke('interp', 'share', src, 'stdout', dist)
3187
+ self
3188
+ end
3189
+ def self.share_stdout(dist, src = '')
3190
+ __getip.share_stdout(dist, src)
3191
+ self
3192
+ end
3193
+
3194
+ def share_stderr(dist, src = '')
3195
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3196
+ @interp._invoke('interp', 'share', src, 'stderr', dist)
3197
+ self
3198
+ end
3199
+ def self.share_stderr(dist, src = '')
3200
+ __getip.share_stderr(dist, src)
3201
+ self
3202
+ end
3203
+
3204
+ def transfer_stdin(dist, src = '')
3205
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3206
+ @interp._invoke('interp', 'transfer', src, 'stdin', dist)
3207
+ self
3208
+ end
3209
+ def self.transfer_stdin(dist, src = '')
3210
+ __getip.transfer_stdin(dist, src)
3211
+ self
3212
+ end
3213
+
3214
+ def transfer_stdout(dist, src = '')
3215
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3216
+ @interp._invoke('interp', 'transfer', src, 'stdout', dist)
3217
+ self
3218
+ end
3219
+ def self.transfer_stdout(dist, src = '')
3220
+ __getip.transfer_stdout(dist, src)
3221
+ self
3222
+ end
3223
+
3224
+ def transfer_stderr(dist, src = '')
3225
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3226
+ @interp._invoke('interp', 'transfer', src, 'stderr', dist)
3227
+ self
3228
+ end
3229
+ def self.transfer_stderr(dist, src = '')
3230
+ __getip.transfer_stderr(dist, src)
3231
+ self
3232
+ end
3233
+
3234
+ def share_stdio(dist, src = '')
3235
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3236
+ @interp._invoke('interp', 'share', src, 'stdin', dist)
3237
+ @interp._invoke('interp', 'share', src, 'stdout', dist)
3238
+ @interp._invoke('interp', 'share', src, 'stderr', dist)
3239
+ self
3240
+ end
3241
+ def self.share_stdio(dist, src = '')
3242
+ __getip.share_stdio(dist, src)
3243
+ self
3244
+ end
3245
+
3246
+ def transfer_stdio(dist, src = '')
3247
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3248
+ @interp._invoke('interp', 'transfer', src, 'stdin', dist)
3249
+ @interp._invoke('interp', 'transfer', src, 'stdout', dist)
3250
+ @interp._invoke('interp', 'transfer', src, 'stderr', dist)
3251
+ self
3252
+ end
3253
+ def self.transfer_stdio(dist, src = '')
3254
+ __getip.transfer_stdio(dist, src)
3255
+ self
3256
+ end
3257
+ end
3258
+
3259
+
3260
+ # Safe Base :: manipulating safe interpreter
3261
+ class MultiTkIp
3262
+ def safeip_configure(slot, value=None)
3263
+ # use for '-noStatics' option ==> {statics=>false}
3264
+ # for '-nestedLoadOk' option ==> {nested=>true}
3265
+ if slot.kind_of?(Hash)
3266
+ ip = MultiTkIp.__getip
3267
+ ip._eval('::safe::interpConfigure ' + @ip_name + ' ' + _keys2opts(slot))
3268
+ else
3269
+ ip._eval('::safe::interpConfigure ' + @ip_name + ' ' +
3270
+ "-#{slot} #{_get_eval_string(value)}")
3271
+ end
3272
+ self
3273
+ end
3274
+
3275
+ def safeip_configinfo(slot = nil)
3276
+ ip = MultiTkIp.__getip
3277
+ ret = {}
3278
+ if slot
3279
+ conf = _lst2ary(ip._eval("::safe::interpConfigure " +
3280
+ @ip_name + " -#{slot}"))
3281
+ if conf[0] == '-deleteHook'
3282
+ =begin
3283
+ if conf[1] =~ /^rb_out\S* (c(_\d+_)?\d+)/
3284
+ ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$1]
3285
+ =end
3286
+ if conf[1] =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
3287
+ ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$4]
3288
+ else
3289
+ ret[conf[0][1..-1]] = conf[1]
3290
+ end
3291
+ else
3292
+ ret[conf[0][1..-1]] = conf[1]
3293
+ end
3294
+ else
3295
+ Hash[*_lst2ary(ip._eval("::safe::interpConfigure " +
3296
+ @ip_name))].each{|k, v|
3297
+ if k == '-deleteHook'
3298
+ =begin
3299
+ if v =~ /^rb_out\S* (c(_\d+_)?\d+)/
3300
+ ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$1]
3301
+ =end
3302
+ if v =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
3303
+ ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$4]
3304
+ else
3305
+ ret[k[1..-1]] = v
3306
+ end
3307
+ else
3308
+ ret[k[1..-1]] = v
3309
+ end
3310
+ }
3311
+ end
3312
+ ret
3313
+ end
3314
+
3315
+ def safeip_delete
3316
+ ip = MultiTkIp.__getip
3317
+ ip._eval("::safe::interpDelete " + @ip_name)
3318
+ end
3319
+
3320
+ def safeip_add_to_access_path(dir)
3321
+ ip = MultiTkIp.__getip
3322
+ ip._eval("::safe::interpAddToAccessPath #{@ip_name} #{dir}")
3323
+ end
3324
+
3325
+ def safeip_find_in_access_path(dir)
3326
+ ip = MultiTkIp.__getip
3327
+ ip._eval("::safe::interpFindInAccessPath #{@ip_name} #{dir}")
3328
+ end
3329
+
3330
+ def safeip_set_log_cmd(cmd = Proc.new)
3331
+ ip = MultiTkIp.__getip
3332
+ ip._eval("::safe::setLogCmd #{@ip_name} #{_get_eval_string(cmd)}")
3333
+ end
3334
+ end
3335
+
3336
+
3337
+ # encoding convert
3338
+ class << MultiTkIp
3339
+ def encoding_table
3340
+ __getip.encoding_table
3341
+ end
3342
+
3343
+ def force_default_encoding=(mode)
3344
+ __getip.force_default_encoding=(mode)
3345
+ end
3346
+
3347
+ def force_default_encoding?
3348
+ __getip.force_default_encoding?
3349
+ end
3350
+
3351
+ def default_encoding=(enc)
3352
+ __getip.default_encoding=(enc)
3353
+ end
3354
+
3355
+ def encoding=(enc)
3356
+ __getip.encoding=(enc)
3357
+ end
3358
+
3359
+ def encoding_name
3360
+ __getip.encoding_name
3361
+ end
3362
+
3363
+ def encoding_obj
3364
+ __getip.encoding_obj
3365
+ end
3366
+ alias encoding encoding_name
3367
+ alias default_encoding encoding_name
3368
+
3369
+ def encoding_convertfrom(str, enc=None)
3370
+ __getip.encoding_convertfrom(str, enc)
3371
+ end
3372
+ alias encoding_convert_from encoding_convertfrom
3373
+
3374
+ def encoding_convertto(str, enc=None)
3375
+ __getip.encoding_convertto(str, enc)
3376
+ end
3377
+ alias encoding_convert_to encoding_convertto
3378
+ end
3379
+ class MultiTkIp
3380
+ def encoding_table
3381
+ @interp.encoding_table
3382
+ end
3383
+
3384
+ def force_default_encoding=(mode)
3385
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3386
+ @interp.force_default_encoding = mode
3387
+ end
3388
+ def force_default_encoding?
3389
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3390
+ @interp.force_default_encoding?
3391
+ end
3392
+
3393
+ def default_encoding=(enc)
3394
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3395
+ @interp.default_encoding = enc
3396
+ end
3397
+
3398
+ def encoding=(enc)
3399
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3400
+ @interp.encoding = enc
3401
+ end
3402
+ def encoding_name
3403
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3404
+ @interp.encoding_name
3405
+ end
3406
+ def encoding_obj
3407
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3408
+ @interp.encoding_obj
3409
+ end
3410
+ alias encoding encoding_name
3411
+ alias default_encoding encoding_name
3412
+
3413
+ def encoding_convertfrom(str, enc=None)
3414
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3415
+ @interp.encoding_convertfrom(str, enc)
3416
+ end
3417
+ alias encoding_convert_from encoding_convertfrom
3418
+
3419
+ def encoding_convertto(str, enc=None)
3420
+ raise SecurityError, "no permission to manipulate" unless self.manipulable?
3421
+ @interp.encoding_convertto(str, enc)
3422
+ end
3423
+ alias encoding_convert_to encoding_convertto
3424
+ end
3425
+
3426
+
3427
+ # remove methods for security
3428
+ =begin
3429
+ class MultiTkIp
3430
+ INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread')
3431
+ INTERP_MUTEX = INTERP_THREAD[:mutex]
3432
+ INTERP_ROOT_CHECK = INTERP_THREAD[:root_check]
3433
+
3434
+ # undef_method :instance_eval
3435
+ undef_method :instance_variable_get
3436
+ undef_method :instance_variable_set
3437
+ end
3438
+
3439
+ module TkCore
3440
+ if MultiTkIp::WITH_RUBY_VM &&
3441
+ ! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
3442
+ INTERP_THREAD = MultiTkIp::INTERP_THREAD
3443
+ INTERP_MUTEX = MultiTkIp::INTERP_MUTEX
3444
+ INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK
3445
+ end
3446
+ end
3447
+ class MultiTkIp
3448
+ remove_const(:INTERP_THREAD)
3449
+ remove_const(:INTERP_MUTEX)
3450
+ remove_const(:INTERP_ROOT_CHECK)
3451
+ end
3452
+ =end
3453
+ if MultiTkIp::WITH_RUBY_VM &&
3454
+ ! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
3455
+ class MultiTkIp
3456
+ INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread')
3457
+ INTERP_THREAD_STATUS = INTERP_THREAD[:status]
3458
+ INTERP_MUTEX = INTERP_THREAD[:mutex]
3459
+ INTERP_ROOT_CHECK = INTERP_THREAD[:root_check]
3460
+ end
3461
+ module TkCore
3462
+ INTERP_THREAD = MultiTkIp::INTERP_THREAD
3463
+ INTERP_THREAD_STATUS = MultiTkIp::INTERP_THREAD_STATUS
3464
+ INTERP_MUTEX = MultiTkIp::INTERP_MUTEX
3465
+ INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK
3466
+ end
3467
+ class MultiTkIp
3468
+ remove_const(:INTERP_THREAD)
3469
+ remove_const(:INTERP_THREAD_STATUS)
3470
+ remove_const(:INTERP_MUTEX)
3471
+ remove_const(:INTERP_ROOT_CHECK)
3472
+ end
3473
+ end
3474
+
3475
+ class MultiTkIp
3476
+ # undef_method :instance_eval
3477
+ undef_method :instance_variable_get
3478
+ undef_method :instance_variable_set
3479
+ end
3480
+ # end of MultiTkIp definition
3481
+
3482
+ # defend against modification
3483
+ #MultiTkIp.freeze
3484
+ #TclTkLib.freeze
3485
+
3486
+ ########################################
3487
+ # start Tk which depends on MultiTkIp
3488
+ module TkCore
3489
+ INTERP = MultiTkIp
3490
+ end
3491
+ require 'tk'