tkがおかしい

fedora10にデフォルトで入っているのは tcl/tk 8.5系統のようで、こちらもこちらで applyが追加されて関数型言語に近付いたとか、色々面白そうなトピックがあるのでそのうち勉強しよっとは思う。んだけれど、その前にsystemsimが「8.4じゃなきゃ付き合って上げない」とか冷たく言い放つので、仕方なしに 8.4.19を拾ってきて入れようとしてハマる。の備忘録。
なんぞwishがいやな長いエラーを出す。しかも頭のほうはフェイント。

Application initialization failed: Can't find a usable tk.tcl in the following directories: 
/usr/local/lib/tcl8.4/tk8.4 /usr/local/lib/tk8.4
/usr/local/lib/tk8.4 /usr/local/lib

/usr/local/lib/tk8.4/tk.tcl: no event type or button # or keysym
while executing                                                               
"bind Listbox <MouseWheel> {                                                      
  %W yview scroll [expr {- (%D / 120) * 4}] units                               
}"                                                                                
:
:

見つからないのにこのファイルでってw まあ下っ側のが本質なので上のほうは無視してみると、要するにMouseWheelが無いと仰っているらしい。実際listbox.tcl, text.tclからMouseWheel関連を全部コメントアウトしてしまえばエラーこそいわなくなるが、いやそれ違うでショなのでちゃんと調べてみる。とどうやら最新版のXorgでこの辺りのイベント扱いが変わったらしい。なるほど。なるほど。
で、それに対応すれば良いらしい。

diff -car tk8.4.19.orig/generic/tk.h tk8.4.19/generic/tk.h
*** tk8.4.19.orig/generic/tk.h  2008-04-08 04:17:54.000000000 +0900
--- tk8.4.19/generic/tk.h       2009-04-14 08:32:46.000000000 +0900
***************
*** 635,651 ****
   *
   *---------------------------------------------------------------------------
   */
! #define VirtualEvent      (LASTEvent)
! #define ActivateNotify            (LASTEvent + 1)
! #define DeactivateNotify    (LASTEvent + 2)
! #define MouseWheelEvent     (LASTEvent + 3)
! #define TK_LASTEVENT      (LASTEvent + 4)

  #define MouseWheelMask            (1L << 28)

  #define ActivateMask      (1L << 29)
  #define VirtualEventMask    (1L << 30)
- #define TK_LASTEVENT      (LASTEvent + 4)


  /*
--- 635,650 ----
   *
   *---------------------------------------------------------------------------
   */
! #define VirtualEvent      (MappingNotify + 1)
! #define ActivateNotify            (MappingNotify + 2)
! #define DeactivateNotify    (MappingNotify + 3)
! #define MouseWheelEvent     (MappingNotify + 4)
! #define TK_LASTEVENT      (MappingNotify + 5)

  #define MouseWheelMask            (1L << 28)

  #define ActivateMask      (1L << 29)
  #define VirtualEventMask    (1L << 30)


  /*
diff -car tk8.4.19.orig/generic/tkEvent.c tk8.4.19/generic/tkEvent.c
*** tk8.4.19.orig/generic/tkEvent.c     2006-01-21 03:42:04.000000000 +0900
--- tk8.4.19/generic/tkEvent.c  2009-04-14 08:30:04.000000000 +0900
***************
*** 77,83 ****
   * Array of event masks corresponding to each X event:
   */

! static unsigned long eventMasks[TK_LASTEVENT] = {
      0,
      0,
      KeyPressMask,                     /* KeyPress */
--- 77,83 ----
   * Array of event masks corresponding to each X event:
   */

! static unsigned long realEventMasks[MappingNotify+1] = {
      0,
      0,
      KeyPressMask,                     /* KeyPress */
***************
*** 116,121 ****
--- 116,124 ----
      ColormapChangeMask,                       /* ColormapNotify */
      0,                                        /* ClientMessage */
      0,                                        /* Mapping Notify */
+ };
+ 
+ static unsigned long virtualEventMasks[TK_LASTEVENT-VirtualEvent] = {
      VirtualEventMask,                 /* VirtualEvents */
      ActivateMask,                     /* ActivateNotify */
      ActivateMask,                     /* DeactivateNotify */
***************
*** 749,755 ****
       */

      handlerWindow = eventPtr->xany.window;
!     mask = eventMasks[eventPtr->xany.type];
      if (mask == StructureNotifyMask) {
        if (eventPtr->xmap.event != eventPtr->xmap.window) {
            mask = SubstructureNotifyMask;
--- 752,764 ----
       */

      handlerWindow = eventPtr->xany.window;
! 
!     if (eventPtr->xany.type <= MappingNotify) {
!       mask = realEventMasks[eventPtr->xany.type];
!     } else if (eventPtr->xany.type >= VirtualEvent && eventPtr->xany.type < TK_LASTEVENT) {
!       mask = virtualEventMasks[eventPtr->xany.type - VirtualEvent];
!     }
! 
      if (mask == StructureNotifyMask) {

tkのツリーのトップにcdして patch -p1 < 上のパッチ、とするとあたる。まあ動いた。めでたい。