1;;; 2;;; Copyright (c) 2003-2013 uim Project https://github.com/uim/uim 3;;; 4;;; All rights reserved. 5;;; 6;;; Redistribution and use in source and binary forms, with or without 7;;; modification, are permitted provided that the following conditions 8;;; are met: 9;;; 1. Redistributions of source code must retain the above copyright 10;;; notice, this list of conditions and the following disclaimer. 11;;; 2. Redistributions in binary form must reproduce the above copyright 12;;; notice, this list of conditions and the following disclaimer in the 13;;; documentation and/or other materials provided with the distribution. 14;;; 3. Neither the name of authors nor the names of its contributors 15;;; may be used to endorse or promote products derived from this software 16;;; without specific prior written permission. 17;;; 18;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 19;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE 22;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24;;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26;;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28;;; SUCH DAMAGE. 29;;;; 30 31(require "util.scm") 32(require "rk.scm") 33(require-custom "generic-key-custom.scm") 34(require-custom "generic-custom.scm") 35 36 37;; widgets and actions 38 39;; widgets 40(define generic-widgets '(widget_generic_input_mode)) 41 42;; default activity for each widgets 43(define default-widget_generic_input_mode 'action_generic_off) 44 45;; actions of widget_generic_input_mode 46(define generic-input-mode-actions 47 '(action_generic_off 48 action_generic_on)) 49 50 51;;; implementations 52 53(define ascii-rule 54 (map (compose (lambda (entry) 55 (list (list entry) entry)) 56 list 57 charcode->string) 58 (iota 95 32))) 59 60(define generic-prepare-activation 61 (lambda (gc) 62 (let ((rkc (generic-context-rk-context gc))) 63 (rk-flush rkc) 64 (generic-update-preedit gc)))) 65 66(register-action 'action_generic_off 67 (lambda (gc) 68 (list 69 'off 70 "-" 71 (N_ "off") 72 (N_ "Direct Input Mode"))) 73 (lambda (gc) 74 (not (generic-context-on gc))) 75 (lambda (gc) 76 (generic-prepare-activation gc) 77 (generic-context-set-on! gc #f))) 78 79(register-action 'action_generic_on 80 (lambda (gc) 81 (let* ((im (generic-context-im gc)) 82 (name (symbol->string (im-name im)))) 83 (list 84 'on 85 "O" 86 (N_ "on") 87 (string-append name (N_ " Mode"))))) 88 (lambda (gc) 89 (generic-context-on gc)) 90 (lambda (gc) 91 (generic-prepare-activation gc) 92 (generic-context-set-on! gc #t))) 93 94;; Update widget definitions based on action configurations. The 95;; procedure is needed for on-the-fly reconfiguration involving the 96;; custom API 97(define generic-configure-widgets 98 (lambda () 99 (register-widget 'widget_generic_input_mode 100 (activity-indicator-new generic-input-mode-actions) 101 (actions-new generic-input-mode-actions)))) 102 103(define generic-context-rec-spec 104 (append 105 context-rec-spec 106 '((rk-context #f) 107 (rk-nth 0) 108 (on #f) 109 (candidate-op-count 0) 110 (raw-commit #f) 111 (multi-cand-input #f) 112 (cands ())))) 113(define-record 'generic-context generic-context-rec-spec) 114(define generic-context-new-internal generic-context-new) 115 116(define generic-context-new 117 (lambda (id im rule back) 118 (let ((gc (generic-context-new-internal id im)) 119 (rkc (rk-context-new rule #f back))) 120 (generic-context-set-widgets! gc generic-widgets) 121 (generic-context-set-rk-context! gc rkc) 122 gc))) 123 124(define generic-context-flush 125 (lambda (pc) 126 (generic-context-set-rk-nth! pc 0) 127 (generic-context-set-candidate-op-count! pc 0) 128 (generic-context-set-multi-cand-input! pc #f) 129 (generic-context-set-cands! pc '()) 130 (rk-flush (generic-context-rk-context pc)))) 131 132(define generic-update-preedit 133 (lambda (pc) 134 (if (generic-context-raw-commit pc) 135 (generic-context-set-raw-commit! pc #f) 136 (let* ((rkc (generic-context-rk-context pc)) 137 (cands (generic-context-cands pc)) 138 (n (generic-context-rk-nth pc))) 139 (im-clear-preedit pc) 140 (im-pushback-preedit 141 pc preedit-reverse 142 (if (and 143 (not (null? cands)) 144 (> n -1)) 145 (if (pair? (car cands)) 146 (car (nth n cands)) 147 (nth n cands)) 148 (rk-pending rkc))) 149 (im-update-preedit pc))))) 150 151(define generic-commit-raw 152 (lambda (pc) 153 (im-commit-raw pc) 154 (generic-context-set-raw-commit! pc #t))) 155 156(define generic-commit 157 (lambda (pc) 158 (let ((rkc (generic-context-rk-context pc)) 159 (cands (generic-context-cands pc)) 160 (n (generic-context-rk-nth pc))) 161 (if (not (null? cands)) 162 (begin 163 (if (> n -1) 164 (if (pair? (car cands)) 165 (im-commit pc (car (nth (generic-context-rk-nth pc) cands))) 166 (im-commit pc (nth (generic-context-rk-nth pc) cands))) 167 ;(im-commit pc (rk-pending rkc)) 168 ) 169 (im-deactivate-candidate-selector pc) 170 (generic-context-flush pc)) 171 (begin 172 (im-commit-raw pc) 173 (rk-flush rkc)))))) 174 175(define generic-commit-by-numkey 176 (lambda (pc key) 177 (let* ((rkc (generic-context-rk-context pc)) 178 (cands (generic-context-cands pc)) 179 (n (generic-context-rk-nth pc)) 180 (nr (length cands)) 181 (cur-page (if (= generic-nr-candidate-max 0) 182 0 183 (quotient n generic-nr-candidate-max))) 184 (pageidx (- (numeric-ichar->integer key) 1)) 185 (compensated-pageidx (cond 186 ((< pageidx 0) ; pressing key_0 187 (+ pageidx 10)) 188 (else 189 pageidx))) 190 (idx (+ (* cur-page generic-nr-candidate-max) compensated-pageidx))) 191 (if (< idx nr) 192 (begin 193 (if (pair? (car cands)) 194 (im-commit pc (car (nth idx cands))) 195 (im-commit pc (nth idx cands))) 196 (im-deactivate-candidate-selector pc) 197 (generic-context-flush pc) 198 #t) 199 #f)))) 200 201(define generic-proc-input-state-without-preedit 202 (lambda (pc key state rkc) 203 (cond 204 ((generic-off-key? key state) 205 (generic-context-set-on! pc #f) 206 #f) 207 ((generic-backspace-key? key state) 208 (generic-commit-raw pc) 209 #f) 210 ((symbol? key) 211 (generic-commit-raw pc) 212 #f) 213 ((and (modifier-key-mask state) 214 (not (shift-key-mask state))) 215 (generic-commit-raw pc) 216 #f) 217 (else 218 #t)))) 219 220(define generic-proc-input-state-with-preedit 221 (lambda (pc key state rkc) 222 (cond 223 ((generic-off-key? key state) 224 (let ((cands (generic-context-cands pc)) 225 (n (generic-context-rk-nth pc))) 226 (if (and 227 (not (null? cands)) 228 (> n -1)) 229 (begin 230 (if (pair? (car cands)) 231 (im-commit pc (car (nth n cands))) 232 (im-commit pc (nth n cands))) 233 (generic-context-flush pc)) 234 (if (not (string=? (rk-pending rkc) "")) ;; flush pending rk 235 (generic-context-flush pc))) 236 (generic-context-set-on! pc #f) 237 #f)) 238 ((generic-prev-candidate-key? key state) 239 (generic-handle-convert-key pc key state) 240 #f) 241 ((generic-next-candidate-key? key state) 242 (generic-handle-convert-key pc key state) 243 #f) 244 ((generic-backspace-key? key state) 245 (rk-backspace rkc) 246 (generic-context-set-rk-nth! pc 0) 247 (generic-update-input-state-cands pc key state 248 rkc (rk-context-seq rkc) #f) 249 #f) 250 ((generic-commit-key? key state) 251 (generic-commit pc) 252 #f) 253 ((generic-cancel-key? key state) 254 (generic-context-flush pc) 255 #f) 256 ((symbol? key) 257 (generic-commit pc) 258 (im-commit-raw pc) 259 #f) 260 ((and (modifier-key-mask state) 261 (not (shift-key-mask state))) 262 (generic-commit pc) 263 (im-commit-raw pc) 264 #f) 265 (else 266 #t)))) 267 268(define generic-flatten 269 (lambda (lst) 270 (cond ((null? lst) '()) 271 ((list? (car lst)) 272 (append (generic-flatten (car lst)) 273 (generic-flatten (cdr lst)))) 274 (else 275 (cons (car lst) (generic-flatten (cdr lst))))))) 276 277(define generic-update-input-state-cands 278 (lambda (pc key state rkc prev-seq res) 279 (if (not (rk-partial? rkc)) 280 ;; exact match or no-match 281 (let* ((cs (rk-current-seq rkc)) 282 (cands (if cs (cadr cs) '()))) 283 (generic-context-set-cands! pc cands) 284 (if cs 285 (if (null? (cdr cands)) 286 ;; single candidate 287 (begin 288 (im-commit pc (nth 0 cands)) 289 (generic-context-flush pc) 290 (im-deactivate-candidate-selector pc)) 291 ;; show candidates for the Pinyin like input method 292 (if (and generic-use-candidate-window? 293 generic-show-candidate-implicitly?) 294 (begin 295 (im-activate-candidate-selector 296 pc (length cands) generic-nr-candidate-max) 297 (im-select-candidate pc 0) 298 (generic-context-set-multi-cand-input! pc #t) 299 (generic-context-set-candidate-op-count! 300 pc 301 (+ 1 (generic-context-candidate-op-count pc))))))) 302 ;; commit no-matching key 303 (if (and 304 (not cs) 305 (null? (rk-context-seq rkc)) 306 (or 307 (null? prev-seq) 308 res) 309 (not (generic-backspace-key? key state))) ;; mmm... 310 (im-commit-raw pc))) 311 ;; partial match, including exact match 312 (let* ((ret (if generic-show-prediction-candidates? 313 (rk-cands-with-minimal-partial rkc) 314 '())) 315 (expand-cands 316 (lambda (lst) 317 (map (lambda (x) 318 (let ((head (car x)) 319 (tail (cdr x))) 320 (map (lambda (y) (cons y tail)) head))) lst))) 321 (cands/keys (generic-flatten (expand-cands ret)))) 322 (if (not generic-show-prediction-candidates?) 323 (let* ((cs (rk-current-seq rkc)) 324 (cands (if cs (cadr cs) '()))) 325 (set! cands/keys cands))) 326 (generic-context-set-cands! pc cands/keys) 327 (if (not (null? cands/keys)) 328 ;; show candidates even in input-state 329 (begin 330 (if (and generic-use-candidate-window? 331 generic-show-candidate-implicitly?) 332 (begin 333 (im-activate-candidate-selector 334 pc (length cands/keys) generic-nr-candidate-max) 335 (if (and 336 generic-show-prediction-candidates? 337 (not (string=? (cdr (car cands/keys)) ""))) 338 (generic-context-set-rk-nth! pc -1) 339 (begin 340 (generic-context-set-rk-nth! pc 0) 341 (im-select-candidate pc 0) 342 (generic-context-set-candidate-op-count! pc (+ 1 (generic-context-candidate-op-count pc))))) 343 (generic-context-set-multi-cand-input! pc #t))))))))) 344 345(define generic-proc-input-state 346 (lambda (pc key state) 347 (let* ((rkc (generic-context-rk-context pc)) 348 (seq (rk-context-seq rkc)) 349 (res #f)) 350 (and 351 (if (string=? (rk-pending rkc) "") 352 (generic-proc-input-state-without-preedit pc key state rkc) 353 (generic-proc-input-state-with-preedit pc key state rkc)) 354 (begin 355 (set! res 356 (rk-push-key! 357 rkc 358 (charcode->string key))) 359 (if res 360 (begin 361 (im-commit pc (nth (generic-context-rk-nth pc) res)) 362 (generic-context-set-rk-nth! pc 0) 363 (generic-context-set-candidate-op-count! pc 0) 364 (generic-context-set-cands! pc '()) 365 (im-deactivate-candidate-selector pc))) 366 (generic-update-input-state-cands pc key state rkc seq res)))))) 367 368(define generic-proc-specific-multi-cand-input-state 369 (lambda (pc key state rkc) 370 (cond 371 ((generic-off-key? key state) 372 (let ((cands (generic-context-cands pc)) 373 (n (generic-context-rk-nth pc))) 374 (if (and 375 (not (null? cands)) 376 (> n -1)) 377 (begin 378 (if (pair? (car cands)) 379 (im-commit pc (car (nth n cands))) 380 (im-commit pc (nth n cands))) 381 (generic-context-flush pc)) 382 (if (not (string=? (rk-pending rkc) "")) ;; flush pending rk 383 (generic-context-flush pc))) 384 (generic-context-set-on! pc #f) 385 (im-deactivate-candidate-selector pc) 386 #f)) 387 ((generic-prev-candidate-key? key state) 388 (generic-handle-convert-key pc key state) 389 #f) 390 ((generic-next-candidate-key? key state) 391 (generic-handle-convert-key pc key state) 392 #f) 393 ((generic-prev-page-key? key state) 394 (generic-handle-convert-key pc key state) 395 #f) 396 ((generic-next-page-key? key state) 397 (generic-handle-convert-key pc key state) 398 #f) 399 ((generic-backspace-key? key state) 400 (rk-backspace rkc) 401 (generic-context-set-rk-nth! pc 0) 402 (generic-update-multi-cand-state-cands pc key state rkc) 403 #f) 404 ((generic-commit-key? key state) 405 (generic-context-set-multi-cand-input! pc #f) 406 (generic-commit pc) 407 #f) 408 ((generic-cancel-key? key state) 409 (im-deactivate-candidate-selector pc) 410 (generic-context-flush pc) 411 #f) 412 ((symbol? key) 413 (generic-context-set-multi-cand-input! pc #f) 414 (generic-commit pc) 415 (im-commit-raw pc) 416 #f) 417 ((and generic-commit-candidate-by-numeral-key? 418 (ichar-numeric? key) 419 (not (rk-expect-key? rkc (charcode->string key)))) 420 (if (generic-commit-by-numkey pc key) 421 (generic-context-set-multi-cand-input! pc #f)) 422 #f) 423 424 ((and (modifier-key-mask state) 425 (not (shift-key-mask state))) 426 (generic-context-set-multi-cand-input! pc #f) 427 (generic-commit pc) 428 (im-commit-raw pc) 429 #f) 430 (else 431 #t)))) 432 433(define generic-update-multi-cand-state-cands 434 (lambda (pc key state rkc) 435 (if (not (rk-partial? rkc)) ;; exact match or no-match 436 (let* ((cs (rk-current-seq rkc)) 437 (cands (if cs (cadr cs) '()))) 438 (generic-context-set-cands! pc cands) 439 (generic-context-set-rk-nth! pc 0) 440 (if cs 441 (if (null? (cdr cands)) 442 (begin 443 (im-commit pc 444 (nth 0 cands)) 445 (generic-context-flush pc) 446 (im-deactivate-candidate-selector pc)) 447 ;; show candidates for the Pinyin like input method 448 (if generic-use-candidate-window? 449 (begin 450 (im-activate-candidate-selector 451 pc (length cands) generic-nr-candidate-max) 452 (im-select-candidate pc 0)))) 453 ;; perhaps backspace to clear preedit 454 (begin 455 (im-deactivate-candidate-selector pc) 456 (generic-context-flush pc)))) 457 ;; partial match, including exact match 458 (let* ((ret (if generic-show-prediction-candidates? 459 (rk-cands-with-minimal-partial rkc) 460 '())) 461 (expand-cands 462 (lambda (lst) 463 (map (lambda (x) 464 (let ((head (car x)) 465 (tail (cdr x))) 466 (map (lambda (y) (cons y tail)) head))) lst))) 467 (cands/nexts (generic-flatten (expand-cands ret)))) 468 469 (if (not generic-show-prediction-candidates?) 470 (let* ((cs (rk-current-seq rkc)) 471 (cands (if cs (cadr cs) '()))) 472 (set! cands/nexts cands))) 473 (generic-context-set-cands! pc cands/nexts) 474 (if (not (null? cands/nexts)) 475 (if (not (null? (cdr cands/nexts))) 476 (begin 477 (im-activate-candidate-selector 478 pc (length cands/nexts) generic-nr-candidate-max) 479 (if (and 480 generic-show-prediction-candidates? 481 (not (string=? (cdr (car cands/nexts)) ""))) 482 (generic-context-set-rk-nth! pc -1) 483 (begin 484 (generic-context-set-rk-nth! pc 0) 485 (im-select-candidate pc 0)))) 486 ;; single candidate 487 (begin 488 (im-deactivate-candidate-selector pc) 489 (generic-context-set-rk-nth! pc 0) 490 (generic-context-set-candidate-op-count! pc 0) 491 (generic-context-set-multi-cand-input! pc #f))) 492 ;; no-candidate 493 (begin 494 (im-deactivate-candidate-selector pc) 495 (generic-context-set-candidate-op-count! pc 0) 496 (generic-context-set-multi-cand-input! pc #f))))))) 497 498(define generic-proc-multi-cand-input-state 499 (lambda (pc key state) 500 (let* ((rkc (generic-context-rk-context pc)) 501 (seq (rk-context-seq rkc)) 502 (cands (generic-context-cands pc)) 503 (res #f)) 504 (and 505 (generic-proc-specific-multi-cand-input-state pc key state rkc) 506 (begin 507 (set! res 508 (rk-push-key! 509 rkc 510 (charcode->string key))) 511 (if res 512 ;; commit matched word and continue new rk 513 (begin 514 (if (< (generic-context-rk-nth pc) (length res)) 515 (im-commit pc (nth (generic-context-rk-nth pc) res)) 516 ;(im-commit pc (car (nth (generic-context-rk-nth pc) cands))) 517 ;(im-commit pc (nth 0 res)) 518 ) ;; XXX: what is the expected behavior here? 519 (generic-context-set-rk-nth! pc 0) 520 (generic-context-set-candidate-op-count! pc 0) 521 (im-deactivate-candidate-selector pc) 522 (generic-context-set-multi-cand-input! pc #f) 523 (generic-update-input-state-cands pc key state rkc seq res)) 524 (generic-update-multi-cand-state-cands pc key state rkc))))))) 525 526(define generic-handle-convert-key 527 (lambda (pc key state) 528 (let* ((rkc (generic-context-rk-context pc)) 529 (n (generic-context-rk-nth pc)) 530 (cands (generic-context-cands pc)) 531 (nr (length cands))) 532 (if (and 533 (not (generic-context-multi-cand-input pc)) 534 (not (null? cands)) 535 (not (null? (cdr cands)))) 536 (generic-context-set-multi-cand-input! pc #t)) 537 (and 538 (if (generic-prev-candidate-key? key state) 539 (if (not (null? cands)) 540 (if (pair? (cdr cands)) 541 ;; multiple candidates 542 (begin 543 (set! n (- n 1)) 544 (generic-context-set-rk-nth! pc n) 545 (if (< n 0) 546 (begin 547 (generic-context-set-rk-nth! pc (- nr 1)) 548 (set! n (- nr 1)))) 549 (generic-context-set-candidate-op-count! 550 pc 551 (+ 1 (generic-context-candidate-op-count pc))) 552 (if (and 553 (= (generic-context-candidate-op-count pc) 554 generic-candidate-op-count) 555 generic-use-candidate-window?) 556 (im-activate-candidate-selector 557 pc nr generic-nr-candidate-max)) 558 (if (and 559 (>= (generic-context-candidate-op-count pc) 560 generic-candidate-op-count) 561 generic-use-candidate-window?) 562 (im-select-candidate pc n)) 563 #f) 564 ;; single candidate 565 (begin 566 (generic-commit pc) 567 #f)) 568 ;; no candidate 569 (begin 570 (generic-context-flush pc) 571 #f)) 572 #t) 573 (if (generic-next-candidate-key? key state) 574 (if (not (null? cands)) 575 (if (pair? (cdr cands)) 576 ;; multiple candidates 577 (begin 578 (generic-context-set-rk-nth! pc (+ 1 n)) 579 (if (<= nr (+ n 1)) 580 (generic-context-set-rk-nth! pc 0)) 581 (generic-context-set-candidate-op-count! 582 pc 583 (+ 1 (generic-context-candidate-op-count pc))) 584 (if (and 585 (= (generic-context-candidate-op-count pc) 586 generic-candidate-op-count) 587 generic-use-candidate-window?) 588 (im-activate-candidate-selector pc nr 589 generic-nr-candidate-max)) 590 (if (and 591 (>= (generic-context-candidate-op-count pc) 592 generic-candidate-op-count) 593 generic-use-candidate-window?) 594 (begin 595 (if (>= (+ n 1) nr) 596 (set! n -1)) 597 (im-select-candidate pc (+ n 1)))) 598 #f) 599 ;; single candidate 600 (begin 601 (generic-commit pc) 602 #f)) 603 ;; no candidate 604 (begin 605 (generic-context-flush pc) 606 #f)) 607 #t) 608 (if (and (generic-prev-page-key? key state) 609 (<= generic-candidate-op-count 610 (generic-context-candidate-op-count pc)) 611 generic-use-candidate-window?) 612 (begin 613 (im-shift-page-candidate pc #f) 614 #f) 615 #t) 616 (if (and (generic-next-page-key? key state) 617 (<= generic-candidate-op-count 618 (generic-context-candidate-op-count pc)) 619 generic-use-candidate-window?) 620 (begin 621 (im-shift-page-candidate pc #t) 622 #f) 623 #t))))) 624 625 626(define generic-proc-off-mode 627 (lambda (pc key state) 628 (and 629 (if (generic-on-key? key state) 630 (begin 631 (generic-context-set-on! pc #t) 632 #f) 633 #t) 634 ;; 635 (generic-commit-raw pc)))) 636 637(define generic-key-press-handler 638 (lambda (pc key state) 639 (if (ichar-control? key) 640 (im-commit-raw pc) 641 (if (generic-context-on pc) 642 (if (generic-context-multi-cand-input pc) 643 (generic-proc-multi-cand-input-state pc key state) 644 (generic-proc-input-state pc key state)) 645 (generic-proc-off-mode pc key state))) 646 (generic-update-preedit pc) 647 ())) 648 649(define generic-key-release-handler 650 (lambda (pc key state) 651 (if (or (ichar-control? key) 652 (not (generic-context-on pc))) 653 ;; don't discard key release event for apps 654 (generic-commit-raw pc)))) 655 656(define generic-reset-handler 657 (lambda (pc) 658 (let ((rkc (generic-context-rk-context pc))) 659 (rk-flush rkc)))) 660 661(define generic-focus-in-handler 662 (lambda (pc) 663 #f)) 664 665(define generic-focus-out-handler 666 (lambda (pc) 667 (generic-commit pc) 668 (generic-update-preedit pc))) 669 670(define generic-place-handler generic-focus-in-handler) 671(define generic-displace-handler generic-focus-out-handler) 672 673(define generic-get-candidate-handler 674 (lambda (pc idx accel-enum-hint) 675 (let* ((cands (generic-context-cands pc)) 676 (cell (nth idx cands)) 677 (cand (if (pair? cell) (string-append (car cell) "\t" (cdr cell)) 678 cell))) 679 (list cand (digit->string (+ idx 1)) "")))) 680 681(define generic-set-candidate-index-handler 682 (lambda (pc idx) 683 (let ((rkc (generic-context-rk-context pc))) 684 (generic-context-set-rk-nth! pc idx) 685 (generic-update-preedit pc)))) 686 687(define generic-init-handler 688 (lambda (id im init-handler) 689 (init-handler id im #f))) 690 691(define generic-register-im 692 (lambda (name lang code name-label short-desc init-arg) 693 (register-im 694 name 695 lang 696 code 697 name-label 698 short-desc 699 init-arg 700 generic-init-handler 701 #f ;; release-handler 702 context-mode-handler 703 generic-key-press-handler 704 generic-key-release-handler 705 generic-reset-handler 706 generic-get-candidate-handler 707 generic-set-candidate-index-handler 708 context-prop-activate-handler 709 #f 710 generic-focus-in-handler 711 generic-focus-out-handler 712 generic-place-handler 713 generic-displace-handler 714 ))) 715 716(generic-configure-widgets) 717