English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 24 February 2024, 09:44   #21
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Sigh ... it does work. There's no menu verify involved. What I forgot to mention was that the MenuItem whose activation you want to emulate needs to have it's item->NextSelect set to MENUNULL (as seen in PowerWB sources). The following definitely works:

Code:
#include <intuition/intuitionbase.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <stdio.h>

#define MENU FULLMENUNUM(0,5,NOSUB) // about menu

struct Screen *scr;
struct Window *win;
struct Menu *menu;
struct MenuItem *item;
struct ExtIntuiMessage imsg;
struct MsgPort *replymp;

int main(void)
{
    scr = IntuitionBase->ActiveScreen;
    if (!scr) return 0;
    
    win = scr->FirstWindow;
    while(win)
    {
        if ((win->Flags & WFLG_BORDERLESS) && (win->Flags & WFLG_WBENCHWINDOW)) break;
	
	win = win->NextWindow;
    }
    
    if (!win) return 0;
    
    menu = win->MenuStrip;
    if (menu) item = ItemAddress(menu, MENU);
    
    if (!item) return 0;
    
    replymp = CreateMsgPort();
    if (!replymp) return 0;
    
    item->NextSelect = MENUNULL;

    imsg.eim_IntuiMessage.Class = IDCMP_MENUPICK;
    imsg.eim_IntuiMessage.Code = MENU;
    imsg.eim_IntuiMessage.IDCMPWindow = win;
    imsg.eim_IntuiMessage.ExecMessage.mn_ReplyPort = replymp;
    
    PutMsg(win->UserPort, &imsg.eim_IntuiMessage.ExecMessage);
    WaitPort(replymp);
        
    DeleteMsgPort(replymp);
}
And this GADGETDOWN was just an example of what PowerWB does to add cursor key scrolling functionality to wb drawer windows. It has nothing to do with menus.
aros-sg is offline  
Old 24 February 2024, 10:31   #22
Minuous
Coder/webmaster/gamer
 
Minuous's Avatar
 
