[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference 7.286::atarist

Title:Atari ST, TT, & Falcon
Notice:Please read note 1.0 and its replies before posting!
Moderator:FUNYET::ANDERSON
Created:Mon Apr 04 1988
Last Modified:Tue May 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1433
Total number of notes:10312

1086.0. "GEM programming tips." by PIKES::BITTROLFF () Wed Mar 06 1991 13:04

Hi,

I have asked similar type questions before, but they were always under the 
heading of C programming. These really aren't C questions, so I thought that I'd
try to broaden the audience a bit...

I have an application in which I create a window, clear it (clvwk or something 
like that). This changes the background from the default green to white, which
is fine. Next, I draw all over it. Finally, I display a dialog box to the user.
The problem is that when the dialog box is removed from the screen I am left 
with a large green 'hole' in my picture. I know that I need to redraw that 
section, my questions are:

1. What is the best way to accomplish this, ie. can I save the chunk of screen
   that I know will be written over to memory and then restore when the dialog
   box is gone, or must I redraw the whole thing. In general, what is the best
   way to handle what is certainly a common occurence.

2. Why is the screen behind the dialog box reset to green when the box 
   is removed? It seems to me that it should reset to white.

Thanks in advance for any tips you can offer,

Steve
T.RTitleUserPersonal
Name
DateLines
1086.1Yeh, I know..KORG::MISKINISWed Mar 06 1991 14:239
    Yeh, I've got the same problems with my software that draws windows.
    
    ALSO, it seems like lots of other applications have this problem.  
    
    I also have this problem when using the file selector library routines.
    
    _John_
    
    
1086.2BAGELS::FELDMANJerry Feldman DTN 226-5271Wed Mar 06 1991 14:493
    Are you using the evnt_multi() function. If so, you should receive one
    or more redraw request when your window is uncovered.
    
1086.3event_multi() yesSALIDA::BITTROLFFWed Mar 06 1991 16:018
I am using event_multi, although I don't handle that condition in the loop.
Since I know when the dialog box has been terminated I was just going to do
whatever I needed to at that time.

This isn't a whole different window, it's just the area under the dialog box
in the same window...

Steve
1086.4The application is responsible!BAGELS::FELDMANJerry Feldman DTN 226-5271Wed Mar 06 1991 16:5111
    Yes, you do know that you called the dialog box using the forms
    manager, (eg form_do()). However, it is the application's
    responsibility to redraw. The only exception is with drop down menus.
    In this case, GEM does save the area under the screen. But on dialog
    boxes, GEM treats them just as any other window, and will send you a
    WM_REDRAW. I very highly recommend that you also redraw according to
    the rectangles you get from the win_get() call, since the user can 
    always cover part of your window with another window (such as a DA).
    
    Jerry
    
1086.5What is the easiest way?SALIDA::BITTROLFFThu Mar 07 1991 10:3120
I understand that I am responsible, what I am looking for is the easiest way.

In my application the drawing I do consists of many circles connected to each
other at the mid-points. Although I could fairly easily figure out which circles
were covered and redraw those, there is no easy way to tell which of the 
connecting lines passed through the box.

What I was looking for was some way to save that block of screen ram to memory,
(similar to what I imagine is done by the system for drop downs, alert boxes,
etc.) so that I can restore the missing part of the screen simply by restoring
that chunck of memory. Otherwise I'll end up having to redraw the whole window.

I feel like I'm missing a trick somewhere. When the docs talk about replacing
missing pieces of the screen using the rectangle set, I can never figure out
how the application knows what is in that specific rectangle, or do they just
set the clipping parameters to that rectangle and redraw the whole screen.

Thanks for all of the replies so far...

Steve
1086.6PRNSYS::LOMICKAJJeffrey A. LomickaThu Mar 07 1991 12:322
I suspect the message went to GEM which redrew the default screen
background (green) for you.
1086.7My methodPRNSYS::LOMICKAJJeffrey A. LomickaThu Mar 07 1991 12:3926
You may want to take a look PRNSYS::USER2:[LOMICKAJ.HOBBY.ST]VIEWFILE.C,
which is a heavily commented example program that illustrates all
aspects of programming with GEM windows and event_multi(). 
Unfortunately, it does NOT cover dialog boxes, but some of the same
issues apply.

In general, the recommended way to recover what's under dialog boxes is
to accept the redraw request, which includes information about what
rectangle is to be redrawn, and redraw the data from whatever in-memory
database you keep.

In certain limited cases, you can use the vr?_cpyfm() routines in the
VDI to save the area under a dialog box before drawing, and restore it
afterwords.  There are many conditions under which this can cause
problems, but there are also many conditions where this works just fine.
Just be sure to declare a buffer large enough to handle the memory
requirements beforehand.

One of my favorite ways (also least compatible adn the biggest "hack"
of all of these methods) of doing this is to declare a separate display
buffer, copy the current display to it, Logbase() into it, put up the
dialog in it, and invoke it as the active display with Physbase().  The
dialog appears to be drawn "instantly" to the user.  Physbase() back to
the old frame buffer whenthe dialog is over.


1086.8You still need to redraw the rectanglesBAGELS::FELDMANJerry Feldman DTN 226-5271Thu Mar 07 1991 17:3412
    I agree with Jeff. Before you draw the form, you can save the image,
    then when you get a redraw request, you can redraw the effected
    rectangle by blitting the save image back, but be sure to set your
    clipping rectangle to the rectangle you get back from the window
    manager because you have no way of knowing if another application's
    window may be overlaying your window. vr?_copyfm(), I believe is the
    appropriate VDI command to save and restore your bit map. (Probably
    vro_copyfm.
    
    It sounds like a pain, but the approach is logical. The only real
    dumbness is that VDI and AES use different methods to define a
    rectangle.
1086.9Another good reasonPRNSYS::LOMICKAJJeffrey A. LomickaFri Mar 08 1991 07:303
Do you let the user use desk accessories?

If so, you MUST be able to handle redraw events from the AES.
1086.10Don't know yetSALIDA::BITTROLFFFri Mar 08 1991 11:3917
I hadn't planned on letting the user have desk accessories, but if this method
works out OK I may as well.

I started doing the research last night and came up with a general flow of:

- Malloc a 32K block of memory.
- Use SetScreen to set LogBase to this memory.
- Copy the current physical screen to it using memcpy? from PhysBase
- Set PhysBase to LogBase
- Do the dialog (I kind of like the expanding box so I'll probably do it on
  screen.
- Set PhysBase and LogBase back to the original unchanged screen memory.

Hopefully I'll get a chance to try it out this weekend. Thanks for all the help,
I sure do appreciate it.

Steve
1086.11You may be better just saving the boxBAGELS::FELDMANJerry Feldman DTN 226-5271Fri Mar 08 1991 12:3612
    Your method will surely work as long as your application is guaranteed
    to own the screen. However, it is overkill, and may be slower than what
    you really want. Since you already know the dimensions of the dialog
    box, you can use vro_copyfm() to save the bit map under the dialog box
    before you draw it, and restore the bit map afterwards. This may be
    somewhat faster if your dialog box is fairly small. I use it to scroll
    a text window by defining 2 rectangles the size of the window (work
    area) less 1 line (8 or 9 pixels depending on the space I want between
    lines). One rectangle starts at the top of the window, and the other
    starts at the top of the second line. To scroll, copy 1 rectangle to
    the other (using vro_copyfm()), and then copy in a new line at the top
    or bottom of the window. 
1086.12It worksPIKES::BITTROLFFMon Mar 11 1991 10:4320
    I put in the fix over the weekend using the vro_copyfm routines, and
    once I had done a little fiddling it worked just fine. (I had to add
    one line to both the width and the height on the save to restore the
    entire area). At any rate, the routine is fairly short, if anyone is
    interested I will clean it up, comment it and post it here.
    
    Two questions. In Jeff's note he states that this method is sometimes
    unsafe, what conditions would cause this?
    
    Second, Jerry mentions in this last method that the vro_copyfm() is
    faster. It seems to me that once the initial copy to the backup screen
    is made that switching back and forth between the screens would be
    faster as you are simply switching a pointer rather than the chunks of
    memory, no?
    
    Finally, thanks for the responses, this notes file can sure save a lot
    of experimenting when getting a program running! (Experimentation for
    me means try, crash, swear, tweak, try, crash, swear, tweak... :^)
    
    Steve 
1086.13GEMDOS: Fdup and FforceBERN01::RUGGIEROMarkus Ruggiero, EIS/PS, Z�rich/SwitzerlandMon Mar 11 1991 10:519
    I think this question fits in here:

    Can someone please explain what the GEMDOS functions Fdup and Fforce
    are good for? I understand that they have to do with i/o redirection.
    But how are they used; and what parameters do they expect/give back?

    Thanks

    ---markus--
1086.14PRNSYS::LOMICKAJJeffrey A. LomickaMon Mar 11 1991 15:025
Any method that depends on saving the screen BEFORE it's clobbered will
be unable to deal with events from desk accessories, unless you ALWAYS
keep a shadow copy off-screen to do the drawing from.  That's the only
unsafe thing about  it.

1086.15Thats what I thought...PIKES::BITTROLFFMon Mar 11 1991 15:125
    re: -1
    
    Gotcha.
    
    Thanks, Steve
1086.16Speed depends on how bog the objc isBAGELS::FELDMANJerry Feldman DTN 226-5271Mon Mar 11 1991 18:2217
    My comment about speed was that if you had to make a copy of the screen
    and restore it, the the vro_copyfm() is faster. Certainly pointing the
    phybase at the logbase is not much more than switching a pointer, but
    you still have to copy 32k before the objc_draw(--your object--);
    
    Saving and restoring under the object will be faster for a small dialog
    box, and slower for a large one. However, as Jeff mentions, blindly
    saving and restoring does not take into account Desk Accessories.
    
    If you were to allow Desk Accesories, use the vro_copyfm() to save the
    portion of the screen covered by the dialog box, then restore is using
    clipping rectangles. If you keep a shadow copy of your window[s], then,
    when you get a redraw request, you can blit (using vro_copyfm()) from
    your shadow copy to the screen. This way you can allow for desk
    accessories, and for other task windows, if and when we ever get a
    multi-tasking gemdos. (I'll probably be older than 65 at that time).
    
1086.17General question...TINCUP::BITTROLFFWed Mar 27 1991 15:0027
Does anybody else run into these problems, or is it just me, or is it MWC, or 
karma, or what.

It seems that I will buzz right along on a programming project but at some point,
I will run into a problem (usually GEM related), that seems to have no basis in
reality and no way to track down to fix. After several weeks of banging away
at the problem I usually get frustrated and move to a different project (I now
have about half a dozen partially completed programs). In some cases I can go
around the block, but usually the secondary solution isn't as good as the 
primary design. Lately I've been getting frustrated enough to consider another
computer as a possible solution. Maybe I'm just spoiled by the utilities 
available to programmers on a bigger machine.

My latest roadblock has to do with a simple dialog box. If I run it in medium
rez the program works just fine. If I run it in low rez (which is what it was
designed for) the machine crashes as soon as the dialog box is brought on screen.
I can't use the debugger to find the problem, since I don't believe that it runs
in anything other than medium rez. When I add printf statements to track the 
program, everything looks just fine right up to the do_dialog call. If I remove
the code that puts values into the dialog box (which works in med. rez) the box
does come up in low rez just fine. The stuff that I throw into the box is OK,
ie. I'm putting in the trailing null and it isn't longer than it's supposed to 
be, it just doesn't work.

Anyone else have these types of problems trying to program this beastie?

Steve 
1086.18Watch your menu bar sizePRNSYS::LOMICKAJJeffrey A. LomickaWed Mar 27 1991 17:1425
I don't think it's *just* you with these problems.  I experience much the same
thing every time I try to use RMS on the VAX. :-)

In this case, it is very likely that the dimensions of the dialog box exceed
that of the screen, and that therefore it is writing into off-screen memory,
which is bad, since that is going to be your code or data or something like
that.  Double check the clipping dimensions that you give the draw routine(s)
do not exceed the size of the low-res screen, or go negative.

ALSO, you MUST be careful in designing the menu bar in low res - as it is very
easy to make a menu that exceeds the size of the buffer used to store the
under-the-menu pixels.  This buffer is pre-allocated in GEM and is somewhat
small.  That is why the low-res menus of NEO-DESK are more terse than the
medium or high-res menus.  If your menu is too large, you will over-write memory
that should not be written.  Quoting from page 411 of the MWC manual (Rev 4 of
the manual, under "menu")  "Note that the Atari ST has a buffer in which to
store the portion of the screen that is overwritten by a drop-down menu, so
that it can be restored when the menu is erased.  This buffer can hold up to
one quarter of the screen,".  They then give a number in "pixels", which is
bunk, it's actually in bits.  Low res is 4 bits per pixel, so you get a
total of 16384 pixels, or about 128 pixels on a side.  Since characters are 8x8,
that translates into 16 lines of 16 characters, or 8 lines of 32 chars.

I pick up some of this information by reading the MWC manual, and some by
hanging around the registered developer's forum on GEnie.
1086.19GEM was fine, this problem was mine...TINCUP::BITTROLFFTue Apr 02 1991 11:5016
Ya know, before I started with C on the ST I used to think I was a pretty good 
programmer... (sigh)

After a lot of work I tracked the problem down to a rounding error. One of the
fields in the FDB is the number of 16 bit words in the width of the block. When
I originally did the routine it worked just fine. When I changed the size of 
the dialog box, however, the calculation came out to 11.9375 words, which should
have been rounded to 12, but which was truncated to 11. It worked in medium
resolution due to the interaction between sizes, number of planes, etc. It then
bombed on the cpyfrm command. 

At any rate, it seems to be (mostly) working now. I promise to debug the next
problem for 40 hours rather than just 20 before I bother you folks here, but
thanks anyway for the help.

Steve