3 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include <X11/Xutil.h>
18 #include <X11/extensions/XShm.h>
19 #include <X11/keysym.h>
20 #include <X11/cursorfont.h>
22 #define KEYSYM_LOWER 0
23 #define KEYSYM_UPPER 1
25 struct uga_drv_shift_mask
{
33 EMU_GRAPHICS_WINDOW_PROTOCOL GraphicsIo
;
36 int screen
; // values for window_size in main
44 unsigned int line_bytes
;
45 unsigned int pixel_shift
;
46 unsigned char *image_data
;
48 struct uga_drv_shift_mask r
, g
, b
;
51 XShmSegmentInfo xshm_info
;
57 unsigned int key_count
;
58 EFI_KEY_DATA keys
[NBR_KEYS
];
60 EFI_KEY_STATE KeyState
;
62 EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeRegisterdKeyCallback
;
63 EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakRegisterdKeyCallback
;
64 VOID
*RegisterdKeyCallbackContext
;
68 EFI_SIMPLE_POINTER_STATE pointer_state
;
69 int pointer_state_changed
;
70 } GRAPHICS_IO_PRIVATE
;
74 IN GRAPHICS_IO_PRIVATE
*Drv
79 IN
struct uga_drv_shift_mask
*sm
,
85 while ((mask
& 1) == 0) {
95 sm
->csize
= 8 - sm
->size
;
100 IN GRAPHICS_IO_PRIVATE
*Drv
103 Drv
->image
= XShmCreateImage (
113 if (Drv
->image
== NULL
) {
117 switch (Drv
->image
->bitmap_unit
) {
119 Drv
->pixel_shift
= 2;
122 Drv
->pixel_shift
= 1;
125 Drv
->pixel_shift
= 0;
129 Drv
->xshm_info
.shmid
= shmget (
131 Drv
->image
->bytes_per_line
* Drv
->image
->height
,
134 if (Drv
->xshm_info
.shmid
< 0) {
135 XDestroyImage (Drv
->image
);
139 Drv
->image_data
= shmat (Drv
->xshm_info
.shmid
, NULL
, 0);
140 if (!Drv
->image_data
) {
141 shmctl (Drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
142 XDestroyImage (Drv
->image
);
148 // This closes shared memory in real time on OS X. Only closes after folks quit using
151 shmctl (Drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
154 Drv
->xshm_info
.shmaddr
= (char *)Drv
->image_data
;
155 Drv
->image
->data
= (char *)Drv
->image_data
;
157 if (!XShmAttach (Drv
->display
, &Drv
->xshm_info
)) {
158 shmdt (Drv
->image_data
);
159 XDestroyImage (Drv
->image
);
168 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
173 GRAPHICS_IO_PRIVATE
*Drv
;
174 XSizeHints size_hints
;
176 // Destroy current buffer if created.
177 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
178 if (Drv
->image
!= NULL
) {
179 // Before destroy buffer, need to make sure the buffer available for access.
180 XDestroyImage (Drv
->image
);
183 shmdt (Drv
->image_data
);
186 Drv
->image_data
= NULL
;
191 Drv
->height
= Height
;
192 XResizeWindow (Drv
->display
, Drv
->win
, Width
, Height
);
195 if (XShmQueryExtension (Drv
->display
) && TryCreateShmImage (Drv
)) {
199 if (Drv
->depth
> 16) {
200 Drv
->pixel_shift
= 2;
201 } else if (Drv
->depth
> 8) {
202 Drv
->pixel_shift
= 1;
204 Drv
->pixel_shift
= 0;
207 Drv
->image_data
= malloc ((Drv
->width
* Drv
->height
) << Drv
->pixel_shift
);
208 Drv
->image
= XCreateImage (
214 (char *)Drv
->image_data
,
217 8 << Drv
->pixel_shift
,
222 Drv
->line_bytes
= Drv
->image
->bytes_per_line
;
224 fill_shift_mask (&Drv
->r
, Drv
->image
->red_mask
);
225 fill_shift_mask (&Drv
->g
, Drv
->image
->green_mask
);
226 fill_shift_mask (&Drv
->b
, Drv
->image
->blue_mask
);
229 size_hints
.flags
= PSize
| PMinSize
| PMaxSize
;
230 size_hints
.min_width
= size_hints
.max_width
= size_hints
.base_width
= Width
;
231 size_hints
.min_height
= size_hints
.max_height
= size_hints
.base_height
= Height
;
232 XSetWMNormalHints (Drv
->display
, Drv
->win
, &size_hints
);
234 XMapWindow (Drv
->display
, Drv
->win
);
241 IN GRAPHICS_IO_PRIVATE
*Drv
,
247 EFI_KEY_DATA KeyData
;
251 if (Drv
->key_count
== NBR_KEYS
) {
256 // keycode is a physical key on the keyboard
257 // KeySym is a mapping of a physical key
258 // KeyboardMapping is the array of KeySym for a given keycode. key, shifted key, option key, command key, ...
260 // Returns an array of KeySymArraySize of KeySym for the keycode. [0] is lower case, [1] is upper case,
261 // [2] and [3] are based on option and command modifiers. The problem we have is command V
262 // could be mapped to a crazy Unicode character so the old scheme of returning a string.
264 KeySym
= XGetKeyboardMapping (Drv
->display
, ev
->xkey
.keycode
, 1, &KeySymArraySize
);
266 KeyData
.Key
.ScanCode
= 0;
267 KeyData
.Key
.UnicodeChar
= 0;
268 KeyData
.KeyState
.KeyShiftState
= 0;
271 // Skipping EFI_SCROLL_LOCK_ACTIVE & EFI_NUM_LOCK_ACTIVE since they are not on Macs
273 if ((ev
->xkey
.state
& LockMask
) == 0) {
274 Drv
->KeyState
.KeyToggleState
&= ~EFI_CAPS_LOCK_ACTIVE
;
277 Drv
->KeyState
.KeyToggleState
|= EFI_CAPS_LOCK_ACTIVE
;
281 // Skipping EFI_MENU_KEY_PRESSED and EFI_SYS_REQ_PRESSED
286 Drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_CONTROL_PRESSED
;
288 Drv
->KeyState
.KeyShiftState
&= ~EFI_RIGHT_CONTROL_PRESSED
;
294 Drv
->KeyState
.KeyShiftState
|= EFI_LEFT_CONTROL_PRESSED
;
296 Drv
->KeyState
.KeyShiftState
&= ~EFI_LEFT_CONTROL_PRESSED
;
303 Drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_SHIFT_PRESSED
;
305 Drv
->KeyState
.KeyShiftState
&= ~EFI_RIGHT_SHIFT_PRESSED
;
311 Drv
->KeyState
.KeyShiftState
|= EFI_LEFT_SHIFT_PRESSED
;
313 Drv
->KeyState
.KeyShiftState
&= ~EFI_LEFT_SHIFT_PRESSED
;
320 Drv
->KeyState
.KeyShiftState
|= EFI_LEFT_ALT_PRESSED
;
322 Drv
->KeyState
.KeyShiftState
&= ~EFI_LEFT_ALT_PRESSED
;
329 Drv
->KeyState
.KeyShiftState
|= EFI_RIGHT_LOGO_PRESSED
;
331 Drv
->KeyState
.KeyShiftState
&= ~EFI_RIGHT_LOGO_PRESSED
;
337 Drv
->KeyState
.KeyShiftState
|= EFI_LEFT_LOGO_PRESSED
;
339 Drv
->KeyState
.KeyShiftState
&= ~EFI_LEFT_LOGO_PRESSED
;
345 case XK_Home
: KeyData
.Key
.ScanCode
= SCAN_HOME
;
349 case XK_End
: KeyData
.Key
.ScanCode
= SCAN_END
;
353 case XK_Left
: KeyData
.Key
.ScanCode
= SCAN_LEFT
;
357 case XK_Right
: KeyData
.Key
.ScanCode
= SCAN_RIGHT
;
361 case XK_Up
: KeyData
.Key
.ScanCode
= SCAN_UP
;
365 case XK_Down
: KeyData
.Key
.ScanCode
= SCAN_DOWN
;
369 case XK_Delete
: KeyData
.Key
.ScanCode
= SCAN_DELETE
;
373 case XK_Insert
: KeyData
.Key
.ScanCode
= SCAN_INSERT
;
377 case XK_Page_Up
: KeyData
.Key
.ScanCode
= SCAN_PAGE_UP
;
380 case XK_KP_Page_Down
:
381 case XK_Page_Down
: KeyData
.Key
.ScanCode
= SCAN_PAGE_DOWN
;
384 case XK_Escape
: KeyData
.Key
.ScanCode
= SCAN_ESC
;
387 case XK_Pause
: KeyData
.Key
.ScanCode
= SCAN_PAUSE
;
391 case XK_F1
: KeyData
.Key
.ScanCode
= SCAN_F1
;
395 case XK_F2
: KeyData
.Key
.ScanCode
= SCAN_F2
;
399 case XK_F3
: KeyData
.Key
.ScanCode
= SCAN_F3
;
403 case XK_F4
: KeyData
.Key
.ScanCode
= SCAN_F4
;
406 case XK_F5
: KeyData
.Key
.ScanCode
= SCAN_F5
;
408 case XK_F6
: KeyData
.Key
.ScanCode
= SCAN_F6
;
410 case XK_F7
: KeyData
.Key
.ScanCode
= SCAN_F7
;
413 // Don't map into X11 by default on a Mac
414 // System Preferences->Keyboard->Keyboard Shortcuts can be configured
415 // to not use higher function keys as shortcuts and the will show up
417 case XK_F8
: KeyData
.Key
.ScanCode
= SCAN_F8
;
419 case XK_F9
: KeyData
.Key
.ScanCode
= SCAN_F9
;
421 case XK_F10
: KeyData
.Key
.ScanCode
= SCAN_F10
;
424 case XK_F11
: KeyData
.Key
.ScanCode
= SCAN_F11
;
426 case XK_F12
: KeyData
.Key
.ScanCode
= SCAN_F12
;
429 case XK_F13
: KeyData
.Key
.ScanCode
= SCAN_F13
;
431 case XK_F14
: KeyData
.Key
.ScanCode
= SCAN_F14
;
433 case XK_F15
: KeyData
.Key
.ScanCode
= SCAN_F15
;
435 case XK_F16
: KeyData
.Key
.ScanCode
= SCAN_F16
;
437 case XK_F17
: KeyData
.Key
.ScanCode
= SCAN_F17
;
439 case XK_F18
: KeyData
.Key
.ScanCode
= SCAN_F18
;
441 case XK_F19
: KeyData
.Key
.ScanCode
= SCAN_F19
;
443 case XK_F20
: KeyData
.Key
.ScanCode
= SCAN_F20
;
445 case XK_F21
: KeyData
.Key
.ScanCode
= SCAN_F21
;
447 case XK_F22
: KeyData
.Key
.ScanCode
= SCAN_F22
;
449 case XK_F23
: KeyData
.Key
.ScanCode
= SCAN_F23
;
451 case XK_F24
: KeyData
.Key
.ScanCode
= SCAN_F24
;
455 // case XK_: KeyData.Key.ScanCode = SCAN_MUTE; break;
456 // case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_UP; break;
457 // case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_DOWN; break;
458 // case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_UP; break;
459 // case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_DOWN; break;
460 // case XK_: KeyData.Key.ScanCode = SCAN_SUSPEND; break;
461 // case XK_: KeyData.Key.ScanCode = SCAN_HIBERNATE; break;
462 // case XK_: KeyData.Key.ScanCode = SCAN_TOGGLE_DISPLAY; break;
463 // case XK_: KeyData.Key.ScanCode = SCAN_RECOVERY; break;
464 // case XK_: KeyData.Key.ScanCode = SCAN_EJECT; break;
466 case XK_BackSpace
: KeyData
.Key
.UnicodeChar
= 0x0008;
470 case XK_Tab
: KeyData
.Key
.UnicodeChar
= 0x0009;
473 case XK_Linefeed
: KeyData
.Key
.UnicodeChar
= 0x000a;
477 case XK_Return
: KeyData
.Key
.UnicodeChar
= 0x000d;
480 case XK_KP_Equal
: KeyData
.Key
.UnicodeChar
= L
'=';
482 case XK_KP_Multiply
: KeyData
.Key
.UnicodeChar
= L
'*';
484 case XK_KP_Add
: KeyData
.Key
.UnicodeChar
= L
'+';
486 case XK_KP_Separator
: KeyData
.Key
.UnicodeChar
= L
'~';
488 case XK_KP_Subtract
: KeyData
.Key
.UnicodeChar
= L
'-';
490 case XK_KP_Decimal
: KeyData
.Key
.UnicodeChar
= L
'.';
492 case XK_KP_Divide
: KeyData
.Key
.UnicodeChar
= L
'/';
495 case XK_KP_0
: KeyData
.Key
.UnicodeChar
= L
'0';
497 case XK_KP_1
: KeyData
.Key
.UnicodeChar
= L
'1';
499 case XK_KP_2
: KeyData
.Key
.UnicodeChar
= L
'2';
501 case XK_KP_3
: KeyData
.Key
.UnicodeChar
= L
'3';
503 case XK_KP_4
: KeyData
.Key
.UnicodeChar
= L
'4';
505 case XK_KP_5
: KeyData
.Key
.UnicodeChar
= L
'5';
507 case XK_KP_6
: KeyData
.Key
.UnicodeChar
= L
'6';
509 case XK_KP_7
: KeyData
.Key
.UnicodeChar
= L
'7';
511 case XK_KP_8
: KeyData
.Key
.UnicodeChar
= L
'8';
513 case XK_KP_9
: KeyData
.Key
.UnicodeChar
= L
'9';
520 // The global state is our state
521 KeyData
.KeyState
.KeyShiftState
= Drv
->KeyState
.KeyShiftState
;
522 KeyData
.KeyState
.KeyToggleState
= Drv
->KeyState
.KeyToggleState
;
524 if (*KeySym
< XK_BackSpace
) {
525 if (((Drv
->KeyState
.KeyShiftState
& (EFI_LEFT_SHIFT_PRESSED
| EFI_RIGHT_SHIFT_PRESSED
)) != 0) ||
526 ((Drv
->KeyState
.KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) != 0))
528 KeyData
.Key
.UnicodeChar
= (CHAR16
)KeySym
[KEYSYM_UPPER
];
530 // Per UEFI spec since we converted the Unicode clear the shift bits we pass up
531 KeyData
.KeyState
.KeyShiftState
&= ~(EFI_LEFT_SHIFT_PRESSED
| EFI_RIGHT_SHIFT_PRESSED
);
533 KeyData
.Key
.UnicodeChar
= (CHAR16
)KeySym
[KEYSYM_LOWER
];
536 // XK_BackSpace is the start of XK_MISCELLANY. These are the XK_? keys we process in this file
540 memcpy (&Drv
->keys
[Drv
->key_wr
], &KeyData
, sizeof (EFI_KEY_DATA
));
541 Drv
->key_wr
= (Drv
->key_wr
+ 1) % NBR_KEYS
;
543 if (Drv
->MakeRegisterdKeyCallback
!= NULL
) {
544 ReverseGasketUint64Uint64 (Drv
->MakeRegisterdKeyCallback
, Drv
->RegisterdKeyCallbackContext
, &KeyData
);
547 if (Drv
->BreakRegisterdKeyCallback
!= NULL
) {
548 ReverseGasketUint64Uint64 (Drv
->BreakRegisterdKeyCallback
, Drv
->RegisterdKeyCallbackContext
, &KeyData
);
555 IN GRAPHICS_IO_PRIVATE
*Drv
,
559 if (ev
->xmotion
.x
!= Drv
->previous_x
) {
560 Drv
->pointer_state
.RelativeMovementX
+= (ev
->xmotion
.x
- Drv
->previous_x
);
561 Drv
->previous_x
= ev
->xmotion
.x
;
562 Drv
->pointer_state_changed
= 1;
565 if (ev
->xmotion
.y
!= Drv
->previous_y
) {
566 Drv
->pointer_state
.RelativeMovementY
+= (ev
->xmotion
.y
- Drv
->previous_y
);
567 Drv
->previous_y
= ev
->xmotion
.y
;
568 Drv
->pointer_state_changed
= 1;
571 Drv
->pointer_state
.RelativeMovementZ
= 0;
576 IN GRAPHICS_IO_PRIVATE
*Drv
,
581 if (ev
->xbutton
.button
== Button1
) {
582 Drv
->pointer_state_changed
= (Drv
->pointer_state
.LeftButton
!= Pressed
);
583 Drv
->pointer_state
.LeftButton
= Pressed
;
586 if ( ev
->xbutton
.button
== Button2
) {
587 Drv
->pointer_state_changed
= (Drv
->pointer_state
.RightButton
!= Pressed
);
588 Drv
->pointer_state
.RightButton
= Pressed
;
594 IN GRAPHICS_IO_PRIVATE
*Drv
,
630 XFlush (Drv
->display
);
635 GRAPHICS_IO_PRIVATE
*Drv
,
652 ev
->xgraphicsexpose
.x
,
653 ev
->xgraphicsexpose
.y
,
654 ev
->xgraphicsexpose
.width
,
655 ev
->xgraphicsexpose
.height
659 handleKeyEvent (Drv
, ev
, TRUE
);
662 handleKeyEvent (Drv
, ev
, FALSE
);
665 XRefreshKeyboardMapping (&ev
->xmapping
);
668 handleMouseMoved (Drv
, ev
);
671 handleMouseDown (Drv
, ev
, TRUE
);
674 handleMouseDown (Drv
, ev
, FALSE
);
678 XCloseDisplay (Drv
->display
);
690 IN GRAPHICS_IO_PRIVATE
*Drv
695 while (XPending (Drv
->display
) != 0) {
696 XNextEvent (Drv
->display
, &ev
);
697 HandleEvent (Drv
, &ev
);
703 IN GRAPHICS_IO_PRIVATE
*Drv
,
704 IN EFI_UGA_PIXEL pixel
707 return ((pixel
.Red
>> Drv
->r
.csize
) << Drv
->r
.shift
)
708 | ((pixel
.Green
>> Drv
->g
.csize
) << Drv
->g
.shift
)
709 | ((pixel
.Blue
>> Drv
->b
.csize
) << Drv
->b
.shift
);
714 IN GRAPHICS_IO_PRIVATE
*Drv
,
720 memset (&Pixel
, 0, sizeof (EFI_UGA_PIXEL
));
722 // Truncation not an issue since X11 and EFI are both using 8 bits per color
723 Pixel
.Red
= (val
>> Drv
->r
.shift
) << Drv
->r
.csize
;
724 Pixel
.Green
= (val
>> Drv
->g
.shift
) << Drv
->g
.csize
;
725 Pixel
.Blue
= (val
>> Drv
->b
.shift
) << Drv
->b
.csize
;
732 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
735 GRAPHICS_IO_PRIVATE
*Drv
;
737 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
741 if (Drv
->key_count
!= 0) {
745 return EFI_NOT_READY
;
750 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
751 IN EFI_KEY_DATA
*KeyData
754 EFI_STATUS EfiStatus
;
755 GRAPHICS_IO_PRIVATE
*Drv
;
757 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
759 EfiStatus
= X11CheckKey (GraphicsIo
);
760 if (EFI_ERROR (EfiStatus
)) {
764 CopyMem (KeyData
, &Drv
->keys
[Drv
->key_rd
], sizeof (EFI_KEY_DATA
));
765 Drv
->key_rd
= (Drv
->key_rd
+ 1) % NBR_KEYS
;
773 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
774 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
777 GRAPHICS_IO_PRIVATE
*Drv
;
779 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
781 if (*KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) {
782 if ((Drv
->KeyState
.KeyToggleState
& EFI_CAPS_LOCK_ACTIVE
) == 0) {
784 // We could create an XKeyEvent and send a XK_Caps_Lock to
785 // the UGA/GOP Window
790 Drv
->KeyState
.KeyToggleState
= *KeyToggleState
;
795 X11RegisterKeyNotify (
796 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
797 IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack
,
798 IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack
,
802 GRAPHICS_IO_PRIVATE
*Drv
;
804 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
806 Drv
->MakeRegisterdKeyCallback
= MakeCallBack
;
807 Drv
->BreakRegisterdKeyCallback
= BreakCallBack
;
808 Drv
->RegisterdKeyCallbackContext
= Context
;
815 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
816 IN EFI_UGA_PIXEL
*BltBuffer OPTIONAL
,
817 IN EFI_UGA_BLT_OPERATION BltOperation
,
818 IN EMU_GRAPHICS_WINDOWS__BLT_ARGS
*Args
821 GRAPHICS_IO_PRIVATE
*Private
;
834 Private
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
839 if ( (BltOperation
== EfiUgaVideoToBltBuffer
)
840 || (BltOperation
== EfiUgaVideoToVideo
))
845 if (Args
->SourceY
+ Args
->Height
> Private
->height
) {
846 return EFI_INVALID_PARAMETER
;
849 if (Args
->SourceX
+ Args
->Width
> Private
->width
) {
850 return EFI_INVALID_PARAMETER
;
854 if ( (BltOperation
== EfiUgaBltBufferToVideo
)
855 || (BltOperation
== EfiUgaVideoToVideo
)
856 || (BltOperation
== EfiUgaVideoFill
))
859 // Destination is Video
861 if (Args
->DestinationY
+ Args
->Height
> Private
->height
) {
862 return EFI_INVALID_PARAMETER
;
865 if (Args
->DestinationX
+ Args
->Width
> Private
->width
) {
866 return EFI_INVALID_PARAMETER
;
870 switch (BltOperation
) {
871 case EfiUgaVideoToBltBuffer
:
872 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)BltBuffer
+ (Args
->DestinationY
* Args
->Delta
) + Args
->DestinationX
* sizeof (EFI_UGA_PIXEL
));
873 Args
->Delta
-= Args
->Width
* sizeof (EFI_UGA_PIXEL
);
874 for (SrcY
= Args
->SourceY
; SrcY
< (Args
->Height
+ Args
->SourceY
); SrcY
++) {
875 for (SrcX
= Args
->SourceX
; SrcX
< (Args
->Width
+ Args
->SourceX
); SrcX
++) {
876 *Blt
++ = X11ColorToPixel (Private
, XGetPixel (Private
->image
, SrcX
, SrcY
));
879 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)Blt
+ Args
->Delta
);
883 case EfiUgaBltBufferToVideo
:
884 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)BltBuffer
+ (Args
->SourceY
* Args
->Delta
) + Args
->SourceX
* sizeof (EFI_UGA_PIXEL
));
885 Args
->Delta
-= Args
->Width
* sizeof (EFI_UGA_PIXEL
);
886 for (DstY
= Args
->DestinationY
; DstY
< (Args
->Height
+ Args
->DestinationY
); DstY
++) {
887 for (DstX
= Args
->DestinationX
; DstX
< (Args
->Width
+ Args
->DestinationX
); DstX
++) {
888 XPutPixel (Private
->image
, DstX
, DstY
, X11PixelToColor (Private
, *Blt
));
892 Blt
= (EFI_UGA_PIXEL
*)((UINT8
*)Blt
+ Args
->Delta
);
896 case EfiUgaVideoToVideo
:
897 Dst
= Private
->image_data
+ (Args
->DestinationX
<< Private
->pixel_shift
)
898 + Args
->DestinationY
* Private
->line_bytes
;
899 Src
= Private
->image_data
+ (Args
->SourceX
<< Private
->pixel_shift
)
900 + Args
->SourceY
* Private
->line_bytes
;
901 Nbr
= Args
->Width
<< Private
->pixel_shift
;
902 if (Args
->DestinationY
< Args
->SourceY
) {
903 for (Index
= 0; Index
< Args
->Height
; Index
++) {
904 memcpy (Dst
, Src
, Nbr
);
905 Dst
+= Private
->line_bytes
;
906 Src
+= Private
->line_bytes
;
909 Dst
+= (Args
->Height
- 1) * Private
->line_bytes
;
910 Src
+= (Args
->Height
- 1) * Private
->line_bytes
;
911 for (Index
= 0; Index
< Args
->Height
; Index
++) {
913 // Source and Destination Y may be equal, therefore Dst and Src may
916 memmove (Dst
, Src
, Nbr
);
917 Dst
-= Private
->line_bytes
;
918 Src
-= Private
->line_bytes
;
923 case EfiUgaVideoFill
:
924 Color
= X11PixelToColor (Private
, *BltBuffer
);
925 for (DstY
= Args
->DestinationY
; DstY
< (Args
->Height
+ Args
->DestinationY
); DstY
++) {
926 for (DstX
= Args
->DestinationX
; DstX
< (Args
->Width
+ Args
->DestinationX
); DstX
++) {
927 XPutPixel (Private
->image
, DstX
, DstY
, Color
);
933 return EFI_INVALID_PARAMETER
;
939 switch (BltOperation
) {
940 case EfiUgaVideoToVideo
:
955 XNextEvent (Private
->display
, &ev
);
956 HandleEvent (Private
, &ev
);
957 if ((ev
.type
== NoExpose
) || (ev
.type
== GraphicsExpose
)) {
963 case EfiUgaVideoFill
:
964 Color
= X11PixelToColor (Private
, *BltBuffer
);
965 XSetForeground (Private
->display
, Private
->gc
, Color
);
975 XFlush (Private
->display
);
977 case EfiUgaBltBufferToVideo
:
978 Redraw (Private
, Args
->DestinationX
, Args
->DestinationY
, Args
->Width
, Args
->Height
);
989 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
992 GRAPHICS_IO_PRIVATE
*Drv
;
994 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
997 if (Drv
->pointer_state_changed
!= 0) {
1001 return EFI_NOT_READY
;
1005 X11GetPointerState (
1006 IN EMU_GRAPHICS_WINDOW_PROTOCOL
*GraphicsIo
,
1007 IN EFI_SIMPLE_POINTER_STATE
*State
1010 EFI_STATUS EfiStatus
;
1011 GRAPHICS_IO_PRIVATE
*Drv
;
1013 Drv
= (GRAPHICS_IO_PRIVATE
*)GraphicsIo
;
1015 EfiStatus
= X11CheckPointer (GraphicsIo
);
1016 if (EfiStatus
!= EFI_SUCCESS
) {
1020 memcpy (State
, &Drv
->pointer_state
, sizeof (EFI_SIMPLE_POINTER_STATE
));
1022 Drv
->pointer_state
.RelativeMovementX
= 0;
1023 Drv
->pointer_state
.RelativeMovementY
= 0;
1024 Drv
->pointer_state
.RelativeMovementZ
= 0;
1025 Drv
->pointer_state_changed
= 0;
1030 X11GraphicsWindowOpen (
1031 IN EMU_IO_THUNK_PROTOCOL
*This
1034 GRAPHICS_IO_PRIVATE
*Drv
;
1035 unsigned int border_width
= 0;
1036 char *display_name
= NULL
;
1038 Drv
= (GRAPHICS_IO_PRIVATE
*)calloc (1, sizeof (GRAPHICS_IO_PRIVATE
));
1040 return EFI_OUT_OF_RESOURCES
;
1043 Drv
->GraphicsIo
.Size
= GasketX11Size
;
1044 Drv
->GraphicsIo
.CheckKey
= GasketX11CheckKey
;
1045 Drv
->GraphicsIo
.GetKey
= GasketX11GetKey
;
1046 Drv
->GraphicsIo
.KeySetState
= GasketX11KeySetState
;
1047 Drv
->GraphicsIo
.RegisterKeyNotify
= GasketX11RegisterKeyNotify
;
1048 Drv
->GraphicsIo
.Blt
= GasketX11Blt
;
1049 Drv
->GraphicsIo
.CheckPointer
= GasketX11CheckPointer
;
1050 Drv
->GraphicsIo
.GetPointerState
= GasketX11GetPointerState
;
1055 Drv
->KeyState
.KeyShiftState
= EFI_SHIFT_STATE_VALID
;
1056 Drv
->KeyState
.KeyToggleState
= EFI_TOGGLE_STATE_VALID
;
1057 Drv
->MakeRegisterdKeyCallback
= NULL
;
1058 Drv
->BreakRegisterdKeyCallback
= NULL
;
1059 Drv
->RegisterdKeyCallbackContext
= NULL
;
1061 Drv
->display
= XOpenDisplay (display_name
);
1062 if (Drv
->display
== NULL
) {
1063 fprintf (stderr
, "uga: cannot connect to X server %s\n", XDisplayName (display_name
));
1065 return EFI_DEVICE_ERROR
;
1068 Drv
->screen
= DefaultScreen (Drv
->display
);
1069 Drv
->visual
= DefaultVisual (Drv
->display
, Drv
->screen
);
1070 Drv
->win
= XCreateSimpleWindow (
1072 RootWindow (Drv
->display
, Drv
->screen
),
1078 WhitePixel (Drv
->display
, Drv
->screen
),
1079 BlackPixel (Drv
->display
, Drv
->screen
)
1082 Drv
->depth
= DefaultDepth (Drv
->display
, Drv
->screen
);
1083 XDefineCursor (Drv
->display
, Drv
->win
, XCreateFontCursor (Drv
->display
, XC_pirate
));
1085 Drv
->Title
= malloc (StrSize (This
->ConfigString
));
1086 UnicodeStrToAsciiStrS (This
->ConfigString
, Drv
->Title
, StrSize (This
->ConfigString
));
1087 XStoreName (Drv
->display
, Drv
->win
, Drv
->Title
);
1089 // XAutoRepeatOff (Drv->display);
1093 ExposureMask
| KeyPressMask
| KeyReleaseMask
| PointerMotionMask
| ButtonPressMask
| ButtonReleaseMask
1095 Drv
->gc
= DefaultGC (Drv
->display
, Drv
->screen
);
1097 This
->Private
= (VOID
*)Drv
;
1098 This
->Interface
= (VOID
*)Drv
;
1103 X11GraphicsWindowClose (
1104 IN EMU_IO_THUNK_PROTOCOL
*This
1107 GRAPHICS_IO_PRIVATE
*Drv
;
1109 Drv
= (GRAPHICS_IO_PRIVATE
*)This
->Private
;
1115 if (Drv
->image
!= NULL
) {
1116 XDestroyImage (Drv
->image
);
1119 shmdt (Drv
->image_data
);
1122 Drv
->image_data
= NULL
;
1126 XDestroyWindow (Drv
->display
, Drv
->win
);
1127 XCloseDisplay (Drv
->display
);
1130 // Free up the shared memory
1131 shmctl (Drv
->xshm_info
.shmid
, IPC_RMID
, NULL
);
1138 EMU_IO_THUNK_PROTOCOL gX11ThunkIo
= {
1139 &gEmuGraphicsWindowProtocolGuid
,
1143 GasketX11GraphicsWindowOpen
,
1144 GasketX11GraphicsWindowClose
,