Join Date: Oct 2001
Location: Canberra/Australia
Posts: 2,640
Quote:
Originally Posted by PeterK View Post
why should he do something else than just waiting till the job is done?
Because it's always been a multitasking system and users expect to be able to multitask, this is not MS-DOS :-D
Minuous is offline  
Old 24 February 2024, 14:25   #23
PeterK
Registered User
 
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,366
Quote:
Originally Posted by aros-sg View Post
Sigh ... it does work. There's no menu verify involved. What I forgot to mention was that the MenuItem whose activation you want to emulate needs to have it's item->NextSelect set to MENUNULL (as seen in PowerWB sources).
Great! Thanks a lot for that hint, it did the trick, and it works now with MENUNULL=-1.w instead of NULL=0 as set by the OS (don't ask me why, because NULL selects menu 0, item 0, subitem 0 instead of nothing or end of list).

So my new code for "Update all", which is still not completely done, looks like this now:
Code:
                incdir  "include:"
                include "exec/execbase.i"
                include "exec/initializers.i"
                include "exec/memory.i"
                include "dos/dos.i"
                include "dos/dosextens.i"
                include "intuition/intuition.i"
                include "workbench/workbench.i"
                include "lvo/LVOs.i"

_LVOPrivateOpenLibrary  EQU -$32A               ; _LVOexecPrivate17

main            MOVEA.L (4).w,A6                ; execbase
                BTST.B  #AFB_68020,AttnFlags+1(A6)
                BNE.S   .cpuisok
                MOVEQ   #RETURN_FAIL,D0
                RTS

                DC.B    "$VER: WBMenuTest 1.1",0

                CNOP    0,2                     ; 2024 by Peter Keunecke

.cpuisok        MOVEA.L ThisTask(A6),A0
                LEA     pr_MsgPort(A0),A5
                TST.L   pr_CLI(A0)              ; from CLI or WB ?
                BNE.S   .openlibs
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOWaitPort(A6)        ; wait for startup
                MOVE.L  D0,-(SP)                ; save WB message
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOGetMsg(A6)          ; remove Msg from port
                PEA     .replyWBmsg(PC)         ; WB patch for RTS from CLI calls
.openlibs       MOVEQ   #RETURN_ERROR,D2
                MOVEQ   #3,D0
                JSR     _LVOPrivateOpenLibrary(A6)
                MOVE.L  D0,D6                   ; intuibase
                BEQ.W   .itfailure
                MOVEQ   #0,D0                   ; LockNumber
                MOVEA.L D6,A6                   ; intuibase
                JSR     _LVOLockIBase(A6)
                MOVE.L  D0,D7
                MOVEA.L ib_ActiveScreen(A6),A0
                MOVE.L  sc_FirstWindow(A0),D0
.trywindow      BEQ.S   .returnnow
                MOVEA.L D0,A2
                MOVE.L  wd_Flags(A2),D1         ; check bit 25 for WFG_WBENCHWINDOW
                LSL.L   #6,D1
                BMI.S   .windowptr
                MOVE.L  (A2),D0                 ; wd_NextWindow
                BRA.S   .trywindow

.returnnow      MOVEA.L D7,A0                   ; lock on IBase
                JSR     _LVOUnlockIBase(A6)
                BRA.W   .closelibs

.windowptr      MOVE.L  wd_MenuStrip(A2),D0     ; first menu in WB menu strip
                BEQ.S   .returnnow
                MOVEA.L D0,A3                   ; A3 = menu strip = menu 0
                MOVE.L  mu_FirstItem(A3),D0     ; item 0 ?
                BEQ.S   .returnnow
                MOVEQ   #3,D1
.nextitem       MOVEA.L D0,A4                   ; item 0 - 3
                MOVE.L  (A4),D0                 ; next ?
                BEQ.S   .returnnow
                DBRA    D1,.nextitem            ; A4 = item 3 should be "Update all"
                MOVEA.L D0,A0                   ; item 4
                MOVE.L  (A0),D0                 ; item 5 ?
                BEQ.S   .returnnow
                MOVEA.L D0,A0                   ; is item 5 the "RescanAll" command
                CMPI.B  #"?",mi_Command(A0)     ; with the "?" as a shortcut key ?
                BNE.S   .returnnow              ; if not, we won't touch this menu
                LEA     MsgMenuRescanAll\.im_IDCMPWindow(PC),A0
                MOVE.L  A2,(A0)                 ; IDCMPWindow = Workbench WindowPtr

                MOVEA.L (4).w,A6                ; execbase
                JSR     _LVOForbid(A6)
                MOVEA.L D7,A0                   ; lock on IBase
                MOVEA.L D6,A6                   ; intuibase
                JSR     _LVOUnlockIBase(A6)

                MOVEA.L A2,A0                   ; WB window
                JSR     _LVOClearMenuStrip(A6)
                ORI.W   #MENUENABLED,mu_Flags(A3)
                ORI.W   #ITEMENABLED,mi_Flags(A4)
                MOVE.W  #MENUNULL,mi_NextSelect(A4) ; this was set to NULL by the OS
                MOVEA.L A2,A0                   ; WB window
                MOVEA.L A3,A1                   ; menu strip
                JSR     _LVOSetMenuStrip(A6)
                MOVEA.L A2,A0                   ; WB window
                JSR     _LVOActivateWindow(A6)

                LEA     MsgMenuRescanAll\.mn_ReplyPort(PC),A0
                MOVE.L  A5,(A0)                 ; pr_MsgPort
                MOVEA.L wd_UserPort(A2),A0      ; IDCMP receiver for Workbench
                LEA     MsgMenuRescanAll(PC),A1 ; message: MENUPICK, MENU_RESCAN_ALL
                MOVEA.L (4).w,A6                ; execbase
                JSR     _LVOPutMsg(A6)
                JSR     _LVOPermit(A6)

                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOWaitPort(A6)        ; wait for reply from Workbench
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOGetMsg(A6)          ; remove Msg from port
                MOVEQ   #RETURN_OK,D2
.closelibs      MOVEA.L D6,A1                   ; intuibase
                JSR     _LVOCloseLibrary(A6)
.itfailure      MOVE.L  D2,D0
                RTS                             ; CLI ends here, on WB to .replyWBmsg

.replyWBmsg     JSR     _LVOForbid(A6)
                MOVEA.L (SP)+,A1
                JSR     _LVOReplyMsg(A6)        ; WB unloads seglist
                MOVE.L  D2,D0                   ; set the final RC
                RTS                             ; return from WB tool


MENU_RESCAN_ALL EQU	(0 & $1F) | ((3 & $3F) << 5) | (($1F & $1F) << 11)

MsgMenuRescanAll
.ln_Succ        DC.L    0
.ln_Pred        DC.L    0
.ln_Type        DC.B    0
.ln_Pri         DC.B    0
.ln_Name        DC.L    0
.mn_ReplyPort   DC.L    0                       ; filled out at program start
.mn_Length      DC.W    $34
.im_Class       DC.L    IDCMP_MENUPICK
.im_Code        DC.W    MENU_RESCAN_ALL         ; Menu 0, Item 3, NoSub
.im_Qualifier   DC.W    0
.im_IAddress    DC.L    0
.im_MouseX      DC.W    0
.im_MouseY      DC.W    0
.im_Seconds     DC.L    0
.im_Micros      DC.L    0
.im_IDCMPWindow DC.L    0                       ; a WBENCHWINDOW
.im_SpecialLink DC.L    0

                CNOP    0,4
Yesterday, I also read in the Amiga RKRM under libraries #9, etc. about the menu details and that mi_NextSelect chain for multiselections of menu items. I thought, that could be a possible reason for locks, but I didn't check the initial settings of the OS. That missing MENUNULL explains, why it never worked for me at the first time, but always after once selecting this menu item manually or by MagicMenu. It seems that both methods are correcting the wrong initial menustrip setup.

@Thomas Richter: Important! You have PM, please read it!

Of course, I've checked the WB window flags for MENUVERIFY and other verifications, because with these flags set Intuition would ask the user first, before it would start any action on MENUPICK. No, there are no such flags set, but maybe I should check that in my code, too.

Last edited by PeterK; 24 February 2024 at 21:00.
PeterK is offline  
Old 24 February 2024, 20:15   #24
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,231
Problem is - this idea is also not without quirks as two processes now potentially access the same data structure (namely the menu item) in parallel. menu->NextSelect is initialized and updated when intuition displays the menu and the user left-clicks multiple elements. A LockIBase() will block out intuition from doing so, but see above.

From what I know, wb 3.1 *does* use MENUVERIFY, or at least temporarily when dragging icons or drawing a frame to multi-select icons. The IDCMP flags can be changed anytime, and thus a quick check with the debugger cannot tell you whether a particular IDCMP is actually used or not.
Thomas Richter is offline  
Old 24 February 2024, 21:33   #25
PeterK
Registered User
 
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,366
Yes, mi_NextSelect should be changed by Intuition when the user selects multiple menu elements, but nevertheless it seems to be wrong initialized by the OS before the very first access to a menu item is ever made. And that's a very old OS bug IMHO.

And no, usually there is no flag MENUVERIFY set in general, not even under 3.1, and if it were, it would probably cause some unnecessary slowdown. Ok, maybe there are temporary MENUVERIFY events, but all my menu handling is done in far less than a millisecond, so don't get paranoid. The worst thing that could happen is that my program aborts its operation.

After finding a typo in my code where SetMenuStrip() is called, with A0=A5=0 instead of A0=A3 containing the menu strip pointer, I wonder why that SMS was running successfully (returning 1) and I did not even get an enforcer hit.

The menu was detached by ClearMenuStrip(), then the data was modified and finally it could, for sure, not be linked into the window structure again by SetMenuStrip(window, NULL), but all was working as if nothing went wrong??? Very strange.

Is ClearMenuStrip() not really detaching the data and changing mi_NextSelect works even without SetMenuStrip()?
Attached Thumbnails
Click image for larger version

Name:	WB3.1window.png
Views:	32
Size:	12.3 KB
ID:	81716  

Last edited by PeterK; 24 February 2024 at 21:54.
PeterK is offline  
Old 24 February 2024, 22:37   #26
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,231
Quote:
Originally Posted by PeterK View Post
Yes, mi_NextSelect should be changed by Intuition when the user selects multiple menu elements, but nevertheless it seems to be wrong initialized by the OS before the very first access to a menu item is ever made. And that's a very old OS bug IMHO.
It is actually not the Os that is responsible for initialization (or rather intuition) of the MenuItem. It is the application program that allocates the "struct MenuItem". That is potentially gadtools or the workbench, but not necessarily so. It is perfectly fine if applications build these structures themselves (and actually that was the only way to create them in 1.3 and before.) But anyhow, it is not necessary to initalize this element as intuition sets it when it becomes necessary.


Quote:
Originally Posted by PeterK View Post
And no, usually there is no flag MENUVERIFY set in general, not even under 3.1, and if it were, it would probably cause some unnecessary slowdown.
Peter, with all necessary respect, but of the two of us, I'm the one that worked on the Os. So please, feel asured that the workbench does use this IDCMP occasionally.


Quote:
Originally Posted by PeterK View Post

Ok, maybe there are temporary MENUVERIFY events, but all my menu handling is done in far less than a millisecond, so don't get paranoid. The worst thing that could happen is that my program aborts its operation.
First of all, it's what the workbench will do that troubles me. Second, it is not a matter of milliseconds whether a software is correct or not. If by circumstances your program is triggered by a menu in the workbench, that millisecond may be long enough. It is a matter of following defined interfaces that makes software correct or incorrect. Even if something is just milliseconds away, chances are that something breaks. Consider, for example, the case that your program is run from the workbench menu.



Quote:
Originally Posted by PeterK View Post



Is ClearMenuStrip() not really detaching the data and changing mi_NextSelect works even without SetMenuStrip()?
Depending on your definition of "works". First, SetMenuStrip and ClearMenuStrip() are most likely implemented through a roundtrip to the intuition input handler. As application programs will directly read from the struct MenuItem, it is obviously not necessary to detach the menu to make such a change, but see my warning above: The only task that actually *should* make that change is the input device in the intuition input handler because only there the state of the menu is stable and under control.



If you modify it from outside, you do not know exactly whether the menu is currently attached, or - possibly - in the state of being teared down. In the latter case, you write into stale memory, even though at the time you looked at the menu of the window, the pointer *seemed* valid. In general, writing into structures whose lifetime is not under your control is not such a great idea.
Thomas Richter is offline  
Old 24 February 2024, 23:37   #27
PeterK
Registered User
 
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,366
Quote:
Originally Posted by Thomas Richter View Post
It is actually not the Os that is responsible for initialization (or rather intuition) of the MenuItem. It is the application program that allocates the "struct MenuItem". That is potentially gadtools or the workbench, but not necessarily so.
The Workbench task belongs to the OS in my eyes and it should initialize the WB menus correctly, but ok, now I've learned that I cannot rely on it.

Quote:
But anyhow, it is not necessary to initalize this element as intuition sets it when it becomes necessary.
No, it sets it only when the user opens the WB menu by mouse or keyboard manually.

Quote:
Peter, with all necessary respect, but of the two of us, I'm the one that worked on the Os. So please, feel asured that the workbench does use this IDCMP occasionally.
Sorry, when I said "in general" that was the wrong term. But usually, a WB window has no MENUVERIFY flag set by default. You can check that with Scout or ARTM also on 3.1 (screenshot above).

Quote:
First of all, it's what the workbench will do that troubles me. Second, it is not a matter of milliseconds whether a software is correct or not. If by circumstances your program is triggered by a menu in the workbench, that millisecond may be long enough. It is a matter of following defined interfaces that makes software correct or incorrect. Even if something is just milliseconds away, chances are that something breaks. Consider, for example, the case that your program is run from the workbench menu.
Good idea, I wanted to test that anyway. And the result was that it even works by launching it from the WB tools menu. No need to worry or to be too pessimistic.

Quote:
If you modify it from outside, you do not know exactly whether the menu is currently attached, or - possibly - in the state of being teared down. In the latter case, you write into stale memory, even though at the time you looked at the menu of the window, the pointer *seemed* valid. In general, writing into structures whose lifetime is not under your control is not such a great idea.
Yes, I should better stop writing hacky programs for the Amiga that don't care about the rules. They just seem to work, better nobody ever tries to use them!
PeterK is offline  
Old 25 February 2024, 07:47   #28
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,231
Quote:
Originally Posted by PeterK View Post
The Workbench task belongs to the OS in my eyes and it should initialize the WB menus correctly, but ok, now I've learned that I cannot rely on it.
I was generally speaking. The same goes for all other programs using intuition menus. They do not initialize this element either, so why should the workbench as user of intuition bother? This element does not need initialization, it is not documented to need it, so it is not done.



Quote:
Originally Posted by PeterK View Post
No, it sets it only when the user opens the WB menu by mouse or keyboard manually.
That is exactly when it is needed, namely when an IDCMP MENUPICK is delivered. It is not needed to be read before that point.


Quote:
Originally Posted by PeterK View Post

Sorry, when I said "in general" that was the wrong term. But usually, a WB window has no MENUVERIFY flag set by default. You can check that with Scout or ARTM also on 3.1 (screenshot above).
..and I told you that a system monitor is not the right tool to find that out. It does not prove that the workbench "does not use the flag". It only proves that it didn't use when you looked, but that's something different. Peter, you know, software works by interfaces, not by observation. Software development is not an empirical science. (It has more to do with math than with physics, in a nutshell)



Quote:
Originally Posted by PeterK View Post


Good idea, I wanted to test that anyway. And the result was that it even works by launching it from the WB tools menu. No need to worry or to be too pessimistic.
No, better to write programs you can prove that they work in first place, and where you get from the system guarantees that the algorithm actually does work. So, in your case, I suggest:


1) LockPubScreen("Workbench"...) This ensures that the workbench screen is not going away while you look. (Provable by the interface definition of LockPubScreen())

