Changeset 97790 in vbox for trunk/src/VBox/Additions/common/VBoxGuest
- Timestamp:
- Dec 13, 2022 1:06:03 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
r96407 r97790 103 103 # define kgid_t gid_t 104 104 # define kuid_t uid_t 105 #endif 106 107 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 108 /** The name of input pointing device for mouse integration. */ 109 # define VBOX_INPUT_DEVICE_NAME "VirtualBox mouse integration" 105 110 #endif 106 111 … … 148 153 static struct fasync_struct *g_pFAsyncQueue; 149 154 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 150 /** Pre-allocated mouse status VMMDev request for use in the IRQ 151 * handler. */ 152 static VMMDevReqMouseStatus *g_pMouseStatusReq; 155 /** Pre-allocated mouse status VMMDev requests for use in the IRQ handler. */ 156 static VMMDevReqMouseStatusEx *g_pMouseStatusReqEx; 153 157 #endif 154 158 #if RTLNX_VER_MIN(2,6,0) … … 421 425 422 426 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 427 /** 428 * Check if extended mouse pointer state request protocol is currently used by driver. 429 * 430 * @returns True if extended protocol is used, False otherwise. 431 */ 432 static bool vgdrvLinuxUsesMouseStatusEx(void) 433 { 434 return g_pMouseStatusReqEx->Core.header.requestType == VMMDevReq_GetMouseStatusEx; 435 } 423 436 424 437 /** … … 450 463 static int vboxguestOpenInputDevice(struct input_dev *pDev) 451 464 { 452 int rc = vgdrvLinuxSetMouseStatus(VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_NEW_PROTOCOL); 465 int rc = vgdrvLinuxSetMouseStatus( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE 466 | VMMDEV_MOUSE_NEW_PROTOCOL 467 | (vgdrvLinuxUsesMouseStatusEx() ? VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL : 0)); 453 468 if (RT_FAILURE(rc)) 454 469 return ENODEV; … … 471 486 472 487 /** 488 * Free corresponding mouse status request structure. 489 */ 490 static void vgdrvLinuxFreeMouseStatusReq(void) 491 { 492 VbglR0GRFree(&g_pMouseStatusReqEx->Core.header); 493 g_pMouseStatusReqEx = NULL; 494 } 495 496 /** 473 497 * Creates the kernel input device. 474 498 */ 475 499 static int __init vgdrvLinuxCreateInputDevice(void) 476 500 { 477 int rc = VbglR0GRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReq, sizeof(*g_pMouseStatusReq), VMMDevReq_GetMouseStatus); 501 /* Try to allocate legacy request data first, and check if host supports extended protocol. */ 502 int rc = VbglR0GRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReqEx, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus); 503 if (RT_SUCCESS(rc)) 504 { 505 /* Check if host supports extended mouse state reporting. */ 506 g_pMouseStatusReqEx->Core.mouseFeatures = 0; 507 rc = VbglR0GRPerform(&g_pMouseStatusReqEx->Core.header); 508 if (RT_SUCCESS(rc)) 509 { 510 if (g_pMouseStatusReqEx->Core.mouseFeatures & VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL) 511 { 512 VMMDevReqMouseStatusEx *pReqEx = NULL; 513 rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pReqEx, sizeof(*pReqEx), VMMDevReq_GetMouseStatusEx); 514 if (RT_SUCCESS(rc)) 515 { 516 /* De-allocate legacy request data, */ 517 VbglR0GRFree(&g_pMouseStatusReqEx->Core.header); 518 /* ..and switch to extended requests. */ 519 g_pMouseStatusReqEx = pReqEx; 520 LogRel(("Host supports full mouse state reporting, switching to extended mouse integration protocol\n")); 521 } 522 else 523 LogRel(("Host supports full mouse state reporting, but feature cannot be initialized, switching to legacy mouse integration protocol\n")); 524 } 525 else 526 LogRel(("Host does not support full mouse state reporting, switching to legacy mouse integration protocol\n")); 527 } 528 else 529 LogRel(("Unable to get host mouse capabilities, switching to legacy mouse integration protocol\n")); 530 } 531 else 532 rc = -ENOMEM; 533 478 534 if (RT_SUCCESS(rc)) 479 535 { … … 481 537 if (g_pInputDevice) 482 538 { 539 g_pInputDevice->name = VBOX_INPUT_DEVICE_NAME; 483 540 g_pInputDevice->id.bustype = BUS_PCI; 484 541 g_pInputDevice->id.vendor = VMMDEV_VENDORID; … … 492 549 g_pInputDevice->dev.parent = &g_pPciDev->dev; 493 550 # endif 551 /* Set up input device capabilities. */ 552 ASMBitSet(g_pInputDevice->evbit, EV_ABS); 553 # ifdef EV_SYN 554 ASMBitSet(g_pInputDevice->evbit, EV_SYN); 555 # endif 556 ASMBitSet(g_pInputDevice->absbit, ABS_X); 557 ASMBitSet(g_pInputDevice->absbit, ABS_Y); 558 559 input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); 560 input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0); 561 562 /* Report extra capabilities to input layer if extended mouse state protocol 563 * will be used in communication with host. */ 564 if (vgdrvLinuxUsesMouseStatusEx()) 565 { 566 ASMBitSet(g_pInputDevice->evbit, EV_REL); 567 ASMBitSet(g_pInputDevice->evbit, EV_KEY); 568 569 ASMBitSet(g_pInputDevice->relbit, REL_WHEEL); 570 ASMBitSet(g_pInputDevice->relbit, REL_HWHEEL); 571 572 ASMBitSet(g_pInputDevice->keybit, BTN_LEFT); 573 ASMBitSet(g_pInputDevice->keybit, BTN_RIGHT); 574 ASMBitSet(g_pInputDevice->keybit, BTN_MIDDLE); 575 ASMBitSet(g_pInputDevice->keybit, BTN_SIDE); 576 ASMBitSet(g_pInputDevice->keybit, BTN_EXTRA); 577 } 578 494 579 rc = input_register_device(g_pInputDevice); 495 580 if (rc == 0) 496 {497 /* Do what one of our competitors apparently does as that works. */498 ASMBitSet(g_pInputDevice->evbit, EV_ABS);499 ASMBitSet(g_pInputDevice->evbit, EV_KEY);500 # ifdef EV_SYN501 ASMBitSet(g_pInputDevice->evbit, EV_SYN);502 # endif503 input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);504 input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);505 ASMBitSet(g_pInputDevice->keybit, BTN_MOUSE);506 /** @todo this string should be in a header file somewhere. */507 g_pInputDevice->name = "VirtualBox mouse integration";508 581 return 0; 509 }510 582 511 583 input_free_device(g_pInputDevice); … … 513 585 else 514 586 rc = -ENOMEM; 515 VbglR0GRFree(&g_pMouseStatusReq->header); 516 g_pMouseStatusReq = NULL; 517 } 518 else 519 rc = -ENOMEM; 587 588 vgdrvLinuxFreeMouseStatusReq(); 589 } 590 520 591 return rc; 521 592 } … … 527 598 static void vgdrvLinuxTermInputDevice(void) 528 599 { 529 VbglR0GRFree(&g_pMouseStatusReq->header); 530 g_pMouseStatusReq = NULL; 600 /* Notify host that mouse integration is no longer available. */ 601 vgdrvLinuxSetMouseStatus(0); 602 603 vgdrvLinuxFreeMouseStatusReq(); 531 604 532 605 /* See documentation of input_register_device(): input_free_device() … … 1155 1228 1156 1229 1230 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 1231 /** 1232 * Get host mouse state. 1233 * 1234 * @returns IPRT status code. 1235 * @param pfMouseFeatures Where to store host mouse capabilities. 1236 * @param pX Where to store X axis coordinate. 1237 * @param pY Where to store Y axis coordinate. 1238 * @param pDz Where to store vertical wheel movement offset (only set if in case of VMMDevReq_GetMouseStatusEx request). 1239 * @param pDw Where to store horizontal wheel movement offset (only set if in case of VMMDevReq_GetMouseStatusEx request). 1240 * @param pfButtons Where to store mouse buttons state (only set if in case of VMMDevReq_GetMouseStatusEx request). 1241 */ 1242 static int vgdrvLinuxGetHostMouseState(uint32_t *pfMouseFeatures, int32_t *pX, int32_t *pY, int32_t *pDz, int32_t *pDw, uint32_t *pfButtons) 1243 { 1244 int rc = VERR_INVALID_PARAMETER; 1245 1246 Assert(pfMouseFeatures); 1247 Assert(pX); 1248 Assert(pY); 1249 Assert(pDz); 1250 Assert(pDw); 1251 Assert(pfButtons); 1252 1253 /* Initialize legacy request data. */ 1254 g_pMouseStatusReqEx->Core.mouseFeatures = 0; 1255 g_pMouseStatusReqEx->Core.pointerXPos = 0; 1256 g_pMouseStatusReqEx->Core.pointerYPos = 0; 1257 1258 /* Initialize extended request data if VMMDevReq_GetMouseStatusEx is used. */ 1259 if (vgdrvLinuxUsesMouseStatusEx()) 1260 { 1261 g_pMouseStatusReqEx->dz = 0; 1262 g_pMouseStatusReqEx->dw = 0; 1263 g_pMouseStatusReqEx->fButtons = 0; 1264 } 1265 1266 /* Get host mouse state - either lagacy or extended version. */ 1267 rc = VbglR0GRPerform(&g_pMouseStatusReqEx->Core.header); 1268 if (RT_SUCCESS(rc)) 1269 { 1270 *pfMouseFeatures = g_pMouseStatusReqEx->Core.mouseFeatures; 1271 *pX = g_pMouseStatusReqEx->Core.pointerXPos; 1272 *pY = g_pMouseStatusReqEx->Core.pointerYPos; 1273 1274 /* Get extended mouse state data in case of VMMDevReq_GetMouseStatusEx. */ 1275 if (vgdrvLinuxUsesMouseStatusEx()) 1276 { 1277 *pDz = g_pMouseStatusReqEx->dz; 1278 *pDw = g_pMouseStatusReqEx->dw; 1279 *pfButtons = g_pMouseStatusReqEx->fButtons; 1280 } 1281 } 1282 1283 return rc; 1284 } 1285 #endif /* VBOXGUEST_WITH_INPUT_DRIVER */ 1286 1287 1157 1288 void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt) 1158 1289 { 1159 1290 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 1160 1291 int rc; 1292 uint32_t fMouseFeatures = 0; 1293 int32_t x = 0; 1294 int32_t y = 0; 1295 int32_t dz = 0; 1296 int32_t dw = 0; 1297 uint32_t fButtons = 0; 1161 1298 #endif 1162 1299 NOREF(pDevExt); … … 1171 1308 kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN); 1172 1309 #ifdef VBOXGUEST_WITH_INPUT_DRIVER 1173 /* Report events to the kernel input device */ 1174 g_pMouseStatusReq->mouseFeatures = 0; 1175 g_pMouseStatusReq->pointerXPos = 0; 1176 g_pMouseStatusReq->pointerYPos = 0; 1177 rc = VbglR0GRPerform(&g_pMouseStatusReq->header); 1310 rc = vgdrvLinuxGetHostMouseState(&fMouseFeatures, &x, &y, &dz, &dw, &fButtons); 1178 1311 if (RT_SUCCESS(rc)) 1179 1312 { 1180 input_report_abs(g_pInputDevice, ABS_X, 1181 g_pMouseStatusReq->pointerXPos); 1182 input_report_abs(g_pInputDevice, ABS_Y, 1183 g_pMouseStatusReq->pointerYPos); 1313 input_report_abs(g_pInputDevice, ABS_X, x); 1314 input_report_abs(g_pInputDevice, ABS_Y, y); 1315 1316 if ( vgdrvLinuxUsesMouseStatusEx() 1317 && fMouseFeatures & VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL 1318 && fMouseFeatures & VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL) 1319 { 1320 input_report_rel(g_pInputDevice, REL_WHEEL, dz); 1321 input_report_rel(g_pInputDevice, REL_HWHEEL, dw); 1322 1323 input_report_key(g_pInputDevice, BTN_LEFT, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_LEFT)); 1324 input_report_key(g_pInputDevice, BTN_RIGHT, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_RIGHT)); 1325 input_report_key(g_pInputDevice, BTN_MIDDLE, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_MIDDLE)); 1326 input_report_key(g_pInputDevice, BTN_SIDE, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_X1)); 1327 input_report_key(g_pInputDevice, BTN_EXTRA, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_X2)); 1328 } 1329 1184 1330 # ifdef EV_SYN 1185 1331 input_sync(g_pInputDevice);
Note:
See TracChangeset
for help on using the changeset viewer.