#if defined(PND)
#include "libpicofe/linux/fbdev.c"
+#include "omapfb.h"
static struct vout_fbdev *fbdev;
static unsigned short host_pal[256];
+static int get_layer_size(int *x, int *y, int *w, int *h)
+{
+ struct omapfb_plane_info pi;
+ int ret;
+
+ ret = ioctl(vout_fbdev_get_fd(fbdev), OMAPFB_QUERY_PLANE, &pi);
+ if (ret != 0) {
+ perror("OMAPFB_QUERY_PLANE");
+ return -1;
+ }
+
+ *x = pi.pos_x;
+ *y = pi.pos_y;
+ *w = pi.out_width;
+ *h = pi.out_height;
+ printf("layer: %d,%d %dx%d\n", *x, *y, *w, *h);
+
+ return 0;
+}
+
void *host_video_flip(void)
{
host_screen = vout_fbdev_flip(fbdev);
host_video_flip();
}
+void host_video_normalize_ts(int *x1024, int *y1024)
+{
+ static int lx, ly, lw = 800, lh = 480, checked;
+
+ if (!checked) {
+ get_layer_size(&lx, &ly, &lw, &lh);
+ checked = 1; // XXX: might change, so may need to recheck
+ }
+ *x1024 = (*x1024 - lx) * 1024 / lw;
+ *y1024 = (*y1024 - ly) * 1024 / lh;
+}
+
#elif defined(WIZ)
#include "warm/warm.c"
}
#endif // LOADER
+void host_video_normalize_ts(int *x1024, int *y1024)
+{
+ *x1024 = *x1024 * 1024 / 320;
+ *y1024 = *y1024 * 1024 / 240;
+}
+
#endif // WIZ
// vim:shiftwidth=2:expandtab
void host_video_blit4(const unsigned char *src, int w, int h, int stride);
void host_video_blit8(const unsigned char *src, int w, int h, int stride);
void host_video_blit16(const unsigned short *src, int w, int h, int stride);
+
+void host_video_normalize_ts(int *x1024, int *y1024);
--- /dev/null
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI__LINUX_OMAPFB_H__
+#define _UAPI__LINUX_OMAPFB_H__
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
+#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
+#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
+#define OMAP_IO(num) _IO('O', num)
+#define OMAPFB_MIRROR OMAP_IOW(31, int)
+#define OMAPFB_SYNC_GFX OMAP_IO(37)
+#define OMAPFB_VSYNC OMAP_IO(38)
+#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
+#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
+#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
+#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
+#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
+#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
+#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
+#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
+#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
+#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
+#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
+#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
+#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
+#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
+#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
+#define OMAPFB_WAITFORGO OMAP_IO(60)
+#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
+#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
+#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
+#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
+#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
+#define OMAPFB_CAPS_PANEL_MASK 0xff000000
+#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
+#define OMAPFB_CAPS_TEARSYNC 0x00002000
+#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
+#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
+#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
+#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
+#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
+#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
+#define OMAPFB_FORMAT_MASK 0x00ff
+#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
+#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
+#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
+#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
+#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
+#define OMAPFB_MEMTYPE_SDRAM 0
+#define OMAPFB_MEMTYPE_SRAM 1
+#define OMAPFB_MEMTYPE_MAX 1
+#define OMAPFB_MEM_IDX_ENABLED 0x80
+#define OMAPFB_MEM_IDX_MASK 0x7f
+enum omapfb_color_format {
+ OMAPFB_COLOR_RGB565 = 0,
+ OMAPFB_COLOR_YUV422,
+ OMAPFB_COLOR_YUV420,
+ OMAPFB_COLOR_CLUT_8BPP,
+ OMAPFB_COLOR_CLUT_4BPP,
+ OMAPFB_COLOR_CLUT_2BPP,
+ OMAPFB_COLOR_CLUT_1BPP,
+ OMAPFB_COLOR_RGB444,
+ OMAPFB_COLOR_YUY422,
+ OMAPFB_COLOR_ARGB16,
+ OMAPFB_COLOR_RGB24U,
+ OMAPFB_COLOR_RGB24P,
+ OMAPFB_COLOR_ARGB32,
+ OMAPFB_COLOR_RGBA32,
+ OMAPFB_COLOR_RGBX32,
+};
+struct omapfb_update_window {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+ __u32 out_x, out_y;
+ __u32 out_width, out_height;
+ __u32 reserved[8];
+};
+struct omapfb_update_window_old {
+ __u32 x, y;
+ __u32 width, height;
+ __u32 format;
+};
+enum omapfb_plane {
+ OMAPFB_PLANE_GFX = 0,
+ OMAPFB_PLANE_VID1,
+ OMAPFB_PLANE_VID2,
+};
+enum omapfb_channel_out {
+ OMAPFB_CHANNEL_OUT_LCD = 0,
+ OMAPFB_CHANNEL_OUT_DIGIT,
+};
+struct omapfb_plane_info {
+ __u32 pos_x;
+ __u32 pos_y;
+ __u8 enabled;
+ __u8 channel_out;
+ __u8 mirror;
+ __u8 mem_idx;
+ __u32 out_width;
+ __u32 out_height;
+ __u32 reserved2[12];
+};
+struct omapfb_mem_info {
+ __u32 size;
+ __u8 type;
+ __u8 reserved[3];
+};
+struct omapfb_caps {
+ __u32 ctrl;
+ __u32 plane_color;
+ __u32 wnd_color;
+};
+enum omapfb_color_key_type {
+ OMAPFB_COLOR_KEY_DISABLED = 0,
+ OMAPFB_COLOR_KEY_GFX_DST,
+ OMAPFB_COLOR_KEY_VID_SRC,
+};
+struct omapfb_color_key {
+ __u8 channel_out;
+ __u32 background;
+ __u32 trans_key;
+ __u8 key_type;
+};
+enum omapfb_update_mode {
+ OMAPFB_UPDATE_DISABLED = 0,
+ OMAPFB_AUTO_UPDATE,
+ OMAPFB_MANUAL_UPDATE
+};
+struct omapfb_memory_read {
+ __u16 x;
+ __u16 y;
+ __u16 w;
+ __u16 h;
+ size_t buffer_size;
+ void *buffer;
+};
+struct omapfb_ovl_colormode {
+ __u8 overlay_idx;
+ __u8 mode_idx;
+ __u32 bits_per_pixel;
+ __u32 nonstd;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+struct omapfb_vram_info {
+ __u32 total;
+ __u32 free;
+ __u32 largest_free_block;
+ __u32 reserved[5];
+};
+struct omapfb_tearsync_info {
+ __u8 enabled;
+ __u8 reserved1[3];
+ __u16 line;
+ __u16 reserved2;
+};
+struct omapfb_display_info {
+ __u16 xres;
+ __u16 yres;
+ __u32 width;
+ __u32 height;
+ __u32 reserved[5];
+};
+#endif
sigaction(SIGSEGV, &segv_action, NULL);
}
-long emu_read_gpiodev(void *buf, int count)
-{
- if (count <= 0) {
- err("gpiodev read %d?\n", count);
- return -EINVAL;
- }
- if (count > 4)
- count = 4;
-
- mmsp2.btn_state = host_read_btns();
- memcpy(buf, &mmsp2.btn_state, count);
- return count;
-}
-
static long emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int offset)
{
u8 *umem, *umem_end;
return -EINVAL;
}
+long emu_do_read(int fd, void *buf, int count)
+{
+ static const char wm97xx_p[] =
+ "5507 0 -831476 0 -4218 16450692 65536"; // from 4.0 fw
+ int ret, pressed = 0, x, y;
+ struct {
+ u16 pressure, x, y;
+ } wm97xx;
+
+ if (count < 0) {
+ err("read(%d, %d)\n", fd, count);
+ return -EINVAL;
+ }
+
+ switch (fd) {
+ case FAKEDEV_GPIO:
+ mmsp2.btn_state = host_read_btns();
+
+ if (count > 4)
+ count = 4;
+ memcpy(buf, &mmsp2.btn_state, count);
+ break;
+ case FAKEDEV_WM97XX:
+ ret = host_read_ts(&pressed, &x, &y);
+ if (ret == 0 && pressed) {
+ wm97xx.pressure = 1;
+ wm97xx.x = x * 3750 / 1024 + 200;
+ wm97xx.y = 3750 - y * 3750 / 1024 + 200;
+ }
+ else {
+ wm97xx.pressure = 0;
+ wm97xx.x = wm97xx.y = 200;
+ }
+
+ if (count > sizeof(wm97xx))
+ count = sizeof(wm97xx);
+ memcpy(buf, &wm97xx, count);
+ break;
+ case FAKEDEV_WM97XX_P:
+ if (count < sizeof(wm97xx_p))
+ err("incomplete pointercal read\n");
+ strncpy(buf, wm97xx_p, count);
+ break;
+ default:
+ err("read(%d, %d)\n", fd, count);
+ return -EINVAL;
+ }
+ return count;
+}
+
struct dev_fd_t emu_interesting_fds[] = {
[IFD_SOUND] = { "/dev/dsp", -1, emu_sound_open },
{ NULL, 0, NULL },
FAKEDEV_FB1,
FAKEDEV_MMUHACK,
FAKEDEV_TTY0,
+ FAKEDEV_WM97XX,
+ FAKEDEV_WM97XX_P,
FAKEDEV_FD_BOUNDARY,
};
long emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
long emu_do_munmap(void *addr, unsigned int length);
long emu_do_ioctl(int fd, int request, void *argp);
-long emu_read_gpiodev(void *buf, int count);
+long emu_do_read(int fd, void *buf, int count);
void *emu_do_fopen(const char *path, const char *mode);
int emu_do_system(const char *command);
long emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
int host_init(void);
int host_read_btns(void);
+int host_read_ts(int *pressed, int *x1024, int *y1024);
void host_forced_exit(int status);
enum { GP2X_UP = 0, GP2X_LEFT = 2, GP2X_DOWN = 4, GP2X_RIGHT = 6,
*/
#define _GNU_SOURCE 1 // for plat.c
#include <stdio.h>
+#include <stdlib.h>
#include <stdarg.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <linux/input.h>
#include "../common/libpicofe/input.h"
#include "../common/libpicofe/linux/in_evdev.h"
+#include "../common/host_fb.h"
#include "header.h"
#include "realfuncs.h"
#endif
char **g_argv;
+static int ts_fd = -1;
+
+/* touscreen. Could just use tsblib, but it's LGPL... */
+static int tsc[7];
+
+static int host_ts_init(void)
+{
+ static const char name_def[] = "/dev/input/touchscreen0";
+ const char *name;
+ FILE *f;
+ int ret;
+
+ f = fopen("/etc/pointercal", "r");
+ if (f == NULL) {
+ perror("fopen pointercal");
+ return -1;
+ }
+ ret = fscanf(f, "%d %d %d %d %d %d %d", &tsc[0], &tsc[1],
+ &tsc[2], &tsc[3], &tsc[4], &tsc[5], &tsc[6]);
+ fclose(f);
+ if (ret != 7) {
+ fprintf(stderr, "could not parse pointercal\n");
+ return -1;
+ }
+
+ name = getenv("TSLIB_TSDEVICE");
+ if (name == NULL)
+ name = name_def;
+ ts_fd = open(name, O_RDONLY | O_NONBLOCK);
+ if (ts_fd == -1) {
+ fprintf(stderr, "open %s", name);
+ perror("");
+ return -1;
+ }
+ return 0;
+}
+
+// returns ranges 0-1023
+int host_read_ts(int *pressure, int *x1024, int *y1024)
+{
+ static int raw_x, raw_y, raw_p;
+ struct input_event ev;
+ ssize_t ret;
+
+ if (ts_fd == -1)
+ return -1;
+
+ for (;;) {
+ errno = 0;
+ ret = read(ts_fd, &ev, sizeof(ev));
+ if (ret != sizeof(ev)) {
+ if (errno == EAGAIN)
+ break;
+ perror("ts read");
+ return -1;
+ }
+ if (ev.type == EV_ABS) {
+ switch (ev.code) {
+ case ABS_X: raw_x = ev.value; break;
+ case ABS_Y: raw_y = ev.value; break;
+ case ABS_PRESSURE: raw_p = ev.value; break;
+ }
+ }
+ }
+
+ *pressure = raw_p;
+ *x1024 = (tsc[0] * raw_x + tsc[1] * raw_y + tsc[2]) / tsc[6];
+ *y1024 = (tsc[3] * raw_x + tsc[4] * raw_y + tsc[5]) / tsc[6];
+
+ host_video_normalize_ts(x1024, y1024);
+
+ return 0;
+}
int host_init(void)
{
in_init();
host_init_input();
in_probe();
+ host_ts_init();
return 0;
}
zeropad = *s == '0';
justify = parse_dec(&s);
- if (*s == 'l')
+ if (*s == 'l' || *s == 'z')
s++; // ignore for now
if (*s == 's') {
char *ns = va_arg(ap, char *);
{ "/dev/mmuhack", FAKEDEV_MMUHACK },
{ "/dev/tty", FAKEDEV_TTY0 },
{ "/dev/tty0", FAKEDEV_TTY0 },
+ { "/dev/touchscreen/wm97xx", FAKEDEV_WM97XX },
+ { "/etc/pointercal", FAKEDEV_WM97XX_P },
#ifdef PND
{ "/dev/input/event*", -1 }, // hide for now, may cause dupe events
#endif
{
long ret;
- if (fd == FAKEDEV_GPIO)
- ret = emu_read_gpiodev(buf, count);
+ if (FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY)
+ ret = emu_do_read(fd, buf, count);
else
ret = g_read_raw(fd, buf, count);
- //strace("read(%d, %p, %ld) = %ld\n", fd, buf, count, ret);
+ //strace("read(%d, %p, %zd) = %ld\n", fd, buf, count, ret);
return ret;
}