chiark / gitweb /
boot: efi - split graphics and splash handling
[elogind.git] / src / boot / efi / graphics.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /*
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * Copyright (C) 2012-2013 Kay Sievers <kay@vrfy.org>
15  * Copyright (C) 2012 Harald Hoyer <harald@redhat.com>
16  * Copyright (C) 2013 Intel Corporation
17  *   Authored by Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
18  */
19
20 #include <efi.h>
21 #include <efilib.h>
22
23 #include "util.h"
24 #include "graphics.h"
25
26 EFI_STATUS graphics_mode(BOOLEAN on) {
27         #define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
28                 { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } };
29
30         struct _EFI_CONSOLE_CONTROL_PROTOCOL;
31
32         typedef enum {
33                 EfiConsoleControlScreenText,
34                 EfiConsoleControlScreenGraphics,
35                 EfiConsoleControlScreenMaxValue,
36         } EFI_CONSOLE_CONTROL_SCREEN_MODE;
37
38         typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE)(
39                 struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
40                 EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
41                 BOOLEAN *UgaExists,
42                 BOOLEAN *StdInLocked
43         );
44
45         typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE)(
46                 struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
47                 EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
48         );
49
50         typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN)(
51                 struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
52                 CHAR16 *Password
53         );
54
55         typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL {
56                 EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
57                 EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
58                 EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
59         } EFI_CONSOLE_CONTROL_PROTOCOL;
60
61         EFI_GUID ConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
62         EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
63         EFI_CONSOLE_CONTROL_SCREEN_MODE new;
64         EFI_CONSOLE_CONTROL_SCREEN_MODE current;
65         BOOLEAN uga_exists;
66         BOOLEAN stdin_locked;
67         EFI_STATUS err;
68
69         err = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **)&ConsoleControl);
70         if (EFI_ERROR(err)) {
71                 /* console control protocol is nonstandard and might not exist. */
72                 return err == EFI_NOT_FOUND ? EFI_SUCCESS : err;
73         }
74
75         /* check current mode */
76         err = uefi_call_wrapper(ConsoleControl->GetMode, 4, ConsoleControl, &current, &uga_exists, &stdin_locked);
77         if (EFI_ERROR(err))
78                 return err;
79
80         /* do not touch the mode */
81         new  = on ? EfiConsoleControlScreenGraphics : EfiConsoleControlScreenText;
82         if (new == current)
83                 return EFI_SUCCESS;
84
85         err = uefi_call_wrapper(ConsoleControl->SetMode, 2, ConsoleControl, new);
86
87         /* some firmware enables the cursor when switching modes */
88         uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
89
90         return err;
91 }