Mercurial > hg > xemacs-beta
annotate src/sunplay.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | 6f2158fa75ed |
children |
rev | line source |
---|---|
428 | 1 /* play.c - play a sound file on the speaker |
2 ** | |
3 ** Copyright (C) 1989 by Jef Poskanzer. | |
4 ** | |
5 ** Modified 24-May-91 by Jamie Zawinski (for Lucid Emacs). | |
6 ** Modified 17-Dec-92 by Jamie Zawinski (largely rewritten for SunOS 4.1.3). | |
7 ** | |
8 ** Permission to use, copy, modify, and distribute this software and its | |
9 ** documentation for any purpose and without fee is hereby granted, provided | |
10 ** that the above copyright notice appear in all copies and that both that | |
11 ** copyright notice and this permission notice appear in supporting | |
12 ** documentation. This software is provided "as is" without express or | |
13 ** implied warranty. | |
14 */ | |
15 | |
16 /* Synched up with: Not in FSF. */ | |
17 | |
563 | 18 /* This file Mule-ized by Ben Wing, 5-15-01. */ |
428 | 19 |
563 | 20 #include <config.h> |
21 #include "lisp.h" | |
22 #include "sound.h" | |
428 | 23 |
563 | 24 #include "sysdep.h" |
25 #include "sysfile.h" | |
26 #include "syssignal.h" | |
428 | 27 |
28 #include <multimedia/libaudio.h> | |
29 #include <multimedia/audio_device.h> | |
30 | |
31 static SIGTYPE (*sighup_handler) (int sig); | |
32 static SIGTYPE (*sigint_handler) (int sig); | |
33 static SIGTYPE sighandler (int sig); | |
34 | |
35 static int audio_fd; | |
36 | |
37 #define audio_open() open ("/dev/audio", (O_WRONLY | O_NONBLOCK), 0) | |
38 | |
442 | 39 static int initialized_device_p; |
428 | 40 static int reset_volume_p, reset_device_p; |
41 static double old_volume; | |
42 static Audio_hdr dev_hdr; | |
43 | |
44 static int | |
2367 | 45 init_device (int volume, Binbyte *data, int fd, |
428 | 46 unsigned int *header_length) |
47 { | |
48 Audio_hdr file_hdr; | |
49 | |
50 reset_volume_p = 0; | |
51 reset_device_p = 0; | |
52 | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4759
diff
changeset
|
53 assert (!(data && fd)); /* one or the other */ |
428 | 54 |
55 if (AUDIO_SUCCESS != audio_get_play_config (audio_fd, &dev_hdr)) | |
56 { | |
563 | 57 sound_perror ("Not a valid audio device"); |
428 | 58 return 1; |
59 } | |
60 | |
61 if (AUDIO_SUCCESS != (data | |
62 ? audio_decode_filehdr (data, &file_hdr, header_length) | |
63 : audio_read_filehdr (fd, &file_hdr, 0, 0))) | |
64 { | |
65 if (data) | |
563 | 66 sound_perror ("invalid audio data"); |
428 | 67 else |
563 | 68 sound_perror ("invalid audio file"); |
428 | 69 return 1; |
70 } | |
71 | |
72 audio_flush_play (audio_fd); | |
73 | |
442 | 74 if (!initialized_device_p || (0 != audio_cmp_hdr (&dev_hdr, &file_hdr))) |
428 | 75 { |
76 Audio_hdr new_hdr; | |
77 new_hdr = file_hdr; | |
78 reset_device_p = 1; | |
442 | 79 initialized_device_p = 1; |
428 | 80 if (AUDIO_SUCCESS != audio_set_play_config (audio_fd, &new_hdr)) |
81 { | |
563 | 82 Extbyte buf1 [100], buf2 [100], buf3 [250]; |
428 | 83 audio_enc_to_str (&file_hdr, buf1); |
84 audio_enc_to_str (&new_hdr, buf2); | |
85 sprintf (buf3, "wanted %s, got %s", buf1, buf2); | |
563 | 86 sound_warn (buf3); |
428 | 87 return 1; |
88 } | |
89 } | |
90 | |
91 if (volume < 0 || volume > 100) | |
92 { | |
563 | 93 Extbyte buf [255]; |
428 | 94 sprintf (buf, "volume must be between 0 and 100 (not %d)", volume); |
563 | 95 sound_warn (buf); |
428 | 96 return 1; |
97 } | |
98 { | |
99 /* set the volume; scale it to 0.0 - 1.0 */ | |
100 double V = (volume / 100.0); | |
101 audio_get_play_gain (audio_fd, &old_volume); | |
102 reset_volume_p = 1; | |
103 audio_set_play_gain (audio_fd, &V); | |
104 } | |
105 | |
106 return 0; | |
107 } | |
108 | |
109 | |
110 static void | |
111 reset_device (int wait_p) | |
112 { | |
113 if (wait_p) | |
114 audio_drain (audio_fd, 1); | |
115 else | |
116 audio_flush_play (audio_fd); | |
117 if (reset_device_p) | |
118 audio_set_play_config (audio_fd, &dev_hdr); | |
119 if (reset_volume_p) | |
120 audio_set_play_gain (audio_fd, &old_volume); | |
121 } | |
122 | |
123 | |
124 void | |
563 | 125 play_sound_file (Extbyte *sound_file, int volume) |
428 | 126 { |
127 int rrtn, wrtn; | |
2367 | 128 Binbyte buf [255]; |
428 | 129 int file_fd; |
130 | |
131 audio_fd = audio_open (); | |
132 | |
133 if (audio_fd < 0) | |
134 { | |
563 | 135 sound_perror ("open /dev/audio"); |
428 | 136 return; |
137 } | |
138 | |
139 /* where to find the proto for signal()... */ | |
613 | 140 sighup_handler = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGHUP, sighandler); |
141 sigint_handler = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGINT, sighandler); | |
428 | 142 |
143 file_fd = open (sound_file, O_RDONLY, 0); | |
144 if (file_fd < 0) | |
145 { | |
563 | 146 sound_perror (sound_file); |
428 | 147 goto END_OF_PLAY; |
148 } | |
149 | |
2367 | 150 if (init_device (volume, (Binbyte *) 0, file_fd, (unsigned int *) 0)) |
428 | 151 goto END_OF_PLAY; |
152 | |
153 while (1) | |
154 { | |
2367 | 155 rrtn = read (file_fd, (CBinbyte *) buf, sizeof (buf)); |
428 | 156 if (rrtn < 0) |
157 { | |
563 | 158 sound_perror ("read"); |
428 | 159 goto END_OF_PLAY; |
160 } | |
161 if (rrtn == 0) | |
162 break; | |
163 | |
164 while (1) | |
165 { | |
2367 | 166 wrtn = write (audio_fd, (CBinbyte *) buf, rrtn); |
428 | 167 if (wrtn < 0) |
168 { | |
563 | 169 sound_perror ("write"); |
428 | 170 goto END_OF_PLAY; |
171 } | |
172 if (wrtn != 0) | |
173 break; | |
174 | |
175 if (AUDIO_ERR_INTERRUPTED == audio_drain (audio_fd, 1)) | |
176 goto END_OF_PLAY; | |
177 } | |
178 if (wrtn != rrtn) | |
179 { | |
563 | 180 Extbyte warn_buf [255]; |
428 | 181 sprintf (warn_buf, "play: rrtn = %d, wrtn = %d", rrtn, wrtn); |
563 | 182 sound_warn (warn_buf); |
428 | 183 goto END_OF_PLAY; |
184 } | |
185 } | |
186 | |
187 END_OF_PLAY: | |
188 | |
189 if (file_fd > 0) | |
190 close (file_fd); | |
191 | |
192 if (audio_fd > 0) | |
193 { | |
194 reset_device (1); | |
195 close (audio_fd); | |
196 } | |
197 | |
613 | 198 EMACS_SIGNAL (SIGHUP, sighup_handler); |
199 EMACS_SIGNAL (SIGINT, sigint_handler); | |
428 | 200 } |
201 | |
202 | |
442 | 203 int |
2367 | 204 play_sound_data (Binbyte *data, int length, int volume) |
428 | 205 { |
206 int wrtn, start = 0; | |
207 unsigned int ilen; | |
442 | 208 int result = 0; |
428 | 209 |
210 audio_fd = -1; | |
211 | |
442 | 212 if (length == 0) return 0; |
428 | 213 |
214 /* this is just to get a better error message */ | |
2367 | 215 if (strncmp (".snd\0", (CBinbyte *) data, 4)) |
428 | 216 { |
563 | 217 sound_warn ("Not valid audio data (bad magic number)"); |
428 | 218 goto END_OF_PLAY; |
219 } | |
220 if (length <= sizeof (Audio_hdr)) | |
221 { | |
563 | 222 sound_warn ("Not valid audio data (too short)"); |
428 | 223 goto END_OF_PLAY; |
224 } | |
225 | |
226 audio_fd = audio_open (); | |
227 if (audio_fd < 0) | |
442 | 228 return 0; |
428 | 229 |
230 /* where to find the proto for signal()... */ | |
613 | 231 sighup_handler = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGHUP, sighandler); |
232 sigint_handler = (SIGTYPE (*) (int)) EMACS_SIGNAL (SIGINT, sighandler); | |
428 | 233 |
234 if (init_device (volume, data, 0, &ilen)) | |
235 goto END_OF_PLAY; | |
236 | |
237 data += (ilen<<2); | |
238 length -= (ilen<<2); | |
239 if (length <= 1) | |
240 goto END_OF_PLAY; | |
241 | |
242 while (1) | |
243 { | |
2367 | 244 wrtn = write (audio_fd, (CBinbyte *) (data+start), length-start); |
428 | 245 if (wrtn < 0) |
246 { | |
563 | 247 sound_perror ("write"); |
428 | 248 goto END_OF_PLAY; |
249 } | |
250 if (wrtn != 0) | |
251 { | |
252 start += wrtn; | |
253 break; | |
254 } | |
255 if (AUDIO_ERR_INTERRUPTED == audio_drain (audio_fd, 1)) | |
256 goto END_OF_PLAY; | |
257 } | |
258 if (wrtn != length) | |
259 { | |
563 | 260 Extbyte buf [255]; |
428 | 261 sprintf (buf, "play: rrtn = %d, wrtn = %d", length, wrtn); |
563 | 262 sound_warn (buf); |
428 | 263 goto END_OF_PLAY; |
264 } | |
265 | |
442 | 266 result = 1; |
267 | |
428 | 268 END_OF_PLAY: |
269 | |
270 if (audio_fd > 0) | |
271 { | |
272 reset_device (1); | |
273 close (audio_fd); | |
274 } | |
275 | |
613 | 276 EMACS_SIGNAL (SIGHUP, sighup_handler); |
277 EMACS_SIGNAL (SIGINT, sigint_handler); | |
442 | 278 |
279 return result; | |
428 | 280 } |
281 | |
282 /* #### sigcontext doesn't exist in Solaris. This should be updated | |
283 to be correct for Solaris. */ | |
442 | 284 static SIGTYPE |
428 | 285 sighandler (int sig) |
286 { | |
287 if (audio_fd > 0) | |
288 { | |
289 reset_device (0); | |
290 close (audio_fd); | |
291 } | |
292 if (sig == SIGHUP && sighup_handler) | |
293 sighup_handler (sig); | |
294 else if (sig == SIGINT && sigint_handler) | |
295 sigint_handler (sig); | |
296 else | |
297 exit (1); | |
298 } |