PtRaw Widget Question - Can I break the rule?

Hi,
Hello,
I have the need to update a PtRaw widget when a real time servo
process changes state. The servo process sends messages to the
process running photon controlling the PtRaw widget. I have been
reading the documentation and it says that processes should not try to
update PtRaw Widgets themselves–they should damage the widget (using
the PtDamageWidget call) and then update the widget when the raw
widget drawing function is called with the damage tiles.

I understand that this would work well, but I would prefer not to do
it this way… I’m sorry…

Here’s why. First, when my real time process sends a message, only a
few pixels out of the full widget will need to be changed. As far as
I can tell, the DamageWidget call tells the widget draw function that
the extent of the raw widget has been damaged–so I would have to
redraw the entire widget to update a few pixels. I don’t see any way
to send a special sort of ‘DamageWidget’ message to the widget so it
will know to update only a few pixels. I would need some way to know
if it was a few pixel update or a real damage repair request.

I had thought to do it this way:
create a graphic context using CreateGC.
Find out the region number of my raw widget
set that region in the graphics context

When ever I need to do a few pixel update, I would save the current
graphics context, switch to my created one, update the pixels, flush
the graphic buffer and then switch back to the origional context.

I would use the created context only for updates. All repairs to the
Raw widget would happen using the origional context.

Would this work? If not, do you have any suggestions.


Thank you very much for spending the time to help,
Greg Laird

I think that you are on the right track. The reason
QSSL wants you to update the widget in the drawing
function is that they setup the context for your.

You could save the current context, setup the drawing
context, and then revert. This is tricky and I haven’t
done it recently enough to give suggestions other than
read the docs carefully. If your screen ends up looking
like a pizza, well you know.

Another alternative might be to set a flag before
damaging the widget. Your drawing routines could use
this as a signal to just update the minimum. If by
some luck, your application can’t be covered over or
minimized then you don’t even need to worry about the
flag.


Previously, Greg Laird wrote in qdn.public.qnx4.photon:

Hi,
Hello,
I have the need to update a PtRaw widget when a real time servo
process changes state. The servo process sends messages to the
process running photon controlling the PtRaw widget. I have been
reading the documentation and it says that processes should not try to
update PtRaw Widgets themselves–they should damage the widget (using
the PtDamageWidget call) and then update the widget when the raw
widget drawing function is called with the damage tiles.

I understand that this would work well, but I would prefer not to do
it this way… I’m sorry…

Here’s why. First, when my real time process sends a message, only a
few pixels out of the full widget will need to be changed. As far as
I can tell, the DamageWidget call tells the widget draw function that
the extent of the raw widget has been damaged–so I would have to
redraw the entire widget to update a few pixels. I don’t see any way
to send a special sort of ‘DamageWidget’ message to the widget so it
will know to update only a few pixels. I would need some way to know
if it was a few pixel update or a real damage repair request.

I had thought to do it this way:
create a graphic context using CreateGC.
Find out the region number of my raw widget
set that region in the graphics context

When ever I need to do a few pixel update, I would save the current
graphics context, switch to my created one, update the pixels, flush
the graphic buffer and then switch back to the origional context.

I would use the created context only for updates. All repairs to the
Raw widget would happen using the origional context.

Would this work? If not, do you have any suggestions.


Thank you very much for spending the time to help,
Greg Laird


Mitchell Schoenbrun --------- maschoen@pobox.com

Greg Laird <glaird@teleport.com> wrote:

I have the need to update a PtRaw widget when a real time servo
process changes state. The servo process sends messages to the
process running photon controlling the PtRaw widget. I have been
reading the documentation and it says that processes should not try to
update PtRaw Widgets themselves–they should damage the widget (using
the PtDamageWidget call) and then update the widget when the raw
widget drawing function is called with the damage tiles.

I understand that this would work well, but I would prefer not to do
it this way… I’m sorry…

Here’s why. First, when my real time process sends a message, only a
few pixels out of the full widget will need to be changed. As far as
I can tell, the DamageWidget call tells the widget draw function that
the extent of the raw widget has been damaged–so I would have to
redraw the entire widget to update a few pixels. I don’t see any way
to send a special sort of ‘DamageWidget’ message to the widget so it
will know to update only a few pixels. I would need some way to know
if it was a few pixel update or a real damage repair request.

There is a PtDamageExtent() function that lets you specify which part of
the widget you need to redraw. Your draw function can look at the
damage list passed to it and figure out what needs to be drawn and what
doesn’t.


Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.

Hello Wojtek,
I had thought to use DamageWidgetExtent after I submitted the post but
have concluded that this would not work that well because clipping
would be active when my damage repair function was called. I would
only be able to repair the damage in the areas that were specified as
damaged. Possibly, if I could DamageWidgetExtent the complete raw
canvas in a way that would be decrenable from ‘real’ damage by my draw
routine, this would work.

I would prefer to do the change context and PgDraw and the restore the
context as I described in my original post–it seems much more
straightforward. Mitchell has suggested that he thought this would
work–do you see any problems? I am using Photon 1.14, Qnx 4.25. All
of this will occur on a single machine.

Thanks,
Greg Laird

On 23 Oct 2000 15:01:43 GMT, Wojtek Lerch <wojtek@qnx.com> wrote:

Greg Laird <> glaird@teleport.com> > wrote:
I have the need to update a PtRaw widget when a real time servo
process changes state. The servo process sends messages to the
process running photon controlling the PtRaw widget. I have been
reading the documentation and it says that processes should not try to
update PtRaw Widgets themselves–they should damage the widget (using
the PtDamageWidget call) and then update the widget when the raw
widget drawing function is called with the damage tiles.

I understand that this would work well, but I would prefer not to do
it this way… I’m sorry…

Here’s why. First, when my real time process sends a message, only a
few pixels out of the full widget will need to be changed. As far as
I can tell, the DamageWidget call tells the widget draw function that
the extent of the raw widget has been damaged–so I would have to
redraw the entire widget to update a few pixels. I don’t see any way
to send a special sort of ‘DamageWidget’ message to the widget so it
will know to update only a few pixels. I would need some way to know
if it was a few pixel update or a real damage repair request.

There is a PtDamageExtent() function that lets you specify which part of
the widget you need to redraw. Your draw function can look at the
damage list passed to it and figure out what needs to be drawn and what
doesn’t.


Wojtek Lerch (> wojtek@qnx.com> ) QNX Software Systems Ltd.

Greg Laird <glaird@teleport.com> wrote:

I had thought to use DamageWidgetExtent after I submitted the post but
have concluded that this would not work that well because clipping
would be active when my damage repair function was called. I would
only be able to repair the damage in the areas that were specified as

I don’t think I get it. Why would you need to redraw areas that you
haven’t given to DamageWidgetExtent()? Or, in other words, why would you
not give DamageWidgetExtent() any areas that you do need to redraw?

BTW In case you think it’s a problem that DamageWidgetExtent() only
takes a single rectangle: if you call PtHold(), then
DamageWidgetExtent() a few times, and then PtUpdate(), your draw
function will be only called once, and the damage list will be the
intersection of all the rectangles that you gave to
DamageWidgetExtent(). Does that help?

damaged. Possibly, if I could DamageWidgetExtent the complete raw
canvas in a way that would be decrenable from ‘real’ damage by my draw
routine, this would work.

Of course, you could set a global flag or something before calling
DamageWidgetExtent(), and clear it in your draw function. Note however
that when your draw function gets called eventually, there is a chance
that your damages have been merged with some unrelated damages, and you
need to also redraw things that have nothing to do with your global flag
and your call to DamageWidgetExtent().

I would prefer to do the change context and PgDraw and the restore the
context as I described in my original post–it seems much more
straightforward. Mitchell has suggested that he thought this would
work–do you see any problems? I am using Photon 1.14, Qnx 4.25. All
of this will occur on a single machine.

It can work but will be less efficient (switching a GC causes a flush)
and requires more knowledge about how the context needs to be set up.
It will be particularly difficult if other widgets in your window might
partially cover your PtRaw widget.

\

Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.

Hello Wojtek,
Thanks again for your input. I do understand Qnx’s desire to have
developers not stray outside boundaries so I apologize for this. I
do think my straying will result in a cleaner system design.
I will try to clarify my needs so you can maybe understand why I would
prefer to plot directly instead of go through the DamageWidget
process.

My system is composed of two processes on the same hardware. Process
1 is a high priority real time process performing a servoing
operation. It acquires a/d data, manipulates it, and then outputs the
values in d/a form. Concurrent with doing this, the process will
store a/d data in shared memory for evaluation by the system operator.
The data update rate is reasonably fast–around 2000 hz.

A second process, P2 runs at a lower priority and provides graphic
displays of the data in shared memory via photon. As new data is
ready for display, P1 will trigger a proxy attached to P2. P2 will
then know that new data is available and the graphic display needs
updating. I have written a main loop using a Receive, PhEventRead,
PtEventHandler loop as described in the PhEventRead example in the
manual. If the Receive pid is not a photon event (determined by
PhEventRead) I check to see if it is the new data proxy, and if so, I
will do my updates. In this way, my updates occur only when photon is
in a stable state-not mid any PtEventHandler activity.

The display update will usually involve updating 15-30 50x10 pixel
areas scattered about the display area.

One option would be to generate a PtDamageWidgetExtent call for each
of the 15-30 update areas. This would be a little tricky, in that the
physical plotting location will not provide me with sufficient
information to update the pixels. I will have use my window repair
algorithm for these little rectangles.

As an aside, the window repair algorithm is designed to repair good
size chunks of the video display since this will be the most likely
occurrence. The windows will be rarely occluded and when occluded it
will be some good size rectangular window (some sort of option
selection window). The current display status model is fairly complex
hence using this model for small updates would be clumsy.

So, using the PtDamageWidgetExtent to update the screen will be
reasonably complex, in my opinion.

The direct plotting of the raw widget is much simpler. I just simply
go to the various rectangles that need updating and update them. I
change my model so they can be restored in case of damage and that’s
it. I have all the information I need for updating at the time of
update. It is very clean, in my opinion.

Photon will handle all the window occluding–the only thing I will not
be able to do (it seems to me) will be to create widgets on my windows
that are not windows themselves. I have experimented with this and it
seems to work. I do the following:

Oldcontext = PgSetGC(created context)

PgSetRegion(parent window’s region)
do my updates
PgSetGC(OldContext)
done


You have said that photon will do a flush on the PgSetGC call, so I
don’t flush the drawing buffer before I restore the context.

This all seems to work fine. Do you see any problems that I am likely
to have that I have not anticipated?

One thing I have noticed: The raw widget I have created has an rid of
zero (raw → rid) so I am using the rid of the raw widget’s parent
window. Why would the raw widget have an rid of zero?



Thanks,
Greg Laird

On 24 Oct 2000 16:32:15 GMT, Wojtek Lerch <wojtek@qnx.com> wrote:

Greg Laird <> glaird@teleport.com> > wrote:
I had thought to use DamageWidgetExtent after I submitted the post but
have concluded that this would not work that well because clipping
would be active when my damage repair function was called. I would
only be able to repair the damage in the areas that were specified as

I don’t think I get it. Why would you need to redraw areas that you
haven’t given to DamageWidgetExtent()? Or, in other words, why would you
not give DamageWidgetExtent() any areas that you do need to redraw?

BTW In case you think it’s a problem that DamageWidgetExtent() only
takes a single rectangle: if you call PtHold(), then
DamageWidgetExtent() a few times, and then PtUpdate(), your draw
function will be only called once, and the damage list will be the
intersection of all the rectangles that you gave to
DamageWidgetExtent(). Does that help?

damaged. Possibly, if I could DamageWidgetExtent the complete raw
canvas in a way that would be decrenable from ‘real’ damage by my draw
routine, this would work.

Of course, you could set a global flag or something before calling
DamageWidgetExtent(), and clear it in your draw function. Note however
that when your draw function gets called eventually, there is a chance
that your damages have been merged with some unrelated damages, and you
need to also redraw things that have nothing to do with your global flag
and your call to DamageWidgetExtent().

I would prefer to do the change context and PgDraw and the restore the
context as I described in my original post–it seems much more
straightforward. Mitchell has suggested that he thought this would
work–do you see any problems? I am using Photon 1.14, Qnx 4.25. All
of this will occur on a single machine.

It can work but will be less efficient (switching a GC causes a flush)
and requires more knowledge about how the context needs to be set up.
It will be particularly difficult if other widgets in your window might
partially cover your PtRaw widget.

\

Wojtek Lerch (> wojtek@qnx.com> ) QNX Software Systems Ltd.

Greg Laird <glaird@teleport.com> wrote:

Thanks again for your input. I do understand Qnx’s desire to have
developers not stray outside boundaries so I apologize for this. I
do think my straying will result in a cleaner system design.
I will try to clarify my needs so you can maybe understand why I would
prefer to plot directly instead of go through the DamageWidget
process.

So, using the PtDamageWidgetExtent to update the screen will be
reasonably complex, in my opinion.

I realize that it can be complex – I was only trying to warn you that
doing it the other way will not be entirely trivial either, and dealing
with some of its complexities will require much more knowledge of
internal details of how the widget library works.

The direct plotting of the raw widget is much simpler. I just simply
go to the various rectangles that need updating and update them. I
change my model so they can be restored in case of damage and that’s
it. I have all the information I need for updating at the time of
update. It is very clean, in my opinion.

I realize that using PtDamageWidgetExtent() makes your code more
complicated – you have to encode the changes in the widget’s state as a
list of rectangles, and then decode the rectangles into a list of things
to draw in your draw function. But from my point of view, this solution
is cleaner in the sense that it doesn’t require very detailed knowledge
of how the library works – you just need to know how to turn your data
into rectangles and back.

By doing it your way, you’re just pushing the complexity elswhere.
Setting up your own draw context can be a bit tricky – that’s why we
prefer to do it for you…

Photon will handle all the window occluding–the only thing I will not
be able to do (it seems to me) will be to create widgets on my windows
that are not windows themselves. I have experimented with this and it
seems to work. I do the following:

Oldcontext = PgSetGC(created context)

PgSetRegion(parent window’s region)
do my updates
PgSetGC(OldContext)
done



You have said that photon will do a flush on the PgSetGC call, so I
don’t flush the drawing buffer before I restore the context.

This all seems to work fine. Do you see any problems that I am likely
to have that I have not anticipated?

One thing I have noticed: The raw widget I have created has an rid of
zero (raw → rid) so I am using the rid of the raw widget’s parent
window. Why would the raw widget have an rid of zero?

I told you: you will need knowledge of how the library works. This is
just one of many little issues that you’ll have to deal with.

A widget has a rid of zero when it has no region. Widgets only have a
region if they need a region – examples of why a widget might need a
region include widgets that define their own cursor or are sensitive to
certain events. Details may depend on the version of the Photon library
that you’re running.

Even if a widget has a region, Photon library doesn’t use that region
for drawing. All widgets in a window draw from the window’s region –
that’s how we try to avoid unnecessary flushes (PgSetRegion() causes a
flush).

\

Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.

Is there some sort of special coordinates I could use on
PtDamageWidgetExtent that would not otherwise be used by Photon. This
way, I could signal my draw routine that it was an update as opposed
to a damage repair–I would do all my update plotting then. Maybe use
coordinates larger than the window or something.

You did say that photon would combine the damage tiles so this may not
always work.

Another option would be to set a flag before calling
PtDamageWidgetExtent. Would my draw routine be called directly from
the PtDamageWidgetExtent or would I need to go back to the mainloop
and wait for a photon event and this event would be the call to my
function? If I would have to wait for other photon events to
process the damage request, it seems that a real damage request could
sneak in between my call to PtDamageWE and the actual call to my
drawing routine–and this could cause problems.


On 26 Oct 2000 15:59:45 GMT, Wojtek Lerch <wojtek@qnx.com> wrote:

Greg Laird <> glaird@teleport.com> > wrote:
Thanks again for your input. I do understand Qnx’s desire to have
developers not stray outside boundaries so I apologize for this. I
do think my straying will result in a cleaner system design.
I will try to clarify my needs so you can maybe understand why I would
prefer to plot directly instead of go through the DamageWidget
process.

So, using the PtDamageWidgetExtent to update the screen will be
reasonably complex, in my opinion.

I realize that it can be complex – I was only trying to warn you that
doing it the other way will not be entirely trivial either, and dealing
with some of its complexities will require much more knowledge of
internal details of how the widget library works.

The direct plotting of the raw widget is much simpler. I just simply
go to the various rectangles that need updating and update them. I
change my model so they can be restored in case of damage and that’s
it. I have all the information I need for updating at the time of
update. It is very clean, in my opinion.

I realize that using PtDamageWidgetExtent() makes your code more
complicated – you have to encode the changes in the widget’s state as a
list of rectangles, and then decode the rectangles into a list of things
to draw in your draw function. But from my point of view, this solution
is cleaner in the sense that it doesn’t require very detailed knowledge
of how the library works – you just need to know how to turn your data
into rectangles and back.

By doing it your way, you’re just pushing the complexity elswhere.
Setting up your own draw context can be a bit tricky – that’s why we
prefer to do it for you…

Photon will handle all the window occluding–the only thing I will not
be able to do (it seems to me) will be to create widgets on my windows
that are not windows themselves. I have experimented with this and it
seems to work. I do the following:

Oldcontext = PgSetGC(created context)

PgSetRegion(parent window’s region)
do my updates
PgSetGC(OldContext)
done


You have said that photon will do a flush on the PgSetGC call, so I
don’t flush the drawing buffer before I restore the context.

This all seems to work fine. Do you see any problems that I am likely
to have that I have not anticipated?

One thing I have noticed: The raw widget I have created has an rid of
zero (raw → rid) so I am using the rid of the raw widget’s parent
window. Why would the raw widget have an rid of zero?

I told you: you will need knowledge of how the library works. This is
just one of many little issues that you’ll have to deal with.

A widget has a rid of zero when it has no region. Widgets only have a
region if they need a region – examples of why a widget might need a
region include widgets that define their own cursor or are sensitive to
certain events. Details may depend on the version of the Photon library
that you’re running.

Even if a widget has a region, Photon library doesn’t use that region
for drawing. All widgets in a window draw from the window’s region –
that’s how we try to avoid unnecessary flushes (PgSetRegion() causes a
flush).

\

Wojtek Lerch (> wojtek@qnx.com> ) QNX Software Systems Ltd.

Another option would be to set a flag before calling
PtDamageWidgetExtent. Would my draw routine be called directly from
the PtDamageWidgetExtent or would I need to go back to the mainloop
and wait for a photon event and this event would be the call to my
function? If I would have to wait for other photon events to
process the damage request, it seems that a real damage request could
sneak in between my call to PtDamageWE and the actual call to my
drawing routine–and this could cause problems.

Set your flag, do PtDamageWidgetExtent(), then call PtFlush() and your draw
function will be called immediately.

Markus


On 26 Oct 2000 15:59:45 GMT, Wojtek Lerch <> wojtek@qnx.com> > wrote:

Greg Laird <> glaird@teleport.com> > wrote:
Thanks again for your input. I do understand Qnx’s desire to have
developers not stray outside boundaries so I apologize for this. I
do think my straying will result in a cleaner system design.
I will try to clarify my needs so you can maybe understand why I would
prefer to plot directly instead of go through the DamageWidget
process.

So, using the PtDamageWidgetExtent to update the screen will be
reasonably complex, in my opinion.

I realize that it can be complex – I was only trying to warn you that
doing it the other way will not be entirely trivial either, and dealing
with some of its complexities will require much more knowledge of
internal details of how the widget library works.

The direct plotting of the raw widget is much simpler. I just simply
go to the various rectangles that need updating and update them. I
change my model so they can be restored in case of damage and that’s
it. I have all the information I need for updating at the time of
update. It is very clean, in my opinion.

