⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fax_list.cpp

📁 linux pritner GUI
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // is going on    pid_t pid = fork();    if (pid == -1) {      write_error("Fork error - exiting\n");      std::exit(FORK_ERROR);    }    if (!pid) { // child print process      // make the call to connect_to_stderr() in this child process      // dependent on calling a print confirmation popup dialog: if we have      // elected not to bring up such a dialog, we are probably using a      // print manager such as kprinter, and we can get confusing messages      // from stderr from these      // no mutex is required for the access to prog_config.print_popup      // because we have fork()ed into a separate process      if (prog_config.print_popup) connect_to_stderr();      // now create a blocking pipe which the print processes can use to      // communicate via stdout/stdin      Pipe_fifo fork_pipe(Pipe_fifo::block);            pid_t pid = fork();      if (pid == -1) {	write_error("Fork error - exiting\n");	_exit(FORK_ERROR);      }      if (!pid) { // process to exec to print_from_stdin()      	fork_pipe.connect_to_stdin();	execvp(print_from_stdin_parms.first, print_from_stdin_parms.second);	// if we reached this point, then the execvp() call must have failed	// write error and then end process - use _exit(), not exit()	write_error("Can't find the print program - please check your installation\n"		    "and the PATH environmental variable\n");	_exit(0);      }      // this is the process which will send postscript to stdout      fork_pipe.connect_to_stdout();      execvp(fax_to_ps_parms.first, fax_to_ps_parms.second);      // if we reached this point, then the execvp() call must have failed      // report error and then end process - use _exit(), not exit()      write_error("Can't find the efix-0.9a program - please check your installation\n"		  "and the PATH environmental variable\n");      _exit(0);    }    // release the memory allocated on the heap for    // the redundant print_from_stdin_parms and fax_to_ps_parms    // we are in the main parent process here - no worries about    // only being able to use async-signal-safe functions    delete_parms(print_from_stdin_parms);  }  delete_parms(fax_to_ps_parms);}void FaxListDialog::view_fax(void) {   // we do not need a mutex before reading prog_config.ps_view_cmd  // as although read in FaxListDialog::get_ps_viewer_parms(),  // the thread which executes that method is launched below as  // FaxListsDialog::view_fax_thread() and is therefore not running  // at this stage  if (fax_list_manager.is_fax_selected() && !prog_config.ps_view_cmd.empty()) {    // fax_basename_sem is initialised to a count of 1, so this will stop    // fax_basename being overwritten until Sem_sync::post() is called in    // print_fax_thread() or view_fax_thread() or on Glib::ThreadError being    // caught    fax_basename_sem.wait();    fax_basename = prog_config.working_dir;    if (mode == FaxListEnum::received) fax_basename += "/faxin/";    else fax_basename += "/faxsent/";    // we don't need to use a Glib conversion function here - we know the    // fax name is just plain ASCII numbers    std::string fax_number(fax_list_manager.get_fax_number());    fax_basename += fax_number;    fax_basename += '/';    fax_basename += fax_number;    fax_basename += '.';    // now block off the signals for which we have set handlers so that the socket server    // thread does not receive the signals, otherwise we will have memory synchronisation    // issues in multi-processor systems - we will unblock in the initial (GUI) thread    // as soon as the socket server thread has been launched    sigset_t sig_mask;    sigemptyset(&sig_mask);    sigaddset(&sig_mask, SIGCHLD);    sigaddset(&sig_mask, SIGQUIT);    sigaddset(&sig_mask, SIGTERM);    sigaddset(&sig_mask, SIGINT);    sigaddset(&sig_mask, SIGHUP);#ifdef HAVE_PTHREAD_SIGMASK     pthread_sigmask(SIG_BLOCK, &sig_mask, 0);#else    sigprocmask(SIG_BLOCK, &sig_mask, 0);#endif    try {      Glib::Thread::create(sigc::mem_fun(*this, &FaxListDialog::view_fax_thread), false);    }    catch (Glib::ThreadError&) {      write_error("Cannot start new view fax thread, fax cannot be viewed\n");      fax_basename_sem.post();    }    // now unblock the signals so that the initial (GUI) thread can receive them#ifdef HAVE_PTHREAD_SIGMASK     pthread_sigmask(SIG_UNBLOCK, &sig_mask, 0);#else    sigprocmask(SIG_UNBLOCK, &sig_mask, 0);#endif  }}void FaxListDialog::view_fax_thread(void) {   // get a temporary file  char filename[] = "/tmp/efax-gtk-view.XXXXXX";  int file_fd = mkstemp(filename);  if (file_fd == -1) {    write_error("Failed to make temporary file:\n"		"please check permissions in /tmp directory");    _exit(0);  }  // now create a pipe and proceed to fork to write the postscript to temporary file  Pipe_fifo fork_pipe(Pipe_fifo::block);  // get the arguments for the exec() call to convert the fax files to  // PS format following the next fork() call (because this is a multi-  // threaded program, we must do this before fork()ing because we use  // functions to get the arguments which are not async-signal-safe)  std::pair<const char*, char* const*> fax_to_ps_parms(get_fax_to_ps_parms(fax_basename, false));  // release main GUI thread in print_fax() or view_fax()  // waiting for this use of fax_basename to finish  fax_basename_sem.post();  // now fork to create the process which will write postscript to stdout  pid_t pid = fork();  if (pid == -1) {    write_error("Fork error - exiting\n");    _exit(FORK_ERROR);  }      if (!pid) { // child process which will send postscript to stdout      // this is the child process to write to stdin    // now we have fork()ed we can connect to stderr    connect_to_stderr();    fork_pipe.connect_to_stdout();    execvp(fax_to_ps_parms.first, fax_to_ps_parms.second);    // if we reached this point, then the execvp() call must have failed    // report error and then end process - use _exit(), not exit()    write_error("Can't find the efix-0.9a program - please check your installation\n"		"and the PATH environmental variable\n");    _exit(0);  }  // this is the parent process, which will convert the fax to Postscript  // and then pipe it on stdout to write_from_stdin()      // first, release the memory allocated on the heap for  // the redundant fax_to_ps_parms  // we are in the main parent process here - no worries about  // only being able to use async-signal-safe functions  delete_parms(fax_to_ps_parms);      // now write stdin in (containing the generated PS text) to file  fork_pipe.connect_to_stdin();  write_from_stdin(file_fd);  // the temporary file to be viewed has now been created  // so launch a new process to control the viewing process  // we will reset handlers and then fork() again having done  // so, so that we can wait on the child of child  // first get the arguments for the exec() call to launch the fax  // viewer following the next fork() call (because this is a multi-  // threaded program, we must do this before fork()ing because we use  // functions to get the arguments which are not async-signal-safe)  std::pair<const char*, char* const*> ps_viewer_parms(get_ps_viewer_parms(filename));  if (ps_viewer_parms.first) { // this will be 0 if get_ps_viewer_parms()                               // threw a Glib::ConvertError)        pid = fork();        if (pid == -1) {      write_error("Fork error\n");      std::exit(FORK_ERROR);    }    if (!pid) { // child view-control process          // restore the default SIGCHLD signal handler with SA_RESTART      // for systems (such as Linux) which require it.  Also unblock      // signals in case we are blocking them on launching a thread      // elsewhere in this program (I cannot work out from IEEE 1003.1      // whether all masks are emptied on a fork() in any event)      sigset_t sig_mask;      sigemptyset(&sig_mask);      sigaddset(&sig_mask, SIGCHLD);      sigaddset(&sig_mask, SIGQUIT);      sigaddset(&sig_mask, SIGTERM);      sigaddset(&sig_mask, SIGINT);      sigaddset(&sig_mask, SIGHUP);      // this child process is single threaded, so we can use sigprocmask()      // rather than pthread_sigmask() (and should do so as sigprocmask()      // is guaranteed to be async-signal-safe)      sigprocmask(SIG_UNBLOCK, &sig_mask, 0);      struct sigaction sig_act;      sig_act.sa_handler = SIG_DFL;      sigemptyset(&sig_act.sa_mask);#ifdef SA_RESTART      sig_act.sa_flags = SA_RESTART;#else      sig_act.sa_flags = 0;#endif      sigaction(SIGCHLD, &sig_act, 0);            connect_to_stderr();      // now fork() again      pid_t pid = fork();      if (pid == -1) {	write_error("Fork error - exiting\n");	_exit(FORK_ERROR);      }          if (!pid) { // child process to call ps_viewer() from	  	execvp(ps_viewer_parms.first, ps_viewer_parms.second);	// if we reached this point, then the execvp() call must have failed	// report error and then end process - use _exit(), not exit()	write_error("Can't find the ps viewer program - please check your installation\n"		    "and the PATH environmental variable\n");	_exit(0);      }      // now we are back to the main viewing process again      // delete the temporary file      // first wait till the ps_viewer() process is closed by the user exiting      // the postscript viewing program      wait(0);          unlink(filename);      // now terminate the process      _exit(0);    }    // release the memory allocated on the heap for    // the redundant ps_viewer_parms    // we are in the main parent process here - no worries about    // only being able to use async-signal-safe functions    delete_parms(ps_viewer_parms);  }}void FaxListDialog::delete_parms(std::pair<const char*, char* const*> parms_pair) {  delete[] parms_pair.first;  char* const* temp_pp = parms_pair.second;  for(; *temp_pp != 0; ++temp_pp) {    delete[] *temp_pp;  }  delete[] parms_pair.second;}void FaxListDialog::refresh_slot(void) {  fax_list_manager.refresh();  set_buttons_slot();}EntryDialog::EntryDialog(const int standard_size, const Glib::ustring& entry_text,			 const Glib::ustring& label_text, Gtk::Window& window):                             Gtk::Window(Gtk::WINDOW_TOPLEVEL), in_exec_loop(false),			     ok_button(Gtk::Stock::OK), cancel_button(Gtk::Stock::CANCEL),			     button_box(Gtk::BUTTONBOX_END, standard_size/2),			     label(label_text), table(3, 1, false),                             parent(window) {  button_box.add(cancel_button);  button_box.add(ok_button);  table.attach(label, 0, 1, 0, 1, Gtk::FILL | Gtk::EXPAND,	 Gtk::FILL | Gtk::EXPAND, standard_size/2, standard_size/4);  table.attach(entry, 0, 1, 1, 2, Gtk::FILL | Gtk::EXPAND,	 Gtk::EXPAND, standard_size/2, standard_size/4);  table.attach(button_box, 0, 1, 2, 3, Gtk::FILL | Gtk::EXPAND,	 Gtk::SHRINK, standard_size/2, standard_size/4);  ok_button.signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &EntryDialog::selected), true));  cancel_button.signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &EntryDialog::selected), false));  ok_button.set_flags(Gtk::CAN_DEFAULT);  cancel_button.set_flags(Gtk::CAN_DEFAULT);  add(table);    entry.set_text(entry_text);  set_title(gettext("Fax description"));  set_transient_for(parent);  set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);  parent.set_sensitive(false);  set_modal(true);  entry.set_size_request(standard_size * 9, standard_size);  set_border_width(standard_size/2);  entry.grab_focus();  set_position(Gtk::WIN_POS_CENTER_ON_PARENT);  set_resizable(false);  set_icon(prog_config.window_icon_r);  show_all();  // we now need to deselect what is in the entry  entry.select_region(0,0);}void EntryDialog::exec(void) {  in_exec_loop = true;  Gtk::Main::run();}void EntryDialog::selected(bool accept) {  parent.set_sensitive(true); // do this before we emit accepted()  hide_all();  if (accept) accepted(entry.get_text());  if (in_exec_loop) Gtk::Main::quit();  // if we have not called exec(), then this dialog is self-owning and it is safe to call `delete this'  else delete this;}bool EntryDialog::on_delete_event(GdkEventAny*) {  selected(false);  return true; // returning true prevents destroy sig being emitted}bool EntryDialog::on_key_press_event(GdkEventKey* event_p) {  if (event_p->keyval == GDK_Escape) selected(false);  else if (event_p->keyval == GDK_Return && !cancel_button.has_focus()) selected(true);  else Gtk::Window::on_key_press_event(event_p);  return true; // processing ends here}DescriptionDialog::DescriptionDialog(const int standard_size,				     const Glib::ustring& text,				     Gtk::Window& window):                      EntryDialog(standard_size,				  text,				  gettext("Fax description?"),				  window) {}AddFolderDialog::AddFolderDialog(const int standard_size,				 Gtk::Window& window):                      EntryDialog(standard_size,				  "",				  gettext("Folder name?\n"					  "(Note this will be placed in the top\n"					  "level and can be drag-and-dropped\n"					  "into other folders)"),				  window) {}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -