Commit 64d51c0f authored by Siarhei Siamashka's avatar Siarhei Siamashka
Browse files

Support for sunxi hardware cursor

Hardware cursor is necessary because it is also visible on
top of sunxi disp layers, while software cursor is not.

FIXME: there is one minor problem with negative cursor
positions. The hardware does not support them, so such
positions are just set to 0 for now. In the future this
can be solved better by changing the cursor picture and
showing only the parts which are visible on screen.
parent bf7c7a6c
......@@ -62,6 +62,9 @@ Enable or disable use of the shadow framebuffer layer. Default: on.
Enable rotation of the display. The supported values are "CW" (clockwise,
90 degrees), "UD" (upside down, 180 degrees) and "CCW" (counter clockwise,
270 degrees). Implies use of the shadow framebuffer layer. Default: off.
.TP
.BI "Option \*qHWCursor\*q \*q" boolean \*q
Enable or disable the HW cursor. Default: on.
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__),
X(__miscmansuffix__), fbdevhw(__drivermansuffix__)
......
......@@ -33,4 +33,6 @@ sunxifb_drv_la_SOURCES = \
fbdev.c \
fbdev_priv.h \
sunxi_disp.c \
sunxi_disp.h
sunxi_disp.h \
sunxi_disp_hwcursor.c \
sunxi_disp_hwcursor.h
......@@ -152,7 +152,9 @@ typedef enum {
OPTION_SHADOW_FB,
OPTION_ROTATE,
OPTION_FBDEV,
OPTION_DEBUG
OPTION_DEBUG,
OPTION_HW_CURSOR,
OPTION_SW_CURSOR
} FBDevOpts;
static const OptionInfoRec FBDevOptions[] = {
......@@ -160,6 +162,8 @@ static const OptionInfoRec FBDevOptions[] = {
{ OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE },
{ OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE },
{ OPTION_DEBUG, "debug", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_HW_CURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
......@@ -919,6 +923,24 @@ FBDevScreenInit(SCREEN_INIT_ARGS_DECL)
fPtr->sunxi_disp_private = sunxi_disp_init(xf86FindOptionValue(
fPtr->pEnt->device->options,"fbdev"));
if (!fPtr->sunxi_disp_private)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"failed to enable the use of sunxi display controller\n");
if (!xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE) &&
xf86ReturnOptValBool(fPtr->Options, OPTION_HW_CURSOR, TRUE)) {
fPtr->SunxiDispHardwareCursor_private = SunxiDispHardwareCursor_Init(
pScreen);
if (fPtr->SunxiDispHardwareCursor_private)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"using hardware cursor\n");
else
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"failed to enable hardware cursor\n");
}
TRACE_EXIT("FBDevScreenInit");
return TRUE;
......@@ -930,6 +952,12 @@ FBDevCloseScreen(CLOSE_SCREEN_ARGS_DECL)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
FBDevPtr fPtr = FBDEVPTR(pScrn);
if (fPtr->SunxiDispHardwareCursor_private) {
SunxiDispHardwareCursor_Close(pScreen);
free(fPtr->SunxiDispHardwareCursor_private);
fPtr->SunxiDispHardwareCursor_private = NULL;
}
if (fPtr->sunxi_disp_private) {
sunxi_disp_close(fPtr->sunxi_disp_private);
free(fPtr->sunxi_disp_private);
......
......@@ -49,9 +49,13 @@ typedef struct {
OptionInfoPtr Options;
void *sunxi_disp_private;;
void *SunxiDispHardwareCursor_private;
} FBDevRec, *FBDevPtr;
#define FBDEVPTR(p) ((FBDevPtr)((p)->driverPrivate))
#define SUNXI_DISP(p) ((sunxi_disp_t *) \
(FBDEVPTR(p)->sunxi_disp_private))
#define SUNXI_DISP_HWC(p) ((SunxiDispHardwareCursor *) \
(FBDEVPTR(p)->SunxiDispHardwareCursor_private))
/*
* Copyright © 2013 Siarhei Siamashka <siarhei.siamashka@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86Cursor.h"
#include "sunxi_disp_hwcursor.h"
#include "sunxi_disp.h"
#include "fbdev_priv.h"
static void ShowCursor(ScrnInfoPtr pScrn)
{
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
sunxi_hw_cursor_show(disp);
}
static void HideCursor(ScrnInfoPtr pScrn)
{
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
sunxi_hw_cursor_hide(disp);
}
static void SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
sunxi_hw_cursor_set_position(disp, x, y);
}
static void SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
uint32_t palette[4] = { 0, 0, bg | 0xFF000000, fg | 0xFF000000 };
sunxi_hw_cursor_load_palette(disp, &palette[0]);
}
static void LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
{
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
sunxi_hw_cursor_load_pixeldata(disp, bits);
}
SunxiDispHardwareCursor *SunxiDispHardwareCursor_Init(ScreenPtr pScreen)
{
xf86CursorInfoPtr InfoPtr;
SunxiDispHardwareCursor *private;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
sunxi_disp_t *disp = SUNXI_DISP(pScrn);
if (!disp)
return NULL;
if (!(InfoPtr = xf86CreateCursorInfoRec())) {
ErrorF("SunxiDispHardwareCursor_Init: xf86CreateCursorInfoRec() failed\n");
return NULL;
}
InfoPtr->ShowCursor = ShowCursor;
InfoPtr->HideCursor = HideCursor;
InfoPtr->SetCursorPosition = SetCursorPosition;
InfoPtr->SetCursorColors = SetCursorColors;
InfoPtr->LoadCursorImage = LoadCursorImage;
InfoPtr->MaxWidth = InfoPtr->MaxHeight = 64;
InfoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
HARDWARE_CURSOR_ARGB;
if (!xf86InitCursor(pScreen, InfoPtr)) {
ErrorF("SunxiDispHardwareCursor_Init: xf86InitCursor(pScreen, InfoPtr) failed\n");
xf86DestroyCursorInfoRec(InfoPtr);
return NULL;
}
private = calloc(1, sizeof(SunxiDispHardwareCursor));
if (!private) {
ErrorF("SunxiDispHardwareCursor_Init: calloc failed\n");
xf86DestroyCursorInfoRec(InfoPtr);
return NULL;
}
private->hwcursor = InfoPtr;
return private;
}
void SunxiDispHardwareCursor_Close(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
SunxiDispHardwareCursor *private = SUNXI_DISP_HWC(pScrn);
if (private) {
xf86DestroyCursorInfoRec(private->hwcursor);
}
}
/*
* Copyright © 2013 Siarhei Siamashka <siarhei.siamashka@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef SUNXI_DISP_HWCURSOR_H
#define SUNXI_DISP_HWCURSOR_H
#include "xf86Cursor.h"
typedef struct {
xf86CursorInfoPtr hwcursor;
} SunxiDispHardwareCursor;
SunxiDispHardwareCursor *SunxiDispHardwareCursor_Init(ScreenPtr pScreen);
void SunxiDispHardwareCursor_Close(ScreenPtr pScreen);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment