void qt_pipe_link_rep::listen (int msecs) { if (!alive) return; time_t wait_until= texmacs_time () + msecs; while ((PipeLink.getOutbuf() == "") && (PipeLink.getErrbuf() == "")) { PipeLink.listenChannel (QProcess::StandardOutput, 0); PipeLink.listenChannel (QProcess::StandardError, 0); if (texmacs_time () - wait_until > 0) break; } }
void edit_interface_rep::handle_repaint (SI x1, SI y1, SI x2, SI y2) { if (is_nil (eb)) apply_changes (); if (env_change != 0) { system_warning ("Invalid situation (" * as_string (env_change) * ")", "(edit_interface_rep::handle_repaint)"); return; } /* // In the past, we used the code below in order to hide the trace of // a moving cursor. This code is now incorrect, because the rectangle // (x1, y1)--(x2, y2) does not correspond to the repaint region clipping. // Nevertheless, the code seems no longer necessary. In case it would be, // it should be moved somewhere inside the internal repaint routines. SI extra= 3 * get_init_int (FONT_BASE_SIZE) * PIXEL / (2*sfactor); SI X1= (x1-extra) * sfactor, Y1= (y1-extra) * sfactor; SI X2= (x2+extra) * sfactor, Y2= (y2+extra) * sfactor; draw_with_stored (rectangle (X1, Y1, X2, Y2)); */ // cout << "Repainting\n"; draw_with_stored (rectangle (x1, y1, x2, y2) * sfactor); if (last_change-last_update > 0) last_change = texmacs_time (); // cout << "Repainted\n"; }
void pipe_link_rep::listen (int msecs) { if (!alive) return; time_t wait_until= texmacs_time () + msecs; while ((outbuf == "") && (errbuf == "")) { fd_set rfds; FD_ZERO (&rfds); FD_SET (out, &rfds); FD_SET (err, &rfds); struct timeval tv; tv.tv_sec = msecs / 1000; tv.tv_usec = 1000 * (msecs % 1000); int nr= select (max (out, err) + 1, &rfds, NULL, NULL, &tv); if (nr != 0 && FD_ISSET (out, &rfds)) feed (LINK_OUT); if (nr != 0 && FD_ISSET (err, &rfds)) feed (LINK_ERR); if (texmacs_time () - wait_until > 0) break; } }
void picture_cache_clean () { static time_t last_gc= 0; if (texmacs_time () - last_gc <= 60000) return; last_gc= texmacs_time (); iterator<tree> it= iterate (picture_blacklist); while (it->busy ()) { tree key= it->next (); if (picture_count [key] <= 0) { picture_count -> reset (key); picture_cache -> reset (key); picture_stamp -> reset (key); //cout << "Removed " << key << "\n"; } } picture_blacklist= hashmap<tree,int> (); }
string tm_link_rep::read_packet (int channel, int timeout, bool& success) { success= false; string& r= watch (channel); time_t start= texmacs_time (); while (!message_complete (r)) { int n= N(r); if (timeout > 0) listen (timeout); if (N(r) == n && (texmacs_time () - start >= timeout)) return ""; } if (channel == LINK_OUT && N(r) > 0 && r[0] == '!') { secure_server (message_receive (r)); return ""; } else { string back= message_receive (r); if (secret != "") back= secret_decode (back, secret); success= true; return back; } }
void windows_refresh (string kind) { if (kind == "auto" && texmacs_time () < refresh_time) return; iterator<int> it= iterate (window_table); while (it->busy ()) { int id= it->next (); send_refresh (window_table[id], kind); #ifdef X11TEXMACS if (kind == "auto") refresh_size (window_table[id], false); #endif } if (kind == "auto") windows_delayed_refresh (1000000000); }
void x_window_rep::delayed_message (widget wid, string s, time_t delay) { time_t ct= texmacs_time (); the_gui->messages= insert_message (the_gui->messages, wid, s, ct, ct+ delay); }
void windows_delayed_refresh (int ms) { refresh_time= texmacs_time () + ms; }
int unix_system (array<string> arg, array<int> fd_in, array<string> str_in, array<int> fd_out, array<string*> str_out) { // Run command arg[0] with arguments arg[i], i >= 1. // str_in[i] is sent to the file descriptor fd_in[i]. // str_out[i] is filled from the file descriptor fd_out[i]. // If str_in[i] is -1 then $$i automatically replaced by a valid // file descriptor in arg. if (N(arg) == 0) return 0; string which= recompose (arg, " "); int n_in= N(fd_in), n_out= N(fd_out); ASSERT(N(str_in) == n_in, "size mismatch"); ASSERT(N(str_out) == n_out, "size mismatch"); array<_pipe_t> pp_in (n_in), pp_out (n_out); _file_actions_t file_actions; for (int i= 0; i < n_in; i++) { if (posix_spawn_file_actions_addclose (&file_actions.rep, pp_in[i].out ()) != 0) return -1; if (fd_in[i] >= 0) { if (posix_spawn_file_actions_adddup2 (&file_actions.rep, pp_in[i].in (), fd_in[i]) != 0) return -1; if (posix_spawn_file_actions_addclose (&file_actions.rep, pp_in[i].in ()) != 0) return -1; } } for (int i= 0; i < n_out; i++) { if (posix_spawn_file_actions_addclose (&file_actions.rep, pp_out[i].in ()) != 0) return -1; if (posix_spawn_file_actions_adddup2 (&file_actions.rep, pp_out[i].out (), fd_out[i]) != 0) return -1; if (posix_spawn_file_actions_addclose (&file_actions.rep, pp_out[i].out ()) != 0) return -1; } array<string> arg_= arg; for (int j= 0; j < N(arg); j++) for (int i= 0; i < n_in; i++) if (fd_in[i] < 0) arg_[j]= replace (arg_[j], "$$" * as_string (i), as_string (pp_in[i].in ())); if (DEBUG_IO) debug_io << "unix_system, launching: " << arg_ << "\n"; array<char*> _arg; for (int j= 0; j < N(arg_); j++) _arg << as_charp (arg_[j]); _arg << (char*) NULL; pid_t pid; int status= posix_spawnp (&pid, _arg[0], &file_actions.rep, NULL, A(_arg), environ); for (int j= 0; j < N(arg_); j++) tm_delete_array (_arg[j]); if (status != 0) { if (DEBUG_IO) debug_io << "unix_system, failed" << "\n"; return -1; } if (DEBUG_IO) debug_io << "unix_system, succeeded to create pid " << pid << "\n"; // close useless ports for (int i= 0; i < n_in ; i++) close (pp_in[i].in ()); for (int i= 0; i < n_out; i++) close (pp_out[i].out ()); // write to spawn process array<_channel> channels_in (n_in); array<pthread_t> threads_write (n_in); for (int i= 0; i < n_in; i++) { channels_in[i]._init_in (pp_in[i].out (), str_in[i], 1 << 12); if (pthread_create (&threads_write[i], NULL /* &attr */, _background_write_task, (void *) &(channels_in[i]))) return -1; } // read from spawn process array<_channel> channels_out (n_out); array<pthread_t> threads_read (n_out); for (int i= 0; i < n_out; i++) { channels_out[i]._init_out (pp_out[i].in (), 1 << 12); if (pthread_create (&threads_read[i], NULL /* &attr */, _background_read_task, (void *) &(channels_out[i]))) return -1; } int wret; time_t last_wait_time= texmacs_time (); while ((wret= waitpid (pid, &status, WNOHANG)) == 0) { usleep (100); if (texmacs_time () - last_wait_time > 5000) { last_wait_time= texmacs_time (); _unix_system_warn (pid, which, "waiting spawn process"); } } if (DEBUG_IO) debug_io << "unix_system, pid " << pid << " terminated" << "\n"; // wait for terminating threads void* exit_status; int thread_status= 0; for (int i= 0; i < n_in; i++) { pthread_join (threads_write[i], &exit_status); if (channels_in[i].status < 0) thread_status= -1; } for (int i= 0; i < n_out; i++) { pthread_join (threads_read[i], &exit_status); *(str_out[i])= string (channels_out[i].data.data (), channels_out[i].data.length ()); if (channels_out[i].status < 0) thread_status= -1; } if (thread_status < 0) return thread_status; if (wret < 0 || WIFEXITED(status) == 0) return -1; return WEXITSTATUS(status); }