Aros/開發人員/文件/庫/Intuition
- V34 = Amiga OS1.3
- V36 = Amiga OS2.x
- V37 = Amiga OS3.0
- V40 = Amiga OS3.1 AROS 開始相容級別
- V44 = Amiga OS3.5 OS3.9
- V45 = Amiga OS4
典型的應用程式或遊戲將涉及...
- 設定任何庫、螢幕、視窗。
- 設定任何需要的基於直覺的小部件、選單和請求器或 Zune(基於 mui)小部件、選單和請求器。
- Wait() 等待來自 Intuition/Zune 關於使用者活動或其他事件的訊息。
- 從訊息中複製所需資料,並透過回覆告訴 Intuition/Zune 你已經收到它。檢視資料並採取相應的行動。例如(按鍵盤上的鍵,移動滑鼠,點選小部件,選擇選單項,時間流逝,插入磁碟,移除磁碟,以及視窗重新排列)。
- 重複,直到使用者想要退出。(然後關閉視窗、螢幕和庫)
大多數情況下,你不需要設定螢幕,因為你經常會使用已經使用的公共螢幕(漫遊者、Scalos 或其他 WB 替代品),因此你可以跳過在該螢幕上開啟視窗。
AROS(像之前的 Amigas 一樣)支援稱為螢幕的概念,每個螢幕都可以設定特定的解析度和顏色深度,受使用的顯示器驅動程式或 CRT 或 LCD 顯示器限制。
- 自己的公共螢幕,主應用程式可以在其中“託管”具有相同螢幕規格等的附加模組,如果需要。
- 預設的共享公共螢幕(通常稱為漫遊者、Scalos 或 Workbook)表示多個應用程式駐留在同一個螢幕上,這可以節省記憶體。
- 最後一種選擇是自定義螢幕,為每個應用程式建立一個新的顯示,例如,如果你想要特定的解析度和顏色深度。開啟任何新的螢幕都會使用記憶體。
下面是已經設定在 AROS 中的公共結構,它是一個模板,可以在程式設計中快速使用。
struct Screen {
struct Screen *NextScreen; /* linked list of screens */
struct Window *FirstWindow; /* linked list Screen's Windows */
WORD LeftEdge, TopEdge; /* parameters of the screen */
WORD Width, Height; /* parameters of the screen */
WORD MouseY, MouseX; /* position relative to upper-left */
UWORD Flags; /* see definitions below */
UBYTE *Title; /* null-terminated Title text */
UBYTE *DefaultTitle; /* for Windows without ScreenTitle */
/* Bar sizes for this Screen and all Window's in this Screen */
BYTE BarHeight, BarVBorder, BarHBorder, MenuVBorder, MenuHBorder;
BYTE WBorTop, WBorLeft, WBorRight, WBorBottom;
struct TextAttr *Font; /* this screen's default font */
/* the display data structures for this Screen */
struct ViewPort ViewPort; /* underlying graphics struct for each screen (&my_screen->ViewPort) */
struct RastPort RastPort; /* allow direct rendering into the screen (not useful) &my_screen->RastPort) */
struct BitMap BitMap; /* Screen->RastPort.BitMap in place of &Screen->BitMap whenever possible */
struct Layer_Info LayerInfo; /* each screen gets a LayerInfo */
/* Only system gadgets may be attached to a screen. The standard system Screen Gadgets automatically */
struct Gadget *FirstGadget;
UBYTE DetailPen, BlockPen; /* for bar/border/gadget rendering */
/* the following variable(s) are maintained by Intuition to support the DisplayBeep() color flashing technique */
UWORD SaveColor0;
/* This layer is for the Screen and Menu bars */
struct Layer *BarLayer;
UBYTE *ExtData;
UBYTE *UserData; /* general-purpose pointer to User data extension */
};
每一行都會新增並存儲一些關於正在使用的螢幕的資訊。Screen 結構內的每個附加結構都是 AROS 內已經存在的預定義資料儲存的“塊”。許多 AROS 依賴於結構在更新的結構中使用,以幫助和加快開發。
每個螢幕都有一個 ViewPort 結構(螢幕由圖形庫表示),每個螢幕都有一個 drawinfo(高階)和一個 RastPort 結構(圖形庫用來在該螢幕上繪圖的低階控制代碼)。View 是整個顯示,包括所有可見的螢幕,透過 ViewAddress() 訪問。
標籤是引數名稱後跟逗號,然後是值。例如,要指定螢幕的 DefaultTitle,可以使用 SA_Title 後跟逗號,然後是引號內的標題,還有許多其他標籤可以用來定義螢幕的位,稍後將列出。最後一個標籤項始終應該是 TAG_DONE。
螢幕的標題欄,而不是視窗的標題欄,是在視窗前面繪製的。如果將視窗從預設的 0,0 位置移動,使用 WA_Top 和/或 WA_Left(SA_ShowTitle 為 FALSE 當然),在全屏模式下,只需忽略這些標籤,而不要將它們設定為 0。
// Opens a PubScreen. The name can be given as argument.
// Default name is "MYPUBSCREEN".
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <stdio.h>
struct Screen *myscreen;
struct Window *mywindow;
BYTE signalnum;
void clean_exit(STRPTR txt)
{
if (mywindow) CloseWindow(mywindow);
if (myscreen) CloseScreen(myscreen);
FreeSignal(signalnum);
if (txt)
{
PutStr(txt);
exit(RETURN_FAIL);
}
exit(RETURN_OK);
}
int main(int argc, char **argv)
{
BOOL done = FALSE;
BOOL closewindow = FALSE;
ULONG signals, winsig, pubsig;
struct IntuiMessage *message;
char *name;
if (argc == 2)
{
name = argv[1];
}
else
{
name = "MYPUBSCREEN";
}
if ((signalnum = AllocSignal(-1)) == -1)
{
clean_exit("Can't allocate signal\n");
}
if
(
(
myscreen = OpenScreenTags
(
NULL,
SA_PubName, name,
SA_PubSig, signalnum,
SA_LikeWorkbench, TRUE,
SA_Title, name,
TAG_DONE
)
) == NULL
)
{
clean_exit("Can't open screen\n");
}
if
(
(
mywindow = OpenWindowTags
(
NULL,
WA_Left, 30,
WA_Top, 30,
WA_Width, 250,
WA_Height, 100,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_Activate, TRUE,
WA_Title, "Close me to close the screen",
WA_IDCMP, IDCMP_CLOSEWINDOW,
WA_PubScreen, myscreen,
TAG_DONE
)
) == NULL
)
{
clean_exit("Can't open window\n");
}
if ((PubScreenStatus(myscreen, 0) & 1) == 0)
{
clean_exit("Can't make screen public");
}
winsig = 1L << mywindow->UserPort->mp_SigBit;
pubsig = 1L << signalnum;
while (!done)
{
signals = Wait(winsig | pubsig);
if (mywindow && (signals & winsig))
{
while (NULL != (message = (struct IntuiMessage *)GetMsg(mywindow->UserPort)))
{
if (message->Class == IDCMP_CLOSEWINDOW)
{
closewindow = TRUE;
}
ReplyMsg((struct Message *)message);
}
}
if (signals & pubsig)
{
if (PubScreenStatus(myscreen, PSNF_PRIVATE) & 1)
{
done = TRUE;
}
else
{
PutStr("Failed to make screen private\n");
}
}
if (closewindow)
{
if (mywindow) CloseWindow(mywindow);
winsig = 0;
mywindow = NULL;
closewindow = FALSE;
}
}
clean_exit(NULL);
return 0;
}
#include <proto/intuition.h>
#include <proto/dos.h>
#include <intuition/screens.h>
int main() {
/* makes a copy of the Screen struct(ure) and calls that copy myScreen, changes are made to this copy */
struct Screen *myScreen;
/* you can call the copy 'myScreen' any name you like, as long as you use it throughout the program consistently */
/* describe how 'myScreen' looks like by using tags SA_? */
myScreen = OpenScreenTags(NULL,
SA_Left, 0, SA_Top, 0, SA_Width, 640, SA_Height, 480,
SA_Depth, 8, SA_Title, "My New Screen",
SA_Type, PUBLICSCREEN,
SA_SysFont, 1,
TAG_DONE);
Delay(500);
/* check if screen open, returns TRUE for success and FALSE for failure, if so, use CloseScreen() command to close */
if (myScreen) CloseScreen(myScreen);
}
#include <proto/intuition.h>
#include <proto/dos.h>
#include <intuition/screens.h>
#include <proto/graphics.h>
int main (void)
{
struct Screen *scr;
struct Window *win;
struct RastPort *rp;
if (scr = OpenScreenTags (NULL,SA_LikeWorkbench,TRUE,TAG_END)) /* open RTG screen */
{
Delay (50); /* one second */
if (win = OpenWindowTags (NULL,
WA_CustomScreen,scr,
WA_Left,100,WA_Top,100,
WA_Width,200,WA_Height,100,
TAG_END))
{
rp = win->RPort;
Move (rp,20,40);
Text (rp,"Beep !",6); /* you won't see DisplayBeep on a RTG screen */
Delay (50); /* one second */
CloseWindow (win);
}
Delay (100); /* two seconds */
CloseScreen (scr);
}
return (0);
}
如果你不希望使用自定義螢幕,那麼可以使用現有的公共螢幕,例如漫遊者。螢幕可以隨時關閉,所以為了防止這種情況,應用程式執行時應該鎖定公共螢幕。你可以使用 LockPubScreen 函式來實現這一點。
myScreen = LockPubScreen(name)
其中 name 是要鎖定的公共螢幕的名稱。如果未提供名稱(NULL),則它將使用工作臺公共螢幕。完成對公共螢幕的操作後,你可以解鎖它。
UnlockPubScreen(NULL, myScreen);
#include <proto/intuition.h>
#include <intuition/screens.h>
#include <proto/dos.h>
#include <stdio.h>
int main(void) {
struct Screen *myScreen;
if (myScreen = LockPubScreen(NULL)) {
printf("Public Screen locked.\n");
Delay(100);
UnlockPubScreen(NULL, myScreen);
printf("Public Screen unlocked.\n");
}
return 0;
}
if ((scr->screen = LockPubScreen(PROGNAME)))
{
scr->screentype = PUBLICSCREEN;
success = TRUE;
scr->modeID = GetVPModeID(&scr->screen->ViewPort);
}
else
{
if (id != INVALID_ID)
{
UWORD empty = 0xffff;
if ((scr->screen = OpenScreenTags(NULL,
SA_Width, width,
SA_Height, height
SA_Depth, depth,
SA_DisplayID, id,
SA_Type, PUBLICSCREEN,
SA_AutoScroll, TRUE,
SA_Title, (IPTR)PROGNAME,
SA_PubName, (IPTR)PROGNAME,
SA_ShowTitle, FALSE,
SA_LikeWorkbench, TRUE,
SA_FullPalette, TRUE,
SA_SharePens, TRUE,
SA_Pens, (IPTR)&empty,
TAG_DONE)))
{
PubScreenStatus(scr->screen, 0);
scr->screentype = CUSTOMSCREEN;
scr->modeID = id;
success = TRUE;
}
}
}
if (defscreen)
{
UnlockPubScreen(NULL, defscreen);
}
}
//else
if (!success)
{
if (!success)
{
if (mvs->scropenmode == SCROPENMODE_PUBLIC)
{
if ((scr->screen = LockPubScreen(mvs->pubscreen)))
{
ScreenToFront(scr->screen);
success = TRUE;
}
}
}
if (!success)
{
success = !!(scr->screen = LockPubScreen(NULL));
}
if (success)
{
scr->screentype = PUBLICSCREEN;
scr->modeID = GetVPModeID(&scr->screen->ViewPort);
}
}
SA_Left - Default is 0
SA_Top - Default is 0
SA_Width - Default depends on display
SA_Height - Default depends on display
SA_Depth - Select depth of screen. This specifies how many colors the screen can display. Default 1
SA_DetailPen - Pen number for details. Default is 0 (obsolete)
SA_BlockPen - Pen number for block fills. Default is 1 (obsolete)
SA_Title (STRPTR) - Default NULL
SA_Font (struct TextAttr *) - user's preferred monospace font. Default NULL
SA_BitMap (struct BitMap *) - Provide a bitmap
SA_ShowTitle (BOOL) - Default TRUE
SA_Behind (BOOL) - Screen will be created behind other open screens. Default is FALSE
SA_Quiet (BOOL) - Intuition does not draw any system gadgets and screen title. Defaults is FALSE
SA_Type - PUBLICSCREEN or CUSTOMSCREEN
SA_DisplayID - 32-bit display mode ID
SA_Overscan - Set an overscan mode. Possible values OSCAN_TEXT (default) - OSCAN_STANDARD - OSCAN_MAX - OSCAN_VIDEO
SA_DClip (struct Rectangle *) - Define a DisplayClip region - see SA_Overscan above
SA_AutoScroll (BOOL) - Screens can be larger than the DisplayClip region. Set this tag TRUE if automatic scrolling
SA_PubName (STRPTR) - Make this screen a public screen with the given name. Screen is opened in "private" mode
SA_PubTask (struct Task *) - Task to be signalled, when last visitor window of a public screen is closed
SA_PubSig (UBYTE) - Signal number used to notify a task when the last visitor window of a public screen is closed
SA_Colors (struct ColorSpec *) - Screen's initial color palette. Array must be terminated with ColorIndex = -1
SA_FullPalette (BOOL) - Intuition maintains a set of 32 preference colors. Default is FALSE
SA_ErrorCode (ULONG *) - OSERR_NOMONITOR, OSERR_NOCHIPS, OSERR_NOMEM, OSERR_NOCHIPMEM, OSERR_PUBNOTUNIQUE, OSERR_UNKNOWNMODE, OSERR_TOODEEP, OSERR_ATTACHFAIL
SA_SysFont - Select screen font type. overwrites SA_Font. 0=Fixed-width font, 1=Font set by font prefs
SA_Parent (struct Screen *) - Attach the screen to the given parent screen
SA_FrontChild (struct Screen *) - Attach given child screen to this screen
SA_BackChild (struct Screen *) - Attach given child screen to this screen
SA_BackFill (struct Hook *) - Backfill hook (see layers library)
SA_Draggable (BOOL) - Make screen movable. Default is TRUE
SA_Exclusive (BOOL) - False (default) but if TRUE screen must not share the display with other screens
SA_Pens (UWORD *) - Define the pen array for struct DrawInfo. This enables the 3D look - terminates with 0
SA_SharePens (BOOL) - if FALSE (default) obtains the pens of a public screen with PENF_EXCLUSIVE. if TRUE pens are not set
SA_Colors32 (ULONG *) - Data is sent to graphics.library/LoadRGB32(). Overwrites values which were set by SA_Colors
SA_Interleaved (BOOL) - Request interleaved bitmap. It this fails a non-interleaved bitmap will be allocated
SA_VideoControl (struct TagItem *) - Taglist which will be passed to VideoControl() after the screen is open
SA_ColorMapEntries = Number of entries of the ColorMap. Default 1<<depth, but not less than 32
SA_LikeWorkbench (BOOL) - Inherit depth, colors, pen-array, screen mode, etc. from the WB replacement screen
SA_MinimizeISG (BOOL) - Minimize the Inter-Screen Gap
下面是另一個已經設定在 AROS 中的公共結構,它是一個模板,可以在程式設計中快速使用。
struct Window
{
struct Window *NextWindow; /* for the linked list to next Window */
WORD LeftEdge, TopEdge, Width, Height; /* window dimensions */
WORD MouseY, MouseX; /* relative top top-left corner */
WORD MinWidth, MinHeight; /* minimum sizes */
UWORD MaxWidth, MaxHeight; /* maximum sizes */
ULONG Flags;
struct Menu *MenuStrip; /* first in a list of menu headers */
UBYTE *Title; /* title text for the Window */
struct Requester *FirstRequest, *DMRequest; /* first in linked list of active reqs - the double-menu Requester */
WORD ReqCount; /* number of Requesters blocking this Window */
struct Screen *WScreen; /* this Window's Screen */
/* Each window has one RastPort but within each RastPort a BitMap pointer. */
struct RastPort *RPort;
BYTE BorderLeft, BorderTop, BorderRight, BorderBottom;
struct RastPort *BorderRPort;
struct Gadget *FirstGadget;
/* these are for opening/closing the windows */
struct Window *Parent, *Descendant;
/* sprite data information for your own Pointer set these AFTER you Open the Window by calling SetPointer() */
UWORD *Pointer;
BYTE PtrHeight, PtrWidth;
BYTE XOffset, YOffset;
/* the IDCMP Flags and User's and Intuition's Message Ports */
ULONG IDCMPFlagS;
struct MsgPort *UserPort, *WindowPort;
struct IntuiMessage *MessageKey;
UBYTE DetailPen, BlockPen;
/* the CheckMark is a pointer to the imagery that will be used when rendering MenuItems of this Window checkmarked - if this is equal to NULL, you'll get the default imagery */
struct Image *CheckMark;
/* if non-null, Screen title when Window is active */
UBYTE *ScreenTitle;
WORD GZZMouseX, GZZMouseY, GZZWidth, GZZHeight;
; general-purpose pointer to User data extension
UBYTE *ExtData;
BYTE *UserData;
struct Layer *WLayer; /* stash of Window.RPort->Layer */
struct TextFont *IFont;
ULONG MoreFlags;
};
設定好屏幕後,你可以在該螢幕上建立任意數量的視窗。
開啟視窗與開啟螢幕非常相似,OpenWindowTags() 以及視窗標籤...
螢幕標籤以 SA_ 開頭,視窗標籤以 WA_ 開頭,而 WA_IDCMP 和 WA_Flags 則有進一步的子標籤。列表將在後面給出...
因此,當我執行 window->Width / rport->TxWidth 時,列數最終會大於可見區域,因此文字會超出螢幕,高度也是如此。有沒有辦法獲取視窗大小減去附加的小部件/工具的大小?對於非無邊框視窗(即普通視窗),可用寬度為 w->Width - w->BorderLeft - w->BorderRight,高度為 w->Height - w->BorderTop - w->BorderBottom。
對於 GimmeZeroZero 視窗,使用 w->GZZWidth 和 w->GZZHeight 代替 w->Width 和 w->Height。GZZWidth 和 GZZHeight 也為非 GZZ 視窗維護。您無需自己計算它們。
要能夠調整視窗大小,您需要設定 WA_MinWidth、WA_MinHeight、WA_MaxWidth 和 WA_MaxHeight,因為它們都預設設定為 WA_Width 或 WA_Height。
對於 AROS,您應該省略所有常見的 #?Base(GfxBase、IntuitionBase、DOSBase 等)宣告以及它們對應的“OpenLibrary() & CloseLibrary()”呼叫,因為 AROS GCC 編譯器會在看到引用時自動為您開啟和關閉它們。大多數核心庫會由編譯器自動開啟。
這僅供背景知識。開啟庫時,它將返回指向庫結構或該庫的特定基礎結構的指標,否則將返回 NULL 值。轉換舊的 Commodore 示例可能是瞭解 Amiga 程式與 AROS 程式差異的好方法。注意,由於 OpenLibrary、CloseLibrary 和 #?base 的問題,這些舊示例需要編輯... 過去,要關閉庫,請使用 CloseLibrary() 函式並提供在 OpenLibrary() 中返回的指向庫或基礎結構的指標。通常的做法是在嘗試關閉庫之前測試它是否已開啟。
請參閱 AROS 網站示例、Aros/Developer/Docs/Examples/SimpleWindowIntuition 和 這裡
#include <proto/exec.h>
#include <exec/libraries.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <intuition/intuition.h>
int main(int argc, char *argv[])
{
int error = RETURN_OK;
/* makes a copy of the Window struct(ure) and calls that copy win, changes are made to this copy */
struct Window *win;
/* describe the copy window 'win' looks like by using tags WA_?, this is separate from the struct stuff above */
win = OpenWindowTags
(
NULL, WA_Width, 200, WA_Height, 100,
WA_Title, "Hello World!", TAG_DONE
);
if( win )
{
/* Now wait for two seconds, so we can look at our nice window.
*/
Delay(100);
/* We close our window again. */
CloseWindow(win);
}
return error;
}
struct TagItem + OpenWindowTagList() Open a window. Not used much see below... OpenWindowTags() Alternate calling sequence for OpenWindowTagList(). CloseWindow() Close a window. BeginRefresh() Turn on optimized window refresh mode. EndRefresh() Turn off optimized window refresh mode. RefreshWindowFrame() Redraw the borders and border gadgets of an open window. ActivateWindow() Make an open window active. SizeWindow() Change the size of an open window. MoveWindow() Change the position of an open window. ChangeWindowBox() Change the size and position of an open window. WindowLimits() Change the minimum and maximum sizes of an open window. WindowToBack() Move a window behind all other windows. WindowToFront() Move a window in front of all other windows. MoveWindowInFrontOf() Move a window in front of another window. ZipWindow() Change the size of window to its alternate size. SetWindowTitles() Change the window titles for the window and the screen. SetPointer() Set up a custom pointer to display whenever the window is active. ClearPointer() Restore the mouse pointer to its default imagery.
WA_Left - Left edge of the window
WA_Top - Top edge of the window
WA_Width - Width of the window
WA_Height - Height of the window
WA_DetailPen - Pen number for window details (obsolete)
WA_BlockPen - Pen number for filled blocks (obsolete)
WA_IDCMP - Define what events should send messages to your task
IDCMP_CLOSEWINDOW - Check if the Window Close button has been pressed. If so, then close down program
IDCMP_GADGETUP - Check to see if a Gadget has been pressed AND released
IDCMP_GADGETDOWN - Check to see if a Gadget has been pressed (but not released yet) - Not often used
IDCMP_MENUPICK - Check to see if a menu item has been selected
IDCMP_ACTIVEWINDOW - Check to see if Window has been activated (clicked on title bar)
IDCMP_MOUSEMOVE - Check if mouse moves (useful to keep track of x,y position)
IDCMP_NEWSIZE - Check to see if window has been resized
IDCMP_VANILLAKEY - Check to see if a key on keyboard has been pressed
IDCMP_RAWKEY -
IDCMP_NEWPREFS -
IDCMP_DISKINSERTED - Check to see if a floppy disk has been inserted, probably ready for saving
IDCMP_DISKREMOVED - message type is broadcast to all IDCMP that have this flag set, not just active win
IDCMP_INTUITICKS -
IDCMP_IDCMPUPDATE -
IDCMP_CHANGEWINDOW -
IDCMP_LONELYMESSAGE - system use only
WA_Flags -
WFLG_SIZEGADGET, WFLG_DRAGBAR, WFLG_DEPTHGADGET, WFLG_CLOSEGADGET
WFLG_BORDERLESS, WFLG_ACTIVATE, WFLG_NEWLOOKMENUS
WA_Gadgets (struct Gadget *) - Pointer to a linked list of gadgets (WB 2.0 only)
WA_Title (STRPTR) - Window title string
WA_CustomScreen (struct Screen *) - Open window on the given screen
WA_MinWidth
WA_MinHeight
WA_MaxWidth
WA_MaxHeight
WA_SizeGadget (BOOL) - Make window resizeable
WA_DragBar (BOOL) - Make window dragable
WA_DepthGadget (BOOL) - Add a depth gadget
WA_CloseGadget (BOOL) - Add a close gadget
WA_Backdrop (BOOL) - Create a window which is placed behind other windows
WA_ReportMouse (BOOL) - Store mouse position in struct Window
WA_NoCareRefresh (BOOL) - Use this if you don't want to be responsible for calling BeginRefresh()/EndRefresh()
WA_Borderless (BOOL) - Create borderless window
WA_Activate (BOOL) - Make this window the active one, i.e. it receives the input from mouse and keyboard
WA_RMBTrap (BOOL) - Set to TRUE if you want to get button events events for the right mouse button
WA_SimpleRefresh (BOOL) - Enable simplerefresh mode. Only specify if TRUE
WA_SmartRefresh (BOOL) - Enable smartrefresh mode. Only specify if TRUE
WA_SuperBitMap (struct BitMap *) - Create window with superbitmap refreshing, 0 to keep the current size as limit
WA_SizeBRight (BOOL) - Place size gadget in right window border
WA_SizeBBottom (BOOL) - Place size gadget in bottom window border
WA_GimmeZeroZero (BOOL) - Create a GimmeZeroZero window
WA_NewLookMenus (BOOL) - Use DrawInfo colors for rendering the menu bar
WA_ScreenTitle (STRPTR) - Screen title which is shown when window is active
WA_AutoAdjust (BOOL) - usually TRUE make the window to fit on the screen, wrt WA_MinWidth and WA_MinHeight
WA_InnerWidth
WA_InnerHeight - Dimensions of the interior region of the window - this restricts border gadgets
GACT_LEFTBORDER gadgets can't be GFLG_RELWIDTH if WA_InnerWidth is used
GACT_RIGHTBORDER gadgets must be GFLG_RELRIGHT if WA_InnerWidth is used
GACT_TOPBORDER gadgets can't be GFLG_RELHEIGHT if WA_InnerHeight is used
GACT_BOTTOMBORDER gadgets must be GFLG_RELBOTTOM if WA_InnerHeight is used
WA_PubScreen (struct Screen *) - Open the window on the public screen - NULL being WB replacement
WA_PubScreenName (STRPTR) - Open the window on the public screen (name)
WA_PubScreenFallBack (BOOL) - if TRUE fallback to default public screen if other public screen is not available
WA_Zoom (WORD *) - 4 WORDs set Left Top Width Height of the other zoom position - also adds zoom gadget
WA_MouseQueue - Limits the number of possible mousemove messages. Can be changed with SetMouseQueue()
WA_RptQueue - Limits the number of possible repeated IDCMP_RAWKEY, IDCMP_VANILLAKEY and IDCMP_IDCMPUPDATE messages
WA_BackFill (struct Hook *) - Function to be called for backfilling
WA_MenuHelp (BOOL) - Enables menuhelp. Pressing the help key during menu handling sends IDCMP_MENUHELP messages.
WA_NotifyDepth (BOOL) - If TRUE send IDCMP_CHANGEWINDOW events when window is depth arranged. Code field=CWCODE_DEPTH
WA_Checkmark (struct Image *) - Image to use as a checkmark in menus
WA_AmigaKey (struct Image *) - Image to use as the Amiga-key symbol in menus
WA_Pointer (APTR) - The pointer to associate with the window. Use NULL for the Preferences default pointer
WA_BusyPointer (BOOL) - Enable the Preferences busy-pointer. Default is FALSE
WA_PointerDelay (BOOL) - Set this to TRUE to delay change of the pointer image - prevents flickering
WA_HelpGroup (ULONG) - Get IDCMP_GADGETHELP messages from the active window and all other windows
WA_HelpGroupWindow (struct Window *) - Similar for WA_HelpGroup. Use the helpgroup of another window
WA_TabletMessages (BOOL) - Request extended tablet data - Default is FALSE
WA_ToolBox (BOOL) - Make this window a toolbox window
WA_Parent (struct Window *) - Make the window a child of the given window.
WA_Visible (BOOL) - Make window visible Default is TRUE
WA_Shape (struct Region *) -
WA_ShapeHook (struct Hook *) -
視窗可以接收發往它的事件。通常的做法是讓應用程式請求 Intuition 傳送訊息,這些訊息基於 Intuition 已處理的輸入事件。這些訊息稱為 IntuiMessages,是標準的 Amiga Exec 訊息,並且傳送到一個名為 Intuition Direct Communications Message Port(IDCMP)的埠。每個視窗都可能與它關聯一個 IDCMP。雖然 AmigaOS(TM) 從 Intuition 事件開始,但 AROS 也為向後相容性目的納入了這些事件,但建議使用 Zune,請參閱這裡 Zune
a) Wait for signal from the current Active Window b) If a signal has been sent, get the Message data structure c) Reply to the message, so that message is removed from the queue and is being dealt with. d) Determine the message class (or gadget or event) occurred by comparing class value with IDCMP flags e) Do some user processing with that event.
輸入 = 硬體裝置 -> HIDD 或 .device -> 事件處理程式 -> IDCMP 或控制檯 -> 應用程式
輸出 = 應用程式 -> 控制檯或 Intuition -> 圖形庫 -> 顯示器
應用程式將透過任何 Intuition 事件收到發往它的訊息。這些訊息(IntuiMessages)是標準的 Exec 訊息,並且傳送到一個名為 IDCMP 的埠。每個視窗都可能/將與它關聯一個 IDCMP(Window->UserPort)。鍵不會在視窗中自動工作。您必須透過 WA_IDCMP 標籤進行設定。
struct IntuiMessage
{
struct Message ExecMessage;
ULONG Class;
UWORD Code;
UWORD Qualifier;
APTR IAddress;
WORD MouseX, MouseY;
ULONG Seconds, Micros;
struct Window *IDCMPWindow;
struct IntuiMessage *SpecialLink;
};
- IDCMP_VANILLAKEY - 事件提供簡單的 ASCII 文字和標準控制鍵,如空格鍵、回車鍵和退格鍵
- IDCMP_RAWKEY - 返回所有按鍵程式碼,包括按鍵按下和鬆開,包括功能鍵(是指鍵盤、移動、工具(關閉/調整大小)和其他許多東西)
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
int main (void)
{
/* set up variables to be used in this function */
struct Window *win;
struct IntuiMessage *mess;
BOOL cont;
BOOL lbutton;
BOOL rbutton;
long old_x;
long old_y;
long x;
long y;
win = OpenWindowTags (NULL,
WA_Left,112,
WA_Top,84,
WA_Width,800,
WA_Height,600,
WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_RMBTRAP | WFLG_REPORTMOUSE | WFLG_ACTIVATE | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE,
WA_MinWidth,80,WA_MinHeight,40,
WA_MaxWidth,-1,WA_MaxHeight,-1,
TAG_END);
/* if (win==NULL) { */
if (!win)
{
Printf ("cannot open window\n");
return (RETURN_FAIL);
}
rbutton = FALSE;
lbutton = FALSE;
x = win->MouseX;
y = win->MouseY;
old_x = x;
old_y = y;
cont = TRUE;
do {
if (Wait ((1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
cont = FALSE;
while (mess = (struct IntuiMessage *) GetMsg (win->UserPort))
{
switch (mess->Class)
{
case IDCMP_MOUSEMOVE:
x = mess->MouseX - win->BorderLeft;;
y = mess->MouseY - win->BorderTop;
break;
case IDCMP_MOUSEBUTTONS:
switch (mess->Code)
{
case SELECTDOWN:
lbutton = TRUE;
break;
case SELECTUP:
lbutton = FALSE;
break;
case MENUDOWN:
rbutton = TRUE;
break;
case MENUUP:
rbutton = FALSE;
break;
}
break;
case IDCMP_VANILLAKEY:
if (mess->Code == 0x1b) /* Esc */
cont = FALSE;
break;
case IDCMP_CLOSEWINDOW:
cont = FALSE;
break;
}
ReplyMsg ((struct Message *)mess);
}
if (x != old_x || y != old_y)
{
if (rbutton && lbutton)
{
SetAPen (win->RPort,3);
Move (win->RPort,old_x,old_y);
Draw (win->RPort,x,y);
}
else if (rbutton)
{
SetAPen (win->RPort,2);
Move (win->RPort,old_x,old_y);
Draw (win->RPort,x,y);
}
else if (lbutton)
{
SetAPen (win->RPort,1);
Move (win->RPort,old_x,old_y);
Draw (win->RPort,x,y);
}
old_x = x;
old_y = y;
}
}
while (cont);
CloseWindow (win);
return (RETURN_OK);
}
- 在這裡瞭解有關按鍵程式碼的更多資訊 https://wikibook.tw/wiki/Aros/Developer/Docs/Libraries/Keymap
/* loop for each frame */
while (loop) {
/* check for input */
while ((msg = (struct IntuiMessage *)GetMsg (w->UserPort)) != NULL) {
/* After we have successfully collected the message we can read */
/* it, and save any important values which we maybe want to check later */
class = msg->Class; /* IDCMP flag */
code = msg->Code;
/* After we have read it we reply as fast as possible: */
/* REMEMBER! Do never try to read a message after you have replied! */
/* (Some other process has maybe changed it.) */
ReplyMsg ((struct Message *)msg);
switch (class) {
case IDCMP_VANILLAKEY:
switch (code) {
case 0x03: /* CTRL/C */
case 0x1b: /* ESC */
case 'q': /* q */
case 'Q': /* Q */
break;
default:
break;
}
break;
case IDCMP_RAWKEY:
switch (code) {
case 0x11: /* W */
break;
case 0x20: /* A */
break;
case 0x21: /* S */
break;
case 0x22: /* D */
break;
case 0x50: /* F1 */
break;
case 0x51: /* F2 */
break;
case 0x52: /* F3 */
break;
case 0x53: /* F4 */
break;
case 0x54: /* F5 */
break;
case 0x55: /* F6 */
break;
case 0x56: /* F7 */
break;
case 0x57: /* F8 */
break;
case 0x58: /* F9 */
break;
case 0x59: /* F10 */
break;
default:
break;
}
break;
case IDCMP_MOUSEBUTTONS:
if (code == MENUDOWN)
loop = FALSE;
break;
default:
break;
}
}
基本上,建立了一個 IDCMP 迴圈來檢查使用者輸入和/或計時器事件。然後您可能設定了一個計時器裝置呼叫,該呼叫將為您提供這些事件。您必須使用 IDCMP_INTUITICKS(“滴答”每秒大約十次)更新您的視窗內容。這些滴答事件應作為喚醒呼叫使用,而不是作為計時器使用。
case IDCMP_GADGETUP:
gadget_down_happened=FALSE;
break;
case IDCMP_GADGETDOWN:
gadget_down_happened=TRUE;
break;
case IDCMP_INTUITICKS:
if(gadget_down_happened) {
update_window_contents();
}
break;
case IDCMP_INTUITICKS:
/*
* If the user is NOT holding the LMB down, then we'll
* report this event back to the program in order not to confuse
* the select box drawing routines.
*/
if( !(imsg->Qualifier & IEQUALIFIER_LEFTBUTTON))
method = GID_DW_INTUITICKS;
break;
當然,您可能只想在每 3 個 Intuition 滴答中更新一次內容,例如,並且僅在比例工具已更改時更新。
Intuition 中定義的舊式和新式數位板事件
系統對數位板的支援始於 WB 2.x。當時,數位板驅動程式應該將資訊作為事件傳送到輸入裝置,例如 (X,Y) 範圍和座標以及壓力。這種方法現在被稱為舊式數位板事件。
從 WB3.0 開始,定義了一種新型數位板事件來支援更多數位板功能,例如接近度、傾斜度等。這種方法被稱為新式數位板事件。
所有 IntuiMessages 現在都略微擴充套件了。ExtIntuiMessage 結構有一個用於數位板資料的額外欄位,該欄位通常為 NULL。如果系統中安裝了傳送 IESUBCLASS_NEWTABLET 事件的數位板驅動程式,則設定了 WA_TabletMessages 屬性的視窗將發現 eim_TabletData 指向 TabletData 結構。應用程式必須首先檢查該欄位是否非 NULL;對於某些型別的訊息(包括來自數位板以外的其他來源生成的滑鼠活動(即鍵盤等效項或滑鼠本身)),它將為 NULL。
struct IntuiMessage
{
struct Message ExecMessage;
ULONG Class;
UWORD Code;
UWORD Qualifier;
APTR IAddress;
WORD MouseX, MouseY;
ULONG Seconds, Micros;
struct Window *IDCMPWindow;
struct IntuiMessage *SpecialLink;
};
struct ExtIntuiMessage
{
struct IntuiMessage eim_IntuiMessage;
struct TabletData *eim_TabletData;
};
WA_TabletMessages - (BOOL)設定為 TRUE 以請求為您的視窗擴充套件 IntuiMessages。如果數位板驅動程式正在生成 IESUBCLASS_NEWTABLET 輸入事件,您將能夠使用大多數 IntuiMessages 接收擴充套件的數位板資訊。請參閱 ExtIntuiMessage 結構的 eim_TabletData 欄位。預設為 FALSE。(V39)
#define WA_TabletMessages TRUE
(WA_Dummy + 0x37)是一個布林值。設定為 TRUE 以請求將數位板資訊包含在傳送到您的視窗的 IntuiMessages 中。要求某些東西(即數位板驅動程式)將 IESUBCLASS_NEWTABLET InputEvents 提供給系統。要獲得指向 TabletData 的指標,請檢查 ExtIntuiMessage->eim_TabletData 欄位。
struct TabletData
{
UWORD td_XFraction;
UWORD td_YFraction;
ULONG td_TabletX;
ULONG td_TabletY;
ULONG td_RangeX;
ULONG td_RangeY;
struct TagItem * td_TagList; /* see below */
};
/* Tags */
#define TABLETA_Dummy (TAG_USER + 0x3A000)
#define TABLETA_TabletZ (TABLETA_Dummy + 0x01)
#define TABLETA_RangeZ (TABLETA_Dummy + 0x02)
#define TABLETA_AngleX (TABLETA_Dummy + 0x03)
#define TABLETA_AngleY (TABLETA_Dummy + 0x04)
#define TABLETA_AngleZ (TABLETA_Dummy + 0x05)
#define TABLETA_Pressure (TABLETA_Dummy + 0x06)
#define TABLETA_ButtonBits (TABLETA_Dummy + 0x07)
#define TABLETA_InProximity (TABLETA_Dummy + 0x08)
#define TABLETA_ResolutionX (TABLETA_Dummy + 0x09)
#define TABLETA_ResolutionY (TABLETA_Dummy + 0x0a)
struct TabletHookData
{
struct Screen * thd_Screen;
ULONG thd_Width;
ULONG thd_Height;
LONG thd_ScreenChanged;
};
Intuition 支援 IECLASS_NEWPOINTERPOS 事件的 IESUBCLASS_NEWTABLET 子類。此類事件的 ie_EventAddress 指向 TabletData 結構
TabletData 結構包含某些元素,包括一個標籤列表。標籤列表可用於特殊的數位板引數。數位板驅動程式應該只包含數位板支援的標籤項。應用程式可以監聽它感興趣的任何標籤項。注意:應用程式必須將 WA_TabletMessages 屬性設定為 TRUE 以在其 IntuiMessages 中接收此擴充套件資訊。
這裡給出的定義必須遵守。請仔細注意歸一化和符號的解釋。
TABLETA_TabletZ:數位板在 Z 方向上的當前值。此無符號值通常應該使用數位板的自然單位。您還應該提供 TABLETA_RangeZ。
TABLETA_RangeZ:數位板在 Z 方向上的最大值。通常與 TABLETA_TabletZ 一起指定,這允許應用程式在其範圍內縮放實際 Z 值。
TABLETA_AngleX:圍繞 X 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +X 方向看向原點時圍繞 X 軸的順時針旋轉。
TABLETA_AngleY:圍繞 Y 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +Y 方向看向原點時圍繞 Y 軸的順時針旋轉。
TABLETA_AngleZ:圍繞 Z 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +Z 方向看向原點時圍繞 Z 軸的順時針旋轉。
注意:支援傾斜的觸控筆應使用 TABLETA_AngleX 和 TABLETA_AngleY 屬性。將觸控筆傾斜使筆尖指向 X 軸增大或減小的方向實際上是繞 Y 軸旋轉。因此,如果觸控筆筆尖指向正 X 軸,則該傾斜表示為負 TABLETA_AngleY。同樣,如果觸控筆筆尖指向正 Y 軸,則該傾斜表示為正 TABLETA_AngleX。
TABLETA_Pressure:觸控筆的壓力讀數。壓力應規範化為填充有符號的長整型。典型裝置不會產生負壓力,但不能排除這種可能性。預計壓力閾值將在平板電腦供應商提供的偏好程式中設定,以被視為導致按鈕單擊。當壓力超過該閾值時,平板電腦驅動程式將傳送 IECODE_LBUTTON 型別的事件。
TABLETA_ButtonBits:ti_Data 是一個長整型,其位應被解釋為平板電腦前 32 個按鈕的狀態。
TABLETA_InProximity:ti_Data 是一個布林值。對於支援鄰近度的平板電腦,當觸控筆不在鄰近度內時,它們應該傳送 TABLETA_InProximity,FALSE} 標籤項。可以用作滑鼠空白商品,它以此為鍵來空白滑鼠。當此標籤不存在時,假設觸控筆在鄰近度內。
TABLETA_ResolutionX:ti_Data 是一個無符號長整型,表示以每英寸點數為單位的 X 軸解析度。
TABLETA_ResolutionY:ti_Data 是一個無符號長整型,表示以每英寸點數為單位的 Y 軸解析度。
struct IntuiText
{
UBYTE FrontPen, BackPen; /* the pen numbers for the rendering */
UBYTE DrawMode; /* the mode for rendering the text */
WORD LeftEdge; /* relative start location for the text */
WORD TopEdge; /* relative start location for the text */
struct TextAttr *ITextFont; /* if NULL, you accept the default */
UBYTE *IText; /* pointer to null-terminated text */
struct IntuiText *NextText; /* pointer to another IntuiText to render */
};
dri_Pens[TEXTPEN];
myBACKGROUNDPEN = drawinfo->dri_Pens[BACKGROUNDPEN];
/* create a TextAttr that matches the specified font. */
myTextAttr.ta_Name = drawinfo->dri_Font->tf_Message.mn_Node.ln_Name;
myTextAttr.ta_YSize = drawinfo->dri_Font->tf_YSize;
myTextAttr.ta_Style = drawinfo->dri_Font->tf_Style;
myTextAttr.ta_Flags = drawinfo->dri_Font->tf_Flags;
/* open a simple window on the workbench screen for displaying a text string.
An application would probably never use such a window, but it is useful for demonstrating graphics...
*/
if ((win = OpenWindowTags(NULL,
WA_PubScreen, (IPTR)screen,
WA_RMBTrap, TRUE,
WA_IDCMP, IDCMP_RAWKEY,
TAG_END)))
{
myIText.FrontPen = myTEXTPEN;
myIText.BackPen = myBACKGROUNDPEN;
myIText.DrawMode = JAM2;
myIText.LeftEdge = MYTEXT_LEFT;
myIText.TopEdge = MYTEXT_TOP;
myIText.ITextFont = &myTextAttr;
myIText.IText = "Hello, World. ;-)";
myIText.NextText = NULL;
/* Draw the text string at 10,10 */
PrintIText(win->RPort,&myIText,10,10);
/* Wait for keypress */
Wait (1L << win->UserPort->mp_SigBit);
CloseWindow(win);
}
FreeScreenDrawInfo(screen,drawinfo);
}
UnlockPubScreen(NULL,screen);
}
return 0;
}
儘管 AmigaOS(TM) 最初是基於直覺的選單、小工具、請求器和事件。
Amiga 引入了許多替代方案,如 GadTools、BOOPSI、ASL、BGui、ReqTools、ClassAct 和 MUI。AROS 選擇了 MUI 重寫(Zune)作為預設圖形使用者介面工具集,例如 Zune(MUI)選單。
本頁的其餘部分包含資訊(僅限基於直覺的內容),僅供向後相容使用。
如果你想定義自己的選單,我認為 intuition.library 也可以滿足你的需求,儘管選單最好留到後面再處理,因為我認為它們過於複雜且容易出錯。
對於選單欄中的每個主選單標題(即頂部選項),你為每個標題宣告一個 Menu 結構。對於選單中的每個專案或子專案,你為每個專案宣告一個 MenuItem 結構。你應該使用比 Menu 更多的 MenuItem。基於文字的選單需要一個額外的 IntuiText 結構,用於每個選單和(子)專案。(它們出現最多)。影像選單需要影像結構。
要使用選單,你需要使用 Menu 和 MenuItem 結構,然後將它們附加到視窗。請注意,IntuiTexts 和 Image 結構應該在呼叫它們的 MenuItem 結構之前定義。
struct Menu
{
struct Menu *NextMenu; /* same level */
WORD LeftEdge, TopEdge; /* position of the select box */
WORD Width, Height; /* dimensions of the select box */
UWORD Flags; /* flag definitions*/
BYTE *MenuName; /* text for this Menu Header */
struct MenuItem *FirstItem; /* pointer to first in chain */
};
struct MenuItem
{
struct MenuItem *NextItem; /* pointer to next in chained list */
WORD LeftEdge, TopEdge; /* position of the select box */
WORD Width, Height; /* dimensions of the select box */
UWORD Flags; /* see the defines below */
LONG MutualExclude; /* set bits mean this item excludes that */
IPTR ItemFill; /* points to Image, IntuiText, or NULL */
IPTR SelectFill; /* points to Image, IntuiText, or NULL */
BYTE Command; /* only if appliprog sets the COMMSEQ flag */
struct MenuItem *SubItem; /* if non-zero, points to MenuItem for submenu */
UWORD NextSelect; /* Menu no of next selected item when drag-selecting items */
};
struct Image
{
WORD LeftEdge; /* starting offset relative to some origin */
WORD TopEdge; /* starting offsets relative to some origin */
WORD Width; /* pixel size (though data is word-aligned) */
WORD Height;
WORD Depth; /* >= 0, for images you create */
UWORD *ImageData; /* pointer to the actual word-aligned bits */
UBYTE PlanePick, PlaneOnOff;
struct Image *NextImage;
};
要向視窗新增或刪除選單,你需要使用以下命令
BOOL SetMenuStrip( struct Window *window, struct Menu *menu )
void ClearMenuStrip( struct Window *window )
在定義並開啟視窗後使用 SetMenuStrip 命令,並提供視窗地址和連結列表中最後一個 Menu 結構的地址。在關閉視窗之前,你必須首先使用 ClearMenuStrip 命令從螢幕上刪除選單,然後再關閉視窗。將選單附加到視窗而不是螢幕,可以使你的程式具有靈活性,這樣如果你打開了多個視窗,你就可以自定義選單以適應相應的視窗,例如,在繪畫軟體或影片程式中,你可以擁有具有自己選單的較小視窗。
可以啟用或停用選單項,當你不想讓使用者訪問某個選單功能時。可以使用 OnMenu 和 OffMenu 函式來實現
void OffMenu( struct Window *window, unsigned long menuNumber)
void OnMenu( struct Window *window, unsigned long menuNumber )
只需提供要啟用或停用的專案的選單編號。如果你更改了選單項的 CHECKED 或 ITEMENABLED 值,那麼你可以使用 ResetMenuStrip 命令重新整理選單,該命令與使用 SetMenuStrip 命令類似,但速度更快。
AROS 支援幾種型別的請求器:原始系統(直覺)和 ASL、ReqTools 和 MUI(推薦)。直覺的 AutoRequest() 和 Request() 函式現在已棄用。
檔案請求器不會返回完整路徑嗎?需要額外的步驟。
EasyRequest() 提供了一種簡單的方法來建立一個請求器,允許使用者從有限數量的選擇中選擇一個。
LONG EasyRequest( struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR argl, ... );
LONG EasyRequestArgst struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR ergs );
struct EasyStruct
{
ULONG es_StructSize;
ULONG es_Flags;
UBYTE *es_Title;
UBYTE *es_TextFormat;
UBYTE *es_GadgetFormat;
};
也可以看看 這裡
int amiga_filereq(char *buffer, int len, ...)
{
va_list args;
LONG result;
if (FileReq == 0)
{
if ((FileReq = AllocAslRequestTags(ASL_FileRequest,
ASLFR_SleepWindow,1,
ASLFR_RejectIcons,1,TAG_DONE)) == 0)
{
return 0;
}
}
va_start(args,len);
result = AslRequest(FileReq,(struct TagItem *)args);
va_end(args);
if (result)
{
strncpy(buffer,FileReq->fr_Drawer,len);
AddPart(buffer,FileReq->fr_File,len);
return 1;
}
return 0;
}
/* Chaos: The Chess HAppening Organisation System V5.3
Copyright (C) 1993 Jochen Wiedmann
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$RCSfile: ProjectAmi.c,v $
$Revision: 3.4 $
$Date: 1994/11/19 19:32:01 $
This file contains the system dependent functions that support the
Project menu.
Computer: Amiga 1200 Compiler: Dice 2.07.54 (3.0)
Author: Jochen Wiedmann
Am Eisteich 9
72555 Metzingen
Tel. 07123 / 14881
Internet: jochen.wiedmann@zdv.uni-tuebingen.de
*/
#ifndef CHAOS_H
#include "chaos.h"
#endif
#ifdef AMIGA
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <libraries/dos.h>
#include <proto/asl.h>
#include <proto/icon.h>
#endif /* AMIGA */
/*
FileRequest() creates a file requester which reads a file name.
Inputs: defaultfile a pointer to a string containing the default name
title a pointer to a string containing the requester's
title. This may be NULL, in which case
MSG_CDAT_SELECTION is assumed.
ending a pointer to a string containing the default ending.
This may be NULL, in which case "#?.cdat" is assumed.
Note, that this MUST be something like "#?.xxx" on
the Amiga!
savemode TRUE, if non-existing files may be selected.
Result: Full path name of the file, that was selected or NULL, if the
user cancelled.
*/
char *FileRequest(char *defaultfile, char *title, char *ending, int savemode)
#ifdef AMIGA
{ struct FileRequester *requester;
char pattern[20];
char *result = NULL;
char *filename, *pathname, *endptr;
BPTR dir;
static char FileRequestName[TRNFILENAME_LEN+1];
static char PathName[TRNFILENAME_LEN+1];
struct Window *window;
/*
Bring up default settings, if needed.
*/
if (title == NULL)
{ title = (char *) MSG_CDAT_SELECTION;
}
if (ending == NULL)
{ ending = "#?.cdat";
}
/*
Get Intuition window pointer from MUI window, allocate Filerequester
and parse the ending for wildcards.
*/
get(MainWnd, MUIA_Window_Window, &window);
if ((requester = (struct FileRequester *)
MUI_AllocAslRequest(ASL_FileRequest, NULL)) == NULL)
{ MemError();
return(NULL);
}
ParsePatternNoCase((UBYTE *) ending, (UBYTE *) pattern, sizeof(pattern));
/*
Get default file- and drawername.
*/
if (defaultfile && *defaultfile != '\0')
{ strcpy(FileRequestName, defaultfile);
}
else
{ if (TrnFileName != '\0')
{ strcpy(FileRequestName, TrnFileName);
}
else
{ sprintf(FileRequestName, savemode ? "chaos.%d.cdat" : "", NumRounds);
}
}
filename = (char *) FilePart((STRPTR) FileRequestName);
strcpy(PathName, FileRequestName);
*(pathname = (char *) PathPart((STRPTR) PathName)) = '\0';
/*
Make the drawername absolute.
*/
dir = Lock((STRPTR) PathName, SHARED_LOCK);
NameFromLock(dir, (STRPTR) PathName, sizeof(PathName));
UnLock(dir);
/*
Ensure, that the default filename has the right ending.
*/
if (ending != NULL && (endptr = strrchr(filename, '.')) != NULL)
{ strcpy(endptr, ending+2);
}
/*
Bring up the requester
*/
#ifdef V39_INCLUDES
if (MUI_AslRequestTags(requester,
ASLFR_Window, window,
ASLFR_PrivateIDCMP, TRUE,
ASLFR_SleepWindow, TRUE,
ASLFR_TitleText, title,
ASLFR_InitialFile, filename,
ASLFR_InitialDrawer, PathName,
ASLFR_InitialPattern, ending,
ASLFR_DoSaveMode, savemode,
ASLFR_RejectIcons, TRUE,
ASLFR_AcceptPattern, pattern,
TAG_DONE) != FALSE &&
requester->fr_File != NULL && requester->fr_File != '\0')
{ strcpy(FileRequestName, (char *) requester->fr_Drawer);
AddPart((STRPTR) FileRequestName, requester->fr_File,
sizeof(FileRequestName));
result = FileRequestName;
}
#else
if (MUI_AslRequestTags(requester,
ASL_Window, window,
ASL_Hail, title
ASL_File, filename,
ASL_Dir, PathName,
TAG_DONE) == FALSE &&
requester->rf_File != NULL && requester->rf_File != '\0')
{ strcpy(FileRequestName, (char *) requester->rf_Dir);
AddPart((STRPTR) FileRequestName, (STRPTR) requester->rf_File,
sizeof(FileRequestName));
result = FileRequestName;
}
#endif
MUI_FreeAslRequest((APTR) requester);
return (result);
}
#endif /* AMIGA */
/*
CreateIcon() puts an icon to a recently saved file.
Inputs: name of the file just created; must not be NULL
*/
void CreateIcon(char *name)
#ifdef AMIGA
{ extern int MakeIcons;
/*
Does the user want to have an icon?
*/
if (MakeIcons)
{ /*
Yes, get a diskobject
*/
struct DiskObject *dobj;
char *olddeftool;
int len = strlen(IconName);
/*
Icon.library doesn't like a trailing ".info" when calling
GetDiskObject().
*/
if (len >= 5 &&
Stricmp((STRPTR) IconName+len-5, (STRPTR) ".info") == 0)
{ IconName[len-5] = '\0';
}
if ((dobj = GetDiskObject((STRPTR) IconName)) != NULL ||
(dobj = GetDiskObject((STRPTR) "s:Chaos_Project")) != NULL ||
(dobj = GetDefDiskObject(WBPROJECT)) != NULL)
{ /*
Put the right settings into the diskobject and save it.
*/
dobj->do_Type = WBPROJECT;
olddeftool = dobj->do_DefaultTool;
dobj->do_DefaultTool = ProgName;
dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
if (dobj->do_StackSize < 20000)
{ dobj->do_StackSize = 20000;
}
PutDiskObject((STRPTR) name, dobj);
dobj->do_DefaultTool = olddeftool;
FreeDiskObject(dobj);
}
}
}
#else /* !AMIGA */
{ /*
There is nothing to be done on other systems.
*/
}
#endif /* !AMIGA */
/*
AskSave brings up a requester asking the user, if he wants to save
first.
*/
int AskSave(void)
#ifdef AMIGA
{
switch (MUI_RequestA(App, MainWnd, 0,
(char *) MSG_ATTENTION,
(char *) MSG_YES_NO_CANCEL,
(char *) MSG_CHANGES_MADE, NULL))
{ case 2:
return(TRUE);
case 1:
return(SaveTournament(NULL));
}
return(FALSE);
}
#endif /* AMIGA */
/*
The TerminateTrnWnd() function closes the tournament input window.
*/
#ifdef AMIGA
static APTR TrnWnd = NULL; /* Tournament window */
static APTR TrnOkGad; /* Ok gadget (tournament window) */
static APTR TrnCancelGad; /* Cancel gadget (tournament window) */
static APTR TrnNameGad; /* Tournament name gadget */
static APTR WinnerPointsGad; /* Winner points gadget */
static APTR DrawPointsGad; /* Draw points gadget */
void TerminateTrnWnd(void)
{ if (TrnWnd)
{ set(TrnWnd, MUIA_Window_Open, FALSE);
DoMethod(App, OM_REMMEMBER, TrnWnd);
MUI_DisposeObject(TrnWnd);
TrnWnd = NULL;
}
}
#endif /* AMIGA */
/*
The InitTrnWnd() function brings up a window, that allows to input
tournament data.
Inputs: name pointer to a buffer, that can hold the tournament name
winnerpoints current number of points for winning a game
drawpoints current number of points for a draw
Results: TRUE, if successful, FALSE otherwise
*/
#ifdef AMIGA
#define ID_TrnWnd_Cancel 201
#define ID_TrnWnd_Ok 202
int InitTrnWnd(char *buffer, int winnerpoints, int drawpoints)
{ ULONG open;
int OK_SC = *MSG_OK_SC;
int Cancel_SC = *MSG_CANCEL_SC;
/*
Open the window and check for success.
*/
TrnWnd = WindowObject,
MUIA_Window_ID, MAKE_ID('T','R','N','I'),
MUIA_Window_Title, MSG_TOURNAMENT_INPUT_TITLE,
MUIA_Window_Width, MUIV_Window_Width_MinMax(40),
WindowContents, VGroup,
Child, HGroup,
Child, Label2(MSG_TOURNAMENT_NAME_OUTPUT),
Child, TrnNameGad = StringObject,
StringFrame,
MUIA_String_MaxLen, TRNNAME_LEN+1,
MUIA_String_Contents, buffer,
End,
End,
Child, VSpace(0),
Child, HGroup,
Child, VGroup,
Child, Label2(MSG_WINNERPOINTS),
Child, Label2(MSG_DRAWPOINTS),
End,
Child, VGroup,
Child, WinnerPointsGad = StringObject,
StringFrame,
MUIA_String_MaxLen, 3,
MUIA_String_Accept, "0123456789 ",
MUIA_String_Integer, winnerpoints,
End,
Child, DrawPointsGad = StringObject,
StringFrame,
MUIA_String_MaxLen, 3,
MUIA_String_Accept, "0123456789 ",
MUIA_String_Integer, drawpoints,
End,
End,
Child, HSpace(0),
End,
Child, VSpace(0),
Child, HGroup,
MUIA_Group_SameSize, TRUE,
Child, TrnOkGad = KeyButton(MSG_OK, OK_SC),
Child, HSpace(0),
Child, TrnCancelGad = KeyButton(MSG_CANCEL_INPUT, Cancel_SC),
End,
End,
End;
if (!TrnWnd)
{ return(FALSE);
}
DoMethod(App, OM_ADDMEMBER, TrnWnd);
DoMethod(TrnWnd, MUIM_Window_SetCycleChain, TrnNameGad, TrnOkGad,
TrnCancelGad, NULL);
set(TrnWnd, MUIA_Window_ActiveObject, TrnNameGad);
/*
Setting up the notification events for the tournament input window:
CloseWindow, Ok- and Cancel Gadget
*/
DoMethod(TrnWnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2,
MUIM_Application_ReturnID, ID_TrnWnd_Cancel);
DoMethod(TrnWnd, MUIM_Notify, MUIA_Window_InputEvent, "ctrl return",
App, 2, MUIM_Application_ReturnID, ID_TrnWnd_Ok);
DoMethod(TrnOkGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
MUIM_Application_ReturnID, ID_TrnWnd_Ok);
DoMethod(TrnCancelGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
MUIM_Application_ReturnID, ID_TrnWnd_Cancel);
DoMethod(TrnWnd, MUIM_Window_SetCycleChain,
TrnNameGad, WinnerPointsGad, DrawPointsGad, TrnOkGad, TrnCancelGad,
NULL);
DoMethod(TrnNameGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, WinnerPointsGad);
DoMethod(WinnerPointsGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, DrawPointsGad);
DoMethod(DrawPointsGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, TrnNameGad);
set(TrnWnd, MUIA_Window_Open, TRUE);
get(TrnWnd, MUIA_Window_Open, &open);
if (!open)
{ MUIError((char *) ERRMSG_CANNOT_OPEN_WINDOW);
TerminateTrnWnd();
return(FALSE);
}
set(TrnWnd, MUIA_Window_ActiveObject, TrnNameGad);
set(MainWnd, MUIA_Window_Open, FALSE);
return(TRUE);
}
#endif /* AMIGA */
/*
The ProcessTrnWnd() function waits for user actions concerning
the tournament input window.
Inputs: buffer pointer to a string, that holds the users input.
(Not needed on the Amiga.)
winnerpoints pointer to an int where to store the
number of points for winning a game
game
drawpoints pointer to an int where to store the
number of points for a draw
Results: 0 Indicates, that the user has cancelled.
1 Indicates, that this has to be called again.
-1 Terminating via Ok-Gadget, okay
*/
int ProcessTrnWnd(char *buffer, int *winnerpoints, int *drawpoints)
#ifdef AMIGA
{ ULONG Signal;
char *name;
/*
Check for user actions
*/
switch (DoMethod(App, MUIM_Application_Input, &Signal))
{ case MUIV_Application_ReturnID_Quit:
if (TestSaved())
{ exit(0);
}
break;
case ID_TrnWnd_Cancel:
return(0);
case ID_TrnWnd_Ok:
/*
Get the final state of the tournament name gadget.
*/
if (buffer)
{ get(TrnNameGad, MUIA_String_Contents, &name);
strcpy (buffer, name);
get(WinnerPointsGad, MUIA_String_Integer, winnerpoints);
get(DrawPointsGad, MUIA_String_Integer, drawpoints);
}
return(-1);
}
if (Signal)
{ Wait(Signal);
}
return(1);
}
#endif
它非常易於使用,只需要一個要附加的視窗、一個結構、一個指向 IDCMP 標誌列表的指標以及可選引數。
struct Requester
{
struct Requester *OlderRequest;
WORD LeftEdge, TopEdge;
WORD Width, Height;
WORD RelLeft, RelTop;
struct Gadget *ReqGadget;
struct Border *ReqBorder;
struct IntuiText *ReqText;
UWORD Flags;
POINTREL
PREDRAWN
NOISYREQ
USEREQIMAGE
NOREQBACKFILL
REQOFFWINDOW (the following are library called)
REQACTIVE
SYSREQUEST
UBYTE Backfill;
struct Layer *ReqLayer;
UBYTE ReqPad1[32];
struct BitMap *ImageBMap;
struct Window *RWindow;
struct Image *ReqImage;
UBYTE ReqPad2[32];
};
BuildSysRequest(Window)
FreeSysRequest (Window)
AutoRequest( Window, BodyText, PosText, NegText, PosFlags, NegFlags, Width, Height)
每個小工具(用於視窗或請求器)都會建立一個獨立的 Gadget 結構
struct Gadget {
struct Gadget *NextGadget;
WORD LeftEdge, TopEdge;
WORD Width, Height;
UWORD Flags;
UWORD Activation;
UWORD GadgetType;
GTYP_BOOLGADGET - Boolean gadget type.
GTYP_STRGADGET - String gadget type. For an integer gadget, also set the GACT_LONGINT flag.
GTYP_PROPGADGET - Proportional gadget type.
GTYP_CUSTOMGADGET - Normally not set by the application. Used by custom BOOPSI gadget types.
GTYP_GZZGADGET - If the gadget is placed in a GimmeZeroZero window, will place the gadget in the border layer.
GTYP_REQGADGET - Set this bit if this gadget is placed in a requester.
APTR GadgetRender;
APTR SelectRender;
struct IntuiText *GadgetText;
IPTR MutualExclude; /* changed from LONG used by BOOPSI gadgets to store dispatcher address */
APTR SpecialInfo;
UWORD GadgetID;
APTR UserData;
};
突出顯示標誌
GFLG_GADGHNONE - GFLG_GADGHCOMP - GFLG_GADGHBOX - GFLG_GADGHIMAGE -
除了突出顯示標誌之外,還可以將這些其他值設定在 Gadget 結構的 Flags 欄位中。
GFLG_GADGIMAGE - GFLG_RELBOTTOM - GFLG_RELRIGHT - GFLG_RELWIDTH - GFLG_RELHEIGHT - GFLG_SELECTED - GFLG_DISABLED - GFLG_STRINGEXTEND - GFLG_TABCYCLE -
小工具啟用標誌 - 可以設定在 Gadget 結構的 Activation 欄位中。
GACT_TOGGLESELECT GACT_IMMEDIATE GACT_RELVERIFY GACT_ENDGADGET GACT_FOLLOWMOUSE
邊框標誌
GACT_RIGHTBORDER GACT_LEFTBORDER GACT_TOPBORDER GACT_BOTTOMBORDER
以下標誌僅適用於字串小工具
GACT_STRINGCENTER GACT_STRINGRIGHT GACT_STRINGLEFT GACT_LONGINT GACT_ALTKEYMAP GACT_BOOLEXTEND GACT_STRINGEXTEND
如果你使用老式 struct Gadget,你需要適當地計算和設定 PropInfo 結構的 BODY 和 POT 欄位。
閱讀更多 gadtools.library。
字串小工具需要它們自己的特殊結構,稱為 StringInfo 結構。對於字串小工具,將 Gadget 結構中的 GadgetType 欄位設定為 GTYP_STRGADGET。將 SpecialInfo 欄位設定為指向 StringInfo 結構的例項,該例項必須由應用程式初始化。
struct StringInfo
{
UBYTE *Buffer;
UBYTE *UndoBuffer;
WORD BufferPos;
WORD MaxChars;
WORD DispPos;
WORD UndoPos;
WORD NumChars;
WORD DispCount;
WORD CLeft, CTop;
struct StringExtend *Extension;
LONG LongInt;
struct KeyMap *AltKeyMap;
};
自定義字串編輯
struct SGWork
{
struct Gadget *Gadget;
struct StringInfo *StringInfo;
UBYTE *WorkBuffer;
UBYTE *PrevBuffer;
ULONG Modes;
struct InputEvent *IEvent;
UWORD Code;
WORD BufferPos;
WORD NumChars;
ULONG Actions;
LONG LongInt;
struct GadgetInfo *GadgetInfo;
UWORD EditOp;
};
EditOp Action Taken by Global Hook ------ --------------------------- EO_NOOP Did nothing. EO_DELBACKWARD Deleted some chars (possibly 0). EO_DELFORWARD Deleted some characters under and in front of the cursor. EO_MOVECURSOR Moved the cursor. EO_ENTER Enter or Return key, terminate. EO_RESET Current Intuition-style undo. EO_REPLACECHAR Replaced one character and (maybe) advanced cursor. EO_INSERTCHAR Inserted one character into string or added one at end. EO_BADFORMAT Didn't like the text data, e.g., alpha characters in a GACT_LONGINT type. EO_BIGCHANGE Complete or major change to the text, e.g. new string. EO_UNDO Some other style of undo. EO_CLEAR Clear the string. EO_SPECIAL An operation that doesn't fit into the categories here. These are the actions to be taken by Intuition after the hook returns. Actions Flag Purpose ------------ ------- SGA_USE If set, use contents of SGWork. SGA_END Terminate gadget, Code field is sent to application in IDCMP_GADGETUP event code field. SGA_BEEP Beep (i.e., flash) the screen. SGA_REUSE Reuse the input event. Only valid with SGA_END. SGA_REDISPLAY Gadget visuals have changed, update on screen. SGA_NEXTACTIVE Make next possible gadget active SGA_PREVACTIVE Make previous possible gadget active
struct PropInfo
{
UWORD Flags;
PROPBORDERLESS -
AUTOKNOB -
FREEHORIZ and FREEVERT
PROPNEWLOOK
KNOBHIT
UWORD HorizPot;
UWORD VertPot;
UWORD HorizBody;
UWORD VertBody;
UWORD Cwidth;
UWORD Cheight;
UWORD HPotRes, VPotRes;
UWORD LeftBorder;
UWORD TopBorder;
};
在 Gadget 結構中,將 GadgetType 欄位設定為 GTYP_PROPGADGET,並將 PropInfo 結構的地址放在 SpecialInfo 欄位中。
要更改小工具顯示後的標誌以及 pot 和 body 變數,程式可以呼叫 NewModifyProp()。
void NewModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester,
unsigned long flags, unsigned long horizPot, unsigned long vertPot,
unsigned long horizBody, unsigned long vertBody, long numGad );
BOOPSI 非常適合 GUI 內容和執行時類載入/方法分派。它是用 C 編寫的,考慮到這種系統語言的限制,設計人員做得非常出色。但是,如果我們從 Amiga 開始就擁有良好的 C++ 支援,當然 BOOPSI 會用它編寫。
問題是,BOOPSI 很適合事件驅動程式碼(例如 GUI),其中使用者互動是決定速度的因素。但是,方法分派機制和資料訪問方法比 C++ 虛擬函式呼叫慢得多(由於它們的工作原理),更不用說非虛擬或靜態成員函數了。
你不會想在所有 OOP 需要中都依賴 BOOPSI。想象一下在時間關鍵迴圈中使用的函式呼叫的速度損失。哎喲:-)
如果你使用 BOOPSI 捲軸,你可以設定 Total、Visible 和 Top 屬性。你還可以讓它在使用者移動捲軸時向你傳送訊息。Intuition 自帶自己的 BOOPSI 捲軸類 - propgclass。它更好地整合在視窗邊框內。
似乎還存在將 SA_PubSig 訊號傳送到 SA_PubTask 的問題。如果呼叫 UnlockPubScreen 並且這是最後一個鎖定,則 SA_PubTask 會收到訊號。這與螢幕上的視窗數量無關。
因此,這可能會發生
- Open Pubscreen - Lock Pubscreen - Open window on Pubscreen - UnlockPubscreen - SA_PubSig is sent!! - .... - Close Window
正如你所見在中,似乎不需要鎖定 pubscreen 才能在其上開啟視窗,至少,如果你擁有它的話。
LockPubScreen() Find Workbench or any other public screen; prevent it from closing while a window is opened or its attributes copied.
UnlockPubScreen() Release the lock allowing the screen to later be closed.
struct Screen *LockPubScreen( UBYTE * )
VOID UnlockPubScreen( UBYTE * , struct Screen *)
SetDefaultPubScreen() Establishes a given public screen as the default.
GetDefaultPubScreen() Copies the name of the default screen to a user supplied buffer for use by the screen manager utility
(the name is not needed by normal applications, use LockPubScreen(NULL) instead).
PubScreenStatus() Converts a screen to private or public status.
SetPubScreenModes() Controls the public screen global mode bits.
WBenchToBack() Move the Workbench screen behind all other screens.
WBenchToFront() Move the Workbench screen in front of all other screens.
OpenWorkBench() Open the Workbench screen. If the screen is already open, this call has no effect.
This call will re-awaken the Workbench application if it was active when CloseWorkBench() was called.
CloseWorkBench() Attempt to reclaim memory used for the Workbench screen.
If successful, this call closes the screen and puts the Workbench application to sleep.
This call fails if any application has windows open or locks on the Workbench screen.
LockPubScreenList() Lock the public screen list maintained by intuition so that it may be quickly copied.
UnlockPubScreenList() Release the lock on the public screen list.
NextPubScreen() Find the next screen in the public screen list.
在 AROS 上,你的正常入口點是 main(int argc, char **argv)。
如果 argc == 0,則 argv 實際上指向 struct WBStartup。
如果 argc > 0,則程式是從 CLI 啟動的。
但是,從 CLI 執行的程式 *必須* 對每個 Forbid() 呼叫 Permit(),因為最終的 'rts' 返回到 shell,而不是終止程序。
儘可能使用訊號量。僅當沒有其他選擇時,才應使用 Forbid()/Permit()。訊號量對於訪問記憶體池、可能被其他執行緒修改的列表等非常有用。
一些程式使用啟動新程序並清除 cli_Module 以從執行它們的 shell 中分離的技術。至少對於 FileX(參見 contrib/aminet/disk/moni/filex/main.c),這似乎不再起作用。FileX 僅在使用 SYNC 引數停用此行為時才起作用。
標準啟動程式碼或 shell 是否支援這種分離?也許 seglist 無論 cli_Module 中放置的值如何都會被解除安裝。
如果 cli_Module 已被程式清除,是否可以將庫在退出時保持開啟狀態?它們是否可以在分離的程序退出時關閉?實際上不行,因為它不會修復更常見的“拆分段列表”分離方式。
這與 FileX 的做法有什麼不同?:-| 我認為 SegmentSplit() 函式名稱的相似性具有誤導性。是的,FileX 不會做任何段拆分技巧(也許它最初做過了?),它只是清除了 cli_Module。“標準”段列表拆分是擁有 2 個(或更多)段,第一個段中的程式碼從單鏈表中刪除後續段 -> 只有第一個段被 dos 釋放。
當原始程序存在時,aroscbase 被設定為 NULL(猜想它也被釋放了)。當然,分離的程序仍在使用它.. 哎喲。我猜想 FileX 沒有使用 detach.o?它應該這樣做以避免此類問題。
這意味著要包含 aros/detach.h,並且不要連結到標準啟動模組,而是連結到 detach.o,正如 Fabio 剛剛所說的。這是在 mmakefile.src 中透過 detach=yes 斷言完成的。你甚至可以使用 Detach() 函式選擇分離發生的位置。
AmigaOS libnix 僅為 libc I/O 開啟自己的控制檯。它不會將預設的 dos.library 流重新分配到它。換句話說:當程式從 CLI 啟動時,libc I/O(printf()、write()、stdin、stdout 等)將被定向到 dos.library 預設流。當程式從 Workbench 啟動時,libc 為自己的 I/O 開啟自己的視窗,但不會觸及 dos.library 流。因此,當從 WB 啟動時,printf() 會將字串傳送到 __stdiowin,但是 Printf() 會將它傳送到 NIL:。
#include <proto/exec.h>
#include <proto/dos.h>
int __stack = 0x500000; /* 5 MiB */
int real_main (int argc, char *argv[]);
int main (int argc, char *argv[])
{
struct Task *mytask = FindTask(NULL);
ULONG stacksize = mytask->tc_SPUpper - mytask->tc_SPLower;
int rc = 1;
int i;
Printf("stack desired: %lu current %lun", __stack, stacksize);
Printf("SPUpper %lu SPLower %lu SPReg %lun", mytask->tc_SPUpper, mytask->tc_SPLower, mytask->tc_SPReg);
Printf("argc %d argv %pn", argc, argv);
for (i = 0; i < argc; i++)
Printf("argv[%d] = %sn", i, argv[i]);
if (stacksize >= __stack)
{
Printf("no stack adjustment is necessaryn");
rc = real_main(argc, argv);
}
else
{
struct StackSwapArgs swapargs;
struct StackSwapStruct stack;
swapargs.Args[0] = argc;
swapargs.Args[1] = (IPTR) argv;
Printf("stack was too small, stackswappingn");
if (stack.stk_Lower = AllocVec(__stack, MEMF_PUBLIC))
{
stack.stk_Upper = stack.stk_Lower + __stack;
stack.stk_Pointer = stack.stk_Upper;
rc = NewStackSwap(&stack, real_main, &swapargs);
FreeVec(stack.stk_Lower);
}
else
{
Printf("Couldn't allocate %d bytes for stack.n", __stack);
}
}
return rc;
}
int real_main (int argc, char *argv[])
{
int i;
struct Task *mytask = FindTask(NULL);
ULONG stacksize = mytask->tc_SPUpper - mytask->tc_SPLower;
Printf("New stack size: %lun", stacksize);
Printf("SPUpper %lu SPLower %lu SPReg %lun", mytask->tc_SPUpper, mytask->tc_SPLower, mytask->tc_SPReg);
Printf("argc %d argv %pn", argc, argv);
for (i = 0; i < argc; i++)
Printf("argv[%d] = %sn", i, argv[i]);
return RETURN_OK;
}
start:
wbmsg = NULL;
task = FindTask(NULL)
if (task->pr_CLI == 0 )
{
WaitPort(&task->pr_MsgPort);
wbmsg = GetMsg(&task->pr_MsgPort);
}
; your code here
if ( wbmsg != NULL )
{
Forbid();
ReplyMsg(wbmsg);
}
return return_code;
最後的 Forbid() 保證 Workbench 在程式仍在執行時沒有機會 UnLoadSeg() 程式的 seglist。
如果沒有 Forbid(),ReplyMsg() 將導致任務排程,Workbench 會有機會執行。Workbench 會 UnLoadSeg() seglist,最後幾條指令將在未分配的記憶體上執行。這會導致崩潰。
不需要最後的 Permit(),因為程序最終會 RemTask(NULL) 自身(預設的任務 EndPC),並且這會完全刪除程序。
{
struct WBStartup *wbmsg;
BPTR win;
if (argc != 0)
{
Printf ("This program cannot be run in DOS mode :-)\n");
return (RETURN_ERROR);
}
wbmsg = (struct WBStartup *)argv;
if (win = Open ("con:0/0/640/400/WB Icon/CLOSE/WAIT",MODE_NEWFILE))
{
char buffer[256];
long i;
NameFromLock (wbmsg->sm_ArgList->wa_Lock,buffer,256);
AddPart (buffer,wbmsg->sm_ArgList->wa_Name,256);
FPrintf (win,"Program name: <%s>\n",buffer);
for (i = 1; i < wbmsg->sm_NumArgs; i++)
{
NameFromLock (wbmsg->sm_ArgList[i].wa_Lock,buffer,256);
AddPart (buffer,wbmsg->sm_ArgList[i].wa_Name,256);
FPrintf (win,"Argument #%ld: <%s>\n",i,buffer);
}
Close (win);
}
return (RETURN_OK);
}
使用 intuition.library/StartScreenNotifyTagList(),以便在不需要關閉/重新開啟螢幕的情況下允許更改螢幕首選項。
你可以使用一些其他函式來操作螢幕。
void DisplayBeep(struct Screen *) This function will flash the specified screen, for example, to indicate an error. e.g. DisplayBeep(myScreen); void MoveScreen(struct Screen *, WORD dx, WORD dy) This function will move the current screen to the specified pixel co-ordinates. This is similar to dragging the screen bar to a new location. e.g. MoveScreen(myScreen, 0, 100); /* Move screen down to y co-ord 100 */ void ScreenToBack(struct Screen *) void ScreenToFront(struct Screen *) If you have multiple screens open, then you can switch between screens using these functions. ScreenToFront will make a screen the visible screen. e.g. ScreenToFront(myScreen); void MakeScreen(struct Screen *) e.g. MakeScreen(myScreen); void ShowTitle(struct Screen *, BOOL) Specifies whether to show the screen's title bar or not. e.g. ShowTitle(myScreen, FALSE);
有關更多命令,請參閱Intuition 參考文件。
GetScreenDrawInfo() Get the DrawInfo information for an open screen. FreeScreenDrawInfo() Free the DrawInfo information for a screen. MakeScreen() Low level screen handling--rebuild Copper list. RethinkDisplay() Low level screen handling--incorporate Copper list changes. RemakeDisplay() MakeScreen() for all screens, then RethinkDisplay(). ScreenNotify() Private function
請參閱此執行緒
AROS_UFH3(void ,sbackfillfunc,
AROS_UFHA(struct Hook *,hook,a0),
AROS_UFHA(struct RastPort *,frp,a2),
AROS_UFHA(struct BackfillMsg *,bfm,a1))
{
AROS_USERFUNC_INIT
struct RastPort rp;
CopyMem(frp, &rp, sizeof(struct RastPort));
rp.Layer = NULL;
FillPixelArray( &rp,
bfm->rect.MinX,
bfm->rect.MinY,
bfm->rect.MaxX - bfm->rect.MinX + 1,
bfm->rect.MaxY - bfm->rect.MinY + 1,
0x00000000);
AROS_USERFUNC_EXIT
}
struct Hook sbackfillhook;
以下是開啟螢幕的呼叫
sbackfillhook.h_Entry = (HOOKFUNC) sbackfillfunc;
info->screen = OpenScreenTags( NULL,
SA_Width, target_width,
SA_Height, target_height,
SA_Depth, target_depth,
SA_Quiet, TRUE,
SA_ShowTitle, FALSE,
SA_Type, CUSTOMSCREEN,
SA_DisplayID, dispid,
SA_BackFill, (ULONG) &sbackfillhook,
TAG_DONE);
SA_BackFill, (ULONG) &sbackfillhook,
請不要在程式碼中使用 ULONG 來儲存/強制轉換指標。在適當的情況下使用 APTR/IPTR。
如果你釋出的程式碼是完整的程式碼,那麼它不起作用的原因可能是你填充 sbackfillhook 的方式。在 Demos/scrbackfill 中,鉤子是這樣填充的
static void InitBackfillHook(void)
{
backfillhook.h_Entry = HookEntry;
backfillhook.h_SubEntry = (HOOKFUNC)MyBackfillFunc;
}
HookEntry 在 clib/alib_protos.h 中定義,MyBackfillFunc 是
static void MyBackfillFunc(struct Hook *hook,struct RastPort *rp, struct LayerHookMsg *msg);
或者直接檢視 Demos/scrbackfill.c。
struct DrawInfo
{
UWORD dri_Version; /* will be DRI_VERSION */
UWORD dri_NumPens; /* guaranteed to be >= 9 */
UWORD *dri_Pens; /* pointer to pen array */
struct TextFont *dri_Font; /* screen default font */
UWORD dri_Depth; /* (initial) depth of screen bitmap */
struct { /* from DisplayInfo database for initial display mode */
UWORD X;
UWORD Y;
} dri_Resolution;
ULONG dri_Flags; /* defined below */
/* New for V39: dri_CheckMark, dri_AmigaKey. */
struct Image *dri_CheckMark; /* pointer to scaled checkmark image
* Will be NULL if DRI_VERSION < 2
*/
struct Image *dri_AmigaKey; /* pointer to scaled Amiga-key image
* Will be NULL if DRI_VERSION < 2
*/
ULONG dri_Reserved[5]; /* avoid recompilation ;^) */
};
#define DRIF_NEWLOOK 0x00000001L /* specified SA_Pens, full treatment */
/* rendering pen number indexes into DrawInfo.dri_Pens[] */
#define DETAILPEN (0x0000) /* compatible Intuition rendering pens */
#define BLOCKPEN (0x0001) /* compatible Intuition rendering pens */
#define TEXTPEN (0x0002) /* text on background */
#define SHINEPEN (0x0003) /* bright edge on 3D objects */
#define SHADOWPEN (0x0004) /* dark edge on 3D objects */
#define FILLPEN (0x0005) /* active-window/selected-gadget fill */
#define FILLTEXTPEN (0x0006) /* text over FILLPEN */
#define BACKGROUNDPEN (0x0007) /* may not always be color 0 */
#define HIGHLIGHTTEXTPEN (0x0008) /* special color text, on background */
/* New for V39, only present if DRI_VERSION >= 2: */
#define BARDETAILPEN (0x0009) /* text/detail in screen-bar/menus */
#define BARBLOCKPEN (0x000A) /* screen-bar/menus fill */
#define BARTRIMPEN (0x000B) /* trim under screen-bar */
#define NUMDRIPENS (0x000C)
/* New for V39: It is sometimes useful to specify that a pen value
* is to be the complement of color zero to three. The "magic" numbers
* serve that purpose:
*/
#define PEN_C3 0xFEFC /* Complement of color 3 */
#define PEN_C2 0xFEFD /* Complement of color 2 */
#define PEN_C1 0xFEFE /* Complement of color 1 */
#define PEN_C0 0xFEFF /* Complement of color 0 */
要隱藏視窗(並使其重新出現!),請使用 ChangeWindowShape()。仍然不知道如何使用 WA_Visible=FALSE 開啟的視窗再次可見;)
如果我們收到 MENUVERIFY 訊息,我們會檢視相應的開啟視窗。如果在滑鼠點選時它已清除 WFLG_RMBTRAP,我們會顯示相應的 AROS intuition 選單。
繁忙指標,我已經嘗試新增 ..
SetWindowPointer( win, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE ); SetWindowPointer( win, TAG_DONE );
因為我只得到預設指標,而不是應用程式使用 SetWindowPointer() 或 SetPointer() 函式設定的當前指標。
有沒有辦法獲得當前的指標點陣圖?你始終可以在執行時修補必要的函式,以便你的例程會使用必要的資訊被呼叫,然後執行你需要的操作(以及呼叫原始函式以實際設定可見指標)。
- 攔截呼叫,
- 複製點陣圖以便我可以將其用於自己的目的
- 將呼叫轉發到原始函式
深入研究似乎不是 SetWindowPointerA 而是 ChangeExtSpriteA 需要修補。當為視窗設定新的指標時使用 SetWindowPointer,因此當視窗處於活動狀態時將使用此指標。但是,每次指標發生變化時都會呼叫 ChangeExtSprite,即當活動視窗發生變化時也會呼叫。
有沒有辦法獲得當前指標變化的通知?應用程式可以透過呼叫 SetWindowPointer() 隨時更改指標影像,例如顯示繁忙指標。這些更改不會反映在檔案更改中,也不會觸發 DOS 通知。
UWORD AddGadget(struct Window *window, struct Gadget *gadget, ULONG position) (A0, A1, D0) BOOL ClearDMRequest(struct Window *window) (A0) void ClearMenuStrip(struct Window *window) (A0) void ClearPointer(struct Window *window) (A0) BOOL CloseScreen(struct Screen *screen) (A0) void CloseWindow(struct Window *window) (A0) LONG CloseWorkBench() () void CurrentTime(ULONG *seconds, ULONG *micros) (A0, A1) BOOL DisplayAlert(ULONG alertnumber, UBYTE *string, UWORD height) (D0, A0, D1) void DisplayBeep(struct Screen *screen) (A0) BOOL DoubleClick(ULONG sSeconds, ULONG sMicros, ULONG cSeconds, ULONG cMicros) (D0, D1, D2, D3) void DrawBorder(struct RastPort *rp, struct Border *border, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1) void DrawImage(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1) void EndRequest(struct Requester *requester, struct Window *window) (A0, A1) struct Preferences *GetDefPrefs(struct Preferences *prefbuffer, WORD size) (A0, D0) struct Preferences *GetPrefs(struct Preferences *prefbuffer, WORD size) (A0, D0) void InitRequester(struct Requester *requester) (A0) struct MenuItem *ItemAddress(struct Menu *menustrip, UWORD menunumber) (A0, D0) BOOL ModifyIDCMP(struct Window *window, ULONG flags) (A0, D0) void ModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester, ULONG flags, ULONG horizPot, ULONG vertPot, ULONG horizBody, ULONG vertBody) (A0, A1, A2, D0, D1, D2, D3, D4) void MoveScreen(struct Screen *screen, LONG dx, LONG dy) (A0, D0, D1) void MoveWindow(struct Window *window, LONG dx, LONG dy) (A0, D0, D1) void OffGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2) void OffMenu(struct Window *window, UWORD menunumber) (A0, D0) void OnGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2) void OnMenu(struct Window *window, UWORD menunumber) (A0, D0) struct Screen *OpenScreen(struct NewScreen *newScreen) (A0) struct Window *OpenWindow(struct NewWindow *newWindow) (A0) IPTR OpenWorkBench() () void PrintIText(struct RastPort *rp, struct IntuiText *iText, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1) void RefreshGadgets(struct Gadget *gadgets, struct Window *window, struct Requester *requester) (A0, A1, A2) UWORD RemoveGadget(struct Window *window, struct Gadget *gadget) (A0, A1) void ReportMouse(LONG flag, struct Window *window) (D0, A0) BOOL Request(struct Requester *requester, struct Window *window) (A0, A1) void ScreenToBack(struct Screen *screen) (A0) void ScreenToFront(struct Screen *screen) (A0) BOOL SetDMRequest(struct Window *window, struct Requester *dmrequest) (A0, A1) BOOL SetMenuStrip(struct Window *window, struct Menu *menu) (A0, A1) void SetPointer(struct Window *window, UWORD *pointer, LONG height, LONG width, LONG xOffset, LONG yOffset) (A0, A1, D0, D1, D2, D3) void SetWindowTitles(struct Window *window, CONST_STRPTR windowTitle, CONST_STRPTR screenTitle) (A0, A1, A2) void ShowTitle(struct Screen *screen, BOOL ShowIt) (A0, D0) void SizeWindow(struct Window *window, LONG dx, LONG dy) (A0, D0, D1) struct View *ViewAddress() () struct ViewPort *ViewPortAddress(struct Window *Window) (A0) void WindowToBack(struct Window *window) (A0) void WindowToFront(struct Window *window) (A0) BOOL WindowLimits(struct Window *window, WORD MinWidth, WORD MinHeight, UWORD MaxWidth, UWORD MaxHeight) (A0, D0, D1, D2, D3) struct Preferences *SetPrefs(struct Preferences *prefbuffer, LONG size, BOOL inform) (A0, D0, D1) LONG IntuiTextLength(struct IntuiText *iText) (A0) BOOL WBenchToBack() () BOOL WBenchToFront() () BOOL AutoRequest(struct Window *window, struct IntuiText *body, struct IntuiText *posText, struct IntuiText *negText, ULONG pFlag, ULONG nFlag, ULONG width, ULONG height) (A0, A1, A2, A3, D0, D1, D2, D3) void BeginRefresh(struct Window *window) (A0) struct Window *BuildSysRequest(struct Window *window, struct IntuiText *bodytext, struct IntuiText *postext, struct IntuiText *negtext, ULONG IDCMPFlags, WORD width, WORD height) (A0, A1, A2, A3, D0, D2, D3) void EndRefresh(struct Window *window, BOOL complete) (A0, D0) void FreeSysRequest(struct Window *window) (A0) LONG MakeScreen(struct Screen *screen) (A0) LONG RemakeDisplay() () LONG RethinkDisplay() () APTR AllocRemember(struct Remember **rememberKey, ULONG size, ULONG flags) (A0, D0, D1) void AlohaWorkbench(struct MsgPort *wbmsgport) (A0) void FreeRemember(struct Remember **rememberKey, LONG reallyForget) (A0, D0) ULONG LockIBase(ULONG What) (D0) void UnlockIBase(ULONG ibLock) (A0) LONG GetScreenData(APTR buffer, ULONG size, ULONG type, struct Screen *screen) (A0, D0, D1, A1) void RefreshGList(struct Gadget *gadgets, struct Window *window, struct Requester *requester, LONG numGad) (A0, A1, A2, D0) UWORD AddGList(struct Window *window, struct Gadget *gadget, ULONG position, LONG numGad, struct Requester *requester) (A0, A1, D0, D1, A2) UWORD RemoveGList(struct Window *remPtr, struct Gadget *gadget, LONG numGad) (A0, A1, D0) void ActivateWindow(struct Window *window) (A0) void RefreshWindowFrame(struct Window *window) (A0) BOOL ActivateGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2) void NewModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester, ULONG flags, ULONG horizPot, ULONG vertPot, ULONG horizBody, ULONG vertBody, LONG numGad) (A0, A1, A2, D0, D1, D2, D3, D4, D5) LONG QueryOverscan(ULONG displayid, struct Rectangle *rect, WORD oscantype) (A0, A1, D0) void MoveWindowInFrontOf(struct Window *window, struct Window *behindwindow) (A0, A1) void ChangeWindowBox(struct Window *window, LONG left, LONG top, LONG width, LONG height) (A0, D0, D1, D2, D3) struct Hook *SetEditHook(struct Hook *hook) (A0) LONG SetMouseQueue(struct Window *window, UWORD queuelength) (A0, D0) void ZipWindow(struct Window *window) (A0) struct Screen *LockPubScreen(CONST_STRPTR name) (A0) void UnlockPubScreen(UBYTE *name, struct Screen *screen) (A0, A1) struct List *LockPubScreenList() () void UnlockPubScreenList() () UBYTE *NextPubScreen(struct Screen *screen, UBYTE *namebuff) (A0, A1) void SetDefaultPubScreen(UBYTE *name) (A0) UWORD SetPubScreenModes(UWORD modes) (D0) UWORD PubScreenStatus(struct Screen *Scr, UWORD StatusFlags) (A0, D0) struct RastPort *ObtainGIRPort(struct GadgetInfo *gInfo) (A0) void ReleaseGIRPort(struct RastPort *rp) (A0) void GadgetMouse(struct Gadget *gadget, struct GadgetInfo *ginfo, WORD *mousepoint) (A0, A1, A2) ULONG SetIPrefs(APTR data, ULONG length, ULONG type) (A0, D0, D1) struct Screen *GetDefaultPubScreen(UBYTE *nameBuffer) (A0) LONG EasyRequestArgs(struct Window *window, struct EasyStruct *easyStruct, ULONG *IDCMP_ptr, APTR argList) (A0, A1, A2, A3) struct Window *BuildEasyRequestArgs(struct Window *RefWindow, struct EasyStruct *easyStruct, ULONG IDCMP, APTR Args) (A0, A1, D0, A3) LONG SysReqHandler(struct Window *window, ULONG *IDCMPFlagsPtr, BOOL WaitInput) (A0, A1, D0) struct Window *OpenWindowTagList(struct NewWindow *newWindow, struct TagItem *tagList) (A0, A1) struct Screen *OpenScreenTagList(struct NewScreen *newScreen, struct TagItem *tagList) (A0, A1) void DrawImageState(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset, ULONG state, struct DrawInfo *drawInfo) (A0, A1, D0, D1, D2, A2) BOOL PointInImage(ULONG point, struct Image *image) (D0, A0) void EraseImage(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1) APTR NewObjectA(struct IClass *classPtr, UBYTE *classID, struct TagItem *tagList) (A0, A1, A2) void DisposeObject(APTR object) (A0) IPTR SetAttrsA(APTR object, struct TagItem *tagList) (A0, A1) ULONG GetAttr(ULONG attrID, Object *object, IPTR *storagePtr) (D0, A0, A1) IPTR SetGadgetAttrsA(struct Gadget *gadget, struct Window *window, struct Requester *requester, struct TagItem *tagList) (A0, A1, A2, A3) APTR NextObject(APTR objectPtrPtr) (A0) struct IClass *FindClass(ClassID classID) (A0) struct IClass *MakeClass(ClassID classID, ClassID superClassID, struct IClass *superClassPtr, ULONG instanceSize, ULONG flags) (A0, A1, A2, D0, D1) void AddClass(struct IClass *classPtr) (A0) struct DrawInfo *GetScreenDrawInfo(struct Screen *screen) (A0) void FreeScreenDrawInfo(struct Screen *screen, struct DrawInfo *drawInfo) (A0, A1) BOOL ResetMenuStrip(struct Window *window, struct Menu *menu) (A0, A1) void RemoveClass(struct IClass *classPtr) (A0) BOOL FreeClass(struct IClass *iclass) (A0) struct ScreenBuffer *AllocScreenBuffer(struct Screen *screen, struct BitMap *bitmap, ULONG flags) (A0, A1, D0) void FreeScreenBuffer(struct Screen *screen, struct ScreenBuffer *screenbuffer) (A0, A1) ULONG ChangeScreenBuffer(struct Screen *screen, struct ScreenBuffer *screenbuffer) (A0, A1) void ScreenDepth(struct Screen *screen, ULONG flags, APTR reserved) (A0, D0, A1) void ScreenPosition(struct Screen *screen, ULONG flags, LONG x1, LONG y1, LONG x2, LONG y2) (A0, D0, D1, D2, D3, D4) void ScrollWindowRaster(struct Window *win, WORD dx, WORD dy, WORD xmin, WORD ymin, WORD xmax, WORD ymax) (A1, D0, D1, D2, D3, D4, D5) void LendMenus(struct Window *fromwindow, struct Window *towindow) (A0, A1) IPTR DoGadgetMethodA(struct Gadget *gad, struct Window *win, struct Requester *req, Msg msg) (A0, A1, A2, A3) void SetWindowPointerA(struct Window *window, struct TagItem *taglist) (A0, A1) BOOL TimedDisplayAlert(ULONG alertnumber, UBYTE *string, UWORD height, ULONG time) (D0, A0, D1, A1) void HelpControl(struct Window *window, ULONG flags) (A0, D0) LONG IsWindowVisible(struct Window *window) (A0) void ShowWindow(struct Window *window) (A0) void HideWindow(struct Window *window) (A0) struct Region *ChangeWindowShape(struct Window *window, struct Region *newshape, struct Hook *callback) (A0, A1, A2) void SetDefaultScreenFont(struct TextFont *textfont) (A0) IPTR DoNotify(Class *cl, Object *o, struct ICData *ic, struct opUpdate *msg) (A0, A1, A2, A3) void FreeICData(struct ICData *icdata) (A0) struct IntuiMessage *AllocIntuiMessage(struct Window *window) (A0) void FreeIntuiMessage(struct IntuiMessage *imsg) (A0) void SendIntuiMessage(struct Window *window, struct IntuiMessage *imsg) (A0, A1) void ChangeDecoration(ULONG ID, struct NewDecorator *decor) (D0, A0) void WindowAction(struct Window *window, ULONG action, struct TagItem *tags) (A0, D0, A1) void ScrollWindowRasterNoFill(struct Window *win, WORD dx, WORD dy, WORD xmin, WORD ymin, WORD xmax, WORD ymax) (A1, D0, D1, D2, D3, D4, D5) ULONG SetPointerBounds(struct Screen *screen, struct Rectangle *rect, ULONG reserved, struct TagItem *tags) (A0, A1, D0, A2) IPTR StartScreenNotifyTagList(struct TagItem *tags) (A0) BOOL EndScreenNotify(IPTR notify) (A0) Object **GetMonitorList(struct TagItem *tags) (A1) void FreeMonitorList(Object **list) (A1)