2) LockIBase(). This ensures that the window list is not going to change and menu is not just going away.
3) Walk the window list of the screen and find a workbench window. Nothing can happen now as the list is stable.
4) Find the menu in the window, and also walk that menu to the item you want to locate. This is *likely* going to work as in principle the owner of the window could possibly remove it manually there. Though the workbench is playing nicely with the system, this *should* be ok.
5) Check whether MENUVERIFY is requested. If so, skip the next two steps as this is a message you cannot generate so easily.

6) Play with NextSelect, and set it to MENUNULL. (This is where things can possibly go wrong, see below).
7) PutMsg() your fake IDCMP to the message port. DO NOT WAIT FOR REPLY.
8) Unlock IBbase.
9) Unlock the screen.
10) Wait for the message to come back.


Even this algorithm has a race condition because after you unlock IBase, intuition may overwrite NextSelect. This should hopefully not do too much harm, in worst case the item contains the next selected menu item and the workbench will process both of them. There is at least no race that follows invalid pointers and will crash the system.

Quote:
Originally Posted by PeterK View Post


Yes, I should better stop writing hacky programs for the Amiga that don't care about the rules. They just seem to work, better nobody ever tries to use them!
It would certainly be better because we would have a more stable system then. Sure, 3.1 has plenty of bugs, but it doesn't get better by adding more to them.
Thomas Richter is offline  
Old 25 February 2024, 09:15   #29
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by Thomas Richter View Post
Problem is - this idea is also not without quirks as two processes now potentially access the same data structure (namely the menu item) in parallel.
It's also Intuition itself which (or who's "design") makes some things not 100 % safe. Like this menu multi select stuff.

