bool IpcCallExtra(handle_t ipc, uint32_t code, const wnd_params_t *params, const void *extra, size_t extra_length) { ipc_packet_t packet = { 0 }; if (ipc == NULL) ipc = IpcGetDefault(); packet.code = code; if (params != NULL) packet.params = *params; packet.extra_length = extra_length; errno = 0; if (!FsWrite(ipc, &packet, 0, sizeof(packet), NULL)) { _wdprintf(L"%s: IpcCallExtra: FsWrite(1) failed: %s\n", ProcGetProcessInfo()->module_first->name, _wcserror(errno)); //return false; } if (extra_length > 0) { if (!FsWrite(ipc, extra, 0, extra_length, NULL)) { _wdprintf(L"%s: IpcCallExtra: FsWrite(2) failed: %s\n", ProcGetProcessInfo()->module_first->name, _wcserror(errno)); //return false; } } return true; }
bool GmgrInit(void) { params_vid_t params; handle_t device; LmuxInit(&gmgr_draw); LmuxInit(&gmgr_mux_gfxs); atexit(GmgrCleanup); device = FsOpen(SYS_DEVICES L"/Classes/video0", FILE_READ | FILE_WRITE); if (device == NULL) { _wdprintf(SYS_DEVICES L"/Classes/video0" L": %s\n", _wcserror(errno)); goto error0; } memset(¶ms.vid_setmode, 0, sizeof(params.vid_setmode)); if (!FsRequestSync(device, VID_SETMODE, ¶ms, sizeof(params), NULL)) { _wdprintf(L"VID_SETMODE: %s\n", _wcserror(errno)); goto error1; } gmgr_screen = GmgrCreateDeviceSurface(device, ¶ms.vid_setmode); if (gmgr_screen == NULL) { _wdprintf(L"GmgrCreateDeviceSurface: %s\n", _wcserror(errno)); goto error1; } gmgr_font = FontLoad(L"/Mobius/veramono.ttf", 12 * 64, gmgr_screen->mode.bitsPerPixel < 8 ? FB_FONT_MONO : FB_FONT_SMOOTH); if (gmgr_font == NULL) { _wdprintf(L"/Mobius/veramono.ttf: %s\n", _wcserror(errno)); goto error2; } if (!GmgrInitCursor()) goto error3; return true; error3: FontDelete(gmgr_font); gmgr_font = NULL; error2: GmgrCloseSurface(gmgr_screen); gmgr_screen = NULL; error1: HndClose(device); error0: return false; }
void LmuxRelease(lmutex_t *mux) { unsigned my_id; my_id = ThrGetThreadInfo()->id; if (mux->locks > 1) { if (mux->owner != my_id) { _wdprintf(L"LmuxRelease(%p/%u): incorrect owner %u, should be %u\n", mux, mux->mutex, mux->owner, my_id); __asm__("int3"); } mux->eip = 0; mux->owner = 0; if (!SemUp(mux->mutex)) __asm__("int3"); } else { mux->eip = 0; mux->locks = 0; mux->owner = 0; } }
gmgr_surface_t *GmgrCreateDeviceSurface(handle_t device, const videomode_t *mode) { gmgr_surface_t *surf; handle_t memory; surf = malloc(sizeof(*surf)); if (surf == NULL) return NULL; surf->refs = 1; surf->device = device; surf->flags = GMGR_SURFACE_SHARED; surf->mode = *mode; if (mode->framebuffer[0] == '\0') { surf->base = NULL; if (!AccelCreateSurface(mode, device, &surf->surf)) { _wdprintf(L"GmgrCreateDeviceSurface: AccelCreateSurface failed\n"); free(surf); return NULL; } } else { memory = HndOpen(mode->framebuffer); surf->base = VmmMapSharedArea(memory, NULL, VM_MEM_USER | VM_MEM_READ | VM_MEM_WRITE); HndClose(memory); if (!FramebufCreateSurface(mode, surf->base, &surf->surf)) { _wdprintf(L"GmgrCreateDeviceSurface: FramebufCreateSurface failed\n"); VmmFree(surf->base); free(surf); return NULL; } } return surf; }
static bool DbgHandleException(context_t *ctx) { printf("libc: exception %ld at %08lx\n", ctx->intr, ctx->eip); _wdprintf(L"libc: exception %ld at %08lx\n", ctx->intr, ctx->eip); DbgDumpStack(ctx); return false; }
void __malloc_leak_dump(void) { __maldbg_header_t *header; for (header = maldbg_first; header != NULL; header = header->next) if (__malloc_check_header(header) && header->tag == maldbg_tag) _wdprintf(L"%S(%d): memory leaked: %p\n", header->file, header->line, header + 1); }
void LmuxAcquire(lmutex_t *mux) { unsigned my_id; volatile lmutex_t *vmux = (volatile lmutex_t*) mux; my_id = ThrGetThreadInfo()->id; if (vmux->owner == my_id) { _wdprintf(L"LmuxAcquire(%p/%u): recursive acquisition by %u\n", vmux, vmux->mutex, my_id); __asm__("int3"); } if (SysIncrement(&vmux->locks) > 0) { if (!SemDown(vmux->mutex)) __asm__("int3"); if (vmux->owner != 0) { _wdprintf(L"LmuxAcquire(%p/%u): still locked by %u, %u contend\n", vmux, vmux->mutex, vmux->owner, my_id); __asm__("int3"); } vmux->eip = *(&mux - 1); vmux->locks--; vmux->owner = my_id; } else { vmux->eip = *(&mux - 1); vmux->owner = my_id; } }
bool __malloc_check_header(__maldbg_header_t *header) { if (header->magic[0] != 0xdeadbeef) { _wdprintf(L"%p: memory check error (1): got 0x%x, should be 0xdeadbeef\n", header + 1, header->magic[0]); return false; } if (header->magic[1] != (header->magic[0] ^ header->size)) { _wdprintf(L"%p: memory check error (2): got 0x%x, should be 0x%x\n", header + 1, header->magic[1], header->magic[0] ^ header->size); return false; } if (__malloc_find_block(header + 1) == NULL) { _wdprintf(L"%p: memory block not found in list\n", header + 1); return false; } return true; }
void OnKeyDown(uint32_t key) { wchar_t name[MAX_PATH]; unsigned index; if (key == 27) m_result = -1; else if (key < 0x10000) { key = towupper((wchar_t) key); if (key >= 'A' && key < 'A' + m_num_buttons) { index = key - 'A'; wcscpy(name, SYS_DEVICES L"/Classes/"); wcscat(name, m_names[index]); _wdprintf(L"key = %u (%c), device = %s\n", key, key, name); OS::WndAttachInputDevice(0, name); m_result = index + 1; } } }
static bool IpcReadFromPipe(handle_t file, void *buf, size_t length) { size_t bytes, total; total = 0; errno = 0; while (total < length) { //printf("FsRead(file=%u, length=%u-%u=%u)\n", //file, length, total, length - total); if (!FsRead(file, (char*) buf + total, 0, length - total, &bytes) || (length > 0 && bytes == 0)) { _wdprintf(L"%s: IpcReadFromPipe(%u): bytes = %u, errno = %d\n", ProcGetProcessInfo()->module_first->name, file, bytes, errno); return false; } total += bytes; } return true; }
int mainCRTStartup(void) { handle_t server, client; unsigned i; params_vid_t params; font_t *font; vid = FsOpen(SYS_DEVICES L"/Classes/video0", FILE_READ | FILE_WRITE); if (vid == NULL) { _wdprintf(L"console: " SYS_DEVICES L"/Classes/video0: %s\n", _wcserror(errno)); return errno; } memset(&mode, 0, sizeof(mode)); params.vid_setmode = mode; if (!FsRequestSync(vid, VID_SETMODE, ¶ms, sizeof(params), NULL)) { _wdprintf(L"console: failed to set video mode: %s\n", _wcserror(errno)); HndClose(vid); return errno; } mode = params.vid_setmode; if (mode.flags & VIDEO_MODE_TEXT) { _wdprintf(L"console: text mode not supported\n"); return 0; } if (mode.bitsPerPixel == 4) { vidmem = NULL; if (!AccelCreateSurface(&mode, vid, &surf)) { _wdprintf(L"console: AccelCreateSurface failed\n"); return errno; } } else { handle_t handle_vidmem; handle_vidmem = HndOpen(mode.framebuffer); if (handle_vidmem == 0) { _wdprintf(L"console: unable to open framebuffer %s\n", mode.framebuffer); return errno; } vidmem = VmmMapSharedArea(handle_vidmem, 0, VM_MEM_USER | VM_MEM_READ | VM_MEM_WRITE); HndClose(handle_vidmem); if (!FramebufCreateSurface(&mode, vidmem, &surf)) { _wdprintf(L"console: video mode not supported: %u bits per pixel\n", mode.bitsPerPixel); return errno; } } FontInit(); font = FontLoad(font_name, 10 * 64, mode.bitsPerPixel < 8 ? FB_FONT_MONO : FB_FONT_SMOOTH); if (font == NULL) { _wdprintf(L"console: failed to load font %s\n", font_name); return errno; } cookies[0] = (void*) 0x12345678; num_buffers = 1; LmuxInit(&lmux_consoles); for (i = 0; i < _countof(consoles); i++) { LmuxInit(&consoles[i].lmux); consoles[i].width = consoles[i].height = 0; consoles[i].fg_colour = consoles[i].default_fg_colour = 0xc0c0c0; consoles[i].bg_colour = consoles[i].default_bg_colour = 0x000000; consoles[i].cookie = cookies[0]; consoles[i].buf_chars = NULL; consoles[i].font = font; FontGetMaxSize(consoles[i].font, &consoles[i].char_width, &consoles[i].char_height); } num_consoles = _countof(consoles); ConTileBuffer(0); num_consoles = 0; current = consoles; for (i = 0; i < _countof(consoles); i++) ConClear(consoles + i); server = FsCreate(server_name, 0); ThrCreateThread(ConKeyboardThread, NULL, 16, L"ConKeyboardThread"); ThrCreateThread(ConCursorThread, NULL, 16, L"ConCursorThread"); ConDisplaySignonMessage(); while ((client = PortAccept(server, FILE_READ | FILE_WRITE))) { if (num_consoles < _countof(consoles)) { consoles[num_consoles].client = client; ThrCreateThread(ConClientThread, consoles + num_consoles, 15, L"ConClientThread"); num_consoles++; } else HndClose(client); } for (i = 0; i < _countof(consoles); i++) { LmuxDelete(&consoles[i].lmux); free(consoles[i].buf_chars); } LmuxDelete(&lmux_consoles); FontDelete(font); HndClose(server); if (vidmem != NULL) VmmFree(vidmem); HndClose(vid); return EXIT_SUCCESS; }
int ConKeyboardThread(void *param) { uint32_t ch, code; handle_t keyboard; //void *old_buffer; //unsigned i; keyboard = FsOpen(SYS_DEVICES L"/keyboard", FILE_READ); while (FsRead(keyboard, &ch, 0, sizeof(ch), NULL)) { code = ch & ~KBD_BUCKY_ANY; if ((ch & KBD_BUCKY_ALT) != 0 && code >= KEY_F1 && code <= KEY_F12) { /*LmuxAcquire(&lmux_consoles); LmuxAcquire(¤t->lmux); ConDrawCursor(current, false); old_buffer = current->cookie; current = consoles + code - KEY_F1; if (old_buffer != current->buffer) for (i = 0; i < num_consoles; i++) if (consoles[i].buffer == current->buffer) ConRedraw(consoles + i); ConDrawCursor(current, true); LmuxRelease(¤t->lmux); LmuxRelease(&lmux_consoles);*/ } else if (ch == (KBD_BUCKY_CTRL | KBD_BUCKY_ALT | KEY_DEL)) SysShutdown(SHUTDOWN_REBOOT); else if (ch == (KBD_BUCKY_ALT | '\t') || ch == (KBD_BUCKY_ALT | KBD_BUCKY_SHIFT | '\t')) { LmuxAcquire(&lmux_consoles); LmuxAcquire(¤t->lmux); ConDrawCursor(current, false); LmuxRelease(¤t->lmux); if (ch & KBD_BUCKY_SHIFT) { if (current - consoles - 1 < 0) current = consoles + num_consoles - 1; else current--; } else { if (current - consoles + 1 >= num_consoles) current = consoles; else current++; } LmuxAcquire(¤t->lmux); ConDrawCursor(current, true); LmuxRelease(¤t->lmux); LmuxRelease(&lmux_consoles); } else { LmuxAcquire(&lmux_consoles); if (current != NULL && current->client != NULL) FsWrite(current->client, &ch, 0, sizeof(ch), NULL); LmuxRelease(&lmux_consoles); } } _wdprintf(L"console(keyboard): FsRead failed, %s\n", _wcserror(errno)); return errno; }
size_t ConMultiByteToWideChar(wchar_t *dest, const char *src, size_t src_bytes, con_mbstate_t *state) { int i; unsigned char b[3]; unsigned count; size_t dest_chars; if (state->num_spare > 0) assert(ConIsLeadByte(state->spare[0])); switch (state->num_spare) { case 0: if (src_bytes > 0) b[0] = src[0]; if (src_bytes > 1) b[1] = src[1]; if (src_bytes > 2) b[2] = src[2]; break; case 1: b[0] = state->spare[0]; if (src_bytes > 0) b[1] = src[0]; if (src_bytes > 1) b[2] = src[1]; break; case 2: b[0] = state->spare[0]; b[1] = state->spare[1]; if (src_bytes > 0) b[2] = src[0]; break; } dest_chars = 0; i = -state->num_spare; state->num_spare = 0; while (i < (int) src_bytes) { if ((b[0] & 0x80) == 0) count = 1; else if ((b[0] & 0xE0) == 0xC0) count = 2; else if ((b[0] & 0xF0) == 0xE0) count = 3; else { _wdprintf(L"ConMultiByteToWideChar: invalid lead byte: %02x = %c\n", b[0], b[0]); count = 1; } if (i + count > src_bytes) { int j; state->num_spare = (int) src_bytes - i; assert(state->num_spare <= _countof(state->spare)); for (j = 0; j < state->num_spare; j++) state->spare[j] = src[i + j]; break; } i += count; switch (count) { case 1: *dest = (wchar_t) b[0]; b[0] = b[1]; b[1] = b[2]; b[2] = src[i + 2]; break; case 2: *dest = (b[0] & 0x1f) << 6 | (b[1] & 0x3f); b[0] = b[2]; b[1] = src[i + 1]; b[2] = src[i + 2]; break; case 3: *dest = (b[0] & 0x0f) << 12 | (b[1] & 0x3f) << 6 | (b[2] & 0x3f); b[0] = src[i + 0]; b[1] = src[i + 1]; b[2] = src[i + 2]; break; } dest_chars++; dest++; } return dest_chars; }