// === 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
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
};\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
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
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
// 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
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
\r
if( dst > src ) {\r
// Reverse copy\r
- Debug("Reverse scroll");\r
dst += H*scrnpitch;\r
src += H*scrnpitch;\r
while( H -- ) {\r
}\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