Discussion:
Drawing in Mac OS X
n***@efi.com
2004-06-27 11:38:07 UTC
Permalink
Hi All,

I am new wxWidgets, may be this question would have been repeated many times
(Is there any archive maintained for wxWidgets mailing lists?).

I am drawing on a wxWindow object by passing that as an argument to
wxClientDC. I could see the output for the code in the windows platform, but
the same code is not producing any result in Mac OS X 10.3.

The same code when invoked from OnSize() method, I could see the drawing
flashing for a fraction of a second and then disappear. I think I am missing
something basic which is essential to get results in Mac.

Please provide your suggestions.

Thanks in advance.

Regards,
Nagaraj
Stefan Csomor
2004-06-28 06:05:33 UTC
Permalink
Hi

Drawing should never occur as result of a event like OnSize, only when
getting a wxPaintEvent, have a look at the drawing sample

HTH

Stefan
-----Original Message-----
Sent: Sonntag, 27. Juni 2004 12:38
Subject: Drawing in Mac OS X
Hi All,
I am new wxWidgets, may be this question would have been repeated many times
(Is there any archive maintained for wxWidgets mailing lists?).
I am drawing on a wxWindow object by passing that as an argument to
wxClientDC. I could see the output for the code in the windows platform, but
the same code is not producing any result in Mac OS X 10.3.
The same code when invoked from OnSize() method, I could see the drawing
flashing for a fraction of a second and then disappear. I think I am missing
something basic which is essential to get results in Mac.
Please provide your suggestions.
Thanks in advance.
Regards,
Nagaraj
---------------------------------------------------------------------
Christopher B Egner
2004-06-28 18:10:34 UTC
Permalink
Hi,

I'm not sure he's drawing as a result of OnSize. It sounds to me
like he's drawing and seeing no result on the screen until he resizes
the window. Is this right?

MacOS X doesn't do window drawing quite like any other OS I've run
into. OS X always draws everything, or at least it appears that way
to the application, regardless of any occlusion. As a result, there
seems to be a good caching mechanism involved. That's good for the
user, but complicates matters a little for the developer. Explicity
firing a paint event when you have finished drawing seems to solve
the problem. Use wxWindow::Refresh to do this.

I've implemented my own rotating-buffer scheme for my app.
Basically, I draw to a buffer then blit to the screen when done.
MacOS X needs this to be followed by a Refresh in order for it to
take effect. I don't recall that MSW and X11 need this. Been a
little while since I solved this issue and I don't remember the
details specifically. Sorry.

Chris Egner
Chris Barker
2004-06-28 19:03:03 UTC
Permalink
Post by Christopher B Egner
MacOS X doesn't do window drawing quite like any other OS I've run
into. OS X always draws everything, or at least it appears that way to
the application, regardless of any occlusion. As a result, there seems
to be a good caching mechanism involved. That's good for the user, but
complicates matters a little for the developer. Explicity firing a
paint event when you have finished drawing seems to solve the problem.
Use wxWindow::Refresh to do this.
OS-X automatically does double buffering for you. This is very nice, but
kind of a pain when doing cross-platform apps, as the other platforms
don't do it. As a result you can get triple buffering accidentally on
the Mac.
Post by Christopher B Egner
I've implemented my own rotating-buffer scheme for my app. Basically, I
draw to a buffer then blit to the screen when done.
Exactly, so you now have a triple buffer on the Mac. (So do I, I'm not
being critical!)
Post by Christopher B Egner
MacOS X needs this
to be followed by a Refresh in order for it to take effect.
Sometimes. That's because you've drawn to OS-X's buffer, not the screen
itself. However, apparently, it's frowned upon to explicitly call
Refresh on OS-X. Ideally, the system keeps the screen updated for you.
Also, Refresh() does a complete clear and re-draw of the Window, which
can produce some flashing. I've found a Yield() will usually paint the
screen for you, but it's frowned upon to use that a lot also...

