xaizek / tos (License: GPLv3 only) (since 2018-12-07)
This is an alternative version of sources presented as part of Write Your Own OS video tutorial by Viktor Engelmann.
<root> / src / drv / mouse.cpp (767d38adf64cacc032da3bd8205727b1c782329f) (1,758B) (mode 100644) [raw]
#include "drv/mouse.hpp"

using namespace drv;

void
MouseEventHandler::onActivate()
{
}

void
MouseEventHandler::onMouseDown(std::uint8_t /*button*/)
{
}

void
MouseEventHandler::onMouseUp(std::uint8_t /*button*/)
{
}

void
MouseEventHandler::onMouseMove(int /*dx*/, int /*dy*/)
{
}

MouseDriver::MouseDriver(MouseEventHandler &handler)
    : InterruptHandler(0x2c),
      dataPort(0x60), cmdPort(0x64), offset(0), buttons(0),
      handler(handler)
{
}

void
MouseDriver::activate()
{
    cmdPort.write(0xa8);

    // Update controller command byte.
    cmdPort.write(0x20);
    std::uint8_t status = dataPort.read();
    cmdPort.write(0x60);
    dataPort.write(status | 2);

    cmdPort.write(0xd4);

    // Clear output buffer.
    dataPort.write(0xf4);
    // Wait and read ACK.
    while (!(cmdPort.read() & 0x1)) {
        // Wait.
    }
    dataPort.read();

    handler.onActivate();
}

const char *
MouseDriver::getName() const
{
    return "mouse";
}

std::uint32_t
MouseDriver::handleInterrupt(std::uint32_t esp)
{
    std::uint8_t status = cmdPort.read();
    if (!(status & 0x20)) {
        return esp;
    }

    buffer[offset] = dataPort.read();
    offset = (offset + 1) % 3;

    if (offset != 0) {
        return esp;
    }


    if (buffer[1] != 0 || buffer[2] != 0) {
        handler.onMouseMove(static_cast<std::int8_t>(buffer[1]),
                            -static_cast<std::int8_t>(buffer[2]));
    }

    for (std::uint8_t i = 0; i < 3; ++i) {
        if ((buffer[0] & (0x1 << i)) != (buttons & (0x1 << i))) {
            if (buttons & (0x1 << i)) {
                handler.onMouseUp(i + 1);
            } else {
                handler.onMouseDown(i + 1);
            }
        }
    }
    buttons = buffer[0];

    return esp;
}
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master