[comp.sys.amiga] Burning Questions

grant@hpindda.HP.COM (Grant Haidinyak) (11/24/87)

Hello,

I seem to be having trouble with requesters.  The problem is that I 
have a requester with a PREDRAWN image, and one boolean gadget.
To acivate the requester, I use the InitRequester, and setup the
requester stucture as follows:

    InitRequester(rqstr);
    rqstr->LeftEdge   = 160;
    rqstr->TopEdge    = 50;
    rqstr->Width      = log_rqstr_image.Width;
    rqstr->Height     = log_rqstr_image.Height;
    rqstr->RelLeft    = 0;
    rqstr->RelTop     = 0;
    rqstr->ReqGadget  = &log_rqstr_gadget;
    rqstr->ReqBorder  = NULL;
    rqstr->ReqText    = NULL;
    rqstr->Flags      = PREDRAWN;
    rqstr->BackFill   = 1;
    rqstr->ImageBMap  = log_rqstr_bitmap;

and to render the requester I do the following:

    Request(&log_rqstr, win_main);

where win_main is a pointer to the window that I am trying to render
the requester in.

What happens is that after the call to Request, nothing is displayed,
however, after I double click on the window, the requester is rendered,
and everything works fine from then on.

My Question is: What am I doing wrong?


Also, I'm writing a program that has multiple windows being opened, that
are attached to one port.  The problem that I have found with this is:

  1) A Close request for a window comes in.
  2) I Close the window, the messages associated with this window
     get deallocated.
  3) There are still pending messages for the window queued to the port.
  4) I start to process the queueed messages.
  5) Guru because of bad next link pointer (memory had been deallocated).
  
I have come up with 2 solutions to this problem.

  1) When I close the window, do the following:
     a) Forbid
     b) Go through the list of messages queued to the port, and if
        the message is for the Closing window the remove it from the queue,
        and reply to the message.
     c) Permit

  2) Maintain a second queue of messages, and a second series of procedures
     that get and put messages associated with the port, i.e. 
        my_get_msg - would first check the secondary queue for messages, and
                     if none were available, then do a normal GetMsg().
        my_put_msg - would put a message on the secondary queue.
        
     Then when a window was to be closed, the following would occur:
       a) while (GetMsg() != NULL) {
            if (msg is for window) 
              Reply()
            else
              my_put_msg()
          }
  
  There are good points, and bad points associated with each method, but
  I'd like to know which is accepted, or if there is a standard way of 
  doing this already.

  Thanks,
    Grant
    

cmcmanis%pepper@Sun.COM (Chuck McManis) (11/25/87)

[Coming soon : The Compleate Intuition Example Program (TCIEP) ]

In article <6570001@hpindda.HP.COM> (Grant Haidinyak) writes:
>I seem to be having trouble with requesters...  
>I use the InitRequester, and setup the requester stucture as follows:
>    InitRequester(rqstr);
>    rqstr->LeftEdge   = 160;
>    rqstr->TopEdge    = 50;
>    rqstr->Width      = log_rqstr_image.Width;
>    rqstr->Height     = log_rqstr_image.Height;
>    rqstr->RelLeft    = 0;
>    rqstr->RelTop     = 0;
>    rqstr->ReqGadget  = &log_rqstr_gadget;
>    rqstr->ReqBorder  = NULL;
>    rqstr->ReqText    = NULL;
>    rqstr->Flags      = PREDRAWN;
>    rqstr->BackFill   = 1;
>    rqstr->ImageBMap  = log_rqstr_bitmap;
>
>and to render the requester I do the following:
>    Request(&log_rqstr, win_main);

Didn't you mean "Request(rqstr,win_main);" here? The variable log_rqstr
doesn't seem to be initialized by the above code. Also if you declare
log_rqstr as a struct Requester then the above call will work but if
you declare it as a struct Requester * then the & above causes the
C compiler to pass a pointer to a pointer to a struct Requester. 

>What happens is that after the call to Request, nothing is displayed,
>however, after I double click on the window, the requester is rendered,
>and everything works fine from then on.
>My Question is: What am I doing wrong?

Well, this should work if you set it up correctly. When you say 'double click'
are you referring to the select button or the Menu button of the mouse ? I
ask because if the requester flags are set with DMREQUEST then it takes
a double menu click to bring up the requester. 