- User multiselects "Render" -> "Save"
- User selects "Render"

"Save" selection can get lost/forgotten. Slow/non responsive program may end up with two IDCMP_MENUPICK msgs in the queue and Intuition (because of user asynchronously accessing the menus) may modify item->nextselect while program has not yet done (or is in the middle of) handling the first menupick message.

Other things in Intuition are not 100 % safe either. Like string gadgets. User may asynchronously (in input.device task) modify string buffer contents, while programs is in the middle of accesing/reading the exact same buffer
aros-sg is offline  
Old 25 February 2024, 10:04   #30
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,231
Quote:
Originally Posted by aros-sg View Post
It's also Intuition itself which (or who's "design") makes some things not 100 % safe. Like this menu multi select stuff.

- User multiselects "Render" -> "Save"
- User selects "Render"

"Save" selection can get lost/forgotten. Slow/non responsive program may end up with two IDCMP_MENUPICK msgs in the queue and Intuition (because of user asynchronously accessing the menus) may modify item->nextselect while program has not yet done (or is in the middle of) handling the first menupick message.
While that is true, the result is not a disaster - that is, no invalid pointers are deferenced, and the system cannot go down. The worst thing that happens is that you miss a menu selection. That's probably ok.


Quote:
Originally Posted by aros-sg View Post
Other things in Intuition are not 100 % safe either. Like string gadgets. User may asynchronously (in input.device task) modify string buffer contents, while programs is in the middle of accesing/reading the exact same buffer
Again, sure, that can happen, but nothing will hang or crash if this happens. You get a half-edited string in worst case. Not a desaster. An alternative design would have been to copy the string into the IDCMP message, but that's neither a great design as you now need to dispose this memory again at some point.
Thomas Richter is offline  
Old 25 February 2024, 13:48   #31
aros-sg
Registered User
 
