VirtualBox

Changeset 38594 in vbox


Ignore:
Timestamp:
Sep 1, 2011 10:39:43 AM (13 years ago)
Author:
vboxsync
Message:

Additions/linux: kernel input driver for mouse integration, first drop

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c

    r36408 r38594  
    2727#include "the-linux-kernel.h"
    2828#include "VBoxGuestInternal.h"
     29#include <linux/input.h>
    2930#include <linux/miscdevice.h>
    3031#include <linux/poll.h>
     
    136137#endif
    137138
     139/** The input device handle */
     140static struct input_dev        *g_pInputDevice = NULL;
     141/** Is the input device registered? */
     142static bool                     g_fInputDeviceRegistered = false;
     143
    138144/** The file_operations structure. */
    139145static struct file_operations   g_FileOps =
     
    198204MODULE_DEVICE_TABLE(pci, g_VBoxGuestPciId);
    199205
     206static PVBOXGUESTSESSION        g_pKernelSession = NULL;
    200207
    201208/**
     
    375382
    376383
     384enum
     385{
     386    /** The minumum value our device can return */
     387    RANGE_MIN = 0,
     388    /** The maximum value our device can return */
     389    RANGE_MAX = 0xFFFF
     390};
     391
     392
     393static int vboxguestLinuxSetMouseStatus(uint32_t fStatus)
     394{
     395    return VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &g_DevExt,
     396                                g_pKernelSession, &fStatus, sizeof(fStatus),
     397                                NULL);
     398}
     399
     400
     401/**
     402 * Creates the kernel input device.
     403 */
     404static int __init vboxguestLinuxCreateInputDevice(void)
     405{
     406    int rc;
     407
     408    g_pInputDevice = input_allocate_device();
     409    if (!g_pInputDevice)
     410        return -ENOMEM;
     411    g_pInputDevice->id.bustype = BUS_PCI;
     412    g_pInputDevice->id.vendor  = VMMDEV_VENDORID;
     413    g_pInputDevice->id.product = VMMDEV_DEVICEID;
     414    g_pInputDevice->id.version =   (VBOX_VERSION_MAJOR << 11)
     415                                 + (VBOX_VERSION_MINOR << 6)
     416                                 + VBOX_VERSION_BUILD;  /** @todo */
     417    /** @todo parent (PCI?) device in device model view. */
     418    /* g_pInputDevice->dev.parent = */
     419    rc = input_register_device(g_pInputDevice);
     420    if (!rc)
     421        g_fInputDeviceRegistered = true;
     422    else
     423        return rc;
     424    /* Do what one of our competitors apparently does as that works. */
     425    g_pInputDevice->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
     426    __set_bit(BTN_MOUSE, g_pInputDevice->keybit);
     427    input_set_abs_params(g_pInputDevice, ABS_X, RANGE_MIN, RANGE_MAX, 0, 0);
     428    input_set_abs_params(g_pInputDevice, ABS_Y, RANGE_MIN, RANGE_MAX, 0, 0);
     429    /** @todo this string should be in a header file somewhere. */
     430    g_pInputDevice->name = "VirtualBox mouse integration";
     431    vboxguestLinuxSetMouseStatus(  VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
     432                                 | VMMDEV_MOUSE_NEW_PROTOCOL);
     433    return rc;
     434}
     435
     436
     437/**
     438 * Terminates the kernel input device.
     439 */
     440static void vboxguestLinuxTermInputDevice(void)
     441{
     442    vboxguestLinuxSetMouseStatus(0);
     443    if (g_fInputDeviceRegistered)
     444    {
     445        input_unregister_device(g_pInputDevice);
     446        g_fInputDeviceRegistered = false;
     447    }
     448    if (g_pInputDevice)
     449    {
     450        input_free_device(g_pInputDevice);
     451        g_pInputDevice = NULL;
     452    }
     453}
     454
     455
    377456/**
    378457 * Creates the device nodes.
     
    435514    misc_deregister(&g_MiscDeviceUser);
    436515}
    437 
    438516
    439517
     
    516594            {
    517595                /*
    518                  * Finally, create the device nodes.
     596                 * Create the kernel session for this driver.
    519597                 */
    520                 rc = vboxguestLinuxInitDeviceNodes();
    521                 if (rc >= 0)
     598                rc = VBoxGuestCreateKernelSession(&g_DevExt,
     599                                                  &g_pKernelSession);
     600                if (RT_SUCCESS(rc))
    522601                {
    523                     /* some useful information for the user but don't show this on the console */
    524                     LogRel((DEVICE_NAME ": major %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n",
    525                             g_iModuleMajor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
    526                     printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
    527                            VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n");
    528                     return rc;
     602                    /*
     603                     * Create the kernel input device.
     604                     */
     605                    rc = vboxguestLinuxCreateInputDevice();
     606                    if (rc >= 0)
     607                    {
     608                        /*
     609                         * Finally, create the device nodes.
     610                         */
     611                        rc = vboxguestLinuxInitDeviceNodes();
     612                        if (rc >= 0)
     613                        {
     614                            /* some useful information for the user but don't show this on the console */
     615                            LogRel((DEVICE_NAME ": major %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n",
     616                                    g_iModuleMajor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
     617                            printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
     618                                   VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n");
     619                            return rc;
     620                        }
     621
     622                        /* bail out */
     623                        vboxguestLinuxTermInputDevice();
     624                    }
     625                    else
     626                    {
     627                        LogRel((DEVICE_NAME ": vboxguestCreateInputDevice failed with rc=%Rrc\n", rc));
     628                        rc = RTErrConvertFromErrno(rc);
     629                    }
     630                    VBoxGuestCloseSession(&g_DevExt, g_pKernelSession);
    529631                }
    530 
    531                 /* bail out */
    532632                VBoxGuestDeleteDevExt(&g_DevExt);
    533633            }
     
    557657     */
    558658    vboxguestLinuxTermDeviceNodes();
     659    vboxguestLinuxTermInputDevice();
     660    VBoxGuestCloseSession(&g_DevExt, g_pKernelSession);
    559661    VBoxGuestDeleteDevExt(&g_DevExt);
    560662    vboxguestLinuxTermISR();
     
    776878void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
    777879{
     880    VMMDevReqMouseStatus *pReq;
     881    int rc;
    778882    NOREF(pDevExt);
    779883
     
    786890    Log(("VBoxGuestNativeISRMousePollEvent: kill_fasync\n"));
    787891    kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN);
     892    /* Report events to the kernel input device */
     893    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_GetMouseStatus);
     894    if (RT_SUCCESS(rc))
     895    {
     896        pReq->mouseFeatures = 0;
     897        pReq->pointerXPos = 0;
     898        pReq->pointerYPos = 0;
     899        rc = VbglGRPerform(&pReq->header);
     900        input_report_abs(g_pInputDevice, ABS_X, pReq->pointerXPos);
     901        input_report_abs(g_pInputDevice, ABS_Y, pReq->pointerYPos);
     902        VbglGRFree(&pReq->header);
     903    }
    788904    Log(("VBoxGuestNativeISRMousePollEvent: done\n"));
    789905}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette