[comp.sys.atari.st] Who have I clobbered?

saj@chinet.chi.il.us (Stephen Jacobs) (02/27/89)

Before I try out my 3 best guesses, I thought I'd ask for advice on this one:
I'd like to have a particular program plaster a big dialog box on the screen.
After the dialog is over, I'd like to get the screen redrawn properly (natch')
The problem is: suppose I've plastered that dialog over someone else's window.
The prime example is the control panel: if it's displayed when I need that 
dialog, I'd like to cover it up, but I'd also like to be able to restore it
at the end of the dialog.  The three hottest ideas I had were: 
1) When I redraw my own screen, watch the rectangle list for areas I don't
own.  Use wind_find to see who does own those areas (I presume the mouse 
doesn't actually have to be there for the wind_find to work) and send redraw
messages.
2) Open another window to contain the dialog and close it when the dialog is
done.  This should cause everyone (me included) to get redraw messages, but
I'm trying to limit the number of windows if I can.
3) Make a buffer. Save the area under the dialog, and restore it at the end
of the dialog.  How dull; how memory-hungry.

Any informed suggestions?  Other ways?  Warnings?  
                               Steve J.

sirkm@ssyx.ucsc.edu (Greg Anderson) (02/28/89)

In article <7829@chinet.chi.il.us> saj@chinet.chi.il.us (Stephen Jacobs) writes:
>Before I try out my 3 best guesses, I thought I'd ask for advice on this one:
>I'd like to have a particular program plaster a big dialog box on the screen.
>After the dialog is over, I'd like to get the screen redrawn properly (natch')

From the Laser C manual:

"Any rectangular area of the screen can be invalidated by calling form_dial
with a value of FMD_FINISH.  The rectangle will be redrawn by a series of
events for all windows covered by it."

>3) Make a buffer. Save the area under the dialog, and restore it at the end
>of the dialog.  How dull; how memory-hungry.

Actually, that's a nice solution.  Memory-hungry is may be, but it is a much
faster solution.
----------------------------------------------------------------
	Greg Anderson
	Social Sciences Computing
	University of California, Santa Cruz
	email:   sirkm@ssyx.ucsc.edu
	BBS:     (408) 462-3832        2400/1200/300 baud

hedley@imagen.UUCP (Hedley Rainnie) (02/28/89)

saj@chinet.chi.il.us (Stephen Jacobs) writes about dialog trashing. Here is
my code for dialogs. You will get a redraw event upon closing the
dialog if things are set up right. No muss no fuss. This code works
so enjoy! (Its actually part of the user interface from UltraScript).

Here is code to pop up the dialog.

			wind_update(BEG_UPDATE);   
			form_center(who,diptr);
			form_dial(0,1,1,1,1,dibox);
			form_dial(1,1,1,1,1,dibox);
			objc_draw(who,ROOT,MAX_DEPTH,dibox);
			what = form_do(who,0);
			form_dial(2,1,1,1,1,dibox);
			form_dial(3,1,1,1,1,dibox);
			wind_update(END_UPDATE);
			(who+1)->ob_state = NORMAL;   /* Select off */

And here is my code to redraw here:

