今天这里贴出从应用层传出一个id或图片byte[]数组,通过aidl与service交互调用JNI,最后到Cursor.c实现画不同状态的光标。下面就给出Cursor.c的实现画图,前面的过程就不全给出了:
Cursor.c
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "hardware_legacy/cursor.h"#define LOG_TAG "CursorHW"typedef struct{ int id; int width; int height; char *buf;}CURSOR_BITMPA_S;static CURSOR_BITMPA_S g_cursor_data[ID_MAX_BITMAP_NO];static char g_cursor_name[ID_MAX_BITMAP_NO][32] = { "cursor_normal.bmp", "cursor_help.bmp", "cursor_bg.bmp", "cursor_busy.bmp", "cursor_accpos.bmp", "cursor_edit.bmp", "cursor_wait.bmp", "cursor_handwrite.bmp", "cursor_link.bmp", "cursor_disable.bmp",};static int s_cursorfd = -1;//光标的绝对位置static int s_cursor_x = 0;static int s_cursor_y = 0;static int s_screen_width = 0;static int s_memp_size = 0;static char *s_memp_start = NULL;#define CHECK_FD() do { if (s_cursorfd < 0) return -1; } while(0) #define HI_CURSOR_W 32#define HI_CURSOR_H 32#define HI_CURSOR_BPP 32#define HI_CURSOR_STRIDE (HI_CURSOR_BPP*HI_CURSOR_W/8)static char s_Cursordata[12*20*4] = {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, \0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \};static int cursor_load_bitmap(int id);static int cursor_unload_bitmap();int cursor_open(){ int size = 0; int i; HIFB_ALPHA_S as; struct fb_fix_screeninfo finfo; struct fb_var_screeninfo info; /*我们让光标显示在高清图层,为了DDMS截图正确*/ int fd = open("/dev/graphics/fb2", O_RDWR, 0); if(fd > 0) { LOGI("open fb0 ok. fd=%d\n", fd); } else { LOGE("open fb error:\n"); return 1; } if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) { LOGE("info error.\n"); goto quit; } //设置光标大小,像素格式 info.xres = info.xres_virtual = 12; info.yres = info.yres_virtual = 20; info.bits_per_pixel = HI_CURSOR_BPP; info.transp.length = 8; info.transp.msb_right = 0; info.transp.offset = 24; info.red.length = 8; info.red.msb_right = 0; info.red.offset = 16; info.green.length = 8; info.green.msb_right = 0; info.green.offset = 8; info.blue.length = 8; info.blue.msb_right = 0; info.blue.offset = 0; if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { LOGE("info error.\n"); goto quit; } if (ioctl(fd, FBIOGET_ALPHA_HIFB, &as) < 0) { LOGE("get alpha error.\n"); goto quit; } as.bAlphaEnable = HI_TRUE; if (ioctl(fd, FBIOPUT_ALPHA_HIFB, &as) < 0) { LOGE("get alpha error.\n"); goto quit; } if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) { LOGE("finfo error.\n"); goto quit; } //size = info.xres * info.yres * info.bits_per_pixel/8; //----->12*20*32/8=960 size = finfo.smem_len; LOGI("*******size = %d*******", size); s_memp_start = (char*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if((char*)-1 == s_memp_start) { LOGE("mmap error:\n"); goto quit; } s_memp_size = size; s_cursorfd = fd; s_screen_width = finfo.line_length; //copy 光标位图到framebuffer上 cursor_set_visible(0); memset(s_memp_start, 0x0, size); for (i= 0; i<20; i++) { memcpy(s_memp_start + i*s_screen_width, s_Cursordata + 48*i, 48); } cursor_set_visible(1); return 0; quit: cursor_close(); return -1; }int cursor_close(){ if (s_cursorfd > 0) { close(s_cursorfd); s_cursorfd = -1; } cursor_unload_bitmap(); return 0;}int cursor_set_visible(int flag){ CHECK_FD(); //需要考虑范围不要超过屏幕 todo if (ioctl(s_cursorfd, FBIOPUT_SHOW_HIFB, &flag) < 0) { LOGE("failed to %s cursor! \n", flag ? "show":"hide"); } return 0; }int cursor_set_sharp(const char *buf,int w,int h){ int i=0; int width=w,height=h; char *buffer = (char*)buf; char *start = s_memp_start; if(width > HI_CURSOR_W) width = HI_CURSOR_W; if(height > HI_CURSOR_H) height = HI_CURSOR_H; LOGI("width=%d,height=%d",width,height); /* 1、先将光标隐藏掉 */ cursor_set_visible(0); /* 2、将光标数据定入到fb中进行显示(操作共享区) */ memset(s_memp_start, 0x00, s_memp_size); for (i=0; i ID_DISABLE_BITMAP){ LOGE("cursor_set_sharpID error param: id=%d",id); return -1; } ret = cursor_load_bitmap(id); if(ret < 0){ LOGE("cursor_load_bitmap load bitmap failed(id = %d)",id); return -1; } ret = cursor_set_sharp(g_cursor_data[id].buf,g_cursor_data[id].width,g_cursor_data[id].height); if(ret < 0){ LOGE("cursor_set_sharpID set sharp failed"); return -1; } return ret;}static int cursor_bitmpa_format_convert(CURSOR_BITMPA_S *cs,char *src){ int i ,j ; int width = cs->width,height = cs->height; char *psrc = src ; char *pdst = cs->buf; char *p = psrc; int value = 0x00; /* 由于bmp存储是从后面往前面,所以需要倒序进行转换 */ pdst += (width * height * 4); for(i=0;i = 0) { if (ret == 0) { cursor_sleep_millis(1); continue; } if ((len -= ret) == 0) return 0; buf = ((char*) buf) + ret; } return -1;}static int cursor_load_bitmap(int id){ int ret = -1; char *cursor_path = "/system/usr/cursor"; char file_path[128]; FILE *fp = NULL; char bmp_header[54]; int flen , total_length = 0; char *bmp_buf = NULL; int n = 0; if(g_cursor_data[id].buf != NULL){ LOGV("cursor_load_bitmap already load,success!"); return 0; } memset(bmp_header,0x00,sizeof(bmp_header)); /* 读取位图的前面开始的54字节数据 */ snprintf(file_path,128,"%s/%s",cursor_path,g_cursor_name[id]); LOGI("file path = %s",file_path); fp = fopen(file_path,"rb"); if(fp == NULL){ LOGE("load > cursor file open failed"); return -1; } /* 求解文件长度 */ fseek(fp,0,SEEK_SET); fseek(fp,0,SEEK_END); flen = ftell(fp); bmp_buf = (char*)calloc(1,flen - 54); if(bmp_buf == NULL){ LOGE("load > malloc bmp out of memory!"); goto BAIL; } /* 再移位到文件头部 */ fseek(fp,0,SEEK_SET); n = fread(bmp_header,1,54,fp); if(n != 54){ LOGE("load > read bmp header failed failed"); goto BAIL; } g_cursor_data[id].width = bmp_header[18]; g_cursor_data[id].height = bmp_header[22]; LOGV("cursor_load_bitmap:load > bmp width = %d,heigth = %d",g_cursor_data[id].width,g_cursor_data[id].height); /* 24位位图 */ total_length = g_cursor_data[id].width * g_cursor_data[id].height * 3; ret = cursor_load_util_read(fp,bmp_buf,total_length); if(ret != 0) { LOGE("load > read bmp body data failed"); goto BAIL; } /* 32位显示 */ total_length = g_cursor_data[id].width * g_cursor_data[id].height * 4; g_cursor_data[id].buf = (char*)calloc(1,total_length); if(g_cursor_data[id].buf == NULL){ LOGE("load > malloc curosr buf failed"); goto BAIL; } ret = cursor_bitmpa_format_convert(&g_cursor_data[id],bmp_buf); if(ret < 0){ LOGE("load > convert bmp to cursor data failed"); goto BAIL; } g_cursor_data[id].id = id; if(bmp_buf != NULL){ free(bmp_buf); bmp_buf = NULL; } if(fp != NULL){ fclose(fp); fp = NULL; } LOGI("cursor_load_bitmap:load > load bitmap success"); return 0;BAIL: if(bmp_buf != NULL){ free(bmp_buf); bmp_buf = NULL; } if(fp != NULL){ fclose(fp); fp = NULL; } LOGE("cursor_load_bitmap load bitmap failed"); return -1;}static int cursor_unload_bitmap(){ int i = 0,rid = -1; for(i=0;i
注:
1.图片为32*32*24的bmp位图,字节长位3126byte,前54byte为头部信息,其中第16-19个和20-23个字节位为长和高
2.因为这里定义的是32位有透明色的位图,所以加载的24位位图需要转换成32位的-- cursor_bitmpa_format_convert这个方法
3.android java层也可以解析位图,然后传byte[]数据下来,cursor里面直接读取位图byte[]数据。android中的解析方法如下:
private void loadBmpData(){ pic_Curs=new Pic_Cur[10]; String[] cur_name=new String[]{ "cursor_normal.bmp", "cursor_help.bmp", "cursor_bg.bmp", "cursor_busy.bmp", "cursor_accpos.bmp", "cursor_edit.bmp", "cursor_wait.bmp", "cursor_handwrite.bmp", "cursor_link.bmp", "cursor_disable.bmp" }; for(int i=0;i
中间省略aidl与service的交互、jni调用等;之后会在cursor.c里的
int cursor_set_sharp(const char *buf,int w,int h)
把光标显示出来
注:bmp位图可以参考后面的一篇文章:
……O(∩_∩)O~