On the plus side, I've found recent versions of wx seems to work better
in this regard, I have no idea why, but I've been able to remove a
Yield() that I used to need. You might want to go back and check if you
still need all your Refresh() calls, when you upgrade.
Post by Christopher B Egner
I don't
recall that MSW and X11 need this.
Nope. They don't buffer for you, so when you draw to a wxClientDC, you
are drawing directly tho the screen.

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
Christopher B Egner
2004-06-28 22:50:42 UTC
Permalink
Post by Chris Barker
Sometimes. That's because you've drawn to OS-X's buffer, not the
screen itself. However, apparently, it's frowned upon to explicitly
call Refresh on OS-X. Ideally, the system keeps the screen updated
for you. Also, Refresh() does a complete clear and re-draw of the
Window, which can produce some flashing. I've found a Yield() will
usually paint the screen for you, but it's frowned upon to use that
a lot also...
In my case, this is okay since I'm plotting and basically throw away
everything I once had. Your mileage may vary, however.
Post by Chris Barker
On the plus side, I've found recent versions of wx seems to work
better in this regard, I have no idea why, but I've been able to
remove a Yield() that I used to need. You might want to go back and
check if you still need all your Refresh() calls, when you upgrade.
An interesting solution, though I'd hesitate to count on it. Is
there any reason other than the one that it forces a full redraw
(though you can specify a region, right?) not to use Refresh? In my
case, I've swapped out the Carbon Threads implementation in favor of
the pthreads implementation. I found that programming for one thread
model to be particularly advantageous. As a result, it's not clear
to me that calling Yield will have the same effect.

Chris Egner
Kevin Ollivier
2004-06-28 23:15:33 UTC
Permalink
Hi,
Post by Christopher B Egner
Post by Chris Barker
Sometimes. That's because you've drawn to OS-X's buffer, not the
screen itself. However, apparently, it's frowned upon to explicitly
call Refresh on OS-X. Ideally, the system keeps the screen updated
for you. Also, Refresh() does a complete clear and re-draw of the
Window, which can produce some flashing. I've found a Yield() will
usually paint the screen for you, but it's frowned upon to use that a
lot also...
wxMac CVS HEAD handles redraws much differently than 2.4.x, or even the
CVS from a few months ago. ;-) wxMac now lets the OS deal with control
layering and determining which regions of a control to draw, and no
longer does any actual drawing in Refresh, like it used to. So the
problems with flicker should be gone, even if you use Refresh. (Whether
or not the call is actually needed is another question, but my
suggestion is to test and see if it's still needed.)
Post by Christopher B Egner
In my case, this is okay since I'm plotting and basically throw away
everything I once had. Your mileage may vary, however.
Post by Chris Barker
On the plus side, I've found recent versions of wx seems to work
better in this regard, I have no idea why, but I've been able to
remove a Yield() that I used to need. You might want to go back and
check if you still need all your Refresh() calls, when you upgrade.
An interesting solution, though I'd hesitate to count on it. Is there
any reason other than the one that it forces a full redraw (though you
can specify a region, right?) not to use Refresh?
Basically, with the current CVS, Refresh just invalidates the control
(or a region of the control if you pass in a wxRect) and lets the OS
know it's ready for a redraw.
Post by Christopher B Egner
In my case, I've swapped out the Carbon Threads implementation in
favor of the pthreads implementation. I found that programming for
one thread model to be particularly advantageous. As a result, it's
not clear to me that calling Yield will have the same effect.
I don't think (the other =) Chris meant to say that you should call
Yield - I think he meant that calling Yield in his own code was no
longer necessary thanks to changes in wxMac's drawing code. The code is
definitely more efficient than what was in wx 2.4 and 2.5.1, so I would
recommend that anyone having problems with drawing code on OS X check
out CVS HEAD and see if they get better performance.

Kevin
Stefan Csomor
2004-06-29 11:18:52 UTC
Permalink
Hi
Post by Chris Barker
Post by Christopher B Egner
MacOS X needs this
to be followed by a Refresh in order for it to take effect.
Sometimes. That's because you've drawn to OS-X's buffer, not the screen
itself. However, apparently, it's frowned upon to explicitly call
Refresh on OS-X. Ideally, the system keeps the screen updated for you.
Also, Refresh() does a complete clear and re-draw of the Window, which
can produce some flashing. I've found a Yield() will usually paint the
screen for you, but it's frowned upon to use that a lot also...
You should not use Yield anymore, as this might lead to reentrancy problems,
if you have updated something and you want the screen to reflect this 'now'
instead of during the main event loop 'paint handling', then call
wxWindow::Update()

Best,

Stefan
David Elliott
2004-06-29 13:39:16 UTC
Permalink
Post by Stefan Csomor
You should not use Yield anymore, as this might lead to reentrancy problems,
if you have updated something and you want the screen to reflect this 'now'
instead of during the main event loop 'paint handling', then call
wxWindow::Update()
Injecting a little Cocoa knowledge I can also say that it's highly
recommended that you NEVER use the equivalent of a wxClientDC. The
documentation for and several books covering Cocoa graphics (and I
think by extension all OS X graphics) explicitly recommend that you
force a window refresh and handle the drawing from your paint event.
It is suggested that you do this even for "rubber-banding!"

So in most cases the proper solution is to, as Stefan says, handle
everything from the regular paint event and explicitly force an
Update() if you need it to draw before the next event iteration.

-Dave
Riccardo Cohen
2004-06-29 13:54:25 UTC
Permalink
hi,
This seems strange to me. I mean, for instance, movie players and games obviously don't wait for
paint event to draw things, and don't even use the native double buffering (drawing appear
immediatly, not when paint event finishes). Am I missing something ?
Post by David Elliott
Post by Stefan Csomor
You should not use Yield anymore, as this might lead to reentrancy problems,
if you have updated something and you want the screen to reflect this 'now'
instead of during the main event loop 'paint handling', then call
wxWindow::Update()
Injecting a little Cocoa knowledge I can also say that it's highly
recommended that you NEVER use the equivalent of a wxClientDC. The
documentation for and several books covering Cocoa graphics (and I think
by extension all OS X graphics) explicitly recommend that you force a
window refresh and handle the drawing from your paint event. It is
suggested that you do this even for "rubber-banding!"
So in most cases the proper solution is to, as Stefan says, handle
everything from the regular paint event and explicitly force an Update()
if you need it to draw before the next event iteration.
-Dave
---------------------------------------------------------------------
--
Riccardo Cohen

