]> git.proxmox.com Git - mirror_edk2.git/blame - UnixPkg/Sec/UgaX11.c
Complete coding to support X64 EFI ABI in UnixPkg. Code is not currently hooked in...
[mirror_edk2.git] / UnixPkg / Sec / UgaX11.c
CommitLineData
ccd55824 1/*++
2
f9b8ab56
HT
3Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
4Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5This program and the accompanying materials
ccd55824 6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13--*/
14
804405e7 15#include <sys/ipc.h>
16#include <sys/shm.h>
804405e7 17#include <stdio.h>
18#include <stdlib.h>
19
20#include "PiPei.h"
21#include "Protocol/UnixThunk.h"
22#include "Protocol/SimpleTextIn.h"
23#include "Protocol/UgaDraw.h"
24#include "Protocol/UnixUgaIo.h"
25#include <X11/Xlib.h>
26#include <X11/Xutil.h>
27#include <X11/Xos.h>
28#include <X11/extensions/XShm.h>
29#include <X11/keysym.h>
30
804405e7 31#include <Ppi/StatusCode.h>
32
33#include <Library/PeCoffLib.h>
34#include <Library/BaseLib.h>
35#include <Library/BaseMemoryLib.h>
36#include <Library/PrintLib.h>
37#include <Library/PcdLib.h>
38#include <Library/DebugLib.h>
39
40extern void msSleep (unsigned long Milliseconds);
41
42/* XQueryPointer */
43
44struct uga_drv_shift_mask
45{
46 unsigned char shift;
47 unsigned char size;
48 unsigned char csize;
49};
50
51#define NBR_KEYS 32
52typedef struct
53{
54 EFI_UNIX_UGA_IO_PROTOCOL UgaIo;
55
56 Display *display;
57 int screen; /* values for window_size in main */
58 Window win;
59 GC gc;
60 Visual *visual;
61
62 int depth;
63 unsigned int width;
64 unsigned int height;
65 unsigned int line_bytes;
66 unsigned int pixel_shift;
67 unsigned char *image_data;
68
69 struct uga_drv_shift_mask r, g, b;
70
71 int use_shm;
72 XShmSegmentInfo xshm_info;
73 XImage *image;
74
75 unsigned int key_rd;
76 unsigned int key_wr;
77 unsigned int key_count;
78 EFI_INPUT_KEY keys[NBR_KEYS];
79} UGA_IO_PRIVATE;
80
7492c63d 81void
804405e7 82HandleEvents(UGA_IO_PRIVATE *drv);
83
7492c63d 84void
804405e7 85fill_shift_mask (struct uga_drv_shift_mask *sm, unsigned long mask)
86{
87 sm->shift = 0;
88 sm->size = 0;
89 while ((mask & 1) == 0)
90 {
91 mask >>= 1;
92 sm->shift++;
93 }
94 while (mask & 1)
95 {
96 sm->size++;
97 mask >>= 1;
98 }
99 sm->csize = 8 - sm->size;
100}
101
7492c63d 102int
804405e7 103TryCreateShmImage(UGA_IO_PRIVATE *drv)
104{
105 drv->image = XShmCreateImage (drv->display, drv->visual,
288a3c98 106 drv->depth, ZPixmap, NULL, &drv->xshm_info,
107 drv->width, drv->height);
804405e7 108 if (drv->image == NULL)
109 return 0;
110
111 switch (drv->image->bitmap_unit) {
112 case 32:
113 drv->pixel_shift = 2;
114 break;
115 case 16:
116 drv->pixel_shift = 1;
117 break;
118 case 8:
119 drv->pixel_shift = 0;
120 break;
121 }
122
123 drv->xshm_info.shmid = shmget
288a3c98 124 (IPC_PRIVATE, drv->image->bytes_per_line * drv->image->height,
125 IPC_CREAT | 0777);
7ee3b613
A
126 if (drv->xshm_info.shmid < 0) {
127 XDestroyImage(drv->image);
128 return 0;
129 }
804405e7 130
131 drv->image_data = shmat (drv->xshm_info.shmid, NULL, 0);
7ee3b613
A
132 if(!drv->image_data) {
133 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
134 XDestroyImage(drv->image);
135 return 0;
136 }
ccd55824 137
138#ifndef __APPLE__
139 //
140 // This closes shared memory in real time on OS X. Only closes after folks quit using
141 // it on Linux.
142 //
804405e7 143 /* Can this fail ? */
144 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
ccd55824 145#endif
804405e7 146
147 drv->xshm_info.shmaddr = (char*)drv->image_data;
148 drv->image->data = (char*)drv->image_data;
288a3c98 149
7ee3b613
A
150 if (!XShmAttach (drv->display, &drv->xshm_info)) {
151 shmdt (drv->image_data);
152 XDestroyImage(drv->image);
153 return 0;
154 }
804405e7 155 return 1;
156}
157
804405e7 158EFI_STATUS
159UgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
160{
161 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
162
163 if (drv == NULL)
164 return EFI_SUCCESS;
165 if (drv->image != NULL)
166 {
167 XDestroyImage(drv->image);
168
169 if (drv->use_shm)
288a3c98 170 shmdt (drv->image_data);
804405e7 171
172 drv->image_data = NULL;
173 drv->image = NULL;
174 }
175 XDestroyWindow(drv->display, drv->win);
176 XCloseDisplay(drv->display);
ccd55824 177
178#ifdef __APPLE__
179 // Free up the shared memory
180 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
181#endif
182
804405e7 183 free(drv);
184 return EFI_SUCCESS;
185}
186
804405e7 187EFI_STATUS
188UgaSize(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height)
189{
190 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
191 XSizeHints size_hints;
192
193 /* Destroy current buffer if created. */
194 if (drv->image != NULL)
195 {
7d28e82d 196 /* Before destroy buffer, need to make sure the buffer available for access. */
804405e7 197 XDestroyImage(drv->image);
198
199 if (drv->use_shm)
288a3c98 200 shmdt (drv->image_data);
804405e7 201
202 drv->image_data = NULL;
203 drv->image = NULL;
204 }
205
206 drv->width = Width;
207 drv->height = Height;
208 XResizeWindow (drv->display, drv->win, Width, Height);
209
210 /* Allocate image. */
288a3c98 211 if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv)) {
212 drv->use_shm = 1;
213 } else {
214 drv->use_shm = 0;
215 if (drv->depth > 16)
216 drv->pixel_shift = 2;
217 else if (drv->depth > 8)
218 drv->pixel_shift = 1;
219 else
220 drv->pixel_shift = 0;
804405e7 221
222 drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift);
223 drv->image = XCreateImage (drv->display, drv->visual, drv->depth,
288a3c98 224 ZPixmap, 0, (char *)drv->image_data,
225 drv->width, drv->height,
226 8 << drv->pixel_shift, 0);
804405e7 227 }
228 drv->line_bytes = drv->image->bytes_per_line;
229 fill_shift_mask (&drv->r, drv->image->red_mask);
230 fill_shift_mask (&drv->g, drv->image->green_mask);
231 fill_shift_mask (&drv->b, drv->image->blue_mask);
232
233 /* Set WM hints. */
234 size_hints.flags = PSize | PMinSize | PMaxSize;
235 size_hints.min_width = size_hints.max_width = size_hints.base_width = Width;
236 size_hints.min_height = size_hints.max_height = size_hints.base_height = Height;
237 XSetWMNormalHints (drv->display, drv->win, &size_hints);
238
239 XMapWindow (drv->display, drv->win);
240 HandleEvents(drv);
241 return EFI_SUCCESS;
242}
243
7492c63d 244void
804405e7 245handleKeyEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
246{
247 KeySym keysym;
248 char str[4];
249 EFI_INPUT_KEY Key;
250 int res;
251
252 if (drv->key_count == NBR_KEYS)
253 return;
254
255 res = XLookupString(&ev->xkey, str, sizeof(str), &keysym, NULL);
288a3c98 256 Key.ScanCode = 0;
804405e7 257 Key.UnicodeChar = 0;
288a3c98 258 switch (keysym) {
259 case XK_Home: Key.ScanCode = SCAN_HOME; break;
260 case XK_End: Key.ScanCode = SCAN_END; break;
261 case XK_Left: Key.ScanCode = SCAN_LEFT; break;
262 case XK_Right: Key.ScanCode = SCAN_RIGHT; break;
263 case XK_Up: Key.ScanCode = SCAN_UP; break;
264 case XK_Down: Key.ScanCode = SCAN_DOWN; break;
265 case XK_Delete: Key.ScanCode = SCAN_DELETE; break;
266 case XK_Insert: Key.ScanCode = SCAN_INSERT; break;
267 case XK_Page_Up: Key.ScanCode = SCAN_PAGE_UP; break;
268 case XK_Page_Down: Key.ScanCode = SCAN_PAGE_DOWN; break;
269 case XK_Escape: Key.ScanCode = SCAN_ESC; break;
270
271 case XK_F1: Key.ScanCode = SCAN_F1; break;
272 case XK_F2: Key.ScanCode = SCAN_F2; break;
273 case XK_F3: Key.ScanCode = SCAN_F3; break;
274 case XK_F4: Key.ScanCode = SCAN_F4; break;
275 case XK_F5: Key.ScanCode = SCAN_F5; break;
276 case XK_F6: Key.ScanCode = SCAN_F6; break;
277 case XK_F7: Key.ScanCode = SCAN_F7; break;
278 case XK_F8: Key.ScanCode = SCAN_F8; break;
279 case XK_F9: Key.ScanCode = SCAN_F9; break;
804405e7 280
281 default:
282 if (res == 1) {
283 Key.UnicodeChar = str[0];
284 } else {
285 return;
286 }
288a3c98 287 }
288
804405e7 289 drv->keys[drv->key_wr] = Key;
290 drv->key_wr = (drv->key_wr + 1) % NBR_KEYS;
291 drv->key_count++;
292}
293
7492c63d 294void
804405e7 295Redraw(UGA_IO_PRIVATE *drv, UINTN X, UINTN Y, UINTN Width, UINTN Height)
296{
297 if (drv->use_shm)
298 XShmPutImage (drv->display, drv->win, drv->gc, drv->image,
288a3c98 299 X, Y, X, Y, Width, Height, False);
804405e7 300 else
301 XPutImage (drv->display, drv->win, drv->gc, drv->image,
288a3c98 302 X, Y, X, Y, Width, Height);
303 XFlush(drv->display);
804405e7 304}
305
7492c63d 306void
804405e7 307HandleEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
308{
309 switch (ev->type)
310 {
311 case Expose:
312 Redraw(drv, ev->xexpose.x, ev->xexpose.y,
288a3c98 313 ev->xexpose.width, ev->xexpose.height);
804405e7 314 break;
315 case GraphicsExpose:
316 Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
288a3c98 317 ev->xgraphicsexpose.width, ev->xgraphicsexpose.height);
804405e7 318 break;
319 case KeyPress:
320 handleKeyEvent(drv, ev);
321 break;
322 case MappingNotify:
323 XRefreshKeyboardMapping(&ev->xmapping);
324 break;
325#if 0
326 case DestroyNotify:
327 XCloseDisplay (drv->display);
328 exit (1);
329 break;
330#endif
331 case NoExpose:
332 default:
333 break;
334 }
335}
336
7492c63d 337void
804405e7 338HandleEvents(UGA_IO_PRIVATE *drv)
339{
340 while (XPending(drv->display) != 0)
341 {
342 XEvent ev;
288a3c98 343
804405e7 344 XNextEvent (drv->display, &ev);
345 HandleEvent(drv, &ev);
346 }
347}
348
804405e7 349unsigned long
350UgaPixelToColor (UGA_IO_PRIVATE *drv, EFI_UGA_PIXEL pixel)
351{
352 return ((pixel.Red >> drv->r.csize) << drv->r.shift)
353 | ((pixel.Green >> drv->g.csize) << drv->g.shift)
354 | ((pixel.Blue >> drv->b.csize) << drv->b.shift);
355}
356
804405e7 357EFI_UGA_PIXEL
358UgaColorToPixel (UGA_IO_PRIVATE *drv, unsigned long val)
359{
360 EFI_UGA_PIXEL res;
361
362 memset (&res, 0, sizeof (EFI_UGA_PIXEL));
363 /* FIXME: should round instead of truncate. */
364 res.Red = (val >> drv->r.shift) << drv->r.csize;
365 res.Green = (val >> drv->g.shift) << drv->g.csize;
366 res.Blue = (val >> drv->b.shift) << drv->b.csize;
367
368 return res;
369}
370
804405e7 371EFI_STATUS
372UgaCheckKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
373{
374 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
375 HandleEvents(drv);
b9c8e50e 376
377 if (drv->key_count != 0) {
804405e7 378 return EFI_SUCCESS;
b9c8e50e 379 } else {
804405e7 380 /* EFI is certainly polling. Be CPU-friendly. */
381 msSleep (20);
382 return EFI_NOT_READY;
383 }
384}
385
804405e7 386EFI_STATUS
7ee3b613 387UgaGetKey (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key)
804405e7 388{
389 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
390 EFI_STATUS status;
391
392 status = UgaCheckKey(UgaIo);
393 if (status != EFI_SUCCESS)
394 return status;
395
396 *key = drv->keys[drv->key_rd];
397 drv->key_rd = (drv->key_rd + 1) % NBR_KEYS;
398 drv->key_count--;
399 return EFI_SUCCESS;
400}
401
288a3c98 402EFI_STATUS
a4902ccc 403UgaBlt(
404 IN EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
405 IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
406 IN EFI_UGA_BLT_OPERATION BltOperation,
407 IN UGA_BLT_ARGS *Args
288a3c98 408 )
804405e7 409{
410 UGA_IO_PRIVATE *Private = (UGA_IO_PRIVATE *)UgaIo;
288a3c98 411 UINTN DstY;
412 UINTN SrcY;
804405e7 413 UINTN DstX;
414 UINTN SrcX;
415 UINTN Index;
288a3c98 416 EFI_UGA_PIXEL *Blt;
804405e7 417 UINT8 *Dst;
418 UINT8 *Src;
419 UINTN Nbr;
420 unsigned long Color;
421
422 //
423 // Check bounds
424 //
425 if (BltOperation == EfiUgaVideoToBltBuffer
288a3c98 426 || BltOperation == EfiUgaVideoToVideo) {
427 //
804405e7 428 // Source is Video.
288a3c98 429 //
a4902ccc 430 if (Args->SourceY + Args->Height > Private->height) {
288a3c98 431 return EFI_INVALID_PARAMETER;
432 }
433
a4902ccc 434 if (Args->SourceX + Args->Width > Private->width) {
288a3c98 435 return EFI_INVALID_PARAMETER;
436 }
804405e7 437 }
438
439 if (BltOperation == EfiUgaBltBufferToVideo
440 || BltOperation == EfiUgaVideoToVideo
288a3c98 441 || BltOperation == EfiUgaVideoFill) {
442 //
443 // Destination is Video
444 //
a4902ccc 445 if (Args->DestinationY + Args->Height > Private->height) {
288a3c98 446 return EFI_INVALID_PARAMETER;
447 }
448
a4902ccc 449 if (Args->DestinationX + Args->Width > Private->width) {
288a3c98 450 return EFI_INVALID_PARAMETER;
451 }
804405e7 452 }
453
288a3c98 454 switch (BltOperation) {
804405e7 455 case EfiUgaVideoToBltBuffer:
a4902ccc 456 Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->DestinationY * Args->Delta) + Args->DestinationX * sizeof (EFI_UGA_PIXEL));
457 Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL);
458 for (SrcY = Args->SourceY; SrcY < (Args->Height + Args->SourceY); SrcY++) {
459 for (SrcX = Args->SourceX; SrcX < (Args->Width + Args->SourceX); SrcX++) {
288a3c98 460 *Blt++ = UgaColorToPixel(Private,
461 XGetPixel(Private->image, SrcX, SrcY));
804405e7 462 }
a4902ccc 463 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta);
288a3c98 464 }
804405e7 465 break;
288a3c98 466 case EfiUgaBltBufferToVideo:
a4902ccc 467 Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->SourceY * Args->Delta) + Args->SourceX * sizeof (EFI_UGA_PIXEL));
468 Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL);
469 for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) {
470 for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) {
288a3c98 471 XPutPixel(Private->image, DstX, DstY, UgaPixelToColor(Private, *Blt));
472 Blt++;
804405e7 473 }
a4902ccc 474 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta);
804405e7 475 }
476 break;
288a3c98 477 case EfiUgaVideoToVideo:
a4902ccc 478 Dst = Private->image_data + (Args->DestinationX << Private->pixel_shift)
479 + Args->DestinationY * Private->line_bytes;
480 Src = Private->image_data + (Args->SourceX << Private->pixel_shift)
481 + Args->SourceY * Private->line_bytes;
482 Nbr = Args->Width << Private->pixel_shift;
483 if (Args->DestinationY < Args->SourceY) {
484 for (Index = 0; Index < Args->Height; Index++) {
288a3c98 485 memcpy (Dst, Src, Nbr);
486 Dst += Private->line_bytes;
487 Src += Private->line_bytes;
804405e7 488 }
489 }
490 else {
a4902ccc 491 Dst += (Args->Height - 1) * Private->line_bytes;
492 Src += (Args->Height - 1) * Private->line_bytes;
493 for (Index = 0; Index < Args->Height; Index++) {
288a3c98 494 //
495 // Source and Destination Y may be equal, therefore Dst and Src may
496 // overlap.
497 //
498 memmove (Dst, Src, Nbr);
499 Dst -= Private->line_bytes;
500 Src -= Private->line_bytes;
804405e7 501 }
502 }
503 break;
504 case EfiUgaVideoFill:
505 Color = UgaPixelToColor(Private, *BltBuffer);
a4902ccc 506 for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) {
507 for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) {
288a3c98 508 XPutPixel(Private->image, DstX, DstY, Color);
804405e7 509 }
288a3c98 510 }
804405e7 511 break;
512 default:
288a3c98 513 return EFI_INVALID_PARAMETER;
804405e7 514 }
515
516 //
517 // Refresh screen.
518 //
288a3c98 519 switch (BltOperation) {
520 case EfiUgaVideoToVideo:
804405e7 521 XCopyArea(Private->display, Private->win, Private->win, Private->gc,
a4902ccc 522 Args->SourceX, Args->SourceY, Args->Width, Args->Height, Args->DestinationX, Args->DestinationY);
804405e7 523 while (1) {
524 XEvent ev;
288a3c98 525
804405e7 526 XNextEvent (Private->display, &ev);
527 HandleEvent(Private, &ev);
528 if (ev.type == NoExpose || ev.type == GraphicsExpose)
288a3c98 529 break;
804405e7 530 }
531 break;
532 case EfiUgaVideoFill:
533 Color = UgaPixelToColor(Private, *BltBuffer);
534 XSetForeground(Private->display, Private->gc, Color);
535 XFillRectangle(Private->display, Private->win, Private->gc,
a4902ccc 536 Args->DestinationX, Args->DestinationY, Args->Width, Args->Height);
288a3c98 537 XFlush(Private->display);
804405e7 538 break;
288a3c98 539 case EfiUgaBltBufferToVideo:
a4902ccc 540 Redraw(Private, Args->DestinationX, Args->DestinationY, Args->Width, Args->Height);
804405e7 541 break;
542 default:
543 break;
544 }
545 return EFI_SUCCESS;
546}
547
548EFI_STATUS
549UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL **Uga, CONST CHAR16 *Title)
550{
551 UGA_IO_PRIVATE *drv;
552 unsigned int border_width = 0;
553 char *display_name = NULL;
554 int title_len;
555
ccd55824 556 drv = (UGA_IO_PRIVATE *)calloc (1, sizeof (UGA_IO_PRIVATE));
804405e7 557 if (drv == NULL)
558 return EFI_OUT_OF_RESOURCES;
559
ccd55824 560#ifdef __APPLE__
561//
562//
563//
564EFI_STATUS EFIAPI GasketUgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo);
565EFI_STATUS EFIAPI GasketUgaSize (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height);
566EFI_STATUS EFIAPI GasketUgaCheckKey (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo);
567EFI_STATUS EFIAPI GasketUgaGetKey (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key);
568EFI_STATUS EFIAPI GasketUgaBlt (
a4902ccc 569 EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
ccd55824 570 IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
571 IN EFI_UGA_BLT_OPERATION BltOperation,
a4902ccc 572 IN UGA_BLT_ARGS *Args
ccd55824 573 );
574
575 drv->UgaIo.UgaClose = GasketUgaClose;
576 drv->UgaIo.UgaSize = GasketUgaSize;
577 drv->UgaIo.UgaCheckKey = GasketUgaCheckKey;
578 drv->UgaIo.UgaGetKey = GasketUgaGetKey;
579 drv->UgaIo.UgaBlt = GasketUgaBlt;
580#else
804405e7 581 drv->UgaIo.UgaClose = UgaClose;
582 drv->UgaIo.UgaSize = UgaSize;
583 drv->UgaIo.UgaCheckKey = UgaCheckKey;
584 drv->UgaIo.UgaGetKey = UgaGetKey;
585 drv->UgaIo.UgaBlt = UgaBlt;
ccd55824 586#endif
587
588
804405e7 589
590 drv->key_count = 0;
591 drv->key_rd = 0;
592 drv->key_wr = 0;
593 drv->display = XOpenDisplay (display_name);
594 if (drv->display == NULL)
595 {
596 fprintf (stderr, "uga: cannot connect to X server %s\n",
288a3c98 597 XDisplayName (display_name));
804405e7 598 free (drv);
599 return EFI_DEVICE_ERROR;
600 }
601 drv->screen = DefaultScreen (drv->display);
602 drv->visual = DefaultVisual (drv->display, drv->screen);
603 drv->win = XCreateSimpleWindow
288a3c98 604 (drv->display, RootWindow (drv->display, drv->screen),
605 0, 0, 4, 4, border_width,
606 WhitePixel (drv->display, drv->screen),
607 BlackPixel (drv->display, drv->screen));
804405e7 608
609 drv->depth = DefaultDepth (drv->display, drv->screen);
610
611 /* Compute title len and convert to Ascii. */
612 for (title_len = 0; Title[title_len] != 0; title_len++)
613 ;
614 {
615 char title[title_len + 1];
616 int i;
617 for (i = 0; i < title_len; i++)
618 title[i] = Title[i];
619 title[i] = 0;
620
621 XStoreName (drv->display, drv->win, title);
622 }
623
b9c8e50e 624 XSelectInput (drv->display, drv->win, ExposureMask | KeyPressMask);
625
804405e7 626 drv->gc = DefaultGC (drv->display, drv->screen);
627
628 *Uga = (EFI_UNIX_UGA_IO_PROTOCOL *)drv;
629 return EFI_SUCCESS;
630}