A question (or 2) about ScreenNotification

10 posts / 0 new
Last post
OldFart
OldFart's picture
Offline
Last seen: 4 months 2 weeks ago
Joined: 2010-11-30 14:09
A question (or 2) about ScreenNotification

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!):

  1. #include <proto/exec.h>
  2. #include <proto/dos.h>
  3. #include <proto/intuition.h>
  4.  
  5. struct Library *IntuitionBase;
  6. struct IntuitionIFace *IIntuition;
  7.  
  8. #define INFO(X) IDOS->Printf("INFO : * %s\n", X)
  9. #define ELSE_ERROR(Text) else {IDOS->Printf("ERROR: Failed to %s\n", Text);}
  10. #define MAX_SN_BIT 17
  11.  
  12. int main(int argc, char *argv[])
  13. {
  14. int RetVal = RETURN_FAIL;
  15.  
  16. struct MsgPort *SNPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
  17.  
  18. if (SNPort != NULL)
  19. {
  20. APTR SNHandle = IIntuition->StartScreenNotifyTags(SNA_PubName, NULL, //"Workbench",
  21. SNA_MsgPort, SNPort,
  22. SNA_Notify, 0
  23. // | SNOTIFY_WAIT_REPLY
  24. | SNOTIFY_BEFORE_OPENWINDOW
  25. // | SNOTIFY_BEFORE_CLOSEWINDOW
  26. // | SNOTIFY_AFTER_OPENWINDOW
  27. // | SNOTIFY_AFTER_CLOSEWINDOW
  28. ,
  29. TAG_END
  30. );
  31.  
  32. if (SNHandle != NULL)
  33. {
  34. struct ScreenNotifyMessage *snm;
  35. uint16 Counter = 3;
  36. BOOL Done = FALSE;
  37. uint32 WaitSigs = (1 << SNPort->mp_SigBit);
  38. IDOS->Printf("INFO : Notification started...\n");
  39.  
  40. while (Done == FALSE)
  41. {
  42. IExec->Wait(WaitSigs);
  43.  
  44. INFO("Notification received");
  45.  
  46. snm = (struct ScreenNotifyMessage *)IExec->GetMsg(SNPort);
  47.  
  48. if (snm != NULL)
  49. {
  50. IDOS->Printf("INFO : Class %08lX\n", snm->snm_Class);
  51. IDOS->Printf("INFO : Code %08lX\n", snm->snm_Code);
  52. IDOS->Printf("INFO : Object %08lX\n", snm->snm_Object);
  53. IDOS->Printf("INFO : Request %08lX\n", snm->snm_Request);
  54.  
  55. if (snm->snm_Object != NULL)
  56. {
  57. if (snm->snm_Class == SNOTIFY_BEFORE_OPENWINDOW)
  58. {
  59. IDOS->Printf("INFO : * Next Window [ %08lx ]\n", ((struct Window *)snm->snm_Object)->NextWindow);
  60. IDOS->Printf("INFO : * Window left < %ld >\n", ((struct Window *)snm->snm_Object)->LeftEdge);
  61. IDOS->Printf("INFO : * Window top < %ld >\n", ((struct Window *)snm->snm_Object)->TopEdge);
  62. IDOS->Printf("INFO : * Window width < %ld >\n", ((struct Window *)snm->snm_Object)->Width);
  63. IDOS->Printf("INFO : * Window height < %ld >\n", ((struct Window *)snm->snm_Object)->Height);
  64. }
  65. }
  66. ELSE_ERROR("Retrieve Object");
  67.  
  68. // IExec->ReplyMsg((struct Message *)snm);
  69. }
  70. ELSE_ERROR("Get Message");
  71.  
  72. Counter--;
  73.  
  74. if (Counter == 0)
  75. {
  76. Done = TRUE;
  77. }
  78. }
  79.  
  80. IIntuition->EndScreenNotify(SNHandle);
  81. IDOS->Printf("INFO : Notification ended...\n");
  82. }
  83. ELSE_ERROR("Start notification")
  84.  
  85. IExec->FreeSysObject(ASOT_PORT, SNPort);
  86. }
  87. ELSE_ERROR("Allocate SysObject (ASOT_PORT)")
  88.  
  89. return RetVal;
  90. }

and this is the results I get:

  1. INFO : Notification started...
  2. INFO : * Signal received
  3. INFO : * Notification received
  4. INFO : Class 00001000
  5. INFO : Code 00000000
  6. INFO : Object 00000000
  7. INFO : Request 68195b78
  8. ERROR: Failed to Retrieve Object
  9. INFO : * Signal received
  10. INFO : * Notification received
  11. INFO : Class 00001000
  12. INFO : Code 00000000
  13. INFO : Object 6acd69f8
  14. INFO : Request 68195b78
  15. INFO : * Next Window [ 00000003 ]
  16. INFO : * Window left < 28656 >
  17. INFO : * Window top < -16384 >
  18. INFO : * Window width < 27341 >
  19. INFO : * Window height < 27168 >
  20. INFO : * Signal received
  21. INFO : * Notification received
  22. INFO : Class 00001000
  23. INFO : Code 00000000
  24. INFO : Object 6acd69f8
  25. INFO : Request 68195b78
  26. INFO : * Next Window [ 00000003 ]
  27. INFO : * Window left < 28656 >
  28. INFO : * Window top < -16384 >
  29. INFO : * Window width < 27341 >
  30. INFO : * Window height < 27168 >
  31. 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

thomas
thomas's picture
Offline
Last seen: 1 week 6 days ago
Joined: 2011-05-16 14:23
Re: A question (or 2) about ScreenNotification

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.

hypex
hypex's picture
Offline
Last seen: 4 months 3 weeks ago
Joined: 2011-09-09 16:20
Re: A question (or 2) about ScreenNotification

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?

msteed
msteed's picture
Offline
Last seen: 5 months 6 hours ago
Joined: 2022-01-18 08:34
Re: A question (or 2) about ScreenNotification

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.)

OldFart
OldFart's picture
Offline
Last seen: 4 months 2 weeks ago
Joined: 2010-11-30 14:09
Re: A question (or 2) about ScreenNotification

@all involved

Here's the slightly modified source:

  1. #include <proto/exec.h>
  2. #include <proto/dos.h>
  3. #include <proto/intuition.h>
  4.  
  5. struct Library *IntuitionBase;
  6. struct IntuitionIFace *IIntuition;
  7.  
  8. #define INFO(X) IDOS->Printf("INFO : * %s\n", X)
  9. #define ELSE_ERROR(Text) else {IDOS->Printf("ERROR: Failed to %s\n", Text);}
  10. #define MAX_SN_BIT 17
  11.  
  12. int main(int argc, char *argv[])
  13. {
  14. IDOS->Printf("INFO : --- main entered\n");
  15. int RetVal = RETURN_FAIL;
  16.  
  17. struct MsgPort *SNPort = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
  18.  
  19. if (SNPort != NULL)
  20. {
  21. APTR SNHandle = IIntuition->StartScreenNotifyTags(SNA_PubName, NULL, //"Workbench",
  22. SNA_MsgPort, SNPort,
  23. SNA_Notify, 0
  24. | SNOTIFY_WAIT_REPLY
  25. | SNOTIFY_BEFORE_OPENWINDOW
  26. // | SNOTIFY_BEFORE_CLOSEWINDOW
  27. // | SNOTIFY_AFTER_OPENWINDOW
  28. // | SNOTIFY_AFTER_CLOSEWINDOW
  29. ,
  30. TAG_END
  31. );
  32.  
  33. if (SNHandle != NULL)
  34. {
  35. struct ScreenNotifyMessage *snm;
  36. uint16 Counter = 3;
  37. BOOL Done = FALSE;
  38. uint32 WaitSigs = (1 << SNPort->mp_SigBit);
  39. IDOS->Printf("INFO : Notification started...\n");
  40.  
  41. while (Done == FALSE)
  42. {
  43. IExec->Wait(WaitSigs);
  44.  
  45. INFO("Signal received");
  46.  
  47. {
  48. INFO("Notification received");
  49.  
  50. snm = (struct ScreenNotifyMessage *)IExec->GetMsg(SNPort);
  51.  
  52. if (snm != NULL)
  53. {
  54. IDOS->Printf("INFO : Class %08lX\n", snm->snm_Class);
  55. IDOS->Printf("INFO : Code %08lX\n", snm->snm_Code);
  56. IDOS->Printf("INFO : Object %08lX\n", snm->snm_Object);
  57. IDOS->Printf("INFO : Request %08lX\n", snm->snm_Request);
  58.  
  59. if (snm->snm_Object != NULL)
  60. {
  61. if (snm->snm_Class == SNOTIFY_BEFORE_OPENWINDOW)
  62. {
  63. uint16 i;
  64.  
  65. for (i = 0; i < 12; i++)
  66. {
  67. IDOS->Printf(" : - %08lx\n", *(((uint32 *)snm->snm_Object) + i));
  68. }
  69. }
  70. }
  71. ELSE_ERROR("Retrieve Object");
  72.  
  73. IExec->ReplyMsg((struct Message *)snm);
  74. }
  75. ELSE_ERROR("Get Message");
  76.  
  77. Counter--;
  78.  
  79. if (Counter == 0)
  80. {
  81. Done = TRUE;
  82. }
  83. }
  84. }
  85.  
  86. IIntuition->EndScreenNotify(SNHandle);
  87. IDOS->Printf("INFO : Notification ended...\n");
  88. }
  89. ELSE_ERROR("Start notification")
  90.  
  91. IExec->FreeSysObject(ASOT_PORT, SNPort);
  92. }
  93. ELSE_ERROR("Allocate SysObject (ASOT_PORT)")
  94.  
  95. IDOS->Printf("INFO : --- main vacated\n");
  96. return RetVal;
  97. }