I realize that using PtDamageWidgetExtent() makes your code more
complicated – you have to encode the changes in the widget’s state as a
list of rectangles, and then decode the rectangles into a list of things
to draw in your draw function. But from my point of view, this solution
is cleaner in the sense that it doesn’t require very detailed knowledge
of how the library works – you just need to know how to turn your data
into rectangles and back.

By doing it your way, you’re just pushing the complexity elswhere.
Setting up your own draw context can be a bit tricky – that’s why we
prefer to do it for you…

Photon will handle all the window occluding–the only thing I will not
be able to do (it seems to me) will be to create widgets on my windows
that are not windows themselves. I have experimented with this and it
seems to work. I do the following:

Oldcontext = PgSetGC(created context)

PgSetRegion(parent window’s region)
do my updates
PgSetGC(OldContext)
done


You have said that photon will do a flush on the PgSetGC call, so I
don’t flush the drawing buffer before I restore the context.

This all seems to work fine. Do you see any problems that I am likely
to have that I have not anticipated?

One thing I have noticed: The raw widget I have created has an rid of
zero (raw → rid) so I am using the rid of the raw widget’s parent
window. Why would the raw widget have an rid of zero?

I told you: you will need knowledge of how the library works. This is
just one of many little issues that you’ll have to deal with.

A widget has a rid of zero when it has no region. Widgets only have a
region if they need a region – examples of why a widget might need a
region include widgets that define their own cursor or are sensitive to
certain events. Details may depend on the version of the Photon library
that you’re running.

Even if a widget has a region, Photon library doesn’t use that region
for drawing. All widgets in a window draw from the window’s region –
that’s how we try to avoid unnecessary flushes (PgSetRegion() causes a
flush).

\

Wojtek Lerch (> wojtek@qnx.com> ) QNX Software Systems Ltd.

Greg Laird <glaird@teleport.com> wrote:

Is there some sort of special coordinates I could use on
PtDamageWidgetExtent that would not otherwise be used by Photon. This
way, I could signal my draw routine that it was an update as opposed
to a damage repair–I would do all my update plotting then. Maybe use
coordinates larger than the window or something.

No, not really. The damage is clipped to the size of your widget.

You did say that photon would combine the damage tiles so this may not
always work.

Another option would be to set a flag before calling

Instead of just a flag, perhaps it might make sense to have a global
variable that held enough information about the old state that your
draw function could compare to the current state and figure out which
parts of the widget need special attention. Your draw function does
need to know how to draw the current state anyway, doesn’t it – you did
say that the entire picture will rarely need to be redrawn.

But if you think that would be too complicated, go for the other
solution. Just remember that it might turn out complicated, too – and
since you would be doing things that most people, including ourselves,
tend to avoid, there’s a possibility that your code will be more easily
broken by subtle changes in the library that we might not be willing to
undo or maybe even to explain to you in detail.

Now, have I scared you enough? Don’t worry, I exaggerated a bit. :wink:

PtDamageWidgetExtent. Would my draw routine be called directly from
the PtDamageWidgetExtent or would I need to go back to the mainloop

If you call PtHold(), then PtDamageWidgetExtent() a few times, and then
PtRelease(), the draw function will be called either from within the
PtRelease() or soon after your callback returns. If you want to make
sure that it’s called before your callback returns, call PtFlush()
before PtRelease().

Another solution would be to call PtFlush(), then set your flag, call
PtDamageWidget(), and then call PtFlush() again. This would guarantee
that all the draw function needs to deal with when the flag is set is
the state change: the first PtFlush() is to make sure that if the widget
is damaged already, it will be redrawn.

and wait for a photon event and this event would be the call to my
function? If I would have to wait for other photon events to

No, it doesn’t wait. It would be silly if you had to move your mouse or
type a key before your changes showed on the screen, wouldn’t it…

But there is the possibility that the widget is already damaged (by
something unrelated) when your callback gets invoked, and your calls to
PtDamageWidgetExtent() could be adding damages to its damage list – or
perhaps even doing nothing, because the areas that you’re trying to
damaged are already damaged.

process the damage request, it seems that a real damage request could
sneak in between my call to PtDamageWE and the actual call to my
drawing routine–and this could cause problems.


Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.