diff --git a/CMakeLists.txt b/CMakeLists.txt index d9fd70d..e355699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB_RECURSE TESTS test/*.cpp) include_directories(src) include_directories(test) -add_library(library ${SOURCES} ${HEADERS}) +add_library(library ${SOURCES} ${HEADERS} src/FontType.cpp) file(COPY "${CMAKE_SOURCE_DIR}/src/" DESTINATION "${CMAKE_SOURCE_DIR}/include" diff --git a/src/Color.cpp b/src/Color.cpp index b4bdb15..7d796fb 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -5,3 +5,28 @@ Color::Color(unsigned char red, unsigned char green, unsigned char blue) : red(red), green(green), blue(blue){ } + +unsigned char Color::getRed() { + return red; +} + +unsigned char Color::getGreen() { + return green; +} + +unsigned char Color::getBlue() { + return blue; +} + +void Color::setRed(unsigned char value) { + red = value; +} + +void Color::setGreen(unsigned char value) { + green = value; +} + +void Color::setBlue(unsigned char value) { + blue = value; +} + diff --git a/src/Color.h b/src/Color.h index b01a9c6..1191da4 100644 --- a/src/Color.h +++ b/src/Color.h @@ -17,6 +17,14 @@ private: public: Color(unsigned char red, unsigned char green, unsigned char blue); + unsigned char getRed(); + unsigned char getGreen(); + unsigned char getBlue(); + + void setRed(unsigned char value); + void setGreen(unsigned char value); + void setBlue(unsigned char value); + }; const static Color black = Color(0, 0, 0); diff --git a/src/Font.cpp b/src/Font.cpp deleted file mode 100644 index fa42d3b..0000000 --- a/src/Font.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -#include -#include -#include "Font.h" - -Font::Font(std::string name, int height, int width) { - this->name = std::move(name); - this->height = height; - this->width = width; -} - -std::string Font::getName() { - return name; -} - -int Font::getHeight() { - return height; -} - -int Font::getWidth() { - return width; -} diff --git a/src/FontType.cpp b/src/FontType.cpp new file mode 100644 index 0000000..6ef7a54 --- /dev/null +++ b/src/FontType.cpp @@ -0,0 +1,20 @@ +#include "FontType.h" + + +FontType::FontType(std::string name, int height, int width) { + this->name = std::move(name); + this->height = height; + this->width = width; +} + +std::string FontType::getName() { + return name; +} + +int FontType::getHeight() { + return height; +} + +int FontType::getWidth() { + return width; +} diff --git a/src/Font.h b/src/FontType.h similarity index 59% rename from src/Font.h rename to src/FontType.h index 041c3c9..cf76bf4 100644 --- a/src/Font.h +++ b/src/FontType.h @@ -3,14 +3,16 @@ #ifndef LIBRARY_FONT_H #define LIBRARY_FONT_H -class Font { +#include + +class FontType { private: std::string name; int height; int width; public: - Font(std::string name, int height, int width); + FontType(std::string name, int height, int width); std::string getName(); int getHeight(); int getWidth(); @@ -18,6 +20,6 @@ public: }; -const static Font font_1 = Font("DummyFont", 10, 5); +const static FontType font_1 = FontType("DummyFont", 10, 5); #endif diff --git a/src/SharedMemoryAccess.cpp b/src/SharedMemoryAccess.cpp index 8a4f4d0..0fd13dd 100644 --- a/src/SharedMemoryAccess.cpp +++ b/src/SharedMemoryAccess.cpp @@ -24,7 +24,9 @@ int semId; struct sembuf semaphore; -int initSemaphore (void) { +std::vector localSharedMemory; + +int initSemaphore () { /* Testen, ob das Semaphor bereits existiert */ semId = semget (SEM_KEY, 0, IPC_PRIVATE); if (semId < 0) { @@ -44,11 +46,11 @@ int initSemaphore (void) { } int semaphoreOperation (int op) { - semaphore.sem_op = op; + semaphore.sem_op = (short)op; semaphore.sem_flg = SEM_UNDO; if( semop (semId, &semaphore, 1) == -1) { perror(" semop "); - exit (EXIT_FAILURE); + return -1; } return 1; } @@ -56,7 +58,7 @@ int semaphoreOperation (int op) { void writeSharedMemory(char *data, int size, int offset) { int shmId = shmget(impl.sharedMemoryKey, NULL, 0); // dont init just get the ID if already existing. if(shmId < 0 ) { - exit(EXIT_FAILURE); + return; /* we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason*/ } else { char *shm_pointer = (char *) shmat(shmId, NULL, 0); @@ -66,12 +68,34 @@ void writeSharedMemory(char *data, int size, int offset) { } } -const char* getSharedMemory() { +char* getSharedMemory() { + /* int shmId = shmget(impl.sharedMemoryKey, NULL, 0); if(shmId < 0) { - exit(EXIT_FAILURE); - /* we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason*/ + return nullptr; + // we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason } else { return (char *) shmat(shmId, NULL, 0); } -} \ No newline at end of file + */ + + //using a local buffer for shared memory testing + if(localSharedMemory.empty()){ + initSemaphore(); + localSharedMemory.resize(impl.sharedMemorySize * 1024); + } + + return &localSharedMemory[0]; +} + +int getSharedMemorySize() { + return impl.sharedMemorySize; +} + +void lockSharedMemory() { + semaphoreOperation(LOCK); +} + +void unlockSharedMemory() { + semaphoreOperation(UNLOCK); +} diff --git a/src/SharedMemoryAccess.h b/src/SharedMemoryAccess.h index cdb4c45..949307b 100644 --- a/src/SharedMemoryAccess.h +++ b/src/SharedMemoryAccess.h @@ -7,10 +7,10 @@ /** - * only to read the shared memory + * use lock and unlock when writing * @return pointer to the shared memory */ -const char *getSharedMemory(); +char *getSharedMemory(); /** * @@ -18,6 +18,10 @@ const char *getSharedMemory(); */ int getSharedMemorySize(); +void lockSharedMemory(); + +void unlockSharedMemory(); + /** * * @param data poiter to data diff --git a/src/internal.cpp b/src/internal.cpp index feba66a..4fb1a26 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -1,9 +1,10 @@ #include "internal.h" +#include "SharedMemoryAccess.h" +#include "vkvm.h" + #include #include -#include "SharedMemoryAccess.h" - Impl impl; void sendSignal(pid_t pid, int signalNumber) { @@ -15,7 +16,22 @@ void onSignal(int signalNumber, void(*callback)(int)) { } InterruptEntry *getInterrupTable(){ - return (InterruptEntry*)((char*)getSharedMemory() + sizeof(Registers) + 1024/*reserved*/); + return (InterruptEntry*)(getSharedMemory() + sizeof(Registers) + impl.reservedSize); +} + +Registers *getRegisters(){ + return (Registers*)getSharedMemory(); +} + +char *getTextArea(){ + return ((getSharedMemory() + sizeof(Registers) + impl.reservedSize) + + sizeof(InterruptEntry) * impl.interruptEntyCount); +} + +char *getPixelArea(){ + return (((getSharedMemory() + sizeof(Registers) + impl.reservedSize) + + sizeof(InterruptEntry) * impl.interruptEntyCount) + + getCharactersPerRow() * getCharactersPerColumn()); } bool callEvent(EventType type) { @@ -27,21 +43,30 @@ bool callEvent(EventType type) { } void setLayoutVersion(LayoutVersion newValue) { - + lockSharedMemory(); + getRegisters()->layout_version = newValue; + unlockSharedMemory(); } -void setCharactersPerLine(int newValue) { - +void setCharactersPerColumn(int newValue) { + lockSharedMemory(); + getRegisters()->characters_per_column = newValue; + unlockSharedMemory(); } void setCharactersPerRow(int newValue) { - + lockSharedMemory(); + getRegisters()->characters_per_row = newValue; + unlockSharedMemory(); } void setMousePosition(int x, int y) { - + lockSharedMemory(); + getRegisters()->mouse_pos_x = x; + getRegisters()->mouse_pos_y = y; + unlockSharedMemory(); } void buttonPressed(KeyCode keyCode) { - + //TODO } diff --git a/src/internal.h b/src/internal.h index a6f273a..098575a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -50,6 +50,7 @@ struct Impl { key_t sharedMemoryKey; int sharedMemorySize; int interruptEntyCount = 64; + int reservedSize = 1024; std::vector> eventTable; }; @@ -70,6 +71,10 @@ void onSignal(int signalNumber, void(*callback)(int)); InterruptEntry *getInterrupTable(); +Registers *getRegisters(); +char *getTextArea(); +char *getPixelArea(); + /** * set layout version. @@ -78,10 +83,10 @@ InterruptEntry *getInterrupTable(); void setLayoutVersion(LayoutVersion newValue); /** - * set characters per line for current font. - * @param newValue characters per line. + * set characters per column for current font. + * @param newValue characters per column. */ -void setCharactersPerLine(int newValue); +void setCharactersPerColumn(int newValue); /** * set characters per row for current font. diff --git a/src/vkvm.cpp b/src/vkvm.cpp index 72d999b..9ea06b3 100644 --- a/src/vkvm.cpp +++ b/src/vkvm.cpp @@ -1,29 +1,36 @@ #include "vkvm.h" #include "internal.h" +#include "SharedMemoryAccess.h" + #include #include void initialize(int pid) { impl.sharedMemoryPid = pid; impl.sharedMemoryKey = 12345; - impl.sharedMemorySize = 0; -} + impl.sharedMemorySize = 8000; -bool setPixel(int x, int y, Color color) { - return true; -} - -Color getPixel(int x, int y) { - return {255, 0, 0}; + //set default values + setCharactersPerRow(60); + setCharactersPerColumn(20); + setHeight(600); + setWidth(800); + setMousePosition(42,42); + setBackgroundColor(Color(200,50,20)); + setForegroundColor(Color(20,200,50)); + setMode(GraphicMode::TrueColor); + setRedrawInterval(20); + setTimerInterruptInterval(10); } bool registerEvent(EventType type, std::function handler) { int signum = SIGUSR1 + impl.eventTable.size(); - auto ivt = getInterrupTable(); + + lockSharedMemory(); + ivt[type].pid = getpid(); ivt[type].signum = signum; - impl.eventTable.push_back(handler); onSignal(signum, [](int sig){ @@ -34,101 +41,149 @@ bool registerEvent(EventType type, std::function handler) { } }); + unlockSharedMemory(); + return true; } -bool setText(std::string text) { +bool setPixel(int x, int y, Color color) { + char *ptr = getPixelArea() + (y * getWidth() + x) * 3; + ptr[0] = color.getRed(); + ptr[1] = color.getGreen(); + ptr[2] = color.getBlue(); return false; } +Color getPixel(int x, int y) { + //TODO: other than RGB colores + //only RGB colores for now + unsigned char *ptr = (unsigned char *)getPixelArea() + (y * getWidth() + x) * 3; + return Color(ptr[0], ptr[1], ptr[2]); +} + +bool setText(std::string text) { + lockSharedMemory(); + char *ptr = getTextArea(); + for(int i = 0; i < text.size();i++){ + if(i >= getCharactersPerColumn() * getCharactersPerRow()){ + break; + } + ptr[i] = text[i]; + } + if(text.size() < getCharactersPerColumn() * getCharactersPerRow()){ + ptr[text.size()] = '\0'; + } + unlockSharedMemory(); + return true; +} + std::string getText() { - return "Hallo Welt"; + return std::string (getTextArea()); } LayoutVersion getLayoutVersion() { - return V1; + return (LayoutVersion)getRegisters()->layout_version; } void reset() { - + //TODO } int getWidth() { - return 360; + return getRegisters()->width_pixels; } void setWidth(int newValue) { - + lockSharedMemory(); + getRegisters()->width_pixels = newValue; + unlockSharedMemory(); } int getHeight() { - return 360; + return getRegisters()->height_pixels; } void setHeight(int newValue) { - + lockSharedMemory(); + getRegisters()->height_pixels = newValue; + unlockSharedMemory(); } GraphicMode getMode() { - return TrueColor; + return getRegisters()->graphicMode; } void setMode(GraphicMode newValue) { - + lockSharedMemory(); + getRegisters()->graphicMode = newValue; + unlockSharedMemory(); } int getRedrawInterval() { - return 10; + return getRegisters()->autoRedrawInterval; } void setRedrawInterval(int newValue) { - + lockSharedMemory(); + getRegisters()->autoRedrawInterval = newValue; + unlockSharedMemory(); } int getTimerInterruptInterval() { - return 5; + return getRegisters()->timerInterruptInterval; } void setTimerInterruptInterval(int newValue) { - + lockSharedMemory(); + getRegisters()->timerInterruptInterval = newValue; + unlockSharedMemory(); } Color getBackgroundColor() { - return black; + return getRegisters()->background_color; } void setBackgroundColor(Color newValue) { - + lockSharedMemory(); + getRegisters()->background_color = newValue; + unlockSharedMemory(); } Color getForegroundColor() { - return white; + return getRegisters()->foreground_color; } void setForegroundColor(Color newValue) { - + lockSharedMemory(); + getRegisters()->foreground_color = newValue; + unlockSharedMemory(); } int getCharactersPerRow() { - return 5; + return getRegisters()->characters_per_row; } int getCharactersPerColumn() { - return 5; + return getRegisters()->characters_per_column; } -Font getFont() { +FontType getFont() { + //TODO return font_1; } -void setFont(Font newValue) { - +void setFont(FontType newValue) { + //TODO + lockSharedMemory(); + getRegisters()->textMode_font = 0; + unlockSharedMemory(); } std::pair getMousePosition() { - return {10, 50}; + return {getRegisters()->mouse_pos_x, getRegisters()->mouse_pos_y}; } KeyCode getLastPressedKey() { - return KeyCode(50); + //TODO + return KeyCode(0); } diff --git a/src/vkvm.h b/src/vkvm.h index a95731f..180a1d5 100644 --- a/src/vkvm.h +++ b/src/vkvm.h @@ -6,7 +6,7 @@ #include "Color.h" #include "EventType.h" #include "GraphicMode.h" -#include "Font.h" +#include "FontType.h" #include "KeyCode.h" #include "LayoutVersion.h" @@ -178,13 +178,13 @@ int getCharactersPerColumn(); * get currently used font in text mode. * @return currently used font. */ -Font getFont(); +FontType getFont(); /** * set text mode font. * @param newValue new text mode font. */ -void setFont(Font newValue); +void setFont(FontType newValue); /** * get current mouse position