WIP add of commodities support.
[AROS.git] / workbench / tools / BoingIconBar / iconbar.c
blob6c1c2abf037c825b92fa53d254facf04cfbb5c5d
1 //////////////////////////////////////////////////////////////
2 // //
3 // AROS PORT by LuKeJerry (at) gmail.com //
4 // Based on the program version with standard window //
5 // + BackFill //
6 // //
7 // -- last update: 26-04-2012 //
8 // - Fixed the notification //
9 // - Use D(bug()) macros //
10 // -------------------------------------------------------- //
11 // //
12 // -- translated to ENG from 26-09-2011 //
13 // -- converted TABs to 4-Spaces //
14 // //
15 // - FIXME: //
16 // //
17 // . When there are more icons than the screen width //
18 // can handle, exceeding icons should appear in the //
19 // next submenu. Seems that icon space is allocated, //
20 // but icon is not appearing //
21 // Look in: Read_Prefs( and SetWindowParameters( //
22 // //
23 // TO DO: //
24 // //
25 // - Even in static mode, put BiB window //
26 // active when mouse cursor goes to very //
27 // bottom of screen //
28 // //
29 // - Add possibility to show icon labels //
30 // - Add support for screennotify //
31 // - Add support for d&d to add an icon to a dock //
32 // - Add commodities CX support //
33 // //
34 //////////////////////////////////////////////////////////////
36 #define DEBUG 1
37 #include <aros/debug.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <proto/workbench.h>
43 #include <proto/icon.h>
44 #include <proto/exec.h>
45 #include <proto/intuition.h>
46 #include <proto/graphics.h>
47 #include <proto/gadtools.h>
48 #include <proto/dos.h>
49 #include <proto/datatypes.h>
50 #include <proto/commodities.h>
51 #include <proto/alib.h>
52 #include <exec/types.h>
53 #include <exec/libraries.h>
54 #include <workbench/icon.h>
55 #include <workbench/startup.h>
56 #include <intuition/intuition.h>
57 #include <intuition/imageclass.h>
58 #include <datatypes/datatypes.h>
59 #include <datatypes/pictureclass.h>
60 #include <devices/rawkeycodes.h>
61 #include <dos/dos.h>
63 #define SUM_ICON 200
64 #define ICON_ACTIVE (1<<7)
65 #define SELECTED_ICON (1<<6)
67 #define TEMPLATE "SPACE/N/K,STATIC/N/K,AUTOREMAP/S,BACKGROUND/S"
68 #define ARG_SPACE 0
69 #define ARG_STATIC 1
70 #define ARG_AUTOREMAP 2
71 #define ARG_BACKGROUND 3
73 #define BIB_PREFS "ENV:Iconbar.prefs"
75 /*****************************************************************************/
77 static BOOL BiB_Exit = FALSE,
78 Icon_Remap = FALSE,
79 Bar_Background = FALSE,
80 PositionMenuOK = FALSE,
81 // Image = FALSE, // <--- FIXME: "Image" seems not used at all
82 Window_Active = FALSE,
83 Window_Open = FALSE,
84 MenuWindow_Open = FALSE,
85 FirstOpening = TRUE;
87 static int Static = 0,
88 Spacing = 5,
89 CurrentLevel = 0,
90 lbm = 0,
91 rbm = 0;
93 static int WindowHeight,
94 WindowWidth,
95 ScreenHeight,
96 ScreenWidth,
97 IconWidth,
98 // ImageWidth,
99 // ImageHeight, // <--- FIXME: ...also: ImageWidth, ImageHeight not used at all
100 Position,
101 OldPosition,
102 IconCounter,
103 LevelCounter,
104 MouseIcon,
105 Lenght,
106 BeginningWindow,
107 EndingWindow,
108 Window_Max_X,
109 Window_Max_Y;
111 const char version[] = "$VER: BoingIconBar 1.02 (26.04.2012) ©2012 Robert 'Phibrizzo' Krajcarz";
113 static char //Background_name[256], // <-- FIXME: Background_name not used at all,
114 BufferList[20], // but might be interesting to implement
115 MovingTable[8] = {0, 4, 7, 9, 10, 9, 7, 4};
117 static ULONG WindowMask,
118 MenuMask,
119 CxSigMask,
120 NotifMask,
121 WindowSignal;
123 static IPTR args[] = {(IPTR)&Spacing, (IPTR)&Static, 0, 0};
125 /*****************************************************************************/
127 static struct DiskObject *Icon[SUM_ICON];
129 static struct Window *Window_struct, *MenuWindow_struct; // FIXME: really ugly _struct names...
130 static struct Screen *Screen_struct;
132 static struct BitMap *BMP_Buffer, *BMP_DoubleBuffer;
133 static struct RastPort RP_Buffer, RP_DoubleBuffer;
134 static CxObj *broker;
136 // struct of icons
138 static struct Icon_Struct
140 int Icon_Height; // icon height
141 int Icon_Width; // icon width
142 int Icon_PositionX; // X position on main window
143 int Icon_PositionY; // Y position on main window
144 int Icon_Status; // status of icon: normal or selected
145 BOOL Icon_OK; // everything OK with icon
146 char Icon_Path[255]; // name to path of icon
147 } Icons_Struct[SUM_ICON];
149 // struct of submenu
151 static struct Level_Struct
153 char Level_Name[20]; // name submenu - level name
154 int Beginning; // first icon on menu
155 int WindowPos_X; // X position main window
156 int WindowPos_Y; // Y position main window
157 } Levels_Struct[11];
159 static struct TextAttr Topaz8 = {"topaz.font",8,0,FPF_ROMFONT};
161 static struct IntuiText Names = {1,0,JAM1,0,0,&Topaz8,BufferList,NULL};
163 // background pictures
165 static Object *picture[3];
166 static struct BitMap *bm[3];
168 static struct Struct_BackgroundData
170 int Width; // width
171 int Height; // height
172 } BackgroundData[3];
174 static struct NewBroker newbroker = {
175 NB_VERSION,
176 "BoingIconBar", // string to identify this broker
177 "Icon Toolbar",
178 "Start Programs from Toolbar",
179 NBU_UNIQUE | NBU_NOTIFY,
180 0, 0, 0, 0
183 /*****************************************************************************/
184 // functions
185 static int ReadPrefs(void); // load prefs
186 static void LoadBackground(void); //load background pictures
187 static void SetWindowParameters(void); // check window sizes
188 static void Decode_IDCMP(struct IntuiMessage *KomIDCMP); // decode IDCMP main signals
189 static void Change_State(int Reset); // change icon state
190 static void Insert_Icon(int Tryb, int IconNumber); // draw icon
191 static void Blink_Icon(int IconNumber); // blink the icon
192 static BOOL OpenMainWindow(void); // open main window
193 static void CloseMainWindow(void); // close main window
194 static void CheckMousePosition(void); // check mouse position
195 static void Show_Selected_Level(void); // change the submenu
196 static void OpenMenuWindow(void); // open menu window
197 static void CloseMenuWindow(void); // close menu window
198 static void Decode_IDCMP2(struct IntuiMessage *KomIDCMP); // decode IDCMP menu signals
199 static void Launch_Program(char *Program); // start the chosed program
200 static void Settings(void); // open the prefs program
201 static void Reload_BiB(void); // reload the BiB
204 /*****************************************************************************/
206 int main(int argc, char *argv[])
208 int x, outt = FALSE;
210 struct IntuiMessage *KomIDCMP, KopiaIDCMP;
211 struct RDArgs *rda = NULL;
212 struct DiskObject *dob = NULL;
213 struct NotifyRequest *nr;
214 struct MsgPort *BIBport, *BrokerMP = NULL;
215 BOOL notification = FALSE;
216 BPTR out = BNULL;
217 int result = RETURN_OK;
219 if ((BrokerMP = CreateMsgPort()) != NULL)
221 newbroker.nb_Port = BrokerMP;
222 CxSigMask = 1L << BrokerMP->mp_SigBit;
223 broker = CxBroker(&newbroker, NULL);
224 if (broker == NULL)
226 D(bug("[IconBar] is already running\n"));
227 DeleteMsgPort(BrokerMP);
228 return 0;
232 ActivateCxObj(broker, 1);
233 D(bug("[IconBar] broker %p\n", broker));
235 // Read arguments
236 if (argc)
238 // Started from Shell
239 if (!(rda = ReadArgs(TEMPLATE, args, NULL)))
241 PrintFault(IoErr(), argv[0]);
242 return RETURN_FAIL;
245 if (args[ARG_AUTOREMAP]) Icon_Remap = TRUE;
247 if (args[ARG_BACKGROUND]) Bar_Background = TRUE;
249 out = Output();
250 } else {
251 // Started from WB: Read ToolTypes
252 struct WBStartup *wbs=(struct WBStartup*)argv;
253 struct WBArg *wba=&wbs->sm_ArgList[wbs->sm_NumArgs-1];
254 BPTR oldcd;
256 if (!(*wba->wa_Name))
258 return RETURN_FAIL;
261 oldcd=CurrentDir(wba->wa_Lock);
262 if ((dob=GetDiskObjectNew(wba->wa_Name)))
264 char *str;
266 if ((str=FindToolType(dob->do_ToolTypes, "SPACE")))
267 *(ULONG*)args[ARG_SPACE]=(ULONG)atoi(str);
269 if ((str=FindToolType(dob->do_ToolTypes, "STATIC")))
270 *(ULONG*)args[ARG_STATIC]=(ULONG)atoi(str);
272 if ((str=FindToolType(dob->do_ToolTypes, "AUTOREMAP")))
273 Icon_Remap = TRUE;
274 if ((str=FindToolType(dob->do_ToolTypes, "BACKGROUND")))
275 Bar_Background = TRUE;
278 CurrentDir(oldcd);
279 outt = TRUE;
282 if (out || outt)
284 Spacing = *(LONG*)args[ARG_SPACE];
285 Static = *(LONG*)args[ARG_STATIC];
288 D(bug("[IconBar] Specified options: SPACE=%d, STATIC=%d, AUTOREMAP=%d\n", Spacing, Static, Icon_Remap));
290 // Read the prefs file, fail if it doesn't exist
291 if(ReadPrefs())
293 // Set notification of prefs change
294 if ((BIBport = CreateMsgPort()))
296 if ((nr = AllocMem(sizeof(struct NotifyRequest), MEMF_CLEAR)))
298 nr->nr_Name = BIB_PREFS;
300 D(bug("[IconBar] prefs filename: %s\n",nr->nr_Name));
302 nr->nr_Flags = NRF_SEND_MESSAGE;
303 nr->nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
304 nr->nr_stuff.nr_Msg.nr_Port = BIBport;
306 if (StartNotify(nr) != DOSFALSE)
308 notification = TRUE;
309 NotifMask = 1L << BIBport->mp_SigBit;
310 D(bug("[IconBar] Notification started\n"));
314 if (Bar_Background)
315 LoadBackground();
317 if(Static)
319 Delay(Static * 50);
320 OpenMainWindow();
321 FirstOpening = FALSE;
324 // ---- main loop
326 while (BiB_Exit==FALSE)
328 if (Window_Open || MenuWindow_Open)
330 WindowSignal = Wait(WindowMask | MenuMask | CxSigMask | NotifMask);
332 else
334 Delay(50);
335 CheckMousePosition();
336 WindowSignal = 0;
339 if(WindowSignal & WindowMask)
341 while((KomIDCMP = GT_GetIMsg(Window_struct->UserPort)))
343 CopyMem(KomIDCMP, &KopiaIDCMP, sizeof(struct IntuiMessage));
344 GT_ReplyIMsg(KomIDCMP);
345 Decode_IDCMP(&KopiaIDCMP);
348 if(!(Static) && Window_Active == FALSE) CloseMainWindow();
351 if(WindowSignal & MenuMask)
353 while((KomIDCMP = GT_GetIMsg(MenuWindow_struct->UserPort)))
355 CopyMem(KomIDCMP, &KopiaIDCMP, sizeof(struct IntuiMessage));
356 GT_ReplyIMsg(KomIDCMP);
357 Decode_IDCMP2(&KopiaIDCMP);
360 if(MenuWindow_Open == FALSE) CloseMenuWindow();
363 if(WindowSignal & CxSigMask)
365 D(bug("[IconBar] Signal received\n"));
366 CxMsg *msg;
367 ULONG msgid, msgtype;
368 while((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL)
370 msgid = CxMsgID(msg);
371 msgtype = CxMsgType(msg);
372 ReplyMsg((struct Message *)msg);
374 switch(msgtype)
376 case CXM_COMMAND:
377 switch(msgid)
379 case CXCMD_DISABLE:
380 D(bug("[IconBar] CXCMD_DISABLE\n"));
381 ActivateCxObj(broker, 0L);
382 break;
383 case CXCMD_ENABLE:
384 D(bug("[IconBar] CXCMD_ENABLE\n"));
385 ActivateCxObj(broker, 1L);
386 break;
387 case CXCMD_KILL:
388 D(bug("[IconBar] CXCMD_KILL\n"));
389 BiB_Exit = TRUE;
390 break;
391 case CXCMD_UNIQUE:
392 D(bug("[IconBar] CXCMD_UNIQUE\n"));
393 BiB_Exit = TRUE;
394 break;
395 default:
396 D(bug("[IconBar] Unknown msgid\n"));
397 break;
399 break;
400 default:
401 D(bug("[IconBar] Unknown msgtype\n"));
402 break;
407 if(WindowMask & NotifMask)
409 if (GetMsg(BIBport) != NULL)
411 D(bug("[IconBar] Prefs modified!\n"));
412 Reload_BiB();
415 } // ---- end of main loop
417 // ---- close all
418 CloseMainWindow();
420 for(x=0; x<SUM_ICON; x++)
422 if(Icon[x] != NULL)
424 FreeDiskObject(Icon[x]);
428 if(BMP_Buffer) FreeBitMap(BMP_Buffer);
429 if(BMP_DoubleBuffer) FreeBitMap(BMP_DoubleBuffer);
431 for(x=0; x<3; x++)
433 if(picture[x]) DisposeDTObject(picture[x]);
436 // Close notification of prefs change
437 if(notification)
438 EndNotify(nr);
439 if(nr)
440 FreeMem(nr, sizeof(struct NotifyRequest));
441 if(BIBport)
442 DeleteMsgPort(BIBport);
444 } else {
445 D(bug("[IconBar] No prefs found!\n"));
446 result = RETURN_FAIL;
448 D(bug("[IconBar] Quitting...\n"));
450 if (broker) DeleteCxObjAll(broker);
451 if (BrokerMP)
453 CxMsg *msg;
454 while ((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL)
455 ReplyMsg((struct Message *)msg);
456 DeletePort(BrokerMP);
458 if (rda) FreeArgs(rda);
459 if (dob) FreeDiskObject(dob);
460 return(result);
463 /*****************************************************************************/
465 static int ReadPrefs(void)
467 BPTR Prefs;
468 int x, TextLenght, NumChars;
470 Icons_Struct[0].Icon_OK = FALSE;
471 IconCounter = 0;
472 LevelCounter = 0;
473 Lenght = 0;
475 if((Prefs = Open(BIB_PREFS, MODE_OLDFILE)))
477 FGets(Prefs, Icons_Struct[0].Icon_Path, 255);
479 if(strncmp(Icons_Struct[0].Icon_Path, "BOING_PREFS", 11) != 0)
481 Close(Prefs);
482 //FIXME: A better error handling might be added
483 D(bug("[IconBar] Prefs error\n"));
484 return(0);
487 if((Screen_struct = LockPubScreen(NULL)) != NULL)
489 while (FGets(Prefs, Icons_Struct[IconCounter].Icon_Path, 255))
491 NumChars = strlen(Icons_Struct[IconCounter].Icon_Path);
492 Icons_Struct[IconCounter].Icon_Path[NumChars-1] = '\0';
494 if (Icons_Struct[IconCounter].Icon_Path[0] == ';')
496 D(bug("[IconBar] Found a submenu! Name lenght = %d, last char = %d\n",
497 NumChars, Icons_Struct[IconCounter].Icon_Path[NumChars-1]));
499 if (NumChars > 20) NumChars = 20;
500 Icons_Struct[IconCounter].Icon_Path[19] = '\0';
502 for (x=1; x<NumChars; x++)
504 Levels_Struct[LevelCounter].Level_Name[x-1] = Icons_Struct[IconCounter].Icon_Path[x];
507 D(bug("[IconBar] x after \'for\' = %d\n", x));
509 strcpy(BufferList, Levels_Struct[LevelCounter].Level_Name);
511 D(bug("[IconBar] Level name: %s\n", Levels_Struct[LevelCounter].Level_Name));
513 TextLenght = IntuiTextLength(&Names);
515 if (TextLenght > Lenght) Lenght = TextLenght;
517 D(bug("[IconBar] IntuiTextLenght = %d\n", TextLenght));
519 D(bug("[IconBar] Submenu %d - %s, beginning %d\n",
520 LevelCounter, Levels_Struct[LevelCounter].Level_Name, Levels_Struct[LevelCounter].Beginning));
522 Levels_Struct[LevelCounter].Beginning = IconCounter;
523 LevelCounter++;
524 } else {
525 D(bug("[IconBar] Loading icon #%d - name: %s\n", IconCounter, Icons_Struct[IconCounter].Icon_Path));
527 if ((Icon[IconCounter] = GetIconTags(Icons_Struct[IconCounter].Icon_Path,
528 ICONGETA_RemapIcon, FALSE,
529 TAG_DONE)))
531 IconControl(Icon[IconCounter],
532 ICONCTRLA_GetWidth, &Icons_Struct[IconCounter].Icon_Width,
533 ICONCTRLA_GetHeight, &Icons_Struct[IconCounter].Icon_Height,
534 ICONCTRLA_SetNewIconsSupport, TRUE,
535 TAG_END);
537 if (Icons_Struct[IconCounter].Icon_Width == 0)
539 Icons_Struct[IconCounter].Icon_Width = Icon[IconCounter]->do_Gadget.Width;
542 if (Icons_Struct[IconCounter].Icon_Height == 0)
544 Icons_Struct[IconCounter].Icon_Height = Icon[IconCounter]->do_Gadget.Height;
547 LayoutIcon(Icon[IconCounter], Screen_struct, NULL);
549 D(bug("[IconBar] Dimension icon #%d: Widht=%d Height=%d\n",
550 IconCounter, Icons_Struct[IconCounter].Icon_Width, Icons_Struct[IconCounter].Icon_Height));
552 D(bug("[IconBar] Icon %d loaded\n", IconCounter));
554 Icons_Struct[IconCounter].Icon_OK = TRUE;
555 IconCounter++;
557 if (IconCounter == SUM_ICON) break;
558 } else {
559 //FIXME: A better error handling might be added
560 D(bug("[IconBar] Not found icon %s.\n", Icons_Struct[IconCounter].Icon_Path));
564 Close(Prefs);
566 ScreenWidth = Screen_struct->Width;
567 ScreenHeight = Screen_struct->Height;
569 UnlockPubScreen(NULL, Screen_struct);
571 Levels_Struct[LevelCounter].Beginning = IconCounter;
573 D(bug("[IconBar] Screen size: Width=%d, Height=%d\n", ScreenWidth, ScreenHeight));
575 SetWindowParameters();
577 IconCounter = Levels_Struct[1].Beginning;
578 WindowWidth = Levels_Struct[0].WindowPos_X;
579 WindowHeight = Levels_Struct[0].WindowPos_Y;
581 BeginningWindow = (ScreenWidth>>1) - (WindowWidth>>1);
582 EndingWindow = (ScreenWidth>>1) + (WindowWidth>>1);
584 CurrentLevel = 0;
586 sprintf(Levels_Struct[LevelCounter].Level_Name, "Settings");
587 sprintf(Names.IText, "%s", Levels_Struct[LevelCounter].Level_Name);
589 TextLenght = IntuiTextLength(&Names);
591 if (TextLenght > Lenght) Lenght = TextLenght;
593 LevelCounter++;
595 Lenght = Lenght + 10;
596 } else {
597 //FIXME: A better error handling might be added
598 D(bug("[IconBar] Error reading screen parameters\n"));
602 return Icons_Struct[0].Icon_OK;
605 /*****************************************************************************/
607 static void LoadBackground(void)
609 int x;
611 STRPTR name[3] =
613 "SYS:System/Images/bibgfx/left" ,
614 "SYS:System/Images/bibgfx/middle",
615 "SYS:System/Images/bibgfx/right"
618 for (x=0; x<3; x++)
620 picture[x] = NewDTObject (name[x],
621 DTA_GroupID, GID_PICTURE,
622 PDTA_Remap, TRUE,
623 PDTA_DestMode, PMODE_V43,
624 OBP_Precision, PRECISION_IMAGE,
625 PDTA_Screen, (IPTR)Screen_struct,
626 TAG_END);
628 if (picture[x])
630 D(bug("[IconBar] Loading image n. %d - name: %s\n",x,name[x]));
632 DoDTMethod(picture[x], NULL, NULL, DTM_PROCLAYOUT, NULL, DTSIF_NEWSIZE);
634 GetDTAttrs
635 ( picture[x],
636 PDTA_DestBitMap, (SIPTR)&bm[x],
637 DTA_NominalHoriz, (SIPTR)&BackgroundData[x].Width,
638 DTA_NominalVert, (SIPTR)&BackgroundData[x].Height,
639 TAG_END
645 /*****************************************************************************/
647 static void SetWindowParameters(void)
650 int x, y;
652 Window_Max_X = 0;
653 Window_Max_Y = 0;
655 Icons_Struct[0].Icon_PositionX = 0;
657 for (y=0; y<(LevelCounter); y++)
659 WindowHeight = 0;
660 WindowWidth = 0;
662 IconCounter = Levels_Struct[y+1].Beginning;
664 for (x=Levels_Struct[y].Beginning; x<IconCounter; x++)
666 if (Icons_Struct[x].Icon_OK)
668 if (Icons_Struct[x].Icon_Height > WindowHeight)
670 WindowHeight = Icons_Struct[x].Icon_Height;
673 if (Icons_Struct[x].Icon_Width > IconWidth)
675 IconWidth = Icons_Struct[x].Icon_Width;
678 if ((WindowWidth + Icons_Struct[x].Icon_Width + 35) > ScreenWidth)
680 D(bug("[IconBar] Exceeding the size of the screen, can't display all icons!\n"));
682 IconCounter = x;
683 Levels_Struct[y+1].Beginning = x;
684 break;
687 WindowWidth = WindowWidth + Icons_Struct[x].Icon_Width + Spacing;
689 Icons_Struct[x].Icon_PositionY = 10;
691 if ((x+1) != IconCounter)
693 Icons_Struct[x+1].Icon_PositionX = WindowWidth;
696 else break;
699 for (x=Levels_Struct[y].Beginning; x<IconCounter; x++)
701 if (Icons_Struct[x].Icon_OK)
703 Icons_Struct[x].Icon_PositionX = Icons_Struct[x].Icon_PositionX + 15;
704 Icons_Struct[x].Icon_PositionY = (WindowHeight>>1) - (Icons_Struct[x].Icon_Height>>1) + 15;
708 Levels_Struct[y].WindowPos_X = WindowWidth + 30;
709 Levels_Struct[y].WindowPos_Y = WindowHeight + 20;
711 if (Levels_Struct[y].WindowPos_X > ScreenWidth)
712 Levels_Struct[y].WindowPos_X = WindowWidth;
714 if (Window_Max_X < Levels_Struct[y].WindowPos_X)
715 Window_Max_X = Levels_Struct[y].WindowPos_X;
717 if (Window_Max_Y < Levels_Struct[y].WindowPos_Y)
718 Window_Max_Y = Levels_Struct[y].WindowPos_Y;
720 D(bug("[IconBar] Window size %d: S=%d, W=%d\n", y, Levels_Struct[y].WindowPos_X, Levels_Struct[y].WindowPos_Y));
723 D(bug("[IconBar] Maximum window size: S=%d, W=%d\n", Window_Max_X, Window_Max_Y));
724 D(bug("[IconBar] Icon width: %d\n", IconWidth));
726 if((Screen_struct=LockPubScreen(NULL)) != NULL)
728 BMP_Buffer = AllocBitMap
730 Window_Max_X,
731 Window_Max_Y,
732 GetBitMapAttr(Screen_struct->RastPort.BitMap, BMA_DEPTH),
733 BMF_MINPLANES | BMF_CLEAR,
734 Screen_struct->RastPort.BitMap
737 InitRastPort(&RP_Buffer);
738 RP_Buffer.BitMap = BMP_Buffer;
739 RP_Buffer.Layer = NULL;
741 BMP_DoubleBuffer = AllocBitMap
743 IconWidth + 8,
744 Window_Max_Y,
745 GetBitMapAttr(Screen_struct->RastPort.BitMap, BMA_DEPTH),
746 BMF_MINPLANES | BMF_CLEAR,
747 Screen_struct->RastPort.BitMap
750 InitRastPort(&RP_DoubleBuffer);
751 RP_DoubleBuffer.BitMap = BMP_DoubleBuffer;
752 RP_DoubleBuffer.Layer = NULL;
754 UnlockPubScreen(NULL,Screen_struct);
758 /*****************************************************************************/
760 static void Decode_IDCMP(struct IntuiMessage *KomIDCMP)
762 int x;
764 // LJ: Temporary disabled mouse cases in function Decode_IDCMP
766 switch (KomIDCMP->Class)
768 case IDCMP_CLOSEWINDOW:
769 BiB_Exit = TRUE;
770 break;
772 case IDCMP_MOUSEMOVE:
773 for(MouseIcon=Levels_Struct[CurrentLevel].Beginning; MouseIcon<IconCounter; MouseIcon++)
775 if(Icons_Struct[MouseIcon].Icon_OK)
777 // too noisy: D(bug("[IconBar] Mouse position in the window X=%d, Y=%d\n",
778 // KomIDCMP->MouseX, KomIDCMP->MouseY));
780 if((ScreenHeight - Screen_struct->MouseY) > WindowHeight)
782 Window_Active = FALSE;
785 if(KomIDCMP->MouseX > Icons_Struct[MouseIcon].Icon_PositionX &&
786 KomIDCMP->MouseX < Icons_Struct[MouseIcon].Icon_PositionX + Icons_Struct[MouseIcon].Icon_Width &&
787 KomIDCMP->MouseY > 0 &&
788 KomIDCMP->MouseY < WindowHeight - 5)
790 if((Icons_Struct[MouseIcon].Icon_Status & ICON_ACTIVE) != ICON_ACTIVE)
792 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
794 Icons_Struct[x].Icon_Status = Icons_Struct[x].Icon_Status & 0x07;
797 Icons_Struct[MouseIcon].Icon_Status = ICON_ACTIVE | (SELECTED_ICON * lbm);
798 D(bug("[IconBar] Pointer on icon #%d\n", MouseIcon));
800 break;
802 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status & 0x07;
805 break;
807 case IDCMP_MOUSEBUTTONS:
808 switch (KomIDCMP->Code)
810 case SELECTDOWN:
811 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status | SELECTED_ICON;
812 lbm = 1;
814 D(bug("[IconBar] Icon #%d\n", MouseIcon));
815 break;
817 case SELECTUP:
818 lbm = 0;
820 if((Icons_Struct[MouseIcon].Icon_Status & (SELECTED_ICON | ICON_ACTIVE)) == (SELECTED_ICON | ICON_ACTIVE))
822 Blink_Icon(MouseIcon);
824 D(bug("[IconBar] Launching program function with param: %s\n",
825 Icons_Struct[MouseIcon].Icon_Path));
826 Launch_Program(Icons_Struct[MouseIcon].Icon_Path);
828 D(bug("[IconBar] Icon #%d confirmed\n", MouseIcon));
831 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status & 0xBF; //10001111b
833 break;
835 case MENUDOWN:
836 rbm = 1;
837 OpenMenuWindow();
838 break;
841 case IDCMP_RAWKEY:
842 switch(KomIDCMP->Code)
844 case RAWKEY_ESCAPE:
845 if((KomIDCMP->Qualifier) & IEQUALIFIER_LSHIFT)
847 BiB_Exit = TRUE;
849 break;
851 case RAWKEY_F1:
852 for(x=0; x<SUM_ICON; x++)
854 if(Icon[x] != NULL)
856 LayoutIcon(Icon[x],
857 Screen_struct,
858 NULL);
862 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
864 if(Icon[x] != NULL)
866 DrawIconState(Window_struct->RPort,
867 Icon[x],
868 NULL,
869 Icons_Struct[x].Icon_PositionX,
870 Icons_Struct[x].Icon_PositionY,
871 IDS_NORMAL,
872 ICONDRAWA_Frameless, TRUE,
873 ICONDRAWA_EraseBackground, FALSE,
874 TAG_DONE);
877 break;
879 case RAWKEY_F2:
880 case RAWKEY_NM_WHEEL_DOWN:
881 CurrentLevel++;
882 if(CurrentLevel == (LevelCounter -1 )) CurrentLevel = 0;
883 Show_Selected_Level();
884 break;
886 case RAWKEY_F3:
887 case RAWKEY_NM_WHEEL_UP:
888 CurrentLevel--;
889 if(CurrentLevel < 0) CurrentLevel = LevelCounter - 2;
890 Show_Selected_Level();
891 break;
893 case RAWKEY_F4:
894 Settings();
895 break;
897 break;
899 case IDCMP_INACTIVEWINDOW:
900 if(rbm == 0) Window_Active = FALSE;
901 lbm = 0;
903 if(Static)
905 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
907 if(Icons_Struct[x].Icon_Status != 0)
909 Icons_Struct[x].Icon_Status = 0;
910 Insert_Icon(IDS_NORMAL, x);
915 break;
917 case IDCMP_INTUITICKS:
918 Change_State(0);
919 break;
924 static void Change_State(int Reset)
926 int x;
928 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
930 if(Icons_Struct[x].Icon_OK)
932 if(Icons_Struct[x].Icon_Status != 0)
934 if(Reset == 0)
936 if((Icons_Struct[x].Icon_Status & ICON_ACTIVE) == 0 && Icons_Struct[x].Icon_Status < 4)
938 // 11000111b
939 Icons_Struct[x].Icon_Status = (Icons_Struct[x].Icon_Status - 1) & 0xC7;
941 else
943 Icons_Struct[x].Icon_Status = (Icons_Struct[x].Icon_Status + 1) & 0xC7;
946 else
948 Icons_Struct[x].Icon_Status = 0;
951 Insert_Icon((Icons_Struct[x].Icon_Status & SELECTED_ICON) ? IDS_SELECTED : IDS_NORMAL, x);
957 static void Insert_Icon(int Tryb, int IconNumber)
959 BltBitMapRastPort(BMP_Buffer,
960 Icons_Struct[IconNumber].Icon_PositionX,
962 &RP_DoubleBuffer, //Window_struct->RPort,
963 0, //Icons_Struct[IconNumber].Icon_PositionX,
965 Icons_Struct[IconNumber].Icon_Width + 1,
966 WindowHeight,
967 0xC0);
969 DrawIconState(&RP_DoubleBuffer, //Window_struct->RPort,
970 Icon[IconNumber],
971 NULL,
972 0, //Icons_Struct[IconNumber].Icon_PositionX,
973 Icons_Struct[IconNumber].Icon_PositionY - MovingTable[(Icons_Struct[IconNumber].Icon_Status & 0x07)],
974 Tryb,
975 ICONDRAWA_Frameless, TRUE,
976 ICONDRAWA_EraseBackground, FALSE,
977 TAG_DONE);
979 BltBitMapRastPort(BMP_DoubleBuffer,
982 Window_struct->RPort,
983 Icons_Struct[IconNumber].Icon_PositionX,
985 Icons_Struct[IconNumber].Icon_Width + 1,
986 WindowHeight,
987 0xC0);
990 static void Blink_Icon(int IconNumber)
992 int x, Tryb=IDS_SELECTED;
994 for(x=0; x<8; x++)
996 Insert_Icon(Tryb, IconNumber);
997 Delay(3);
999 if(Tryb == IDS_NORMAL) Tryb = IDS_SELECTED;
1000 else Tryb = IDS_NORMAL;
1004 static BOOL OpenMainWindow(void)
1006 int x, y, a;
1008 if((Screen_struct=LockPubScreen(NULL)) != NULL)
1010 BltBitMapRastPort(Screen_struct->RastPort.BitMap,
1011 (ScreenWidth>>1) - (WindowWidth>>1),
1012 ScreenHeight - WindowHeight,
1013 &RP_Buffer,
1014 0, 0,
1015 Window_Max_X,
1016 Window_Max_Y,
1017 0xC0);
1019 UnlockPubScreen(NULL,Screen_struct);
1022 if(picture[0] && picture[1] && picture[2])
1024 y = WindowWidth - BackgroundData[0].Width - BackgroundData[2].Width;
1025 a = y / BackgroundData[1].Width;
1027 BltBitMapRastPort(bm[0],
1030 &RP_Buffer,
1032 WindowHeight - BackgroundData[0].Height,
1033 BackgroundData[0].Width,
1034 BackgroundData[0].Height,
1035 0xC0);
1037 for(x=0; x<a; x++)
1039 BltBitMapRastPort(bm[1],
1042 &RP_Buffer,
1043 BackgroundData[0].Width + x * BackgroundData[1].Width,
1044 WindowHeight - BackgroundData[1].Height,
1045 BackgroundData[1].Width,
1046 BackgroundData[1].Height,
1047 0xC0);
1050 BltBitMapRastPort(bm[1],
1053 &RP_Buffer,
1054 BackgroundData[0].Width + x * BackgroundData[1].Width,
1055 WindowHeight - BackgroundData[1].Height,
1056 y - BackgroundData[1].Width * a,
1057 BackgroundData[1].Height,
1058 0xC0);
1060 BltBitMapRastPort(bm[2],
1063 &RP_Buffer,
1064 WindowWidth - BackgroundData[2].Width,
1065 WindowHeight - BackgroundData[2].Height,
1066 BackgroundData[2].Width,
1067 BackgroundData[2].Height,
1068 0xC0);
1069 } else if(picture[1]) {
1070 for(x=0; x<WindowWidth; x=x+BackgroundData[1].Width)
1072 BltBitMapRastPort(bm[1],
1075 &RP_Buffer,
1077 WindowHeight - BackgroundData[1].Height,
1078 BackgroundData[1].Width,
1079 BackgroundData[1].Height,
1080 0xC0);
1084 if(Icon_Remap == TRUE)
1086 D(bug("[IconBar] Iconremap is true!\n"));
1088 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1090 if(Icon[x]!=NULL)
1092 // D(bug("[Iconbar] Icon#%d-%s was not NULL, so LayoutIcon Adapt a palette-mapped icon to display\n", x, Icons_Struct[x].Icon_Path);
1093 LayoutIcon(Icon[x], Screen_struct, NULL);
1098 D(bug("[IconBar] Opening window: S=%d, W=%d\n", WindowWidth, WindowHeight));
1100 if((Window_struct = OpenWindowTags(NULL,
1101 WA_Left, BeginningWindow,
1102 WA_Top, ScreenHeight - WindowHeight,
1103 WA_InnerWidth, WindowWidth,
1104 WA_InnerHeight, WindowHeight,
1105 WA_ReportMouse, TRUE,
1106 WA_MouseQueue, 3,
1107 WA_Borderless, TRUE,
1108 WA_SizeGadget, FALSE,
1109 WA_Activate, ((FirstOpening && Static) ? FALSE : TRUE),
1110 WA_PubScreenName, NULL,
1111 WA_BackFill, LAYERS_NOBACKFILL,
1112 WA_Flags, WFLG_NOCAREREFRESH|
1113 WFLG_SMART_REFRESH|
1114 WFLG_RMBTRAP,
1115 WA_IDCMP, IDCMP_NEWSIZE|
1116 IDCMP_RAWKEY|
1117 IDCMP_INACTIVEWINDOW|
1118 IDCMP_MOUSEMOVE|
1119 IDCMP_INTUITICKS|
1120 IDCMP_MOUSEBUTTONS,
1121 TAG_END)))
1123 D(bug("[IconBar] Window opened\n"));
1125 WindowMask = 1 << Window_struct->UserPort->mp_SigBit;
1127 BltBitMapRastPort(BMP_Buffer,
1128 0, 0,
1129 Window_struct->RPort,
1130 0, 0,
1131 WindowWidth,
1132 WindowHeight,
1133 0xC0);
1135 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1137 if(Icon[x] != NULL)
1139 DrawIconState(Window_struct->RPort,
1140 Icon[x],
1141 NULL,
1142 Icons_Struct[x].Icon_PositionX,
1143 Icons_Struct[x].Icon_PositionY,
1144 IDS_NORMAL,
1145 ICONDRAWA_Frameless, TRUE,
1146 ICONDRAWA_EraseBackground, FALSE,
1147 TAG_DONE);
1150 } else {
1151 D(bug("[IconBar] Can't open main toolbar window\n"));
1152 return FALSE;
1155 Window_Open = TRUE;
1156 Window_Active = TRUE;
1158 return TRUE;
1161 static void CloseMainWindow(void)
1163 D(bug("[IconBar] ClosingMainWindow...\n"));
1165 int x;
1167 if(Window_struct) CloseWindow(Window_struct);
1169 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1171 Icons_Struct[x].Icon_Status = 0;
1174 Window_Open = FALSE;
1175 WindowMask = 0;
1178 static void CheckMousePosition(void)
1180 // noisy: D(bug("[IconBar] Mouse current position: Y=%d\n", Screen_struct->MouseY));
1182 if((Screen_struct->MouseY == ScreenHeight - 1) &&
1183 Window_Open == FALSE &&
1184 Screen_struct->MouseX > BeginningWindow &&
1185 Screen_struct->MouseX < EndingWindow)
1187 D(bug("[IconBar] Opening the window\n"));
1188 if(OpenMainWindow() == FALSE)
1190 BiB_Exit = TRUE;
1194 // LJ: trying to make window active when going to very bottom of the screen
1195 // even in static mode - but it doesn't work because this code is checked
1196 // only in static=0 mode
1198 else if ((Screen_struct->MouseY == ScreenHeight - 1) &&
1199 Window_Open == TRUE &&
1200 Screen_struct->MouseX > BeginningWindow &&
1201 Screen_struct->MouseX < EndingWindow)
1203 D(bug("[IconBar] You're at the very bottom! I should make this window active!\n"));
1204 Window_Active = TRUE;
1208 static void Show_Selected_Level(void)
1210 CloseMainWindow();
1212 IconCounter = Levels_Struct[CurrentLevel+1].Beginning;
1213 WindowWidth = Levels_Struct[CurrentLevel].WindowPos_X;
1214 WindowHeight = Levels_Struct[CurrentLevel].WindowPos_Y;
1215 BeginningWindow = (ScreenWidth>>1) - (WindowWidth>>1);
1216 EndingWindow = (ScreenWidth>>1) + (WindowWidth>>1);
1218 //LJ: delay needed for AROS, otherwise garbage from old icons remains
1219 Delay(10); //10 ms seems to be enough
1221 if(OpenMainWindow() == FALSE)
1223 BiB_Exit = TRUE;
1227 static void OpenMenuWindow(void)
1229 int x;
1231 if((MenuWindow_struct = OpenWindowTags(NULL,
1232 WA_Left, Screen_struct->MouseX,
1233 WA_Top, Screen_struct->MouseY,
1234 WA_InnerWidth, Lenght + 1,
1235 WA_InnerHeight, LevelCounter << 4,
1236 WA_AutoAdjust, TRUE,
1237 WA_ReportMouse, TRUE,
1238 WA_Borderless, TRUE,
1239 WA_IDCMP,IDCMP_MOUSEBUTTONS|
1240 IDCMP_MOUSEMOVE|
1241 IDCMP_INACTIVEWINDOW,
1242 WA_Flags,WFLG_ACTIVATE|
1243 WFLG_RMBTRAP|
1244 WFLG_SMART_REFRESH,
1245 TAG_END)))
1247 MenuMask = 1 << MenuWindow_struct->UserPort->mp_SigBit;
1249 SetAPen(MenuWindow_struct->RPort, 1);
1250 Move(MenuWindow_struct->RPort, Lenght, 0);
1251 Draw(MenuWindow_struct->RPort, Lenght, LevelCounter << 4);
1252 Draw(MenuWindow_struct->RPort, 0, LevelCounter << 4);
1253 SetAPen(MenuWindow_struct->RPort, 2);
1254 Draw(MenuWindow_struct->RPort, 0, 0);
1255 Draw(MenuWindow_struct->RPort, Lenght, 0);
1257 SetAPen(MenuWindow_struct->RPort, 1);
1258 Move(MenuWindow_struct->RPort, 0, (LevelCounter - 1) << 4);
1259 Draw(MenuWindow_struct->RPort, Lenght - 1, (LevelCounter - 1) << 4);
1261 SetAPen(MenuWindow_struct->RPort, 2);
1262 Move(MenuWindow_struct->RPort, 0, ((LevelCounter - 1) << 4) + 1);
1263 Draw(MenuWindow_struct->RPort, Lenght - 1, ((LevelCounter - 1) << 4) + 1);
1265 for(x=0; x<LevelCounter; x++)
1267 if(x == CurrentLevel) Names.FrontPen = 2;
1268 else Names.FrontPen = 1;
1270 strcpy(BufferList, Levels_Struct[x].Level_Name);
1272 PrintIText(MenuWindow_struct->RPort, &Names, 5, (x << 4) + 5);
1274 D(bug("[IconBar] Level %d: %s\n", x, Levels_Struct[x].Level_Name));
1276 MenuWindow_Open = TRUE;
1278 else D(bug("[IconBar] Can't open menu\n"));
1281 static void CloseMenuWindow(void)
1283 CloseWindow(MenuWindow_struct);
1284 MenuMask = 0;
1286 if(PositionMenuOK == TRUE)
1288 if(Position == (LevelCounter - 1))
1290 Settings();
1291 } else {
1292 CurrentLevel = Position;
1293 Show_Selected_Level();
1298 static void Decode_IDCMP2(struct IntuiMessage *KomIDCMP)
1300 int x, kolA, kolB, dluG, x4;
1302 dluG = Lenght - 2;
1304 switch(KomIDCMP->Class)
1306 case IDCMP_MOUSEMOVE:
1307 if(MenuWindow_struct->MouseX > 0 &&
1308 MenuWindow_struct->MouseX < Lenght &&
1309 MenuWindow_struct->MouseY >0)
1311 Position = MenuWindow_struct->MouseY >> 4;
1313 else
1315 Position = 100;
1318 if(Position != OldPosition)
1320 for(x=0; x<LevelCounter; x++)
1322 x4 = (x << 4) + 2;
1324 if(x == Position)
1326 kolA = 2;
1327 kolB = 1;
1329 else
1331 kolA = 0;
1332 kolB = 0;
1335 SetAPen(MenuWindow_struct->RPort, kolA);
1336 Move(MenuWindow_struct->RPort, dluG, x4);
1337 Draw(MenuWindow_struct->RPort, dluG, x4 + 13);
1338 Draw(MenuWindow_struct->RPort, 2, x4 + 13);
1339 SetAPen(MenuWindow_struct->RPort, kolB);
1340 Draw(MenuWindow_struct->RPort, 2, x4);
1341 Draw(MenuWindow_struct->RPort, dluG, x4);
1344 if(Position != CurrentLevel && Position != 100)
1345 PositionMenuOK = TRUE;
1346 else PositionMenuOK = FALSE;
1348 OldPosition = Position;
1350 D(bug("[IconBar] Menu %d, level %d\n", Position, CurrentLevel));
1352 break;
1354 case IDCMP_MOUSEBUTTONS: //LJ: Adding IDCMP_ seems to do the trick...
1355 switch (KomIDCMP->Code)
1357 case MENUUP:
1358 MenuWindow_Open = FALSE;
1359 rbm = 0;
1360 break;
1362 break;
1364 case IDCMP_INACTIVEWINDOW:
1365 MenuWindow_Open = FALSE;
1366 break;
1370 static void Launch_Program(char *Program)
1372 BPTR oldlock;
1374 // Get current directory lock
1375 oldlock = CurrentDir(BNULL);
1377 D(bug("[IconBar] Launch_Program %s\n", Program));
1378 OpenWorkbenchObject(Program, TAG_DONE);
1380 // Go back to old directory
1381 CurrentDir(oldlock);
1384 static void Settings(void)
1386 if (!OpenWorkbenchObject("PROGDIR:BIBPrefs", TAG_DONE))
1387 OpenWorkbenchObject("SYS:Prefs/BIBPrefs", TAG_DONE);
1390 static void Reload_BiB(void)
1392 D(bug("[IconBar] Reloading BiB...\n"));
1394 int x;
1396 if (Window_Open == TRUE)
1398 D(bug("[IconBar] The Main window is open.. so let's close it...\n"));
1399 CloseMainWindow();
1402 for(x=0; x<SUM_ICON; x++)
1404 if(Icon[x] != NULL)
1406 FreeDiskObject(Icon[x]);
1408 Icons_Struct[x].Icon_Height = 0;
1409 Icons_Struct[x].Icon_Width = 0;
1410 Icons_Struct[x].Icon_PositionX = 0;
1411 Icons_Struct[x].Icon_PositionY = 0;
1414 if(BMP_Buffer) FreeBitMap(BMP_Buffer);
1416 if(BMP_DoubleBuffer) FreeBitMap(BMP_DoubleBuffer);
1418 if(ReadPrefs() == FALSE)
1420 D(bug("[IconBar] Prefs error\n"));
1421 return;
1424 if(Static)
1426 Delay(Static * 50);
1427 OpenMainWindow();
1428 FirstOpening = FALSE;