コード例 #1
0
ファイル: sound.c プロジェクト: GiantGeorgeGo/emacs
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;
}
コード例 #2
0
ファイル: xgselect.c プロジェクト: JJJollyjim/remacs
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;
}
コード例 #3
0
ファイル: profiler.c プロジェクト: aspiers/emacs-git
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;
}
コード例 #4
0
ファイル: xgselect.c プロジェクト: 0230/deepin-emacs
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;
}