I changed the output to be showing uint32's in hexadecimal format:

  1. INFO : --- main entered
  2. INFO : Notification started...
  3. INFO : * Signal received
  4. INFO : * Notification received
  5. INFO : Class 00001000
  6. INFO : Code 00000000
  7. INFO : Object 6773ad54
  8. INFO : Request 6773aa38
  9. : - 04330033
  10. : - 0000004B
  11. : - 000000BA
  12. : - 6FF0C1AC
  13. : - 6FF0C1A8
  14. : - 67DA14F0
  15. : - 6B34FA0C
  16. : - 67739064
  17. : - 00000000
  18. : - 00000000
  19. : - 00000000
  20. : - 00000000
  21. INFO : * Signal received
  22. INFO : * Notification received
  23. INFO : Class 00001000
  24. INFO : Code 00000000
  25. INFO : Object 6773c5c4
  26. INFO : Request 6773aa38
  27. : - 03D90033
  28. : - 0000004B
  29. : - 000000BA
  30. : - 6FF0C1AC
  31. : - 6FF0C1A8
  32. : - 680FC130
  33. : - 69AB0ACC
  34. : - 69AB0AF8
  35. : - 69AB0B24
  36. : - 69AB0B50
  37. : - 69AB0B7C
  38. : - 69AB0BA8
  39. INFO : * Signal received
  40. INFO : * Notification received
  41. INFO : Class 00001000
  42. INFO : Code 00000000
  43. INFO : Object 681b7f14
  44. INFO : Request 6773aa38
  45. : - 048A0094
  46. : - 0000004B
  47. : - 000000BA
  48. : - 6FF0C1AC
  49. : - 6FF0C1A8
  50. : - 80000010
  51. : - 00050000
  52. : - 00000000
  53. : - 00000000
  54. : - 00006AE5
  55. : - 94680000
  56. : - 0000FFFD
  57. INFO : Notification ended...
  58. INFO : --- main vacated

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

OldFart
OldFart's picture
Offline
Last seen: 4 months 2 weeks ago
Joined: 2010-11-30 14:09
Re: A question (or 2) about ScreenNotification

@thomas

What do you expect to get before OpenWindow?

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

msteed
msteed's picture
Offline
Last seen: 5 months 6 hours ago
Joined: 2022-01-18 08:34
Re: A question (or 2) about ScreenNotification

@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.

msteed
msteed's picture
Offline
Last seen: 5 months 6 hours ago
Joined: 2022-01-18 08:34
Re: A question (or 2) about ScreenNotification

@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.

OldFart
OldFart's picture
Offline
Last seen: 4 months 2 weeks ago
Joined: 2010-11-30 14:09
Re: A question (or 2) about ScreenNotification

@msteed

Any progress on this, or have you given up?

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.

It might be worth posting about this over on the OS4 support forum.

I might just do that! Thanks.

OldFart

OldFart
OldFart's picture
Offline
Last seen: 4 months 2 weeks ago
Joined: 2010-11-30 14:09
Re: A question (or 2) about ScreenNotification

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

Log in or register to post comments