2019-11-13 13:37:49 +01:00
|
|
|
#include "SharedMemoryAccess.hpp"
|
|
|
|
#include "internal.hpp"
|
|
|
|
#include "vkvm.hpp"
|
2019-11-07 16:34:15 +01:00
|
|
|
|
2019-11-06 13:41:24 +01:00
|
|
|
#include <csignal>
|
2019-11-12 14:07:02 +01:00
|
|
|
#include <unistd.h>
|
2019-10-29 15:24:57 +01:00
|
|
|
|
2019-11-13 13:37:49 +01:00
|
|
|
namespace vkvm {
|
|
|
|
// NOLINT
|
|
|
|
auto initialize(int pid) -> void {
|
|
|
|
impl.sharedMemoryPid = pid;
|
|
|
|
impl.sharedMemoryKey = 12345;// NOLINT
|
|
|
|
impl.sharedMemorySize = 8000;// NOLINT
|
|
|
|
initSemaphore();
|
|
|
|
setDefaultValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto setDefaultValues() -> void {
|
2019-11-26 13:22:53 +01:00
|
|
|
impl.localMemoryWarn = false;
|
2019-11-13 13:37:49 +01:00
|
|
|
if(getSharedMemory() != nullptr) {
|
|
|
|
//set default values
|
2019-11-26 13:22:53 +01:00
|
|
|
setMode(GraphicMode::RGB);
|
2019-11-13 13:37:49 +01:00
|
|
|
setCharactersPerRow(60);// NOLINT
|
|
|
|
setCharactersPerColumn(20);// NOLINT
|
2019-11-27 11:40:54 +01:00
|
|
|
setHeight(60);// NOLINT
|
|
|
|
setWidth(80);// NOLINT
|
2019-11-13 13:37:49 +01:00
|
|
|
setMousePosition(42, 42);// NOLINT
|
2019-11-21 11:35:54 +01:00
|
|
|
setBackgroundColor(black);
|
|
|
|
setForegroundColor(white);
|
2019-11-13 13:37:49 +01:00
|
|
|
setRedrawInterval(20);// NOLINT
|
|
|
|
setTimerInterruptInterval(10);// NOLINT
|
|
|
|
}
|
2019-11-26 13:22:53 +01:00
|
|
|
impl.localMemoryWarn = true;
|
2019-11-13 13:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
auto registerEvent(EventType type, const std::function<void()> &handler) -> bool {
|
|
|
|
int signum = SIGUSR1 + impl.eventTable.size();
|
|
|
|
auto ivt = getInterrupTable();
|
|
|
|
|
|
|
|
lockSharedMemory();
|
|
|
|
|
2019-11-19 11:56:18 +01:00
|
|
|
for(int i = 0; i < impl.interruptEntrysPerEventType;i++){
|
|
|
|
auto &entry= ivt[type * impl.interruptEntrysPerEventType + i];
|
|
|
|
if (entry.pid == 0) {
|
2019-11-13 13:37:49 +01:00
|
|
|
|
2019-11-19 11:56:18 +01:00
|
|
|
entry.pid = getpid();
|
|
|
|
entry.signum = signum;
|
|
|
|
impl.eventTable.push_back(handler);
|
2019-11-13 13:37:49 +01:00
|
|
|
|
2019-11-19 11:56:18 +01:00
|
|
|
onSignal(signum, [](int sig){
|
|
|
|
if(sig >= SIGUSR1){
|
|
|
|
if((sig - SIGUSR1) < impl.eventTable.size()){
|
|
|
|
impl.eventTable[sig - SIGUSR1]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
unlockSharedMemory();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2019-11-13 13:37:49 +01:00
|
|
|
unlockSharedMemory();
|
2019-11-19 11:56:18 +01:00
|
|
|
return false;
|
2019-11-13 13:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
auto setPixel(int x, int y, Color color) -> bool {
|
2019-11-26 12:33:34 +01:00
|
|
|
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();
|
2019-11-13 13:37:49 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto getPixel(int x, int y) -> Color {
|
2019-11-26 12:33:34 +01:00
|
|
|
Color color = Color(0,0,0);
|
|
|
|
auto reg = getRegisters();
|
2019-11-21 11:35:54 +01:00
|
|
|
|
2019-11-26 12:33:34 +01:00
|
|
|
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;
|
2019-11-21 11:35:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return color;
|
2019-11-13 13:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2019-11-06 13:41:24 +01:00
|
|
|
}
|
2019-11-13 13:37:49 +01:00
|
|
|
ptr[i] = text[i];
|
2019-11-06 13:41:24 +01:00
|
|
|
}
|
2019-11-13 13:37:49 +01:00
|
|
|
if(text.size() < getCharactersPerColumn() * getCharactersPerRow()){
|
|
|
|
ptr[text.size()] = '\0';
|
2019-11-07 16:34:15 +01:00
|
|
|
}
|
2019-11-13 13:37:49 +01:00
|
|
|
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();
|
2019-11-26 13:22:53 +01:00
|
|
|
auto reg = getRegisters();
|
|
|
|
if(reg->graphicMode != newValue){
|
|
|
|
|
|
|
|
std::vector<Color> pixels;
|
|
|
|
int height = reg->height_pixels;
|
|
|
|
int width = reg->width_pixels;
|
|
|
|
pixels.resize(height * width);
|
|
|
|
|
|
|
|
for(int y = 0; y < height;y++){
|
|
|
|
for(int x = 0;x < width;x++){
|
|
|
|
pixels[y * width + x] = getPixel(x,y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getRegisters()->graphicMode = newValue;
|
|
|
|
|
|
|
|
unlockSharedMemory();
|
|
|
|
for(int y = 0; y < height;y++){
|
|
|
|
for(int x = 0;x < width;x++){
|
|
|
|
setPixel(x,y, pixels[y * width + x]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lockSharedMemory();
|
|
|
|
}else{
|
|
|
|
reg->graphicMode = newValue;
|
|
|
|
}
|
2019-11-13 13:37:49 +01:00
|
|
|
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 {
|
2019-11-26 11:49:19 +01:00
|
|
|
lockSharedMemory();
|
2019-11-26 12:33:34 +01:00
|
|
|
KeyCode keyCode = KeyCode(0);
|
2019-11-26 11:49:19 +01:00
|
|
|
auto reg = getRegisters();
|
2019-11-26 12:33:34 +01:00
|
|
|
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;
|
|
|
|
}
|
2019-11-26 11:49:19 +01:00
|
|
|
}
|
|
|
|
unlockSharedMemory();
|
|
|
|
return keyCode;
|
2019-11-13 13:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|