From: Chris M. <ch...@cm...> - 2006-12-15 01:41:13
|
Hi, I am using the wxHaskell library built from the Darcs repository at haskell.org, with wxWidgets "gtk-2.6.3" and GHC 6.6. I am trying to draw a polygon with the "polygon" function, but it isn't doing what I expected. I wrote the following program: > import Graphics.UI.WX > > main = start go > > go = frame [on paint := p] > > p dc view = polygon dc [(pt 50 50), (pt 100 50), (pt 75 100)] [] and I expected to get a an isosceles triangle like this (ASCII art): ------- \ / \ / v but instead, I get this: http://www.cmears.id.au/triangle.png >From some experimentation, it seems that the first line is drawn correctly, but the subsequent ones are drawn from the origin instead of from the previous point, and the last point is ignored altogether. Also, I ran the "Camels" sample program in samples/contrib/ and it looks like this: http://www.cmears.id.au/camels.png Can anyone help me understand what is happening? Thanks, Chris |
From: Chris M. <ch...@cm...> - 2006-12-15 21:34:14
|
Chris Mears <ch...@cm...> writes: > I am using the wxHaskell library built from the Darcs repository at > haskell.org, with wxWidgets "gtk-2.6.3" and GHC 6.6. I am trying to > draw a polygon with the "polygon" function, but it isn't doing what I > expected. [...] > From some experimentation, it seems that the first line is drawn > correctly, but the subsequent ones are drawn from the origin instead of > from the previous point, and the last point is ignored altogether. I think I have tracked down the source of the problem. It works correctly on my 32-bit computer, but misbehaves on the 64-bit one. Summary: On my 64-bit machine, Haskell Int is 64-bit, C int is 32-bit. The polygon function takes a list of Point, where a Point is a pair (basically) of Ints. On 64-bit GHC, an Int is 64-bits long, so each component of a Point is 64-bits. The Point components are marshalled into an array and passed to C code (wxc/src/ewxw/eljdc.c). The C code treats the array as an array of (C) int. However, on the 64-bit machine a C int is 32-bits. So, when I passed the 64-bit points (50, 50), (100, 100), etc. as 32-bit points they were interpreted as (50, 50), (0, 0), (100, 100), etc., which explains the strange drawing I saw. Changing the cast in the C code from (int*) to (long*) corrects the problem, but is not a general fix. Sadly, I don't know enough about FFI and marshalling to suggest the proper correction. |
From: Jeremy O'D. <jer...@gm...> - 2006-12-18 12:23:23
|
Hi Chris, On 15/12/06, Chris Mears <ch...@cm...> wrote: > Chris Mears <ch...@cm...> writes: > > > I am using the wxHaskell library built from the Darcs repository at > > haskell.org, with wxWidgets "gtk-2.6.3" and GHC 6.6. I am trying to > > draw a polygon with the "polygon" function, but it isn't doing what I > > expected. [...] > I think I have tracked down the source of the problem. It works > correctly on my 32-bit computer, but misbehaves on the 64-bit one. > Summary: On my 64-bit machine, Haskell Int is 64-bit, C int is 32-bit. This makes perfect sense. I think you may well be the first person to have tried wxHaskell on a 64 bit machine, so perhaps no surprise that you are coming up with these issues. > The polygon function takes a list of Point, where a Point is a pair > (basically) of Ints. On 64-bit GHC, an Int is 64-bits long, so each > component of a Point is 64-bits. The Point components are marshalled > into an array and passed to C code (wxc/src/ewxw/eljdc.c). The C code > treats the array as an array of (C) int. However, on the 64-bit machine > a C int is 32-bits. > > So, when I passed the 64-bit points (50, 50), (100, 100), etc. as 32-bit > points they were interpreted as (50, 50), (0, 0), (100, 100), etc., > which explains the strange drawing I saw. Changing the cast in the C > code from (int*) to (long*) corrects the problem, but is not a general > fix. Sadly, I don't know enough about FFI and marshalling to suggest > the proper correction. Unfortunately, I think your basic solution is the way forward, but probably mapped onto a suitable set of macros to hide the platform difference. We could probably do this by working through all of the wxC implementation files and replacing all int with types of known size and appropriate casts. Very tedious, but not difficult. I think we, as the development team, need to put this on our TODO list, and I am happy to do once I have finished cabalization (so it may take a while). I'll need help to test it though - I have four machines available to me, but none has a 64 bit CPU :-( Regards Jeremy |