>Also, I'm writing a program that has multiple windows being opened, that
>are attached to one port.  The problem that I have found with this is:
>
>  1) A Close request for a window comes in.
>  2) I Close the window, the messages associated with this window
>     get deallocated.
>  3) There are still pending messages for the window queued to the port.
>  4) I start to process the queueed messages.
>  5) Guru because of bad next link pointer (memory had been deallocated).

The magic is that you open your initial window, then subsequent windows 
you open with NULL IDCMP Flags, and copy the message port pointer from 
the initial window into the new windows structure. Then use ModifyICMP()
to set the events you want to see. Before closing the window you do the
same thing in reverse. ModifyIDCMP() back to nothing, set the message
port pointer to NULL, and then close the window. Let the parent window
dispose of any extra messages.

>  There are good points, and bad points associated with each method, but
>  I'd like to know which is accepted, or if there is a standard way of 
>  doing this already.

The above is the 'accepted' way of doing that. It's based on an example
that Jim Mackraz did which included a routine CloseWindowSafely() that
took care of the message port stuff.

This is another case of 'Those Fish Disks sure are valuable!' There are
examples of ways to do this on some of the early disks. 


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't youme

grant@hpindda.HP.COM (Grant Haidinyak) (12/01/87)

>Didn't you mean "Request(rqstr,win_main);" here? The variable log_rqstr
>doesn't seem to be initialized by the above code. Also if you declare
>log_rqstr as a struct Requester then the above call will work but if
>you declare it as a struct Requester * then the & above causes the
>C compiler to pass a pointer to a pointer to a struct Requester. 

Sorry about that.  The Initial code is in a procedure that intializes the
requester sturcture, and the end line was the actual line that is code, so
the code looks something like:


make_log_rqstr(rqstr)
struct Requester  *rqstr;
{
  /*  initialization code */
}


get_log()
{
  make_log_rqstr(&log_rqstr);
  Request(&log_rqstr, win_main);
}


Also, I had a WindowToFront(win_main) before the get_log() call, but
when I took the call out, the requestor appeared when specified.
(win_main was already to the front of the window stack).

>Well, this should work if you set it up correctly. When you say 'double click'
>are you referring to the select button or the Menu button of the mouse ? I
>ask because if the requester flags are set with DMREQUEST then it takes
>a double menu click to bring up the requester. 

What I mean by double click, is click on the left (select) button twice.

>>Also, I'm writing a program that has multiple windows being opened, that
>>are attached to one port.  The problem that I have found with this is:
>>
>>  1) A Close request for a window comes in.
>>  2) I Close the window, the messages associated with this window
>>     get deallocated.
>>  3) There are still pending messages for the window queued to the port.
>>  4) I start to process the queueed messages.
>>  5) Guru because of bad next link pointer (memory had been deallocated).
>
>The magic is that you open your initial window, then subsequent windows 
>you open with NULL IDCMP Flags, and copy the message port pointer from 
>the initial window into the new windows structure. Then use ModifyICMP()
>to set the events you want to see. Before closing the window you do the
>same thing in reverse. ModifyIDCMP() back to nothing, set the message
>port pointer to NULL, and then close the window. Let the parent window
>dispose of any extra messages.

I'm not opening an initial window, I'm just opening a standard port.
Also, the setup described above, is correct. However, closing the window
isn't how it is described in the "Intuition" manual (which could now be
out of date, as I have the original manuals).  In the manual, to close a
window with a shared message port, it says to NULL out the message port
field in the window structure, but to leave the IDCMP field alone.

The is a "Grim, Forboding Note" however, the manual says that if
you don't reply to the messages, there will probably be a GURU. (paraphrased)

I tried resetting the IDCMP's to NULL, and then resetting the message port
to NULL, but the also GURU'ed the machine.

>>  There are good points, and bad points associated with each method, but
>>  I'd like to know which is accepted, or if there is a standard way of 
>>  doing this already.
>
>The above is the 'accepted' way of doing that. It's based on an example
>that Jim Mackraz did which included a routine CloseWindowSafely() that
>took care of the message port stuff.

Would you or anyone else please post, or tell me where to get the
CloseWindowSafely() routine.  (I want to do things "right", not just do them)