Articque
Les Roches
37230 Fondettes
France
web = http://www.articque.com
tel: +33 02 47 49 90 49
fax: +33 02 47 49 91 49
David Elliott
2004-06-29 20:16:13 UTC
Permalink
Post by Riccardo Cohen
hi,
This seems strange to me. I mean, for instance, movie players and
games obviously don't wait for paint event to draw things, and don't
even use the native double buffering (drawing appear immediatly, not
when paint event finishes). Am I missing something ?
http://developer.apple.com/documentation/Cocoa/Conceptual/DrawViews/
Tasks/OptimizingDrawing.html

--- quote ---
Deferred Drawing

Cocoa uses a deferred drawing model. Rather than drawing immediately
when it determines that drawing is necessary, a Cocoa application marks
views or (better yet) regions of views that need updating. To do this,
it uses the NSView methods setNeedsDisplay: or setNeedsDisplayInRect: .
When it comes time for a view (specifically, an NSView object) to
display itself, either at the end of an event cycle or in response to
an explicit display... message, Cocoa sends the view a drawRect:
message, asking it to draw all or part of its content. Deferring
drawing in this way promotes efficiency by enabling the Application Kit
to satisfy multiple requests to draw parts of a view with a single
drawing pass.

When your application requires immediate drawing of a view, you can
send the view one of the display... messages declared by NSView and
NSWindow. You can also lock focus on a view yourself, draw something,
and then unlock focus. However, posting deferred drawing requests
through the setNeedsDisplay: or setNeedsDisplayInRect: methods is the
preferred approach because it is more efficient.

--- end quote ---

If you drill down into the details you'll find that in Cocoa you would
do one or more [myView setNeedsDisplayInRect:someRect]; and either wait
for the event loop to update the window or call [myView
displayIfNeeded]; to do it immediately.

In wxWidgets that means you do one or more myWindow->Refresh(someRect);
and either wait for the event loop to update the window or call
myWindow->Update() to do it immediately.

/Developer/Examples/Worm is a good example of a game (a snake game
obviously) that uses setNeedsDisplay and displayIfNeeded along with a
timer to animate the display. I wish I knew of a good wxWidgets
example that did this.

-Dave
Riccardo Cohen
2004-06-29 22:47:16 UTC
Permalink
Thanks a lot, your answers are always very clear.
I had a look at the worm example, and saw that the timer (every 1/7th of second) updates the game
state and then displays it.

You can use this strategy for instance if you display the evolution of a processing. But how do you
do if the "drawRect" is itself a long processing, and you want to let the user continue to use your
application while the drawing is progressing ?

On windows, I simply draw in another thread, using a new wxClientDC(window). the drawing appears
progressively, instead of being shown only at the end, and the user interface continue tu work in
the main thread.

