From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:45837) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSWR2-0006ok-Ue for qemu-devel@nongnu.org; Fri, 03 Jun 2011 11:37:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QSWR0-0002g3-01 for qemu-devel@nongnu.org; Fri, 03 Jun 2011 11:37:16 -0400 Received: from mail-bw0-f45.google.com ([209.85.214.45]:49730) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QSWQy-0002fk-UJ for qemu-devel@nongnu.org; Fri, 03 Jun 2011 11:37:13 -0400 Received: by bwz16 with SMTP id 16so2053006bwz.4 for ; Fri, 03 Jun 2011 08:37:11 -0700 (PDT) From: Vasily Khoruzhick Date: Fri, 3 Jun 2011 18:36:36 +0300 Message-Id: <1307115397-6496-1-git-send-email-anarsoul@gmail.com> In-Reply-To: <1306920487-18705-1-git-send-email-anarsoul@gmail.com> References: <1306920487-18705-1-git-send-email-anarsoul@gmail.com> Subject: [Qemu-devel] [PATCH v3 1/2] pxa2xx_lcd: add proper rotation support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell , "qemu-devel@nongnu.org" Cc: Vasily Khoruzhick Until now, pxa2xx_lcd only supported 90deg rotation, but some machines (for example Zipit Z2) needs 270deg rotation. Signed-off-by: Vasily Khoruzhick --- v2: codestyle fixes v3: fix dpy_update calls for 180 and 360 deg. rotation. hw/framebuffer.c | 2 + hw/pxa2xx_lcd.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++------ input.c | 34 +++++++++++++----- qemu-options.hx | 9 +++++ vl.c | 11 +++++- 5 files changed, 136 insertions(+), 21 deletions(-) diff --git a/hw/framebuffer.c b/hw/framebuffer.c index 24cdf25..5e9ab5e 100644 --- a/hw/framebuffer.c +++ b/hw/framebuffer.c @@ -78,6 +78,8 @@ void framebuffer_update_display( dest = ds_get_data(ds); if (dest_col_pitch < 0) dest -= dest_col_pitch * (cols - 1); + if (dest_row_pitch < 0) + dest -= dest_row_pitch * (rows - 1); first = -1; addr = pd; diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index e524802..3db900b 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -665,7 +665,7 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) } } -static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -692,7 +692,7 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, fn, s->dma_ch[0].palette, miny, maxy); } -static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -720,6 +720,61 @@ static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, miny, maxy); } +static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, + target_phys_addr_t addr, int *miny, int *maxy) +{ + int src_width, dest_width; + drawfn fn = NULL; + if (s->dest_width) + fn = s->line_fn[s->transp][s->bpp]; + if (!fn) + return; + + src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ + if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) + src_width *= 3; + else if (s->bpp > pxa_lcdc_16bpp) + src_width *= 4; + else if (s->bpp > pxa_lcdc_8bpp) + src_width *= 2; + + dest_width = s->xres * s->dest_width; + *miny = 0; + framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -dest_width, -s->dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, miny, maxy); +} + +static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, + target_phys_addr_t addr, int *miny, int *maxy) +{ + int src_width, dest_width; + drawfn fn = NULL; + if (s->dest_width) + fn = s->line_fn[s->transp][s->bpp]; + if (!fn) + return; + + src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ + if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) + src_width *= 3; + else if (s->bpp > pxa_lcdc_16bpp) + src_width *= 4; + else if (s->bpp > pxa_lcdc_8bpp) + src_width *= 2; + + dest_width = s->yres * s->dest_width; + *miny = 0; + framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -s->dest_width, dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, + miny, maxy); +} + static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) { int width, height; @@ -730,10 +785,11 @@ static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) height = LCCR2_LPP(s->control[2]) + 1; if (width != s->xres || height != s->yres) { - if (s->orientation) + if (s->orientation == 90 || s->orientation == 270) { qemu_console_resize(s->ds, height, width); - else + } else { qemu_console_resize(s->ds, width, height); + } s->invalidated = 1; s->xres = width; s->yres = height; @@ -797,10 +853,24 @@ static void pxa2xx_update_display(void *opaque) } if (miny >= 0) { - if (s->orientation) - dpy_update(s->ds, miny, 0, maxy - miny, s->xres); - else + switch (s->orientation) { + case 0: dpy_update(s->ds, 0, miny, s->xres, maxy - miny); + break; + case 90: + dpy_update(s->ds, miny, 0, maxy - miny, s->xres); + break; + case 180: + maxy = s->yres - maxy; + miny = s->yres - miny; + dpy_update(s->ds, 0, maxy, s->xres, miny - maxy); + break; + case 270: + maxy = s->yres - maxy; + miny = s->yres - miny; + dpy_update(s->ds, maxy, 0, miny - maxy, s->xres); + break; + } } pxa2xx_lcdc_int_update(s); @@ -822,10 +892,19 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; - if (angle) { - s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert; - } else { - s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_horiz; + switch (angle) { + case 0: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0; + break; + case 90: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90; + break; + case 180: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180; + break; + case 270: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270; + break; } s->orientation = angle; diff --git a/input.c b/input.c index 5664d3a..f0a02e7 100644 --- a/input.c +++ b/input.c @@ -148,7 +148,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) QEMUPutMouseEntry *entry; QEMUPutMouseEvent *mouse_event; void *mouse_event_opaque; - int width; + int width, height; if (QTAILQ_EMPTY(&mouse_handlers)) { return; @@ -160,15 +160,31 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) mouse_event_opaque = entry->qemu_put_mouse_event_opaque; if (mouse_event) { - if (graphic_rotate) { - if (entry->qemu_put_mouse_event_absolute) { - width = 0x7fff; - } else { - width = graphic_width - 1; - } - mouse_event(mouse_event_opaque, width - dy, dx, dz, buttons_state); + if (entry->qemu_put_mouse_event_absolute) { + width = 0x7fff; + height = 0x7fff; } else { - mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state); + width = graphic_width - 1; + height = graphic_height - 1; + } + + switch (graphic_rotate) { + case 0: + mouse_event(mouse_event_opaque, + dx, dy, dz, buttons_state); + break; + case 90: + mouse_event(mouse_event_opaque, + width - dy, dx, dz, buttons_state); + break; + case 180: + mouse_event(mouse_event_opaque, + width - dx, height - dy, dz, buttons_state); + break; + case 270: + mouse_event(mouse_event_opaque, + dy, height - dx, dz, buttons_state); + break; } } } diff --git a/qemu-options.hx b/qemu-options.hx index 82e085a..46d8f25 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -771,6 +771,15 @@ STEXI Rotate graphical output 90 deg left (only PXA LCD). ETEXI +DEF("rotate", HAS_ARG, QEMU_OPTION_rotate, + "-rotate rotate graphical output some deg left (only PXA LCD)\n", + QEMU_ARCH_ALL) +STEXI +@item -rotate +@findex -rotate +Rotate graphical output some deg left (only PXA LCD). +ETEXI + DEF("vga", HAS_ARG, QEMU_OPTION_vga, "-vga [std|cirrus|vmware|qxl|xenfb|none]\n" " select video card type\n", QEMU_ARCH_ALL) diff --git a/vl.c b/vl.c index b362871..5074bfe 100644 --- a/vl.c +++ b/vl.c @@ -2289,7 +2289,16 @@ int main(int argc, char **argv, char **envp) #endif break; case QEMU_OPTION_portrait: - graphic_rotate = 1; + graphic_rotate = 90; + break; + case QEMU_OPTION_rotate: + graphic_rotate = atoi(optarg); + if (graphic_rotate != 0 && graphic_rotate != 90 && + graphic_rotate != 180 && graphic_rotate != 270) { + fprintf(stderr, + "qemu: only 90, 180, 270 deg rotation is available\n"); + exit(1); + } break; case QEMU_OPTION_kernel: kernel_filename = optarg; -- 1.7.5.rc3