Dan Knapp <[EMAIL PROTECTED]> writes:
> Well, I can do that right enough. I can create a bitmap; I can even
> use it as the clip mask. What I can't do is actually draw into the bitmap. (Thus,
> since it's uninitialized, the drawing results look like
> garbage - but the same garbage for the duration of each run, you see,
> so I know it's working.)
>
> If I try to use (put-image), no matter how carefully I prepare the image and
> ensure that it only has one bit of depth, and no matter whether I use the image-x,
> image-xy, or image-z formats, it results
> in a match-error.
>
> I also get a match-error, oddly, on any other attempted drawing operation into the
> bitmap. At first I suspected that this was due to
> the gcontext specifying a foreground color which the bitmap couldn't
> handle; but I can't imagine what it should be, in that case. I
> tried (screen-black-value), 0, and 1.
>
> I did a long search looking for any CLX code anywhere which uses
> this technique, but actually, I couldn't find a single example. I
> did have no trouble finding C programs which use it...
> ...
> Any suggestions?
You might look at the source code for READ-BITMAP-FILE in the CMUCL
source directory src/clx/image.lisp.
I had trouble finding simple example programs to call PUT-IMAGE so
I stripped this out of a larger program of mine.
====== showbm.lisp ======
;;;; showbm.lisp - simple load bitmap into window
;;;; Commentary
;;; Simple hack to load a bitmap into a window.
#+:cmu
(require :clx)
;;; Keep general x connection info global
(defparameter *display* nil
"X11 Display object when connection is active.")
(defparameter *screen* nil
"X11 Screen object when connection is active.")
(defparameter *root* nil
"Root window on display when connection is active.")
(defparameter *gremblin* nil
"Image displayed in window")
(defun open-x-display ()
"Open default \":0.0\" display"
(setf *display* (xlib:open-display "" :display 0))
(setf *screen* (car (xlib:display-roots *display*)))
(setf *root* (xlib:screen-root *screen*))
(unless *root*
(error "Failed to open display~%"))
*root*)
(defun close-x-display ()
(xlib:close-display *display*)
(setf *display* nil))
(defun show-image (win gcon image)
"Display image. Called on exposure events."
;; (format t "-- Exposure --~%")
(xlib:put-image win gcon image :x 0 :y 0
:width (xlib:image-width image)
:height (xlib:image-height image)
:bitmap-p t)
(xlib:display-force-output *display*))
(defun handle-events (refresh-image)
"Process events, passing function to refresh image on window"
(xlib:event-case (*display*)
(:button-press (code window)
(case code
(3 t)))
(:selection-notify (window selection target property)
nil)
(:key-press (code window)
(case (xlib:keycode->keysym *display* code 0)
;; 'q' keycode causes exit
(#o161 t)))
(:exposure (count window)
(if (= 0 count)
(funcall refresh-image window))
nil) ))
(defun dump-data (image)
"Dump pixmap data as grid"
(let ((data (xlib::image-x-data image))
(width (xlib:image-width image))
(height (xlib:image-height image))
(bytes-per-line (xlib::image-x-bytes-per-line image)))
(format t "Bitmap :width ~A :height ~A :bytes-per-line ~A~%"
width height bytes-per-line)
(dotimes (yc height)
(format t "|")
(let ((rowpos (* bytes-per-line yc)))
(dotimes (xc width)
(multiple-value-bind (byte-offset bit-offset)
(floor xc 8)
(format t "~A" (if (/= (logand (aref data (+ rowpos byte-offset))
(expt 2 bit-offset))
0)
"*"
" ")))))
(format t "|~%"))))
(defun main (bmfile)
"Say using via-voice whatever pasted in its window."
;; Read in background image
(let ((bmfile (or bmfile "gremblin.xbm")))
(setf *gremblin* (or (xlib:read-bitmap-file bmfile)
(error "Cannot read bitmap file: ~A~%" bmfile))))
(format t "~A~%" *gremblin*)
; (format t "data (~S):~%~s~%" (type-of (xlib::image-x-data *gremblin*))
; (xlib::image-x-data *gremblin*))
; (dump-data *gremblin*)
(open-x-display)
;; Set up background pixmap
(let* ((width (xlib:image-width *gremblin*))
(height (xlib:image-height *gremblin*))
(black-pixel (xlib:screen-black-pixel *screen*))
(win (xlib:create-window :parent *root* :x 10 :y 10
:width width :height height
:background black-pixel
:event-mask '(:button-press
:key-press
:exposure)))
;; Try for an appropriate color
(color (xlib:alloc-color (xlib:window-colormap win)
"Light Green"))
(gcon (xlib:create-gcontext :drawable win
:foreground color)))
(setf (xlib:wm-name win) "Gremblin")
(xlib:map-window win)
(xlib:display-finish-output *display*)
;; Process event loop
(handle-events (lambda (win) (show-image win gcon *gremblin*)))
;; Done
(xlib:unmap-window win)
(xlib:destroy-window win))
(close-x-display))
#-cmu
(main (car *ARGS*))
====== END OF showbm.lisp ======
--
Barry Fishman