Also, since I'm on my soapbox, how do I get the Autodocs that are refered
to by the Enhancer Manual.

>--Chuck McManis

Grant Haidinyak

cmcmanis%pepper@Sun.COM (Chuck McManis) (12/02/87)

In article <6570004@hpindda.HP.COM> (Grant Haidinyak) writes:
>Also, I had a WindowToFront(win_main) before the get_log() call, but
>when I took the call out, the requestor appeared when specified.
>(win_main was already to the front of the window stack).

Is your window a SIMPLE_REFRESH window? I recently noticed that when you
move a SIMPLE_REFRESH window to the front of the list it gets cleared to
0 for some reason (But you get a refresh request to redraw it). Also you
should know that the WindowToFront() operation happens asynchronously. That
is, you call WindowToFront() and it returns, then sometime later your 
window actually gets moved to the front. There are two ways I can think of
off the top of my head to determine when your window has made it to the 
front. One is to spin on (window->WScreen->FirstWindow == window) the
other is to wait for the REFRESHWINDOW message and assume that it meant you
are now in front. 

>What I mean by double click, is click on the left (select) button twice.

I thought of something else that could cause this behaviour, that is 
if you had REQVERIFY set, but you don't mention it so I assume you don't.

>I'm not opening an initial window, I'm just opening a standard port.
>Also, the setup described above, is correct. However, closing the window
>isn't how it is described in the "Intuition" manual (which could now be
>out of date, as I have the original manuals).  In the manual, to close a
>window with a shared message port, it says to NULL out the message port
>field in the window structure, but to leave the IDCMP field alone.

The manual is correct, I was wrong, you don't NULL out the IDCMP flags.
You may still get messages from this 'closed' window if you plan it 
right :-). Since Intuition queues messages until you can get to them. 
In my code I check to see if the 'other' window pointer is now NULL, and
if it is just throw away messages coming from it. 

>Would you or anyone else please post, or tell me where to get the
>CloseWindowSafely() routine.  (I want to do things "right", not just do them)

If I can find a copy of it I will post it.

>Also, since I'm on my soapbox, how do I get the Autodocs that are refered
>to by the Enhancer Manual.

Write "I want the Native Developers Update, here is $20 and my address ..."
on a sheet of paper put it into an envelope and mail it to :
	Lauren Brown
	CATS
	1200 Wilson Dr.
	West Chester, PA 19380


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

grant@hpindda.UUCP (12/03/87)

>Is your window a SIMPLE_REFRESH window?

No, it's a SMART_REFRESH window.
I do have the REFRESH_WINDOW flag set, however, I currently reply to the
message immediately

>What I mean by double click, is click on the left (select) button twice.

>I thought of something else that could cause this behaviour, that is 
>if you had REQVERIFY set, but you don't mention it so I assume you don't.

I do have the REQVERIFY flag set, infact, I have all the REQ flags set
(sorry, I forgot to mention it before). Here are all the flags set in the 
window 

#define STD_WIN_FLAGS (long)(WINDOWCLOSE | SMART_REFRESH | WINDOWDEPTH\
       | WINDOWSIZING | WINDOWDRAG | REPORTMOUSE)

#define STD_IDCMPS  (long)(MOUSEBUTTONS | MOUSEMOVE | CLOSEWINDOW\
       | MENUPICK | MENUVERIFY | REQSET | REQCLEAR | REQVERIFY | NEWSIZE\
       | REFRESHWINDOW | SIZEVERIFY | ACTIVEWINDOW | INACTIVEWINDOW | RAWKEY\
       | NEWPREFS | GADGETDOWN | GADGETUP)

But, like I said before, I reply to these messages immediately
(I just started to write the message handler functions)
Also, I tried taking out the REQ* flags, but to no avail.

>Since Intuition queues messages until you can get to them. 
>In my code I check to see if the 'other' window pointer is now NULL, and
>if it is just throw away messages coming from it. 

There is a problem when you try to CloseWindow() on that window, after NULLing
the message port.  Intuition will close it's port and reclaim all the messages
that it sent.  But, there could be messages still queued to the my port
(usually mouse move messages), and when they get reclaimed, the reclaimation
process screws up the links in the message queue. Then Guru...

>--Chuck McManis

Thanks,
 
Grant Haidinyak