Join Date: Nov 2015
Location: Italy
Posts: 191
Quote:
Originally Posted by Thomas Richter View Post
Again, sure, that can happen, but nothing will hang or crash if this happens. You get a half-edited string in worst case.

Sure? If a stringgadget contains "12345678" and the program tries to read buffer and while doing that (it is at char "6") the buffer is modified to "1234" in input.device task (maybe through "Undo". stringadgets can have undobuffers) can it be sure that there is still a trailing 0-byte somewhere that will prevent it from reading past the string buffer size? The undo buffer may be "1234\0" and contain trash after that and what if the undo buffer is copied over to the string buffer using copymem() instead of strcpy() ...
aros-sg is offline  
Old 25 February 2024, 23:49   #32
PeterK
Registered User
 
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,366
Tried to take all the suggestions for a safer and more system friendly code into account now, and I'm glad that it still works.
Code:
                incdir  "include:"
                include "exec/execbase.i"
                include "exec/initializers.i"
                include "exec/memory.i"
                include "dos/dos.i"
                include "dos/dosextens.i"
                include "intuition/intuition.i"
                include "workbench/workbench.i"
                include "lvo/LVOs.i"

_LVOPrivateOpenLibrary  EQU -$32A               ; _LVOexecPrivate17

main            MOVEA.L (4).w,A6                ; execbase
                BTST.B  #AFB_68020,AttnFlags+1(A6)
                BNE.S   .cpuisok
                MOVEQ   #RETURN_FAIL,D0
                RTS

                DC.B    "$VER: WBMenuTest 1.2",0

                CNOP    0,2                     ; 2024 by Peter Keunecke

