Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / popupmenu / window.c
blobfac7b4316d7c34280f59e7196c559e10de18f729
1 //
2 // Popup Menu Window funcs
3 // ©1996-2002 Henrik Isaksson
4 //
6 #include "pmpriv.h"
8 //
9 // Allocate memory and copy a RastPort structure
11 struct RastPort *PM_CpyRPort(struct RastPort *rp)
13 #ifdef __AROS__
14 return CloneRastPort(rp);
15 #else
16 struct RastPort *rpc;
18 rpc=PM_Mem_Alloc(sizeof(struct RastPort));
19 if(rpc) {
20 CopyMem(rp, rpc, sizeof(struct RastPort));
23 return rpc;
24 #endif
28 // Copy the region beneath a window to the transparency buffer.
30 void PM_TransparencyBfr(struct PM_Window *bw)
32 int j, bpp;
33 ULONG transparent = FALSE;
35 #ifndef __AROS__
36 GetGUIAttrs(NULL, bw->p->DrawInfo, GUIA_MenuTransparency, &transparent, TAG_DONE);
37 #endif
39 if(CyberGfx && transparent) {
40 if(GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_ISCYBERGFX)) {
41 bpp = GetCyberMapAttr(bw->Wnd->WScreen->RastPort.BitMap, CYBRMATTR_BPPIX);
42 if(bpp<2)
43 return;
44 } else return;
46 // If we've gotten this far, the screen is CyberGfx and > 15 bpp
48 bw->bg.BgArray = PM_Mem_Alloc(3 * bw->Width * bw->Height);
49 if(bw->bg.BgArray) {
50 ReadPixelArray(bw->bg.BgArray, 0, 0,
51 bw->Width * 3, bw->RPort, 0, 0,
52 bw->Width, bw->Height, RECTFMT_RGB);
53 // Fast and simple way to blend the background to gray...
54 for(j = 0; j < bw->Width * bw->Height * 3; j++) {
55 bw->bg.BgArray[j] = (bw->bg.BgArray[j]>>2) + 150;
62 // Create an offscreen buffer for rendering animation and transition
63 // effects.
65 void PM_OffScreenBfr(struct PM_Window *bw)
67 if(PM_Prefs->pmp_Animation) {
68 bw->te.BMap=AllocBitMap(bw->Width, bw->Height, bw->Wnd->WScreen->RastPort.BitMap->Depth, BMF_MINPLANES, bw->Wnd->WScreen->RastPort.BitMap);
69 if(bw->te.BMap) {
70 bw->te.RPort=PM_CpyRPort(&bw->Wnd->WScreen->RastPort);
71 if(bw->te.RPort) {
72 bw->te.RPort->Layer = NULL; /* huuu! */
73 bw->te.RPort->BitMap = bw->te.BMap;
80 // Open a window
82 BOOL PM_OpenWindow(struct PM_Window *pw, int left, int top, int width, int height, struct Screen *scr)
84 pw->bg.BgArray = NULL;
85 pw->te.RPort = NULL;
86 pw->te.BMap = NULL;
87 pw->Wnd = OpenWindowTags(NULL,
88 WA_Borderless, TRUE,
89 WA_RMBTrap, TRUE,
90 WA_Left, left,
91 WA_Top, top,
92 WA_Width, width,
93 WA_Height, height,
94 //WA_ReportMouse, TRUE,
95 WA_CustomScreen, scr,
96 //WA_IDCMP, IDCMP_CLOSEWINDOW, // Kommer aldrig att inträffa - anv. för resize
97 WA_SmartRefresh, TRUE,
98 WA_BackFill, LAYERS_NOBACKFILL,
99 TAG_DONE);
101 if(pw->Wnd) {
102 pw->RPort = pw->Wnd->RPort;
104 /* Transparency/background image */
105 PM_TransparencyBfr(pw);
107 /* Transition effects */
108 PM_OffScreenBfr(pw);
110 return TRUE;
111 } else {
112 DisplayBeep(NULL);
113 return FALSE;
118 // Close a window
120 void PM_CloseWindow(struct PM_Window *bw)
122 if(bw->bg.BgArray) PM_Mem_Free(bw->bg.BgArray);
123 #ifdef __AROS__
124 if(bw->te.RPort) FreeRastPort(bw->te.RPort);
125 #else
126 if(bw->te.RPort) PM_Mem_Free(bw->te.RPort);
127 #endif
128 if(bw->te.BMap) FreeBitMap(bw->te.BMap);
129 if(bw->Wnd) CloseWindow(bw->Wnd);
131 bw->bg.BgArray = NULL;
132 bw->te.RPort = NULL;
133 bw->te.BMap = NULL;
134 bw->Wnd = NULL;
138 // Resize a window
140 void PM_ResizeWindow(struct PM_Window *bw, int l, int t, int w, int h)
142 struct Message *msg;
144 if(l==bw->Wnd->LeftEdge && t==bw->Wnd->TopEdge && w==bw->Width && h==bw->Height)
145 return; // If no change
147 ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE);
148 ChangeWindowBox(bw->Wnd, l, t, w, h);
149 WaitPort(bw->Wnd->UserPort);
150 while((msg=GetMsg(bw->Wnd->UserPort))) ReplyMsg(msg);
151 ModifyIDCMP(bw->Wnd, IDCMP_CLOSEWINDOW);
153 // bw->Width=bw->wnd->Width;
154 // bw->Height=bw->wnd->Height;
158 // Find out if we should close our submenu
162 // PM_InsideWindows(px, py, wnd)
164 // px, py - Screen coords
165 // wnd - PM_Window
168 BOOL PM_InsideWindows(int px, int py, struct PM_Window *wnd)
170 int x=px;
171 int y=py;
172 struct PM_Window *w;
174 w = wnd->Prev;
176 if(w) {
177 if(w->Selected) {
178 if(px > w->Wnd->LeftEdge + w->Selected->Left - 2 &&
179 px < w->Wnd->LeftEdge + w->Selected->Left + w->Selected->Width + 2 &&
180 py > w->Wnd->TopEdge + w->Selected->Top - 2 &&
181 py < w->Wnd->TopEdge + w->Selected->Top + w->Selected->Height + 2)
182 return FALSE;
186 while(w) {
187 if(x > w->Wnd->LeftEdge &&
188 y >= w->Wnd->TopEdge &&
189 x < w->Wnd->LeftEdge + w->Width &&
190 y < w->Wnd->TopEdge + w->Height) {
191 return TRUE;
193 w=w->Prev;
196 return FALSE;