/* Copyright (C) 2010, 2011 tico-tico */ #include "bass_interface.h" HINSTANCE hInst; PLUGINLINK *pluginLink; int hLangpack; PLUGININFOEX pluginInfo={ sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), __DESCRIPTION, __AUTHOR, __AUTHOREMAIL, __COPYRIGHT, __AUTHORWEB, UNICODE_AWARE, 0, MIID_BASSINT }; struct MM_INTERFACE mmi; static HANDLE hHooks[5] = {0}; static HANDLE hService; static HINSTANCE hBass = NULL; extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { hInst=hinstDLL; return TRUE; } extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { return &pluginInfo; } static const MUUID interfaces[] = {MIID_BASSINT, MIID_LAST}; extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { return interfaces; } #define MAXCHAN 5 static TCHAR CurrBassPath[MAX_PATH], tmp[MAX_PATH]; static int sndNSnd = 0, sndLimSnd; static HSTREAM sndSSnd[MAXCHAN] = {0}; static WORD TimeWrd1, TimeWrd2, StatMask; static BOOL QuietTime, Preview, EnPreview; static int Volume; static int device = -1; static int newBass = 0; static HWND ClistHWND; static int OnPlaySnd(WPARAM wParam, LPARAM lParam) { char * pszFile = (char *) lParam; SYSTEMTIME systime; WORD currtime, currstat; BOOL doPlay = TRUE; GetLocalTime(&systime); currtime = MAKEWORD(systime.wMinute, systime.wHour); currstat = 1; switch (CallService(MS_CLIST_GETSTATUSMODE, 0, 0)) { case ID_STATUS_OUTTOLUNCH: currstat <<= 1; case ID_STATUS_ONTHEPHONE: currstat <<= 1; case ID_STATUS_INVISIBLE: currstat <<= 1; case ID_STATUS_FREECHAT: currstat <<= 1; case ID_STATUS_DND: currstat <<= 1; case ID_STATUS_OCCUPIED: currstat <<= 1; case ID_STATUS_NA: currstat <<= 1; case ID_STATUS_AWAY: currstat <<= 1; case ID_STATUS_ONLINE: currstat <<= 1; } if ( !DBGetContactSettingByte(NULL,"Skin","UseSound",0) ) doPlay = FALSE; if ( QuietTime ) if ( ((TimeWrd1 < TimeWrd2) && (TimeWrd1 <= currtime && currtime < TimeWrd2)) || ((TimeWrd2 < TimeWrd1) && (TimeWrd1 <= currtime || currtime < TimeWrd2)) ) doPlay = FALSE; if ( !(currstat & StatMask) ) doPlay = FALSE; if ( Preview || (int)wParam==1 ) doPlay = TRUE; if ( !pszFile ) doPlay = FALSE; if ( doPlay ) { BASS_StreamFree(sndSSnd[sndNSnd]); sndSSnd[sndNSnd] = BASS_StreamCreateFile(FALSE, pszFile, 0, 0, BASS_STREAM_AUTOFREE); BASS_ChannelPlay(sndSSnd[sndNSnd], FALSE); sndNSnd = (sndNSnd+1)%sndLimSnd; } Preview = FALSE; return 0; } #define SLIDER_MIN 0 #define SLIDER_MAX 100 INT_PTR CALLBACK OptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INITDIALOG: { int i; SYSTEMTIME systime = {0}; TranslateDialogDefault(hwndDlg); SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_RESETCONTENT, 0, 0); for(i=1; i<=MAXCHAN; i++) SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_ADDSTRING, 0, (LPARAM)_itot(i, tmp, 10)); SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_SETCURSEL, sndLimSnd - 1, 0); SendDlgItemMessage(hwndDlg, IDC_CURRPATH, WM_SETTEXT, 0, (LPARAM)CurrBassPath); SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETRANGE, FALSE, MAKELONG(SLIDER_MIN,SLIDER_MAX)); SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETPOS, TRUE, Volume); SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETPAGESIZE, 0, 5); systime.wHour = HIBYTE(TimeWrd1); systime.wMinute = LOBYTE(TimeWrd1); systime.wYear = 2000; systime.wMonth = 1; systime.wDay = 1; SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_SETFORMAT, 0, (LPARAM)_T("HH:mm")); SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&systime); systime.wHour = HIBYTE(TimeWrd2); systime.wMinute = LOBYTE(TimeWrd2); SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_SETFORMAT, 0, (LPARAM)_T("HH:mm")); SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&systime); CheckDlgButton(hwndDlg, IDC_PREVIEW, EnPreview ? BST_CHECKED : BST_UNCHECKED); for(i = IDC_CHECKBOX1; i < IDC_CHECKBOX10+1; i++) { if (StatMask & (1 << (i-IDC_CHECKBOX1))) CheckDlgButton(hwndDlg, i, BST_CHECKED); } if (QuietTime) { EnableWindow(GetDlgItem(hwndDlg,IDC_TIME1), TRUE); EnableWindow(GetDlgItem(hwndDlg,IDC_TIME2), TRUE); CheckDlgButton(hwndDlg, IDC_QUIETTIME, BST_CHECKED); } if (hBass == NULL) { EnableWindow(GetDlgItem(hwndDlg, IDC_VOLUME), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_MAXCHANNEL), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_OUTDEVICE), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_QUIETTIME), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), FALSE); for(i = IDC_CHECKBOX1; i < IDC_CHECKBOX10+1; i++) { EnableWindow(GetDlgItem(hwndDlg, i), FALSE); } } else { DBVARIANT dbv = {0}; BASS_DEVICEINFO info; DWORD bassver = BASS_GetVersion(); mir_sntprintf(tmp, SIZEOF(tmp), TranslateT("un4seen's bass version: %d.%d.%d.%d"), bassver >> 24, (bassver >> 16) & 0xff, (bassver >> 8) & 0xff, bassver & 0xff); SendDlgItemMessage(hwndDlg, IDC_BASSVERSION, WM_SETTEXT, 0, (LPARAM)tmp); SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_ADDSTRING, 0, (LPARAM)TranslateT("--default device--")); SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_SETCURSEL, 0, 0); DBGetContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, &dbv); for (i=1; BASS_GetDeviceInfo(i+newBass, &info); i++) { SendDlgItemMessageA(hwndDlg, IDC_OUTDEVICE, CB_ADDSTRING, 0, (LPARAM)info.name); if (!lstrcmpA(dbv.pszVal, info.name)) SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_SETCURSEL, i, 0); } DBFreeVariant(&dbv); } return 1; } case WM_HSCROLL: if (hBass != NULL) if (LOWORD(wParam) == SB_ENDSCROLL || LOWORD(wParam) == SB_THUMBTRACK) { BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_GETPOS, 0, 0) * 100); Preview = TRUE; if (EnPreview) SkinPlaySound("AlertMsg"); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } break; case WM_NOTIFY: switch(((LPNMHDR)lParam)->code) { case PSN_APPLY: if (hBass != NULL) { int i; SYSTEMTIME systime; SendDlgItemMessageA(hwndDlg, IDC_OUTDEVICE, WM_GETTEXT, sizeof(tmp), (LPARAM)tmp); DBWriteContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, (char *)tmp); Volume = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_GETPOS, 0, 0); DBWriteContactSettingByte(NULL, ModuleName, OPT_VOLUME, Volume); sndLimSnd = SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_GETCURSEL, 0, 0) + 1; if ( sndLimSnd > MAXCHAN ) sndLimSnd = MAXCHAN; DBWriteContactSettingByte(NULL, ModuleName, OPT_MAXCHAN, sndLimSnd); QuietTime = IsDlgButtonChecked(hwndDlg, IDC_QUIETTIME) == BST_CHECKED; DBWriteContactSettingByte(NULL, ModuleName, OPT_QUIETTIME, QuietTime); SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_GETSYSTEMTIME, 0, (LPARAM)&systime); TimeWrd1 = MAKEWORD(systime.wMinute, systime.wHour); DBWriteContactSettingWord(NULL, ModuleName, OPT_TIME1, TimeWrd1); SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_GETSYSTEMTIME, 0, (LPARAM)&systime); TimeWrd2 = MAKEWORD(systime.wMinute, systime.wHour); DBWriteContactSettingWord(NULL, ModuleName, OPT_TIME2, TimeWrd2); EnPreview = IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED; DBWriteContactSettingByte(NULL, ModuleName, OPT_PREVIEW, EnPreview); StatMask = 0; for(i = IDC_CHECKBOX10; i > IDC_CHECKBOX1-1; i--) { StatMask <<= 1; if(IsDlgButtonChecked(hwndDlg, i) == BST_CHECKED) StatMask |= 1; } DBWriteContactSettingWord(NULL, ModuleName, OPT_STATUS, StatMask); device = SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_GETCURSEL, 0, 0); if (device == 0) device = -1; else device += newBass; if (CallService(MS_TB_GETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", 0)==TBST_RELEASED) { BASS_Free(); BASS_Init(device, 44100, 0, ClistHWND, NULL); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 ); } } return 1; case PSN_RESET: if (hBass != NULL) { BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100); } return 1; case DTN_DATETIMECHANGE: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return 1; } break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_QUIETTIME: { BOOL b = IsDlgButtonChecked(hwndDlg, IDC_QUIETTIME) == BST_CHECKED; EnableWindow(GetDlgItem(hwndDlg,IDC_TIME1), b); EnableWindow(GetDlgItem(hwndDlg,IDC_TIME2), b); } case IDC_MAXCHANNEL: case IDC_OUTDEVICE: case IDC_CHECKBOX1: case IDC_CHECKBOX2: case IDC_CHECKBOX3: case IDC_CHECKBOX4: case IDC_CHECKBOX5: case IDC_CHECKBOX6: case IDC_CHECKBOX7: case IDC_CHECKBOX8: case IDC_CHECKBOX9: case IDC_CHECKBOX10: case IDC_PREVIEW: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; case IDC_GETBASS: CallService(MS_UTILS_OPENURL , 1, (LPARAM)"http://www.un4seen.com/"); break; } break; //case WM_CLOSE: // EndDialog(hwndDlg, 0); } return 0; } struct { char* szDescr; char* szName; int defIconID; } static const iconList[] = { { "Audio device is opened", "BASSSoundOnOffUp", IDI_BASSSoundOnOffUp }, { "Audio device is closed", "BASSSoundOnOffDown", IDI_BASSSoundOnOffDown } }; static HANDLE hIconLibItem[SIZEOF(iconList)]; void InitIcons(void) { int i; char szSettingName[100]; SKINICONDESC sid = {0}; TCHAR szFile[MAX_PATH]; GetModuleFileName(hInst, szFile, SIZEOF(szFile)); sid.cbSize = sizeof(SKINICONDESC); sid.ptszDefaultFile = szFile; sid.cx = sid.cy = 16; sid.pszName = szSettingName; sid.pszSection = ModuleName; sid.flags = SIDF_PATH_TCHAR; for (i = 0; i < SIZEOF(iconList); i++) { mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", ModuleName, iconList[i].szName); sid.pszDescription = (char*)iconList[i].szDescr; sid.iDefaultIndex = -iconList[i].defIconID; hIconLibItem[i] = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); } } int OptionsInit(WPARAM wParam, LPARAM lParam) { OPTIONSDIALOGPAGE odp = {0}; odp.cbSize = sizeof(odp); odp.position = 0; odp.hInstance = hInst; odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); odp.ptszTitle = _T(ModuleName); odp.pfnDlgProc = OptionsProc; odp.ptszGroup = _T("Customize"); odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); return 0; } INT_PTR BASSSoundOnOff(WPARAM wParam, LPARAM lParam) { if (hBass != NULL) { BOOL opened = CallService(MS_TB_GETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", 0) == TBST_RELEASED; if ( opened ) { BASS_Free(); // Close Device } else { BASS_Init(device, 44100, 0, ClistHWND, NULL); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 ); } CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", opened ? TBST_PUSHED : TBST_RELEASED); DBWriteContactSettingByte(NULL, ModuleName, OPT_DEVOPEN, !opened); } return 0; } int OnToolbarLoaded(WPARAM wParam, LPARAM lParam) { TBButton tbb = {0}; tbb.cbSize = sizeof(TBButton); tbb.pszButtonID = "BASSSoundOnOff"; tbb.pszButtonName = Translate("Open/close audio device"); tbb.pszServiceName = "BASSinterface/BASSSoundOnOff"; tbb.pszTooltipUp = Translate("Audio device is opened"); tbb.pszTooltipDn = Translate("Audio device is closed"); tbb.hPrimaryIconHandle = hIconLibItem[0]; tbb.hSecondaryIconHandle = hIconLibItem[1]; tbb.tbbFlags = TBBF_SHOWTOOLTIP; tbb.defPos = 1000; CallService(MS_TB_ADDBUTTON, 0, (LPARAM)&tbb); return 0; } int OnModulesLoaded(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv = {0}; if (DBGetContactSettingTString(NULL, ModuleName, OPT_BASSPATH, &dbv)) { DBWriteContactSettingTString(NULL, ModuleName, OPT_BASSPATH, _T("Plugins\\Bass\\Bass.dll")); lstrcpy(tmp, _T("Plugins\\Bass\\Bass.dll")); } else { lstrcpy(tmp, dbv.ptszVal); } DBFreeVariant(&dbv); CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)tmp, (LPARAM)CurrBassPath); hBass = LoadLibrary(CurrBassPath); if (hBass != NULL) { if (LOADBASSFUNCTION(BASS_Init) != NULL && LOADBASSFUNCTION(BASS_SetConfig) != NULL && LOADBASSFUNCTION(BASS_ChannelPlay) != NULL && LOADBASSFUNCTION(BASS_StreamCreateFile) != NULL && LOADBASSFUNCTION(BASS_GetVersion) != NULL && LOADBASSFUNCTION(BASS_StreamFree) != NULL && LOADBASSFUNCTION(BASS_GetDeviceInfo) != NULL && LOADBASSFUNCTION(BASS_Free)) { int i; BASS_DEVICEINFO info; newBass = (BASS_SetConfig(BASS_CONFIG_DEV_DEFAULT, TRUE) != 0); // will use new "Default" device if (!DBGetContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, &dbv)) { for (i=1; BASS_GetDeviceInfo(i, &info); i++) if (!lstrcmpA(dbv.pszVal, info.name)) device = i; } DBFreeVariant(&dbv); sndLimSnd = DBGetContactSettingByte(NULL, ModuleName, OPT_MAXCHAN, MAXCHAN); if ( sndLimSnd > MAXCHAN ) sndLimSnd = MAXCHAN; TimeWrd1 = DBGetContactSettingWord(NULL, ModuleName, OPT_TIME1, 0); TimeWrd2 = DBGetContactSettingWord(NULL, ModuleName, OPT_TIME2, 0); QuietTime = DBGetContactSettingByte(NULL, ModuleName, OPT_QUIETTIME, 0); EnPreview = DBGetContactSettingByte(NULL, ModuleName, OPT_PREVIEW, 0); StatMask = DBGetContactSettingWord(NULL, ModuleName, OPT_STATUS, 0x3ff); ClistHWND = (HWND)CallService("CLUI/GetHwnd", 0, 0); if (DBGetContactSettingByte(NULL, ModuleName, OPT_DEVOPEN, 1)) BASS_Init(device, 44100, 0, ClistHWND, NULL); else CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", TBST_PUSHED); Volume = DBGetContactSettingByte(NULL, ModuleName, OPT_VOLUME, 33); BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 ); hHooks[3] = HookEvent(ME_SKIN_PLAYINGSOUND, OnPlaySnd); } else { FreeLibrary(hBass); hBass = NULL; } } hHooks[4] = HookEvent(ME_OPT_INITIALISE, OptionsInit); return 0; } int OnShutdown(WPARAM wParam, LPARAM lParam) { if(hBass != NULL) { BASS_Free(); FreeLibrary(hBass); } return 0; } extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) { pluginLink = link; mir_getLP(&pluginInfo); mir_getMMI(&mmi); hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); hHooks[1] = HookEvent(ME_SYSTEM_SHUTDOWN, OnShutdown); hHooks[2] = HookEvent(ME_TB_MODULELOADED, OnToolbarLoaded); hService = CreateServiceFunction("BASSinterface/BASSSoundOnOff", BASSSoundOnOff); InitIcons(); return 0; } extern "C" int __declspec(dllexport) Unload(void) { int i; for (i = 0; i < SIZEOF(hHooks); i++) { if (hHooks[i]) UnhookEvent(hHooks[i]); } DestroyServiceFunction(hService); return 0; }