Result HcdInitialise() { volatile Result result; if (sizeof(struct CoreGlobalRegs) != 0x400 || sizeof(struct HostGlobalRegs) != 0x400 || sizeof(struct PowerReg) != 0x4) { LOGF("HCD: Incorrectly compiled driver. HostGlobalRegs: %#x (0x400), CoreGlobalRegs: %#x (0x400), PowerReg: %#x (0x4).\n", sizeof(struct HostGlobalRegs), sizeof(struct CoreGlobalRegs)); return ErrorCompiler; // Correct packing settings are required. } LOG_DEBUG("HCD: Reserving memory.\n"); CorePhysical = MemoryReserve(sizeof(struct CoreGlobalRegs), HCD_DESIGNWARE_BASE); Core = MemoryAllocate(sizeof(struct CoreGlobalRegs)); HostPhysical = MemoryReserve(sizeof(struct HostGlobalRegs), (void*)((u8*)HCD_DESIGNWARE_BASE + 0x400)); Host = MemoryAllocate(sizeof(struct HostGlobalRegs)); PowerPhysical = MemoryReserve(sizeof(struct PowerReg), (void*)((u8*)HCD_DESIGNWARE_BASE + 0xe00)); Power = MemoryAllocate(sizeof(struct PowerReg)); #ifdef BROADCOM_2835 ReadBackReg(&Core->VendorId); ReadBackReg(&Core->UserId); if ((Core->VendorId & 0xfffff000) != 0x4f542000) { // 'OT'2 LOGF("HCD: Hardware: %c%c%x.%x%x%x (BCM%.5x). Driver incompatible. Expected OT2.xxx (BCM2708x).\n", (Core->VendorId >> 24) & 0xff, (Core->VendorId >> 16) & 0xff, (Core->VendorId >> 12) & 0xf, (Core->VendorId >> 8) & 0xf, (Core->VendorId >> 4) & 0xf, (Core->VendorId >> 0) & 0xf, (Core->UserId >> 12) & 0xFFFFF); result = ErrorIncompatible; goto deallocate; }
BOOL InsertGraph (HWND hWnd) { PGRAPHSTRUCT pGraph; pGraph = MemoryAllocate (sizeof (GRAPHSTRUCT)) ; if (!pGraph) return (FALSE) ; pGraphs = pGraph; GetGraphConfig(pGraph); pGraph->bManualRefresh = FALSE ; pGraph->gMaxValues = DEFAULT_MAX_VALUES; pGraph->pptDataPoints = NULL ; pGraph->pDataTime = NULL ; pGraph->hWnd = hWnd ; pGraph->bModified = FALSE ; pGraph->Visual.iColorIndex = 0 ; pGraph->Visual.iWidthIndex = 0 ; pGraph->Visual.iStyleIndex = 0 ; return(TRUE) ; }
EngineAPIList #undef _ #ifdef VENOM_SINGLE_TRANSLATION_UNIT #include "venom_render.cpp" #include "venom_asset.cpp" #include "venom_physics.cpp" #include "venom_entity.cpp" #include "math_procedural.cpp" #ifndef VENOM_RELEASE #include "venom_debug.cpp" #include "venom_editor.cpp" #include "venom_serializer.cpp" #endif//VENOM_RELEASE #endif//VENOM_SINGE_TRANSLATION_UNIT #endif//VENOM_HOTLOAD //TODO(Torin) Remove This!!! static int VenomCopyFile(const char *a, const char *b) { FILE *fa = fopen(a, "rb"); FILE *fb = fopen(b, "wb"); if(fa == 0 || fb == 0) return 0; fseek(fa, 0, SEEK_END); size_t fileSize = ftell(fa); fseek(fa, 0, SEEK_SET); void *buffer = MemoryAllocate(fileSize); fread(buffer, 1, fileSize, fa); fwrite(buffer, 1, fileSize, fb); MemoryFree(buffer); fclose(fa); fclose(fb); return 1; }
PILINE AllocateILData (HWND hWndIL) { PILINE pILine ; pILine = MemoryAllocate (sizeof (ILINE)) ; SetWindowLong (hWndIL, 0, (LONG) pILine) ; return (pILine) ; }
BOOL SystemSetupThread (PPERFSYSTEM pSystem) { DWORD dwThreadID ; HANDLE hThread ; HANDLE hStateDataMutex ; HANDLE hPerfDataEvent ; SECURITY_ATTRIBUTES SecAttr ; PPERFDATA pSystemPerfData ; SecAttr.nLength = sizeof (SecAttr) ; SecAttr.bInheritHandle = TRUE ; SecAttr.lpSecurityDescriptor = NULL ; hThread = CreateThread (&SecAttr, 1024L, (LPTHREAD_START_ROUTINE)PerfDataThread, (LPVOID)(pSystem), 0L, &dwThreadID); if (!hThread) { SystemFree (pSystem, TRUE); return (FALSE) ; } // create a State Data Lock mutex hStateDataMutex = CreateMutex (&SecAttr, FALSE, NULL); if (!hStateDataMutex) { CloseHandle (hThread) ; SystemFree (pSystem, TRUE); return (FALSE); } hPerfDataEvent = CreateEvent (&SecAttr, TRUE, 0L, NULL) ; if (!hPerfDataEvent) { CloseHandle (hStateDataMutex) ; CloseHandle (hThread) ; SystemFree (pSystem, TRUE); return (FALSE); } // allocate Perfdata pSystemPerfData = (PPERFDATA) MemoryAllocate (4096L) ; if (!pSystemPerfData) { CloseHandle (hPerfDataEvent) ; CloseHandle (hStateDataMutex) ; CloseHandle (hThread) ; SystemFree (pSystem, TRUE); return (FALSE); } // now setup the pSystem.. pSystem->dwThreadID = dwThreadID ; pSystem->hThread = hThread ; pSystem->hPerfDataEvent = hPerfDataEvent ; pSystem->pSystemPerfData = pSystemPerfData ; pSystem->hStateDataMutex = hStateDataMutex ; return (TRUE) ; }
/* General function for allocating memory for array of any type */ static void *AllocateArray(int Dim, int ElementSize, ...) { void ***A; /* stores a pointer to the start of the allocated block for */ /* each dimension */ void *AA; /* contains the start of the allocated nD-array */ va_list ap; /* argument pointer in the variable length list */ int i; /* */ int j; /* */ int n; /* number of entries that are to allocated for a block */ int *Size; /* Size (in number of entries) for each dimension */ /* Retrieve sizes for the different dimensions from the variable arg. list. */ Size = MemoryAllocate(Dim, sizeof(*Size)); va_start(ap, ElementSize); for (i = 0; i < Dim; i++) { Size[i] = va_arg(ap, int); } va_end(ap); A = MemoryAllocate(Dim, sizeof(**A)); /* Allocate for each dimension a contiguous block of memory. */ for (n = 1, i = 0; i < Dim - 1; i++) { n *= Size[i]; A[i] = MemoryAllocate(n, sizeof(void*)); } n *= Size[i]; A[i] = MemoryAllocate(n, ElementSize); /* Set pointers for each dimension to the correct entries of its lower dim.*/ for (n = 1, i = 0; i < Dim - 1; i++) { n *= Size[i]; for (j = 0; j < n; j++) { /* A[i][j] = &A[i+1][j * Size[i+1]]; */ A[i][j] = &((char *)A[i+1])[j * Size[i+1] * ElementSize]; } } AA = A[0]; MemoryFree(A); MemoryFree(Size); return AA; }
char *Pxf::StringConcat(const char *str1, const char *str2) { int len_str1 = StringLength(str1); int len_str2 = StringLength(str2); int len = len_str1 + len_str2; char *ret = (char*)MemoryAllocate((len + 1)*sizeof(char)); StringCopy(ret, str1, len_str1); StringCopy(ret+len_str1, str2, len_str2); ret[len] = 0; return ret; }
PVOID MemoryReallocate(PVOID Buffer, int NumberOfBytes) { PVOID temp; if (LibraryMode == USER_MODE) { return realloc(Buffer, NumberOfBytes); } temp = MemoryAllocate(NumberOfBytes); memcpy(temp, Buffer, NumberOfBytes); MemoryFree(Buffer); return temp; }
task* CreateTask(void* EntryPoint, unsigned int AssignedStack) { taskElement* NewTask; task* TaskInfo; // Add task to tasklist NewTask=MemoryAllocate(sizeof(taskElement), memHEAP); NewTask->Next=SystemTasks; SystemTasks=NewTask; // Set up task TaskInfo=&(NewTask->Value); TaskInfo->StackFrameTop=MemoryAllocate(AssignedStack, memSTACK); TaskInfo->StackFrameBottom=(void*)((unsigned int)TaskInfo->StackFrameTop-AssignedStack); TaskInfo->SP=TaskInfo->StackFrameTop; TaskInfo->SP--; *(void**)(TaskInfo->SP)=EntryPoint; TaskInfo->SP--; *TaskInfo->SP=0; // AF TaskInfo->SP--; *TaskInfo->SP=0; // BC TaskInfo->SP--; *TaskInfo->SP=0; // DE TaskInfo->SP--; *TaskInfo->SP=0; // HL TaskInfo->SP--; *TaskInfo->SP=0; // IX TaskInfo->SP--; *TaskInfo->SP=0; // IY TaskInfo->RegisteredEvents=EVENT_RUNTASK; TaskInfo->EventId=0; return TaskInfo; }
/* Allocate memory for all dynamic variables of the decoder. */ static void AllocateDecMemory (ebunch * D) { D->FrameHdr.ICoefA = AllocateArray(2,sizeof(**D->FrameHdr.ICoefA),D->FrameHdr.MaxNrOfFilters, (1<<SIZE_CODEDPREDORDER)); D->StrFilter.Coded = MemoryAllocate(D->FrameHdr.MaxNrOfFilters, sizeof(*D->StrFilter.Coded)); D->StrFilter.BestMethod = MemoryAllocate(D->FrameHdr.MaxNrOfFilters, sizeof(*D->StrFilter.BestMethod)); D->StrFilter.m = AllocateArray(2, sizeof(**D->StrFilter.m), D->FrameHdr.MaxNrOfFilters, NROFFRICEMETHODS); D->StrFilter.Data = AllocateArray(2, sizeof(**D->StrFilter.Data), D->FrameHdr.MaxNrOfFilters, (1<<SIZE_CODEDPREDORDER) * SIZE_PREDCOEF); D->StrFilter.DataLen = MemoryAllocate(D->FrameHdr.MaxNrOfFilters, sizeof(*D->StrFilter.DataLen)); D->StrFilter.CPredOrder = MemoryAllocate(NROFFRICEMETHODS, sizeof(*D->StrFilter.CPredOrder)); D->StrFilter.CPredCoef = AllocateArray(2, sizeof(**D->StrFilter.CPredCoef), NROFFRICEMETHODS, MAXCPREDORDER); D->StrPtable.Coded = MemoryAllocate(D->FrameHdr.MaxNrOfPtables, sizeof(*D->StrPtable.Coded)); D->StrPtable.BestMethod = MemoryAllocate(D->FrameHdr.MaxNrOfPtables, sizeof(*D->StrPtable.BestMethod)); D->StrPtable.m = AllocateArray(2, sizeof(**D->StrPtable.m), D->FrameHdr.MaxNrOfPtables, NROFPRICEMETHODS); D->StrPtable.Data = AllocateArray(2, sizeof(**D->StrPtable.Data), D->FrameHdr.MaxNrOfPtables, AC_BITS * AC_HISMAX); D->StrPtable.DataLen = MemoryAllocate(D->FrameHdr.MaxNrOfPtables, sizeof(*D->StrPtable.DataLen)); D->StrPtable.CPredOrder = MemoryAllocate(NROFPRICEMETHODS, sizeof(*D->StrPtable.CPredOrder)); D->StrPtable.CPredCoef = AllocateArray(2, sizeof(**D->StrPtable.CPredCoef), NROFPRICEMETHODS, MAXCPREDORDER); D->P_one = AllocateArray(2, sizeof(**D->P_one), D->FrameHdr.MaxNrOfPtables, AC_HISMAX); D->AData = MemoryAllocate(D->FrameHdr.BitStreamLen, sizeof(*D->AData)); }
char *Pxf::StringSub(const char *str, int start, int length) { int str_length = StringLength(str); char *ret; if (length == -1) length = str_length - start; if (length < 0) length = str_length - start + length; if (start < 0) start = str_length + start; if (start > str_length || length < 0 || length-start > length) return 0; ret = (char*)MemoryAllocate((length+1)*sizeof(char)); StringCopy(ret, str+start, length); ret[length] = 0; return ret; }
void InitalizeEngine() { BeginProfileEntry("Initalize Engine"); Engine *engine = &g_engine; #ifdef VENOM_SINGLE_THREADED size_t workerCount = 1; #else VENOM_SINGLE_THREADED size_t workerCount = std::thread::hardware_concurrency(); #endif//VENOM_SINGLE_THREADED size_t requiredMemory = Align8(workerCount * sizeof(Worker)); requiredMemory += Align8(WORKER_STACK_MEMORY_SIZE * workerCount); U8 *memory = (U8 *)MemoryAllocate(requiredMemory); memset(memory, 0x00, requiredMemory); engine->workers = (Worker *)memory; engine->workerCount = workerCount; engine->isRunning = true; U8 *currentStackMemoryPtr = memory + Align8(workerCount * sizeof(Worker)); g_threadID = 0; //Set the main thread's id to 0 for (size_t i = 0; i < workerCount; i++) { Worker *worker = &engine->workers[i]; worker->workerID = i; worker->stackMemory.memory = currentStackMemoryPtr; worker->stackMemory.size = WORKER_STACK_MEMORY_SIZE; currentStackMemoryPtr += WORKER_STACK_MEMORY_SIZE; } for (size_t i = 1; i < workerCount; i++) { Worker *worker = &engine->workers[i]; worker->thread = std::thread(WorkerThreadProc, worker); } { //Initalize physics simulation paramaters PhysicsSimulation *sim = &engine->physicsSimulation; sim->gravityAcceleration = V3(0.0f, -9.81f, 0.0f); } InitalizeTerrain(&engine->terrain, 5, 8, 32); #ifndef VENOM_RELEASE OpenGLEnableDebug(&engine->debugLog); #endif//VENOM_RELEASE EndProfileEntry(); }
Void CFreeList<DataType>::SetCapacity( const UInt32 count ) { Free(); if( count ) { m_Array = (SEntry*) MemoryAllocate( *m_MemoryHeap, sizeof(SEntry) * count); for(UInt32 i=0;i<count;i++) { m_Array[i].Free = TRUE; } } else { m_Array = NULL; } m_Capacity = count; m_NextFree = 0; }
PLEGEND AllocateLegendData (HWND hWnd, BOOL bChartLegend) { PLEGEND pLegend ; pLegend = MemoryAllocate (sizeof (LEGEND)) ; // SetWindowLong (hWnd, 0, (LONG) pLegend) ; if (bChartLegend) { hWndGraphLegend = hWnd ; pGraphLegendData = pLegend ; } else { hWndAlertLegend = hWnd ; pAlertLegendData = pLegend ; } return (pLegend) ; }
char *Pxf::DuplicateReplaceString(const char *str, const char *find, const char *replace) { int len_find = StringLength(find); int len_replace = StringLength(replace); int count = 0, newlen = 0; /*char *src = (char*)str; */ char *ret, *q; const char *p = str; p = StringFind(str, find); if (!p) return strdup(str); /* count occurrences of find */ do { count++; } while ((p = StringFind(p+len_find, find))); newlen = (StringLength(str) + count * (len_replace - len_find) + 1) * sizeof(char); ret = (char*)MemoryAllocate( newlen ); if (!ret) return 0; p = (char*)str; q = ret; while(1) { const char *tmp = StringFind(p, find); if (!tmp) { StringCopy(q, p, StringLength(str)-(unsigned)(p-str)+1); ret[newlen-1] = 0; return ret; } MemoryCopy(q, p, (unsigned)(tmp-p)); q += tmp-p; MemoryCopy(q, replace, len_replace); q += len_replace; p = tmp+len_find; } return 0; }
PPERFSYSTEM GetComputer ( HDLG hDlg, WORD wControlID, BOOL bWarn, PPERFDATA *ppPerfData, PPERFSYSTEM *ppSystemFirst ) /* Effect: Attempt to set the current computer to the one in the hWndComputers dialog edit box. If this computer system can be found, load the objects, etc. for the computer and set pSystem and ppPerfdata to the values for this system. */ { // GetComputer TCHAR szComputer [MAX_SYSTEM_NAME_LENGTH + 1] ; PPERFSYSTEM pSystem; TCHAR tempBuffer [LongTextLen] ; DWORD dwBufferSize = 0; LPTSTR pBuffer = NULL ; DWORD dwLastError; DialogText (hDlg, wControlID, szComputer) ; // If necessary, add the system to the lists for this view. pSystem = SystemGet (*ppSystemFirst, szComputer) ; if (!pSystem) { pSystem = SystemAdd (ppSystemFirst, szComputer, hDlg) ; } if (!pSystem && bWarn) { dwLastError = GetLastError(); EditSetModified (GetDlgItem(hDlg, wControlID), FALSE) ; // unable to get specified computer so set to: // the first computer in the system list if present // -- or -- // set he local machine if not. pSystem = *ppSystemFirst; // set to first in list if (pSystem == NULL) { // this would mean the user can't access the local // system since normally that would be the first one // so the machine name will be restored to the // local machine (for lack of a better one) but the // system won't be added unless they want to explicitly DialogSetString (hDlg, wControlID, LocalComputerName) ; } else { // set to name in system structure DialogSetString (hDlg, wControlID, pSystem->sysName); } if (dwLastError != ERROR_ACCESS_DENIED) { DlgErrorBox (hDlg, ERR_COMPUTERNOTFOUND) ; } else { // the appropriate error message has already been displayed } SetFocus (DialogControl(hDlg, wControlID)) ; } if (pSystem) { if (PlayingBackLog ()) { *ppPerfData = LogDataFromPosition (pSystem, &(PlaybackLog.StartIndexPos)) ; } else { if (pSystem->lpszValue) { // save the previous lpszValue string before // SetSystemValueNameToGlobal screw it up dwBufferSize = MemorySize (pSystem->lpszValue) ; if (dwBufferSize <= sizeof(tempBuffer)) { pBuffer = tempBuffer ; } else { pBuffer = MemoryAllocate (dwBufferSize) ; } memcpy (pBuffer, pSystem->lpszValue, dwBufferSize) ; } SetSystemValueNameToGlobal (pSystem); UpdateSystemData (pSystem, ppPerfData) ; if (pSystem->lpszValue) { // retore the previous lpszValue string memcpy (pSystem->lpszValue, pBuffer, dwBufferSize) ; if (pBuffer != tempBuffer) { MemoryFree (pBuffer) ; } } } } return (pSystem) ; } // GetComputer
PPERFSYSTEM SystemCreate ( LPCTSTR lpszSystemName ) { PPERFSYSTEM pSystem ; PPERFDATA pLocalPerfData = NULL; DWORD Status ; DWORD dwMemSize; TCHAR GlobalValueBuffer[] = L"Global" ; TCHAR ForeignValueBuffer[8+MAX_SYSTEM_NAME_LENGTH+1] = L"Foreign " ; // attempt to allocate system data structure pSystem = MemoryAllocate (sizeof (PERFSYSTEM)) ; if (!pSystem) { SetLastError (ERROR_OUTOFMEMORY) ; return (NULL) ; } // initialize name and help table pointers pSystem->CounterInfo.pNextTable = NULL; pSystem->CounterInfo.dwLangId = 0; pSystem->CounterInfo.dwLastId = 0; pSystem->CounterInfo.TextString = NULL; lstrcpy (pSystem->sysName, lpszSystemName) ; // try to open key to registry, error code is in GetLastError() pSystem->sysDataKey = OpenSystemPerfData(lpszSystemName); // if a Null Key was returned then: // a) there's no such computer // b) the system is a foreign computer // // before giving up, then see if it's a foreign computer if (!pSystem->sysDataKey) { // build foreign computer string lstrcat(ForeignValueBuffer, lpszSystemName) ; // assign System value name pointer to the local variable for trial pSystem->lpszValue = ForeignValueBuffer; // try to get data from the computer to see if it's for real // otherwise, give up and return NULL pLocalPerfData = MemoryAllocate (STARTING_SYSINFO_SIZE); if (pLocalPerfData == NULL) { // no mem so give up pSystem->lpszValue = NULL; SystemFree (pSystem, TRUE); SetLastError (ERROR_OUTOFMEMORY); return (NULL); } else { pSystem->sysDataKey = HKEY_PERFORMANCE_DATA; // local machine bCloseLocalMachine = TRUE ; dwMemSize = STARTING_SYSINFO_SIZE; Status = GetSystemPerfData ( pSystem->sysDataKey, pSystem->lpszValue, pLocalPerfData, &dwMemSize); // success means a valid buffer came back // more data means someone tried (so it's probably good (?) if ((Status == ERROR_MORE_DATA) || (Status == ERROR_SUCCESS)) { if (Status == ERROR_SUCCESS) { // see if a perf buffer was returned if ((dwMemSize > 0) && pLocalPerfData->Signature[0] == (WCHAR)'P' && pLocalPerfData->Signature[1] == (WCHAR)'E' && pLocalPerfData->Signature[2] == (WCHAR)'R' && pLocalPerfData->Signature[3] == (WCHAR)'F' ) { // valid buffer so continue } else { // invalid so unable to connect to that machine pSystem->lpszValue = NULL; SystemFree (pSystem, TRUE); SetLastError (ERROR_BAD_NET_NAME); // unable to find name return (NULL); } } else { // assume that if MORE_DATA is returned that SOME // data was attempted so the buffer must be valid // (we hope) } MemoryFree ((LPMEMORY)pLocalPerfData) ; pLocalPerfData = NULL; // if we are reading from a setting file, let this pass thru' if (bDelayAddAction == TRUE) { pSystem->sysDataKey = NULL ; pSystem->FailureTime = GetTickCount(); pSystem->dwSystemState = SYSTEM_DOWN; // Free any memory that may have created SystemFree (pSystem, FALSE) ; pSystem->lpszValue = MemoryAllocate (TEMP_BUF_LEN*sizeof(WCHAR)); if (!pSystem->lpszValue) { // unable to allocate memory SystemFree (pSystem, TRUE); SetLastError (ERROR_OUTOFMEMORY); return (NULL) ; } else { lstrcpy (pSystem->lpszValue, GlobalValueBuffer); } // Setup the thread's stuff if (SystemSetupThread (pSystem)) return (pSystem) ; else return NULL; } } else { // some other error was returned so pack up and leave pSystem->lpszValue = NULL; SystemFree (pSystem, TRUE); SetLastError (ERROR_BAD_NET_NAME); // unable to find name return (NULL); } if (pLocalPerfData != NULL) { MemoryFree ((LPMEMORY)pLocalPerfData); // don't really need anything from it } // ok, so we've established that a foreign data provider // exists, now to finish the initialization. // change system name in structure to get counter names lstrcpy (pSystem->sysName, LocalComputerName); Status = GetSystemNames(pSystem); // get counter names & explain text if (Status != ERROR_SUCCESS) { // unable to get names so bail out pSystem->lpszValue = NULL; SystemFree (pSystem, TRUE); SetLastError (Status); return (NULL) ; } // restore computer name for displays, etc. lstrcpy (pSystem->sysName, lpszSystemName); // allocate value string buffer pSystem->lpszValue = MemoryAllocate (TEMP_BUF_LEN*sizeof(WCHAR)); if (!pSystem->lpszValue) { // unable to allocate memory SystemFree (pSystem, TRUE); SetLastError (ERROR_OUTOFMEMORY); return (NULL) ; } else { lstrcpy (pSystem->lpszValue, ForeignValueBuffer); } } } else { // if here, then a connection to the system's registry was established // so continue with the system data structure initialization // get counter names & explain text from local computer Status = GetSystemNames(pSystem); if (Status != ERROR_SUCCESS) { // unable to get names so bail out SystemFree (pSystem, TRUE); SetLastError (Status); return (NULL) ; } // allocate value string buffer pSystem->lpszValue = MemoryAllocate(TEMP_BUF_LEN*sizeof(WCHAR)); if (!pSystem->lpszValue) { // unable to allocate memory SystemFree (pSystem, TRUE); SetLastError (ERROR_OUTOFMEMORY); return (NULL) ; } else { SetSystemValueNameToGlobal (pSystem); } } // initialize remaining system pointers pSystem->pSystemNext = NULL ; pSystem->FailureTime = 0; // setup data for thread data collection if (!PlayingBackLog()) { // create a thread for data collection if (!SystemSetupThread (pSystem)) return (NULL) ; } SetLastError (ERROR_SUCCESS); return (pSystem) ; } // SystemCreate
void* malloc(unsigned Size) { return MemoryAllocate(Size); }
Result KeyboardAttach(struct UsbDevice *device, u32 interface __attribute__((unused))) { u32 keyboardNumber; struct HidDevice *hidData; struct KeyboardDevice *data; struct HidParserResult *parse; if ((KeyboardMaxKeyboards & 3) != 0) { LOG("KBD: Warning! KeyboardMaxKeyboards not a multiple of 4. The driver wasn't built for this!\n"); } if (keyboardCount == KeyboardMaxKeyboards) { LOGF("KBD: %s not connected. Too many keyboards connected (%d/%d). Change KeyboardMaxKeyboards in device.keyboard.c to allow more.\n", UsbGetDescription(device), keyboardCount, KeyboardMaxKeyboards); return ErrorIncompatible; } hidData = (struct HidDevice*)device->DriverData; if (hidData->Header.DeviceDriver != DeviceDriverHid) { LOGF("KBD: %s isn't a HID device. The keyboard driver is built upon the HID driver.\n", UsbGetDescription(device)); return ErrorIncompatible; } parse = hidData->ParserResult; if ((parse->Application.Page != GenericDesktopControl && parse->Application.Page != Undefined) || parse->Application.Desktop != DesktopKeyboard) { LOGF("KBD: %s doesn't seem to be a keyboard (%x != %x || %x != %x)...\n", UsbGetDescription(device), parse->Application.Page, GenericDesktopControl, parse->Application.Desktop, DesktopKeyboard); return ErrorIncompatible; } if (parse->ReportCount < 1) { LOGF("KBD: %s doesn't have enough outputs to be a keyboard.\n", UsbGetDescription(device)); return ErrorIncompatible; } hidData->HidDetached = KeyboardDetached; hidData->HidDeallocate = KeyboardDeallocate; if ((hidData->DriverData = MemoryAllocate(sizeof(struct KeyboardDevice))) == NULL) { LOGF("KBD: Not enough memory to allocate keyboard %s.\n", UsbGetDescription(device)); return ErrorMemory; } data = (struct KeyboardDevice*)hidData->DriverData; data->Header.DeviceDriver = DeviceDriverKeyboard; data->Header.DataSize = sizeof(struct KeyboardDevice); data->Index = keyboardNumber = 0xffffffff; for (u32 i = 0; i < KeyboardMaxKeyboards; i++) { if (keyboardAddresses[i] == 0) { data->Index = keyboardNumber = i; keyboardAddresses[i] = device->Number; keyboardCount++; break; } } if (keyboardNumber == 0xffffffff) { LOG("KBD: PANIC! Driver in inconsistent state! KeyboardCount is inaccurate.\n"); KeyboardDeallocate(device); return ErrorGeneral; } keyboards[keyboardNumber] = device; for (u32 i = 0; i < KeyboardMaxKeys; i++) data->Keys[i] = 0; *(u8*)&data->Modifiers = 0; *(u8*)&data->LedSupport = 0; for (u32 i = 0; i < 9; i++) data->KeyFields[i] = NULL; for (u32 i = 0; i < 8; i++) data->LedFields[i] = NULL; data->LedReport = NULL; data->KeyReport = NULL; for (u32 i = 0; i < parse->ReportCount; i++) { LOG_DEBUGF("KBD: type %x report %d. %d fields.\n", parse->Report[i]->Type, i, parse->Report[i]->FieldCount); if (parse->Report[i]->Type == Input && data->KeyReport == NULL) { LOG_DEBUGF("KBD: Output report %d. %d fields.\n", i, parse->Report[i]->FieldCount); data->KeyReport = parse->Report[i]; for (u32 j = 0; j < parse->Report[i]->FieldCount; j++) { if (parse->Report[i]->Fields[j].Usage.Page == KeyboardControl || parse->Report[i]->Fields[j].Usage.Page == Undefined) { if (parse->Report[i]->Fields[j].Attributes.Variable) { if (parse->Report[i]->Fields[j].Usage.Keyboard >= KeyboardLeftControl && parse->Report[i]->Fields[j].Usage.Keyboard <= KeyboardRightGui) LOG_DEBUGF("KBD: Modifier %d detected! Offset=%x, size=%x\n", parse->Report[i]->Fields[j].Usage.Keyboard, parse->Report[i]->Fields[j].Offset, parse->Report[i]->Fields[j].Size); data->KeyFields[(u16)parse->Report[i]->Fields[j].Usage.Keyboard - (u16)KeyboardLeftControl] = &parse->Report[i]->Fields[j]; } else { LOG_DEBUG("KBD: Key input detected!\n"); data->KeyFields[8] = &parse->Report[i]->Fields[j]; } } } } else if (parse->Report[i]->Type == Output && data->LedReport == NULL) { data->LedReport = parse->Report[i]; LOG_DEBUGF("KBD: Input report %d. %d fields.\n", i, parse->Report[i]->FieldCount); for (u32 j = 0; j < parse->Report[i]->FieldCount; j++) { if (parse->Report[i]->Fields[j].Usage.Page == Led) { switch (parse->Report[i]->Fields[j].Usage.Led) { case LedNumberLock: LOG_DEBUG("KBD: Number lock LED detected!\n"); data->LedFields[0] = &parse->Report[i]->Fields[j]; data->LedSupport.NumberLock = true; break; case LedCapsLock: LOG_DEBUG("KBD: Caps lock LED detected!\n"); data->LedFields[1] = &parse->Report[i]->Fields[j]; data->LedSupport.CapsLock = true; break; case LedScrollLock: LOG_DEBUG("KBD: Scroll lock LED detected!\n"); data->LedFields[2] = &parse->Report[i]->Fields[j]; data->LedSupport.ScrollLock = true; break; case LedCompose: LOG_DEBUG("KBD: Compose LED detected!\n"); data->LedFields[3] = &parse->Report[i]->Fields[j]; data->LedSupport.Compose = true; break; case LedKana: LOG_DEBUG("KBD: Kana LED detected!\n"); data->LedFields[4] = &parse->Report[i]->Fields[j]; data->LedSupport.Kana = true; break; case LedPower: LOG_DEBUG("KBD: Power LED detected!\n"); data->LedFields[5] = &parse->Report[i]->Fields[j]; data->LedSupport.Power = true; break; case LedShift: LOG_DEBUG("KBD: Shift LED detected!\n"); data->LedFields[6] = &parse->Report[i]->Fields[j]; data->LedSupport.Shift = true; break; case LedMute: LOG_DEBUG("KBD: Mute LED detected!\n"); data->LedFields[7] = &parse->Report[i]->Fields[j]; data->LedSupport.Mute = true; break; default: break; } } } } } LOG_DEBUGF("KBD: New keyboard assigned %d!\n", device->Number); return OK; }