The Pedigree Project  0.1
user/applications/gfxcon/main.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/klog.h>
30 #include <sys/stat.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33 
34 #include "pedigree/native/graphics/Graphics.h"
35 #include "pedigree/native/input/Input.h"
36 
37 #include <pedigree_fb.h>
38 #include <tui.h>
39 
40 static Tui *g_Tui = nullptr;
41 
43 {
44  public:
45  GfxConTuiRedrawer(Framebuffer *pFramebuffer)
46  {
47  m_pFramebuffer = pFramebuffer;
48  }
49 
50  virtual void redraw(size_t x, size_t y, size_t w, size_t h)
51  {
52  m_pFramebuffer->flush(x, y, w, h);
53  }
54 
55  private:
56  Framebuffer *m_pFramebuffer;
57 };
58 
64 void input_handler(Input::InputNotification &note)
65 {
66  if (!g_Tui) // No terminal yet!
67  return;
68 
69  if (note.type != Input::Key)
70  return;
71 
72  uint64_t c = note.data.key.key;
73  g_Tui->keyInput(c);
74 }
75 
76 int main(int argc, char *argv[])
77 {
78  // Create ourselves a lock file so we don't end up getting run twice.
80  int fd = open("runtimeĀ»/gfxcon.lck", O_WRONLY | O_EXCL | O_CREAT, 0500);
81  if (fd < 0)
82  {
83  fprintf(stderr, "gfxcon: lock file exists, terminating.\n");
84  return EXIT_FAILURE;
85  }
86  close(fd);
87 
88  Framebuffer *pFramebuffer = new Framebuffer();
89  if (!pFramebuffer->initialise())
90  {
91  fprintf(stderr, "gfxcon: framebuffer initialisation failed\n");
92  return EXIT_FAILURE;
93  }
94 
95  // Save current mode so we can restore it on quit.
96  pFramebuffer->storeMode();
97 
98  // Kick off a process group, fork to run the modeset shim.
99  setpgid(0, 0);
100  pid_t child = fork();
101  if (child == -1)
102  {
103  fprintf(stderr, "gfxcon: could not fork: %s\n", strerror(errno));
104  return 1;
105  }
106  else if (child != 0)
107  {
108  // Wait for the child (ie, real window manager process) to terminate.
109  int status = 0;
110  waitpid(child, &status, 0);
111 
112  // Restore old graphics mode.
113  pFramebuffer->restoreMode();
114  delete pFramebuffer;
115 
116  // Termination information
117  if (WIFEXITED(status))
118  {
119  fprintf(
120  stderr, "gfxcon: terminated with status %d\n",
121  WEXITSTATUS(status));
122  }
123  else if (WIFSIGNALED(status))
124  {
125  fprintf(
126  stderr, "gfxcon: terminated by signal %d\n", WTERMSIG(status));
127  }
128  else
129  {
130  fprintf(stderr, "gfxcon: terminated by unknown means\n");
131  }
132 
133  // Terminate our process group.
134  kill(0, SIGTERM);
135  return 0;
136  }
137 
138  // Can we set the graphics mode we want?
140  int result = pFramebuffer->enterMode(1024, 768, 32);
141  if (result != 0)
142  {
143  return result;
144  }
145 
146  size_t nWidth = pFramebuffer->getWidth();
147  size_t nHeight = pFramebuffer->getHeight();
148 
149  Input::installCallback(Input::Key, input_handler);
150 
151  GfxConTuiRedrawer *redrawer = new GfxConTuiRedrawer(pFramebuffer);
152 
153  g_Tui = new Tui(redrawer);
154  g_Tui->resize(nWidth, nHeight);
155  g_Tui->recreateSurfaces(pFramebuffer->getFramebuffer());
156  if (!g_Tui->initialise(nWidth, nHeight))
157  {
158  return 1;
159  }
160 
161  g_Tui->run();
162 
163  delete g_Tui;
164  delete pFramebuffer;
165 
166  return 0;
167 }
Definition: tui.h:36
void run()
Runs the TUI main loop.
Definition: tui.cc:261
void restoreMode()
Definition: fb.cc:85
int enterMode(size_t desiredW, size_t desiredH, size_t desiredBpp)
Definition: fb.cc:98
void recreateSurfaces(void *fb)
Re-create rendering surfaces from the newest framebuffer.
Definition: tui.cc:189
bool initialise()
Definition: fb.cc:56
void keyInput(uint64_t key)
Handles a key press with all Pedigree input special flags.
Definition: tui.cc:355
void flush(size_t x, size_t y, size_t w, size_t h)
Definition: fb.cc:186
bool initialise(size_t width, size_t height)
(Re-)initialise the terminal
Definition: tui.cc:71
Abstracts the system&#39;s framebuffer offering.
virtual void * getFramebuffer()
void resize(size_t newWidth, size_t newHeight)
Handle a resize of the terminal.
Definition: tui.cc:230
void storeMode()
Definition: fb.cc:70