bool MFFileNative_FindNext(MFFind *pFind, MFFindData *pFindData) { WIN32_FIND_DATA fd; BOOL more = FindNextFile((HANDLE)pFind->pFilesystemData, &fd); if(!more) return false; MFString_CopyCat(pFindData->pSystemPath, (char*)pFind->pMount->pFilesysData, pFind->searchPattern); char *pLast = MFString_RChr(pFindData->pSystemPath, '/'); if(pLast) pLast[1] = 0; else pFindData->pSystemPath[0] = 0; pFindData->info.attributes = ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? MFFA_Directory : 0) | ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? MFFA_Hidden : 0) | ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? MFFA_ReadOnly : 0); pFindData->info.size = (uint64)fd.nFileSizeLow | (((uint64)fd.nFileSizeHigh) << 32); pFindData->info.createTime = (uint64)fd.ftCreationTime.dwHighDateTime << 32 | (uint64)fd.ftCreationTime.dwLowDateTime; pFindData->info.writeTime = (uint64)fd.ftLastWriteTime.dwHighDateTime << 32 | (uint64)fd.ftLastWriteTime.dwLowDateTime; pFindData->info.accessTime = (uint64)fd.ftLastAccessTime.dwHighDateTime << 32 | (uint64)fd.ftLastAccessTime.dwLowDateTime; MFString_CopyUTF16ToUTF8((char*)pFindData->pFilename, fd.cFileName); return true; }
MF_API char* MFString_WCharAsUTF8(const wchar_t *pWString, size_t *pNumBytes) { // count number of actual characters in the string size_t numBytes = 0; const wchar_t *pCount = pWString; while (*pCount) numBytes += MFString_EncodeUTF8(*pCount++, NULL); // get some space in the MFStr buffer char *pBuffer = &gStringBuffer[gStringOffset]; gStringOffset += numBytes + 1; // if we wrapped the string buffer if (gStringOffset >= sizeof(gStringBuffer) - 1024) { gStringOffset = numBytes + 1; pBuffer = gStringBuffer; } // copy the string MFString_CopyUTF16ToUTF8(pBuffer, pWString); if (pNumBytes) *pNumBytes = numBytes; return pBuffer; }
virtual HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) { MFDebug_Log(2, MFStr("WASAPI: Device added: %S", pwstrDeviceId)); char temp[128]; MFString_CopyUTF16ToUTF8(temp, pwstrDeviceId); MFDevice *pDev = MFDevice_GetDeviceById(temp); if(!pDev) pDev = NewDevice(pwstrDeviceId); return S_OK; }
virtual HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) { MFDebug_Log(2, MFStr("WASAPI: Default device changed: %S", pwstrDefaultDeviceId)); char temp[128]; MFString_CopyUTF16ToUTF8(temp, pwstrDefaultDeviceId); MFDevice *pDev = MFDevice_GetDeviceById(temp); if(!pDev) pDev = NewDevice(pwstrDefaultDeviceId); if(pDev) MFDevice_SetDefaultDevice(gDt[flow], gDef[role], pDev); return S_OK; }
virtual HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) { MFDebug_Log(2, MFStr("WASAPI: Device removed: %S", pwstrDeviceId)); char temp[128]; MFString_CopyUTF16ToUTF8(temp, pwstrDeviceId); MFDevice *pDev = MFDevice_GetDeviceById(temp); if(!pDev) pDev = NewDevice(pwstrDeviceId); if(pDev) UpdateState(pDev, DEVICE_STATE_UNPLUGGED); return S_OK; }
virtual HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { MFDebug_Log(2, MFStr("WASAPI: State changed: %d (%S)", dwNewState, pwstrDeviceId)); char temp[128]; MFString_CopyUTF16ToUTF8(temp, pwstrDeviceId); MFDevice *pDev = MFDevice_GetDeviceById(temp); if(!pDev) pDev = NewDevice(pwstrDeviceId); if(pDev) UpdateState(pDev, dwNewState); return S_OK; }
static void GetDeviceInfo(IMMDevice *pDevice, MFDevice *pDev) { wchar_t *pWC; pDevice->GetId(&pWC); MFString_CopyUTF16ToUTF8(pDev->strings[MFDS_ID], pWC); CoTaskMemFree(pWC); DWORD state; pDevice->GetState(&state); UpdateState(pDev, state); IPropertyStore *pProps; pDevice->OpenPropertyStore(STGM_READ, &pProps); PROPVARIANT v; PropVariantInit(&v); pProps->GetValue(PKEY_DeviceInterface_FriendlyName, &v); MFString_CopyUTF16ToUTF8(pDev->strings[MFDS_InterfaceName], v.pwszVal); PropVariantClear(&v); PropVariantInit(&v); pProps->GetValue(PKEY_Device_DeviceDesc, &v); MFString_CopyUTF16ToUTF8(pDev->strings[MFDS_Description], v.pwszVal); PropVariantClear(&v); PropVariantInit(&v); pProps->GetValue(PKEY_Device_FriendlyName, &v); MFString_CopyUTF16ToUTF8(pDev->strings[MFDS_DeviceName], v.pwszVal); PropVariantClear(&v); PropVariantInit(&v); pProps->GetValue(PKEY_Device_Manufacturer, &v); MFString_CopyUTF16ToUTF8(pDev->strings[MFDS_Manufacturer], v.pwszVal ? v.pwszVal : L""); PropVariantClear(&v); pProps->Release(); }
bool MFFileNative_FindFirst(MFFind *pFind, const char *pSearchPattern, MFFindData *pFindData) { WIN32_FIND_DATA fd; HANDLE hFind = FindFirstFile(MFString_UFT8AsWChar(MFStr("%s%s", (char*)pFind->pMount->pFilesysData, pSearchPattern)), &fd); if(hFind == INVALID_HANDLE_VALUE) return false; BOOL more = TRUE; while(!MFWString_Compare(fd.cFileName, L".") || !MFWString_Compare(fd.cFileName, L"..") && more) more = FindNextFile(hFind, &fd); if(!more) { FindClose(hFind); return false; } MFString_CopyCat(pFindData->pSystemPath, (char*)pFind->pMount->pFilesysData, pFind->searchPattern); char *pLast = MFString_RChr(pFindData->pSystemPath, '/'); if(pLast) pLast[1] = 0; else pFindData->pSystemPath[0] = NULL; pFind->pFilesystemData = (void*)hFind; pFindData->info.attributes = ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? MFFA_Directory : 0) | ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? MFFA_Hidden : 0) | ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? MFFA_ReadOnly : 0); pFindData->info.size = (uint64)fd.nFileSizeLow | (((uint64)fd.nFileSizeHigh) << 32); pFindData->info.createTime = (uint64)fd.ftCreationTime.dwHighDateTime << 32 | (uint64)fd.ftCreationTime.dwLowDateTime; pFindData->info.writeTime = (uint64)fd.ftLastWriteTime.dwHighDateTime << 32 | (uint64)fd.ftLastWriteTime.dwLowDateTime; pFindData->info.accessTime = (uint64)fd.ftLastAccessTime.dwHighDateTime << 32 | (uint64)fd.ftLastAccessTime.dwLowDateTime; MFString_CopyUTF16ToUTF8((char*)pFindData->pFilename, fd.cFileName); return true; }
MFString& MFString::FromUTF16(const wchar_t *pString) { if(pData) { MFStringData_Release(pData); pData = NULL; } if(pString) { pData = MFStringData_Alloc(); size_t len = 0; const wchar_t *pS = pString; while(*pS) len += MFString_EncodeUTF8(*pS++, NULL); pData->bytes = len; pData->pMemory = (char*)stringHeap.Alloc(pData->bytes + 1, &pData->allocated); MFString_CopyUTF16ToUTF8(pData->pMemory, (const wchar_t*)pString); } return *this; }
void MFSound_InitWASAPI() { gDevices.Init(sizeof(MFAudioDevice), 8, 8); gCaptureDevices.Init(sizeof(MFAudioCaptureDevice), 8, 8); HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&gpEnumerator); if(FAILED(hr)) { MFDebug_Assert(false, "Couldn't create multimedia device enumerator!"); return; } // enumerate audio devices... gpNotification = new MFAudioDeviceNotification; gpEnumerator->RegisterEndpointNotificationCallback(gpNotification); // enumerate render devices IMMDeviceCollection *pDevices; gpEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices); if(pDevices) { UINT count; pDevices->GetCount(&count); for(UINT i=0; i<count; ++i) { IMMDevice *pDevice; pDevices->Item(i, &pDevice); MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioRender, NULL); pDev->pInternal = gDevices.AllocAndZero(); MFAudioDevice &device = *(MFAudioDevice*)pDev->pInternal; GetDeviceInfo(pDevice, pDev); pDevice->Release(); MFDebug_Log(0, MFStr("Found audio device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID])); } pDevices->Release(); } // enumerate capture devices gpEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices); if(pDevices) { UINT count; pDevices->GetCount(&count); for(UINT i=0; i<count; ++i) { IMMDevice *pDevice; pDevices->Item(i, &pDevice); MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioCapture, NULL); pDev->pInternal = gCaptureDevices.AllocAndZero(); MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)pDev->pInternal; GetDeviceInfo(pDevice, pDev); pDevice->Release(); MFDebug_Log(0, MFStr("Found audio capture device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID])); } pDevices->Release(); } // set defaults (this is some awkward windows code!) for(int i=0; i<2; ++i) { for(int j=0; j<3; ++j) { IMMDevice *pDevice; gpEnumerator->GetDefaultAudioEndpoint(gDirection[i], gRole[j], &pDevice); if(pDevice) { wchar_t *pDefaultId; pDevice->GetId(&pDefaultId); char temp[128]; MFString_CopyUTF16ToUTF8(temp, pDefaultId); MFDevice *pDev = MFDevice_GetDeviceById(temp); MFDevice_SetDefaultDevice(gDt[i], gDef[j], pDev); CoTaskMemFree(pDefaultId); pDevice->Release(); } } } }
void MFMidi_InitModulePlatformSpecific() { UINT numInputDevices = midiInGetNumDevs(); for (UINT i = 0; i < numInputDevices; ++i) { MIDIINCAPS caps; MMRESULT r = midiInGetDevCaps(i, &caps, sizeof(caps)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to query midi input device: %s", MFString_WCharAsUTF8(errorBuffer))); continue; } MFDevice *pDevice = MFDevice_AllocDevice(MFDT_MidiInput, &DestroyInputDevice); pDevice->pInternal = MFHeap_AllocAndZero(sizeof(MFMidiPC_MidiInputDevice)); pDevice->state = MFDevState_Available; MFMidiPC_MidiOutputDevice *pDev = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; pDev->mid = caps.wMid; pDev->pid = caps.wPid; MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_ID], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_DeviceName], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_Description], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_InterfaceName], caps.szPname); // MFDS_Manufacturer MFDebug_Log(0, MFStr("Found midi input device: %s (%04X:%04X) - state: %d", pDevice->strings[MFDS_ID], caps.wMid, caps.wPid, pDevice->state)); } UINT numOutputDevices = midiOutGetNumDevs(); for (UINT i = 0; i < numOutputDevices; ++i) { MIDIOUTCAPS caps; MMRESULT r = midiOutGetDevCaps(i, &caps, sizeof(caps)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to query midi output device: %s", MFString_WCharAsUTF8(errorBuffer))); continue; } MFDevice *pDevice = MFDevice_AllocDevice(MFDT_MidiOutput, &DestroyOutputDevice); pDevice->pInternal = MFHeap_AllocAndZero(sizeof(MFMidiPC_MidiOutputDevice)); pDevice->state = MFDevState_Available; MFMidiPC_MidiOutputDevice *pDev = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal; pDev->mid = caps.wMid; pDev->pid = caps.wPid; MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_ID], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_DeviceName], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_Description], caps.szPname); MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_InterfaceName], caps.szPname); // MFDS_Manufacturer MFDebug_Log(0, MFStr("Found midi output device: %s (%04X:%04X) - state: %d", pDevice->strings[MFDS_ID], caps.wMid, caps.wPid, pDevice->state)); } }
void HKStringEntryLogic::Update() { bool shiftL = !!MFInput_Read(Key_LShift, IDD_Keyboard); bool shiftR = !!MFInput_Read(Key_RShift, IDD_Keyboard); bool ctrlL = !!MFInput_Read(Key_LControl, IDD_Keyboard); bool ctrlR = !!MFInput_Read(Key_RControl, IDD_Keyboard); int keyPressed = 0; bool shift = shiftL || shiftR; bool ctrl = ctrlL || ctrlR; #if defined(MF_WINDOWS) if(ctrl && MFInput_WasPressed(Key_C, IDD_Keyboard) && selectionStart != selectionEnd) { BOOL opened = OpenClipboard(apphWnd); if(opened) { int selMin = MFMin(selectionStart, selectionEnd); int selMax = MFMax(selectionStart, selectionEnd); int numChars = selMax-selMin; HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, numChars + 1); char *pString = (char*)GlobalLock(hData); MFString_Copy(pString, GetRenderString().SubStr(selMin, numChars).CStr()); GlobalUnlock(hData); EmptyClipboard(); SetClipboardData(CF_TEXT, hData); CloseClipboard(); } } else if(ctrl && MFInput_WasPressed(Key_X, IDD_Keyboard) && selectionStart != selectionEnd) { BOOL opened = OpenClipboard(apphWnd); if(opened) { int selMin = MFMin(selectionStart, selectionEnd); int selMax = MFMax(selectionStart, selectionEnd); int numChars = selMax-selMin; HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, numChars + 1); char *pString = (char*)GlobalLock(hData); MFString_Copy(pString, GetRenderString().SubStr(selMin, numChars).CStr()); GlobalUnlock(hData); EmptyClipboard(); SetClipboardData(CF_TEXT, hData); CloseClipboard(); ClearSelection(); } } else if(ctrl && MFInput_WasPressed(Key_V, IDD_Keyboard)) { BOOL opened = OpenClipboard(apphWnd); if(opened) { int selMin = MFMin(selectionStart, selectionEnd); int selMax = MFMax(selectionStart, selectionEnd); int numChars = selMax-selMin; HANDLE hData = GetClipboardData(CF_TEXT); MFString paste((const char*)GlobalLock(hData), true); buffer.Replace(selMin, numChars, paste); GlobalUnlock(hData); cursorPos = selMin + paste.NumBytes(); selectionStart = selectionEnd = cursorPos; GlobalUnlock(hData); CloseClipboard(); if((numChars || cursorPos != selMin) && changeCallback) changeCallback(buffer.CStr()); } } else #endif { // check for new keypresses for(int a=0; a<255; a++) { if(MFInput_WasPressed(a, IDD_Keyboard)) { keyPressed = a; holdKey = a; repeatDelay = gRepeatDelay; break; } } // handle repeat keys if(holdKey && MFInput_Read(holdKey, IDD_Keyboard)) { repeatDelay -= MFSystem_TimeDelta(); if(repeatDelay <= 0.f) { keyPressed = holdKey; repeatDelay += gRepeatRate; } } else holdKey = 0; // if there was a new key press if(keyPressed) { switch(keyPressed) { case Key_Backspace: case Key_Delete: { if(selectionStart != selectionEnd) { ClearSelection(); } else { if(keyPressed == Key_Backspace && cursorPos > 0) { buffer.ClearRange(--cursorPos, 1); selectionStart = selectionEnd = cursorPos; if(changeCallback) changeCallback(buffer.CStr()); } else if(keyPressed == Key_Delete && cursorPos < buffer.NumBytes()) { buffer.ClearRange(cursorPos, 1); selectionStart = selectionEnd = cursorPos; if(changeCallback) changeCallback(buffer.CStr()); } } break; } case Key_Left: case Key_Right: case Key_Home: case Key_End: { if(ctrl) { if(keyPressed == Key_Left) { while(cursorPos && MFIsWhite(buffer[cursorPos-1])) --cursorPos; if(MFIsAlphaNumeric(buffer[cursorPos-1])) { while(cursorPos && MFIsAlphaNumeric(buffer[cursorPos-1])) --cursorPos; } else if(cursorPos) { --cursorPos; while(cursorPos && buffer[cursorPos-1] == buffer[cursorPos]) --cursorPos; } } else if(keyPressed == Key_Right) { while(cursorPos < buffer.NumBytes() && MFIsWhite(buffer[cursorPos])) ++cursorPos; if(MFIsAlphaNumeric(buffer[cursorPos])) { while(cursorPos < buffer.NumBytes() && MFIsAlphaNumeric(buffer[cursorPos])) ++cursorPos; } else if(cursorPos < buffer.NumBytes()) { ++cursorPos; while(cursorPos < buffer.NumBytes() && buffer[cursorPos] == buffer[cursorPos-1]) ++cursorPos; } } else if(keyPressed == Key_Home) cursorPos = 0; else if(keyPressed == Key_End) cursorPos = buffer.NumBytes(); } else { if(keyPressed == Key_Left) cursorPos = (!shift && selectionStart != selectionEnd ? MFMin(selectionStart, selectionEnd) : MFMax(cursorPos-1, 0)); else if(keyPressed == Key_Right) cursorPos = (!shift && selectionStart != selectionEnd ? MFMax(selectionStart, selectionEnd) : MFMin(cursorPos+1, buffer.NumBytes())); else if(keyPressed == Key_Home) cursorPos = 0; // TODO: if multiline, go to start of line.. else if(keyPressed == Key_End) cursorPos = buffer.NumBytes(); // TODO: if multiline, go to end of line... } if(shift) selectionEnd = cursorPos; else selectionStart = selectionEnd = cursorPos; break; } default: { bool caps = MFInput_GetKeyboardStatusState(KSS_CapsLock); int ascii = MFInput_KeyToAscii(keyPressed, shift, caps); if(ascii && (!maxLen || buffer.NumBytes() < maxLen-1)) { // check character exclusions if(MFIsNewline(ascii) && type != ST_MultiLine) break; if(ascii == '\t' && type != ST_MultiLine) break; if(type == ST_Numeric && !MFIsNumeric(ascii)) break; if(include) { if(include.FindChar(ascii) < 0) break; } if(exclude) { if(exclude.FindChar(ascii) >= 0) break; } int selMin = MFMin(selectionStart, selectionEnd); int selMax = MFMax(selectionStart, selectionEnd); int selRange = selMax - selMin; const uint16 wstr[] = { (uint16)ascii, 0 }; char insert[5]; MFString_CopyUTF16ToUTF8(insert, wstr); buffer.Replace(selMin, selRange, insert); cursorPos = selMin + 1; selectionStart = selectionEnd = cursorPos; if(changeCallback) changeCallback(buffer.CStr()); } break; } } } } }