Skip to content

Commit

Permalink
PR nir9#8 Keyboard Update
Browse files Browse the repository at this point in the history
  • Loading branch information
DemiRom committed Feb 5, 2024
2 parents 5a3ac67 + 8e7fd66 commit 36f80fa
Show file tree
Hide file tree
Showing 17 changed files with 797 additions and 53 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@
*.obj
*.exp
*.exe
*.pdb
*.ilk

tags

.idea/
.vs/
debug/
release/
*.res
60 changes: 49 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
# Define compiler and linker
CC = cl
LD = link
LINKER = link
RC = rc

EXEC = lightwm.exe
DLL = lightwm_dll.dll
# Define common compiler flags
CFLAGS = /W3 /EHsc

all: clean $(DLL) $(EXEC)
# Define debug specific compiler flags
DBGCFLAGS = $(CFLAGS) /DDEBUG /Zi /Wall

$(EXEC): wm.c
$(CC) wm.c tiling.c error.c user32.lib /link /out:$(EXEC)
# Define release specific compiler flags
RELCFLAGS = $(CFLAGS) /Ox

$(DLL): wm_dll.obj
$(LD) wm_dll.obj user32.lib /dll /out:$(DLL)
# Define source files
EXE_SRCS = wm.c tiling.c error.c config.c keyboard.c
DLL_SRCS = wm_dll.c error.c
RES_FILE = wm_resources.rc

wm_dll.obj: wm_dll.c
$(CC) /c wm_dll.c
# Define directories
DBGDIR = debug
RELDIR = release

# Define output names
EXE_NAME = lightwm.exe
DLL_NAME = lightwm_dll.dll

all: debug release

debug: clean prep resource wm.c
$(CC) $(DBGCFLAGS) $(EXE_SRCS) $(RES_FILE).res /link user32.lib shell32.lib ole32.lib shlwapi.lib /out:$(DBGDIR)/$(EXE_NAME)
$(CC) $(DBGCFLAGS) $(DLL_SRCS) /LD /link user32.lib /DEF:wm_dll.def /out:$(DBGDIR)/$(DLL_NAME)

release: clean prep resource wm.c
$(CC) $(RELCFLAGS) $(EXE_SRCS) $(RES_FILE).res /link user32.lib shell32.lib ole32.lib shlwapi.lib /out:$(RELDIR)/$(EXE_NAME)
$(CC) $(RELCFLAGS) $(DLL_SRCS) /LD /link user32.lib /DEF:wm_dll.def /out:$(RELDIR)/$(DLL_NAME)

resource: $(RES_FILE)
$(RC) /fo $(RES_FILE).res $(RES_FILE)

prep:
@echo off > temp.bat && \
echo IF NOT EXIST $(DBGDIR) mkdir $(DBGDIR) >> temp.bat && \
echo IF NOT EXIST $(RELDIR) mkdir $(RELDIR) >> temp.bat && \
temp.bat && \
del temp.bat

clean:
del *.obj *.exe *.dll *.lib *.exp
del *.obj *.exe *.dll *.lib *.exp *.ilk *.pdb *.res

@echo off > temp.bat && \
echo IF EXIST $(DBGDIR) del /S /Q $(DBGDIR) >> temp.bat && \
echo IF EXIST $(RELDIR) del /S /Q $(RELDIR) >> temp.bat && \
echo IF EXIST $(DBGDIR) rd /S /Q $(DBGDIR) >> temp.bat && \
echo IF EXIST $(RELDIR) rd /S /Q $(RELDIR) >> temp.bat && \
temp.bat && \
del temp.bat
26 changes: 26 additions & 0 deletions actions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

//Just add the action to this preprocessor macro to generate the ENUM and string array
#define FOREACH_ACTION(ACTION) \
ACTION(ACTION_NONE) \
ACTION(WORKSPACE_1) \
ACTION(WORKSPACE_2) \
ACTION(WORKSPACE_3) \
ACTION(WORKSPACE_4) \
ACTION(WINDOW_LEFT) \
ACTION(WINDOW_RIGHT) \
ACTION(WINDOW_UP) \
ACTION(WINDOW_DOWN)


#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRINGS(STRING) #STRING,

typedef enum
{
FOREACH_ACTION(GENERATE_ENUM)
} Actions;

static const char* ACTION_STRINGS[] = {
FOREACH_ACTION(GENERATE_STRINGS)
};
258 changes: 258 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
#include "config.h"

#include <Windows.h>
#include <Shlobj.h>
#include <wchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <shlwapi.h>
#include <assert.h>

#include "error.h"
#include "resource.h"
#include "string_helpers.h"
#include "debug.h"

#define BUFF_SIZE 65536

PWSTR szConfigFilePath;

char *defaultConfigData = NULL;

ConfigItems *configItems;

BOOL createDefaultConfigFile(HINSTANCE);

BOOL loadDefaultConfigResourceData(HINSTANCE);

BOOL writeDefaultConfigDataToFile();

size_t getLineCount(FILE *file);

void freeConfigItems(ConfigItems *items);

DWORD readConfigFile() {
assert(szConfigFilePath != NULL);

//Try to open the config file based on the path
FILE *configFileHandle = _wfopen(szConfigFilePath, L"r");

if (configFileHandle == NULL) {
reportWin32Error(L"Config file could not be opened");
cleanupConfigReader();
return ERROR_INVALID_HANDLE;
}

char line[BUFF_SIZE];

configItems = (ConfigItems *) malloc(sizeof(ConfigItems));

configItems->configItem = (ConfigItem *) malloc(sizeof(ConfigItem) * getLineCount(configFileHandle) + 1);
configItems->configItemsCount = getLineCount(configFileHandle);

if (configItems->configItem == NULL) {
reportWin32Error(L"Allocation ConfigItem memory");
cleanupConfigReader();
return ERROR_NOT_ENOUGH_MEMORY;
}

for (size_t lineCount = 0; fgets(line, sizeof(line), configFileHandle); lineCount++) {
if (strlen(line) == 0) {
continue;
}

//Get the first half of the line
char *token = strtok(line, " ");
configItems->configItem[lineCount].name = (char *) malloc(strlen(token) + 1);
strncpy(configItems->configItem[lineCount].name, token, strlen(token) + 1);

//Get the second half of the line
token = strtok(NULL, " ");
removeControlChars(token);
configItems->configItem[lineCount].value = (char *) malloc(strlen(token) + 1);
strncpy(configItems->configItem[lineCount].value, token, strlen(token) + 1);

DEBUG_PRINT("Name: %s Value: %s Name LEN: %zu Value LEN: %zu Count: %zu",
configItems->configItem[lineCount].name,
configItems->configItem[lineCount].value,
strlen(configItems->configItem[lineCount].name),
strlen(configItems->configItem[lineCount].value),
lineCount);
}


fclose(configFileHandle);

return ERROR_SUCCESS;
}

void getConfigFilePath() {
//TODO: We don't check other results possible results, i.e E_FAIL
const HRESULT getAppDataPathResult = SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &szConfigFilePath);

if (!SUCCEEDED(getAppDataPathResult)) {
switch (getAppDataPathResult) {
case E_FAIL:
SetLastError(ERROR_DIRECTORY_NOT_SUPPORTED);
break;
case E_INVALIDARG:
SetLastError(ERROR_TIERING_INVALID_FILE_ID);
break;
default:
SetLastError(ERROR_GEN_FAILURE);
}
reportWin32Error(L"Could not get the users appdata directory");
cleanupConfigReader();
exit(ERROR_PATH_NOT_FOUND);
}

assert(szConfigFilePath != NULL);

//TODO just found a bug that causes the path to become corrupt
const HRESULT concatStringResult = StringCchCatW(szConfigFilePath, MAX_PATH, L"\\lightwm.config\0");

if (!SUCCEEDED(concatStringResult)) {
switch (concatStringResult) {
case STRSAFE_E_INVALID_PARAMETER:
SetLastError(ERROR_INVALID_PARAMETER);
break;
case STRSAFE_E_INSUFFICIENT_BUFFER:
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
default:
SetLastError(ERROR_GEN_FAILURE);
}
reportWin32Error(L"Could not append file name to appdata path");
cleanupConfigReader();
exit(GetLastError());
}
}

