library/src/vkvm.cpp

290 lines
9.0 KiB
C++

#include "SharedMemoryAccess.hpp"
#include "internal.hpp"
#include "vkvm.hpp"
#include <csignal>
#include <unistd.h>
namespace vkvm {
// NOLINT
auto initialize(int pid) -> void {
impl.sharedMemoryPid = pid;
impl.sharedMemoryKey = 12345;// NOLINT
impl.sharedMemorySize = 8000;// NOLINT
initSemaphore();
setDefaultValues();
}
auto setDefaultValues() -> void {
if(getSharedMemory() != nullptr) {
//set default values
setCharactersPerRow(60);// NOLINT
setCharactersPerColumn(20);// NOLINT
setHeight(600);// NOLINT
setWidth(800);// NOLINT
setMousePosition(42, 42);// NOLINT
setBackgroundColor(black);
setForegroundColor(white);
setMode(GraphicMode::RGB);
setRedrawInterval(20);// NOLINT
setTimerInterruptInterval(10);// NOLINT
}
}
auto registerEvent(EventType type, const std::function<void()> &handler) -> bool {
int signum = SIGUSR1 + impl.eventTable.size();
auto ivt = getInterrupTable();
lockSharedMemory();
for(int i = 0; i < impl.interruptEntrysPerEventType;i++){
auto &entry= ivt[type * impl.interruptEntrysPerEventType + i];
if (entry.pid == 0) {
entry.pid = getpid();
entry.signum = signum;
impl.eventTable.push_back(handler);
onSignal(signum, [](int sig){
if(sig >= SIGUSR1){
if((sig - SIGUSR1) < impl.eventTable.size()){
impl.eventTable[sig - SIGUSR1]();
}
}
});
unlockSharedMemory();
return true;
}
}
unlockSharedMemory();
return false;
}
auto setPixel(int x, int y, Color color) -> bool {
lockSharedMemory();
auto reg = getRegisters();
switch(reg->graphicMode) {
case Text: {
int pixelIndex = (y * getWidth() + x);
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / 8);
if(color == reg->foreground_color){
//set bit to 1
ptr[0] |= (1 << (pixelIndex % 8));
}
else{
//set bit to 0
ptr[0] &= ~(1 << (pixelIndex % 8));
}
break;
}
case TwoColors: {
int pixelIndex = (y * getWidth() + x);
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / 8);
if(color == reg->foreground_color){
//set bit to 1
ptr[0] |= (1 << (pixelIndex % 8));
}
else{
//set bit to 0
ptr[0] &= ~(1 << (pixelIndex % 8));
}
break;
}
case Gray_256: {
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 1;
int avg = color.getRed() + color.getGreen() + color.getBlue();
avg /= 3;
ptr[0] = (unsigned char)avg;
break;
}
case RGB: {
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 3;
ptr[0] = (unsigned char)color.getRed();
ptr[1] = (unsigned char)color.getGreen();
ptr[2] = (unsigned char)color.getBlue();
break;
}
}
unlockSharedMemory();
return false;
}
auto getPixel(int x, int y) -> Color {
Color color = Color(0,0,0);
auto reg = getRegisters();
switch(reg->graphicMode) {
case Text: {
int pixelIndex = (y * getWidth() + x);
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + pixelIndex / 8;
bool bit = (bool)(ptr[0] & (1 << (pixelIndex % 8)));
if(bit){
color = reg->foreground_color;
}else{
color =reg->background_color;
}
break;
}
case TwoColors: {
int pixelIndex = (y * getWidth() + x);
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (pixelIndex / 8);
bool bit = (bool)(ptr[0] & (1 << (pixelIndex % 8)));
if(bit){
color = reg->foreground_color;
}else{
color =reg->background_color;
}
break;
}
case Gray_256: {
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 1;
color = {ptr[0], ptr[0], ptr[0]};
break;
}
case RGB: {
unsigned char *ptr = reinterpret_cast<unsigned char *>(getPixelArea()) + (y * getWidth() + x) * 3;
color = {ptr[0], ptr[1], ptr[2]};
break;
}
}
return color;
}
auto setText(std::string text) -> bool {
lockSharedMemory();
char *ptr = getTextArea();
for(int i = 0; i < static_cast<int>(text.size());i++){
if(i >= getCharactersPerColumn() * getCharactersPerRow()){
break;
}
ptr[i] = text[i];
}
if(text.size() < getCharactersPerColumn() * getCharactersPerRow()){
ptr[text.size()] = '\0';
}
unlockSharedMemory();
return true;
}
auto getText() -> std::string {
return std::string (getTextArea());
}
auto getLayoutVersion() -> LayoutVersion {
return static_cast<LayoutVersion>(getRegisters()->layout_version);
}
auto reset() -> void {
//TODO(julian): reset
}
auto getWidth() -> int {
return getRegisters()->width_pixels;
}
auto setWidth(int newValue) -> void {
lockSharedMemory();
getRegisters()->width_pixels = newValue;
unlockSharedMemory();
}
auto getHeight() -> int {
return getRegisters()->height_pixels;
}
auto setHeight(int newValue) -> void {
lockSharedMemory();
getRegisters()->height_pixels = newValue;
unlockSharedMemory();
}
auto getMode() -> GraphicMode {
return getRegisters()->graphicMode;
}
auto setMode(GraphicMode newValue) -> void {
lockSharedMemory();
getRegisters()->graphicMode = newValue;
unlockSharedMemory();
}
auto getRedrawInterval() -> int {
return getRegisters()->autoRedrawInterval;
}
auto setRedrawInterval(int newValue) -> void {
lockSharedMemory();
getRegisters()->autoRedrawInterval = newValue;
unlockSharedMemory();
}
auto getTimerInterruptInterval() -> int {
return getRegisters()->timerInterruptInterval;
}
auto setTimerInterruptInterval(int newValue) -> void {
lockSharedMemory();
getRegisters()->timerInterruptInterval = newValue;
unlockSharedMemory();
}
auto getBackgroundColor() -> Color {
return getRegisters()->background_color;
}
auto setBackgroundColor(Color newValue) -> void {
lockSharedMemory();
getRegisters()->background_color = newValue;
unlockSharedMemory();
}
auto getForegroundColor() -> Color {
return getRegisters()->foreground_color;
}
auto setForegroundColor(Color newValue) -> void {
lockSharedMemory();
getRegisters()->foreground_color = newValue;
unlockSharedMemory();
}
auto getCharactersPerRow() -> int {
return getRegisters()->characters_per_row;
}
auto getCharactersPerColumn() -> int {
return getRegisters()->characters_per_column;
}
auto getFont() -> FontType {
//TODO(julian): get font properly
return font_1;
}
auto setFont(const FontType &newValue) -> void {
//TODO(julian): setFont properly
lockSharedMemory();
getRegisters()->textMode_font = newValue.getId();
unlockSharedMemory();
}
auto getMousePosition() -> Coordinates {
return {getRegisters()->mouse_pos_x, getRegisters()->mouse_pos_y};
}
auto getLastPressedKey() -> KeyCode {
lockSharedMemory();
KeyCode keyCode = KeyCode(0);
auto reg = getRegisters();
if(reg->keyboardBuffer_index_read != reg->keyboardBuffer_index_write) {
keyCode = (KeyCode) reg->keyboardBuffer[reg->keyboardBuffer_index_read++];
if (reg->keyboardBuffer_index_read >= sizeof(reg->keyboardBuffer)) {
reg->keyboardBuffer_index_read = 0;
}
}
unlockSharedMemory();
return keyCode;
}
}