3 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #include <Common/UnixInclude.h>
20 #include <Protocol/SimplePointer.h>
21 #include <Protocol/SimpleTextIn.h>
22 #include <Protocol/SimpleTextInEx.h>
23 #include <Protocol/UgaDraw.h>
25 #include <X11/Xutil.h>
27 #include <X11/extensions/XShm.h>
28 #include <X11/keysym.h>
29 #include <X11/cursorfont.h>
31 #include <Protocol/UnixThunk.h>
32 #include <Protocol/UnixUgaIo.h>
34 #include <Ppi/StatusCode.h>
36 #include <Library/PeCoffLib.h>
37 #include <Library/BaseLib.h>
38 #include <Library/BaseMemoryLib.h>
39 #include <Library/PrintLib.h>
40 #include <Library/PcdLib.h>
41 #include <Library/DebugLib.h>
47 extern void msSleep (unsigned long Milliseconds
);
51 struct uga_drv_shift_mask
{
59 EFI_UNIX_UGA_IO_PROTOCOL UgaIo
;
62 int screen
; /* values for window_size in main */
70 unsigned int line_bytes
;
71 unsigned int pixel_shift
;
72 unsigned char *image_data
;
74 struct uga_drv_shift_mask r
, g
, b
;
77 XShmSegmentInfo xshm_info
;
82 unsigned int key_count
;
83 EFI_KEY_DATA keys
[NBR_KEYS
];
85 EFI_KEY_STATE KeyState
;
87 UGA_REGISTER_KEY_NOTIFY_CALLBACK RegisterdKeyCallback
;
88 VOID
*RegisterdKeyCallbackContext
;
92 EFI_SIMPLE_POINTER_STATE pointer_state
;
93 int pointer_state_changed
;
97 HandleEvents(UGA_IO_PRIVATE
*drv
);
100 fill_shift_mask (struct uga_drv_shift_mask
*sm
, unsigned long mask
)
104 while ((mask
& 1) == 0)
114 sm
->csize
= 8 - sm
->size
;
118 TryCreateShmImage(UGA_IO_PRIVATE
*drv
)
120 drv
->image
= XShmCreateImage (drv
->display
, drv
->visual
,
121 drv
->depth
, ZPixmap
, NULL
, &drv
->xshm_info
,
122 drv
->width
, drv
->height
);
123 if (drv
->image
== NULL
)
126 switch (drv
->image
->bitmap_unit
) {
128 drv
->pixel_shift
= 2;
131 drv
->pixel_shift
= 1;
134 drv
->pixel_shift
= 0;
138 drv
->xshm_info
.shmid
= shmget
139 (IPC_PRIVATE
, drv
->image
->bytes_per_line
* drv
->image
->height
,
141 if (drv
->xshm_info
.shmid
< 0) {
142 XDestroyImage(drv
->image
);
146 drv
->image_data
= shmat (drv
->xshm_info
.shmid
, NULL
, 0);
147 if(!drv
->image_data
) {
148 shmctl (drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
149 XDestroyImage(drv
->image
);
155 // This closes shared memory in real time on OS X. Only closes after folks quit using
158 /* Can this fail ? */
159 shmctl (drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
162 drv
->xshm_info
.shmaddr
= (char*)drv
->image_data
;
163 drv
->image
->data
= (char*)drv
->image_data
;
165 if (!XShmAttach (drv
->display
, &drv
->xshm_info
)) {
166 shmdt (drv
->image_data
);
167 XDestroyImage(drv
->image
);
174 UgaClose (EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
)
176 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
180 if (drv
->image
!= NULL
)
182 XDestroyImage(drv
->image
);
185 shmdt (drv
->image_data
);
187 drv
->image_data
= NULL
;
190 XDestroyWindow(drv
->display
, drv
->win
);
191 XCloseDisplay(drv
->display
);
194 // Free up the shared memory
195 shmctl (drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
203 UgaSize(EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
, UINT32 Width
, UINT32 Height
)
205 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
206 XSizeHints size_hints
;
208 /* Destroy current buffer if created. */
209 if (drv
->image
!= NULL
)
211 /* Before destroy buffer, need to make sure the buffer available for access. */
212 XDestroyImage(drv
->image
);
215 shmdt (drv
->image_data
);
217 drv
->image_data
= NULL
;
222 drv
->height
= Height
;
223 XResizeWindow (drv
->display
, drv
->win
, Width
, Height
);
225 /* Allocate image. */
226 if (XShmQueryExtension(drv
->display
) && TryCreateShmImage(drv
)) {
231 drv
->pixel_shift
= 2;
232 else if (drv
->depth
> 8)
233 drv
->pixel_shift
= 1;
235 drv
->pixel_shift
= 0;
237 drv
->image_data
= malloc((drv
->width
* drv
->height
) << drv
->pixel_shift
);
238 drv
->image
= XCreateImage (drv
->display
, drv
->visual
, drv
->depth
,
239 ZPixmap
, 0, (char *)drv
->image_data
,
240 drv
->width
, drv
->height
,
241 8 << drv
->pixel_shift
, 0);
243 drv
->line_bytes
= drv
->image
->bytes_per_line
;
244 fill_shift_mask (&drv
->r
, drv
->image
->red_mask
);
245 fill_shift_mask (&drv
->g
, drv
->image
->green_mask
);
246 fill_shift_mask (&drv
->b
, drv
->image
->blue_mask
);
249 size_hints
.flags
= PSize
| PMinSize
| PMaxSize
;
250 size_hints
.min_width
= size_hints
.max_width
= size_hints
.base_width
= Width
;
251 size_hints
.min_height
= size_hints
.max_height
= size_hints
.base_height
= Height
;
252 XSetWMNormalHints (drv
->display
, drv
->win
, &size_hints
);
254 XMapWindow (drv
->display
, drv
->win
);
260 handleKeyEvent(UGA_IO_PRIVATE
*drv
, XEvent
*ev
)
264 EFI_KEY_DATA KeyData
;
267 if (drv
->key_count
== NBR_KEYS
)
270 res
= XLookupString(&ev
->xkey
, str
, sizeof(str
), &keysym
, NULL
);
271 KeyData
.Key
.ScanCode
= 0;
272 KeyData
.Key
.UnicodeChar
= 0;
273 KeyData
.KeyState
.KeyShiftState
= 0;
276 // KeyRelease is not supported (on Mac) so we can not easily implement Ex functions.
277 // If a modifier key is hit by its self we get a keysym. If a modfifier and key is hit
278 // we get the state bit set and keysym is the modified key.
280 // We use lack of state bits being set to clear ToggleState and KeyShiftState. We can
281 // also use the stat bits to set ToggleState and KeyShiftState.
282 // Skipping EFI_SCROLL_LOCK_ACTIVE & EFI_NUM_LOCK_ACTIVE since they are not on Macs
284 if ((ev
->xkey
.state
& LockMask
) == 0) {
285 drv
->KeyState
.KeyToggleState
&= ~EFI_CAPS_LOCK_ACTIVE
;
287 drv
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
290 if ((ev
->xkey
.state
& ControlMask
) == 0) {
291 drv
->KeyState
.KeyShiftState
&= ~(EFI_RIGHT_CONTROL_PRESSED
| EFI_LEFT_CONTROL_PRESSED
);
292 } else if ((drv
->KeyState
.KeyShiftState
& EFI_RIGHT_CONTROL_PRESSED
) == 0) {
293 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
296 if ((ev
->xkey
.state
& ShiftMask
) == 0) {
297 drv
->KeyState
.KeyShiftState
&= ~(EFI_RIGHT_SHIFT_PRESSED
| EFI_LEFT_SHIFT_PRESSED
);
298 } else if ((drv
->KeyState
.KeyShiftState
& EFI_RIGHT_SHIFT_PRESSED
) == 0) {
299 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
302 if ((ev
->xkey
.state
& Mod2Mask
) == 0) {
303 drv
->KeyState
.KeyShiftState
&= ~(EFI_RIGHT_LOGO_PRESSED
| EFI_LEFT_LOGO_PRESSED
);
304 } else if ((drv
->KeyState
.KeyShiftState
& EFI_RIGHT_LOGO_PRESSED
) == 0) {
305 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
308 if ((ev
->xkey
.state
& 0x2000) == 0) {
309 drv
->KeyState
.KeyShiftState
&= ~(EFI_LEFT_ALT_PRESSED
);
311 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
317 drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
320 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
324 drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
327 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
331 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
335 drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
338 drv
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
341 case XK_Home
: KeyData
.Key
.ScanCode
= SCAN_HOME
; break;
342 case XK_End
: KeyData
.Key
.ScanCode
= SCAN_END
; break;
343 case XK_Left
: KeyData
.Key
.ScanCode
= SCAN_LEFT
; break;
344 case XK_Right
: KeyData
.Key
.ScanCode
= SCAN_RIGHT
; break;
345 case XK_Up
: KeyData
.Key
.ScanCode
= SCAN_UP
; break;
346 case XK_Down
: KeyData
.Key
.ScanCode
= SCAN_DOWN
; break;
347 case XK_Delete
: KeyData
.Key
.ScanCode
= SCAN_DELETE
; break;
348 case XK_Insert
: KeyData
.Key
.ScanCode
= SCAN_INSERT
; break;
349 case XK_Page_Up
: KeyData
.Key
.ScanCode
= SCAN_PAGE_UP
; break;
350 case XK_Page_Down
: KeyData
.Key
.ScanCode
= SCAN_PAGE_DOWN
; break;
351 case XK_Escape
: KeyData
.Key
.ScanCode
= SCAN_ESC
; break;
352 case XK_Pause
: KeyData
.Key
.ScanCode
= SCAN_PAUSE
; break;
354 case XK_F1
: KeyData
.Key
.ScanCode
= SCAN_F1
; break;
355 case XK_F2
: KeyData
.Key
.ScanCode
= SCAN_F2
; break;
356 case XK_F3
: KeyData
.Key
.ScanCode
= SCAN_F3
; break;
357 case XK_F4
: KeyData
.Key
.ScanCode
= SCAN_F4
; break;
358 case XK_F5
: KeyData
.Key
.ScanCode
= SCAN_F5
; break;
359 case XK_F6
: KeyData
.Key
.ScanCode
= SCAN_F6
; break;
360 case XK_F7
: KeyData
.Key
.ScanCode
= SCAN_F7
; break;
361 case XK_F8
: KeyData
.Key
.ScanCode
= SCAN_F8
; break;
362 case XK_F9
: KeyData
.Key
.ScanCode
= SCAN_F9
; break;
366 KeyData
.Key
.UnicodeChar
= str
[0];
372 // The global state is our state
373 KeyData
.KeyState
.KeyShiftState
= drv
->KeyState
.KeyShiftState
;
374 KeyData
.KeyState
.KeyToggleState
= drv
->KeyState
.KeyToggleState
;
376 CopyMem (&drv
->keys
[drv
->key_wr
], &KeyData
, sizeof (EFI_KEY_DATA
));
377 drv
->key_wr
= (drv
->key_wr
+ 1) % NBR_KEYS
;
381 #if defined(__APPLE__) || defined(MDE_CPU_X64)
382 ReverseGasketUint64Uint64 (drv
->RegisterdKeyCallback
,drv
->RegisterdKeyCallbackContext
, &KeyData
);
384 drv
->RegisterdKeyCallback (drv
->RegisterdKeyCallbackContext
, &KeyData
);
392 handleMouseMoved(UGA_IO_PRIVATE
*drv
, XEvent
*ev
)
394 if ( ev
->xmotion
.x
!= drv
->previous_x
)
396 drv
->pointer_state
.RelativeMovementX
+= ( ev
->xmotion
.x
- drv
->previous_x
);
397 drv
->previous_x
= ev
->xmotion
.x
;
398 drv
->pointer_state_changed
= 1;
401 if ( ev
->xmotion
.y
!= drv
->previous_y
)
403 drv
->pointer_state
.RelativeMovementY
+= ( ev
->xmotion
.y
- drv
->previous_y
);
404 drv
->previous_y
= ev
->xmotion
.y
;
405 drv
->pointer_state_changed
= 1;
408 drv
->pointer_state
.RelativeMovementZ
= 0;
412 handleMouseDown(UGA_IO_PRIVATE
*drv
, XEvent
*ev
, BOOLEAN Pressed
)
414 if ( ev
->xbutton
.button
== Button1
)
416 drv
->pointer_state_changed
= ( drv
->pointer_state
.LeftButton
!= Pressed
);
417 drv
->pointer_state
.LeftButton
= Pressed
;
419 if ( ev
->xbutton
.button
== Button2
)
421 drv
->pointer_state_changed
= ( drv
->pointer_state
.RightButton
!= Pressed
);
422 drv
->pointer_state
.RightButton
= Pressed
;
427 Redraw(UGA_IO_PRIVATE
*drv
, UINTN X
, UINTN Y
, UINTN Width
, UINTN Height
)
430 XShmPutImage (drv
->display
, drv
->win
, drv
->gc
, drv
->image
,
431 X
, Y
, X
, Y
, Width
, Height
, False
);
433 XPutImage (drv
->display
, drv
->win
, drv
->gc
, drv
->image
,
434 X
, Y
, X
, Y
, Width
, Height
);
435 XFlush(drv
->display
);
439 HandleEvent(UGA_IO_PRIVATE
*drv
, XEvent
*ev
)
444 Redraw(drv
, ev
->xexpose
.x
, ev
->xexpose
.y
,
445 ev
->xexpose
.width
, ev
->xexpose
.height
);
448 Redraw(drv
, ev
->xgraphicsexpose
.x
, ev
->xgraphicsexpose
.y
,
449 ev
->xgraphicsexpose
.width
, ev
->xgraphicsexpose
.height
);
452 handleKeyEvent(drv
, ev
);
457 XRefreshKeyboardMapping(&ev
->xmapping
);
460 handleMouseMoved(drv
, ev
);
463 handleMouseDown(drv
, ev
, TRUE
);
466 handleMouseDown(drv
, ev
, FALSE
);
470 XCloseDisplay (drv
->display
);
481 HandleEvents(UGA_IO_PRIVATE
*drv
)
483 while (XPending(drv
->display
) != 0)
487 XNextEvent (drv
->display
, &ev
);
488 HandleEvent(drv
, &ev
);
493 UgaPixelToColor (UGA_IO_PRIVATE
*drv
, EFI_UGA_PIXEL pixel
)
495 return ((pixel
.Red
>> drv
->r
.csize
) << drv
->r
.shift
)
496 | ((pixel
.Green
>> drv
->g
.csize
) << drv
->g
.shift
)
497 | ((pixel
.Blue
>> drv
->b
.csize
) << drv
->b
.shift
);
501 UgaColorToPixel (UGA_IO_PRIVATE
*drv
, unsigned long val
)
505 memset (&res
, 0, sizeof (EFI_UGA_PIXEL
));
506 /* FIXME: should round instead of truncate. */
507 res
.Red
= (val
>> drv
->r
.shift
) << drv
->r
.csize
;
508 res
.Green
= (val
>> drv
->g
.shift
) << drv
->g
.csize
;
509 res
.Blue
= (val
>> drv
->b
.shift
) << drv
->b
.csize
;
515 CheckKeyInternal( UGA_IO_PRIVATE
*drv
, BOOLEAN delay
)
518 if (drv
->key_count
!= 0)
521 /* EFI is polling. Be CPU-friendly. */
523 return EFI_NOT_READY
;
527 UgaCheckKey(EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
)
529 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
530 return( CheckKeyInternal( drv
, TRUE
) );
536 IN EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
,
537 IN EFI_KEY_DATA
*KeyData
540 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
543 status
= CheckKeyInternal(drv
, FALSE
);
544 if (status
!= EFI_SUCCESS
)
547 CopyMem (KeyData
, &drv
->keys
[drv
->key_rd
], sizeof (EFI_KEY_DATA
));
548 drv
->key_rd
= (drv
->key_rd
+ 1) % NBR_KEYS
;
557 IN EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
,
558 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
561 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
564 if (*KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) {
565 if ((drv
->KeyState
.KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) == 0) {
567 // We could create an XKeyEvent and send a XK_Caps_Lock to
568 // the UGA/GOP Window
573 drv
->KeyState
.KeyToggleState
= *KeyToggleState
;
580 UgaRegisterKeyNotify (
581 IN EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
,
582 IN UGA_REGISTER_KEY_NOTIFY_CALLBACK CallBack
,
586 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
588 drv
->RegisterdKeyCallback
= CallBack
;
589 drv
->RegisterdKeyCallbackContext
= Context
;
597 IN EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
,
598 IN EFI_UGA_PIXEL
*BltBuffer OPTIONAL
,
599 IN EFI_UGA_BLT_OPERATION BltOperation
,
600 IN UGA_BLT_ARGS
*Args
603 UGA_IO_PRIVATE
*Private
= (UGA_IO_PRIVATE
*)UgaIo
;
618 if (BltOperation
== EfiUgaVideoToBltBuffer
619 || BltOperation
== EfiUgaVideoToVideo
) {
623 if (Args
->SourceY
+ Args
->Height
> Private
->height
) {
624 return EFI_INVALID_PARAMETER
;
627 if (Args
->SourceX
+ Args
->Width
> Private
->width
) {
628 return EFI_INVALID_PARAMETER
;
632 if (BltOperation
== EfiUgaBltBufferToVideo
633 || BltOperation
== EfiUgaVideoToVideo
634 || BltOperation
== EfiUgaVideoFill
) {
636 // Destination is Video
638 if (Args
->DestinationY
+ Args
->Height
> Private
->height
) {
639 return EFI_INVALID_PARAMETER
;
642 if (Args
->DestinationX
+ Args
->Width
> Private
->width
) {
643 return EFI_INVALID_PARAMETER
;
647 switch (BltOperation
) {
648 case EfiUgaVideoToBltBuffer
:
649 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)BltBuffer
+ (Args
->DestinationY
* Args
->Delta
) + Args
->DestinationX
* sizeof (EFI_UGA_PIXEL
));
650 Args
->Delta
-= Args
->Width
* sizeof (EFI_UGA_PIXEL
);
651 for (SrcY
= Args
->SourceY
; SrcY
< (Args
->Height
+ Args
->SourceY
); SrcY
++) {
652 for (SrcX
= Args
->SourceX
; SrcX
< (Args
->Width
+ Args
->SourceX
); SrcX
++) {
653 *Blt
++ = UgaColorToPixel(Private
,
654 XGetPixel(Private
->image
, SrcX
, SrcY
));
656 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) Blt
+ Args
->Delta
);
659 case EfiUgaBltBufferToVideo
:
660 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)BltBuffer
+ (Args
->SourceY
* Args
->Delta
) + Args
->SourceX
* sizeof (EFI_UGA_PIXEL
));
661 Args
->Delta
-= Args
->Width
* sizeof (EFI_UGA_PIXEL
);
662 for (DstY
= Args
->DestinationY
; DstY
< (Args
->Height
+ Args
->DestinationY
); DstY
++) {
663 for (DstX
= Args
->DestinationX
; DstX
< (Args
->Width
+ Args
->DestinationX
); DstX
++) {
664 XPutPixel(Private
->image
, DstX
, DstY
, UgaPixelToColor(Private
, *Blt
));
667 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) Blt
+ Args
->Delta
);
670 case EfiUgaVideoToVideo
:
671 Dst
= Private
->image_data
+ (Args
->DestinationX
<< Private
->pixel_shift
)
672 + Args
->DestinationY
* Private
->line_bytes
;
673 Src
= Private
->image_data
+ (Args
->SourceX
<< Private
->pixel_shift
)
674 + Args
->SourceY
* Private
->line_bytes
;
675 Nbr
= Args
->Width
<< Private
->pixel_shift
;
676 if (Args
->DestinationY
< Args
->SourceY
) {
677 for (Index
= 0; Index
< Args
->Height
; Index
++) {
678 memcpy (Dst
, Src
, Nbr
);
679 Dst
+= Private
->line_bytes
;
680 Src
+= Private
->line_bytes
;
684 Dst
+= (Args
->Height
- 1) * Private
->line_bytes
;
685 Src
+= (Args
->Height
- 1) * Private
->line_bytes
;
686 for (Index
= 0; Index
< Args
->Height
; Index
++) {
688 // Source and Destination Y may be equal, therefore Dst and Src may
691 memmove (Dst
, Src
, Nbr
);
692 Dst
-= Private
->line_bytes
;
693 Src
-= Private
->line_bytes
;
697 case EfiUgaVideoFill
:
698 Color
= UgaPixelToColor(Private
, *BltBuffer
);
699 for (DstY
= Args
->DestinationY
; DstY
< (Args
->Height
+ Args
->DestinationY
); DstY
++) {
700 for (DstX
= Args
->DestinationX
; DstX
< (Args
->Width
+ Args
->DestinationX
); DstX
++) {
701 XPutPixel(Private
->image
, DstX
, DstY
, Color
);
706 return EFI_INVALID_PARAMETER
;
712 switch (BltOperation
) {
713 case EfiUgaVideoToVideo
:
714 XCopyArea(Private
->display
, Private
->win
, Private
->win
, Private
->gc
,
715 Args
->SourceX
, Args
->SourceY
, Args
->Width
, Args
->Height
, Args
->DestinationX
, Args
->DestinationY
);
719 XNextEvent (Private
->display
, &ev
);
720 HandleEvent(Private
, &ev
);
721 if (ev
.type
== NoExpose
|| ev
.type
== GraphicsExpose
)
725 case EfiUgaVideoFill
:
726 Color
= UgaPixelToColor(Private
, *BltBuffer
);
727 XSetForeground(Private
->display
, Private
->gc
, Color
);
728 XFillRectangle(Private
->display
, Private
->win
, Private
->gc
,
729 Args
->DestinationX
, Args
->DestinationY
, Args
->Width
, Args
->Height
);
730 XFlush(Private
->display
);
732 case EfiUgaBltBufferToVideo
:
733 Redraw(Private
, Args
->DestinationX
, Args
->DestinationY
, Args
->Width
, Args
->Height
);
742 CheckPointerInternal( UGA_IO_PRIVATE
*drv
, BOOLEAN delay
)
745 if (drv
->pointer_state_changed
!= 0)
748 /* EFI is polling. Be CPU-friendly. */
750 return EFI_NOT_READY
;
754 UgaCheckPointer(EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
)
756 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
757 return( CheckPointerInternal( drv
, TRUE
) );
761 UgaGetPointerState (EFI_UNIX_UGA_IO_PROTOCOL
*UgaIo
, EFI_SIMPLE_POINTER_STATE
*state
)
763 UGA_IO_PRIVATE
*drv
= (UGA_IO_PRIVATE
*)UgaIo
;
766 status
= CheckPointerInternal( drv
, FALSE
);
767 if (status
!= EFI_SUCCESS
)
770 memcpy( state
, &drv
->pointer_state
, sizeof( EFI_SIMPLE_POINTER_STATE
) );
772 drv
->pointer_state
.RelativeMovementX
= 0;
773 drv
->pointer_state
.RelativeMovementY
= 0;
774 drv
->pointer_state
.RelativeMovementZ
= 0;
775 drv
->pointer_state_changed
= 0;
780 UgaCreate (EFI_UNIX_UGA_IO_PROTOCOL
**Uga
, CONST CHAR16
*Title
)
783 unsigned int border_width
= 0;
784 char *display_name
= NULL
;
787 drv
= (UGA_IO_PRIVATE
*)calloc (1, sizeof (UGA_IO_PRIVATE
));
789 return EFI_OUT_OF_RESOURCES
;
791 #if defined(__APPLE__) || defined(MDE_CPU_X64)
795 drv
->UgaIo
.UgaClose
= GasketUgaClose
;
796 drv
->UgaIo
.UgaSize
= GasketUgaSize
;
797 drv
->UgaIo
.UgaCheckKey
= GasketUgaCheckKey
;
798 drv
->UgaIo
.UgaGetKey
= GasketUgaGetKey
;
799 drv
->UgaIo
.UgaKeySetState
= GasketUgaKeySetState
;
800 drv
->UgaIo
.UgaRegisterKeyNotify
= GasketUgaRegisterKeyNotify
;
801 drv
->UgaIo
.UgaBlt
= GasketUgaBlt
;
802 drv
->UgaIo
.UgaCheckPointer
= GasketUgaCheckPointer
;
803 drv
->UgaIo
.UgaGetPointerState
= GasketUgaGetPointerState
;
805 drv
->UgaIo
.UgaClose
= UgaClose
;
806 drv
->UgaIo
.UgaSize
= UgaSize
;
807 drv
->UgaIo
.UgaCheckKey
= UgaCheckKey
;
808 drv
->UgaIo
.UgaGetKey
= UgaGetKey
;
809 drv
->UgaIo
.UgaKeySetState
= UgaKeySetState
;
810 drv
->UgaIo
.UgaRegisterKeyNotify
= UgaRegisterKeyNotify
;
811 drv
->UgaIo
.UgaBlt
= UgaBlt
;
812 drv
->UgaIo
.UgaCheckPointer
= UgaCheckPointer
;
813 drv
->UgaIo
.UgaGetPointerState
= UgaGetPointerState
;
821 drv
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
822 drv
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
823 drv
->RegisterdKeyCallback
= NULL
;
824 drv
->RegisterdKeyCallbackContext
= NULL
;
827 drv
->display
= XOpenDisplay (display_name
);
828 if (drv
->display
== NULL
)
830 fprintf (stderr
, "uga: cannot connect to X server %s\n",
831 XDisplayName (display_name
));
833 return EFI_DEVICE_ERROR
;
835 drv
->screen
= DefaultScreen (drv
->display
);
836 drv
->visual
= DefaultVisual (drv
->display
, drv
->screen
);
837 drv
->win
= XCreateSimpleWindow
838 (drv
->display
, RootWindow (drv
->display
, drv
->screen
),
839 0, 0, 4, 4, border_width
,
840 WhitePixel (drv
->display
, drv
->screen
),
841 BlackPixel (drv
->display
, drv
->screen
));
843 drv
->depth
= DefaultDepth (drv
->display
, drv
->screen
);
844 XDefineCursor (drv
->display
, drv
->win
, XCreateFontCursor (drv
->display
, XC_pirate
));
846 /* Compute title len and convert to Ascii. */
847 for (title_len
= 0; Title
[title_len
] != 0; title_len
++)
850 char title
[title_len
+ 1];
852 for (i
= 0; i
< title_len
; i
++)
856 XStoreName (drv
->display
, drv
->win
, title
);
859 XSelectInput (drv
->display
, drv
->win
,
860 ExposureMask
| KeyPressMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
);
861 drv
->gc
= DefaultGC (drv
->display
, drv
->screen
);
863 *Uga
= (EFI_UNIX_UGA_IO_PROTOCOL
*)drv
;