]> git.proxmox.com Git - mirror_edk2.git/blame - UnixPkg/Sec/UgaX11.c
Integrate patch from Andrew Fish to make it run on OS X.
[mirror_edk2.git] / UnixPkg / Sec / UgaX11.c
CommitLineData
ccd55824 1/*++
2
3Copyright (c) 2004 - 2009, Intel Corporation
4Portions copyright (c) 2008-2009 Apple Inc. All rights reserved.
5All rights reserved. This program and the accompanying materials
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);
804405e7 126 if (drv->xshm_info.shmid < 0)
127 {
128 XDestroyImage(drv->image);
129 return 0;
130 }
131
132 drv->image_data = shmat (drv->xshm_info.shmid, NULL, 0);
133 if(!drv->image_data)
134 {
135 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
136 XDestroyImage(drv->image);
137 return 0;
138 }
ccd55824 139
140#ifndef __APPLE__
141 //
142 // This closes shared memory in real time on OS X. Only closes after folks quit using
143 // it on Linux.
144 //
804405e7 145 /* Can this fail ? */
146 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
ccd55824 147#endif
804405e7 148
149 drv->xshm_info.shmaddr = (char*)drv->image_data;
150 drv->image->data = (char*)drv->image_data;
288a3c98 151
804405e7 152 if (!XShmAttach (drv->display, &drv->xshm_info))
153 {
154 shmdt (drv->image_data);
155 XDestroyImage(drv->image);
156 return 0;
157 }
158 return 1;
159}
160
804405e7 161EFI_STATUS
162UgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
163{
164 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
165
166 if (drv == NULL)
167 return EFI_SUCCESS;
168 if (drv->image != NULL)
169 {
170 XDestroyImage(drv->image);
171
172 if (drv->use_shm)
288a3c98 173 shmdt (drv->image_data);
804405e7 174
175 drv->image_data = NULL;
176 drv->image = NULL;
177 }
178 XDestroyWindow(drv->display, drv->win);
179 XCloseDisplay(drv->display);
ccd55824 180
181#ifdef __APPLE__
182 // Free up the shared memory
183 shmctl (drv->xshm_info.shmid, IPC_RMID, NULL);
184#endif
185
804405e7 186 free(drv);
187 return EFI_SUCCESS;
188}
189
804405e7 190EFI_STATUS
191UgaSize(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height)
192{
193 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
194 XSizeHints size_hints;
195
196 /* Destroy current buffer if created. */
197 if (drv->image != NULL)
198 {
7d28e82d 199 /* Before destroy buffer, need to make sure the buffer available for access. */
804405e7 200 XDestroyImage(drv->image);
201
202 if (drv->use_shm)
288a3c98 203 shmdt (drv->image_data);
804405e7 204
205 drv->image_data = NULL;
206 drv->image = NULL;
207 }
208
209 drv->width = Width;
210 drv->height = Height;
211 XResizeWindow (drv->display, drv->win, Width, Height);
212
213 /* Allocate image. */
288a3c98 214 if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv)) {
215 drv->use_shm = 1;
216 } else {
217 drv->use_shm = 0;
218 if (drv->depth > 16)
219 drv->pixel_shift = 2;
220 else if (drv->depth > 8)
221 drv->pixel_shift = 1;
222 else
223 drv->pixel_shift = 0;
804405e7 224
225 drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift);
226 drv->image = XCreateImage (drv->display, drv->visual, drv->depth,
288a3c98 227 ZPixmap, 0, (char *)drv->image_data,
228 drv->width, drv->height,
229 8 << drv->pixel_shift, 0);
804405e7 230 }
231 drv->line_bytes = drv->image->bytes_per_line;
232 fill_shift_mask (&drv->r, drv->image->red_mask);
233 fill_shift_mask (&drv->g, drv->image->green_mask);
234 fill_shift_mask (&drv->b, drv->image->blue_mask);
235
236 /* Set WM hints. */
237 size_hints.flags = PSize | PMinSize | PMaxSize;
238 size_hints.min_width = size_hints.max_width = size_hints.base_width = Width;
239 size_hints.min_height = size_hints.max_height = size_hints.base_height = Height;
240 XSetWMNormalHints (drv->display, drv->win, &size_hints);
241
242 XMapWindow (drv->display, drv->win);
243 HandleEvents(drv);
244 return EFI_SUCCESS;
245}
246
7492c63d 247void
804405e7 248handleKeyEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
249{
250 KeySym keysym;
251 char str[4];
252 EFI_INPUT_KEY Key;
253 int res;
254
255 if (drv->key_count == NBR_KEYS)
256 return;
257
258 res = XLookupString(&ev->xkey, str, sizeof(str), &keysym, NULL);
288a3c98 259 Key.ScanCode = 0;
804405e7 260 Key.UnicodeChar = 0;
288a3c98 261 switch (keysym) {
262 case XK_Home: Key.ScanCode = SCAN_HOME; break;
263 case XK_End: Key.ScanCode = SCAN_END; break;
264 case XK_Left: Key.ScanCode = SCAN_LEFT; break;
265 case XK_Right: Key.ScanCode = SCAN_RIGHT; break;
266 case XK_Up: Key.ScanCode = SCAN_UP; break;
267 case XK_Down: Key.ScanCode = SCAN_DOWN; break;
268 case XK_Delete: Key.ScanCode = SCAN_DELETE; break;
269 case XK_Insert: Key.ScanCode = SCAN_INSERT; break;
270 case XK_Page_Up: Key.ScanCode = SCAN_PAGE_UP; break;
271 case XK_Page_Down: Key.ScanCode = SCAN_PAGE_DOWN; break;
272 case XK_Escape: Key.ScanCode = SCAN_ESC; break;
273
274 case XK_F1: Key.ScanCode = SCAN_F1; break;
275 case XK_F2: Key.ScanCode = SCAN_F2; break;
276 case XK_F3: Key.ScanCode = SCAN_F3; break;
277 case XK_F4: Key.ScanCode = SCAN_F4; break;
278 case XK_F5: Key.ScanCode = SCAN_F5; break;
279 case XK_F6: Key.ScanCode = SCAN_F6; break;
280 case XK_F7: Key.ScanCode = SCAN_F7; break;
281 case XK_F8: Key.ScanCode = SCAN_F8; break;
282 case XK_F9: Key.ScanCode = SCAN_F9; break;
804405e7 283
284 default:
285 if (res == 1) {
286 Key.UnicodeChar = str[0];
287 } else {
288 return;
289 }
288a3c98 290 }
291
804405e7 292 drv->keys[drv->key_wr] = Key;
293 drv->key_wr = (drv->key_wr + 1) % NBR_KEYS;
294 drv->key_count++;
295}
296
7492c63d 297void
804405e7 298Redraw(UGA_IO_PRIVATE *drv, UINTN X, UINTN Y, UINTN Width, UINTN Height)
299{
300 if (drv->use_shm)
301 XShmPutImage (drv->display, drv->win, drv->gc, drv->image,
288a3c98 302 X, Y, X, Y, Width, Height, False);
804405e7 303 else
304 XPutImage (drv->display, drv->win, drv->gc, drv->image,
288a3c98 305 X, Y, X, Y, Width, Height);
306 XFlush(drv->display);
804405e7 307}
308
7492c63d 309void
804405e7 310HandleEvent(UGA_IO_PRIVATE *drv, XEvent *ev)
311{
312 switch (ev->type)
313 {
314 case Expose:
315 Redraw(drv, ev->xexpose.x, ev->xexpose.y,
288a3c98 316 ev->xexpose.width, ev->xexpose.height);
804405e7 317 break;
318 case GraphicsExpose:
319 Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
288a3c98 320 ev->xgraphicsexpose.width, ev->xgraphicsexpose.height);
804405e7 321 break;
322 case KeyPress:
323 handleKeyEvent(drv, ev);
324 break;
325 case MappingNotify:
326 XRefreshKeyboardMapping(&ev->xmapping);
327 break;
328#if 0
329 case DestroyNotify:
330 XCloseDisplay (drv->display);
331 exit (1);
332 break;
333#endif
334 case NoExpose:
335 default:
336 break;
337 }
338}
339
7492c63d 340void
804405e7 341HandleEvents(UGA_IO_PRIVATE *drv)
342{
343 while (XPending(drv->display) != 0)
344 {
345 XEvent ev;
288a3c98 346
804405e7 347 XNextEvent (drv->display, &ev);
348 HandleEvent(drv, &ev);
349 }
350}
351
804405e7 352unsigned long
353UgaPixelToColor (UGA_IO_PRIVATE *drv, EFI_UGA_PIXEL pixel)
354{
355 return ((pixel.Red >> drv->r.csize) << drv->r.shift)
356 | ((pixel.Green >> drv->g.csize) << drv->g.shift)
357 | ((pixel.Blue >> drv->b.csize) << drv->b.shift);
358}
359
804405e7 360EFI_UGA_PIXEL
361UgaColorToPixel (UGA_IO_PRIVATE *drv, unsigned long val)
362{
363 EFI_UGA_PIXEL res;
364
365 memset (&res, 0, sizeof (EFI_UGA_PIXEL));
366 /* FIXME: should round instead of truncate. */
367 res.Red = (val >> drv->r.shift) << drv->r.csize;
368 res.Green = (val >> drv->g.shift) << drv->g.csize;
369 res.Blue = (val >> drv->b.shift) << drv->b.csize;
370
371 return res;
372}
373
804405e7 374EFI_STATUS
375UgaCheckKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo)
376{
377 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
378 HandleEvents(drv);
379 if (drv->key_count != 0)
380 return EFI_SUCCESS;
381 else {
382 /* EFI is certainly polling. Be CPU-friendly. */
383 msSleep (20);
384 return EFI_NOT_READY;
385 }
386}
387
804405e7 388EFI_STATUS
389UgaGetKey(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key)
390{
391 UGA_IO_PRIVATE *drv = (UGA_IO_PRIVATE *)UgaIo;
392 EFI_STATUS status;
393
394 status = UgaCheckKey(UgaIo);
395 if (status != EFI_SUCCESS)
396 return status;
397
398 *key = drv->keys[drv->key_rd];
399 drv->key_rd = (drv->key_rd + 1) % NBR_KEYS;
400 drv->key_count--;
401 return EFI_SUCCESS;
402}
403
288a3c98 404EFI_STATUS
804405e7 405UgaBlt(EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
288a3c98 406 IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
407 IN EFI_UGA_BLT_OPERATION BltOperation,
408 IN UINTN SourceX,
409 IN UINTN SourceY,
410 IN UINTN DestinationX,
411 IN UINTN DestinationY,
412 IN UINTN Width,
413 IN UINTN Height,
414 IN UINTN Delta OPTIONAL
415 )
804405e7 416{
417 UGA_IO_PRIVATE *Private = (UGA_IO_PRIVATE *)UgaIo;
288a3c98 418 UINTN DstY;
419 UINTN SrcY;
804405e7 420 UINTN DstX;
421 UINTN SrcX;
422 UINTN Index;
288a3c98 423 EFI_UGA_PIXEL *Blt;
804405e7 424 UINT8 *Dst;
425 UINT8 *Src;
426 UINTN Nbr;
427 unsigned long Color;
428
429 //
430 // Check bounds
431 //
432 if (BltOperation == EfiUgaVideoToBltBuffer
288a3c98 433 || BltOperation == EfiUgaVideoToVideo) {
434 //
804405e7 435 // Source is Video.
288a3c98 436 //
437 if (SourceY + Height > Private->height) {
438 return EFI_INVALID_PARAMETER;
439 }
440
441 if (SourceX + Width > Private->width) {
442 return EFI_INVALID_PARAMETER;
443 }
804405e7 444 }
445
446 if (BltOperation == EfiUgaBltBufferToVideo
447 || BltOperation == EfiUgaVideoToVideo
288a3c98 448 || BltOperation == EfiUgaVideoFill) {
449 //
450 // Destination is Video
451 //
452 if (DestinationY + Height > Private->height) {
453 return EFI_INVALID_PARAMETER;
454 }
455
456 if (DestinationX + Width > Private->width) {
457 return EFI_INVALID_PARAMETER;
458 }
804405e7 459 }
460
288a3c98 461 switch (BltOperation) {
804405e7 462 case EfiUgaVideoToBltBuffer:
288a3c98 463 Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (DestinationY * Delta) + DestinationX * sizeof (EFI_UGA_PIXEL));
804405e7 464 Delta -= Width * sizeof (EFI_UGA_PIXEL);
288a3c98 465 for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) {
804405e7 466 for (SrcX = SourceX; SrcX < (Width + SourceX); SrcX++) {
288a3c98 467 *Blt++ = UgaColorToPixel(Private,
468 XGetPixel(Private->image, SrcX, SrcY));
804405e7 469 }
470 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
288a3c98 471 }
804405e7 472 break;
288a3c98 473 case EfiUgaBltBufferToVideo:
474 Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (SourceY * Delta) + SourceX * sizeof (EFI_UGA_PIXEL));
804405e7 475 Delta -= Width * sizeof (EFI_UGA_PIXEL);
288a3c98 476 for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
477 for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
478 XPutPixel(Private->image, DstX, DstY, UgaPixelToColor(Private, *Blt));
479 Blt++;
804405e7 480 }
481 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Delta);
482 }
483 break;
288a3c98 484 case EfiUgaVideoToVideo:
804405e7 485 Dst = Private->image_data + (DestinationX << Private->pixel_shift)
486 + DestinationY * Private->line_bytes;
487 Src = Private->image_data + (SourceX << Private->pixel_shift)
488 + SourceY * Private->line_bytes;
489 Nbr = Width << Private->pixel_shift;
288a3c98 490 if (DestinationY < SourceY) {
804405e7 491 for (Index = 0; Index < Height; Index++) {
288a3c98 492 memcpy (Dst, Src, Nbr);
493 Dst += Private->line_bytes;
494 Src += Private->line_bytes;
804405e7 495 }
496 }
497 else {
498 Dst += (Height - 1) * Private->line_bytes;
499 Src += (Height - 1) * Private->line_bytes;
500 for (Index = 0; Index < Height; Index++) {
288a3c98 501 //
502 // Source and Destination Y may be equal, therefore Dst and Src may
503 // overlap.
504 //
505 memmove (Dst, Src, Nbr);
506 Dst -= Private->line_bytes;
507 Src -= Private->line_bytes;
804405e7 508 }
509 }
510 break;
511 case EfiUgaVideoFill:
512 Color = UgaPixelToColor(Private, *BltBuffer);
288a3c98 513 for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
804405e7 514 for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
288a3c98 515 XPutPixel(Private->image, DstX, DstY, Color);
804405e7 516 }
288a3c98 517 }
804405e7 518 break;
519 default:
288a3c98 520 return EFI_INVALID_PARAMETER;
804405e7 521 }
522
523 //
524 // Refresh screen.
525 //
288a3c98 526 switch (BltOperation) {
527 case EfiUgaVideoToVideo:
804405e7 528 XCopyArea(Private->display, Private->win, Private->win, Private->gc,
288a3c98 529 SourceX, SourceY, Width, Height, DestinationX, DestinationY);
804405e7 530 while (1) {
531 XEvent ev;
288a3c98 532
804405e7 533 XNextEvent (Private->display, &ev);
534 HandleEvent(Private, &ev);
535 if (ev.type == NoExpose || ev.type == GraphicsExpose)
288a3c98 536 break;
804405e7 537 }
538 break;
539 case EfiUgaVideoFill:
540 Color = UgaPixelToColor(Private, *BltBuffer);
541 XSetForeground(Private->display, Private->gc, Color);
542 XFillRectangle(Private->display, Private->win, Private->gc,
288a3c98 543 DestinationX, DestinationY, Width, Height);
544 XFlush(Private->display);
804405e7 545 break;
288a3c98 546 case EfiUgaBltBufferToVideo:
804405e7 547 Redraw(Private, DestinationX, DestinationY, Width, Height);
548 break;
549 default:
550 break;
551 }
552 return EFI_SUCCESS;
553}
554
555EFI_STATUS
556UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL **Uga, CONST CHAR16 *Title)
557{
558 UGA_IO_PRIVATE *drv;
559 unsigned int border_width = 0;
560 char *display_name = NULL;
561 int title_len;
562
ccd55824 563 drv = (UGA_IO_PRIVATE *)calloc (1, sizeof (UGA_IO_PRIVATE));
804405e7 564 if (drv == NULL)
565 return EFI_OUT_OF_RESOURCES;
566
ccd55824 567#ifdef __APPLE__
568//
569//
570//
571EFI_STATUS EFIAPI GasketUgaClose (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo);
572EFI_STATUS EFIAPI GasketUgaSize (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, UINT32 Width, UINT32 Height);
573EFI_STATUS EFIAPI GasketUgaCheckKey (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo);
574EFI_STATUS EFIAPI GasketUgaGetKey (EFI_UNIX_UGA_IO_PROTOCOL *UgaIo, EFI_INPUT_KEY *key);
575EFI_STATUS EFIAPI GasketUgaBlt (
576 EFI_UNIX_UGA_IO_PROTOCOL *UgaIo,
577 IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
578 IN EFI_UGA_BLT_OPERATION BltOperation,
579 IN UINTN SourceX,
580 IN UINTN SourceY,
581 IN UINTN DestinationX,
582 IN UINTN DestinationY,
583 IN UINTN Width,
584 IN UINTN Height,
585 IN UINTN Delta OPTIONAL
586 );
587
588 drv->UgaIo.UgaClose = GasketUgaClose;
589 drv->UgaIo.UgaSize = GasketUgaSize;
590 drv->UgaIo.UgaCheckKey = GasketUgaCheckKey;
591 drv->UgaIo.UgaGetKey = GasketUgaGetKey;
592 drv->UgaIo.UgaBlt = GasketUgaBlt;
593#else
804405e7 594 drv->UgaIo.UgaClose = UgaClose;
595 drv->UgaIo.UgaSize = UgaSize;
596 drv->UgaIo.UgaCheckKey = UgaCheckKey;
597 drv->UgaIo.UgaGetKey = UgaGetKey;
598 drv->UgaIo.UgaBlt = UgaBlt;
ccd55824 599#endif
600
601
804405e7 602
603 drv->key_count = 0;
604 drv->key_rd = 0;
605 drv->key_wr = 0;
606 drv->display = XOpenDisplay (display_name);
607 if (drv->display == NULL)
608 {
609 fprintf (stderr, "uga: cannot connect to X server %s\n",
288a3c98 610 XDisplayName (display_name));
804405e7 611 free (drv);
612 return EFI_DEVICE_ERROR;
613 }
614 drv->screen = DefaultScreen (drv->display);
615 drv->visual = DefaultVisual (drv->display, drv->screen);
616 drv->win = XCreateSimpleWindow
288a3c98 617 (drv->display, RootWindow (drv->display, drv->screen),
618 0, 0, 4, 4, border_width,
619 WhitePixel (drv->display, drv->screen),
620 BlackPixel (drv->display, drv->screen));
804405e7 621
622 drv->depth = DefaultDepth (drv->display, drv->screen);
623
624 /* Compute title len and convert to Ascii. */
625 for (title_len = 0; Title[title_len] != 0; title_len++)
626 ;
627 {
628 char title[title_len + 1];
629 int i;
630 for (i = 0; i < title_len; i++)
631 title[i] = Title[i];
632 title[i] = 0;
633
634 XStoreName (drv->display, drv->win, title);
635 }
636
637 XSelectInput (drv->display, drv->win,
288a3c98 638 ExposureMask | KeyPressMask);
804405e7 639 drv->gc = DefaultGC (drv->display, drv->screen);
640
641 *Uga = (EFI_UNIX_UGA_IO_PROTOCOL *)drv;
642 return EFI_SUCCESS;
643}