If you see a way of doing something similar on wxCocoa, please let me know. I'm quite sure it may be
very interesting for many people here. I'm currently working on a little sample that I'll give soon
to Stephen Csomor, and if you want it for some tests, please let me know.
Post by David Elliott
Post by Riccardo Cohen
hi,
This seems strange to me. I mean, for instance, movie players and
games obviously don't wait for paint event to draw things, and don't
even use the native double buffering (drawing appear immediatly, not
when paint event finishes). Am I missing something ?
http://developer.apple.com/documentation/Cocoa/Conceptual/DrawViews/
Tasks/OptimizingDrawing.html
--- quote ---
Deferred Drawing
Cocoa uses a deferred drawing model. Rather than drawing immediately
when it determines that drawing is necessary, a Cocoa application marks
views or (better yet) regions of views that need updating. To do this,
it uses the NSView methods setNeedsDisplay: or setNeedsDisplayInRect: .
When it comes time for a view (specifically, an NSView object) to
display itself, either at the end of an event cycle or in response to
message, asking it to draw all or part of its content. Deferring
drawing in this way promotes efficiency by enabling the Application Kit
to satisfy multiple requests to draw parts of a view with a single
drawing pass.
When your application requires immediate drawing of a view, you can
send the view one of the display... messages declared by NSView and
NSWindow. You can also lock focus on a view yourself, draw something,
and then unlock focus. However, posting deferred drawing requests
through the setNeedsDisplay: or setNeedsDisplayInRect: methods is the
preferred approach because it is more efficient.
--- end quote ---
If you drill down into the details you'll find that in Cocoa you would
do one or more [myView setNeedsDisplayInRect:someRect]; and either wait
for the event loop to update the window or call [myView
displayIfNeeded]; to do it immediately.
In wxWidgets that means you do one or more myWindow->Refresh(someRect);
and either wait for the event loop to update the window or call
myWindow->Update() to do it immediately.
/Developer/Examples/Worm is a good example of a game (a snake game
obviously) that uses setNeedsDisplay and displayIfNeeded along with a
timer to animate the display. I wish I knew of a good wxWidgets
example that did this.
-Dave
---------------------------------------------------------------------
--
Riccardo Cohen

Articque
Les Roches
37230 Fondettes
France
web = http://www.articque.com
tel: +33 02 47 49 90 49
fax: +33 02 47 49 91 49
Chris Barker
2004-06-29 16:51:09 UTC
Permalink
Post by David Elliott
Injecting a little Cocoa knowledge I can also say that it's highly
recommended that you NEVER use the equivalent of a wxClientDC. The
documentation for and several books covering Cocoa graphics (and I think
by extension all OS X graphics) explicitly recommend that you force a
window refresh and handle the drawing from your paint event. It is
suggested that you do this even for "rubber-banding!"
So in most cases the proper solution is to, as Stefan says, handle
everything from the regular paint event and explicitly force an Update()
if you need it to draw before the next event iteration.
This would not work at all well on other platforms, so I'm not sure I
understand what to do here. Stefan, I'd love to hear your thoughts on this!

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
Christopher B Egner
2004-06-29 18:48:36 UTC
Permalink
Sorry if I'm being dim, but I don't quite understand what the Update
function does.
Post by Stefan Csomor
wxWindow::Update
virtual void Update()
Calling this method immediately repaints the invalidated area of
the window while this would usually only happen when the flow of
control returns to the event loop.
Does this imply the painting gets done in the current thread and not
the event loop. This is forbidden with wxGTK and is not a
particularly good idea with wxX11, it seems. I don't remember if MSW
freaks out or not.
Post by Stefan Csomor
Notice that this function doesn't refresh the window and does
nothing if the window hadn't been already repainted.
Has already been, maybe? I don't understand the conditional. What
does "doesn't refresh the window" mean if the purpose of this
function is to repaint it. I know there's a nuance there, it's just
escaping me.
Post by Stefan Csomor
Use Refresh first if you want to immediately redraw the window
unconditionally
So I guess this boils down to what are the differences between
Refresh and Update?

Thanks,
Chris Egner
Robin Dunn
2004-06-29 19:02:00 UTC
Permalink
So I guess this boils down to what are the differences between Refresh
and Update?
Refresh marks a portion of the window or the whole window as needing to
be repainted, which will cause a paint event to be delivered sometime
soon in order to refresh that portion of the window. Update causes that
paint event to happen immediately.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
Stefan Csomor
2004-06-30 08:50:05 UTC
Permalink
Hi

