static int do_play_sound (const char *psz_file, unsigned long ui_volume) { int i_result = 0; MCIERROR mci_error = 0; char sz_cmd_buf_a[520]; char sz_ret_buf_a[520]; MMRESULT mm_result = MMSYSERR_NOERROR; unsigned long ui_volume_org = 0; BOOL b_reset_volume = FALSE; char warn_text[560]; /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we need to encode the file in the ANSI codepage on Windows 9X even if w32_unicode_filenames is non-zero. */ if (w32_major_version <= 4 || !w32_unicode_filenames) { char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use; filename_to_ansi (psz_file, fname_a); fname_to_use = fname_a; /* If the file name is not encodable in ANSI, try its short 8+3 alias. This will only work if w32_unicode_filenames is non-zero. */ if (_mbspbrk ((const unsigned char *)fname_a, (const unsigned char *)"?")) { if (w32_get_short_filename (psz_file, shortname, MAX_PATH)) fname_to_use = shortname; else mci_error = MCIERR_FILE_NOT_FOUND; } if (!mci_error) { memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); sprintf (sz_cmd_buf_a, "open \"%s\" alias GNUEmacs_PlaySound_Device wait", fname_to_use); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); } } else { wchar_t sz_cmd_buf_w[520]; wchar_t sz_ret_buf_w[520]; wchar_t fname_w[MAX_PATH]; filename_to_utf16 (psz_file, fname_w); memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w)); memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w)); /* _swprintf is not available on Windows 9X, so we construct the UTF-16 command string by hand. */ wcscpy (sz_cmd_buf_w, L"open \""); wcscat (sz_cmd_buf_w, fname_w); wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringW (sz_cmd_buf_w, sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL); } if (mci_error != 0) { strcpy (warn_text, "mciSendString: 'open' command failed to open sound file "); strcat (warn_text, psz_file); SOUND_WARNING (mciGetErrorString, mci_error, warn_text); i_result = (int) mci_error; return i_result; } if ((ui_volume > 0) && (ui_volume != UINT_MAX)) { mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org); if (mm_result == MMSYSERR_NOERROR) { b_reset_volume = TRUE; mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume); if (mm_result != MMSYSERR_NOERROR) { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutSetVolume: failed to set the volume level" " of the WAVE_MAPPER device.\n" "As a result, the user selected volume level will" " not be used."); } } else { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutGetVolume: failed to obtain the original" " volume level of the WAVE_MAPPER device.\n" "As a result, the user selected volume level will" " not be used."); } } memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); if (mci_error != 0) { strcpy (warn_text, "mciSendString: 'play' command failed to play sound file "); strcat (warn_text, psz_file); SOUND_WARNING (mciGetErrorString, mci_error, warn_text); i_result = (int) mci_error; } memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); if (b_reset_volume == TRUE) { mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org); if (mm_result != MMSYSERR_NOERROR) { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutSetVolume: failed to reset the original" " volume level of the WAVE_MAPPER device."); } } return i_result; }
int xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timespec *timeout, sigset_t *sigmask) { fd_set all_rfds, all_wfds; struct timespec tmo; struct timespec *tmop = timeout; GMainContext *context; bool have_wfds = wfds != NULL; GPollFD gfds_buf[128]; GPollFD *gfds = gfds_buf; int gfds_size = ARRAYELTS (gfds_buf); int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; bool context_acquired = false; int i, nfds, tmo_in_millisec, must_free = 0; bool need_to_dispatch; context = g_main_context_default (); context_acquired = g_main_context_acquire (context); /* FIXME: If we couldn't acquire the context, we just silently proceed because this function handles more than just glib file descriptors. Note that, as implemented, this failure is completely silent: there is no feedback to the caller. */ if (rfds) all_rfds = *rfds; else FD_ZERO (&all_rfds); if (wfds) all_wfds = *wfds; else FD_ZERO (&all_wfds); n_gfds = (context_acquired ? g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, gfds, gfds_size) : -1); if (gfds_size < n_gfds) { /* Avoid using SAFE_NALLOCA, as that implicitly refers to the current thread. Using xnmalloc avoids thread-switching problems here. */ gfds = xnmalloc (n_gfds, sizeof *gfds); must_free = 1; gfds_size = n_gfds; n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, gfds, gfds_size); } for (i = 0; i < n_gfds; ++i) { if (gfds[i].events & G_IO_IN) { FD_SET (gfds[i].fd, &all_rfds); if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; } if (gfds[i].events & G_IO_OUT) { FD_SET (gfds[i].fd, &all_wfds); if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; have_wfds = true; } } if (must_free) xfree (gfds); if (n_gfds >= 0 && tmo_in_millisec >= 0) { tmo = make_timespec (tmo_in_millisec / 1000, 1000 * 1000 * (tmo_in_millisec % 1000)); if (!timeout || timespec_cmp (tmo, *timeout) < 0) tmop = &tmo; } fds_lim = max_fds + 1; nfds = thread_select (pselect, fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop, sigmask); if (nfds < 0) retval = nfds; else if (nfds > 0) { for (i = 0; i < fds_lim; ++i) { if (FD_ISSET (i, &all_rfds)) { if (rfds && FD_ISSET (i, rfds)) ++retval; else ++our_fds; } else if (rfds) FD_CLR (i, rfds); if (have_wfds && FD_ISSET (i, &all_wfds)) { if (wfds && FD_ISSET (i, wfds)) ++retval; else ++our_fds; } else if (wfds) FD_CLR (i, wfds); if (efds && FD_ISSET (i, efds)) ++retval; } } /* If Gtk+ is in use eventually gtk_main_iteration will be called, unless retval is zero. */ #ifdef USE_GTK need_to_dispatch = retval == 0; #else need_to_dispatch = true; #endif if (need_to_dispatch && context_acquired) { int pselect_errno = errno; /* Prevent g_main_dispatch recursion, that would occur without block_input wrapper, because event handlers call unblock_input. Event loop recursion was causing Bug#15801. */ block_input (); while (g_main_context_pending (context)) g_main_context_dispatch (context); unblock_input (); errno = pselect_errno; } if (context_acquired) g_main_context_release (context); /* To not have to recalculate timeout, return like this. */ if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0)) { retval = -1; errno = EINTR; } return retval; }
static enum profiler_cpu_running setup_cpu_timer (Lisp_Object sampling_interval) { struct sigaction action; struct itimerval timer; struct timespec interval; int billion = 1000000000; if (! RANGED_INTEGERP (1, sampling_interval, (TYPE_MAXIMUM (time_t) < EMACS_INT_MAX / billion ? ((EMACS_INT) TYPE_MAXIMUM (time_t) * billion + (billion - 1)) : EMACS_INT_MAX))) return NOT_RUNNING; current_sampling_interval = XINT (sampling_interval); interval = make_timespec (current_sampling_interval / billion, current_sampling_interval % billion); emacs_sigaction_init (&action, deliver_profiler_signal); sigaction (SIGPROF, &action, 0); #ifdef HAVE_ITIMERSPEC if (! profiler_timer_ok) { /* System clocks to try, in decreasing order of desirability. */ static clockid_t const system_clock[] = { #ifdef CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID, #endif #ifdef CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID, #endif #ifdef CLOCK_MONOTONIC CLOCK_MONOTONIC, #endif CLOCK_REALTIME }; int i; struct sigevent sigev; sigev.sigev_value.sival_ptr = &profiler_timer; sigev.sigev_signo = SIGPROF; sigev.sigev_notify = SIGEV_SIGNAL; for (i = 0; i < ARRAYELTS (system_clock); i++) if (timer_create (system_clock[i], &sigev, &profiler_timer) == 0) { profiler_timer_ok = 1; break; } } if (profiler_timer_ok) { struct itimerspec ispec; ispec.it_value = ispec.it_interval = interval; if (timer_settime (profiler_timer, 0, &ispec, 0) == 0) return TIMER_SETTIME_RUNNING; } #endif #ifdef HAVE_SETITIMER timer.it_value = timer.it_interval = make_timeval (interval); if (setitimer (ITIMER_PROF, &timer, 0) == 0) return SETITIMER_RUNNING; #endif return NOT_RUNNING; }
int xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timespec const *timeout, sigset_t const *sigmask) { fd_set all_rfds, all_wfds; struct timespec tmo; struct timespec const *tmop = timeout; GMainContext *context; int have_wfds = wfds != NULL; GPollFD gfds_buf[128]; GPollFD *gfds = gfds_buf; int gfds_size = ARRAYELTS (gfds_buf); int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; int i, nfds, tmo_in_millisec; bool need_to_dispatch; USE_SAFE_ALLOCA; context = g_main_context_default (); if (rfds) all_rfds = *rfds; else FD_ZERO (&all_rfds); if (wfds) all_wfds = *wfds; else FD_ZERO (&all_wfds); n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, gfds, gfds_size); if (gfds_size < n_gfds) { SAFE_NALLOCA (gfds, sizeof *gfds, n_gfds); gfds_size = n_gfds; n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, gfds, gfds_size); } for (i = 0; i < n_gfds; ++i) { if (gfds[i].events & G_IO_IN) { FD_SET (gfds[i].fd, &all_rfds); if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; } if (gfds[i].events & G_IO_OUT) { FD_SET (gfds[i].fd, &all_wfds); if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; have_wfds = 1; } } SAFE_FREE (); if (tmo_in_millisec >= 0) { tmo = make_timespec (tmo_in_millisec / 1000, 1000 * 1000 * (tmo_in_millisec % 1000)); if (!timeout || timespec_cmp (tmo, *timeout) < 0) tmop = &tmo; } fds_lim = max_fds + 1; nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop, sigmask); if (nfds < 0) retval = nfds; else if (nfds > 0) { for (i = 0; i < fds_lim; ++i) { if (FD_ISSET (i, &all_rfds)) { if (rfds && FD_ISSET (i, rfds)) ++retval; else ++our_fds; } else if (rfds) FD_CLR (i, rfds); if (have_wfds && FD_ISSET (i, &all_wfds)) { if (wfds && FD_ISSET (i, wfds)) ++retval; else ++our_fds; } else if (wfds) FD_CLR (i, wfds); if (efds && FD_ISSET (i, efds)) ++retval; } } /* If Gtk+ is in use eventually gtk_main_iteration will be called, unless retval is zero. */ #ifdef USE_GTK need_to_dispatch = retval == 0; #else need_to_dispatch = true; #endif if (need_to_dispatch) { int pselect_errno = errno; /* Prevent g_main_dispatch recursion, that would occur without block_input wrapper, because event handlers call unblock_input. Event loop recursion was causing Bug#15801. */ block_input (); while (g_main_context_pending (context)) g_main_context_dispatch (context); unblock_input (); errno = pselect_errno; } /* To not have to recalculate timeout, return like this. */ if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0)) { retval = -1; errno = EINTR; } return retval; }