C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Initializing View I/O

Populate the C-Menu View Struct and Connect Input. More...

Files

file  init_view.c
 Initialize C-Menu View Screen IO and Input.

Functions

int init_view_full_screen (Init *init)
 Initialize C-Menu View in full screen mode.
int init_view_boxwin (Init *init, char *title)
 Initialize the C-Menu View in box window mode.
int view_init_input (View *view, char *file_name)
 Initialize the input for a C-Menu View.

Detailed Description

Populate the C-Menu View Struct and Connect Input.

Function Documentation

◆ init_view_boxwin()

int init_view_boxwin ( Init * init,
char * title )

Initialize the C-Menu View in box window mode.

Note
sets up the view structure for box window mode, adjusts dimensions based on screen size, and creates a new pad for the view. It also configures various parameters such as scroll lines, command line position, and tab size.
Parameters
initPointer to the Init structure containing view settings.
titleTitle for the box window.
Returns
0 on success, -1 on failure.

view->ln_win: line number window

pad for main content

Definition at line 123 of file init_view.c.

123 {
124 int scr_lines, scr_cols;
125 view = init->view;
126
127 if (view->tab_stop <= 0)
128 view->tab_stop = TABSIZE;
129 set_tabsize(view->tab_stop);
130 view->f_full_screen = false;
131 getmaxyx(stdscr, scr_lines, scr_cols);
132 if (view->lines > scr_lines)
133 view->lines = scr_lines;
134 if (view->cols > scr_cols)
135 view->cols = scr_cols;
136 if (view->begy + view->lines > scr_lines)
137 view->begy = scr_lines - view->lines - 2;
138 if (view->begx + view->cols > scr_cols)
139 view->begx = scr_cols - view->cols - 2;
140 if (title != nullptr && title[0] != '\0')
141 strnz__cpy(view->title, title, MAXLEN - 1);
142 else {
143 if (view->argv != nullptr && view->argv[0] != nullptr &&
144 view->argv[0][0] != '\0')
145 strnz__cpy(view->title, view->argv[0], MAXLEN - 1);
146 }
147 if (win_new(view->lines, view->cols, view->begy, view->begx, view->title,
148 F_VIEW)) {
149 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 1);
150 ssnprintf(em1, MAXLEN - 1, "win_new(%d, %d, %d, %d, %s, %b) failed",
151 view->lines, view->cols, view->begy, view->begx, "nullptr",
152 F_VIEW);
153 em2[0] = '\0';
154 display_error(em0, em1, em2, nullptr);
155 return (-1);
156 }
157
158 view->win = newwin(1, view->cols, view->begy + view->lines, view->begx + 1);
159 keypad(view->win, true);
160 idlok(view->win, false);
161 idcok(view->win, false);
162 wbkgrnd(view->win, &CCC_WIN);
163 wbkgrndset(view->win, &CCC_WIN);
164 scrollok(view->win, false);
165#ifdef NCDEBUG
166 immedok(view->win, true);
167#endif
168
170 view->ln_win_lines = view->lines - 1;
171 view->ln_win_cols = 7;
172 view->ln_win = newwin(view->ln_win_lines, view->ln_win_cols, view->begy + 1,
173 view->begx + 1);
174 keypad(view->ln_win, false);
175 idlok(view->ln_win, false);
176 idcok(view->ln_win, false);
177 wbkgrnd(view->ln_win, &CCC_LN);
178 wbkgrndset(view->ln_win, &CCC_LN);
179 scrollok(view->ln_win, true);
180 wsetscrreg(view->ln_win, 0, view->scroll_lines - 1);
181#ifdef NCDEBUG
182 immedok(view->ln_win, true);
183#endif
185 view->scroll_lines = view->lines - 1;
186 view->cmd_line = 0;
187 view->pminrow = 0;
188 view->pmincol = 0;
189 view->sminrow = view->begy + 1;
190 view->smincol = view->begx + 1;
191 view->smaxrow = view->begy + view->lines;
192 view->smaxcol = view->begx + view->cols;
193 view->pad = newpad(view->lines - 1, PAD_COLS);
194 keypad(view->pad, true);
195 idlok(view->pad, false);
196 idcok(view->pad, false);
197 wbkgrnd(view->pad, &CCC_WIN);
198 wbkgrndset(view->pad, &CCC_WIN);
199 scrollok(view->pad, true);
200 wsetscrreg(view->pad, 0, view->scroll_lines - 1);
201#ifdef NCDEBUG
202 immedok(view->pad, true);
203#endif
204 return (0);
205}
Init * init
Definition common.h:186
#define F_VIEW
Definition common.h:49
#define PAD_COLS
Definition view.h:30
View * view
Definition mem.c:48
#define MAXLEN
Definition curskeys.c:15
cchar_t CCC_LN
Definition dwin.c:151
char em1[MAXLEN]
Definition dwin.c:133
cchar_t CCC_WIN
Definition dwin.c:146
char em0[MAXLEN]
Definition dwin.c:132
char em2[MAXLEN]
Definition dwin.c:134
int win_new(int, int, int, int, char *, int)
Create a new window with optional box and title.
Definition dwin.c:783
int display_error(char *em0, char *em1, char *em2, char *em3)
Display an error message window or print to stderr.
Definition dwin.c:1054
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:269
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:147

References View::argv, View::begx, View::begy, CCC_LN, CCC_WIN, View::cmd_line, View::cols, display_error(), em0, em1, em2, View::f_full_screen, View::lines, View::ln_win, View::ln_win_cols, View::ln_win_lines, View::pad, View::pmincol, View::pminrow, View::scroll_lines, View::smaxcol, View::smaxrow, View::smincol, View::sminrow, ssnprintf(), strnz__cpy(), View::tab_stop, View::title, Init::view, view, View::win, and win_new().

Referenced by mview(), and popup_view().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_view_full_screen()

int init_view_full_screen ( Init * init)

Initialize C-Menu View in full screen mode.

Note
This function sets up the view structure for full screen mode and creates a new pad for the view.
Parameters
initPointer to the Init structure containing view settings.
Returns
0 on success, -1 on failure.
The function creates the following windows:
1. view->win: Status or Command Line
2. view->ln_win: Line Number Window
3. view->pad: Main Content Pad

view->win: status or command line window

view->ln_win: line number window

view->win: status or command line window

Definition at line 40 of file init_view.c.

40 {
41 int scr_lines, scr_cols;
42 view = init->view;
43
44 if (view->tab_stop <= 0)
45 view->tab_stop = TABSIZE;
46 set_tabsize(view->tab_stop);
47 view->f_full_screen = true;
48 getmaxyx(stdscr, scr_lines, scr_cols);
49 if (view->lines == 0 || view->lines > scr_lines)
50 view->lines = scr_lines;
51 if (view->cols == 0 || view->cols > scr_cols)
52 view->cols = scr_cols;
53 if (view->begy + view->lines > scr_lines)
54 view->begy = scr_lines - view->lines;
55 if (view->begx + view->cols > scr_cols)
56 view->begx = scr_cols - view->cols;
58 view->win = newwin(1, view->cols, view->begy + view->lines - 1, view->begx);
59 keypad(view->win, true);
60 idlok(view->win, false);
61 idcok(view->win, false);
62 wbkgrnd(view->win, &CCC_WIN);
63 wbkgrndset(view->win, &CCC_WIN);
64 scrollok(view->win, false);
65#ifdef NCDEBUG
66 immedok(view->win, true);
67#endif
68
70 view->ln_win_lines = scr_lines;
71 view->ln_win_cols = 7;
72 view->ln_win = newwin(view->ln_win_lines - 1, view->ln_win_cols, 0, 0);
73 keypad(view->ln_win, false);
74 idlok(view->ln_win, false);
75 idcok(view->ln_win, false);
76 wbkgrnd(view->ln_win, &CCC_LN);
77 wbkgrndset(view->ln_win, &CCC_LN);
78 scrollok(view->ln_win, true);
79 wsetscrreg(view->ln_win, 0, view->scroll_lines - 1);
80#ifdef NCDEBUG
81 immedok(view->ln_win, true);
82#endif
83
85 view->pminrow = 0;
86 view->pmincol = 0;
87 view->sminrow = 0;
88 view->smincol = 0;
89 view->scroll_lines = view->lines - 1;
90 view->cmd_line = 0;
91 view->smaxrow = view->lines - 1;
92 view->smaxcol = view->cols - 1;
93 view->pad = newpad(view->lines - 1, PAD_COLS);
94 if (view->pad == nullptr) {
95 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 2);
96 ssnprintf(em1, MAXLEN - 1, "newpad(%d, %d) failed", view->lines,
97 PAD_COLS);
98 em2[0] = '\0';
99 display_error(em0, em1, em2, nullptr);
100 abend(-1, "init_view_full_screen: newpad() failed");
101 }
102 keypad(view->pad, false);
103 idlok(view->pad, false);
104 idcok(view->pad, false);
105 wbkgrnd(view->pad, &CCC_WIN);
106 wbkgrndset(view->pad, &CCC_WIN);
107 scrollok(view->pad, true);
108 wsetscrreg(view->pad, 0, view->scroll_lines - 1);
109#ifdef NCDEBUG
110 immedok(view->pad, true);
111#endif
112 return 0;
113}
void abend(int, char *)
Abnormal program termination.
Definition dwin.c:1331

