gmgr_surface_t *GmgrCreateMemorySurface(const videomode_t *mode, uint32_t flags) { gmgr_surface_t *surf; surf = malloc(sizeof(*surf)); if (surf == NULL) return NULL; surf->device = NULL; surf->flags = flags; surf->mode = *mode; surf->base = VmmAlloc(PAGE_ALIGN_UP(mode->bytesPerLine * mode->height) / PAGE_SIZE, NULL, VM_MEM_USER | VM_MEM_READ | VM_MEM_WRITE); if (surf->base == NULL) { free(surf); return NULL; } if (!FramebufCreateSurface(mode, surf->base, &surf->surf)) { VmmFree(surf->base); free(surf); return NULL; } return surf; }
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; }
void GmgrCloseSurface(gmgr_surface_t *surf) { if (SysDecrementAndTest(&surf->refs)) { surf->surf.vtbl->SurfDeleteCookie(&surf->surf); if (surf->base != NULL) { if (surf->flags & GMGR_SURFACE_SHARED) VmmFree(surf->base); else free(surf->base); } if (surf->device != 0) HndClose(surf->device); free(surf); } }
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; }