do_redraw(msg)
int msg[];
{
    int whandle;
    GRECT t1,t2;
    int clip[4];
    lineaa(); /* Mouse off */
    whandle = msg[3];
    t2.g_x  = msg[4];
    t2.g_y  = msg[5];
    t2.g_w  = msg[6];
    t2.g_h  = msg[7];
    wind_update(BEG_UPDATE);

    wind_get(whandle,WF_FIRSTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
    while(t1.g_w && t1.g_h) {
        if(rc_intersect(&t2,&t1)) {
            clip[0] = t1.g_x;
            clip[1] = t1.g_y;
            clip[2] = t1.g_x + t1.g_w - 1;
            clip[3] = t1.g_y + t1.g_h - 1;
            vs_clip(vdihandle,1,clip);
    	    /* Redraw your stuff here */
        }
        wind_get(whandle,WF_NEXTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
    }
    wind_update(END_UPDATE);
    linea9(); /* Mouse on. I would use graf_mouse BUT that is another story */
}





-- 
{decwrl!sun}!imagen!hedley
hedley@imagen.com

saj@chinet.chi.il.us (Stephen Jacobs) (03/01/89)

I asked how to pass redraw messages to applications whose windows I had 
scribbled in.  Hedley Rainnie posted a piece of code that handled dialog
closing properly, and Greg Anderson explained it.  In summary, GEM doesn't
know about the scribbling, but the correct form_dial() call tells GEM to
send redraw messages.  I looked at my code, and the problem was that I
ended the dialog handler with form_dial(FMD_FINISH, cx, cy, cw, ch, 0,
0, 0, 0);.  Apparently this only sends a redraw to a null rectangle 
rather than the one defined by cx cy cw ch.  The fix is then apparent.  
It appears from the documentation I have that DR defined this call as
taking only one rectangle as an argument, but wrote the code to require 
two.  As a result, the documentation available is not quite clear enough to
penetrate the cotton in my head.  (By the way, I use MWC).
                           Steve J.

saj@chinet.chi.il.us (Stephen Jacobs) (03/01/89)

In my continuing quest to make my GEM dialogs co-exist with desk accessories,
I noticed something that didn't come up earlier in the discussion.  It helps
a lot to do an evnt_timer(0, 0); just before starting the dialog handler.
That way other people's queued redraws get done BEFORE your dialog starts, 
not during it.
                                    Steve J.

jgj@hcx2.SSD.HARRIS.COM (03/02/89)

/* Written 11:17 am  Feb 27, 1989 by sirkm@ssyx.ucsc.edu in hcx2:comp.sys.atari.st */
In article <7829@chinet.chi.il.us> saj@chinet.chi.il.us (Stephen Jacobs) writes:
>Before I try out my 3 best guesses, I thought I'd ask for advice on this one:
>I'd like to have a particular program plaster a big dialog box on the screen.
>After the dialog is over, I'd like to get the screen redrawn properly (natch')

From the Laser C manual:

"Any rectangular area of the screen can be invalidated by calling form_dial
with a value of FMD_FINISH.  The rectangle will be redrawn by a series of
events for all windows covered by it."

>3) Make a buffer. Save the area under the dialog, and restore it at the end
>of the dialog.  How dull; how memory-hungry.

Actually, that's a nice solution.  Memory-hungry is may be, but it is a much
faster solution.
----------------------------------------------------------------
	Greg Anderson
	Social Sciences Computing
	University of California, Santa Cruz
	email:   sirkm@ssyx.ucsc.edu
	BBS:     (408) 462-3832        2400/1200/300 baud
/* End of text from hcx2:comp.sys.atari.st */

rosenkra@hall.cray.com (Bill Rosenkranz) (03/02/89)

---

regarding redraw messages: there is a better (i define better as more
general) way of forcing a redraw using the appl_write () function. it
is more tricky but once u master it, it is more like a general interprocess
message passing utility (i.e. send a message to the current appl, or
to and from an accessory). most applications are written with some sort
of evnt_multi () loop that checks for messages, timer events, keyboard
events, and button events. one of the messages which is looked for is
WM_REDRAW.

tim oren's GEM tutorials presented such a "self redraw" code. the code
fragments recently posted are ok to do the actual redraw.

the only trick involved with using the appl_write () code is getting
the correct application id. i was having some problems and found out that
gulam was somehow messing this up. invoked from the desktop, everything
worked fine. most texts on GEM say the appli_init () function returns
an application id (apid). this MAY be the case on PC GEM or with some
compilers on the ST. however, at least with (beloved) alcyon, the AES 
bindings (AESBIND) export a global 16-bit int containing the proper
gl_apid to use. don't use the return value from appl_init (unless your
compiler bindings say it's ok).

main()
{
	extern int	gl_apid;

	appl_init ();

	/* now gl_apid contains the id of THIS application */

}

u can use appl_find () to get the id of any other gem application in memory
(like .acc's).

if youse guys want, i'll post a small example...

-bill

rosenkra@hall.cray.com or rosenkra%boston@hall.cray.com
...!rutgers!umn-sc!hall!rosenkra

(p.s. there was an article back in STart circa 1987 by tom hudson on this
message pipe scheme...)

uace0@uhnix2.uh.edu (Michael B. Vederman) (03/04/89)

The easiest way to force a redraw of everything on the screen is to perform a
form_dial(FMD_FINISH,0,0,0,0,dx,dy,dw,dh);

where dx, dy, dw, dh are the maximum area of the desktop as returned by the
call wind_get(0,WF_WORKXYWH,&dx,&dy,&dw,&dh)

This will force a redraw message to be sent to everyone.  This is by far
the easiest way to get other applications to redraw.  If they don't do it,
some DAs won't handle redraw messages, then they don't do redraws.

- mike vederman

-- 
for (;;)                              : Use ATARINET, send an interactive
        do_it(c_programmers);         : message such as:
                                      : Tell UH-INFO at UHUPVM1 ATARINET HELP
University Atari Computer Enthusiasts : University of Houston UACE