(defextern |_XMenuCreate|(external string) external) (defextern |_XMenuAddPane|(external external fix) fix) (defextern |_XMenuAddSelection|(external fix t external fix) fix) (defextern |_XMenuInsertPane|(external fix external fix) fix) (defextern |_XMenuInsertSelection|(external fix fix t external fix) fix) ;(defextern |_XMenuFindPane|(external string) fix) ;(defextern |_XMenuFindSelection|(external fix string) fix) (defextern |_XMenuChangePane|(external fix external) fix) (defextern |_XMenuChangeSelection|(external fix fix t fix external fix) fix) (defextern |_XMenuSetPane|(external fix fix) fix) (defextern |_XMenuSetSelection|(external fix fix fix) fix) (defextern |_XMenuDeletePane|(external fix) fix) (defextern |_XMenuDeleteSelection|(external fix fix) fix) ;(defextern |_XMenuRecompute|(external) fix) ;(defextern |_XMenuEventHandler|(external) fix) (defextern |_XMenuLocate|(external fix fix fix fix t t t t) fix) ;(defextern |_XMenuSetFreeze|(external fix) fix) (defextern |_XMenuActivate|(external t t fix fix fix t) fix) (defextern |_XMenuDestroy|(external) fix) (setq #:sys-package:colon 'menu) (defstruct :x def ; liste de (string cstring et liste de (string cstring value)) (selection 0) (pane 0)) (unless (boundp ':x:all-menus) (defvar :x:all-menus ())) (de #:bitmap:x:create-menu (menu) (let ((newmenu (:x:make)) (extend (|_XMenuCreate| (|_rootwindow|) "lelisp"))) (:extend newmenu extend) (newl :x:all-menus newmenu) newmenu)) (de :x:kill-menu (menu) (mapc (lambda (l) (|_free| (caddr l)) (mapc (lambda (def) (|_free| (caddr def))) (cdddr l))) (:x:def menu)) (setq :x:all-menus (delq menu :x:all-menus)) (|_XMenuDestroy| (:extend menu))) (defvar :x:pane 0) (defvar :x:selection 0) (defvar :x:result 0) (defvar :x:x-menu) (defvar :x:y-menu) (defvar :x:w-menu) (defvar :x:h-menu) (de :x:activate-menu (menu x y) (setq :x:selection (:x:selection menu)) (setq :x:pane (:x:pane menu)) (|_XMenuLocate| (:extend menu) :x:pane :x:selection x y ':x:x-menu ':x:y-menu ':x:w-menu ':x:h-menu) (setq :x:x-menu (or (fixp :x:x-menu) (cdr (loc :x:x-menu)))) (setq :x:y-menu (or (fixp :x:y-menu) (cdr (loc :x:y-menu)))) (setq x (max (add1 (sub x :x:x-menu)) (min x (add (sub (bitxmax) :x:w-menu) (sub x :x:x-menu))))) (setq y (max (add1 (sub y :x:y-menu)) (min y (add (sub (bitymax) :x:h-menu) (sub y :x:y-menu))))) (cond ((eqn (|_XMenuActivate| (:extend menu) ':x:pane ':x:selection x y #$ffff ':x:result) 1) (:x:selection menu -1) (:x:pane menu :x:pane) menu :x:result) (t (:x:selection menu -1) (:x:pane menu 0) ()))) (de :x:menu-insert-item-list (menu choix name active) (setq name (string name)) (let ((cname (|_cstring| name (slen name)))) (or (and (eqn 0 choix) (neqn -1 (|_XMenuInsertPane| (:extend menu) choix cname active))) (|_XMenuAddPane| (:extend menu) cname active)) (:x:def menu (nconc (firstn choix (:x:def menu)) (ncons (list name active cname)) (nthcdr choix (:x:def menu)))))) (de :x:menu-insert-item (menu choix item name active value) (setq name (string name)) (let ((cname (|_cstring| name (slen name)))) (or (and (eqn 0 item) (neqn -1 (|_XMenuInsertSelection| (:extend menu) choix item value cname active))) (|_XMenuAddSelection| (:extend menu) choix value cname active)) (let ((ilist (nth choix (:x:def menu)))) (rplacd (cddr ilist) (nconc (firstn item (cdddr ilist)) (ncons (list name active cname value)) (nthcdr item (cdddr ilist))))))) (de :x:menu-delete-item-list (menu choix) (|_XMenuDeletePane| (:extend menu) choix) ; il manque un FREE des chaines C (:x:def menu (nconc (firstn choix (:x:def menu)) (nthcdr (add1 choix) (:x:def menu))))) (de :x:menu-delete-item (menu choix item) (|_XMenuDeleteSelection| (:extend menu) choix item) (let ((ilist (nth choix (:x:def menu)))) (rplacd (cddr ilist) (nconc (firstn item (cdddr ilist)) (nthcdr (add1 item) (cdddr ilist)))))) (de :x:menu-modify-item-list (menu choix name active) (when name (setq name (string name)) (let ((cname (|_cstring| name (slen name)))) (|_XMenuChangePane| (:extend menu) choix cname) (rplaca (nth choix (:x:def menu)) name) (rplaca (cddr (nth choix (:x:def menu))) cname))) (when active (|_XMenuSetPane| (:extend menu) choix active) (rplaca (cdr (nth choix (:x:def menu))) active))) (de :x:menu-modify-item (menu choix item name active value) (let (cname) (when name (setq name (string name)) (setq cname (|_cstring| name (slen name))) (|_XMenuChangeSelection| (:extend menu) choix item value (if value 1 0) cname (if name 1 0))) (when (or name value) (let ((itemdef (nth item (cdddr (nth choix (:x:def menu)))))) (when name (rplaca itemdef name)) (when name (rplaca (cddr itemdef) cname)) (when value (rplaca (cdddr itemdef) value)))) (when active (let ((itemdef (nth item (cdddr (nth choix (:x:def menu)))))) (rplaca (cdr itemdef) active) (|_XMenuSetSelection| (:extend menu) choix item active))))) (de :x:rebuild-menu (menu) (let ((def (:x:def menu))) (:x:def menu ()) (:extend menu (|_XMenuCreate| (|_rootwindow|) "lelisp")) (mapc (lambda (ilist) (menu-insert-item-list menu 0 (car ilist) (cadr ilist)) (mapc (lambda (item) (menu-insert-item menu 0 0 (car item) (cadr item) (cadddr item))) (reverse (cdddr ilist)))) (reverse def))))