Fix the display issue when using UnixUga driver to support graphic display

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5408 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
eric_tian 2008-07-04 03:17:52 +00:00
parent 1a24918483
commit 288a3c98c7
2 changed files with 133 additions and 134 deletions

View File

@ -91,8 +91,8 @@ static int
TryCreateShmImage(UGA_IO_PRIVATE *drv) TryCreateShmImage(UGA_IO_PRIVATE *drv)
{ {
drv->image = XShmCreateImage (drv->display, drv->visual, drv->image = XShmCreateImage (drv->display, drv->visual,
drv->depth, ZPixmap, NULL, &drv->xshm_info, drv->depth, ZPixmap, NULL, &drv->xshm_info,
drv->width, drv->height); drv->width, drv->height);
if (drv->image == NULL) if (drv->image == NULL)
return 0; return 0;
@ -109,8 +109,8 @@ TryCreateShmImage(UGA_IO_PRIVATE *drv)
} }
drv->xshm_info.shmid = shmget drv->xshm_info.shmid = shmget
(IPC_PRIVATE, drv->image->bytes_per_line * drv->image->height, (IPC_PRIVATE, drv->image->bytes_per_line * drv->image->height,
IPC_CREAT | 0777); IPC_CREAT | 0777);
if (drv->xshm_info.shmid < 0) if (drv->xshm_info.shmid < 0)
{ {
XDestroyImage(drv->image); XDestroyImage(drv->image);
@ -129,7 +129,7 @@ TryCreateShmImage(UGA_IO_PRIVATE *drv)
drv->xshm_info.shmaddr = (char*)drv->image_data; drv->xshm_info.shmaddr = (char*)drv->image_data;
drv->image->data = (char*)drv->image_data; drv->image->data = (char*)drv->image_data;
if (!XShmAttach (drv->display, &drv->xshm_info)) if (!XShmAttach (drv->display, &drv->xshm_info))
{ {
shmdt (drv->image_data); shmdt (drv->image_data);
@ -152,7 +152,7 @@ UgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
XDestroyImage(drv->image); XDestroyImage(drv->image);
if (drv->use_shm) if (drv->use_shm)
shmdt (drv->image_data); shmdt (drv->image_data);
drv->image_data = NULL; drv->image_data = NULL;
drv->image = NULL; drv->image = NULL;
@ -176,7 +176,7 @@ UgaSize(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height)
XDestroyImage(drv->image); XDestroyImage(drv->image);
if (drv->use_shm) if (drv->use_shm)
shmdt (drv->image_data); shmdt (drv->image_data);
drv->image_data = NULL; drv->image_data = NULL;
drv->image = NULL; drv->image = NULL;
@ -187,25 +187,22 @@ UgaSize(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height)
XResizeWindow (drv->display, drv->win, Width, Height); XResizeWindow (drv->display, drv->win, Width, Height);
/* Allocate image. */ /* Allocate image. */
if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv)) if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv)) {
{ drv->use_shm = 1;
drv->use_shm = 1; } else {
} drv->use_shm = 0;
else if (drv->depth > 16)
{ drv->pixel_shift = 2;
drv->use_shm = 0; else if (drv->depth > 8)
if (drv->depth > 16) drv->pixel_shift = 1;
drv->pixel_shift = 2; else
else if (drv->depth > 8) drv->pixel_shift = 0;
drv->pixel_shift = 1;
else
drv->pixel_shift = 0;
drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift); drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift);
drv->image = XCreateImage (drv->display, drv->visual, drv->depth, drv->image = XCreateImage (drv->display, drv->visual, drv->depth,
ZPixmap, 0, (char *)drv->image_data, ZPixmap, 0, (char *)drv->image_data,
drv->width, drv->height, drv->width, drv->height,
8 << drv->pixel_shift, 0); 8 << drv->pixel_shift, 0);
} }
drv->line_bytes = drv->image->bytes_per_line; drv->line_bytes = drv->image->bytes_per_line;
fill_shift_mask (&drv->r, drv->image->red_mask); fill_shift_mask (&drv->r, drv->image->red_mask);
@ -235,30 +232,30 @@ handleKeyEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
return; return;
res = XLookupString(&ev->xkey, str, sizeof(str), &keysym, NULL); res = XLookupString(&ev->xkey, str, sizeof(str), &keysym, NULL);
Key.ScanCode = 0; Key.ScanCode = 0;
Key.UnicodeChar = 0; Key.UnicodeChar = 0;
switch (keysym) { switch (keysym) {
case XK_Home: Key.ScanCode = SCAN_HOME; break; case XK_Home: Key.ScanCode = SCAN_HOME; break;
case XK_End: Key.ScanCode = SCAN_END; break; case XK_End: Key.ScanCode = SCAN_END; break;
case XK_Left: Key.ScanCode = SCAN_LEFT; break; case XK_Left: Key.ScanCode = SCAN_LEFT; break;
case XK_Right: Key.ScanCode = SCAN_RIGHT; break; case XK_Right: Key.ScanCode = SCAN_RIGHT; break;
case XK_Up: Key.ScanCode = SCAN_UP; break; case XK_Up: Key.ScanCode = SCAN_UP; break;
case XK_Down: Key.ScanCode = SCAN_DOWN; break; case XK_Down: Key.ScanCode = SCAN_DOWN; break;
case XK_Delete: Key.ScanCode = SCAN_DELETE; break; case XK_Delete: Key.ScanCode = SCAN_DELETE; break;
case XK_Insert: Key.ScanCode = SCAN_INSERT; break; case XK_Insert: Key.ScanCode = SCAN_INSERT; break;
case XK_Page_Up: Key.ScanCode = SCAN_PAGE_UP; break; case XK_Page_Up: Key.ScanCode = SCAN_PAGE_UP; break;
case XK_Page_Down: Key.ScanCode = SCAN_PAGE_DOWN; break; case XK_Page_Down: Key.ScanCode = SCAN_PAGE_DOWN; break;
case XK_Escape: Key.ScanCode = SCAN_ESC; break; case XK_Escape: Key.ScanCode = SCAN_ESC; break;
case XK_F1: Key.ScanCode = SCAN_F1; break; case XK_F1: Key.ScanCode = SCAN_F1; break;
case XK_F2: Key.ScanCode = SCAN_F2; break; case XK_F2: Key.ScanCode = SCAN_F2; break;
case XK_F3: Key.ScanCode = SCAN_F3; break; case XK_F3: Key.ScanCode = SCAN_F3; break;
case XK_F4: Key.ScanCode = SCAN_F4; break; case XK_F4: Key.ScanCode = SCAN_F4; break;
case XK_F5: Key.ScanCode = SCAN_F5; break; case XK_F5: Key.ScanCode = SCAN_F5; break;
case XK_F6: Key.ScanCode = SCAN_F6; break; case XK_F6: Key.ScanCode = SCAN_F6; break;
case XK_F7: Key.ScanCode = SCAN_F7; break; case XK_F7: Key.ScanCode = SCAN_F7; break;
case XK_F8: Key.ScanCode = SCAN_F8; break; case XK_F8: Key.ScanCode = SCAN_F8; break;
case XK_F9: Key.ScanCode = SCAN_F9; break; case XK_F9: Key.ScanCode = SCAN_F9; break;
default: default:
if (res == 1) { if (res == 1) {
@ -266,8 +263,8 @@ handleKeyEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
} else { } else {
return; return;
} }
} }
drv->keys[drv->key_wr] = Key; drv->keys[drv->key_wr] = Key;
drv->key_wr = (drv->key_wr + 1) % NBR_KEYS; drv->key_wr = (drv->key_wr + 1) % NBR_KEYS;
drv->key_count++; drv->key_count++;
@ -278,10 +275,11 @@ Redraw(UGA_IO_PRIVATE *drv, UINTN X, UINTN Y, UINTN Width, UINTN Height)
{ {
if (drv->use_shm) if (drv->use_shm)
XShmPutImage (drv->display, drv->win, drv->gc, drv->image, XShmPutImage (drv->display, drv->win, drv->gc, drv->image,
X, Y, X, Y, Width, Height, False); X, Y, X, Y, Width, Height, False);
else else
XPutImage (drv->display, drv->win, drv->gc, drv->image, XPutImage (drv->display, drv->win, drv->gc, drv->image,
X, Y, X, Y, Width, Height); X, Y, X, Y, Width, Height);
XFlush(drv->display);
} }
static void static void
@ -291,11 +289,11 @@ HandleEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
{ {
case Expose: case Expose:
Redraw(drv, ev->xexpose.x, ev->xexpose.y, Redraw(drv, ev->xexpose.x, ev->xexpose.y,
ev->xexpose.width, ev->xexpose.height); ev->xexpose.width, ev->xexpose.height);
break; break;
case GraphicsExpose: case GraphicsExpose:
Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y, Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
ev->xgraphicsexpose.width, ev->xgraphicsexpose.height); ev->xgraphicsexpose.width, ev->xgraphicsexpose.height);
break; break;
case KeyPress: case KeyPress:
handleKeyEvent(drv, ev); handleKeyEvent(drv, ev);
@ -321,7 +319,7 @@ HandleEvents(UGA_IO_PRIVATE *drv)
while (XPending(drv->display) != 0) while (XPending(drv->display) != 0)
{ {
XEvent ev; XEvent ev;
XNextEvent (drv->display, &ev); XNextEvent (drv->display, &ev);
HandleEvent(drv, &ev); HandleEvent(drv, &ev);
} }
@ -383,26 +381,26 @@ UgaGetKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key)
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS EFI_STATUS
UgaBlt(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UgaBlt(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
IN EFI_UGA_BLT_OPERATION BltOperation, IN EFI_UGA_BLT_OPERATION BltOperation,
IN UINTN SourceX, IN UINTN SourceX,
IN UINTN SourceY, IN UINTN SourceY,
IN UINTN DestinationX, IN UINTN DestinationX,
IN UINTN DestinationY, IN UINTN DestinationY,
IN UINTN Width, IN UINTN Width,
IN UINTN Height, IN UINTN Height,
IN UINTN Delta OPTIONAL IN UINTN Delta OPTIONAL
) )
{ {
UGA_IO_PRIVATE *Private = (UGA_IO_PRIVATE *)UgaIo; UGA_IO_PRIVATE *Private = (UGA_IO_PRIVATE *)UgaIo;
UINTN DstY; UINTN DstY;
UINTN SrcY; UINTN SrcY;
UINTN DstX; UINTN DstX;
UINTN SrcX; UINTN SrcX;
UINTN Index; UINTN Index;
EFI_UGA_PIXEL *Blt; EFI_UGA_PIXEL *Blt;
UINT8 *Dst; UINT8 *Dst;
UINT8 *Src; UINT8 *Src;
UINTN Nbr; UINTN Nbr;
@ -412,119 +410,120 @@ UgaBlt(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
// Check bounds // Check bounds
// //
if (BltOperation == EfiUgaVideoToBltBuffer if (BltOperation == EfiUgaVideoToBltBuffer
|| BltOperation == EfiUgaVideoToVideo) { || BltOperation == EfiUgaVideoToVideo) {
// //
// Source is Video. // Source is Video.
// //
if (SourceY + Height > Private->height) { if (SourceY + Height > Private->height) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (SourceX + Width > Private->width) { if (SourceX + Width > Private->width) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
if (BltOperation == EfiUgaBltBufferToVideo if (BltOperation == EfiUgaBltBufferToVideo
|| BltOperation == EfiUgaVideoToVideo || BltOperation == EfiUgaVideoToVideo
|| BltOperation == EfiUgaVideoFill) { || BltOperation == EfiUgaVideoFill) {
// //
// Destination is Video // Destination is Video
// //
if (DestinationY + Height > Private->height) { if (DestinationY + Height > Private->height) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (DestinationX + Width > Private->width) { if (DestinationX + Width > Private->width) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
switch (BltOperation) { switch (BltOperation) {
case EfiUgaVideoToBltBuffer: case EfiUgaVideoToBltBuffer:
Blt = BltBuffer; Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (DestinationY * Delta) + DestinationX * sizeof (EFI_UGA_PIXEL));
Delta -= Width * sizeof (EFI_UGA_PIXEL); Delta -= Width * sizeof (EFI_UGA_PIXEL);
for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) { for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) {
for (SrcX = SourceX; SrcX < (Width + SourceX); SrcX++) { for (SrcX = SourceX; SrcX < (Width + SourceX); SrcX++) {
*Blt++ = UgaColorToPixel(Private, *Blt++ = UgaColorToPixel(Private,
XGetPixel(Private->image, SrcX, SrcY)); XGetPixel(Private->image, SrcX, SrcY));
}
Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
}
break;
case EfiUgaBltBufferToVideo:
Blt = BltBuffer;
Delta -= Width * sizeof (EFI_UGA_PIXEL);
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
XPutPixel(Private->image, DstX, DstY, UgaPixelToColor(Private, *Blt));
Blt++;
} }
Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta); Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
} }
break; break;
case EfiUgaVideoToVideo: case EfiUgaBltBufferToVideo:
Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (SourceY * Delta) + SourceX * sizeof (EFI_UGA_PIXEL));
Delta -= Width * sizeof (EFI_UGA_PIXEL);
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
XPutPixel(Private->image, DstX, DstY, UgaPixelToColor(Private, *Blt));
Blt++;
}
Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
}
break;
case EfiUgaVideoToVideo:
Dst = Private->image_data + (DestinationX << Private->pixel_shift) Dst = Private->image_data + (DestinationX << Private->pixel_shift)
+ DestinationY * Private->line_bytes; + DestinationY * Private->line_bytes;
Src = Private->image_data + (SourceX << Private->pixel_shift) Src = Private->image_data + (SourceX << Private->pixel_shift)
+ SourceY * Private->line_bytes; + SourceY * Private->line_bytes;
Nbr = Width << Private->pixel_shift; Nbr = Width << Private->pixel_shift;
if (DestinationY < SourceY) { if (DestinationY < SourceY) {
for (Index = 0; Index < Height; Index++) { for (Index = 0; Index < Height; Index++) {
memcpy (Dst, Src, Nbr); memcpy (Dst, Src, Nbr);
Dst += Private->line_bytes; Dst += Private->line_bytes;
Src += Private->line_bytes; Src += Private->line_bytes;
} }
} }
else { else {
Dst += (Height - 1) * Private->line_bytes; Dst += (Height - 1) * Private->line_bytes;
Src += (Height - 1) * Private->line_bytes; Src += (Height - 1) * Private->line_bytes;
for (Index = 0; Index < Height; Index++) { for (Index = 0; Index < Height; Index++) {
// //
// Source and Destination Y may be equal, therefore Dst and Src may // Source and Destination Y may be equal, therefore Dst and Src may
// overlap. // overlap.
// //
memmove (Dst, Src, Nbr); memmove (Dst, Src, Nbr);
Dst -= Private->line_bytes; Dst -= Private->line_bytes;
Src -= Private->line_bytes; Src -= Private->line_bytes;
} }
} }
break; break;
case EfiUgaVideoFill: case EfiUgaVideoFill:
Color = UgaPixelToColor(Private, *BltBuffer); Color = UgaPixelToColor(Private, *BltBuffer);
for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) { for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
XPutPixel(Private->image, DstX, DstY, Color); XPutPixel(Private->image, DstX, DstY, Color);
} }
} }
break; break;
default: default:
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
// //
// Refresh screen. // Refresh screen.
// //
switch (BltOperation) { switch (BltOperation) {
case EfiUgaVideoToVideo: case EfiUgaVideoToVideo:
XCopyArea(Private->display, Private->win, Private->win, Private->gc, XCopyArea(Private->display, Private->win, Private->win, Private->gc,
SourceX, SourceY, Width, Height, DestinationX, DestinationY); SourceX, SourceY, Width, Height, DestinationX, DestinationY);
while (1) { while (1) {
XEvent ev; XEvent ev;
XNextEvent (Private->display, &ev); XNextEvent (Private->display, &ev);
HandleEvent(Private, &ev); HandleEvent(Private, &ev);
if (ev.type == NoExpose || ev.type == GraphicsExpose) if (ev.type == NoExpose || ev.type == GraphicsExpose)
break; break;
} }
break; break;
case EfiUgaVideoFill: case EfiUgaVideoFill:
Color = UgaPixelToColor(Private, *BltBuffer); Color = UgaPixelToColor(Private, *BltBuffer);
XSetForeground(Private->display, Private->gc, Color); XSetForeground(Private->display, Private->gc, Color);
XFillRectangle(Private->display, Private->win, Private->gc, XFillRectangle(Private->display, Private->win, Private->gc,
DestinationX, DestinationY, Width, Height); DestinationX, DestinationY, Width, Height);
XFlush(Private->display);
break; break;
case EfiUgaBltBufferToVideo: case EfiUgaBltBufferToVideo:
Redraw(Private, DestinationX, DestinationY, Width, Height); Redraw(Private, DestinationX, DestinationY, Width, Height);
break; break;
default: default:
@ -559,17 +558,17 @@ UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL **Uga, CONST CHAR16 *Title)
if (drv->display == NULL) if (drv->display == NULL)
{ {
fprintf (stderr, "uga: cannot connect to X server %s\n", fprintf (stderr, "uga: cannot connect to X server %s\n",
XDisplayName (display_name)); XDisplayName (display_name));
free (drv); free (drv);
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
drv->screen = DefaultScreen (drv->display); drv->screen = DefaultScreen (drv->display);
drv->visual = DefaultVisual (drv->display, drv->screen); drv->visual = DefaultVisual (drv->display, drv->screen);
drv->win = XCreateSimpleWindow drv->win = XCreateSimpleWindow
(drv->display, RootWindow (drv->display, drv->screen), (drv->display, RootWindow (drv->display, drv->screen),
0, 0, 4, 4, border_width, 0, 0, 4, 4, border_width,
BlackPixel (drv->display, drv->screen), WhitePixel (drv->display, drv->screen),
WhitePixel (drv->display, drv->screen)); BlackPixel (drv->display, drv->screen));
drv->depth = DefaultDepth (drv->display, drv->screen); drv->depth = DefaultDepth (drv->display, drv->screen);
@ -587,7 +586,7 @@ UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL **Uga, CONST CHAR16 *Title)
} }
XSelectInput (drv->display, drv->win, XSelectInput (drv->display, drv->win,
ExposureMask | KeyPressMask); ExposureMask | KeyPressMask);
drv->gc = DefaultGC (drv->display, drv->screen); drv->gc = DefaultGC (drv->display, drv->screen);
*Uga = (EFI_UNIX_UGA_IO_PROTOCOL *)drv; *Uga = (EFI_UNIX_UGA_IO_PROTOCOL *)drv;

View File

@ -210,7 +210,7 @@ INF UnixPkg/UnixBusDriverDxe/UnixBusDriver.inf
INF UnixPkg/UnixBlockIoDxe/UnixBlockIo.inf INF UnixPkg/UnixBlockIoDxe/UnixBlockIo.inf
INF UnixPkg/UnixSerialIoDxe/UnixSerialIo.inf INF UnixPkg/UnixSerialIoDxe/UnixSerialIo.inf
INF UnixPkg/UnixUgaDxe/UnixUga.inf INF UnixPkg/UnixUgaDxe/UnixUga.inf
INF UnixPkg/UnixConsoleDxe/UnixConsole.inf #INF UnixPkg/UnixConsoleDxe/UnixConsole.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf