@HenryCase
an you talk me through the way OpenWindow() is used in OS 3.1 so that I can look at creating this separation based on how it actually works and not my basic interpretation of Amiga API guides from the Internet.
Uhm... You can not learn it from API guides. Essentially because many actions are not done through API. For example windows can have UserPort. This is allocated by operating system or by application and sometimes there is no UserPort at all. Sometimes application creates its own UserPorts and pokes this into struct Window and Intuition starts using it when you call ModifyIDCMP(). To make things even more complex it is perfectly legal that application A opens a window, application B supplies UserPort to that window and application C manages this window (maybe drawing something). And then there is Intuition task called input.device which manages all windows. You can not assume anything about ownership of that window and its associated structures.
Similarly you can not know who is really going to use memory allocated by AllocMem() or malloc() (in the end malloc() calls AllocMem()). On Amiga you can share all memory allocated by AllocMem()/malloc(), you can even share your code and structures allocated from the stack. There is no absolutely privacy on Amiga. Everything you do is exposed to other applications and both applications and kernel exploit this.
Especially Kickstart 2.0 added many aspects to API which make adding MP even more difficult than it was for Kickstart 1.3.
I should also remind you that OpenWindow() is only one of those few hundred functions which should change to introduce memory protection. Even message passing system in Amiga is flawed in this sense.
To put it short Amiga API is completely broken and can not get fixed. If you want MP, that is