.cpuisok        MOVEA.L ThisTask(A6),A0
                LEA     pr_MsgPort(A0),A5
                TST.L   pr_CLI(A0)              ; from CLI or WB ?
                BNE.S   .openlibs
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOWaitPort(A6)        ; wait for startup
                MOVE.L  D0,-(SP)                ; save WB message
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOGetMsg(A6)          ; remove Msg from port
                PEA     .replyWBmsg(PC)         ; WB patch for RTS from CLI calls
.openlibs       MOVEQ   #RETURN_ERROR,D2
                MOVEQ   #3,D0
                JSR     _LVOPrivateOpenLibrary(A6)
                MOVE.L  D0,D5                   ; intuibase
                BEQ.W   .itfailure
                LEA     WBPubScreenName(PC),A0  ; "Workbench"
                MOVEA.L D5,A6                   ; intuibase
                JSR     _LVOLockPubScreen(A6)
                MOVE.L  D0,D6
                BEQ.W   .wbfailure
                MOVEQ   #0,D0                   ; LockNumber
                JSR     _LVOLockIBase(A6)
                MOVE.L  D0,D7
                MOVEA.L D6,A0                   ; WB screen
                MOVE.L  sc_FirstWindow(A0),D0
.trywindow      BEQ.S   .returnnow
                MOVEA.L D0,A2
                MOVE.L  wd_Flags(A2),D0         ; check bit 25 for WFG_WBENCHWINDOW
                LSL.L   #6,D0
                BMI.S   .windowptr
                MOVE.L  (A2),D0                 ; wd_NextWindow
                BRA.S   .trywindow

.returnnow      MOVEA.L D7,A0                   ; lock on IBase
                JSR     _LVOUnlockIBase(A6)
                BRA.W   .unlockpub

.windowptr      MOVE.L  wd_IDCMPFlags(A2),D0
                LSL.W   #2,D0                   ; check bit 13 for IDCMP_MENUVERIFY
                BMI.S   .returnnow
                MOVE.L  wd_MenuStrip(A2),D0     ; first menu in WB menu strip
                BEQ.S   .returnnow
                MOVEA.L D0,A3                   ; A3 = menu strip = menu 0
                MOVE.L  mu_FirstItem(A3),D0     ; item 0 ?
                BEQ.S   .returnnow
                MOVEQ   #3,D1
