support for latest qemu; update luigi.h

This commit is contained in:
nakst 2021-08-15 00:09:47 +01:00
parent 7a9b3da442
commit edd1b57db7
5 changed files with 170 additions and 26 deletions

View File

@ -78,6 +78,7 @@ struct MMSpace {
bool user; // Regions in the space may be accessed from userspace.
uint64_t commit; // An *approximate* commit in pages. TODO Better memory usage tracking.
uint64_t reserve; // The number of reserved pages.
};
// A physical page of memory.
@ -933,6 +934,8 @@ MMRegion *MMReserve(MMSpace *space, size_t bytes, unsigned flags, uintptr_t forc
outputRegion->itemNonGuard.thisItem = outputRegion;
space->usedRegionsNonGuard.InsertEnd(&outputRegion->itemNonGuard);
}
space->reserve += pagesNeeded;
}
// EsPrint("Reserve: %x->%x\n", outputRegion->baseAddress, outputRegion->pageCount * K_PAGE_SIZE + outputRegion->baseAddress);
@ -976,6 +979,8 @@ void MMUnreserve(MMSpace *space, MMRegion *remove, bool unmapPages, bool guardRe
MMArchUnmapPages(space, remove->baseAddress,
remove->pageCount, ES_FLAGS_DEFAULT);
}
space->reserve += remove->pageCount;
if (space == coreMMSpace) {
remove->core.used = false;

View File

@ -375,7 +375,7 @@ void Build(bool enableOptimisations, bool compile) {
#define DEBUG_START (1)
#define DEBUG_NONE (2)
void Run(int emulator, int memory, int cores, int log, int debug) {
void Run(int emulator, int cores, int log, int debug) {
LoadOptions();
switch (emulator) {
@ -386,7 +386,7 @@ void Run(int emulator, int memory, int cores, int log, int debug) {
const char *driveFlags = IsOptionEnabled("Emulator.ATA") ? "-drive file=bin/drive,format=raw,media=disk,index=0 " :
IsOptionEnabled("Emulator.AHCI") ? "-drive file=bin/drive,if=none,id=mydisk,format=raw,media=disk,index=0 "
"-device ich9-ahci,id=ahci "
"-device ide-drive,drive=mydisk,bus=ahci.0 "
"-device ide-hd,drive=mydisk,bus=ahci.0 "
: "-drive file=bin/drive,if=none,id=mydisk,format=raw "
"-device nvme,drive=mydisk,serial=1234 ";
@ -397,7 +397,7 @@ void Run(int emulator, int memory, int cores, int log, int debug) {
snprintf(cdromFlags, sizeof(cdromFlags), " -cdrom %s ", cdromImage);
} else {
snprintf(cdromFlags, sizeof(cdromFlags), "-drive file=%s,if=none,id=mycdrom,format=raw,media=cdrom,index=1 "
"-device ide-drive,drive=mycdrom,bus=ahci.1", cdromImage);
"-device ide-cd,drive=mycdrom,bus=ahci.1", cdromImage);
}
} else {
cdromFlags[0] = 0;
@ -432,7 +432,8 @@ void Run(int emulator, int memory, int cores, int log, int debug) {
" -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0,id=mykeyboard -device usb-mouse,bus=xhci.0,id=mymouse "
" -netdev user,id=u1 -device e1000,netdev=u1 -object filter-dump,id=f1,netdev=u1,file=bin/net.dat "
" %s %s %s %s ",
audioFlags, IsOptionEnabled("Emulator.RunWithSudo") ? "sudo " : "", driveFlags, cdromFlags, memory,
audioFlags, IsOptionEnabled("Emulator.RunWithSudo") ? "sudo " : "", driveFlags, cdromFlags,
atoi(GetOptionString("Emulator.MemoryMB")),
debug ? (debug == DEBUG_NONE ? "-enable-kvm" : "-S") : "",
cores, audioFlags2, logFlags, usbFlags, usbFlags2);
} break;
@ -973,7 +974,6 @@ void AddressToLine(const char *symbolFile) {
typedef struct BuildType {
const char *name, *alias, *emulator;
bool optimise, debug, smp, noCompile;
int memory;
} BuildType;
BuildType buildTypes[] = {
@ -1020,8 +1020,7 @@ void DoCommand(const char *l) {
if (encounteredErrors) {
printf("Errors were encountered during the build.\n");
} else if (entry->emulator) {
Run(entry->emulator[0] == 'q' ? EMULATOR_QEMU : EMULATOR_VIRTUALBOX,
entry->memory ?: 1024, entry->smp ? 3 : 1, LOG_NORMAL, entry->debug);
Run(entry->emulator[0] == 'q' ? EMULATOR_QEMU : EMULATOR_VIRTUALBOX, entry->smp ? 3 : 1, LOG_NORMAL, entry->debug);
}
return;

View File

@ -251,6 +251,7 @@ typedef struct Option {
OptionVariant defaultState;
OptionVariant state;
bool useDefaultState;
const char *warning;
} Option;
Option options[] = {
@ -262,9 +263,9 @@ Option options[] = {
{ "Driver.FAT", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.HDAudio", OPTION_TYPE_BOOL, { .b = false } },
{ "Driver.I8254x", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.IDE", OPTION_TYPE_BOOL, { .b = false } },
{ "Driver.IDE", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.ISO9660", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.NTFS", OPTION_TYPE_BOOL, { .b = false } },
{ "Driver.NTFS", OPTION_TYPE_BOOL, { .b = false }, .warning = "The NTFS driver has not been updated to work with the new FS layer." },
{ "Driver.NVMe", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.Networking", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.PCI", OPTION_TYPE_BOOL, { .b = true } },
@ -289,15 +290,16 @@ Option options[] = {
{ "Dependency.stb_sprintf", OPTION_TYPE_BOOL, { .b = true } },
{ "Dependency.HarfBuzz", OPTION_TYPE_BOOL, { .b = true } },
{ "Dependency.FreeType", OPTION_TYPE_BOOL, { .b = true } },
{ "Emulator.AHCI", OPTION_TYPE_BOOL, { .b = false } },
{ "Emulator.AHCI", OPTION_TYPE_BOOL, { .b = true } },
{ "Emulator.ATA", OPTION_TYPE_BOOL, { .b = false } },
{ "Emulator.NVMe", OPTION_TYPE_BOOL, { .b = true } },
{ "Emulator.NVMe", OPTION_TYPE_BOOL, { .b = false }, .warning = "Recent versions of Qemu have trouble booting from NVMe drives." },
{ "Emulator.CDROMImage", OPTION_TYPE_STRING, { .s = NULL } },
{ "Emulator.USBImage", OPTION_TYPE_STRING, { .s = NULL } },
{ "Emulator.USBHostVendor", OPTION_TYPE_STRING, { .s = NULL } },
{ "Emulator.USBHostProduct", OPTION_TYPE_STRING, { .s = NULL } },
{ "Emulator.RunWithSudo", OPTION_TYPE_BOOL, { .b = false } },
{ "Emulator.Audio", OPTION_TYPE_BOOL, { .b = false } },
{ "Emulator.MemoryMB", OPTION_TYPE_STRING, { .s = "1024" } },
{ "General.first_application", OPTION_TYPE_STRING, { .s = NULL } },
{ "General.wallpaper", OPTION_TYPE_STRING, { .s = NULL } },
};
@ -312,6 +314,10 @@ void LoadOptions() {
for (uintptr_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
options[i].state = options[i].defaultState;
options[i].useDefaultState = true;
if (options[i].type == OPTION_TYPE_STRING && options[i].state.s) {
options[i].state.s = strdup(options[i].state.s);
}
}
while (s.buffer && EsINIParse(&s)) {

View File

@ -38,14 +38,26 @@ int OptionTableMessage(UIElement *element, UIMessage message, int di, void *dp)
Option *option = options + index;
if (option->type == OPTION_TYPE_BOOL) {
option->state.b = !option->state.b;
bool okay = true;
if (option->warning && !option->state.b) {
if (UIDialogShow(element->window, 0, "Warning:\n%s\n%f%b%b", option->warning, "Enable", "Cancel")[0] == 'C') {
okay = false;
}
}
if (okay) {
option->state.b = !option->state.b;
option->useDefaultState = false;
}
} else if (option->type == OPTION_TYPE_STRING) {
UIDialogShow(element->window, 0, "New value: \n%t\n%f%b", &option->state.s, "OK");
option->useDefaultState = false;
} else {
// TODO.
option->useDefaultState = false;
}
option->useDefaultState = false;
UITableResizeColumns(optionTable);
UIElementRefresh(element);
UILabelSetContent(unsavedChangedLabel, "You have unsaved changes!", -1);
@ -91,10 +103,6 @@ void ActionSave(void *_unused) {
}
int main(int argc, char **argv) {
for (uintptr_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
options[i].state = options[i].defaultState;
}
LoadOptions();
UIInitialise();

View File

@ -164,6 +164,7 @@ typedef enum UIMessage {
UI_MSG_CODE_DECORATE_LINE, // dp = pointer to UICodeDecorateLine
UI_MSG_WINDOW_CLOSE, // return 1 to prevent default (process exit for UIWindow; close for UIMDIChild)
UI_MSG_TAB_SELECTED, // sent to the tab that was selected (not the tab pane itself)
UI_MSG_WINDOW_DROP_FILES, // di = count, dp = char ** of paths
UI_MSG_USER,
} UIMessage;
@ -370,6 +371,7 @@ typedef struct UIWindow {
XImage *image;
XIC xic;
unsigned ctrlCode, shiftCode, altCode;
Window dragSource;
#endif
#ifdef UI_WINDOWS
@ -392,6 +394,7 @@ typedef struct UIPanel {
#define UI_PANEL_MEDIUM_SPACING (1 << 5)
#define UI_PANEL_SMALL_SPACING (1 << 6)
#define UI_PANEL_SCROLL (1 << 7)
#define UI_PANEL_BORDER (1 << 8)
UIElement e;
struct UIScrollBar *scrollBar;
UIRectangle border;
@ -668,7 +671,8 @@ struct {
Display *display;
Visual *visual;
XIM xim;
Atom windowClosedID;
Atom windowClosedID, primaryID, uriListID, plainTextID;
Atom dndEnterID, dndPositionID, dndStatusID, dndActionCopyID, dndDropID, dndSelectionID, dndFinishedID, dndAwareID;
Cursor cursors[UI_CURSOR_COUNT];
#endif
@ -1608,6 +1612,10 @@ int _UIPanelMessage(UIElement *element, UIMessage message, int di, void *dp) {
UIDrawBlock((UIPainter *) dp, element->bounds, ui.theme.panel1);
} else if (element->flags & UI_PANEL_WHITE) {
UIDrawBlock((UIPainter *) dp, element->bounds, ui.theme.panel2);
}
if (element->flags & UI_PANEL_BORDER) {
UIDrawBorder((UIPainter *) dp, element->bounds, ui.theme.border, UI_RECT_1((int) element->window->scale));
}
} else if (message == UI_MSG_MOUSE_WHEEL && panel->scrollBar) {
return UIElementMessage(&panel->scrollBar->e, message, di, dp);
@ -3430,26 +3438,29 @@ const char *UIDialogShow(UIWindow *window, uint32_t flags, const char *format, .
} else if (format[i] == '%') {
i++;
if (format[i] == 'b') {
if (format[i] == 'b' /* button */) {
const char *label = va_arg(arguments, const char *);
UIButton *button = UIButtonCreate(&row->e, 0, label, -1);
if (!focus) focus = &button->e;
button->invoke = _UIDialogButtonInvoke;
button->e.cp = (void *) label;
} else if (format[i] == 's') {
} else if (format[i] == 's' /* label from string */) {
const char *label = va_arg(arguments, const char *);
UILabelCreate(&row->e, 0, label, -1);
} else if (format[i] == 't') {
} else if (format[i] == 't' /* textbox */) {
char **buffer = va_arg(arguments, char **);
UITextbox *textbox = UITextboxCreate(&row->e, UI_ELEMENT_H_FILL);
if (!focus) focus = &textbox->e;
if (*buffer) UITextboxReplace(textbox, *buffer, _UIStringLength(*buffer), false);
textbox->e.cp = buffer;
textbox->e.messageUser = _UIDialogTextboxMessage;
} else if (format[i] == 'f') {
} else if (format[i] == 'f' /* horizontal fill */) {
UISpacerCreate(&row->e, UI_ELEMENT_H_FILL, 0, 0);
} else if (format[i] == 'l') {
} else if (format[i] == 'l' /* horizontal line */) {
UISpacerCreate(&row->e, UI_SPACER_LINE | UI_ELEMENT_H_FILL, 0, 1);
} else if (format[i] == 'u' /* user */) {
void (*callback)(UIElement *) = va_arg(arguments, void (*)(UIElement *));
callback(&row->e);
}
} else {
int j = i;
@ -3462,7 +3473,7 @@ const char *UIDialogShow(UIWindow *window, uint32_t flags, const char *format, .
va_end(arguments);
window->dialogOldFocus = window->focused;
UIElementFocus(focus);
UIElementFocus(focus ? focus : window->dialog);
// Run the modal message loop.
@ -4262,6 +4273,9 @@ UIWindow *UIWindowCreate(UIWindow *owner, uint32_t flags, const char *cTitle, in
window->xic = XCreateIC(ui.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, window->window, XNFocusWindow, window->window, NULL);
int dndVersion = 4;
XChangeProperty(ui.display, window->window, ui.dndAwareID, XA_ATOM, 32 /* bits */, PropModeReplace, (uint8_t *) &dndVersion, 1);
return window;
}
@ -4276,7 +4290,19 @@ void UIInitialise() {
ui.display = XOpenDisplay(NULL);
ui.visual = XDefaultVisual(ui.display, 0);
ui.windowClosedID = XInternAtom(ui.display, "WM_DELETE_WINDOW", 0);
ui.primaryID = XInternAtom(ui.display, "PRIMARY", 0);
ui.dndEnterID = XInternAtom(ui.display, "XdndEnter", 0);
ui.dndPositionID = XInternAtom(ui.display, "XdndPosition", 0);
ui.dndStatusID = XInternAtom(ui.display, "XdndStatus", 0);
ui.dndActionCopyID = XInternAtom(ui.display, "XdndActionCopy", 0);
ui.dndDropID = XInternAtom(ui.display, "XdndDrop", 0);
ui.dndSelectionID = XInternAtom(ui.display, "XdndSelection", 0);
ui.dndFinishedID = XInternAtom(ui.display, "XdndFinished", 0);
ui.dndAwareID = XInternAtom(ui.display, "XdndAware", 0);
ui.uriListID = XInternAtom(ui.display, "text/uri-list", 0);
ui.plainTextID = XInternAtom(ui.display, "text/plain", 0);
ui.cursors[UI_CURSOR_ARROW] = XCreateFontCursor(ui.display, XC_left_ptr);
ui.cursors[UI_CURSOR_TEXT] = XCreateFontCursor(ui.display, XC_xterm);
@ -4394,8 +4420,6 @@ void UIWindowPack(UIWindow *window, int _width) {
}
bool _UIProcessEvent(XEvent *event) {
// printf("x11 event: %d\n", event->type);
if (event->type == ClientMessage && (Atom) event->xclient.data.l[0] == ui.windowClosedID) {
UIWindow *window = _UIFindWindow(event->xclient.window);
if (!window) return false;
@ -4514,6 +4538,107 @@ bool _UIProcessEvent(XEvent *event) {
UIWindow *window = _UIFindWindow(event->xfocus.window);
if (!window) return false;
window->ctrl = window->shift = window->alt = false;
} else if (event->type == ClientMessage && event->xclient.message_type == ui.dndEnterID) {
UIWindow *window = _UIFindWindow(event->xclient.window);
if (!window) return false;
window->dragSource = (Window) event->xclient.data.l[0];
} else if (event->type == ClientMessage && event->xclient.message_type == ui.dndPositionID) {
UIWindow *window = _UIFindWindow(event->xclient.window);
if (!window) return false;
XClientMessageEvent m = { 0 };
m.type = ClientMessage;
m.display = event->xclient.display;
m.window = (Window) event->xclient.data.l[0];
m.message_type = ui.dndStatusID;
m.format = 32;
m.data.l[0] = window->window;
m.data.l[1] = true;
m.data.l[4] = ui.dndActionCopyID;
XSendEvent(ui.display, m.window, False, NoEventMask, (XEvent *) &m);
XFlush(ui.display);
} else if (event->type == ClientMessage && event->xclient.message_type == ui.dndDropID) {
UIWindow *window = _UIFindWindow(event->xclient.window);
if (!window) return false;
// TODO Dropping text.
if (!XConvertSelection(ui.display, ui.dndSelectionID, ui.uriListID, ui.primaryID, window->window, event->xclient.data.l[2])) {
XClientMessageEvent m = { 0 };
m.type = ClientMessage;
m.display = ui.display;
m.window = window->dragSource;
m.message_type = ui.dndFinishedID;
m.format = 32;
m.data.l[0] = window->window;
m.data.l[1] = 0;
m.data.l[2] = ui.dndActionCopyID;
XSendEvent(ui.display, m.window, False, NoEventMask, (XEvent *) &m);
XFlush(ui.display);
}
} else if (event->type == SelectionNotify) {
UIWindow *window = _UIFindWindow(event->xselection.requestor);
if (!window) return false;
if (!window->dragSource) return false;
Atom type = None;
int format = 0;
uint64_t count = 0, bytesLeft = 0;
uint8_t *data = NULL;
XGetWindowProperty(ui.display, window->window, ui.primaryID, 0, 65536, False, AnyPropertyType, &type, &format, &count, &bytesLeft, &data);
if (format == 8 /* bits per character */) {
if (event->xselection.target == ui.uriListID) {
char *copy = (char *) UI_MALLOC(count);
int fileCount = 0;
for (int i = 0; i < (int) count; i++) {
copy[i] = data[i];
if (i && data[i - 1] == '\r' && data[i] == '\n') {
fileCount++;
}
}
char **files = (char **) UI_MALLOC(sizeof(char *) * fileCount);
fileCount = 0;
for (int i = 0; i < (int) count; i++) {
char *s = copy + i;
while (!(i && data[i - 1] == '\r' && data[i] == '\n' && i < (int) count)) i++;
copy[i - 1] = 0;
if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':' && s[5] == '/' && s[6] == '/') {
files[fileCount++] = s + 7;
}
// TODO Replace % codes in the URL.
}
UIElementMessage(&window->e, UI_MSG_WINDOW_DROP_FILES, fileCount, files);
UI_FREE(files);
UI_FREE(copy);
} else if (event->xselection.target == ui.plainTextID) {
// TODO.
}
}
XFree(data);
XClientMessageEvent m = { 0 };
m.type = ClientMessage;
m.display = ui.display;
m.window = window->dragSource;
m.message_type = ui.dndFinishedID;
m.format = 32;
m.data.l[0] = window->window;
m.data.l[1] = true;
m.data.l[2] = ui.dndActionCopyID;
XSendEvent(ui.display, m.window, False, NoEventMask, (XEvent *) &m);
XFlush(ui.display);
window->dragSource = 0; // Drag complete.
_UIUpdate();
}
return false;
@ -4569,6 +4694,7 @@ bool _UIMessageLoopSingle(int *result) {
void UIWindowPostMessage(UIWindow *window, UIMessage message, void *_dp) {
// HACK! Xlib doesn't seem to have a nice way to do this,
// so send a specially crafted key press event instead.
// TODO Maybe ClientMessage is what this should use?
uintptr_t dp = (uintptr_t) _dp;
XKeyEvent event = { 0 };
event.display = ui.display;