Which situations are you thinking of ? rubberbanding ?

Thanks,

Stefan
-----Original Message-----
Sent: Dienstag, 29. Juni 2004 17:51
Subject: Re: Drawing in Mac OS X
Post by David Elliott
Injecting a little Cocoa knowledge I can also say that it's highly
recommended that you NEVER use the equivalent of a wxClientDC. The
documentation for and several books covering Cocoa graphics (and I think
by extension all OS X graphics) explicitly recommend that you force a
window refresh and handle the drawing from your paint event. It is
suggested that you do this even for "rubber-banding!"
So in most cases the proper solution is to, as Stefan says, handle
everything from the regular paint event and explicitly force an Update()
if you need it to draw before the next event iteration.
This would not work at all well on other platforms, so I'm not sure I
understand what to do here. Stefan, I'd love to hear your thoughts on this!
-Chris
--
Christopher Barker, Ph.D.
Oceanographer
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
---------------------------------------------------------------------
Chris Barker
2004-06-30 19:23:49 UTC
Permalink
Post by Stefan Csomor
Which situations are you thinking of ? rubberbanding ?
Yes, as well as virtually any other time you'd use a wxClientDC.

My understanding (and this is from wxPython, not C++, if that makes any
difference) is that you only want to use a PaintDC inside a system Paint
event. There are a LOT of times when I want to draw something to the
screen when there is no paint event, and calling Refresh() causes a lot
of flashing.

-RubberBanding
-User Drawing something with the mouse
-Updating an image as a result of some other event (computation loop, etc)
-Animation

I have mostly used double buffering in my apps. In this case, I tend to
draw to the buffer, and then blit the buffer to a wxClientDC. whenever
it changes. The other option is to draw to the buffer and call
Refresh(), but that results in a lot of flashing, on GTK at least.

My Paint handler does nothing but blit the buffer to the screen.

It sounds like OS-X is double buffering for you, so I wouldn't need to
do that there, but I'm writing cross platform apps, so I'm kind of
stuck. What would be great is if wx had a double buffered Window class,
which would just be a Window on OS-X, and have the double buffering
implemented on the other platforms.
Post by Stefan Csomor
Post by David Elliott
explicitly recommend that you force a
window refresh and handle the drawing from your paint event.
I'm way out of my depth here, but I imagine that that's because OS-X
doesn't trigger Paint events very often, as most of the time it will
just repair the screen with the buffer, and your app doesn't have to do
anything. It also seems to have optimized the refresh process.
Post by Stefan Csomor
Post by David Elliott
So in most cases the proper solution is to, as Stefan says, handle
everything from the regular paint event and explicitly force an Update()
if you need it to draw before the next event iteration.
I've done a couple little test apps in wxPython to see how this would
work. Much to my surprise, I don't get any of the flicker that I
expected! However, this is a pretty simple example. It does two things:

1) Draws a line while the user drags the left mouse button
2) Runs a little animation of a line being drawn

I did three versions, the first two without using a wxClientDC, and the
third with a wxClientDC, which is how I have always done it.

TestUpdate.py is the simplest, without a wxClientDC
TestUpdate2.py uses a double buffer, without a wxClientDC
TestUpdate3.py uses a wxClientDC

I noticed a couple things while writing these tests:

- Without double buffering or a wxClientDC, the entire image has to be
re-drawn with each change, rather than just drawing the new line. This
would be a real problem if you had a complex image (rubberbanding over a
complex image, for instance)

- With the double buffering, I'm essentially triple buffering on OS-X (I
think!)

- With the wxClientDC, I found I needed a wxApp.Yield() in the animation
method, or it would wait 'till the end to draw. Update() did not work in
this case.

Note that these were tested only on wxGTK with wxPython 2.5.1

How should I be doing this kind of thing???

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
Stefan Csomor
2004-07-02 07:52:16 UTC
Permalink
Hi Chris

Thanks for your illustrative samples

I agree that flickering makes the nicest solutions pretty worthless... and
of course the amount of flickering is related to the amount of painting in
the event for a non buffered solution...

My ideal would be a DC that is aware of the OS capabilities, offers
buffering where the OS doesn't and maintains a 'dirty region' there for all
the areas changed since the last blit to the main window.

I have not yet thought through that concept fully, as I'd like to have
multiple layers (true OSX selection is done via an overlayed semitransparent
rect) and paint events for lazy rendering where wanted.

