The Pedigree Project  0.1
live.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 #define __STDCPP_WANT_MATH_SPEC_FUNCS__ 0
21 
22 #include <curses.h>
23 #include <dialog.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <libintl.h>
27 #include <locale.h>
28 
29 #include <string>
30 #include <vector>
31 
32 #ifdef __PEDIGREE__
33 #define LOCALE_DIR "/system/locale"
34 #define KEYMAP_DIR "/system/keymaps"
35 
36 extern "C" int pedigree_load_keymap(char *buffer, size_t len);
37 #else
38 #define LOCALE_DIR "./build/locale"
39 #define KEYMAP_DIR "./images/base/system/keymaps"
40 
41 int pedigree_load_keymap(char *buffer, size_t len)
42 {
43  return 0;
44 }
45 #endif
46 
47 int scan_into_vector(const char *path, std::vector<std::string> &vec)
48 {
49  struct dirent **namelist;
50  int count = scandir(path, &namelist, 0, alphasort);
51  if (count < 0)
52  {
53  perror("scandir");
54  return -1;
55  }
56  else
57  {
58  for (int i = 0; i < count; ++i)
59  {
60  if (!strcmp(namelist[i]->d_name, ".") ||
61  !strcmp(namelist[i]->d_name, ".."))
62  {
63  free(namelist[i]);
64  continue;
65  }
66 
67  vec.push_back(std::string(namelist[i]->d_name));
68  free(namelist[i]);
69  }
70 
71  free(namelist);
72  }
73 
74  return 0;
75 }
76 
77 void load_keymap(const char *path)
78 {
79  std::string real_path = std::string(KEYMAP_DIR "/") + std::string(path);
80  FILE *stream = fopen(real_path.c_str(), "r");
81  if (!stream)
82  {
83  perror("fopen");
84  return;
85  }
86 
87  fseek(stream, 0, SEEK_END);
88  size_t len = ftell(stream);
89  fseek(stream, 0, SEEK_SET);
90 
91  char *buffer = (char *) malloc(len);
92  fread(buffer, len, 1, stream);
93  fclose(stream);
94 
95  pedigree_load_keymap(buffer, len);
96 
97  free(buffer);
98 }
99 
100 int languages()
101 {
102  std::vector<std::string> languages;
103  if (scan_into_vector(LOCALE_DIR, languages) < 0)
104  {
105  return 1;
106  }
107 
108  char **languages_menu = (char **) calloc(languages.size(), sizeof(char *));
109  for (size_t i = 0; i < languages.size(); ++i)
110  {
111  languages_menu[i] = const_cast<char *>(languages[i].c_str());
112  }
113 
114  dlg_clear();
115 
116  int current_item = 0;
117  dialog_vars.nocancel = TRUE;
118  dialog_vars.default_item = const_cast<char *>("en");
119  dialog_vars.no_items = TRUE;
120  dialog_vars.item_help = FALSE;
121  int status = dialog_menu(
122  "Language Selection",
123  "Please select your preferred language from the list below.", 0, 0, 0,
124  languages.size(), languages_menu);
125 
126  free(languages_menu);
127 
128  // Switch to the chosen language now.
129  std::string chosen_language = std::string(dialog_vars.input_result);
130  dlg_clr_result();
131 
132  setenv("LC_ALL", chosen_language.c_str(), 1);
133 
134  return 0;
135 }
136 
137 int keymaps()
138 {
139  std::vector<std::string> keymaps;
140  if (scan_into_vector(KEYMAP_DIR, keymaps) < 0)
141  {
142  return 1;
143  }
144 
145  // Move on to keymap selection.
146  char **keymaps_menu = (char **) calloc(keymaps.size(), sizeof(char *));
147  for (size_t i = 0; i < keymaps.size(); ++i)
148  {
149  keymaps_menu[i] = const_cast<char *>(keymaps[i].c_str());
150  }
151 
152  dlg_clear();
153 
154  dialog_vars.nocancel = TRUE;
155  dialog_vars.ok_label = gettext("OK");
156  dialog_vars.no_items = TRUE;
157  dialog_vars.item_help = FALSE;
158  dialog_menu(
159  gettext("Keyboard Layout Selection"),
160  gettext("Please select your preferred keyboard layout from the list "
161  "below."),
162  0, 0, 0, keymaps.size(), keymaps_menu);
163 
164  free(keymaps_menu);
165 
166  // Load the new keymap.
167  load_keymap(dialog_vars.input_result);
168  dlg_clr_result();
169 
170  dlg_clear();
171 
172  dialog_vars.ok_label = gettext("OK");
173  dialog_vars.nocancel = 1;
174  dialog_msgbox(
175  gettext("Ready to Go"),
176  gettext("Configuration is complete.\n\nPedigree is ready for you."), 0,
177  0, 1);
178 
179  return 0;
180 }
181 
182 int main(int argc, char *argv[])
183 {
184  setlocale(LC_ALL, "");
185  bindtextdomain("live", LOCALE_DIR);
186  bind_textdomain_codeset("live", "UTF-8");
187  textdomain("live");
188 
189  if (argc < 1 || argc > 2)
190  {
191  return 0;
192  }
193 
194  init_dialog(stdin, stdout);
195  dialog_vars.colors = TRUE;
196  int status = dialog_yesno(
197  "Welcome to Pedigree",
198  "Thanks for trying out Pedigree. This Live CD version supports a few "
199  "languages and keyboard mappings, so we're going to ask some questions "
200  "to "
201  "find your preferences and apply them.\n\nAlternatively, you can just "
202  "accept the default configuration (English language, EN-US keyboard).\n"
203  "\nDo you want to accept the defaults?",
204  0, 0);
205 
206  if (status != DLG_EXIT_OK)
207  {
208  if (languages())
209  {
210  return 1;
211  }
212 
213  if (keymaps())
214  {
215  return 1;
216  }
217  }
218 
219  end_dialog();
220 
221 #ifdef __PEDIGREE__
222  execl("/applications/login", "/applications/login", 0);
223 #else
224  return 0;
225 #endif
226 }