Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / c / iprefs / wbpatternprefs.c
blobb287bf72b3163a9961cfcf0db07f15664d32b12d
1 /*
2 Copyright © 2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*********************************************************************************************/
11 #include "global.h"
13 #include <prefs/prefhdr.h>
14 #include <prefs/wbpattern.h>
15 #include <datatypes/pictureclass.h>
17 #define DEBUG 0
18 #include <aros/debug.h>
20 /*********************************************************************************************/
22 struct FileWBPatternPrefs
24 UBYTE wbp_Reserved[4 * 4];
25 UBYTE wbp_Which[2];
26 UBYTE wbp_Flags[2];
27 UBYTE wbp_Revision;
28 UBYTE wbp_Depth;
29 UBYTE wbp_DataLength[2];
32 struct LayerHookMsg
34 struct Layer *lay; /* not valid for layerinfo backfill hook!!! */
35 struct Rectangle bounds;
36 LONG offsetx;
37 LONG offsety;
40 struct LayerHookData
42 struct BitMap *pat_bm;
43 ULONG pat_width;
44 ULONG pat_height;
47 /*********************************************************************************************/
49 static LONG stopchunks[] =
51 ID_PREF, ID_PTRN
54 /*********************************************************************************************/
56 static void RootPatternSetup(STRPTR filename);
58 /*********************************************************************************************/
60 void WBPatternPrefs_Handler(STRPTR filename)
62 struct IFFHandle *iff;
64 D(bug("In IPrefs:WBPatternPrefs_Handler\n"));
66 if ((iff = CreateIFF(filename, stopchunks, 1)))
68 while(ParseIFF(iff, IFFPARSE_SCAN) == 0)
70 struct ContextNode *cn;
71 struct FileWBPatternPrefs wbpatternprefs;
73 cn = CurrentChunk(iff);
75 D(bug("WBPatternPrefs_Handler: ParseIFF okay. Chunk Type = %c%c%c%c ChunkID = %c%c%c%c\n",
76 cn->cn_Type >> 24,
77 cn->cn_Type >> 16,
78 cn->cn_Type >> 8,
79 cn->cn_Type,
80 cn->cn_ID >> 24,
81 cn->cn_ID >> 16,
82 cn->cn_ID >> 8,
83 cn->cn_ID));
85 if ((cn->cn_ID == ID_PTRN) && (cn->cn_Size > sizeof(wbpatternprefs)))
87 D(bug("WBPatternPrefs_Handler: ID_FONT chunk with correct size found.\n"));
89 if (ReadChunkBytes(iff, &wbpatternprefs, sizeof(wbpatternprefs)) == sizeof(wbpatternprefs))
91 UWORD type;
92 UWORD len;
93 STRPTR filename;
95 D(bug("WBPatternPrefs_Handler: Reading of ID_PTRN chunk okay.\n"));
97 type = (wbpatternprefs.wbp_Which[0] << 8) + wbpatternprefs.wbp_Which[1];
98 len = (wbpatternprefs.wbp_DataLength[0] << 8) + wbpatternprefs.wbp_DataLength[1];
100 D(bug("Type = %d Len = %d\n", type, len));
102 if (sizeof(wbpatternprefs) + len == cn->cn_Size)
104 filename = (STRPTR)AllocVec(len + 1, MEMF_ANY);
105 if (filename != NULL)
107 if (ReadChunkBytes(iff, filename, len) == len)
109 filename[len] = 0;
110 D(bug("Filename = %s\n", filename));
111 switch(type)
113 case WBP_ROOT:
114 RootPatternCleanup();
115 RootPatternSetup(filename);
116 break;
117 case WBP_DRAWER:
118 break;
119 case WBP_SCREEN:
120 break;
121 } /* switch(type) */
122 } /* if (ReadChunkBytes(iff, filename, len + 1) == len + 1) */
123 FreeVec(filename);
124 } /* if (filename != NULL) */
125 } /* if (sizeof(wbpatternprefs) + len + 1 == cn->cn_Size) */
126 } /* if (ReadChunkBytes(iff, &wbpatternprefs, sizeof(wbpatternprefs)) == sizeof(wbpatternprefs)) */
128 } /* if ((cn->cn_ID == ID_FONT) && (cn->cn_Size == sizeof(wbpatternprefs))) */
130 } /* while(ParseIFF(iff, IFFPARSE_SCAN) == 0) */
132 KillIFF(iff);
134 } /* if ((iff = CreateIFF(filename))) */
137 D(bug("In IPrefs:WBPatternPrefs_Handler. Done.\n", filename));
140 /****************************************************************************************/
142 static void mybackfillfunc(struct Hook *hook,struct RastPort *rp, struct LayerHookMsg *msg)
144 struct RastPort myrp;
145 struct LayerHookData *data = (struct LayerHookData *)hook->h_Data;
146 WORD x1,y1,x2,y2,px,py,pw,ph;
148 myrp = *rp;
150 myrp.Layer = 0;
152 x1 = msg->bounds.MinX;
153 y1 = msg->bounds.MinY;
154 x2 = msg->bounds.MaxX;
155 y2 = msg->bounds.MaxY;
157 px = x1 % data->pat_width;
159 pw = data->pat_width - px;
163 y1 = msg->bounds.MinY;
164 py = y1 % data->pat_height;
166 ph = data->pat_height - py;
168 if (pw > (x2 - x1 + 1)) pw = x2 - x1 + 1;
172 if (ph > (y2 - y1 + 1)) ph = y2 - y1 + 1;
174 BltBitMap(data->pat_bm,
177 rp->BitMap,
182 192,
183 255,
186 y1 += ph;
188 py = 0;
189 ph = data->pat_height;
191 } while (y1 <= y2); /* while(y1 < y2) */
193 x1 += pw;
195 px = 0;
196 pw = data->pat_width;
198 } while (x1 <= x2); /* while (x1 < x2) */
203 /****************************************************************************************/
205 static struct Hook *installbackfillhook(struct Screen *scr, struct Hook *backfillhook,
206 struct LayerHookData *data)
208 struct Window *tempwin;
209 struct Hook *oldhook;
211 struct TagItem wintags[] =
213 {WA_PubScreen ,(IPTR)scr },
214 {WA_Left ,0 },
215 {WA_Top ,0 },
216 {WA_Width ,scr->Width },
217 {WA_Height ,scr->Height },
218 {WA_Borderless ,TRUE },
219 {WA_Backdrop ,TRUE },
220 {WA_BackFill ,(IPTR)LAYERS_NOBACKFILL },
221 {TAG_DONE }
224 backfillhook->h_Entry = HookEntry;
225 backfillhook->h_SubEntry = (HOOKFUNC)mybackfillfunc;
226 backfillhook->h_Data = data;
228 oldhook = InstallLayerInfoHook(&scr->LayerInfo, backfillhook);
229 tempwin = OpenWindowTagList(NULL, wintags);
230 if (tempwin) CloseWindow(tempwin);
231 return oldhook;
234 /****************************************************************************************/
236 static void removebackfillhook(struct Screen *scr, struct Hook *oldhook)
238 struct TagItem wintags[] =
240 { WA_PubScreen , (IPTR)scr },
241 { WA_Left , 0 },
242 { WA_Top , 0 },
243 { WA_Width , scr->Width },
244 { WA_Height , scr->Height },
245 { WA_Borderless, TRUE },
246 { WA_Backdrop , TRUE },
247 { WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
248 { TAG_DONE }
250 struct Window *tempwin;
252 InstallLayerInfoHook(&scr->LayerInfo, oldhook);
253 tempwin = OpenWindowTagList(NULL, wintags);
254 if (tempwin) CloseWindow(tempwin);
257 /*********************************************************************************************/
259 static struct BitMap *LoadDTBitmap (CONST_STRPTR filename, struct Screen *scr,
260 Object **obj, ULONG *width, ULONG *height)
262 struct BitMapHeader *bmhd;
263 struct BitMap *bitmap = NULL;
264 Object *o;
265 struct Process *myproc = (struct Process *)FindTask(NULL);
266 APTR oldwindowptr = myproc->pr_WindowPtr;
268 myproc->pr_WindowPtr = (APTR)-1;
270 o = NewDTObject((APTR)filename,
271 DTA_GroupID , GID_PICTURE,
272 OBP_Precision , PRECISION_EXACT,
273 PDTA_Screen , (IPTR)scr,
274 PDTA_FreeSourceBitMap, TRUE,
275 PDTA_DestMode , PMODE_V43,
276 PDTA_UseFriendBitMap , TRUE,
277 TAG_DONE);
279 myproc->pr_WindowPtr = oldwindowptr;
281 if (o)
283 struct FrameInfo fri = {0};
284 DoMethod(o, DTM_FRAMEBOX, (IPTR) NULL, (IPTR) &fri, (IPTR) &fri,
285 sizeof(struct FrameInfo), 0);
287 if (fri.fri_Dimensions.Depth > 0)
289 if (DoMethod(o, DTM_PROCLAYOUT, (IPTR) NULL, 1))
291 *obj = o;
292 GetDTAttrs(o, PDTA_BitMapHeader, (IPTR)&bmhd, TAG_DONE);
293 if (bmhd)
295 *width = bmhd->bmh_Width;
296 *height = bmhd->bmh_Height;
297 GetDTAttrs(o, PDTA_DestBitMap, (IPTR)&bitmap, TAG_DONE);
298 if (NULL == bitmap)
299 GetDTAttrs(o, PDTA_BitMap, (IPTR)&bitmap, TAG_DONE);
300 if (bitmap)
301 return bitmap;
306 DisposeDTObject(o);
308 return NULL;
311 /*********************************************************************************************/
313 static Object *myDTObject = NULL;
314 static struct Hook *myOldHook = (APTR)-1; // NULL is a valid value
315 static struct Screen *myScreen = NULL;
316 static struct LayerHookData myData;
317 static struct Hook myBackFillHook;
319 /*********************************************************************************************/
321 static void RootPatternSetup(STRPTR filename)
323 struct BitMap *patternbm = NULL;
324 ULONG w;
325 ULONG h;
327 if ((myScreen = LockPubScreen(NULL)) != NULL)
329 D(bug("loading '%s'\n", filename));
330 patternbm = LoadDTBitmap(filename, myScreen, &myDTObject, &w, &h);
332 if (patternbm)
334 myData.pat_bm = patternbm;
335 myData.pat_width = w;
336 myData.pat_height = h;
338 myOldHook = installbackfillhook(myScreen, &myBackFillHook, &myData);
339 D(bug("oldhook=%p\n", myOldHook));
344 /*********************************************************************************************/
346 void RootPatternCleanup (void)
348 if (myOldHook != (APTR)-1)
350 D(bug("Reinstalling old backfillhook\n"));
351 removebackfillhook(myScreen, myOldHook);
352 myOldHook = (APTR)-1;
354 if (myDTObject)
356 D(bug("Disposing DT obj\n"));
357 DisposeDTObject(myDTObject);
358 myDTObject = NULL;
360 if (myScreen)
362 D(bug("Unlock PubScreen\n"));
363 UnlockPubScreen(NULL, myScreen);
364 myScreen = NULL;