⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
字号:
/*!  \file  MouseServer  \brief class Mouse information  Copyright (c) 2004 Higepon  All rights reserved.  License=MIT/X Licnese  \author  HigePon  \version $Revision: 1.33 $  \date   create:2004/02/08 update:$Date: 2004/08/26 12:02:56 $*/#include <monapi.h>#include <monalibc.h>#include <monapi/messages.h>using namespace MonAPI;#define INIT_PROCESS "MONITOR.BIN"/*----------------------------------------------------------------------    Mouse Server----------------------------------------------------------------------*/class Mouse{  public:    static int init();    static int waitWritable();    static int waitReadable();    static void enable();    static void disable();    static void enableKeyboard();    static void disableKeyboard();  public:    static const int MOUSE_TIMEOUT = 50000;};/*----------------------------------------------------------------------    Mouse Server----------------------------------------------------------------------*/class MouseServer{public:    MouseServer();    virtual ~MouseServer();public:    bool Initialize();    void MessageLoop();protected:    void Paint();    bool SendServerOK();    void SendMouseInformation();    void PaintCursor(int x, int y);    int GetMouseData();    bool SetCurosor();private:    bool needPaint;    int disableCount;    int posX, posY, prevX, prevY;    char dx, dy;    byte button, prevButton;    int w, h;    Screen* screen;    Screen* vscreen;    List<dword>* destList;};/*----------------------------------------------------------------------    Private variables----------------------------------------------------------------------*/static CommonParameters* commonParams;static MouseServer* server;/*----------------------------------------------------------------------    Mouse----------------------------------------------------------------------*/int Mouse::init(){    byte data;    outp8(0x64, 0x20);    if (waitReadable())    {        return 1;    }    data = inp8(0x60);    outp8(0x64, 0x60);    if (waitWritable())    {        return 2;    }    outp8(0x60, data & (~0x30) | 0x3);    if (!waitReadable())    {        inp8(0x60);    }    outp8(0x64, 0xd4);    if (waitWritable())    {        return 4;    }    outp8(0x60, 0xf4);    if (waitReadable())    {        return 5;    }    inp8(0x60);    return 0;}int Mouse::waitWritable() {    byte status;    int i;    for (i = 0, status = inp8(0x64); i < MOUSE_TIMEOUT; i++, status = inp8(0x64)) {        /* writable */        if ((status & 0x03) == 0x00) {            break;        }    }    return (i == MOUSE_TIMEOUT) ? -1 : 0;}int Mouse::waitReadable() {    byte status;    int i;    for (i = 0, status = inp8(0x64); i < MOUSE_TIMEOUT; i++, status = inp8(0x64)) {        /* readable */        if ((status & 0x01) == 0x01) {            break;        }    }    return (i == MOUSE_TIMEOUT) ? -1 : 0;}void Mouse::enable(){    /* enable mouse interrupt slave unmask */    outp8(0x21, (inp8(0x21) & 0xFB)); /* IR2 cascade */    outp8(0xA1, (inp8(0xA1) & 0xEF)); /* IR4         */}void Mouse::disable(){    outp8(0xA1, inp8(0xA1) | 0x10);}void Mouse::disableKeyboard(){    outp8(0x21, inp8(0x21) | 0x02);}void Mouse::enableKeyboard(){    outp8(0x21, inp8(0x21) & 0xFD);}/*----------------------------------------------------------------------    MouseServer----------------------------------------------------------------------*/MouseServer::MouseServer() : needPaint(false), disableCount(0){}MouseServer::~MouseServer(){    delete this->screen;    delete this->vscreen;}bool MouseServer::Initialize(){    MessageInfo msg;    if (Message::sendReceive(&msg, monapi_get_server_thread_id(ID_PROCESS_SERVER), MSG_PROCESS_GET_COMMON_PARAMS) != 0)    {        syscall_print("MouseServer: can not get common parameters\n");        return false;    }    commonParams = (CommonParameters*)MemoryMap::map(msg.arg2);    /* mouse information destination list */    this->destList = new HList<dword>();    if (this->destList == NULL)    {        syscall_print("MouseServer: destList error\n");        return false;    }    /* create screen */    this->screen  = new Screen();    this->vscreen = new VirtualScreen(40 * 1024);    if (this->screen == NULL || this->vscreen == NULL)    {        printf("MouseServer: screen error\n");        return false;    }    /* screen size */    this->w = screen->getWidth();    this->h = screen->getHeight();    /* draw mouse cursor to virtual screen */    for (int i = 0; i < 5; i++)    {        this->vscreen->fillRect16(0, i, i + 1, 1, Color::rgb(0x00, 0xCC, 0x56));    }    for (int i = 0; i < 2; i++)    {        this->vscreen->fillRect16(0, i + 5, 2 - i, 1, Color::rgb(0x00, 0xCC, 0x56));    }    /* cursor to center */    commonParams->mouse.x = this->posX = this->prevX = this->w / 2;    commonParams->mouse.y = this->posY = this->prevY = this->h / 2;    commonParams->mouse.buttons = this->button = this->prevButton = 0;    /* server start ok */    if (!SendServerOK()) return false;    PaintCursor(this->posX, this->posY);    return true;}void MouseServer::MessageLoop(){    MessageInfo receive;    for (;;)    {        if (Message::receive(&receive)) continue;        switch(receive.header)        {        case MSG_MOUSE_REGIST_TO_SERVER:            /* arg1 = tid */            this->destList->add(receive.arg1);            Message::reply(&receive);            break;        case MSG_MOUSE_UNREGIST_FROM_SERVER:            /* arg1 = tid */            this->destList->remove(receive.arg1);            Message::reply(&receive);            break;       case MSG_MOUSE_ENABLE_CURSOR:            if (this->disableCount > 0)            {                disableCount--;                PaintCursor(this->prevX, this->prevY);            }            Message::reply(&receive);            break;        case MSG_MOUSE_DISABLE_CURSOR:            PaintCursor(this->prevX, this->prevY);            disableCount++;            Message::reply(&receive);            break;        case MSG_MOUSE_GET_CURSOR_POSITION:            Message::reply(&receive, this->prevX, this->prevY);            break;        case MSG_INTERRUPTED:            /* we get not all data */            if (GetMouseData() != 2) break;            /* state not changed. */            if (!SetCurosor()) break;            Paint();            SendMouseInformation();            break;        default:            /* ignore */            printf("mouse:header=%x", receive.header);            break;        }    }}bool MouseServer::SetCurosor(){    /* mouse info */    this->posX += (int)(((double)dx) * 1.5);    this->posY += (int)(((double)dy) * 1.5);    /* mouse cursor size */    if (this->posX >= this->w) this->posX = this->w - 1;    if (this->posY >= this->h) this->posY = this->h - 1;    if (this->posX < 0) this->posX = 0;    if (this->posY < 0) this->posY = 0;    /* mouse state changed? */    return ((this->prevButton != this->button) || ((this->prevX != this->posX || this->prevY != this->posY)));}int MouseServer::GetMouseData(){    static int state = 0;    byte data = inp8(0x60);    if(state == 0 && !(data & 0x08)) return -1;    switch(state & 3)    {    case 0:        this->button = (data & 0x01) | (data & 0x02);        state = 1;        this->needPaint = false;        break;    case 1:        this->dx = data;        state = 2;        break;    case 2:        this->dy = -1 * data;        state = 0;        this->needPaint = true;        break;    }    return state & 3;}void MouseServer::Paint(){    PaintCursor(this->prevX, this->prevY);    PaintCursor(this->posX , this->posY);    commonParams->mouse.x = this->prevX = this->posX;    commonParams->mouse.y = this->prevY = this->posY;    commonParams->mouse.buttons = this->prevButton = this->button;}void MouseServer::SendMouseInformation(){    MessageInfo info;    Message::create(&info, MSG_MOUSE_INFO, this->posX, this->posY, this->button);    for (int i = this->destList->size() - 1; i >= 0; i--)    {        if (Message::send(this->destList->get(i), &info))        {            printf("Mouse:send error to thread id = %x", this->destList->get(i));            this->destList->removeAt(i);        }    }}bool MouseServer::SendServerOK(){    dword targetID = Message::lookupMainThread(INIT_PROCESS);    if (targetID == THREAD_UNKNOWN)    {        printf("MouseServer:MONITER not found\n");        return false;    }    if (Message::send(targetID, MSG_SERVER_START_OK))    {        printf("MouseServer:server start send error\n");        return false;    }    return true;}void MouseServer::PaintCursor(int x, int y){    if (this->disableCount > 0) return;    Screen::bitblt(screen, x, y, 5, 7, vscreen, 0, 0, Raster::XOR);}/*----------------------------------------------------------------------    Main----------------------------------------------------------------------*/int MonaMain(List<char*>* pekoe){    /* allow I/O from user mode */    syscall_get_io();    Mouse::disable();    Mouse::disableKeyboard();    /* Mouse init */    int mouse = Mouse::init();    if (mouse)    {        printf("Mouse init error=%d\n", mouse);        return -1;    }    /* Mouse server initialize */    server = new MouseServer();    if (!server->Initialize())    {        syscall_print("MouseServer: initialize error\n");        return -1;    }    Mouse::enable();    Mouse::enableKeyboard();    /* we receive MSG_INTERRUPTED from IRQ12 Handler */    syscall_set_irq_receiver(12);    /* service start */    server->MessageLoop();    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -