Permalink
Browse files

testing: HW mouse pointer

  • Loading branch information...
popcornmix committed Jun 25, 2015
1 parent 7571e1c commit e2bdab4e469084060db0379fade602f30e82aa81
@@ -193,7 +193,9 @@ void CGUIWindowManager::CreateWindows()
Add(new CGUIWindowAddonBrowser);
Add(new CGUIWindowScreensaverDim);
Add(new CGUIWindowDebugInfo);
#ifndef TARGET_RASPBERRY_PI
Add(new CGUIWindowPointer);
#endif
Add(new CGUIDialogYesNo);
Add(new CGUIDialogProgress);
Add(new CGUIDialogExtendedProgressBar);
@@ -28,13 +28,41 @@
#include "cores/omxplayer/OMXImage.h"
#include "guilib/GraphicContext.h"
#include "settings/DisplaySettings.h"
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include "rpi_user_vcsm.h"
#define MAJOR_NUM 100
#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
#define DEVICE_FILE_NAME "/dev/vcio"
typedef struct gpu_mem_ptr_s {
void *arm; // Pointer to memory mapped on ARM side
int vc_handle; // Videocore handle of relocatable memory
int vcsm_handle; // Handle for use by VCSM
int vc; // Address for use in GPU code
int numbytes; // Size of memory block
int suballoc;
} GPU_MEM_PTR_T;
static int mbox_open();
static void mbox_close(int file_desc);
static void gpu_free_internal(GPU_MEM_PTR_T *p, int mb);
static int gpu_malloc_uncached_internal(int numbytes, GPU_MEM_PTR_T *p, int mb);
CRBP::CRBP()
{
m_initialized = false;
m_omx_initialized = false;
m_DllBcmHost = new DllBcmHost();
m_OMX = new COMXCore();
m_display = DISPMANX_NO_HANDLE;
m_p = NULL;
m_mb = mbox_open();
vcsm_init();
}
CRBP::~CRBP()
@@ -118,7 +146,10 @@ void CRBP::LogFirmwareVerison()
DISPMANX_DISPLAY_HANDLE_T CRBP::OpenDisplay(uint32_t device)
{
if (m_display == DISPMANX_NO_HANDLE)
{
m_display = vc_dispmanx_display_open( 0 /*screen*/ );
init_cursor();
}
return m_display;
}
@@ -127,6 +158,7 @@ void CRBP::CloseDisplay(DISPMANX_DISPLAY_HANDLE_T display)
assert(display == m_display);
vc_dispmanx_display_close(m_display);
m_display = DISPMANX_NO_HANDLE;
uninit_cursor();
}
void CRBP::GetDisplaySize(int &width, int &height)
@@ -227,6 +259,15 @@ void CRBP::Deinitialize()
m_omx_image_init = false;
m_initialized = false;
m_omx_initialized = false;
uninit_cursor();
if (m_mb && m_p)
gpu_free_internal(m_p, m_mb);
delete m_p;
m_p = NULL;
if (m_mb)
mbox_close(m_mb);
m_mb = 0;
vcsm_exit();
}
double CRBP::AdjustHDMIClock(double adjust)
@@ -255,4 +296,217 @@ void CRBP::ResumeVideoOutput()
CLog::Log(LOGDEBUG, "Raspberry PI resuming video output\n");
}
static int mbox_property(int file_desc, void *buf)
{
int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf);
if (ret_val < 0) {
printf("ioctl_set_msg failed:%d\n", ret_val);
}
return ret_val;
}
static int mbox_open()
{
int file_desc;
// open a char device file used for communicating with kernel mbox driver
file_desc = open(DEVICE_FILE_NAME, 0);
if (file_desc < 0) {
printf("Can't open device file: %s (%d)\n", DEVICE_FILE_NAME, file_desc);
printf("Try creating a device file with: sudo mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
}
return file_desc;
}
static void mbox_close(int file_desc)
{
close(file_desc);
}
static unsigned mem_lock(int file_desc, unsigned handle)
{
int i=0;
unsigned p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000d; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = handle;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
mbox_property(file_desc, p);
return p[5];
}
unsigned mem_unlock(int file_desc, unsigned handle)
{
int i=0;
unsigned p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x3000e; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 4; // (size of the data)
p[i++] = handle;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
mbox_property(file_desc, p);
return p[5];
}
unsigned int mailbox_set_cursor_info(int file_desc, int width, int height, int format, uint32_t buffer, int hotspotx, int hotspoty)
{
int i=0;
unsigned int p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x00008010; // set cursor state
p[i++] = 24; // buffer size
p[i++] = 24; // data size
p[i++] = width;
p[i++] = height;
p[i++] = format;
p[i++] = buffer; // ptr to VC memory buffer. Doesn't work in 64bit....
p[i++] = hotspotx;
p[i++] = hotspoty;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof(*p); // actual size
mbox_property(file_desc, p);
return p[5];
}
unsigned int mailbox_set_cursor_position(int file_desc, int enabled, int x, int y)
{
int i=0;
unsigned p[32];
p[i++] = 0; // size
p[i++] = 0x00000000; // process request
p[i++] = 0x00008011; // set cursor state
p[i++] = 12; // buffer size
p[i++] = 12; // data size
p[i++] = enabled;
p[i++] = x;
p[i++] = y;
p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size
mbox_property(file_desc, p);
return p[5];
}
static int gpu_malloc_uncached_internal(int numbytes, GPU_MEM_PTR_T *p, int mb)
{
//printf("%s %d\n", __func__, numbytes);
p->numbytes = numbytes;
p->suballoc = 0;
p->vcsm_handle = vcsm_malloc_cache(numbytes, VCSM_CACHE_TYPE_NONE, (char *)"Mouse pointer");
assert(p->vcsm_handle);
p->vc_handle = vcsm_vc_hdl_from_hdl(p->vcsm_handle);
assert(p->vc_handle);
p->arm = vcsm_lock(p->vcsm_handle);
assert(p->arm);
p->vc = mem_lock(mb, p->vc_handle);
assert(p->vc);
return 0;
}
static void gpu_free_internal(GPU_MEM_PTR_T *p, int mb)
{
mem_unlock(mb,p->vc_handle);
vcsm_unlock_ptr(p->arm);
vcsm_free(p->vcsm_handle);
}
#define T 0
#define W 0xffffffff
#define B 0xff000000
const static uint32_t default_cursor_pixels[] =
{
B,B,B,B,B,B,B,B,B,T,T,T,T,T,T,T,
B,W,W,W,W,W,W,B,T,T,T,T,T,T,T,T,
B,W,W,W,W,W,B,T,T,T,T,T,T,T,T,T,
B,W,W,W,W,B,T,T,T,T,T,T,T,T,T,T,
B,W,W,W,W,W,B,T,T,T,T,T,T,T,T,T,
B,W,W,B,W,W,W,B,T,T,T,T,T,T,T,T,
B,W,B,T,B,W,W,W,B,T,T,T,T,T,T,T,
B,B,T,T,T,B,W,W,W,B,T,T,T,T,T,T,
B,T,T,T,T,T,B,W,W,W,B,T,T,T,T,T,
T,T,T,T,T,T,T,B,W,W,W,B,T,T,T,T,
T,T,T,T,T,T,T,T,B,W,W,W,B,T,T,T,
T,T,T,T,T,T,T,T,T,B,W,W,W,B,T,T,
T,T,T,T,T,T,T,T,T,T,B,W,W,W,B,T,
T,T,T,T,T,T,T,T,T,T,T,B,W,W,W,B,
T,T,T,T,T,T,T,T,T,T,T,T,B,W,B,T,
T,T,T,T,T,T,T,T,T,T,T,T,T,B,T,T
};
#undef T
#undef W
#undef B
void CRBP::init_cursor()
{
//printf("%s\n", __func__);
if (!m_mb)
return;
if (!m_p)
{
m_p = new GPU_MEM_PTR_T;
if (m_p)
gpu_malloc_uncached_internal(64 * 64 * 4, m_p, m_mb);
}
if (m_mb && m_p && m_p->arm && m_p->vc)
set_cursor(default_cursor_pixels, 16, 16, 0, 0);
}
void CRBP::set_cursor(const void *pixels, int width, int height, int hotspot_x, int hotspot_y)
{
if (!m_mb || !m_p || !m_p->arm || !m_p->vc || !pixels || width * height > 64 * 64)
return;
//printf("%s %dx%d %p\n", __func__, width, height, pixels);
memcpy(m_p->arm, pixels, width * height * 4);
unsigned int s = mailbox_set_cursor_info(m_mb, width, height, 0, m_p->vc, hotspot_x, hotspot_y);
assert(s == 0);
}
void CRBP::update_cursor(int x, int y, bool enabled)
{
if (!m_mb || !m_p || !m_p->arm || !m_p->vc)
return;
RESOLUTION res = g_graphicsContext.GetVideoResolution();
CRect gui(0, 0, CDisplaySettings::Get().GetResolutionInfo(res).iWidth, CDisplaySettings::Get().GetResolutionInfo(res).iHeight);
CRect display(0, 0, CDisplaySettings::Get().GetResolutionInfo(res).iScreenWidth, CDisplaySettings::Get().GetResolutionInfo(res).iScreenHeight);
int x2 = x * display.Width() / gui.Width();
int y2 = y * display.Height() / gui.Height();
//printf("%s %d,%d (%d)\n", __func__, x, y, enabled);
mailbox_set_cursor_position(m_mb, enabled, x2, y2);
}
void CRBP::uninit_cursor()
{
if (!m_mb || !m_p || !m_p->arm || !m_p->vc)
return;
//printf("%s\n", __func__);
mailbox_set_cursor_position(m_mb, 0, 0, 0);
}
#endif
@@ -41,6 +41,8 @@
#include "threads/CriticalSection.h"
#include "threads/Event.h"
struct gpu_mem_ptr_s;
class CRBP
{
public:
@@ -84,6 +86,14 @@ class CRBP
CEvent m_vsync;
class DllLibOMXCore;
CCriticalSection m_critSection;
struct gpu_mem_ptr_s *m_p;
int m_mb;
public:
void init_cursor();
void set_cursor(const void *pixels, int width, int height, int hotspot_x, int hotspot_y);
void update_cursor(int x, int y, bool enabled);
void uninit_cursor();
};
extern CRBP g_RBP;
Oops, something went wrong.

0 comments on commit e2bdab4

Please sign in to comment.