VESA cursor now works, TODO: Allow setting of colour
[tpg/acess2.git] / Modules / Display / VESA / main.c
index 9d48432..703e708 100644 (file)
@@ -16,6 +16,7 @@
 // === CONSTANTS ===\r
 #define        FLAG_LFB        0x1\r
 #define VESA_DEFAULT_FRAMEBUFFER       (KERNEL_BASE|0xA0000)\r
+#define VESA_CURSOR_PERIOD     1000\r
 \r
 // === PROTOTYPES ===\r
  int   Vesa_Install(char **Arguments);\r
@@ -25,6 +26,7 @@ Uint64        Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   Vesa_Int_SetMode(int Mode);\r
  int   Vesa_Int_FindMode(tVideo_IOCtl_Mode *data);\r
  int   Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data);\r
+void   Vesa_FlipCursor(void *Arg);\r
 // --- 2D Acceleration Functions --\r
 void   Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
 void   Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
@@ -41,13 +43,20 @@ tDevFS_Driver       gVesa_DriverStruct = {
 };\r
 tSpinlock      glVesa_Lock;\r
 tVM8086        *gpVesa_BiosState;\r
+ int   giVesaDriverId = -1;\r
+// --- Video Modes ---\r
  int   giVesaCurrentMode = 0;\r
  int   giVesaCurrentFormat = VIDEO_BUFFMT_TEXT;\r
- int   giVesaDriverId = -1;\r
-char   *gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER;\r
 tVesa_Mode     *gVesa_Modes;\r
  int   giVesaModeCount = 0;\r
- int   giVesaPageCount = 0;\r
+// --- Framebuffer ---\r
+char   *gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER;\r
+ int   giVesaPageCount = 0;    //!< Framebuffer size in pages\r
+// --- Cursor Control ---\r
+ int   giVesaCursorX = -1;\r
+ int   giVesaCursorY = -1;\r
+ int   giVesaCursorTimer = -1; // Invalid timer\r
+// --- 2D Video Stream Handlers ---\r
 tDrvUtil_Video_2DHandlers      gVesa_2DFunctions = {\r
        NULL,\r
        Vesa_2D_Fill,\r
@@ -348,6 +357,22 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)
                return ret;\r
        \r
        case VIDEO_IOCTL_SETCURSOR:     // Set cursor position\r
+               giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x;\r
+               giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y;\r
+               if(\r
+                       giVesaCursorX < 0 || giVesaCursorY < 0\r
+               ||      giVesaCursorX >= gVesa_Modes[giVesaCurrentMode].width\r
+               ||      giVesaCursorY >= gVesa_Modes[giVesaCurrentMode].height)\r
+               {\r
+                       if(giVesaCursorTimer != -1)\r
+                               Time_RemoveTimer(giVesaCursorTimer);\r
+                       giVesaCursorX = -1;\r
+                       giVesaCursorY = -1;\r
+               }\r
+               else {\r
+                       if(giVesaCursorTimer == -1)\r
+                               giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node);\r
+               }\r
                return 0;\r
        \r
        case VIDEO_IOCTL_REQLFB:        // Request Linear Framebuffer\r
@@ -356,6 +381,9 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)
        return 0;\r
 }\r
 \r
+/**\r
+ * \brief Updates the video mode\r
+ */\r
 int Vesa_Int_SetMode(int mode)\r
 {\r
        Log_Log("VESA", "Setting mode to %i", mode);\r
@@ -366,6 +394,8 @@ int Vesa_Int_SetMode(int mode)
        // Check for fast return\r
        if(mode == giVesaCurrentMode)   return 1;\r
        \r
+       Time_RemoveTimer(giVesaCursorTimer);\r
+       \r
        LOCK( &glVesa_Lock );\r
        \r
        gpVesa_BiosState->AX = 0x4F02;\r
@@ -446,6 +476,26 @@ int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data)
        return 1;\r
 }\r
 \r
+/**\r
+ * \brief Updates the state of the text cursor\r
+ * \note Just does a bitwise not on the cursor region\r
+ */\r
+void Vesa_FlipCursor(void *Arg)\r
+{\r
+        int    pitch = gVesa_Modes[giVesaCurrentMode].pitch/4;\r
+        int    x = giVesaCursorX*giVT_CharWidth;\r
+        int    y = giVesaCursorY*giVT_CharHeight;\r
+        int    i;\r
+       Uint32  *fb = (void*)gpVesa_Framebuffer;\r
+       \r
+       if(giVesaCursorX < 0 || giVesaCursorY < 0)      return;\r
+       \r
+       for( i = 1; i < giVT_CharHeight-1; i++ )\r
+               fb[(y+i)*pitch+x] = ~fb[(y+i)*pitch+x];\r
+       \r
+       giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Arg);\r
+}\r
+\r
 // ------------------------\r
 // --- 2D Accelleration ---\r
 // ------------------------\r
@@ -482,7 +532,6 @@ void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY,
        \r
        if( dst > src ) {\r
                // Reverse copy\r
-               Debug("Reverse scroll");\r
                dst += H*scrnpitch;\r
                src += H*scrnpitch;\r
                while( H -- ) {\r
@@ -496,7 +545,6 @@ void Vesa_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY,
        }\r
        else {\r
                // Normal copy is OK\r
-               Debug("memcpy scroll");\r
                while( H -- ) {\r
                        memcpy((void*)gpVesa_Framebuffer + dst, (void*)gpVesa_Framebuffer + src, W*sizeof(Uint32));\r
                        dst += scrnpitch;\r

UCC git Repository :: git.ucc.asn.au