void start_streaming() { if(X11GRAB) { x11_init(&screenWidth, &screenHeight, &screenDepths); } RGBQUAD *pRgb = malloc( screenWidth * screenHeight * 3 * sizeof(RGBQUAD)); if(WITH_NVENC){ } else { desktopStreamer_encoder_init(&screenWidth, &screenHeight); } for(;;) { if(X11GRAB) { x11_getNextFrame(pRgb, &screenWidth, &screenHeight); } if(WITH_NVENC){ } else { desktopStreamer_encoder_encodeFrame(pRgb, &screenWidth, &screenHeight); } } }
void init(const char *_cmd) { x11_init(); checkotherwm(); cmd = _cmd; /* Setup the motion struct */ motion = xcalloc(1, sizeof(struct motion)); motion->type = NoMotion; sysinfo_init(); clients_init(); bars_init(settings()->barfont); launcher_init(); /* Select wvents to handle */ XSelectInput(dpy, root, WM_EVENT_MASK); /* Setup cursors */ cursors_init(); cursor_set(root, NormalCursor); /* Setup key bindings */ keys = settings()->keys; key_init(); key_grab_all(keys); /* Init atoms and EWMH */ atoms_init(); ewmh_init(wm_name); /* Init program lists */ program_init(getenv("PATH")); /* Create monitors */ create_monitors(); /* Init ewmh desktop functionality */ ewmh_root_set_number_of_desktops( monitor_count(mons) * N_WORKSPACES); ewmh_root_set_current_desktop(0); get_windows(); set_environment(); }
static void init_program(int argc,char **argv) { x11_init(argc,argv); if(sm->sologame) start_signal(); else { #ifdef USE_IPC int fd[2]; setup_sigchild(); if(pipe(fd) < 0) { perror("pipe"); exit(1); } if( (child_pids[0] = fork()) == 0) { close(fd[1]); if( (child_pids[1] = fork()) == 0) { /* we use a pipe to check if the daddy is dead: */ dup2(fd[0],0); /* I'm no unix-guru, so if you know a better way, */ close(fd[0]); /* pls. let me know (perhaps with a processgroup */ init_net(sm->hostname); /* <- should be neverending */ exit(1); /* <- but sure is sure :-) */ } close(fd[0]); x11_cntrl(); exit(1); } if(child_pids[0] < 0) { perror("fork"); exit(1); } close(fd[0]); #else if(init_net(sm->hostname) < 0) { fprintf(stderr,"nm: Networkproblems\n"); exit(1); } #endif } }
int main(int argc, char* argv[]) { x11_init(); glewInit(); int init = main_init(argc, argv); if(init) { x11_end(); return init; } while(!killme) { handle_events(); main_loop(); glXSwapBuffers(display, window); } main_end(); x11_end(); return 0; }
int main (int argc, char **argv) { const char *prev_arg; const char *shname; const char *runprog = NULL; int remaining_args = 0; int exit_with_session; int exit_with_x11 = FALSE; int binary_syntax = FALSE; int c_shell_syntax = FALSE; int bourne_shell_syntax = FALSE; int auto_shell_syntax = FALSE; int autolaunch = FALSE; int requires_arg = FALSE; int close_stderr = FALSE; int i; int ret; int bus_pid_to_launcher_pipe[2]; int bus_pid_to_babysitter_pipe[2]; int bus_address_to_launcher_pipe[2]; char *config_file; dbus_bool_t user_bus_supported = FALSE; DBusString user_bus; const char *error_str; exit_with_session = FALSE; config_file = NULL; /* Ensure that the first three fds are open, to ensure that when we * create other file descriptors (for example for epoll, inotify or * a socket), they never get assigned as fd 0, 1 or 2. If they were, * which could happen if our caller had (incorrectly) closed those * standard fds, then we'd start dbus-daemon with those fds closed, * which is unexpected and could cause it to misbehave. */ if (!_dbus_ensure_standard_fds (0, &error_str)) { fprintf (stderr, "dbus-launch: fatal error setting up standard fds: %s: %s\n", error_str, _dbus_strerror (errno)); return 1; } prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) usage (0); else if (strcmp (arg, "--auto-syntax") == 0) auto_shell_syntax = TRUE; else if (strcmp (arg, "-c") == 0 || strcmp (arg, "--csh-syntax") == 0) c_shell_syntax = TRUE; else if (strcmp (arg, "-s") == 0 || strcmp (arg, "--sh-syntax") == 0) bourne_shell_syntax = TRUE; else if (strcmp (arg, "--binary-syntax") == 0) binary_syntax = TRUE; else if (strcmp (arg, "--version") == 0) version (); else if (strcmp (arg, "--exit-with-session") == 0) exit_with_session = TRUE; else if (strcmp (arg, "--exit-with-x11") == 0) exit_with_x11 = TRUE; else if (strcmp (arg, "--close-stderr") == 0) close_stderr = TRUE; else if (strstr (arg, "--autolaunch=") == arg) { const char *s; if (autolaunch) { fprintf (stderr, "--autolaunch given twice\n"); exit (1); } autolaunch = TRUE; s = strchr (arg, '='); ++s; save_machine_uuid (s); } else if (prev_arg && strcmp (prev_arg, "--autolaunch") == 0) { if (autolaunch) { fprintf (stderr, "--autolaunch given twice\n"); exit (1); } autolaunch = TRUE; save_machine_uuid (arg); requires_arg = FALSE; } else if (strcmp (arg, "--autolaunch") == 0) requires_arg = TRUE; else if (strstr (arg, "--config-file=") == arg) { const char *file; if (config_file != NULL) { fprintf (stderr, "--config-file given twice\n"); exit (1); } file = strchr (arg, '='); ++file; config_file = xstrdup (file); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { if (config_file != NULL) { fprintf (stderr, "--config-file given twice\n"); exit (1); } config_file = xstrdup (arg); requires_arg = FALSE; } else if (strcmp (arg, "--config-file") == 0) requires_arg = TRUE; else if (arg[0] == '-') { if (strcmp (arg, "--") != 0) { fprintf (stderr, "Option `%s' is unknown.\n", arg); exit (1); } else { runprog = argv[i+1]; remaining_args = i+2; break; } } else { runprog = arg; remaining_args = i+1; break; } prev_arg = arg; ++i; } if (requires_arg) { fprintf (stderr, "Option `%s' requires an argument.\n", prev_arg); exit (1); } if (auto_shell_syntax) { if ((shname = getenv ("SHELL")) != NULL) { if (!strncmp (shname + strlen (shname) - 3, "csh", 3)) c_shell_syntax = TRUE; else bourne_shell_syntax = TRUE; } else bourne_shell_syntax = TRUE; } if (exit_with_session) verbose ("--exit-with-session enabled\n"); if (exit_with_x11) verbose ("--exit-with-x11 enabled\n"); if (autolaunch) { #ifndef DBUS_BUILD_X11 fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n" "Cannot continue.\n"); exit (1); #else /* DBUS_BUILD_X11 */ fprintf (stderr, "X11 autolaunch support disabled at compile time.\n"); exit (1); #endif /* DBUS_BUILD_X11 */ } else if (exit_with_x11) { #ifndef DBUS_BUILD_X11 fprintf (stderr, "Session lifetime based on X11 requested, but X11 support not compiled in.\n"); exit (1); #else /* DBUS_BUILD_X11 */ if (!read_machine_uuid_if_needed()) { fprintf (stderr, "Session lifetime based on X11 requested, but machine UUID unavailable.\n"); exit (1); } if (!x11_init ()) { fprintf (stderr, "Session lifetime based on X11 requested, but X11 initialization failed.\n"); exit (1); } #endif /* DBUS_BUILD_X11 */ } #ifdef DBUS_BUILD_X11 else if (read_machine_uuid_if_needed()) { x11_init(); } #endif /* DBUS_BUILD_X11 */ if (pipe (bus_pid_to_launcher_pipe) < 0 || pipe (bus_address_to_launcher_pipe) < 0 || pipe (bus_pid_to_babysitter_pipe) < 0) { fprintf (stderr, "Failed to create pipe: %s\n", strerror (errno)); exit (1); } ret = fork (); if (ret < 0) { fprintf (stderr, "Failed to fork: %s\n", strerror (errno)); exit (1); } if (ret == 0) { /* Child */ #define MAX_FD_LEN 64 char write_pid_fd_as_string[MAX_FD_LEN]; char write_address_fd_as_string[MAX_FD_LEN]; #ifdef DBUS_BUILD_X11 xdisplay = NULL; #endif if (close_stderr) do_close_stderr (); verbose ("=== Babysitter's intermediate parent created\n"); /* Fork once more to create babysitter */ ret = fork (); if (ret < 0) { fprintf (stderr, "Failed to fork: %s\n", strerror (errno)); exit (1); } if (ret > 0) { /* In babysitter */ verbose ("=== Babysitter's intermediate parent continues\n"); close (bus_pid_to_launcher_pipe[READ_END]); close (bus_pid_to_launcher_pipe[WRITE_END]); close (bus_address_to_launcher_pipe[READ_END]); close (bus_address_to_launcher_pipe[WRITE_END]); close (bus_pid_to_babysitter_pipe[WRITE_END]); /* babysit() will fork *again* * and will also reap the pre-forked bus * daemon */ babysit (exit_with_session || exit_with_x11, ret, bus_pid_to_babysitter_pipe[READ_END]); exit (0); } verbose ("=== Bus exec process created\n"); /* Now we are the bus process (well, almost; * dbus-daemon itself forks again) */ close (bus_pid_to_launcher_pipe[READ_END]); close (bus_address_to_launcher_pipe[READ_END]); close (bus_pid_to_babysitter_pipe[READ_END]); close (bus_pid_to_babysitter_pipe[WRITE_END]); /* If we have a user bus and want to use it, do so instead of * exec'ing a new dbus-daemon. */ if (autolaunch && user_bus_supported) { do_write (bus_pid_to_launcher_pipe[WRITE_END], "0\n", 2); close (bus_pid_to_launcher_pipe[WRITE_END]); do_write (bus_address_to_launcher_pipe[WRITE_END], _dbus_string_get_const_data (&user_bus), _dbus_string_get_length (&user_bus)); do_write (bus_address_to_launcher_pipe[WRITE_END], "\n", 1); close (bus_address_to_launcher_pipe[WRITE_END]); exit (0); } sprintf (write_pid_fd_as_string, "%d", bus_pid_to_launcher_pipe[WRITE_END]); sprintf (write_address_fd_as_string, "%d", bus_address_to_launcher_pipe[WRITE_END]); verbose ("Calling exec()\n"); #ifdef DBUS_ENABLE_EMBEDDED_TESTS { /* exec from testdir */ const char *test_daemon = getenv ("DBUS_TEST_DAEMON"); if (test_daemon != NULL) { if (config_file == NULL && getenv ("DBUS_TEST_DATA") != NULL) { config_file = concat2 (getenv ("DBUS_TEST_DATA"), "/valid-config-files/session.conf"); if (config_file == NULL) { fprintf (stderr, "Out of memory\n"); exit (1); } } execl (test_daemon, test_daemon, "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute test message bus daemon %s: %s.\n", test_daemon, strerror (errno)); exit (1); } } #endif /* DBUS_ENABLE_EMBEDDED_TESTS */ execl (DBUS_DAEMONDIR"/dbus-daemon", DBUS_DAEMONDIR"/dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute message bus daemon %s: %s. Will try again without full path.\n", DBUS_DAEMONDIR"/dbus-daemon", strerror (errno)); /* * If it failed, try running without full PATH. Note this is needed * because the build process builds the run-with-tmp-session-bus.conf * file and the dbus-daemon will not be in the install location during * build time. */ execlp ("dbus-daemon", "dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute message bus daemon: %s\n", strerror (errno)); exit (1); } else { /* Parent */ #define MAX_PID_LEN 64 pid_t bus_pid; char bus_address[MAX_ADDR_LEN]; char buf[MAX_PID_LEN]; char *end; long wid = 0; long val; verbose ("=== Parent dbus-launch continues\n"); close (bus_pid_to_launcher_pipe[WRITE_END]); close (bus_address_to_launcher_pipe[WRITE_END]); close (bus_pid_to_babysitter_pipe[READ_END]); verbose ("Waiting for babysitter's intermediate parent\n"); /* Immediately reap parent of babysitter * (which was created just for us to reap) */ if (do_waitpid (ret) < 0) { fprintf (stderr, "Failed to waitpid() for babysitter intermediate process: %s\n", strerror (errno)); exit (1); } verbose ("Reading address from bus\n"); /* Read the pipe data, print, and exit */ switch (read_line (bus_address_to_launcher_pipe[READ_END], bus_address, MAX_ADDR_LEN)) { case READ_STATUS_OK: break; case READ_STATUS_EOF: fprintf (stderr, "EOF in dbus-launch reading address from bus daemon\n"); exit (1); break; case READ_STATUS_ERROR: fprintf (stderr, "Error in dbus-launch reading address from bus daemon: %s\n", strerror (errno)); exit (1); break; } close (bus_address_to_launcher_pipe[READ_END]); verbose ("Reading PID from daemon\n"); /* Now read data */ switch (read_line (bus_pid_to_launcher_pipe[READ_END], buf, MAX_PID_LEN)) { case READ_STATUS_OK: break; case READ_STATUS_EOF: fprintf (stderr, "EOF reading PID from bus daemon\n"); exit (1); break; case READ_STATUS_ERROR: fprintf (stderr, "Error reading PID from bus daemon: %s\n", strerror (errno)); exit (1); break; } end = NULL; val = strtol (buf, &end, 0); if (buf == end || end == NULL) { fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n", buf, strerror (errno)); exit (1); } bus_pid = val; /* Have to initialize bus_pid_to_kill ASAP, so that the X error callback can kill it if an error happens. */ bus_pid_to_kill = bus_pid; close (bus_pid_to_launcher_pipe[READ_END]); #ifdef DBUS_ENABLE_X11_AUTOLAUNCH if (xdisplay != NULL) { int ret2; verbose("Saving x11 address\n"); ret2 = x11_save_address (bus_address, bus_pid, &wid); /* Only get an existing dbus session when autolaunching */ if (autolaunch) { if (ret2 == 0) { char *address = NULL; /* another window got added. Return its address */ if (x11_get_address (&address, &bus_pid, &wid) && address != NULL) { verbose ("dbus-daemon is already running. Returning existing parameters.\n"); /* Kill the old bus */ kill_bus(); pass_info (runprog, address, bus_pid, wid, c_shell_syntax, bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); } } if (ret2 < 0) { fprintf (stderr, "Error saving bus information.\n"); bus_pid_to_kill = bus_pid; kill_bus_and_exit (1); } } } #endif /* Forward the pid to the babysitter */ write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid); close (bus_pid_to_babysitter_pipe[WRITE_END]); pass_info (runprog, bus_address, bus_pid, wid, c_shell_syntax, bourne_shell_syntax, binary_syntax, argc, argv, remaining_args); } return 0; }
static void kill_bus_when_session_ends (void) { int tty_fd; int x_fd; fd_set read_set; fd_set err_set; struct sigaction act; sigset_t empty_mask; /* install SIGHUP handler */ got_sighup = FALSE; sigemptyset (&empty_mask); act.sa_handler = signal_handler; act.sa_mask = empty_mask; act.sa_flags = 0; sigaction (SIGHUP, &act, NULL); sigaction (SIGTERM, &act, NULL); sigaction (SIGINT, &act, NULL); #ifdef DBUS_BUILD_X11 x11_init(); if (xdisplay != NULL) { x_fd = ConnectionNumber (xdisplay); } else x_fd = -1; #else x_fd = -1; #endif if (isatty (0)) tty_fd = 0; else tty_fd = -1; if (x_fd >= 0) { verbose ("session lifetime is defined by X, not monitoring stdin\n"); tty_fd = -1; } else if (tty_fd >= 0) { verbose ("stdin isatty(), monitoring it\n"); } else { verbose ("stdin was not a TTY, not monitoring it\n"); } if (tty_fd < 0 && x_fd < 0) { fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n"); kill_bus_and_exit (1); } while (TRUE) { #ifdef DBUS_BUILD_X11 /* Dump events on the floor, and let * IO error handler run if we lose * the X connection. It's important to * run this before going into select() since * we might have queued outgoing messages or * events. */ x11_handle_event (); #endif FD_ZERO (&read_set); FD_ZERO (&err_set); if (tty_fd >= 0) { FD_SET (tty_fd, &read_set); FD_SET (tty_fd, &err_set); } if (x_fd >= 0) { FD_SET (x_fd, &read_set); FD_SET (x_fd, &err_set); } select (MAX (tty_fd, x_fd) + 1, &read_set, NULL, &err_set, NULL); if (got_sighup) { verbose ("Got SIGHUP, exiting\n"); kill_bus_and_exit (0); } #ifdef DBUS_BUILD_X11 /* Events will be processed before we select again */ if (x_fd >= 0) verbose ("X fd condition reading = %d error = %d\n", FD_ISSET (x_fd, &read_set), FD_ISSET (x_fd, &err_set)); #endif if (tty_fd >= 0) { if (FD_ISSET (tty_fd, &read_set)) { int bytes_read; char discard[512]; verbose ("TTY ready for reading\n"); bytes_read = read (tty_fd, discard, sizeof (discard)); verbose ("Read %d bytes from TTY errno = %d\n", bytes_read, errno); if (bytes_read == 0) kill_bus_and_exit (0); /* EOF */ else if (bytes_read < 0 && errno != EINTR) { /* This shouldn't happen I don't think; to avoid * spinning on the fd forever we exit. */ fprintf (stderr, "dbus-launch: error reading from stdin: %s\n", strerror (errno)); kill_bus_and_exit (0); } } else if (FD_ISSET (tty_fd, &err_set)) { verbose ("TTY has error condition\n"); kill_bus_and_exit (0); } } } }
int main (int argc, char *argv[]) { GCContext gc_context; GMainLoop *mainLoop; GKeyFile *keyFile; GThread *displayThread; GThread *inputControllerThread; GThread *x11EventThread; int i; GCConfig config = { .movie_path = DEFAULT_MOVIE_PATH, .mask_path = DEFAULT_MASK_PATH, .controller_path = DEFAULT_CONTROLLER_PATH, .seconds_per_frame = DEFAULT_SECONDS_PER_FRAME, .easing_factor = DEFAULT_EASING_FACTOR, .frames_per_tick = 0, .diameter_controller = 0, .diameter_rim = 0, .ctr = 0, .fpr = 0, .number_of_frames = 0, .fullscreen = TRUE, .timeZone = NULL, }; Movie movie = { .planes = NULL, .frame_offset = 0, .fd_movie = -1, .frame = { .pitches = { FRAME_PITCH, 0, 0 } }, .fd_mask = -1, .mask = { .pitches = { MASK_PITCH, 0, 0 } }, .pre_load_surface = VDP_INVALID_HANDLE, .play_direction = DIRECTION_FORWARD, .ticks = 0, .new_frame = FALSE, .ease_to = TRUE, }; keyFile = g_key_file_new(); if (argc > 1 && g_key_file_load_from_file(keyFile, argv[1], G_KEY_FILE_NONE, NULL)) { if (g_key_file_has_group(keyFile, "MAIN")) { if (g_key_file_has_key(keyFile, "MAIN", "utc_offset", NULL)) config.timeZone = g_time_zone_new(g_key_file_get_string(keyFile, "MAIN", "utc_offset", NULL)); if (g_key_file_has_key(keyFile, "MAIN", "ease_to_time", NULL)) movie.ease_to = g_key_file_get_boolean(keyFile, "MAIN", "ease_to_time", NULL); } if (g_key_file_has_group(keyFile, "MOVIE")) { if (g_key_file_has_key(keyFile, "MOVIE", "file", NULL)) config.movie_path = g_key_file_get_string(keyFile, "MOVIE", "file", NULL); if (g_key_file_has_key(keyFile, "MOVIE", "mask", NULL)) config.mask_path = g_key_file_get_string(keyFile, "MOVIE", "mask", NULL); if (g_key_file_has_key(keyFile, "MOVIE", "seconds_per_frame", NULL)) config.seconds_per_frame = (float)g_key_file_get_double(keyFile, "MOVIE", "seconds_per_frame", NULL); if (g_key_file_has_key(keyFile, "MOVIE", "easing_factor", NULL)) config.easing_factor = (float)g_key_file_get_integer(keyFile, "MOVIE", "easing_factor", NULL); } if (g_key_file_has_group(keyFile, "CONTROLLER")) { if (g_key_file_has_key(keyFile, "CONTROLLER", "path", NULL)) config.controller_path = g_key_file_get_string(keyFile, "CONTROLLER", "path", NULL); if (g_key_file_has_key(keyFile, "CONTROLLER", "diameter_controller", NULL)) config.diameter_controller = (float)g_key_file_get_double(keyFile, "CONTROLLER", "diameter_controller", NULL); if (g_key_file_has_key(keyFile, "CONTROLLER", "diameter_rim", NULL)) config.diameter_rim = (float)g_key_file_get_double(keyFile, "CONTROLLER", "diameter_rim", NULL); if (g_key_file_has_key(keyFile, "CONTROLLER", "ctr", NULL)) config.ctr = (float)g_key_file_get_double(keyFile, "CONTROLLER", "ctr", NULL); if (g_key_file_has_key(keyFile, "CONTROLLER", "fpr", NULL)) config.fpr = (float)g_key_file_get_double(keyFile, "CONTROLLER", "fpr", NULL); if (g_key_file_has_key(keyFile, "CONTROLLER", "frames_per_tick", NULL)) config.frames_per_tick = (float)g_key_file_get_double(keyFile, "CONTROLLER", "frames_per_tick", NULL); } if (g_key_file_has_group(keyFile, "SCREEN")) { if (g_key_file_has_key(keyFile, "SCREEN", "fullscreen", NULL)) config.fullscreen = g_key_file_get_boolean(keyFile, "SCREEN", "fullscreen", NULL); } g_key_file_free(keyFile); } if (!config.timeZone) config.timeZone = g_time_zone_new_local(); if (!config.frames_per_tick && !(config.frames_per_tick = frames_per_tick(config.diameter_controller, config.diameter_rim, config.ctr, config.fpr))) { g_warning("No valid tick settings, using default frames per tick: %f", DEFAULT_FRAMES_PER_TICK); config.frames_per_tick = DEFAULT_FRAMES_PER_TICK; } config.movie_size = get_file_size(config.movie_path); config.number_of_frames = config.movie_size / FRAME_SIZE; mainLoop = g_main_loop_new(NULL, FALSE); gc_context.g_main_loop = mainLoop; gc_context.g_main_context = g_main_loop_get_context(mainLoop); gc_context.window_size.width = MOVIE_WIDTH; gc_context.window_size.height = MOVIE_HEIGHT; gc_context.exit = FALSE; gc_context.movie_context = &movie; gc_context.config = &config; g_message("movie file: %s", config.movie_path); g_message("movie size: %lu", config.movie_size); g_message("movie frames: %lu", config.number_of_frames); g_message("movie mask file: %s", config.mask_path); g_message("frames per minute: %f", get_frames_per_minute(&gc_context)); g_message("frames per day: %lu", get_frames_per_day(&gc_context)); g_message("frames per tick: %f", config.frames_per_tick); g_message("number of days: %d", get_number_of_days(&gc_context)); g_message("current day: %d", get_current_day(&gc_context)); if (movie.ease_to) { movie.ease_to_frame = get_frame_offset(&gc_context, GO_TO_RAND_DAY, DAY_OFFSET_NOW); g_message("ease to frame: %lu", movie.ease_to_frame); } x11_init(&gc_context); vdpau_init(&gc_context); load_movie(&gc_context); load_mask(&gc_context); g_cond_init(&movie.tick_cond); g_mutex_init(&movie.tick_lock); g_mutex_init(&movie.frame_lock); displayThread = g_thread_new("Display thread", display_thread, (gpointer)&gc_context); inputControllerThread = g_thread_new("Input controller thread", input_controller_thread, (gpointer)&gc_context); x11EventThread = g_thread_new("X11 Event thread", x11_event_thread, (gpointer)&gc_context); g_main_loop_run(mainLoop); gc_context.exit = TRUE; g_thread_join(displayThread); g_thread_join(inputControllerThread); g_thread_join(x11EventThread); g_cond_clear(&movie.tick_cond); g_mutex_clear(&movie.tick_lock); g_mutex_clear(&movie.frame_lock); g_time_zone_unref(config.timeZone); }
int main(int argc, char** argv){ CFG config={ 0, //verbosity 0, //padding 0, //line spacing 0, //max size ALIGN_CENTER, //alignment false, //independent resize false, //handle stdin false, //draw debug boxes false, //disable text drawing true, //use double buffering 0, //forced size NULL, //text color NULL, //background color NULL, //debug color name NULL, //font name }; XRESOURCES xres={ 0, //screen NULL, //display 0, //window 0, //back buffer NULL, //xft drawable {}, //text color {}, //bg color {}, //debug color {NULL, 0} //xfd set }; int args_end; unsigned text_length, i; char* args_text=NULL; long flags; //parse command line arguments args_end=args_parse(&config, argc-1, argv+1); if(argc-args_end<1&&!config.handle_stdin){ return usage(argv[0]); } //config sanity check if(!args_sane(&config)){ args_cleanup(&config); return usage(argv[0]); } //set up x11 display if(!x11_init(&xres, &config)){ x11_cleanup(&xres, &config); args_cleanup(&config); return usage(argv[0]); } //preprocess display text if given if(argc-args_end>0){ //copy arguments into buffer text_length=0; for(i=args_end;i<argc;i++){ text_length+=strlen(argv[i])+1; } args_text=calloc(text_length, sizeof(char)); text_length=0; for(i=args_end;i<argc;i++){ strncpy(args_text+text_length, argv[i], strlen(argv[i])); text_length+=strlen(argv[i]); args_text[text_length++]=' '; } args_text[((text_length>0)?text_length:1)-1]=0; errlog(&config, LOG_INFO, "Input text:\n\"%s\"\n", args_text); //preprocess if(!string_preprocess(args_text, true)){ fprintf(stderr, "Failed to preprocess input text\n"); x11_cleanup(&xres, &config); args_cleanup(&config); return usage(argv[0]); } errlog(&config, LOG_DEBUG, "Printing text:\n\"%s\"\n", args_text); } //prepare stdin if(config.handle_stdin){ errlog(&config, LOG_INFO, "Marking stdin as nonblocking\n"); flags=fcntl(0, F_GETFL, 0); flags|=O_NONBLOCK; fcntl(0, F_SETFL, flags); } //enter main loop xecho(&config, &xres, args_text); //clear data x11_cleanup(&xres, &config); args_cleanup(&config); if(args_text){ free(args_text); } errlog(&config, LOG_INFO, "xecho shutdown ok\n"); return 0; }
int main (int argc, char **argv) { const char *prev_arg; const char *shname; const char *runprog = NULL; int remaining_args = 0; int exit_with_session; int binary_syntax = FALSE; int c_shell_syntax = FALSE; int bourne_shell_syntax = FALSE; int auto_shell_syntax = FALSE; int autolaunch = FALSE; int requires_arg = FALSE; int close_stderr = FALSE; int i; int ret; int bus_pid_to_launcher_pipe[2]; int bus_pid_to_babysitter_pipe[2]; int bus_address_to_launcher_pipe[2]; char *config_file; exit_with_session = FALSE; config_file = NULL; prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) usage (0); else if (strcmp (arg, "--auto-syntax") == 0) auto_shell_syntax = TRUE; else if (strcmp (arg, "-c") == 0 || strcmp (arg, "--csh-syntax") == 0) c_shell_syntax = TRUE; else if (strcmp (arg, "-s") == 0 || strcmp (arg, "--sh-syntax") == 0) bourne_shell_syntax = TRUE; else if (strcmp (arg, "--binary-syntax") == 0) binary_syntax = TRUE; else if (strcmp (arg, "--version") == 0) version (); else if (strcmp (arg, "--exit-with-session") == 0) exit_with_session = TRUE; else if (strcmp (arg, "--close-stderr") == 0) close_stderr = TRUE; else if (strstr (arg, "--autolaunch=") == arg) { const char *s; if (autolaunch) { fprintf (stderr, "--autolaunch given twice\n"); exit (1); } autolaunch = TRUE; s = strchr (arg, '='); ++s; save_machine_uuid (s); } else if (prev_arg && strcmp (prev_arg, "--autolaunch") == 0) { if (autolaunch) { fprintf (stderr, "--autolaunch given twice\n"); exit (1); } autolaunch = TRUE; save_machine_uuid (arg); requires_arg = FALSE; } else if (strcmp (arg, "--autolaunch") == 0) requires_arg = TRUE; else if (strstr (arg, "--config-file=") == arg) { const char *file; if (config_file != NULL) { fprintf (stderr, "--config-file given twice\n"); exit (1); } file = strchr (arg, '='); ++file; config_file = xstrdup (file); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { if (config_file != NULL) { fprintf (stderr, "--config-file given twice\n"); exit (1); } config_file = xstrdup (arg); requires_arg = FALSE; } else if (strcmp (arg, "--config-file") == 0) requires_arg = TRUE; else if (arg[0] == '-') { if (strcmp (arg, "--") != 0) { fprintf (stderr, "Option `%s' is unknown.\n", arg); exit (1); } else { runprog = argv[i+1]; remaining_args = i+2; break; } } else { runprog = arg; remaining_args = i+1; break; } prev_arg = arg; ++i; } if (requires_arg) { fprintf (stderr, "Option `%s' requires an argument.\n", prev_arg); exit (1); } if (auto_shell_syntax) { if ((shname = getenv ("SHELL")) != NULL) { if (!strncmp (shname + strlen (shname) - 3, "csh", 3)) c_shell_syntax = TRUE; else bourne_shell_syntax = TRUE; } else bourne_shell_syntax = TRUE; } if (exit_with_session) verbose ("--exit-with-session enabled\n"); if (autolaunch) { #ifndef DBUS_BUILD_X11 fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n" "Cannot continue.\n"); exit (1); #else char *address; pid_t pid; long wid; if (get_machine_uuid () == NULL) { fprintf (stderr, "Machine UUID not provided as arg to --autolaunch\n"); exit (1); } /* FIXME right now autolaunch always does print_variables(), but it should really * exec the child program instead if a child program was specified. For now * we just exit if this conflict arises. */ if (runprog) { fprintf (stderr, "Currently --autolaunch does not support running a program\n"); exit (1); } verbose ("Autolaunch enabled (using X11).\n"); if (!exit_with_session) { verbose ("--exit-with-session automatically enabled\n"); exit_with_session = TRUE; } if (!x11_init ()) { fprintf (stderr, "Autolaunch error: X11 initialization failed.\n"); exit (1); } if (!x11_get_address (&address, &pid, &wid)) { fprintf (stderr, "Autolaunch error: X11 communication error.\n"); exit (1); } if (address != NULL) { verbose ("dbus-daemon is already running. Returning existing parameters.\n"); print_variables (address, pid, wid, c_shell_syntax, bourne_shell_syntax, binary_syntax); exit (0); } #endif } if (pipe (bus_pid_to_launcher_pipe) < 0 || pipe (bus_address_to_launcher_pipe) < 0 || pipe (bus_pid_to_babysitter_pipe) < 0) { fprintf (stderr, "Failed to create pipe: %s\n", strerror (errno)); exit (1); } ret = fork (); if (ret < 0) { fprintf (stderr, "Failed to fork: %s\n", strerror (errno)); exit (1); } if (ret == 0) { /* Child */ #define MAX_FD_LEN 64 char write_pid_fd_as_string[MAX_FD_LEN]; char write_address_fd_as_string[MAX_FD_LEN]; if (close_stderr) do_close_stderr (); verbose ("=== Babysitter's intermediate parent created\n"); /* Fork once more to create babysitter */ ret = fork (); if (ret < 0) { fprintf (stderr, "Failed to fork: %s\n", strerror (errno)); exit (1); } if (ret > 0) { /* In babysitter */ verbose ("=== Babysitter's intermediate parent continues\n"); close (bus_pid_to_launcher_pipe[READ_END]); close (bus_pid_to_launcher_pipe[WRITE_END]); close (bus_address_to_launcher_pipe[READ_END]); close (bus_address_to_launcher_pipe[WRITE_END]); close (bus_pid_to_babysitter_pipe[WRITE_END]); /* babysit() will fork *again* * and will also reap the pre-forked bus * daemon */ babysit (exit_with_session, ret, bus_pid_to_babysitter_pipe[READ_END]); exit (0); } verbose ("=== Bus exec process created\n"); /* Now we are the bus process (well, almost; * dbus-daemon itself forks again) */ close (bus_pid_to_launcher_pipe[READ_END]); close (bus_address_to_launcher_pipe[READ_END]); close (bus_pid_to_babysitter_pipe[READ_END]); close (bus_pid_to_babysitter_pipe[WRITE_END]); sprintf (write_pid_fd_as_string, "%d", bus_pid_to_launcher_pipe[WRITE_END]); sprintf (write_address_fd_as_string, "%d", bus_address_to_launcher_pipe[WRITE_END]); verbose ("Calling exec()\n"); #ifdef DBUS_BUILD_TESTS /* exec from testdir */ if (getenv("DBUS_USE_TEST_BINARY") != NULL) { execl (TEST_BUS_BINARY, TEST_BUS_BINARY, "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute test message bus daemon %s: %s. Will try again with the system path.\n", TEST_BUS_BINARY, strerror (errno)); } #endif /* DBUS_BUILD_TESTS */ execl (DBUS_DAEMONDIR"/dbus-daemon", DBUS_DAEMONDIR"/dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute message bus daemon %s: %s. Will try again without full path.\n", DBUS_DAEMONDIR"/dbus-daemon", strerror (errno)); /* * If it failed, try running without full PATH. Note this is needed * because the build process builds the run-with-tmp-session-bus.conf * file and the dbus-daemon will not be in the install location during * build time. */ execlp ("dbus-daemon", "dbus-daemon", "--fork", "--print-pid", write_pid_fd_as_string, "--print-address", write_address_fd_as_string, config_file ? "--config-file" : "--session", config_file, /* has to be last in this varargs list */ NULL); fprintf (stderr, "Failed to execute message bus daemon: %s\n", strerror (errno)); exit (1); } else { /* Parent */ #define MAX_PID_LEN 64 pid_t bus_pid; char bus_address[MAX_ADDR_LEN]; char buf[MAX_PID_LEN]; char *end; long wid = 0; long val; int ret2; verbose ("=== Parent dbus-launch continues\n"); close (bus_pid_to_launcher_pipe[WRITE_END]); close (bus_address_to_launcher_pipe[WRITE_END]); close (bus_pid_to_babysitter_pipe[READ_END]); verbose ("Waiting for babysitter's intermediate parent\n"); /* Immediately reap parent of babysitter * (which was created just for us to reap) */ if (do_waitpid (ret) < 0) { fprintf (stderr, "Failed to waitpid() for babysitter intermediate process: %s\n", strerror (errno)); exit (1); } verbose ("Reading address from bus\n"); /* Read the pipe data, print, and exit */ switch (read_line (bus_address_to_launcher_pipe[READ_END], bus_address, MAX_ADDR_LEN)) { case READ_STATUS_OK: break; case READ_STATUS_EOF: fprintf (stderr, "EOF in dbus-launch reading address from bus daemon\n"); exit (1); break; case READ_STATUS_ERROR: fprintf (stderr, "Error in dbus-launch reading address from bus daemon: %s\n", strerror (errno)); exit (1); break; } close (bus_address_to_launcher_pipe[READ_END]); verbose ("Reading PID from daemon\n"); /* Now read data */ switch (read_line (bus_pid_to_launcher_pipe[READ_END], buf, MAX_PID_LEN)) { case READ_STATUS_OK: break; case READ_STATUS_EOF: fprintf (stderr, "EOF reading PID from bus daemon\n"); exit (1); break; case READ_STATUS_ERROR: fprintf (stderr, "Error reading PID from bus daemon: %s\n", strerror (errno)); exit (1); break; } end = NULL; val = strtol (buf, &end, 0); if (buf == end || end == NULL) { fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n", buf, strerror (errno)); exit (1); } bus_pid = val; close (bus_pid_to_launcher_pipe[READ_END]); #ifdef DBUS_BUILD_X11 /* FIXME the runprog == NULL is broken - we need to launch the runprog with the existing bus, * instead of just doing print_variables() if there's an existing bus. */ if (xdisplay != NULL && runprog == NULL) { ret2 = x11_save_address (bus_address, bus_pid, &wid); if (ret2 == 0) { /* another window got added. Return its address */ char *address; pid_t pid; long wid; if (x11_get_address (&address, &pid, &wid) && address != NULL) { verbose ("dbus-daemon is already running. Returning existing parameters.\n"); print_variables (address, pid, wid, c_shell_syntax, bourne_shell_syntax, binary_syntax); free (address); bus_pid_to_kill = bus_pid; kill_bus_and_exit (0); } /* if failed, fall through */ } if (ret2 <= 0) { fprintf (stderr, "Error saving bus information.\n"); bus_pid_to_kill = bus_pid; kill_bus_and_exit (1); } } #endif /* Forward the pid to the babysitter */ write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid); close (bus_pid_to_babysitter_pipe[WRITE_END]); if (runprog) { char *envvar; char **args; envvar = malloc (strlen ("DBUS_SESSION_BUS_ADDRESS=") + strlen (bus_address) + 1); args = malloc (sizeof (char *) * ((argc-remaining_args)+2)); if (envvar == NULL || args == NULL) goto oom; args[0] = xstrdup (runprog); if (!args[0]) goto oom; for (i = 1; i <= (argc-remaining_args); i++) { size_t len = strlen (argv[remaining_args+i-1])+1; args[i] = malloc (len); if (!args[i]) goto oom; strncpy (args[i], argv[remaining_args+i-1], len); } args[i] = NULL; strcpy (envvar, "DBUS_SESSION_BUS_ADDRESS="); strcat (envvar, bus_address); putenv (envvar); execvp (runprog, args); fprintf (stderr, "Couldn't exec %s: %s\n", runprog, strerror (errno)); exit (1); } else { print_variables (bus_address, bus_pid, wid, c_shell_syntax, bourne_shell_syntax, binary_syntax); } verbose ("dbus-launch exiting\n"); fflush (stdout); fflush (stderr); close (1); close (2); exit (0); } return 0; oom: fprintf (stderr, "Out of memory!"); exit (1); }