Hi
The other day I was fiddling a bit with ScreenNotification, but the results I got were not in line with my expectations.
This is the source (an open door, I know!):
#include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> struct Library *IntuitionBase; struct IntuitionIFace *IIntuition; #define INFO(X) IDOS->Printf("INFO : * %s\n", X) #define ELSE_ERROR(Text) else {IDOS->Printf("ERROR: Failed to %s\n", Text);} #define MAX_SN_BIT 17 int main(int argc, char *argv[]) { int RetVal = RETURN_FAIL; struct MsgPort *SNPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END); if (SNPort != NULL) { APTR SNHandle = IIntuition->StartScreenNotifyTags(SNA_PubName, NULL, //"Workbench", SNA_MsgPort, SNPort, SNA_Notify, 0 // | SNOTIFY_WAIT_REPLY | SNOTIFY_BEFORE_OPENWINDOW // | SNOTIFY_BEFORE_CLOSEWINDOW // | SNOTIFY_AFTER_OPENWINDOW // | SNOTIFY_AFTER_CLOSEWINDOW , TAG_END ); if (SNHandle != NULL) { struct ScreenNotifyMessage *snm; uint16 Counter = 3; BOOL Done = FALSE; uint32 WaitSigs = (1 << SNPort->mp_SigBit); IDOS->Printf("INFO : Notification started...\n"); while (Done == FALSE) { IExec->Wait(WaitSigs); INFO("Notification received"); snm = (struct ScreenNotifyMessage *)IExec->GetMsg(SNPort); if (snm != NULL) { IDOS->Printf("INFO : Class %08lX\n", snm->snm_Class); IDOS->Printf("INFO : Code %08lX\n", snm->snm_Code); IDOS->Printf("INFO : Object %08lX\n", snm->snm_Object); IDOS->Printf("INFO : Request %08lX\n", snm->snm_Request); if (snm->snm_Object != NULL) { if (snm->snm_Class == SNOTIFY_BEFORE_OPENWINDOW) { IDOS->Printf("INFO : * Next Window [ %08lx ]\n", ((struct Window *)snm->snm_Object)->NextWindow); IDOS->Printf("INFO : * Window left < %ld >\n", ((struct Window *)snm->snm_Object)->LeftEdge); IDOS->Printf("INFO : * Window top < %ld >\n", ((struct Window *)snm->snm_Object)->TopEdge); IDOS->Printf("INFO : * Window width < %ld >\n", ((struct Window *)snm->snm_Object)->Width); IDOS->Printf("INFO : * Window height < %ld >\n", ((struct Window *)snm->snm_Object)->Height); } } ELSE_ERROR("Retrieve Object"); // IExec->ReplyMsg((struct Message *)snm); } ELSE_ERROR("Get Message"); Counter--; if (Counter == 0) { Done = TRUE; } } IIntuition->EndScreenNotify(SNHandle); IDOS->Printf("INFO : Notification ended...\n"); } ELSE_ERROR("Start notification") IExec->FreeSysObject(ASOT_PORT, SNPort); } ELSE_ERROR("Allocate SysObject (ASOT_PORT)") return RetVal; }
and this is the results I get:
INFO : Notification started... INFO : * Signal received INFO : * Notification received INFO : Class 00001000 INFO : Code 00000000 INFO : Object 00000000 INFO : Request 68195b78 ERROR: Failed to Retrieve Object INFO : * Signal received INFO : * Notification received INFO : Class 00001000 INFO : Code 00000000 INFO : Object 6acd69f8 INFO : Request 68195b78 INFO : * Next Window [ 00000003 ] INFO : * Window left < 28656 > INFO : * Window top < -16384 > INFO : * Window width < 27341 > INFO : * Window height < 27168 > INFO : * Signal received INFO : * Notification received INFO : Class 00001000 INFO : Code 00000000 INFO : Object 6acd69f8 INFO : Request 68195b78 INFO : * Next Window [ 00000003 ] INFO : * Window left < 28656 > INFO : * Window top < -16384 > INFO : * Window width < 27341 > INFO : * Window height < 27168 > INFO : Notification ended...
I expected to get a pointer to struct Window in 'Object', but all the values i get when casting snm_Object to a (pointer to) struct Window are 'rather curious' to say the least. Where (and why!) do my expectations divert from reality?
Regards
OldFart
What do you expect to get before OpenWindow? It can hardly be a window pointer because the window does not yet exist. Not sure what kind of pointer you got. Probably the screen. Or the field just has not been cleared when reusing the message memory.
If you want to get a window pointer you should check after OpenWindow.
I see your point Thomas but according to this it should work because the Window object is about to appear as at this stage the Window object does exist:
SNOTIFY_BEFORE_OPENWINDOW
Reports calls to OpenWindow() and will sent a notification right
before a window is about to be opened. snm_Object will point to
the struct (New)Window of the window that is about to be opened.
However the use of the terms "struct (New)Window" is confusing. Is it a NewWindow or Window? By the time this function came about NewWindow was obsolete. But the way I interpret the above is that the window object does exist but isn't yet rendered on screen. Unless it only shares the NewWindow object which won't exist unless used. Okay I don't get it either. :-)
Wait a minute. It says OpenWindow(). It's a modern function to track an obsolete function then?
I agree that the documentation is confusingly written. My reading of it is that the object is indeed a NewWindow (more likely an ExtNewWindow, if WFLG_NW_EXTENDED is set). NewWindow isn't really obsolete; a pointer to a NewWindow is still passed to OpenWindowTags(). Yes, the pointer can be NULL, but I imagine in that case Intuition just substitutes a pointer to a built-in NewWindow containing default values.
If you assume that the object is in fact a NewWindow and modify the example code to print out the size values accordingly, do the numbers make more sense? I suspect that the NewWindow has not had any of the tags applied to it, so if you're using those to, for example, set the window size, you may well get size values different than those you set. But they should at least be reasonable numbers, not like what was seen before. (Of course there's no NextWindow in a NewWindow, so you'd need to omit that part.)
@all involved
Here's the slightly modified source:
I changed the output to be showing uint32's in hexadecimal format:
The very first entry in every set looks like to contain two values: 0x0433 and 0x0033 for the first set. That 0x0433 looks like to correspond with the leftedge of the window to be displayed. This is confirmed by the corresponding entries in set 2 and 3, which I deliberately put 'out of line': their leftedge is put to the left and to the right respectively.
The rest of the entries is quite a maze to me, with entry 4 and 5 showing a curious similarity.
OldFart
@thomas
Well, what I was expecting/hoping for is a structure of some sort which contains the data of the window which is ABOUT to be opened, but is halted by the notification request until the message is returned.
My aim is to modify that structure to have that window open on a different place then planned by Workbench. This may ONLY effect windows of directories which do NOT have an icon (.info-file) of their own and are therefore now relegated by Workbench to a default position somewhere on the lefthand upper side of the screen. I want these windows to open with the same leftedge as their parent and their topedge sufficently lower then their parents to show that parent's titlebar. Like 'AlignWindow' does for drawers/directories with an icon of their own, but now as a commodity ('Aligner', the name of the commodity is already there, now the code...) for those directories without.
OldFart
@OldFart
I'm confused now, as well. The values don't seem to match what you'd expect to see in a NewWindow struct.
I played with your program some, and observed that I got different values each time, even when opening the same Workbench window repeatedly. The second and third entries tend to be small numbers, as in your example (though not always the same). The third and fourth entries look like addresses, though in some cases they differed by only one byte, which seems unlikely for pointers to any kind of real object. The remainder of the entries (including the first) are completely inconsistent.
And when opening other kinds of windows, such as when starting a program, opening a dock panel, and even when bringing up the Workbench "About" requester the Object pointer would usually (but not always) be null.
As an experiment I tried putting all 12 entries into a buffer before printing any of them, in case outputting to a console window in between getting the notification message and replying to it interfered with the process somehow, but it didn't make any difference.
I also tried modifying your program to dump SNOTIFY_AFTER_OPENWINDOW notifications, and the values that were dumped didn't seem to correspond to a Window struct, either. And the Object address didn't match what Ranger showed as the window's address.
So I have to say I don't know what the Object pointer is pointing at, even for SNOTIFY_AFTER_OPENWINDOW notifications.
@OldFart
Any progress on this, or have you given up?
It might be worth posting about this over on the OS4 support forum. Maybe one of the developers can tell you where you're going wrong, or if in fact screen notification is just broken.
@msteed
No, I haven't given up. Just spending time on other pastimes and interests. 'Giving up' is not written in capitals in my vocabulary, although I can easily give things a prolonged time of rest, however.
I might just do that! Thanks.
OldFart
Hi,
Just to get going again, I picked this one issue up and found a curiosity. For the record struct ScreenNotificationMessage in total spans a size of 60 bytes or 15 longs. When that structure is located at address n, snm_Object points to address n + 15 longs, which is just past the structure. What is found there has not much ressemblance with struct Windows, though.
Thought it good to let you know.
OldFart