References abend(), View::begx, View::begy, CCC_LN, CCC_WIN, View::cmd_line, View::cols, display_error(), em0, em1, em2, View::f_full_screen, View::lines, View::ln_win, View::ln_win_cols, View::ln_win_lines, View::pad, View::pmincol, View::pminrow, View::scroll_lines, View::smaxcol, View::smaxrow, View::smincol, View::sminrow, ssnprintf(), View::tab_stop, Init::view, view, and View::win.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ view_init_input()

int view_init_input ( View * view,
char * file_name )

Initialize the input for a C-Menu View.

This function initializes the input for view, which can be a file, standard input, or a provider command to be initiated by view. It handles different input sources and sets up the necessary file descriptors and memory mapping for efficient access.

Parameters
viewPointer to the View structure to be initialized.
file_nameName of the input file or "-" for standard input.
Returns
true on success, false on failure.
Note
if a provider command is specified, set up a pipe to read its output. A child process is spawned, and view, the parent process, reads from the pipe.
If input is from a pipe or standard input, clone it to a temporary file. This allows for memory-mapping the input later. It does not support real-time updates to the input, but it allows for efficient access to the data.

Open the input file for reading and get its size.

< 200ms timeout to check for input

If user cancels while waiting for view input, kill provider_cmd child process and close pipe

If error occurs while waiting for view input, kill provider_cmd child process and close pipe

If timeout occurs while waiting for view input, kill provider_cmd child process and close pipe

If unexpected error occurs while waiting for view input, kill provider_cmd child process and close pipe

Definition at line 223 of file init_view.c.

223 {
224 struct stat sb;
225 int idx = 0;
226 pid_t pid = -1;
227 int pipe_fd[2];
228 int s_argc = 0;
229 char *s_argv[MAXARGS];
230 char tmp_str[MAXLEN];
231 view->f_in_pipe = false;
232 if (strcmp(file_name, "-") == 0) {
233 file_name = "/dev/stdin";
234 view->f_in_pipe = true;
235 }
236 if (view->provider_cmd[0] != '\0') {
237 s_argc = str_to_args(s_argv, view->provider_cmd, MAXARGS - 1);
238 if (pipe(pipe_fd) == -1) {
239 Perror("pipe(pipe_fd) failed in init_view");
240 return -1;
241 }
242 if ((pid = fork()) == -1) {
243 Perror("fork() failed in init_view");
244 return -1;
245 }
246 if (pid == 0) { // Child
247 close(pipe_fd[P_READ]);
248 dup2(pipe_fd[P_WRITE], STDOUT_FILENO);
249 close(pipe_fd[P_WRITE]);
250 execvp(s_argv[0], s_argv);
251 strnz__cpy(tmp_str, "Can't exec view start cmd: ", MAXLEN - 1);
252 strnz__cat(tmp_str, s_argv[0], MAXLEN - 1);
253 Perror(tmp_str);
254 exit(EXIT_FAILURE);
255 }
256 // Back to parent
257 destroy_argv(s_argc, s_argv);
258 close(pipe_fd[P_WRITE]);
259 dup2(pipe_fd[P_READ], STDIN_FILENO);
260 view->in_fd = dup(STDIN_FILENO);
261 view->f_in_pipe = true;
262 } else {
263 if (view->f_in_pipe)
264 view->in_fd = dup(STDIN_FILENO);
265 else {
266 /*----------------------------------------------------------------------*/
269 view->in_fd = open(file_name, O_RDONLY);
270 if (view->in_fd == -1) {
271 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__,
272 __LINE__ - 2);
273 ssnprintf(em1, MAXLEN - 1, "open %s", file_name);
274 strerror_r(errno, em2, MAXLEN);
275 display_error(em0, em1, em2, nullptr);
276 return -1;
277 }
278 if (fstat(view->in_fd, &sb) == -1) {
279 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__,
280 __LINE__ - 1);
281 ssnprintf(em1, MAXLEN - 1, "fstat %s", file_name);
282 strerror_r(errno, em2, MAXLEN);
283 display_error(em0, em1, em2, nullptr);
284 close(view->in_fd);
285 return -1;
286 }
287 view->file_size = sb.st_size;
288 if (view->file_size == 0) {
289 close(view->in_fd);
290 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__,
291 __LINE__ - 1);
292 ssnprintf(em1, MAXLEN - 1, "file %s is empty", file_name);
293 strerror_r(errno, em2, MAXLEN);
294 display_error(em0, em1, em2, nullptr);
295 return -1;
296 }
297 if (!S_ISREG(sb.st_mode))
298 view->f_in_pipe = true;
299 }
300 /*----------------------------------------------------------------------*/
301 }
302 if (view->f_in_pipe) {
303 char tmp_filename[] = "/tmp/view_XXXXXX";
304 char buf[VBUFSIZ];
305 ssize_t bytes_read = 0;
306 ssize_t bytes_written = 0;
307 close(view->in_fd);
308 view->in_fd = mkstemp(tmp_filename);
309 if (view->in_fd == -1) {
310 abend(-1, "failed to mkstemp");
311 exit(EXIT_FAILURE);
312 }
313 unlink(tmp_filename);
314 /*-----------------------------------------------------------------*/
315 bool f_wait = false;
316 int ready;
317 fd_set read_fds;
318 struct timeval timeout;
319 Chyron *wait_chyron = nullptr;
320 WINDOW *wait_win = nullptr;
321 int remaining;
322 FD_ZERO(&read_fds);
323 FD_SET(STDIN_FILENO, &read_fds);
324 timeout.tv_sec = 0;
325 timeout.tv_usec = 200000;
326 ready = select(STDIN_FILENO + 1, &read_fds, nullptr, nullptr, &timeout);
327 if (ready == 0) {
328 f_wait = true;
329 remaining = wait_timeout;
330 wait_chyron = wait_mk_chyron();
331 wait_win = wait_mk_win(wait_chyron, "WAITING for VIEW INPUT");
332 }
333 cmd_key = 0;
334 while (ready == 0 && remaining > 0 && cmd_key != KEY_F(9)) {
335 cmd_key = wait_continue(wait_win, wait_chyron, remaining);
336 if (cmd_key == KEY_F(9))
337 break;
338 FD_ZERO(&read_fds);
339 FD_SET(STDIN_FILENO, &read_fds);
340 timeout.tv_sec = 0;
341 timeout.tv_usec = 0;
342 ready =
343 select(STDIN_FILENO + 1, &read_fds, nullptr, nullptr, &timeout);
344 remaining--;
345 }
346 if (f_wait) {
347 if (wait_chyron != nullptr)
348 wait_destroy(wait_chyron);
349 }
350 if (cmd_key == KEY_F(9)) {
351 if (view->f_in_pipe && pid > 0) {
354 kill(pid, SIGKILL);
355 waitpid(pid, nullptr, 0);
356 close(pipe_fd[P_READ]);
357 }
358 Perror("No view input available");
359 return -1;
360 }
361 if (ready == -1) {
362 Perror("Error waiting for view input");
363 if (view->f_in_pipe && pid > 0) {
366 kill(pid, SIGKILL);
367 waitpid(pid, nullptr, 0);
368 close(pipe_fd[P_READ]);
369 }
370 return -1;
371 }
372 if (ready == 0) {
373 Perror("Timeout waiting for view input");
374 if (view->f_in_pipe && pid > 0) {
377 kill(pid, SIGKILL);
378 waitpid(pid, nullptr, 0);
379 close(pipe_fd[P_READ]);
380 }
381 return -1;
382 }
383 if (ready == 1 && !FD_ISSET(STDIN_FILENO, &read_fds)) {
384 Perror("Unexpected error waiting for view input");
385 if (view->f_in_pipe && pid > 0) {
388 kill(pid, SIGKILL);
389 waitpid(pid, nullptr, 0);
390 close(pipe_fd[P_READ]);
391 }
392 return -1;
393 }
394 /*-----------------------------------------------------------------*/
395 while ((bytes_read = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
396 if (write(view->in_fd, buf, bytes_read) != bytes_read) {
397 abend(-1, "unable to write tmp");
398 exit(EXIT_FAILURE);
399 }
400 bytes_written += bytes_read;
401 }
402 if (bytes_written == 0) {
403 abend(-1, "unable to read stdin");
404 exit(EXIT_FAILURE);
405 }
406 if (fstat(view->in_fd, &sb) == -1) {
407 abend(-1, "fstat failed");
408 exit(EXIT_FAILURE);
409 }
410 view->file_size = sb.st_size;
411 if (view->file_size == 0) {
412 close(view->in_fd);
413 strnz__cpy(tmp_str, "no standard input", MAXLEN - 1);
414 abend(-1, tmp_str);
415 exit(EXIT_FAILURE);
416 }
418 // waitpid(-1, nullptr, 0);
419 }
420 // Memory-map the input file for efficient access.
421 view->buf =
422 mmap(nullptr, view->file_size, PROT_READ, MAP_PRIVATE, view->in_fd, 0);
423 if (view->buf == MAP_FAILED) {
424 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 2);
425 ssnprintf(em1, MAXLEN - 1, "mmap %s", file_name);
426 strerror_r(errno, em2, MAXLEN);
427 display_error(em0, em1, em2, nullptr);
428 close(view->in_fd);
429 return -1;
430 }
431 close(view->in_fd);
432 view->file_size = sb.st_size;
433 view->prev_file_pos = NULL_POSITION;
434 view->buf_curr_ptr = view->buf;
435 if (view->cmd_all[0] != '\0')
436 strnz__cpy(view->cmd, view->cmd_all, MAXLEN - 1);
437 for (idx = 0; idx < NMARKS; idx++)
438 view->mark_tbl[idx] = NULL_POSITION;
439 strnz__cpy(view->cur_file_str, file_name, MAXLEN - 1);
440 base_name(view->file_name, view->cur_file_str);
441 return 0;
442}
#define P_READ
Definition common.h:50
#define P_WRITE
Definition common.h:51
#define MAXARGS
Definition cm.h:30
int wait_timeout
Definition futil.c:98
#define NMARKS
Definition view.h:24
#define VBUFSIZ
Definition view.h:28
#define NULL_POSITION
Definition view.h:27
int pipe_fd[2]
Definition pick_engine.c:39
char * file_name[MAXLEN+1]
Definition whence.c:25
unsigned int cmd_key
Definition dwin.c:117
bool waitpid_with_timeout(pid_t pid, int timeout)
Definition dwin.c:1431
bool wait_destroy(Chyron *)
Destroy the waiting message window and chyron.
Definition dwin.c:1203
int wait_continue(WINDOW *, Chyron *, int)
Update the waiting message with remaining time and check for user input.
Definition dwin.c:1215
WINDOW * wait_mk_win(Chyron *, char *)
Display a popup waiting message.
Definition dwin.c:1172
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1110
Chyron * wait_mk_chyron()
Create a Chyron struct for the waiting message.
Definition dwin.c:1161
void destroy_argv(int argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:221
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:298
bool expand_tilde(char *, int)
Replace Leading Tilde With Home Directory.
Definition futil.c:684
bool base_name(char *, char *)
Returns the base name of a file specification.
Definition futil.c:775
int str_to_args(char **, char *, int)
Converts a string into an array of argument strings.
Definition futil.c:167
Definition cm.h:240

References abend(), base_name(), View::buf, View::buf_curr_ptr, View::cmd, View::cmd_all, cmd_key, View::cur_file_str, destroy_argv(), display_error(), em0, em1, em2, expand_tilde(), View::f_in_pipe, View::file_name, View::file_size, View::in_fd, View::mark_tbl, Perror(), View::prev_file_pos, View::provider_cmd, ssnprintf(), str_to_args(), strnz__cat(), strnz__cpy(), wait_continue(), wait_destroy(), wait_mk_chyron(), wait_mk_win(), wait_timeout, and waitpid_with_timeout().

Referenced by view_file().

Here is the call graph for this function:
Here is the caller graph for this function: