status_t device_ioctl(void* cookie, uint32 msg, void* buf, size_t len) { TRACE("device_ioctl\n"); DeviceInfo* dev = (DeviceInfo*)cookie; switch (msg) { case B_GET_ACCELERANT_SIGNATURE: strcpy((char*)buf, "vboxvideo.accelerant"); return B_OK; case VBOXVIDEO_GET_PRIVATE_DATA: return user_memcpy(buf, &dev->sharedArea, sizeof(area_id)); case VBOXVIDEO_GET_DEVICE_NAME: if (user_strlcpy((char*)buf, gDeviceInfo.name, len) < B_OK) return B_BAD_ADDRESS; else return B_OK; case VBOXVIDEO_SET_DISPLAY_MODE: { display_mode* mode = (display_mode*)buf; VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display, mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0); gDeviceInfo.sharedInfo->currentMode = *mode; return B_OK; } default: return B_BAD_VALUE; } }
status_t VBoxDisplayService::_ServiceThread() { LogFlow(("VBoxDisplayService::_ServiceThread")); VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0); VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0); for (;;) { uint32_t events; int rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 5000, &events); if (rc == -6) // timed out? continue; if (RT_SUCCESS(rc)) { uint32_t cx, cy, cBits, iDisplay; int rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, true); LogFlow(("rc2=%d screen %d size changed (%d, %d, %d)\n", rc2, iDisplay, cx, cy, cBits)); if (RT_SUCCESS(rc2)) { display_mode mode; fScreen.GetMode(&mode); if (cBits == 0) cBits = get_depth_for_color_space(mode.space); mode.timing.h_display = cx; mode.timing.v_display = cy; mode.space = get_color_space_for_depth(cBits); mode.virtual_width = cx; mode.virtual_height = cy; /*= { {0, cx, 0, 0, cBits * cx / 8, cy, 0, 0, cBits * cy / 8, 0}, get_color_space_for_depth(cBits), cx, cy, 0, 0, 0 };*/ fScreen.SetMode(&mode, false); } } else fExiting = true; LogFlow(("processed host event rc = %d\n", rc)); if (fExiting) break; } return 0; }