From patchwork Fri Jun 17 10:04:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasily Khoruzhick X-Patchwork-Id: 100808 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 90419B6FDC for ; Sat, 18 Jun 2011 00:06:26 +1000 (EST) Received: from localhost ([::1]:42527 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXZgi-0008UY-Hq for incoming@patchwork.ozlabs.org; Fri, 17 Jun 2011 10:06:20 -0400 Received: from eggs.gnu.org ([140.186.70.92]:53895) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXZWS-0006T8-Fy for qemu-devel@nongnu.org; Fri, 17 Jun 2011 09:55:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QXZWI-0006PL-Oa for qemu-devel@nongnu.org; Fri, 17 Jun 2011 09:55:42 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:43801) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXZWI-0006Nu-6L for qemu-devel@nongnu.org; Fri, 17 Jun 2011 09:55:34 -0400 Received: by wyb42 with SMTP id 42so2013630wyb.4 for ; Fri, 17 Jun 2011 06:55:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=EP7MjatT8Sdt8LplIsNto69GZ3cC3cxBmDs4fLfc3sM=; b=BYL+2OIsnpaWGeitPriyWfQTJtKTzjAr+W52ubcubNjRqF72LvxorJYko3YWWJ3BHy APOkion2uh6BRPvC7rT6Prvd1GVeO1sqNVFl5tlvgS/aZ3gqLMVA1EC5bL+D66sghk2M L+xxIY3tfIdJYIpXCDfMjK49dq3hfZaac3Ds4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=QkFFD1/SHaoUQ7Tr59FIHztJEGtHzjOB95B0ezYyiGDit1GzZBLfqz3WofR5nGxicf 3Sm9pj2/dPCdpyuZJkuv5cF8yj654Pn4VGeh2Cb9S0sR/tbjdRLr6O24ln2LGunfJvdm Z4dkC2U7W5g4kND1aalgVO5FlnjzHZl9KPMJc= Received: by 10.227.183.143 with SMTP id cg15mr1965114wbb.24.1308305141862; Fri, 17 Jun 2011 03:05:41 -0700 (PDT) Received: from localhost.localdomain ([86.57.155.118]) by mx.google.com with ESMTPS id et5sm819076wbb.50.2011.06.17.03.05.38 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 17 Jun 2011 03:05:40 -0700 (PDT) From: Vasily Khoruzhick To: Peter Maydell , "qemu-devel@nongnu.org" Date: Fri, 17 Jun 2011 13:04:36 +0300 Message-Id: <1308305077-21503-1-git-send-email-anarsoul@gmail.com> X-Mailer: git-send-email 1.7.5.rc3 In-Reply-To: <201106081422.42682.anarsoul@gmail.com> References: <201106081422.42682.anarsoul@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.173 Cc: Vasily Khoruzhick Subject: [Qemu-devel] [PATCH v4 1/2] pxa2xx_lcd: add proper rotation support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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. v4: codestyle fixes; replace atoi with strtol hw/framebuffer.c | 3 + hw/pxa2xx_lcd.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++------ input.c | 34 ++++++++++++---- qemu-options.hx | 9 ++++ vl.c | 11 +++++- 5 files changed, 144 insertions(+), 22 deletions(-) diff --git a/hw/framebuffer.c b/hw/framebuffer.c index 24cdf25..56cf16e 100644 --- a/hw/framebuffer.c +++ b/hw/framebuffer.c @@ -78,6 +78,9 @@ 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..a5f8c51 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,67 @@ 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 +791,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 +859,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 - dpy_update(s->ds, 0, miny, s->xres, maxy - miny); + switch (s->orientation) { + case 0: + dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1); + break; + case 90: + dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres); + break; + case 180: + maxy = s->yres - maxy - 1; + miny = s->yres - miny - 1; + dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1); + break; + case 270: + maxy = s->yres - maxy - 1; + miny = s->yres - miny - 1; + dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres); + break; + } } pxa2xx_lcdc_int_update(s); @@ -822,10 +898,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..c11cc44 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 = strtol(optarg, (char **)&optarg, 10); + 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;