--- /dev/null
+\r
+#include "core.h"\r
+\r
+uint mouse_data0;\r
+DATA_FIFO32 *mouse_fifo;\r
+uint mouse_retv;\r
+\r
+uchar Mouse_Pattern_Standard[24][24] = {\r
+ ".**.....................",\r
+ "*O**....................",\r
+ "*OO**...................",\r
+ "*OOO**..................",\r
+ "*OOOO**.................",\r
+ "*OOOOO**................",\r
+ "*OOOOOO**...............",\r
+ "*OOOOOOO**..............",\r
+ "*OOOOOOOO**.............",\r
+ "*OOOOOOOOO**............",\r
+ "*OOOOOOOOOO**...........",\r
+ "*OOOOOOOOOOO**..........",\r
+ "*OOOOOOOOOOOO**.........",\r
+ "*OOOOOOOOOOOOO**........",\r
+ "*OOOOOOOOOOOOOO**.......",\r
+ "*OOOOOOOOOOOOOOO**......",\r
+ "*OOOOOOOOOOOOOOOO**.....",\r
+ "*OOOOOO************.....",\r
+ "*OOOOO**................",\r
+ "*OOOO**.................",\r
+ "*OOO**..................",\r
+ "*OO**...................",\r
+ "*O**....................",\r
+ "***.....................",\r
+};\r
+\r
+IO_MouseControl *Initialize_Mouse(void)\r
+{\r
+ IO_MouseControl *mctrl;\r
+\r
+ mouse_data0 = 0;\r
+ mouse_fifo = Null;\r
+ mouse_retv = 0;\r
+\r
+ mctrl = (IO_MouseControl *)System_Memory_Allocate(sizeof(IO_MouseControl));\r
+\r
+ IO_CLI();\r
+ System_GateDescriptor_Set(0x2c, (uint)asm_InterruptHandler2c, 0x02, AR_INTGATE32);\r
+ ProgrammableInterruptController_InterruptMask_Clear(0x0c);\r
+ IO_STI();\r
+\r
+ return mctrl;\r
+}\r
+\r
+void InterruptHandler2c(uint *esp)\r
+{\r
+ uint data;\r
+\r
+ data = IO_In8(PORT_KEYDATA);\r
+\r
+ ProgrammableInterruptController_InterruptRequest_Complete(0x0c);\r
+\r
+ if(mouse_fifo != 0){\r
+ FIFO32_Put(mouse_fifo, data + mouse_data0);\r
+ }\r
+\r
+ if(data == KEYDATA_ACK || data == KEYDATA_RESEND){\r
+ mouse_retv = data;\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Mouse_Set_ReceiveFIFO(DATA_FIFO32 *fifo, uint data0)\r
+{\r
+ mouse_data0 = data0;\r
+ mouse_fifo = fifo;\r
+\r
+ return; \r
+}\r
+\r
+void Mouse_SendCommand(uint cmd)\r
+{\r
+ KeyboardController_Wait_SendReady();\r
+ IO_Out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);\r
+\r
+ for(;;){\r
+ mouse_retv = 0;\r
+ KeyboardController_Wait_SendReady();\r
+ IO_Out8(PORT_KEYDATA, cmd);\r
+ for(;;){\r
+ if(mouse_retv == KEYDATA_ACK){\r
+ return;\r
+ }\r
+ if(mouse_retv == KEYDATA_RESEND){\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+UI_MouseCursor *MouseCursor_Initialize(UI_Sheet *parent)\r
+{\r
+ UI_MouseCursor *mcursor;\r
+ uint x, y;\r
+\r
+ if(parent == Null){\r
+ return Null;\r
+ }\r
+\r
+ mcursor = System_Memory_Allocate(sizeof(UI_MouseCursor));\r
+ mcursor->cursor_sheet = Sheet_Initialize();\r
+\r
+ mcursor->cursors[0] = System_Memory_Allocate(24 * 24 * (8 >> 3));\r
+ for(y = 0; y < 24; y++){\r
+ for(x = 0; x < 24; x++){\r
+ if(Mouse_Pattern_Standard[y][x] == '.'){\r
+ (mcursor->cursors[0])[y * 24 + x] = RGB_32_To_08(0x00ff00);\r
+ } else if(Mouse_Pattern_Standard[y][x] == 'O'){\r
+ (mcursor->cursors[0])[y * 24 + x] = RGB_32_To_08(0xffffff);\r
+ } else if(Mouse_Pattern_Standard[y][x] == '*'){\r
+ (mcursor->cursors[0])[y * 24 + x] = RGB_32_To_08(0x000000);\r
+ }\r
+ }\r
+ }\r
+\r
+ Sheet_SetBuffer(mcursor->cursor_sheet, mcursor->cursors[0], 24, 24, 8);\r
+ Sheet_SetParent(mcursor->cursor_sheet, parent);\r
+ Sheet_Enable_InvisibleColor(mcursor->cursor_sheet, 0x00ff00);\r
+ Sheet_SetTopmost(mcursor->cursor_sheet, True);\r
+ Sheet_Slide_Absolute(mcursor->cursor_sheet, mcursor->cursor_sheet->parent->size.x >> 1, mcursor->cursor_sheet->parent->size.y >> 1);\r
+\r
+ return mcursor;\r
+}\r
+\r
+uint MouseCursor_Show(UI_MouseCursor *mcursor)\r
+{\r
+ if(mcursor == Null){\r
+ return 1;\r
+ }\r
+\r
+ if(mcursor->cursor_sheet->location.x < 0){\r
+ mcursor->cursor_sheet->location.x = 0;\r
+ } else if((uint)mcursor->cursor_sheet->location.x > mcursor->cursor_sheet->parent->size.x - 1){\r
+ mcursor->cursor_sheet->location.x = mcursor->cursor_sheet->parent->size.x - 1;\r
+ }\r
+\r
+ if(mcursor->cursor_sheet->location.y < 0){\r
+ mcursor->cursor_sheet->location.y = 0;\r
+ } else if((uint)mcursor->cursor_sheet->location.y > mcursor->cursor_sheet->parent->size.y - 1){\r
+ mcursor->cursor_sheet->location.y = mcursor->cursor_sheet->parent->size.y - 1;\r
+ }\r
+\r
+ Sheet_Show(mcursor->cursor_sheet, SHEET_MAX_CHILDREN, SHEET_LOCATION_NOCHANGE, SHEET_LOCATION_NOCHANGE);\r
+\r
+ return 0;\r
+}\r
+\r
+uint MouseCursor_Move_Relative(UI_MouseCursor *mcursor, int rpx, int rpy)\r
+{\r
+ if(mcursor == Null){\r
+ return 1;\r
+ }\r
+\r
+ rpx += mcursor->cursor_sheet->location.x;\r
+ rpy += mcursor->cursor_sheet->location.y;\r
+\r
+ if(rpx < 0){\r
+ rpx = 0;\r
+ } else if((uint)rpx > mcursor->cursor_sheet->parent->size.x - 1){\r
+ rpx = mcursor->cursor_sheet->parent->size.x - 1;\r
+ }\r
+\r
+ if(rpy < 0){\r
+ rpy = 0;\r
+ } else if((uint)rpy > mcursor->cursor_sheet->parent->size.y - 1){\r
+ rpy = mcursor->cursor_sheet->parent->size.y - 1;\r
+ }\r
+\r
+ Sheet_Slide_Absolute(mcursor->cursor_sheet, rpx, rpy);\r
+\r
+ return 0;\r
+}\r
+\r
+uint MouseCursor_Move_Absolute(UI_MouseCursor *mcursor, int apx, int apy)\r
+{\r
+ if(mcursor == Null){\r
+ return 1;\r
+ }\r
+\r
+ if(apx < 0){\r
+ apx = 0;\r
+ } else if((uint)apx > mcursor->cursor_sheet->parent->size.x - 1){\r
+ apx = mcursor->cursor_sheet->parent->size.x - 1;\r
+ }\r
+\r
+ if(apy < 0){\r
+ apy = 0;\r
+ } else if((uint)apy > mcursor->cursor_sheet->parent->size.y - 1){\r
+ apy = mcursor->cursor_sheet->parent->size.y - 1;\r
+ }\r
+\r
+ Sheet_Slide_Absolute(mcursor->cursor_sheet, apx, apy);\r
+\r
+ return 0;\r
+}\r
+\r
+bool Mouse_Decode(IO_MouseControl *mctrl, uint data)\r
+{\r
+ switch(mctrl->decode_phase){\r
+//マウス初期化及びスクロールマウス識別\r
+ case 0:\r
+ Mouse_SendCommand(MOUSECMD_RESET);\r
+ mctrl->decode_phase++;\r
+ break;\r
+ case 1:\r
+ if(data == KEYDATA_ACK){\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 2:\r
+ if(data == KEYDATA_TEST_SUCCEEDED){\r
+ Mouse_SendCommand(MOUSECMD_SET_SAMPLE_RATE);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 3:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(200);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 4:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(MOUSECMD_SET_SAMPLE_RATE);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 5:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(100);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 6:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(MOUSECMD_SET_SAMPLE_RATE);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 7:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(80);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 8:\r
+ if(data == KEYDATA_ACK){\r
+ Mouse_SendCommand(MOUSECMD_GET_DEVICE_ID);\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 9:\r
+ if(data == KEYDATA_ACK){\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 10:\r
+ if(data == MOUSE_TYPE_3BUTTON){\r
+ mctrl->decode_phase = 20;\r
+ Mouse_SendCommand(MOUSECMD_ENABLE_DATA_REPORTING);\r
+ } else if(data == MOUSE_TYPE_3BUTTON_SCROLL){\r
+ mctrl->flags.scroll = True;\r
+ mctrl->decode_phase = 30;\r
+ Mouse_SendCommand(MOUSECMD_ENABLE_DATA_REPORTING);\r
+ }\r
+ break;\r
+//3ボタンマウス解析\r
+ case 20:\r
+ if(data == KEYDATA_ACK){\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 21:\r
+ //1バイト目が、00XY1CRLの形式になっているかどうかチェック\r
+ //0xc8=11001000なので、ANDすると必ず00001000になるはずである\r
+ if((data & 0xc8) == 0x08){ //1バイト目が、00xx1xxxの形式になっているかどうかチェック 0xc8=11001000なので、ANDすると必ず00001000になるはずである\r
+ mctrl->decode_buf[0] = data;\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 22:\r
+ mctrl->decode_buf[1] = data;\r
+ mctrl->decode_phase++;\r
+ break;\r
+ case 23:\r
+ mctrl->decode_buf[2] = data;\r
+ mctrl->decode_phase = 21;\r
+ mctrl->button.button = mctrl->decode_buf[0] & 0x07;\r
+ mctrl->move.x = mctrl->decode_buf[1];\r
+ mctrl->move.y = mctrl->decode_buf[2];\r
+ if(mctrl->decode_buf[0] & 0x10){\r
+ mctrl->move.x |= 0xffffff00;\r
+ }\r
+ if(mctrl->decode_buf[0] & 0x20){\r
+ mctrl->move.y |= 0xffffff00;\r
+ }\r
+ mctrl->move.y = -mctrl->move.y;\r
+ return True;\r
+//3ボタンスクロールマウス解析\r
+ case 30:\r
+ if(data == KEYDATA_ACK){\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 31:\r
+ //1バイト目が、00XY1CRLの形式になっているかどうかチェック\r
+ //0xc8=11001000なので、ANDすると必ず00001000になるはずである\r
+ if((data & 0xc8) == 0x08){ //1バイト目が、00xx1xxxの形式になっているかどうかチェック 0xc8=11001000なので、ANDすると必ず00001000になるはずである\r
+ mctrl->decode_buf[0] = data;\r
+ mctrl->decode_phase++;\r
+ }\r
+ break;\r
+ case 32:\r
+ mctrl->decode_buf[1] = data;\r
+ mctrl->decode_phase++;\r
+ break;\r
+ case 33:\r
+ mctrl->decode_buf[2] = data;\r
+ mctrl->button.button = mctrl->decode_buf[0] & 0x07;\r
+ mctrl->move.x = mctrl->decode_buf[1];\r
+ mctrl->move.y = mctrl->decode_buf[2];\r
+ if(mctrl->decode_buf[0] & 0x10){\r
+ mctrl->move.x |= 0xffffff00;\r
+ }\r
+ if(mctrl->decode_buf[0] & 0x20){\r
+ mctrl->move.y |= 0xffffff00;\r
+ }\r
+ mctrl->move.y = -mctrl->move.y;\r
+ mctrl->decode_phase++;\r
+ break;\r
+ case 34:\r
+ //はりぼて友の会などの資料には、スクロール情報は下位4バイトだけ有効であると書かれていたが、どうやら8バイト全て有効なようである。\r
+ mctrl->decode_buf[3] = data;\r
+ mctrl->decode_phase = 31;\r
+ mctrl->scroll = mctrl->decode_buf[3];\r
+ if(mctrl->scroll & 0x80){\r
+ mctrl->scroll |= 0xffffff00;\r
+ }\r
+ #ifdef CHNOSPROJECT_DEBUG_MOUSE\r
+ debug("Mouse_Decode:case34:data=0x%02X scroll=%d\n", data, mctrl->scroll);\r
+ #endif\r
+ return True;\r
+ }\r
+\r
+ return False;\r
+}\r