From: Paul Tarvydas
Subject: Win32 call on CAPI pane
Date: 
Message-ID: <MW8i7.21095$f01.5637537@news3.rdc1.on.home.com>
I need a second pair of eyes to look at this simple test and tell me
what I've done wrong or what wrong assumptions I have.

Goal: draw a bezier curve onto an output pane of an existing CAPI
interface.

Problem: CAPI doesn't have beziers.  Win32 does.  I want to make a
Win32 call on a CAPI pane.  The Win32 call requires a Win32 device
context.  I fished around, using Wade's package browser and an
inspector opened on a live CAPI interface.  I found a slot
suspiciously name capi-win32-lib::hdc and am trying to use it as the
dc sent to the Win32 call.  I've reduced the problem to drawing a
simple straight line with Polyline.

Here's the test code.  It uses my home-grown fli:poly-line to draw one
line and capi's gp:draw-line to draw a second line.  Only the
gp:draw-line line appears.

Thanks in advance.
pt


;;
;; Tests to see if I can put a Win32 Polybezier onto a CAPI output-pane.
;; Start by seeing if I can put a simple Polyline out first.
;;

(defparameter *win* nil)

(defun run ()
  (setf *win* (make-instance 'capi:output-pane
                             :min-width 300
                             :min-height 300))
  (capi:contain *win*)
  (line *win*))

(fli:define-foreign-function (poly-line "Polyline")
    ((hdc (:unsigned :long)) (points :ptr) (npoints :long))
  :result-type :boolean
  :calling-convention :stdcall)

(defun get-dc (pane)
  "I'm guessing that this gets the Windows device
   context for the given CAPI pane."
  (slot-value (capi-internals:representation pane)
              'capi-win32-lib::hdc))

(defun line (win)
  (let ((arr (fli:allocate-foreign-object :type '(:c-array :long 4))))
   (setf (fli:foreign-aref arr 0) 0)
   (setf (fli:foreign-aref arr 1) 0)
   (setf (fli:foreign-aref arr 2) 100)
   (setf (fli:foreign-aref arr 3) 100)
   (print (get-dc win))
   (poly-line (get-dc win) arr 2)
   (gp:draw-line win 100 100 200 100)))

From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mb96p$tcp$1@news3.cadvision.com>
> Here's the test code.  It uses my home-grown fli:poly-line to draw one
> line and capi's gp:draw-line to draw a second line.  Only the
> gp:draw-line line appears.
>

Here's some code I just hobbled together last night to draw round
rectangles, you have to do more stuff with pens and brushs.  The function is
not complete yet for adjusting pen/fill color and pattern.

See calls to win32::create-pen

(in-package :graphics-ports)

(defun draw-round-rectangle (port x y width height width-ellipse
height-ellipse)
  (fli:with-dynamic-foreign-objects ()
    (let* ((hwnd (slot-value (slot-value port 'representation) 'win32:hwnd))
           (hdc (slot-value (slot-value port 'representation)
'capi-win32-lib::hdc))
           (hpen (win32::create-pen win32::ps_solid 0 win32::black_pen))
           (oldpen (win32::select-object hdc hpen))
           (logbrush (fli:allocate-foreign-object :type
'win32::tag-logbrush))
           (hbrush (win32::create-brush-indirect
                    (progn
                      (setf (fli:foreign-slot-value logbrush
'win32::lb-style) win32::bs_hollow)
                      logbrush)))
           (oldbrush (win32::select-object hdc hbrush)))
      (win32:round-rect
       hdc
       x y (+ x width) (+ y height)
       width-ellipse height-ellipse)
      (win32::select-object hdc oldpen)
      (win32::delete-object hpen)
      (win32::select-object hdc oldbrush)
      (win32::delete-object hbrush))))
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mbarl$u2b$1@news3.cadvision.com>
>
> (defun get-dc (pane)
>   "I'm guessing that this gets the Windows device
>    context for the given CAPI pane."
>   (slot-value (capi-internals:representation pane)
>               'capi-win32-lib::hdc))
>
> (defun line (win)
>   (let ((arr (fli:allocate-foreign-object :type '(:c-array :long 4))))
>    (setf (fli:foreign-aref arr 0) 0)
>    (setf (fli:foreign-aref arr 1) 0)
>    (setf (fli:foreign-aref arr 2) 100)
>    (setf (fli:foreign-aref arr 3) 100)
>    (print (get-dc win))
>    (poly-line (get-dc win) arr 2)
>    (gp:draw-line win 100 100 200 100)))


This works

(in-package :graphics-ports)

(fli:define-foreign-function (poly-line "Polyline")
    ((hdc (:unsigned :long)) (points :ptr) (npoints :long))
  :result-type :boolean
  :calling-convention :stdcall)

(defun draw-poly-line (port)
  (fli:with-dynamic-foreign-objects ()
    (let* ((arr (fli:allocate-foreign-object :type '(:c-array :long 4)))
           (hdc (slot-value (slot-value port 'representation)
'capi-win32-lib::hdc))
           (hpen (win32::create-pen win32::ps_solid 0 win32::black_pen))
           (oldpen (win32::select-object hdc hpen)))

      (setf (fli:foreign-aref arr 0) 0)
      (setf (fli:foreign-aref arr 1) 0)
      (setf (fli:foreign-aref arr 2) 100)
      (setf (fli:foreign-aref arr 3) 100)
      (poly-line hdc arr 2)
      (win32::select-object hdc oldpen)
      (win32::delete-object hpen))))

Wade
From: Jochen Schmidt
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mb7hd$1la$1@rznews2.rrze.uni-erlangen.de>
Paul Tarvydas wrote:

> I need a second pair of eyes to look at this simple test and tell me
> what I've done wrong or what wrong assumptions I have.
> 
> Goal: draw a bezier curve onto an output pane of an existing CAPI
> interface.
> 
> Problem: CAPI doesn't have beziers.  Win32 does.  I want to make a
> Win32 call on a CAPI pane.  The Win32 call requires a Win32 device
> context.  I fished around, using Wade's package browser and an
> inspector opened on a live CAPI interface.  I found a slot
> suspiciously name capi-win32-lib::hdc and am trying to use it as the
> dc sent to the Win32 call.  I've reduced the problem to drawing a
> simple straight line with Polyline.

I would recommend you to implement bezier curves in Lisp itself and use
the normal CAPI (or GP) API to bring it to screen. You throw away _all_
portability to other platforms.
I've seen several postings last time that talk on mixing CAPI with Win32
special features and IMHO this way should only be gone if there is no
other easy solution.

If more of us begin to create _portable_ CAPI code it will be much better
than exploiting all cross-platform benefits LispWorks brings with it.

Btw. "OnLisp" contains an implementation of calculating Bezier curves that
consists of ~35 lines of code...

ciao,
Jochen

--
http://www.dataheaven.de
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mbdg9$uo7$1@news3.cadvision.com>
> I would recommend you to implement bezier curves in Lisp itself and use
> the normal CAPI (or GP) API to bring it to screen. You throw away _all_
> portability to other platforms.

The only other platform that CAPI runs on is X.  Windows interface features
(I think) are richer than X's.  What I really what is a richer feature set
for Windows, not Linux/Unix.  I am exploring writing things like
gp:draw-rounded-rectangle within CAPI (just for Windows), BUT, it is obvious
already that CAPI inherently does not have the drawing capabilities (and
concepts) of GDI (and certainly not DirectX).  CAPI seems to have used the
lowest common denonimator approach in suppling a solution, which means lower
functionality.

I am all for CAPI's functionality to be increased but I also cannot wait
around for Xanalys to give me what I want.  Bluntly, for me, I am not
interested in CAPI-Widnows/CAPI-X portability.  I would much rather have
CAPI-Windows/CAPI-Mac portability (with LispWorks running on the Mac).


> I've seen several postings last time that talk on mixing CAPI with Win32
> special features and IMHO this way should only be gone if there is no
> other easy solution.

To late.  (define easy?)

Moving on ahead......  :)

Wade
From: Jochen Schmidt
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mbfoi$60p$1@rznews2.rrze.uni-erlangen.de>
Wade Humeniuk wrote:

>> I would recommend you to implement bezier curves in Lisp itself and use
>> the normal CAPI (or GP) API to bring it to screen. You throw away _all_
>> portability to other platforms.
> 
> The only other platform that CAPI runs on is X.  Windows interface
> features
> (I think) are richer than X's.  What I really what is a richer feature set
> for Windows, not Linux/Unix.  I am exploring writing things like
> gp:draw-rounded-rectangle within CAPI (just for Windows), BUT, it is
> obvious already that CAPI inherently does not have the drawing
> capabilities (and
> concepts) of GDI (and certainly not DirectX).  CAPI seems to have used the
> lowest common denonimator approach in suppling a solution, which means
> lower functionality.

X provides the same functionality but I fear you would not be happy if CAPI 
would be only extended on the X side.

CAPI is meant as a portable GUI substrate - I would not go for the way of 
making it a Windows only toolkit!!!

Things like OpenGL might need to go down to this level - and Xanalys 
already provides this for X _and_ Windows.

I see no reason to do Bezier-Curves or even only a rounded rectangle by 
using FLI and the WinAPI.
 
> I am all for CAPI's functionality to be increased but I also cannot wait
> around for Xanalys to give me what I want.  Bluntly, for me, I am not
> interested in CAPI-Widnows/CAPI-X portability.  I would much rather have
> CAPI-Windows/CAPI-Mac portability (with LispWorks running on the Mac).
> 
> 
>> I've seen several postings last time that talk on mixing CAPI with Win32
>> special features and IMHO this way should only be gone if there is no
>> other easy solution.
> 
> To late.  (define easy?)

To late for what?
I don't see it so difficult to implement a gp:draw-rounded-rectangle 
function by the means of only GP...

> Moving on ahead......  :)

Probably - but if you further define new Win32 specific CAPI enhancement 
think it would be better to do them in a WIN32-CAPI-UTILITIES package and
not the cross-platform vendor-packages like CAPI or GP!

ciao,
Jochen

--
http://www.dataheaven.de
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mbhnh$vvc$1@news3.cadvision.com>
>
> To late for what?
> I don't see it so difficult to implement a gp:draw-rounded-rectangle
> function by the means of only GP...

My code is already not portable.

It is hard to do it with CAPI.  Besides just drawing the outline (in CAPI
you are not assurred the sides and arcs will match up with no pixels missing
or extra), how do you effectively fill a round rectangle with a pattern with
CAPI only?  The answer is not without a great deal of difficulty.   That is
why it is a primitive in Windows/GDI, Mac, X.  How do you use a patterned
pen (line) with only CAPI, the answer is you cannot without a great deal of
work.

Other simple functions, how to create a colored button?  (something I do not
really need but..  Once in while it comes in handy)

The list goes on...

The features I like about CAPI are layouts and hiding most of the message
processing and multiprocessing issues.  I think Xanalys purposefully left
open output-panes and pinboard-layouts for this kind of enhancement.  The
example code included for OpenGL does that very thing.

Are you concerned that LWW developers will branch off and leave the LWL
developers in the dust?

My mind is still not made up completely about whether to just use win32
functions directly or blend them with CAPI.  The windows API so far seems
not so hard to use, and I came into it not knowing much.  But I am still
proceeding with the idea of blending the functionality into CAPI.


Wade
From: Jochen Schmidt
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mbiio$7eb$1@rznews2.rrze.uni-erlangen.de>
Wade Humeniuk wrote:

> Are you concerned that LWW developers will branch off and leave the LWL
> developers in the dust?

I'm concerned that the portability issues are raising further.
There are plenty of things in the manual that do not work yet on Linux
that work on Win32 (e. g. your view-pane stuff in the package-browser)

If you now go further defining (in GP and CAPI package) additional
primitives only available to Win32 then it may begin to be a hit in the face
to call CAPI a crossplattform toolkit.
So if you implement system-dependent stuff implement it in another package.
What if Xanalys comes up with an own version of draw-rounded-rectangle & Co.
that differs from yours?

> My mind is still not made up completely about whether to just use win32
> functions directly or blend them with CAPI.  The windows API so far seems
> not so hard to use, and I came into it not knowing much.  But I am still
> proceeding with the idea of blending the functionality into CAPI.

Then do it externally from the vendor-stuff and try to provide interfaces 
that to not show the implementation-details. So other people can implement
it for e. g. X using your interface.

ciao,
Jochen

--
http://www.dataheaven.de
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mck0g$c6u$1@news3.cadvision.com>
> I'm concerned that the portability issues are raising further.
> There are plenty of things in the manual that do not work yet on Linux
> that work on Win32 (e. g. your view-pane stuff in the package-browser)
>

Hmm..  really.  You mean list-view, right?  If you just change the class to
capi:list-panel it should work but you will not see the nicknames.

Wade
From: Jochen Schmidt
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9md652$3t2$1@rznews2.rrze.uni-erlangen.de>
Wade Humeniuk wrote:

>> I'm concerned that the portability issues are raising further.
>> There are plenty of things in the manual that do not work yet on Linux
>> that work on Win32 (e. g. your view-pane stuff in the package-browser)
>>
> 
> Hmm..  really.  You mean list-view, right?  If you just change the class
> to capi:list-panel it should work but you will not see the nicknames.


Under X the Item is named CAPI:MULTIPLE-COLUMN-LIST-PANEL is the equivalent
but there are some differences...

ciao,
Jochen

--
http://www.dataheaven.de
From: Marc Battyani
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <846CD4F501BFFA66.C620FB3244FCD937.141AEDC2EC15E569@lp.airnews.net>
"Wade Humeniuk" <········@cadvision.com> wrote
> >
> > To late for what?
> > I don't see it so difficult to implement a gp:draw-rounded-rectangle
> > function by the means of only GP...
>
> My code is already not portable.
>
> It is hard to do it with CAPI.  Besides just drawing the outline (in CAPI
> you are not assurred the sides and arcs will match up with no pixels
missing
> or extra), how do you effectively fill a round rectangle with a pattern
with
> CAPI only?  The answer is not without a great deal of difficulty.   That
is
> why it is a primitive in Windows/GDI, Mac, X.  How do you use a patterned
> pen (line) with only CAPI, the answer is you cannot without a great deal
of
> work.
>
> Other simple functions, how to create a colored button?  (something I do
not
> really need but..  Once in while it comes in handy)
>
> The list goes on...
>
> The features I like about CAPI are layouts and hiding most of the message
> processing and multiprocessing issues.  I think Xanalys purposefully left
> open output-panes and pinboard-layouts for this kind of enhancement.  The
> example code included for OpenGL does that very thing.
>
> Are you concerned that LWW developers will branch off and leave the LWL
> developers in the dust?
>
> My mind is still not made up completely about whether to just use win32
> functions directly or blend them with CAPI.  The windows API so far seems
> not so hard to use, and I came into it not knowing much.  But I am still
> proceeding with the idea of blending the functionality into CAPI.

I think you should drop CAPI for your Win32 stuff. Using unexported
functions from LW packages is a good way to have problem with future CAPI
releases. I redefined all the FLI functions I use in a WINAPI package to be
sure to have no clash with CAPI.
Doing so you loose compatibility with Linux/FreeBSD but you gain
compatibility with other Win32 Lisps (ACL, Corman, CLisp, etc.) as you just
have to change the FLI syntax.

Marc
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9mcjne$c0b$1@news3.cadvision.com>
> I think you should drop CAPI for your Win32 stuff. Using unexported
> functions from LW packages is a good way to have problem with future CAPI
> releases. I redefined all the FLI functions I use in a WINAPI package to
be
> sure to have no clash with CAPI.
> Doing so you loose compatibility with Linux/FreeBSD but you gain
> compatibility with other Win32 Lisps (ACL, Corman, CLisp, etc.) as you
just
> have to change the FLI syntax.

But I have found a lot of good stuff in CAPI, like

define-interface
layouts

A LOT of thought and good work has gone into CAPI and I would like to see
its functionality expanded.  Like I said before I just need a handful of
graphics operations (better blitting and some additional geometric
operations).  The other functionality I have in mind would be really nice,
but I can live without them.  I am not overly concerned with the internal
interfaces I am using in CAPI/GP, they seem relatively simple (mostly
accessors, like accessing a hdc for a window).  LispWorks has a WIN32 (which
is seperate from CAPI) package that, so far, seems to have had every API
defined for what I needed.  I do not see how their WIN32 API could change in
any meaningful way, as it is just a FLI to win32.

How many years is it now that CAPI has been around, 2, 4, 6??  I got it 2
years ago and the documentation was outdated then, so it must be older.


Wade
From: Wade Humeniuk
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9me7n8$2h0$1@news3.cadvision.com>
> I think you should drop CAPI for your Win32 stuff. Using unexported
> functions from LW packages is a good way to have problem with future CAPI
> releases. I redefined all the FLI functions I use in a WINAPI package to
be
> sure to have no clash with CAPI.
> Doing so you loose compatibility with Linux/FreeBSD but you gain
> compatibility with other Win32 Lisps (ACL, Corman, CLisp, etc.) as you
just
> have to change the FLI syntax.


Well, further delving into the windows api has revealed lots of
functionality that I have needed but did not have in CAPI,  the simple case
being DrawText (with justification, centering, blah blah.....).

I give up!

Wade
From: Paul Tarvydas
Subject: Re: Win32 call on CAPI pane
Date: 
Message-ID: <9iai7.21597$f01.5761561@news3.rdc1.on.home.com>
Thanks.

It's amazing how well writing your own problem down works.  Ten minutes
after hitting SEND, I realized that my program doesn't work because I got
the Windows part of it all wrong.  Sigh.  Whenever I touch Windows, it's
like Slartibartfast starting a new day and wondering what the pointy stick
(a pencil in his hand) is for.

You're right - the code for Bezier curves is in the book!

pt