OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_010 / chnos / mouse.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/mouse.c b/CHNOSProject/chnos/tolset_chn_000/chnos_010/chnos/mouse.c
new file mode 100644 (file)
index 0000000..7f42599
--- /dev/null
@@ -0,0 +1,356 @@
+\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