Don't keep asking for S2EVENT_CONNECT reports if driver doen't
[AROS.git] / workbench / tools / BoingIconBar / iconbar.c
blob1680b5d92a0d334bcc171b26e53aa5edaabd5632
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 #include "locale.h"
65 #define SUM_ICON 200
66 #define ICON_ACTIVE (1<<7)
67 #define SELECTED_ICON (1<<6)
69 #define TEMPLATE "SPACE/N/K,STATIC/N/K,AUTOREMAP/S,BACKGROUND/S"
70 #define ARG_SPACE 0
71 #define ARG_STATIC 1
72 #define ARG_AUTOREMAP 2
73 #define ARG_BACKGROUND 3
75 #define BIB_PREFS "ENV:Iconbar.prefs"
77 /*****************************************************************************/
79 static BOOL BiB_Exit = FALSE,
80 Icon_Remap = FALSE,
81 Bar_Background = FALSE,
82 PositionMenuOK = FALSE,
83 // Image = FALSE, // <--- FIXME: "Image" seems not used at all
84 Window_Active = FALSE,
85 Window_Open = FALSE,
86 MenuWindow_Open = FALSE,
87 FirstOpening = TRUE;
89 static int Static = 0,
90 Spacing = 5,
91 CurrentLevel = 0,
92 lbm = 0,
93 rbm = 0;
95 static int WindowHeight,
96 WindowWidth,
97 ScreenHeight,
98 ScreenWidth,
99 IconWidth,
100 // ImageWidth,
101 // ImageHeight, // <--- FIXME: ...also: ImageWidth, ImageHeight not used at all
102 Position,
103 OldPosition,
104 IconCounter,
105 LevelCounter,
106 MouseIcon,
107 Lenght,
108 BeginningWindow,
109 EndingWindow,
110 Window_Max_X,
111 Window_Max_Y;
113 const char version[] = "$VER: BoingIconBar 1.02 (26.04.2012) ©2012 Robert 'Phibrizzo' Krajcarz";
115 static char //Background_name[256], // <-- FIXME: Background_name not used at all,
116 BufferList[20], // but might be interesting to implement
117 MovingTable[8] = {0, 4, 7, 9, 10, 9, 7, 4};
119 static BOOL notification = FALSE;
121 static ULONG WindowMask,
122 MenuMask,
123 CxSigMask,
124 NotifMask,
125 WindowSignal;
127 static IPTR args[] = {(IPTR)&Spacing, (IPTR)&Static, 0, 0};
129 /*****************************************************************************/
131 static struct DiskObject *Icon[SUM_ICON];
133 static struct Window *Window_struct, *MenuWindow_struct; // FIXME: really ugly _struct names...
134 static struct Screen *Screen_struct;
136 static struct BitMap *BMP_Buffer, *BMP_DoubleBuffer;
137 static struct RastPort RP_Buffer, RP_DoubleBuffer;
138 static CxObj *broker;
140 // struct of icons
142 static struct Icon_Struct
144 int Icon_Height; // icon height
145 int Icon_Width; // icon width
146 int Icon_PositionX; // X position on main window
147 int Icon_PositionY; // Y position on main window
148 int Icon_Status; // status of icon: normal or selected
149 BOOL Icon_OK; // everything OK with icon
150 char Icon_Path[255]; // name to path of icon
151 } Icons_Struct[SUM_ICON];
153 // struct of submenu
155 static struct Level_Struct
157 char Level_Name[20]; // name submenu - level name
158 int Beginning; // first icon on menu
159 int WindowPos_X; // X position main window
160 int WindowPos_Y; // Y position main window
161 } Levels_Struct[11];
163 static struct TextAttr Topaz8 = {"topaz.font",8,0,FPF_ROMFONT};
165 static struct IntuiText Names = {1,0,JAM1,0,0,&Topaz8,BufferList,NULL};
167 // background pictures
169 static Object *picture[3];
170 static struct BitMap *bm[3];
172 static struct Struct_BackgroundData
174 int Width; // width
175 int Height; // height
176 } BackgroundData[3];
178 static struct NewBroker newbroker;
180 static struct NotifyRequest *nr;
181 static struct MsgPort *BIBport, *BrokerMP;
182 struct RDArgs *rda;
183 static struct DiskObject *dob;
185 /*****************************************************************************/
186 // functions
187 static int ReadPrefs(void); // load prefs
188 static void LoadBackground(void); //load background pictures
189 static void SetWindowParameters(void); // check window sizes
190 static void Decode_IDCMP(struct IntuiMessage *KomIDCMP); // decode IDCMP main signals
191 static void Change_State(int Reset); // change icon state
192 static void Insert_Icon(int Tryb, int IconNumber); // draw icon
193 static void Blink_Icon(int IconNumber); // blink the icon
194 static BOOL OpenMainWindow(void); // open main window
195 static void CloseMainWindow(void); // close main window
196 static void CheckMousePosition(void); // check mouse position
197 static void Show_Selected_Level(void); // change the submenu
198 static void OpenMenuWindow(void); // open menu window
199 static void CloseMenuWindow(void); // close menu window
200 static void Decode_IDCMP2(struct IntuiMessage *KomIDCMP); // decode IDCMP menu signals
201 static void Launch_Program(char *Program); // start the chosed program
202 static void Settings(void); // open the prefs program
203 static void Reload_BiB(void); // reload the BiB
204 static void HandleCx(void); // handle Cx messages
205 static void CleanExit(CONST_STRPTR msg); // Cleanup and print a message
207 /*****************************************************************************/
209 int main(int argc, char *argv[])
211 int outt = FALSE;
213 struct IntuiMessage *KomIDCMP, KopiaIDCMP;
214 BPTR out = BNULL;
216 newbroker.nb_Version = NB_VERSION;
217 newbroker.nb_Name = _(MSG_CX_NAME); // string to identify this broker
218 newbroker.nb_Title = _(MSG_CX_TITLE);
219 newbroker.nb_Descr = _(MSG_CX_DESC);
220 newbroker.nb_Unique = NBU_UNIQUE | NBU_NOTIFY;
222 if ((BrokerMP = CreateMsgPort()) != NULL)
224 newbroker.nb_Port = BrokerMP;
225 CxSigMask = 1L << BrokerMP->mp_SigBit;
226 broker = CxBroker(&newbroker, NULL);
227 if (broker == NULL)
229 D(bug("[IconBar] is already running\n"));
230 CleanExit("");
234 ActivateCxObj(broker, 1);
235 D(bug("[IconBar] broker %p\n", broker));
237 // Read arguments
238 if (argc)
240 // Started from Shell
241 if (!(rda = ReadArgs(TEMPLATE, args, NULL)))
243 PrintFault(IoErr(), argv[0]);
244 return RETURN_FAIL;
247 if (args[ARG_AUTOREMAP]) Icon_Remap = TRUE;
249 if (args[ARG_BACKGROUND]) Bar_Background = TRUE;
251 out = Output();
252 } else {
253 // Started from WB: Read ToolTypes
254 struct WBStartup *wbs=(struct WBStartup*)argv;
255 struct WBArg *wba=&wbs->sm_ArgList[wbs->sm_NumArgs-1];
256 BPTR oldcd;
258 if (!(*wba->wa_Name))
260 return RETURN_FAIL;
263 oldcd=CurrentDir(wba->wa_Lock);
264 if ((dob=GetDiskObjectNew(wba->wa_Name)))
266 char *str;
268 if ((str=FindToolType(dob->do_ToolTypes, "SPACE")))
269 *(ULONG*)args[ARG_SPACE]=(ULONG)atoi(str);
271 if ((str=FindToolType(dob->do_ToolTypes, "STATIC")))
272 *(ULONG*)args[ARG_STATIC]=(ULONG)atoi(str);
274 if ((str=FindToolType(dob->do_ToolTypes, "AUTOREMAP")))
275 Icon_Remap = TRUE;
276 if ((str=FindToolType(dob->do_ToolTypes, "BACKGROUND")))
277 Bar_Background = TRUE;
280 CurrentDir(oldcd);
281 outt = TRUE;
284 if (out || outt)
286 Spacing = *(LONG*)args[ARG_SPACE];
287 Static = *(LONG*)args[ARG_STATIC];
290 D(bug("[IconBar] Specified options: SPACE=%d, STATIC=%d, AUTOREMAP=%d\n", Spacing, Static, Icon_Remap));
292 // Read the prefs file, fail if it doesn't exist
293 if (!ReadPrefs())
295 CleanExit("Can't read preferences\n");
298 // Set notification of prefs change
299 if ((BIBport = CreateMsgPort()))
301 if ((nr = AllocMem(sizeof(struct NotifyRequest), MEMF_CLEAR)))
303 nr->nr_Name = BIB_PREFS;
305 D(bug("[IconBar] prefs filename: %s\n",nr->nr_Name));
307 nr->nr_Flags = NRF_SEND_MESSAGE;
308 nr->nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
309 nr->nr_stuff.nr_Msg.nr_Port = BIBport;
311 if (StartNotify(nr) != DOSFALSE)
313 notification = TRUE;
314 NotifMask = 1L << BIBport->mp_SigBit;
315 D(bug("[IconBar] Notification started\n"));
319 if (Bar_Background)
320 LoadBackground();
322 if(Static)
324 Delay(Static * 50);
325 OpenMainWindow();
326 FirstOpening = FALSE;
329 // ---- main loop
331 while (BiB_Exit==FALSE)
333 if (Window_Open || MenuWindow_Open)
335 WindowSignal = Wait(WindowMask | MenuMask | CxSigMask | NotifMask);
337 else
339 Delay(50);
340 CheckMousePosition();
341 WindowSignal = 0;
344 if(WindowSignal & WindowMask)
346 while((KomIDCMP = GT_GetIMsg(Window_struct->UserPort)))
348 CopyMem(KomIDCMP, &KopiaIDCMP, sizeof(struct IntuiMessage));
349 GT_ReplyIMsg(KomIDCMP);
350 Decode_IDCMP(&KopiaIDCMP);
353 if(!(Static) && Window_Active == FALSE) CloseMainWindow();
356 if(WindowSignal & MenuMask)
358 while((KomIDCMP = GT_GetIMsg(MenuWindow_struct->UserPort)))
360 CopyMem(KomIDCMP, &KopiaIDCMP, sizeof(struct IntuiMessage));
361 GT_ReplyIMsg(KomIDCMP);
362 Decode_IDCMP2(&KopiaIDCMP);
365 if(MenuWindow_Open == FALSE) CloseMenuWindow();
368 if(WindowSignal & CxSigMask)
370 HandleCx();
373 if(WindowMask & NotifMask)
375 if (GetMsg(BIBport) != NULL)
377 D(bug("[IconBar] Prefs modified!\n"));
378 Reload_BiB();
381 } // ---- end of main loop
383 D(bug("[IconBar] Quitting...\n"));
385 CleanExit(NULL);
386 return 0;
389 /*****************************************************************************/
391 static int ReadPrefs(void)
393 BPTR Prefs;
394 int x, TextLenght, NumChars;
396 Icons_Struct[0].Icon_OK = FALSE;
397 IconCounter = 0;
398 LevelCounter = 0;
399 Lenght = 0;
401 if((Prefs = Open(BIB_PREFS, MODE_OLDFILE)))
403 FGets(Prefs, Icons_Struct[0].Icon_Path, 255);
405 if(strncmp(Icons_Struct[0].Icon_Path, "BOING_PREFS", 11) != 0)
407 Close(Prefs);
408 //FIXME: A better error handling might be added
409 D(bug("[IconBar] Prefs error\n"));
410 return(0);
413 if((Screen_struct = LockPubScreen(NULL)) != NULL)
415 while (FGets(Prefs, Icons_Struct[IconCounter].Icon_Path, 255))
417 NumChars = strlen(Icons_Struct[IconCounter].Icon_Path);
418 Icons_Struct[IconCounter].Icon_Path[NumChars-1] = '\0';
420 if (Icons_Struct[IconCounter].Icon_Path[0] == ';')
422 D(bug("[IconBar] Found a submenu! Name lenght = %d, last char = %d\n",
423 NumChars, Icons_Struct[IconCounter].Icon_Path[NumChars-1]));
425 if (NumChars > 20) NumChars = 20;
426 Icons_Struct[IconCounter].Icon_Path[19] = '\0';
428 for (x=1; x<NumChars; x++)
430 Levels_Struct[LevelCounter].Level_Name[x-1] = Icons_Struct[IconCounter].Icon_Path[x];
433 D(bug("[IconBar] x after \'for\' = %d\n", x));
435 strcpy(BufferList, Levels_Struct[LevelCounter].Level_Name);
437 D(bug("[IconBar] Level name: %s\n", Levels_Struct[LevelCounter].Level_Name));
439 TextLenght = IntuiTextLength(&Names);
441 if (TextLenght > Lenght) Lenght = TextLenght;
443 D(bug("[IconBar] IntuiTextLenght = %d\n", TextLenght));
445 D(bug("[IconBar] Submenu %d - %s, beginning %d\n",
446 LevelCounter, Levels_Struct[LevelCounter].Level_Name, Levels_Struct[LevelCounter].Beginning));
448 Levels_Struct[LevelCounter].Beginning = IconCounter;
449 LevelCounter++;
450 } else {
451 D(bug("[IconBar] Loading icon #%d - name: %s\n", IconCounter, Icons_Struct[IconCounter].Icon_Path));
453 if ((Icon[IconCounter] = GetIconTags(Icons_Struct[IconCounter].Icon_Path,
454 ICONGETA_RemapIcon, FALSE,
455 TAG_DONE)))
457 IconControl(Icon[IconCounter],
458 ICONCTRLA_GetWidth, &Icons_Struct[IconCounter].Icon_Width,
459 ICONCTRLA_GetHeight, &Icons_Struct[IconCounter].Icon_Height,
460 ICONCTRLA_SetNewIconsSupport, TRUE,
461 TAG_END);
463 if (Icons_Struct[IconCounter].Icon_Width == 0)
465 Icons_Struct[IconCounter].Icon_Width = Icon[IconCounter]->do_Gadget.Width;
468 if (Icons_Struct[IconCounter].Icon_Height == 0)
470 Icons_Struct[IconCounter].Icon_Height = Icon[IconCounter]->do_Gadget.Height;
473 LayoutIcon(Icon[IconCounter], Screen_struct, NULL);
475 D(bug("[IconBar] Dimension icon #%d: Widht=%d Height=%d\n",
476 IconCounter, Icons_Struct[IconCounter].Icon_Width, Icons_Struct[IconCounter].Icon_Height));
478 D(bug("[IconBar] Icon %d loaded\n", IconCounter));
480 Icons_Struct[IconCounter].Icon_OK = TRUE;
481 IconCounter++;
483 if (IconCounter == SUM_ICON) break;
484 } else {
485 //FIXME: A better error handling might be added
486 D(bug("[IconBar] Not found icon %s.\n", Icons_Struct[IconCounter].Icon_Path));
490 Close(Prefs);
492 ScreenWidth = Screen_struct->Width;
493 ScreenHeight = Screen_struct->Height;
495 UnlockPubScreen(NULL, Screen_struct);
497 Levels_Struct[LevelCounter].Beginning = IconCounter;
499 D(bug("[IconBar] Screen size: Width=%d, Height=%d\n", ScreenWidth, ScreenHeight));
501 SetWindowParameters();
503 IconCounter = Levels_Struct[1].Beginning;
504 WindowWidth = Levels_Struct[0].WindowPos_X;
505 WindowHeight = Levels_Struct[0].WindowPos_Y;
507 BeginningWindow = (ScreenWidth>>1) - (WindowWidth>>1);
508 EndingWindow = (ScreenWidth>>1) + (WindowWidth>>1);
510 CurrentLevel = 0;
512 sprintf(Levels_Struct[LevelCounter].Level_Name, "%s", _(MSG_MENU_SETTINGS));
513 sprintf(Names.IText, "%s", Levels_Struct[LevelCounter].Level_Name);
515 TextLenght = IntuiTextLength(&Names);
517 if (TextLenght > Lenght) Lenght = TextLenght;
519 LevelCounter++;
521 Lenght = Lenght + 10;
522 } else {
523 //FIXME: A better error handling might be added
524 D(bug("[IconBar] Error reading screen parameters\n"));
528 return Icons_Struct[0].Icon_OK;
531 /*****************************************************************************/
533 static void LoadBackground(void)
535 int x;
537 STRPTR name[3] =
539 "SYS:System/Images/bibgfx/left" ,
540 "SYS:System/Images/bibgfx/middle",
541 "SYS:System/Images/bibgfx/right"
544 for (x=0; x<3; x++)
546 picture[x] = NewDTObject (name[x],
547 DTA_GroupID, GID_PICTURE,
548 PDTA_Remap, TRUE,
549 PDTA_DestMode, PMODE_V43,
550 OBP_Precision, PRECISION_IMAGE,
551 PDTA_Screen, (IPTR)Screen_struct,
552 TAG_END);
554 if (picture[x])
556 D(bug("[IconBar] Loading image n. %d - name: %s\n",x,name[x]));
558 DoDTMethod(picture[x], NULL, NULL, DTM_PROCLAYOUT, NULL, DTSIF_NEWSIZE);
560 GetDTAttrs
561 ( picture[x],
562 PDTA_DestBitMap, (SIPTR)&bm[x],
563 DTA_NominalHoriz, (SIPTR)&BackgroundData[x].Width,
564 DTA_NominalVert, (SIPTR)&BackgroundData[x].Height,
565 TAG_END
571 /*****************************************************************************/
573 static void SetWindowParameters(void)
576 int x, y;
578 Window_Max_X = 0;
579 Window_Max_Y = 0;
581 Icons_Struct[0].Icon_PositionX = 0;
583 for (y=0; y<(LevelCounter); y++)
585 WindowHeight = 0;
586 WindowWidth = 0;
588 IconCounter = Levels_Struct[y+1].Beginning;
590 for (x=Levels_Struct[y].Beginning; x<IconCounter; x++)
592 if (Icons_Struct[x].Icon_OK)
594 if (Icons_Struct[x].Icon_Height > WindowHeight)
596 WindowHeight = Icons_Struct[x].Icon_Height;
599 if (Icons_Struct[x].Icon_Width > IconWidth)
601 IconWidth = Icons_Struct[x].Icon_Width;
604 if ((WindowWidth + Icons_Struct[x].Icon_Width + 35) > ScreenWidth)
606 D(bug("[IconBar] Exceeding the size of the screen, can't display all icons!\n"));
608 IconCounter = x;
609 Levels_Struct[y+1].Beginning = x;
610 break;
613 WindowWidth = WindowWidth + Icons_Struct[x].Icon_Width + Spacing;
615 Icons_Struct[x].Icon_PositionY = 10;
617 if ((x+1) != IconCounter)
619 Icons_Struct[x+1].Icon_PositionX = WindowWidth;
622 else break;
625 for (x=Levels_Struct[y].Beginning; x<IconCounter; x++)
627 if (Icons_Struct[x].Icon_OK)
629 Icons_Struct[x].Icon_PositionX = Icons_Struct[x].Icon_PositionX + 15;
630 Icons_Struct[x].Icon_PositionY = (WindowHeight>>1) - (Icons_Struct[x].Icon_Height>>1) + 15;
634 Levels_Struct[y].WindowPos_X = WindowWidth + 30;
635 Levels_Struct[y].WindowPos_Y = WindowHeight + 20;
637 if (Levels_Struct[y].WindowPos_X > ScreenWidth)
638 Levels_Struct[y].WindowPos_X = WindowWidth;
640 if (Window_Max_X < Levels_Struct[y].WindowPos_X)
641 Window_Max_X = Levels_Struct[y].WindowPos_X;
643 if (Window_Max_Y < Levels_Struct[y].WindowPos_Y)
644 Window_Max_Y = Levels_Struct[y].WindowPos_Y;
646 D(bug("[IconBar] Window size %d: S=%d, W=%d\n", y, Levels_Struct[y].WindowPos_X, Levels_Struct[y].WindowPos_Y));
649 D(bug("[IconBar] Maximum window size: S=%d, W=%d\n", Window_Max_X, Window_Max_Y));
650 D(bug("[IconBar] Icon width: %d\n", IconWidth));
652 if((Screen_struct=LockPubScreen(NULL)) != NULL)
654 BMP_Buffer = AllocBitMap
656 Window_Max_X,
657 Window_Max_Y,
658 GetBitMapAttr(Screen_struct->RastPort.BitMap, BMA_DEPTH),
659 BMF_MINPLANES | BMF_CLEAR,
660 Screen_struct->RastPort.BitMap
663 InitRastPort(&RP_Buffer);
664 RP_Buffer.BitMap = BMP_Buffer;
665 RP_Buffer.Layer = NULL;
667 BMP_DoubleBuffer = AllocBitMap
669 IconWidth + 8,
670 Window_Max_Y,
671 GetBitMapAttr(Screen_struct->RastPort.BitMap, BMA_DEPTH),
672 BMF_MINPLANES | BMF_CLEAR,
673 Screen_struct->RastPort.BitMap
676 InitRastPort(&RP_DoubleBuffer);
677 RP_DoubleBuffer.BitMap = BMP_DoubleBuffer;
678 RP_DoubleBuffer.Layer = NULL;
680 UnlockPubScreen(NULL,Screen_struct);
684 /*****************************************************************************/
686 static void Decode_IDCMP(struct IntuiMessage *KomIDCMP)
688 int x;
690 // LJ: Temporary disabled mouse cases in function Decode_IDCMP
692 switch (KomIDCMP->Class)
694 case IDCMP_CLOSEWINDOW:
695 BiB_Exit = TRUE;
696 break;
698 case IDCMP_MOUSEMOVE:
699 for(MouseIcon=Levels_Struct[CurrentLevel].Beginning; MouseIcon<IconCounter; MouseIcon++)
701 if(Icons_Struct[MouseIcon].Icon_OK)
703 // too noisy: D(bug("[IconBar] Mouse position in the window X=%d, Y=%d\n",
704 // KomIDCMP->MouseX, KomIDCMP->MouseY));
706 if((ScreenHeight - Screen_struct->MouseY) > WindowHeight)
708 Window_Active = FALSE;
711 if(KomIDCMP->MouseX > Icons_Struct[MouseIcon].Icon_PositionX &&
712 KomIDCMP->MouseX < Icons_Struct[MouseIcon].Icon_PositionX + Icons_Struct[MouseIcon].Icon_Width &&
713 KomIDCMP->MouseY > 0 &&
714 KomIDCMP->MouseY < WindowHeight - 5)
716 if((Icons_Struct[MouseIcon].Icon_Status & ICON_ACTIVE) != ICON_ACTIVE)
718 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
720 Icons_Struct[x].Icon_Status = Icons_Struct[x].Icon_Status & 0x07;
723 Icons_Struct[MouseIcon].Icon_Status = ICON_ACTIVE | (SELECTED_ICON * lbm);
724 D(bug("[IconBar] Pointer on icon #%d\n", MouseIcon));
726 break;
728 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status & 0x07;
731 break;
733 case IDCMP_MOUSEBUTTONS:
734 switch (KomIDCMP->Code)
736 case SELECTDOWN:
737 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status | SELECTED_ICON;
738 lbm = 1;
740 D(bug("[IconBar] Icon #%d\n", MouseIcon));
741 break;
743 case SELECTUP:
744 lbm = 0;
746 if((Icons_Struct[MouseIcon].Icon_Status & (SELECTED_ICON | ICON_ACTIVE)) == (SELECTED_ICON | ICON_ACTIVE))
748 Blink_Icon(MouseIcon);
750 D(bug("[IconBar] Launching program function with param: %s\n",
751 Icons_Struct[MouseIcon].Icon_Path));
752 Launch_Program(Icons_Struct[MouseIcon].Icon_Path);
754 D(bug("[IconBar] Icon #%d confirmed\n", MouseIcon));
757 Icons_Struct[MouseIcon].Icon_Status = Icons_Struct[MouseIcon].Icon_Status & 0xBF; //10001111b
759 break;
761 case MENUDOWN:
762 rbm = 1;
763 OpenMenuWindow();
764 break;
767 case IDCMP_RAWKEY:
768 switch(KomIDCMP->Code)
770 case RAWKEY_ESCAPE:
771 if((KomIDCMP->Qualifier) & IEQUALIFIER_LSHIFT)
773 BiB_Exit = TRUE;
775 break;
777 case RAWKEY_F1:
778 for(x=0; x<SUM_ICON; x++)
780 if(Icon[x] != NULL)
782 LayoutIcon(Icon[x],
783 Screen_struct,
784 NULL);
788 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
790 if(Icon[x] != NULL)
792 DrawIconState(Window_struct->RPort,
793 Icon[x],
794 NULL,
795 Icons_Struct[x].Icon_PositionX,
796 Icons_Struct[x].Icon_PositionY,
797 IDS_NORMAL,
798 ICONDRAWA_Frameless, TRUE,
799 ICONDRAWA_EraseBackground, FALSE,
800 TAG_DONE);
803 break;
805 case RAWKEY_F2:
806 case RAWKEY_NM_WHEEL_DOWN:
807 CurrentLevel++;
808 if(CurrentLevel == (LevelCounter -1 )) CurrentLevel = 0;
809 Show_Selected_Level();
810 break;
812 case RAWKEY_F3:
813 case RAWKEY_NM_WHEEL_UP:
814 CurrentLevel--;
815 if(CurrentLevel < 0) CurrentLevel = LevelCounter - 2;
816 Show_Selected_Level();
817 break;
819 case RAWKEY_F4:
820 Settings();
821 break;
823 break;
825 case IDCMP_INACTIVEWINDOW:
826 if(rbm == 0) Window_Active = FALSE;
827 lbm = 0;
829 if(Static)
831 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
833 if(Icons_Struct[x].Icon_Status != 0)
835 Icons_Struct[x].Icon_Status = 0;
836 Insert_Icon(IDS_NORMAL, x);
841 break;
843 case IDCMP_INTUITICKS:
844 Change_State(0);
845 break;
850 static void Change_State(int Reset)
852 int x;
854 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
856 if(Icons_Struct[x].Icon_OK)
858 if(Icons_Struct[x].Icon_Status != 0)
860 if(Reset == 0)
862 if((Icons_Struct[x].Icon_Status & ICON_ACTIVE) == 0 && Icons_Struct[x].Icon_Status < 4)
864 // 11000111b
865 Icons_Struct[x].Icon_Status = (Icons_Struct[x].Icon_Status - 1) & 0xC7;
867 else
869 Icons_Struct[x].Icon_Status = (Icons_Struct[x].Icon_Status + 1) & 0xC7;
872 else
874 Icons_Struct[x].Icon_Status = 0;
877 Insert_Icon((Icons_Struct[x].Icon_Status & SELECTED_ICON) ? IDS_SELECTED : IDS_NORMAL, x);
883 static void Insert_Icon(int Tryb, int IconNumber)
885 BltBitMapRastPort(BMP_Buffer,
886 Icons_Struct[IconNumber].Icon_PositionX,
888 &RP_DoubleBuffer, //Window_struct->RPort,
889 0, //Icons_Struct[IconNumber].Icon_PositionX,
891 Icons_Struct[IconNumber].Icon_Width + 1,
892 WindowHeight,
893 0xC0);
895 DrawIconState(&RP_DoubleBuffer, //Window_struct->RPort,
896 Icon[IconNumber],
897 NULL,
898 0, //Icons_Struct[IconNumber].Icon_PositionX,
899 Icons_Struct[IconNumber].Icon_PositionY - MovingTable[(Icons_Struct[IconNumber].Icon_Status & 0x07)],
900 Tryb,
901 ICONDRAWA_Frameless, TRUE,
902 ICONDRAWA_EraseBackground, FALSE,
903 TAG_DONE);
905 BltBitMapRastPort(BMP_DoubleBuffer,
908 Window_struct->RPort,
909 Icons_Struct[IconNumber].Icon_PositionX,
911 Icons_Struct[IconNumber].Icon_Width + 1,
912 WindowHeight,
913 0xC0);
916 static void Blink_Icon(int IconNumber)
918 int x, Tryb=IDS_SELECTED;
920 for(x=0; x<8; x++)
922 Insert_Icon(Tryb, IconNumber);
923 Delay(3);
925 if(Tryb == IDS_NORMAL) Tryb = IDS_SELECTED;
926 else Tryb = IDS_NORMAL;
930 static BOOL OpenMainWindow(void)
932 int x, y, a;
934 if((Screen_struct=LockPubScreen(NULL)) != NULL)
936 BltBitMapRastPort(Screen_struct->RastPort.BitMap,
937 (ScreenWidth>>1) - (WindowWidth>>1),
938 ScreenHeight - WindowHeight,
939 &RP_Buffer,
940 0, 0,
941 Window_Max_X,
942 Window_Max_Y,
943 0xC0);
945 UnlockPubScreen(NULL,Screen_struct);
948 if(picture[0] && picture[1] && picture[2])
950 y = WindowWidth - BackgroundData[0].Width - BackgroundData[2].Width;
951 a = y / BackgroundData[1].Width;
953 BltBitMapRastPort(bm[0],
956 &RP_Buffer,
958 WindowHeight - BackgroundData[0].Height,
959 BackgroundData[0].Width,
960 BackgroundData[0].Height,
961 0xC0);
963 for(x=0; x<a; x++)
965 BltBitMapRastPort(bm[1],
968 &RP_Buffer,
969 BackgroundData[0].Width + x * BackgroundData[1].Width,
970 WindowHeight - BackgroundData[1].Height,
971 BackgroundData[1].Width,
972 BackgroundData[1].Height,
973 0xC0);
976 BltBitMapRastPort(bm[1],
979 &RP_Buffer,
980 BackgroundData[0].Width + x * BackgroundData[1].Width,
981 WindowHeight - BackgroundData[1].Height,
982 y - BackgroundData[1].Width * a,
983 BackgroundData[1].Height,
984 0xC0);
986 BltBitMapRastPort(bm[2],
989 &RP_Buffer,
990 WindowWidth - BackgroundData[2].Width,
991 WindowHeight - BackgroundData[2].Height,
992 BackgroundData[2].Width,
993 BackgroundData[2].Height,
994 0xC0);
995 } else if(picture[1]) {
996 for(x=0; x<WindowWidth; x=x+BackgroundData[1].Width)
998 BltBitMapRastPort(bm[1],
1001 &RP_Buffer,
1003 WindowHeight - BackgroundData[1].Height,
1004 BackgroundData[1].Width,
1005 BackgroundData[1].Height,
1006 0xC0);
1010 if(Icon_Remap == TRUE)
1012 D(bug("[IconBar] Iconremap is true!\n"));
1014 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1016 if(Icon[x]!=NULL)
1018 // 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);
1019 LayoutIcon(Icon[x], Screen_struct, NULL);
1024 D(bug("[IconBar] Opening window: S=%d, W=%d\n", WindowWidth, WindowHeight));
1026 if((Window_struct = OpenWindowTags(NULL,
1027 WA_Left, BeginningWindow,
1028 WA_Top, ScreenHeight - WindowHeight,
1029 WA_InnerWidth, WindowWidth,
1030 WA_InnerHeight, WindowHeight,
1031 WA_ReportMouse, TRUE,
1032 WA_MouseQueue, 3,
1033 WA_Borderless, TRUE,
1034 WA_SizeGadget, FALSE,
1035 WA_Activate, ((FirstOpening && Static) ? FALSE : TRUE),
1036 WA_PubScreenName, NULL,
1037 WA_BackFill, LAYERS_NOBACKFILL,
1038 WA_Flags, WFLG_NOCAREREFRESH|
1039 WFLG_SMART_REFRESH|
1040 WFLG_RMBTRAP,
1041 WA_IDCMP, IDCMP_NEWSIZE|
1042 IDCMP_RAWKEY|
1043 IDCMP_INACTIVEWINDOW|
1044 IDCMP_MOUSEMOVE|
1045 IDCMP_INTUITICKS|
1046 IDCMP_MOUSEBUTTONS,
1047 TAG_END)))
1049 D(bug("[IconBar] Window opened\n"));
1051 WindowMask = 1 << Window_struct->UserPort->mp_SigBit;
1053 BltBitMapRastPort(BMP_Buffer,
1054 0, 0,
1055 Window_struct->RPort,
1056 0, 0,
1057 WindowWidth,
1058 WindowHeight,
1059 0xC0);
1061 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1063 if(Icon[x] != NULL)
1065 DrawIconState(Window_struct->RPort,
1066 Icon[x],
1067 NULL,
1068 Icons_Struct[x].Icon_PositionX,
1069 Icons_Struct[x].Icon_PositionY,
1070 IDS_NORMAL,
1071 ICONDRAWA_Frameless, TRUE,
1072 ICONDRAWA_EraseBackground, FALSE,
1073 TAG_DONE);
1076 } else {
1077 D(bug("[IconBar] Can't open main toolbar window\n"));
1078 return FALSE;
1081 Window_Open = TRUE;
1082 Window_Active = TRUE;
1084 return TRUE;
1087 static void CloseMainWindow(void)
1089 D(bug("[IconBar] ClosingMainWindow...\n"));
1091 int x;
1093 if(Window_struct) CloseWindow(Window_struct);
1095 for(x=Levels_Struct[CurrentLevel].Beginning; x<IconCounter; x++)
1097 Icons_Struct[x].Icon_Status = 0;
1100 Window_Open = FALSE;
1101 WindowMask = 0;
1104 static void CheckMousePosition(void)
1106 // noisy: D(bug("[IconBar] Mouse current position: Y=%d\n", Screen_struct->MouseY));
1108 if((Screen_struct->MouseY == ScreenHeight - 1) &&
1109 Window_Open == FALSE &&
1110 Screen_struct->MouseX > BeginningWindow &&
1111 Screen_struct->MouseX < EndingWindow)
1113 D(bug("[IconBar] Opening the window\n"));
1114 if(OpenMainWindow() == FALSE)
1116 BiB_Exit = TRUE;
1120 // LJ: trying to make window active when going to very bottom of the screen
1121 // even in static mode - but it doesn't work because this code is checked
1122 // only in static=0 mode
1124 else if ((Screen_struct->MouseY == ScreenHeight - 1) &&
1125 Window_Open == TRUE &&
1126 Screen_struct->MouseX > BeginningWindow &&
1127 Screen_struct->MouseX < EndingWindow)
1129 D(bug("[IconBar] You're at the very bottom! I should make this window active!\n"));
1130 Window_Active = TRUE;
1134 static void Show_Selected_Level(void)
1136 CloseMainWindow();
1138 IconCounter = Levels_Struct[CurrentLevel+1].Beginning;
1139 WindowWidth = Levels_Struct[CurrentLevel].WindowPos_X;
1140 WindowHeight = Levels_Struct[CurrentLevel].WindowPos_Y;
1141 BeginningWindow = (ScreenWidth>>1) - (WindowWidth>>1);
1142 EndingWindow = (ScreenWidth>>1) + (WindowWidth>>1);
1144 //LJ: delay needed for AROS, otherwise garbage from old icons remains
1145 Delay(10); //10 ms seems to be enough
1147 if(OpenMainWindow() == FALSE)
1149 BiB_Exit = TRUE;
1153 static void OpenMenuWindow(void)
1155 int x;
1157 if((MenuWindow_struct = OpenWindowTags(NULL,
1158 WA_Left, Screen_struct->MouseX,
1159 WA_Top, Screen_struct->MouseY,
1160 WA_InnerWidth, Lenght + 1,
1161 WA_InnerHeight, LevelCounter << 4,
1162 WA_AutoAdjust, TRUE,
1163 WA_ReportMouse, TRUE,
1164 WA_Borderless, TRUE,
1165 WA_IDCMP,IDCMP_MOUSEBUTTONS|
1166 IDCMP_MOUSEMOVE|
1167 IDCMP_INACTIVEWINDOW,
1168 WA_Flags,WFLG_ACTIVATE|
1169 WFLG_RMBTRAP|
1170 WFLG_SMART_REFRESH,
1171 TAG_END)))
1173 MenuMask = 1 << MenuWindow_struct->UserPort->mp_SigBit;
1175 SetAPen(MenuWindow_struct->RPort, 1);
1176 Move(MenuWindow_struct->RPort, Lenght, 0);
1177 Draw(MenuWindow_struct->RPort, Lenght, LevelCounter << 4);
1178 Draw(MenuWindow_struct->RPort, 0, LevelCounter << 4);
1179 SetAPen(MenuWindow_struct->RPort, 2);
1180 Draw(MenuWindow_struct->RPort, 0, 0);
1181 Draw(MenuWindow_struct->RPort, Lenght, 0);
1183 SetAPen(MenuWindow_struct->RPort, 1);
1184 Move(MenuWindow_struct->RPort, 0, (LevelCounter - 1) << 4);
1185 Draw(MenuWindow_struct->RPort, Lenght - 1, (LevelCounter - 1) << 4);
1187 SetAPen(MenuWindow_struct->RPort, 2);
1188 Move(MenuWindow_struct->RPort, 0, ((LevelCounter - 1) << 4) + 1);
1189 Draw(MenuWindow_struct->RPort, Lenght - 1, ((LevelCounter - 1) << 4) + 1);
1191 for(x=0; x<LevelCounter; x++)
1193 if(x == CurrentLevel) Names.FrontPen = 2;
1194 else Names.FrontPen = 1;
1196 strcpy(BufferList, Levels_Struct[x].Level_Name);
1198 PrintIText(MenuWindow_struct->RPort, &Names, 5, (x << 4) + 5);
1200 D(bug("[IconBar] Level %d: %s\n", x, Levels_Struct[x].Level_Name));
1202 MenuWindow_Open = TRUE;
1204 else D(bug("[IconBar] Can't open menu\n"));
1207 static void CloseMenuWindow(void)
1209 CloseWindow(MenuWindow_struct);
1210 MenuMask = 0;
1212 if(PositionMenuOK == TRUE)
1214 if(Position == (LevelCounter - 1))
1216 Settings();
1217 } else {
1218 CurrentLevel = Position;
1219 Show_Selected_Level();
1224 static void Decode_IDCMP2(struct IntuiMessage *KomIDCMP)
1226 int x, kolA, kolB, dluG, x4;
1228 dluG = Lenght - 2;
1230 switch(KomIDCMP->Class)
1232 case IDCMP_MOUSEMOVE:
1233 if(MenuWindow_struct->MouseX > 0 &&
1234 MenuWindow_struct->MouseX < Lenght &&
1235 MenuWindow_struct->MouseY >0)
1237 Position = MenuWindow_struct->MouseY >> 4;
1239 else
1241 Position = 100;
1244 if(Position != OldPosition)
1246 for(x=0; x<LevelCounter; x++)
1248 x4 = (x << 4) + 2;
1250 if(x == Position)
1252 kolA = 2;
1253 kolB = 1;
1255 else
1257 kolA = 0;
1258 kolB = 0;
1261 SetAPen(MenuWindow_struct->RPort, kolA);
1262 Move(MenuWindow_struct->RPort, dluG, x4);
1263 Draw(MenuWindow_struct->RPort, dluG, x4 + 13);
1264 Draw(MenuWindow_struct->RPort, 2, x4 + 13);
1265 SetAPen(MenuWindow_struct->RPort, kolB);
1266 Draw(MenuWindow_struct->RPort, 2, x4);
1267 Draw(MenuWindow_struct->RPort, dluG, x4);
1270 if(Position != CurrentLevel && Position != 100)
1271 PositionMenuOK = TRUE;
1272 else PositionMenuOK = FALSE;
1274 OldPosition = Position;
1276 D(bug("[IconBar] Menu %d, level %d\n", Position, CurrentLevel));
1278 break;
1280 case IDCMP_MOUSEBUTTONS: //LJ: Adding IDCMP_ seems to do the trick...
1281 switch (KomIDCMP->Code)
1283 case MENUUP:
1284 MenuWindow_Open = FALSE;
1285 rbm = 0;
1286 break;
1288 break;
1290 case IDCMP_INACTIVEWINDOW:
1291 MenuWindow_Open = FALSE;
1292 break;
1296 static void Launch_Program(char *Program)
1298 BPTR oldlock;
1300 // Get current directory lock
1301 oldlock = CurrentDir(BNULL);
1303 D(bug("[IconBar] Launch_Program %s\n", Program));
1304 OpenWorkbenchObject(Program, TAG_DONE);
1306 // Go back to old directory
1307 CurrentDir(oldlock);
1310 static void Settings(void)
1312 if (!OpenWorkbenchObject("PROGDIR:BIBPrefs", TAG_DONE))
1313 OpenWorkbenchObject("SYS:Prefs/BoingIconBar", TAG_DONE);
1316 static void Reload_BiB(void)
1318 D(bug("[IconBar] Reloading BiB...\n"));
1320 int x;
1322 if (Window_Open == TRUE)
1324 D(bug("[IconBar] The Main window is open.. so let's close it...\n"));
1325 CloseMainWindow();
1328 for(x=0; x<SUM_ICON; x++)
1330 if(Icon[x] != NULL)
1332 FreeDiskObject(Icon[x]);
1334 Icons_Struct[x].Icon_Height = 0;
1335 Icons_Struct[x].Icon_Width = 0;
1336 Icons_Struct[x].Icon_PositionX = 0;
1337 Icons_Struct[x].Icon_PositionY = 0;
1340 if(BMP_Buffer) FreeBitMap(BMP_Buffer);
1342 if(BMP_DoubleBuffer) FreeBitMap(BMP_DoubleBuffer);
1344 if(ReadPrefs() == FALSE)
1346 D(bug("[IconBar] Prefs error\n"));
1347 return;
1350 if(Static)
1352 Delay(Static * 50);
1353 OpenMainWindow();
1354 FirstOpening = FALSE;
1358 void HandleCx(void)
1360 D(bug("[IconBar] Cx Signal received\n"));
1361 CxMsg *msg;
1362 ULONG msgid, msgtype;
1363 while((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL)
1365 msgid = CxMsgID(msg);
1366 msgtype = CxMsgType(msg);
1367 ReplyMsg((struct Message *)msg);
1369 switch(msgtype)
1371 case CXM_COMMAND:
1372 switch(msgid)
1374 case CXCMD_DISABLE:
1375 D(bug("[IconBar] CXCMD_DISABLE\n"));
1376 ActivateCxObj(broker, 0L);
1377 break;
1378 case CXCMD_ENABLE:
1379 D(bug("[IconBar] CXCMD_ENABLE\n"));
1380 ActivateCxObj(broker, 1L);
1381 break;
1382 case CXCMD_KILL:
1383 D(bug("[IconBar] CXCMD_KILL\n"));
1384 BiB_Exit = TRUE;
1385 break;
1386 case CXCMD_UNIQUE:
1387 D(bug("[IconBar] CXCMD_UNIQUE\n"));
1388 BiB_Exit = TRUE;
1389 break;
1390 default:
1391 D(bug("[IconBar] Unknown msgid\n"));
1392 break;
1394 break;
1395 default:
1396 D(bug("[IconBar] Unknown msgtype\n"));
1397 break;
1402 static void CleanExit(CONST_STRPTR msg)
1404 LONG retval = RETURN_OK;
1405 int x;
1407 if (msg)
1409 PutStr(msg);
1410 retval = RETURN_FAIL;
1413 CloseMainWindow();
1415 for(x=0; x<SUM_ICON; x++)
1417 if(Icon[x] != NULL)
1419 FreeDiskObject(Icon[x]);
1423 if(BMP_Buffer) FreeBitMap(BMP_Buffer);
1424 if(BMP_DoubleBuffer) FreeBitMap(BMP_DoubleBuffer);
1426 for(x=0; x<3; x++)
1428 if(picture[x]) DisposeDTObject(picture[x]);
1431 // Close notification of prefs change
1432 if(notification)
1433 EndNotify(nr);
1434 if(nr)
1435 FreeMem(nr, sizeof(struct NotifyRequest));
1436 if(BIBport)
1437 DeleteMsgPort(BIBport);
1439 if (broker) DeleteCxObjAll(broker);
1440 if (BrokerMP)
1442 CxMsg *msg;
1443 while ((msg = (CxMsg *)GetMsg(BrokerMP)) != NULL)
1444 ReplyMsg((struct Message *)msg);
1445 DeleteMsgPort(BrokerMP);
1447 if (rda) FreeArgs(rda);
1448 if (dob) FreeDiskObject(dob);
1449 exit(retval);