.nextitem       MOVEA.L D0,A4                   ; item 0 - 3
                MOVE.L  (A4),D0                 ; next ?
                BEQ.S   .returnnow
                DBRA    D1,.nextitem            ; A4 = item 3 should be "Update all"
                MOVEA.L D0,A0                   ; item 4
                MOVE.L  (A0),D0                 ; item 5 ?
                BEQ.S   .returnnow
                MOVEA.L D0,A0                   ; is item 5 "Version, Copyright ..."
                CMPI.B  #"?",mi_Command(A0)     ; with the "?" as a shortcut key ?
                BNE.S   .returnnow              ; if not, we won't touch this menu
                LEA     MsgMenuRescanAll\.im_IDCMPWindow(PC),A0
                MOVE.L  A2,(A0)                 ; IDCMPWindow = Workbench WindowPtr

                MOVEA.L (4).w,A6                ; execbase
                JSR     _LVOForbid(A6)
                MOVEA.L D7,A0                   ; lock on IBase
                MOVEA.L D5,A6                   ; intuibase
                JSR     _LVOUnlockIBase(A6)

                MOVEA.L A2,A0                   ; WB window
                JSR     _LVOClearMenuStrip(A6)
                ORI.W   #MENUENABLED,mu_Flags(A3)
                ORI.W   #ITEMENABLED,mi_Flags(A4)
                MOVE.W  #MENUNULL,mi_NextSelect(A4) ; this was set to NULL by the OS
                MOVEA.L A2,A0                   ; WB window
                MOVEA.L A3,A1                   ; menu strip
                JSR     _LVOSetMenuStrip(A6)
                MOVEA.L A2,A0                   ; WB window
                JSR     _LVOActivateWindow(A6)

                LEA     MsgMenuRescanAll\.mn_ReplyPort(PC),A0
                MOVE.L  A5,(A0)                 ; pr_MsgPort
                MOVEA.L wd_UserPort(A2),A0      ; IDCMP receiver for Workbench
                LEA     MsgMenuRescanAll(PC),A1 ; message: MENUPICK, MENU_RESCAN_ALL
                MOVEA.L (4).w,A6                ; execbase
                JSR     _LVOPutMsg(A6)
                JSR     _LVOPermit(A6)

                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOWaitPort(A6)        ; wait for reply from Workbench
                MOVEA.L A5,A0                   ; pr_MsgPort
                JSR     _LVOGetMsg(A6)          ; remove Msg from port
                MOVEQ   #RETURN_OK,D2
.unlockpub      SUBA.L  A0,A0                   ; no screen name supplied
                MOVEA.L D6,A1                   ; WB screen from lock
                MOVEA.L D5,A6                   ; intuibase
                JSR     _LVOUnlockPubScreen(A6)
.wbfailure      MOVEA.L D5,A1                   ; intuibase
                MOVEA.L (4).w,A6                ; execbase
                JSR     _LVOCloseLibrary(A6)
.itfailure      MOVE.L  D2,D0
                RTS                             ; CLI ends here, on WB to .replyWBmsg

.replyWBmsg     JSR     _LVOForbid(A6)
                MOVEA.L (SP)+,A1
                JSR     _LVOReplyMsg(A6)        ; WB unloads seglist
                MOVE.L  D2,D0                   ; set the final RC
                RTS                             ; return from WB tool


MENU_RESCAN_ALL EQU	(0 & $1F) | ((3 & $3F) << 5) | (($1F & $1F) << 11)

MsgMenuRescanAll
.ln_Succ        DC.L    0
.ln_Pred        DC.L    0
.ln_Type        DC.B    0
.ln_Pri         DC.B    0
.ln_Name        DC.L    0
.mn_ReplyPort   DC.L    0                       ; filled out at program start
.mn_Length      DC.W    $34
.im_Class       DC.L    IDCMP_MENUPICK
.im_Code        DC.W    MENU_RESCAN_ALL         ; Menu 0, Item 3, NoSub
.im_Qualifier   DC.W    0
.im_IAddress    DC.L    0
.im_MouseX      DC.W    0
.im_MouseY      DC.W    0
.im_Seconds     DC.L    0
.im_Micros      DC.L    0
.im_IDCMPWindow DC.L    0                       ; a WBENCHWINDOW
.im_SpecialLink DC.L    0

WBPubScreenName DC.B    "Workbench",0

                CNOP    0,4
PeterK is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Commodity that adds list of windows to WB menu? coldacid request.Apps 6 25 June 2020 15:24
ClassicWB Scalos Menu - Item Renaming Heywood project.ClassicWB 1 26 June 2019 15:50
Simplest way of creating a menu in WB? Foebane support.Apps 8 22 September 2018 19:46
IBrowse custom contextual menu item _amigan support.Apps 0 30 November 2012 17:13
scalos/wb top menu _psy project.ClassicWB 3 03 January 2011 13:32

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 20:33.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.12666 seconds with 14 queries