BOOL loadConfigFile(HINSTANCE resourceModuleHandle) {
szConfigFilePath = (PWSTR) malloc(sizeof(WCHAR) * MAX_PATH);
getConfigFilePath();
assert(szConfigFilePath != NULL);

if (!PathFileExistsW(szConfigFilePath)) {
if (!createDefaultConfigFile(resourceModuleHandle)) {
reportWin32Error(L"Create a default config file");
return FALSE;
}
}

readConfigFile();

return TRUE;
}

void freeConfigItems(ConfigItems *items) {
if (items != NULL) {
for(size_t i = 0; i < items->configItemsCount; i++) {
free(items->configItem[i].name);
free(items->configItem[i].value);
}
free(items);
} else {
DEBUG_PRINT("items ptr was freed earlier!");
}
}

void cleanupConfigReader() {
freeConfigItems(configItems);
DEBUG_PRINT("Cleaned up config items");

CoTaskMemFree(szConfigFilePath);
DEBUG_PRINT("Cleaned up filePath ptr");
}

ConfigItems *getConfigItems() {
return configItems;
}

/**
* Private definitions here
**/
BOOL createDefaultConfigFile(HINSTANCE resourceModuleHandle) {
if (!loadDefaultConfigResourceData(resourceModuleHandle)) {
return FALSE;
}

if (!writeDefaultConfigDataToFile()) {
return FALSE;
}

return TRUE;
}

BOOL loadDefaultConfigResourceData(HINSTANCE resourceModuleHandle) {
const HRSRC hRes = FindResource(resourceModuleHandle, MAKEINTRESOURCE(IDR_DEFAULT_CONFIG), RT_RCDATA);

if (hRes == NULL) {
puts("Could not get HRSRC Handle");
DEBUG_PRINT("FindResource Error: %lu", GetLastError());
return FALSE;
}

const HGLOBAL hData = LoadResource(resourceModuleHandle, hRes);

if (hData == NULL) {
puts("Could not load resource");
DEBUG_PRINT("LoadResource Error: %lu", GetLastError());
return FALSE;
}

const LPVOID defaultConfigResourceData = LockResource(hData);

if (defaultConfigResourceData == NULL) {
puts("Could not read resource");
DEBUG_PRINT("LockResource Error: %lu", GetLastError());
return FALSE;
}

size_t defaultConfigResourceDataLen = strlen(defaultConfigResourceData) + 1; //+1 for the null char
defaultConfigData = (char *) malloc(sizeof(char) * defaultConfigResourceDataLen); //TODO Error checking
strcpy(defaultConfigData, defaultConfigResourceData);

return TRUE;
}

BOOL writeDefaultConfigDataToFile() {
FILE *configFileHandle = _wfopen(szConfigFilePath, L"w");

if (configFileHandle == NULL) {
return FALSE;
}

fprintf(configFileHandle, defaultConfigData);

puts("Created default config file");

fclose(configFileHandle);

return TRUE;
}

size_t getLineCount(FILE *file) {
int counter = 0;
for (;;) {
char buf[BUFF_SIZE];
const size_t res = fread(buf, 1, BUFF_SIZE, file);
if (ferror(file)) {
return -1;
}

for (int i = 0; i < res; i++) {
if (buf[i] == '\n') {
counter++;
}
}

if (feof(file)) {
break;
}
}

fseek(file, 0, SEEK_SET);

return counter;
}
22 changes: 22 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include <Windows.h>
#include <stdint.h>

typedef struct _ConfigItem ConfigItem;
typedef struct _ConfigItems ConfigItems;

typedef struct _ConfigItem {
char *name;
char *value;
} ConfigItem;

typedef struct _ConfigItems {
ConfigItem *configItem;
size_t configItemsCount;
} ConfigItems;

BOOL loadConfigFile(HINSTANCE);

void cleanupConfigReader();

ConfigItems *getConfigItems();
Loading

0 comments on commit 36f80fa

Please sign in to comment.