// DOCKY.C //#define DDEBUG #include "dockybase.h" #include <proto/intuition.h> #include <proto/datatypes.h> #include <proto/graphics.h> #include <proto/Picasso96API.h> #include <workbench/icon.h> #include <classes/popupmenu.h> #include <classes/requester.h> #include <images/bitmap.h> #include <graphics/composite.h> #include "KeyMapSwitcher_rev.h" extern struct ExecIFace *IExec; extern struct UtilityIFace *IUtility; extern struct IntuitionIFace *IIntuition; extern struct IconIFace *IIcon; extern struct DataTypesIFace *IDataTypes; extern struct DOSIFace *IDOS; extern struct GraphicsIFace *IGraphics; extern struct P96IFace *IP96; extern struct TagItem dockyTags[]; extern Object *Objects[LAST_NUM]; extern int OpenPrefsWindow(struct DockyData *dd); extern void OpenDockWindow(struct DockyData *dd); extern void OpenDockMenu(struct DockyData *dd); extern void SetKeyMapFlag(char *keymapname, char *keymapflag); extern void ChangeKeymap(struct DockyData *dd, STRPTR keymap); extern void ReadInputPrefsKeymap(STRPTR keymap); void SignalDocky(struct DockyData *dd, uint32 flags); BOOL DockySClick = FALSE, WinMode = FALSE; char keymap1Flag[1024] = "", keymap2Flag[1024] = ""; Object *picObject = NULL; uint32 _docky_Obtain(struct DockyIFace *Self) { #ifdef DDEBUG IExec->DebugPrintF("[%s]docky_Obtain\n",LIBNAME); #endif Self->Data.RefCount++; return Self->Data.RefCount; } void LoadImageFlag(struct DockyData *dd) { char keymapflag[64]; #ifdef DDEBUG IDOS->Printf("keymapSel='%s' Loading flag image...\n",dd->keymapSel); #endif if(IUtility->Stricmp(dd->keymap2Name, dd->keymapSel) == 0) IUtility->Strlcpy( keymapflag, keymap2Flag, sizeof(keymapflag) ); else IUtility->Strlcpy( keymapflag, keymap1Flag, sizeof(keymapflag) ); /* picObject = IIntuition->NewObject(NULL, "bitmap.image", BITMAP_SourceFile, keymapflag, BITMAP_Screen, dd->scr, //BITMAP_Precision, PRECISION_IMAGE, BITMAP_Masking, TRUE, BITMAP_Transparent, TRUE, TAG_DONE); */ picObject = IDataTypes->NewDTObject(keymapflag, PDTA_Screen, dd->scr, PDTA_DestMode, PMODE_V43, DTA_GroupID, GID_PICTURE, TAG_DONE); } void DockyRender(struct DockyData *dd) { struct BitMap *tempBM = NULL; LONG lock; struct RenderInfo ri; tempBM = IP96->p96AllocBitMap(25, 18, 32, 0L, NULL, RGBFB_A8R8G8B8); #ifdef DDEBUG IDOS->Printf("tempBM=0x%08lx\n",tempBM); #endif if( (lock = IP96->p96LockBitMap( tempBM, (UBYTE *)&ri, sizeof(ri) )) ) {// to pass the Alpha info from the DT object to the memory (RenderInfo) of the bitmap IIntuition->IDoMethod(picObject, PDTM_READPIXELARRAY,ri.Memory, PBPAFMT_ARGB,ri.BytesPerRow, 0, 0, 25, 18); #ifdef DDEBUG IDOS->Printf("[0x%08lx]ri.Memory=0x%08lx ri.BytesPerRow=%ld\n",ri,ri.Memory,ri.BytesPerRow); #endif // IDataTypes->DisposeDTObject(picObject); // picObject = NULL; IP96->p96UnlockBitMap(tempBM, lock); } // if(picObject) // { // IDataTypes->DisposeDTObject(picObject); // picObject = NULL; // } IGraphics->CompositeTags(COMPOSITE_Src_Over_Dest, tempBM, dd->rp->BitMap, //COMPTAG_SrcWidth, 25, //COMPTAG_SrcHeight, 18, //COMPTAG_SrcX, 0, //COMPTAG_SrcY, 0, //COMPTAG_OffsetX, 0, //COMPTAG_OffsetY, 0, TAG_DONE); IP96->p96FreeBitMap(tempBM); tempBM = NULL; } uint32 _docky_Release(struct DockyIFace *Self) { #ifdef DDEBUG IExec->DebugPrintF("[%s]docky_Release\n",LIBNAME); #endif Self->Data.RefCount--; if( !Self->Data.RefCount && (Self->Data.Flags & IFLF_CLONED) ) { IExec->DeleteInterface( (struct Interface *)Self ); return 0; } return Self->Data.RefCount; } struct DockyIFace *_docky_Clone(struct DockyIFace *Self) { struct DockyIFace *docky; #ifdef DDEBUG IExec->DebugPrintF("[%s]docky_Clone\n",LIBNAME); #endif docky = (struct DockyIFace *)IExec->MakeInterface(Self->Data.LibBase, dockyTags); if(docky) { struct DockyData *dd = (struct DockyData *)((uint32)docky - docky->Data.NegativeSize); docky->Data.Flags |= IFLF_CLONED; IUtility->ClearMem( dd, sizeof(struct DockyData) ); dd->size.width = 25; // width of flag images dd->size.height = 18; // height of flag images ReadInputPrefsKeymap(dd->keymap1Name); } return docky; } static void ReadDockyPrefs(struct DockyData *dd) { struct DiskObject *micon; STRPTR ttp; #ifdef DDEBUG IExec->DebugPrintF("[%s]ReadDockyPrefs\n",LIBNAME); #endif micon = IIcon->GetDiskObjectNew(dd->filename); if(micon) { ttp = IIcon->FindToolType(micon->do_ToolTypes, "KEYMAP2"); if(ttp) IUtility->Strlcat( dd->keymap2Name, ttp, sizeof(dd->keymap2Name) ); ttp = IIcon->FindToolType(micon->do_ToolTypes, "DOCKY_1CLICK"); if(ttp) DockySClick = ( IIcon->MatchToolValue(ttp, "YES") | IIcon->MatchToolValue(ttp, "ON") ); ttp = IIcon->FindToolType(micon->do_ToolTypes, "MODE"); if(ttp) WinMode = IIcon->MatchToolValue(ttp, "WIN"); } IIcon->FreeDiskObject(micon); IUtility->Strlcpy( dd->keymapSel, dd->keymap1Name, sizeof(dd->keymapSel) ); // default keymap selected #ifdef DDEBUG IDOS->Printf("DOCKY_1CLICK=%ld\n",DockySClick); #endif // language 1: input.prefs; keymap1Name & keymap1Flag SetKeyMapFlag(dd->keymap1Name, keymap1Flag); #ifdef DDEBUG IDOS->Printf("KEYMAP1='%s' FLAG1='%s' (input.prefs)\n",dd->keymap1Name,keymap1Flag); #endif // language 2: tooltype (KEYMAP2); keymap2Name & keymap2Flag SetKeyMapFlag(dd->keymap2Name, keymap2Flag); #ifdef DDEBUG IDOS->Printf("KEYMAP2='%s' FLAG2='%s' (tooltype)\n",dd->keymap2Name,keymap2Flag); #endif } void _docky_Expunge(struct DockyIFace *Self) { struct DockyData *dd = (struct DockyData *)((uint32)Self - Self->Data.NegativeSize); #ifdef DDEBUG IExec->DebugPrintF("[%s]docky_Expunge\n",LIBNAME); #endif if(!Self->Data.RefCount) { #ifdef DDEBUG IDOS->Printf("Reseting to Input Prefs. keymap ('%s')\n",dd->keymap1Name); #endif ChangeKeymap(dd, dd->keymap1Name); // reset default input keymap #ifdef DDEBUG IDOS->Printf("Disposing picObject=0x%08lx\n",picObject); #endif if(picObject) IDataTypes->DisposeDTObject(picObject); picObject = NULL; } } BOOL _docky_DockyGet(struct DockyIFace *Self, uint32 msgType, uint32 *msgData) { struct DockyData *dd = (struct DockyData *)((uint32)Self - Self->Data.NegativeSize); BOOL res = TRUE; #ifdef DDEBUG IExec->DebugPrintF("[%s]DockyGet\n",LIBNAME); //IDOS->Printf(" %02ld\n",msgType); #endif switch(msgType) { case DOCKYGET_Version: *msgData = DOCKYVERSION; break; case DOCKYGET_GetSize: *((struct DockySize *)msgData) = dd->size; break; case DOCKYGET_FrameDelay: *msgData = -1; break; case DOCKYGET_RenderMode: *msgData = DOCKYRENDERMODE_RPPA; break; // case DOCKYGET_AllowsIconChange: // *msgData = FALSE; // break; case DOCKYGET_Notifications: *msgData = DOCKYNOTIFY_MOUSEBUTTONS; break; case DOCKYGET_ContextMenu: { Object *contextMenu = (Object *)msgData; #ifdef DDEBUG IDOS->Printf("[DOCKYGET_ContextMenu]\n"); #endif /* Object *item1 = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, dd->keymap1Name, PMIA_ID, MENU_OPT1, PMIA_Disabled, TRUE, //PMIA_ReadOnly, TRUE, PMIA_Icon, OBJ(GID_BITMAP1) = IIntuition->NewObject(NULL, "bitmap.image", BITMAP_SourceFile, keymap1Flag, BITMAP_Screen, dd->scr, BITMAP_Masking, TRUE, TAG_DONE), TAG_END); Object *item2 = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, dd->keymap2Name, PMIA_ID, MENU_OPT2, PMIA_Disabled, TRUE, //PMIA_ReadOnly, TRUE, PMIA_Icon, OBJ(GID_BITMAP2) = IIntuition->NewObject(NULL, "bitmap.image", BITMAP_SourceFile, keymap2Flag, BITMAP_Screen, dd->scr, BITMAP_Masking, TRUE, TAG_DONE), TAG_END); */ Object *subMenu = IIntuition->NewObject(NULL, "popupmenu.class", TAG_END); Object *itemSM = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, "Mode", PMIA_SubMenu, subMenu, TAG_END); Object *itemS1 = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, "PopUp", PMIA_ID, MENU_OPT1, PMIA_CheckIt, TRUE, PMIA_Checked, !WinMode, TAG_END); Object *itemS2 = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, "Window", PMIA_ID, MENU_OPT2, PMIA_CheckIt, TRUE, PMIA_Checked, WinMode, TAG_END); Object *item3 = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title, "Settings...", PMIA_ID, MENU_PREFS, TAG_END); // Object *itemBar = IIntuition->NewObject(NULL, "popupmenuitem.class", PMIA_Title,~0, TAG_END); // language2 valid/available // if( !OBJ(GID_BITMAP2) ) IIntuition->SetAttrs(item2, PMIA_Disabled,FALSE, PMIA_ReadOnly,TRUE, TAG_DONE); IIntuition->IDoMethod(subMenu, OM_ADDMEMBER, itemS1); // mode popup IIntuition->IDoMethod(subMenu, OM_ADDMEMBER, itemS2); // mode window IIntuition->IDoMethod(contextMenu, OM_ADDMEMBER, itemSM); // Submenu string 'Mode' if(WinMode) IIntuition->IDoMethod(contextMenu, OM_ADDMEMBER, item3); // Settings... // IIntuition->IDoMethod(contextMenu, OM_ADDMEMBER, itemBar); } break; // case DOCKYGET_AllowsRename: // *msgData = FALSE; // break; case DOCKYGET_InvisibleProcess: *msgData = FALSE; break; case DOCKYGET_ShowsName: *msgData = TRUE; break; // case DOCKYGET_Name: // *msgData = (uint32)IDOS->FilePart(dd->filename); // break; case DOCKYGET_NeedsAttention: // uint32 BOOL #ifdef DDEBUG IDOS->Printf("[DOCKYGET_NeedsAttention]\n"); #endif *msgData = TRUE; break; default: #ifdef DDEBUG IDOS->Printf("[DOCKYGET_????] %02ld\n",msgType); #endif res = FALSE; break; } return res; } BOOL _docky_DockySet(struct DockyIFace *Self, uint32 msgType, uint32 msgData) { struct DockyData *dd = (struct DockyData *)((uint32)Self - Self->Data.NegativeSize); BOOL res = TRUE; #ifdef DDEBUG IExec->DebugPrintF("[%s]DockySet\n",LIBNAME); //IDOS->Printf("%04ld\n",msgType); #endif switch(msgType) { case DOCKYSET_FileName: IUtility->Strlcpy( dd->filename, (STRPTR)msgData, sizeof(dd->filename) ); ReadDockyPrefs(dd); break; case DOCKYSET_Screen: dd->scr = (struct Screen *)msgData; LoadImageFlag(dd); #ifdef DDEBUG IDOS->Printf("[DOCKYSET_Screen]\n"); #endif break; case DOCKYSET_Window: dd->win = (struct Window *)msgData; #ifdef DDEBUG IDOS->Printf("[DOCKYSET_Window]\n"); #endif break; case DOCKYSET_RenderDestination: { struct DockyRenderDestination *drd = (struct DockyRenderDestination *)msgData; #ifdef DDEBUG IDOS->Printf("[DOCKYSET_RenderDestination] "); #endif dd->size = drd->renderSize; switch(drd->renderMode) { case DOCKYRENDERMODE_RPPA: #ifdef DDEBUG IDOS->Printf("DOCKYRENDERMODE_RPPA\n"); #endif dd->rp = drd->render.RP; break; default: #ifdef DDEBUG IDOS->Printf("default\n"); #endif dd->rp = NULL; res = FALSE; break; } } break; case DOCKYSET_RedrawNow: #ifdef DDEBUG IDOS->Printf("[DOCKYSET_RedrawNow]\n"); #endif // LoadImageFlag(dd); <- DON'T! Freezes system if drag an icon over docky DockyRender(dd); break; case DOCKYSET_DockTypeChange: { struct DockyDockType *ddt = (struct DockyDockType *)msgData; #ifdef DDEBUG IDOS->Printf("[DOCKYSET_DockTypeChange]\n"); #endif if(dd->self.dockNr == ddt->dockNr && ddt->dockType != AMIDOCK_DockType_Icons) res = FALSE; } break; case DOCKYSET_SingleClick: #ifdef DDEBUG IDOS->Printf("[DOCKYSET_SingleClick]\n"); #endif if(!DockySClick) break; case DOCKYSET_DoubleClick: #ifdef DDEBUG IDOS->Printf("[DOCKYSET_DoubleClick]\n"); #endif if(WinMode) OpenDockWindow(dd); else OpenDockMenu(dd); LoadImageFlag(dd); // (re)load new image/flag after user choosed new SignalDocky(dd, 0); // we only need to 'RedrawNow': just send IExec->Signal... break; case DOCKYSET_ContextMenuResult: { Object *o = (Object *)msgData; #ifdef DOCKY_DEBUG IDOS->Printf("[DOCKYSET_ContextMenuResult]\n"); #endif if(o) { IIntuition->GetAttr(PMIA_ID, o, (uint32 *)&dd->km_item); #ifdef DDEBUG IDOS->Printf("KeyMapSwitcher: item=%ld\n",dd->km_item); #endif switch(dd->km_item) { case MENU_OPT1: WinMode = FALSE; // PopUp mode break; case MENU_OPT2: WinMode = TRUE; // Window mode break; case MENU_PREFS: { char keymap2Sel[128]; // to check if keymap2 changed IUtility->Strlcpy( keymap2Sel, dd->keymap2Name, sizeof(keymap2Sel) ); OpenPrefsWindow(dd); #ifdef DDEBUG IDOS->Printf("%s == %s?\n",dd->keymap2Name,keymap2Sel); #endif if(IUtility->Stricmp(dd->keymap2Name, keymap2Sel) != 0) {// NEW keymap2: tooltype (KEYMAP2); keymap2Name & keymap2Flag SetKeyMapFlag(dd->keymap2Name, keymap2Flag); #ifdef DDEBUG IDOS->Printf("[NEW]KEYMAP2='%s' FLAG2='%s' (tooltype)\n",dd->keymap2Name,keymap2Flag); #endif } } break; } // END switch(dd-km->item) } // END if(o).. } break; case DOCKYSET_DockyAttention: dd->attn = *(struct DockyAttention *)msgData; #ifdef DDEBUG IDOS->Printf("[DOCKYSET_DockyAttention] 0x%08lx %d\n",dd->attn.amidockTask,dd->attn.attentionSignalBit); #endif break; default: #ifdef DDEBUG IDOS->Printf("[DOCKYSET_????] %04ld\n",msgType); #endif res = FALSE; break; } return res; } BOOL _docky_DockyProcess(struct DockyIFace *Self, uint32 turnCount, uint32 *msgType, uint32 *msgData, BOOL *anotherTurn) { // struct DockyData *dd = (struct DockyData *)((uint32)Self - Self->Data.NegativeSize); #ifdef DDEBUG IExec->DebugPrintF("[%s]docky_DockyProcess\n",LIBNAME); IDOS->Printf("DockyProcess: turnCount=%ld msgType=%ld msgData=%ld anotherTurn=%ld\n",\ turnCount,*msgType,*msgData,*anotherTurn); #endif return TRUE; } void SignalDocky(struct DockyData *dd, uint32 flags) { IExec->Signal( (struct Task *)dd->attn.amidockTask, 1L << dd->attn.attentionSignalBit); }