I wanted to offer a more formal proposal but things did not yet fall into
place easily, and wxMac is demanding fixes...

Thanks,

Stefan
Chris Barker
2004-07-02 16:53:42 UTC
Permalink
Post by Stefan Csomor
Thanks for your illustrative samples
I agree that flickering makes the nicest solutions pretty worthless... and
of course the amount of flickering is related to the amount of painting in
the event for a non buffered solution...
My conclusion from that exercise is that you need to either use a
wxClientDC or a double buffer, so that you don't re-draw stuff
unnecessarily. The problem with the OS-X double buffer is that you don't
have access to it directly, although, without knowing the internals, I
guess that's what a wx.ClientDC is drawing too. If that's the case, why
is recommended not to use it? Or was the recommendation not to actually
draw directly to the screen, which I don't think there is any way to so
in wx anyway.
Post by Stefan Csomor
My ideal would be a DC that is aware of the OS capabilities, offers
buffering where the OS doesn't and maintains a 'dirty region' there for all
the areas changed since the last blit to the main window.
That would be fabulous, though I'm not sure it would be a DC. It seems
to me it would be a wxWindow. It's really the window that needs to keep
a buffer around. If the system already does this, then there is nothing
to do, and on a system that doesn't double buffer, you'd have to
maintain a buffer.

With this kind of window, the user would never have to deal with Paint
events, and would draw to it with another kind of DC (though I'd be
tempted to overload wxClientDC) that just drew to the buffer.

Hmmm. I wrote a little Buffered Window class for the wxPython Wiki:

(http://wiki.wxpython.org/index.cgi/DoubleBufferedDrawing )

Perhaps I'll try to re-work to fit this idea better.

By the way, wxPython has a wxBufferedDC, but it really doesn't do much
for you. You can see how it works on the Wiki page above.
Post by Stefan Csomor
I have not yet thought through that concept fully, as I'd like to have
multiple layers (true OSX selection is done via an overlayed semitransparent
rect) and paint events for lazy rendering where wanted.
This went right over my head.
Post by Stefan Csomor
I wanted to offer a more formal proposal but things did not yet fall into
place easily, and wxMac is demanding fixes...
wxMac bug fixes are certainly a priority, but perhaps you'll get time
for this one day...

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
Robert J. Lang
2004-07-04 02:51:20 UTC
Permalink
I'm using CVS HEAD 2004-07-03, trying to compile MachO targets with
CodeWarrior 8.3 under OS X 10.2.8. The problem is that type std::size_t is
not properly recognized in a wxW project.

The problem can be illustrated by pasting the following 4 lines at the very
beginning of file minimal.cpp in the minimalM8.mcp project:

#include <vector>
std::vector<int> foo1;
std::size_t foo2;
size_t foo3;

In a non-wxWidgets project, the 4th line generates a compiler error, as it
should, since there's no using namespace std directive, but the first 3
lines compile OK.

However, in the minimal sample, MachO target, the 3rd line, "std::size_t
foo2;", generates an error while the 4th line flies through un-flagged.

And in minimal's Carbon target, the same four lines compile with no errors
-- which is incorrect behavior because size_t shouldn't be defined outside
of namespace std.

I guess that wxW's prefix header, wx_cwc_d.h, is interacting with MSL's
<vector> standard library to put size_t in the global namespace rather than
in namespace std, and it does it differently in Carbon and MachO targets.
But I haven't figured out precisely how, or how to fix it. Any suggestions?

Thanks,

Robert
Robert J. Lang
2004-07-04 03:25:53 UTC
Permalink
This is a problem with building the Carbon libraries from wxWindowsM8.xml.

I'm compiling CVS HEAD 2004-07-03 using CodeWarrior 8.3 under OS X 10.2.8.
Project wxWindowsM8.mcp: MachO targets build OK, but the Carbon targets
generate a series of errors like this one:

Error : undefined identifier 'QDLocalToGlobalPoint'
window.cpp line 1033 obalPoint( UMAGetWindowPort( (WindowRef)
tlw->MacGetWindowRef() ) , &tlworigin ) ;

According to the Apple docs, QDLocalToGlobalPoint() should be declared in
<Quickdraw.h>, but adding "#include <Quickdraw.h>" immediately before the
offending command doesn't help.

I have 3 header files by that name on my system:

(1) /Developer/Headers/FlatCarbon/Quickdraw.h

(2) /Applications/Metrowerks CodeWarrior 8.0/MacOS
Support/Universal/Interfaces/Cincludes/Quickdraw.h

(3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Framewor
ks/QD.framework/Versions/A/Headers/Quickdraw.h

It looks like the access paths in wxWindowsM8.mcp are set to pick up (2),
which doesn't contain a declaration for QDLocalToGlobalPoint.

I'm sort of reluctant to start munching around with the access paths to pick
up one of the other 2, since I'm not sure what other side effects there
might be. Any suggestions?

Thanks,

Robert
Stefan Csomor
2004-07-04 05:23:10 UTC
Permalink
Hi

The correct solution is to update your header files, what's odd is that
actually you should first get an error message from a pragma that tells you
to do so.

ftp://ftp.apple.com/developer/Development_Kits/UniversalInterfaces3.4.2.img.
bin

drop the corresponding folders into your MacOS Support/Universal folder

HTH

Stefan
-----Original Message-----
Sent: Sonntag, 4. Juli 2004 04:26
Subject: Unrecognized QDLocalToGlobalPoint et al
This is a problem with building the Carbon libraries from wxWindowsM8.xml.
I'm compiling CVS HEAD 2004-07-03 using CodeWarrior 8.3 under OS X 10.2.8.
Project wxWindowsM8.mcp: MachO targets build OK, but the Carbon targets
Error : undefined identifier 'QDLocalToGlobalPoint'
window.cpp line 1033 obalPoint( UMAGetWindowPort( (WindowRef)
tlw->MacGetWindowRef() ) , &tlworigin ) ;
According to the Apple docs, QDLocalToGlobalPoint() should be declared in
<Quickdraw.h>, but adding "#include <Quickdraw.h>" immediately before the
offending command doesn't help.
(1) /Developer/Headers/FlatCarbon/Quickdraw.h
(2) /Applications/Metrowerks CodeWarrior 8.0/MacOS
Support/Universal/Interfaces/Cincludes/Quickdraw.h
(3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Framew
or
ks/QD.framework/Versions/A/Headers/Quickdraw.h
It looks like the access paths in wxWindowsM8.mcp are set to pick up (2),
which doesn't contain a declaration for QDLocalToGlobalPoint.
I'm sort of reluctant to start munching around with the access paths to pick
up one of the other 2, since I'm not sure what other side effects there
might be. Any suggestions?
Thanks,
Robert
---------------------------------------------------------------------
Robert J. Lang
2004-07-04 15:34:57 UTC
Permalink
Thank you, Stefan. That fixed my Carbon problem.

Robert
Post by Stefan Csomor
Hi
The correct solution is to update your header files, what's odd is that
actually you should first get an error message from a pragma that tells you
to do so.
ftp://ftp.apple.com/developer/Development_Kits/UniversalInterfaces3.4.2.img.
bin
drop the corresponding folders into your MacOS Support/Universal folder
HTH
Stefan
-----Original Message-----
Sent: Sonntag, 4. Juli 2004 04:26
Subject: Unrecognized QDLocalToGlobalPoint et al
This is a problem with building the Carbon libraries from wxWindowsM8.xml.
I'm compiling CVS HEAD 2004-07-03 using CodeWarrior 8.3 under OS X 10.2.8.
Project wxWindowsM8.mcp: MachO targets build OK, but the Carbon targets
Error : undefined identifier 'QDLocalToGlobalPoint'
window.cpp line 1033 obalPoint( UMAGetWindowPort( (WindowRef)
tlw->MacGetWindowRef() ) , &tlworigin ) ;
According to the Apple docs, QDLocalToGlobalPoint() should be declared in
<Quickdraw.h>, but adding "#include <Quickdraw.h>" immediately before the
offending command doesn't help.
(1) /Developer/Headers/FlatCarbon/Quickdraw.h
(2) /Applications/Metrowerks CodeWarrior 8.0/MacOS
Support/Universal/Interfaces/Cincludes/Quickdraw.h
(3)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Framew
or
ks/QD.framework/Versions/A/Headers/Quickdraw.h
It looks like the access paths in wxWindowsM8.mcp are set to pick up (2),
which doesn't contain a declaration for QDLocalToGlobalPoint.
I'm sort of reluctant to start munching around with the access paths to pick
up one of the other 2, since I'm not sure what other side effects there
might be. Any suggestions?
Thanks,
Robert
---------------------------------------------------------------------
---------------------------------------------------------------------
Loading...