TRAP LOCAL
CATCH GOTO beep_print_message
SYSTEM "xset b on 2>/dev/null"
IMPORT "ioctl" FROM "libc.so" TYPE int
DEF FN beep_KIOCSOUND = DEC("4B2F")
DEF FN beep_KDMKTONE = DEC("4B30")
CONST beep_DEVICE = 1
CONST beep_X86_oscillator = 1193180
GLOBAL beep_NoUseX = 0
CATCH GOTO beep_No_X_Environment
IMPORT "XOpenDisplay" FROM "libX11.so.6" TYPE long
IMPORT "XGetKeyboardControl" FROM "libX11.so.6" TYPE void
IMPORT "XChangeKeyboardControl" FROM "libX11.so.6" TYPE void
IMPORT "XCloseDisplay" FROM "libX11.so.6" TYPE void
IMPORT "XBell" FROM "libX11.so.6" TYPE void
IMPORT "XFlush" FROM "libX11.so.6" TYPE void
CONST beep_KBBellPitch = 1 << 2
CONST beep_KBBellDuration = 1 << 3
RECORD beep_XKeyboardState
LOCAL key_click_percent TYPE int
LOCAL bell_percent TYPE int
LOCAL bell_pitch, bell_duration TYPE unsigned int
LOCAL led_mask TYPE unsigned long
LOCAL global_auto_repeat TYPE int
LOCAL auto_repeats[32] TYPE char
END RECORD
RECORD beep_XKeyboardControl
LOCAL key_click_percent TYPE int
LOCAL bell_percent TYPE int
LOCAL bell_pitch TYPE int
LOCAL bell_duration TYPE int
LOCAL led TYPE int
LOCAL led_mode TYPE int
LOCAL key TYPE int
LOCAL auto_repeat_mode TYPE int
END RECORD
SUB BEEP(NUMBER freq, NUMBER duration)
LOCAL result, display
IF freq > 0 THEN
result = ioctl(beep_DEVICE, beep_KIOCSOUND, beep_X86_oscillator / freq)
IF result < 0 THEN
IF ISFALSE(beep_NoUseX) THEN
display = XOpenDisplay(0)
XGetKeyboardControl(display, ADDRESS(beep_XKeyboardState))
beep_XKeyboardControl.key_click_percent = 0
beep_XKeyboardControl.bell_percent = 0
beep_XKeyboardControl.bell_pitch = freq
beep_XKeyboardControl.bell_duration = duration
beep_XKeyboardControl.led = 0
beep_XKeyboardControl.led_mode = 0
beep_XKeyboardControl.key = 0
beep_XKeyboardControl.auto_repeat_mode = 0
XChangeKeyboardControl(display, beep_KBBellDuration | beep_KBBellPitch, ADDRESS(beep_XKeyboardControl))
XBell(display, 100)
XFlush(display)
SLEEP duration
XChangeKeyboardControl(display, beep_KBBellDuration | beep_KBBellPitch, ADDRESS(beep_XKeyboardState))
XCloseDisplay(display)
ELSE
PRINT "Cannot use PC speaker on this machine!"
END IF
ELSE
SLEEP duration*2
ioctl(beep_DEVICE, beep_KIOCSOUND, 0)
END IF
END IF
END SUB
SUB SHUT
LOCAL result, display
result = ioctl(beep_DEVICE, beep_KIOCSOUND, 0)
IF result < 0 THEN
IF ISFALSE(beep_NoUseX) THEN
display = XOpenDisplay(0)
XFlush(display)
XCloseDisplay(display)
ELSE
PRINT "Cannot use PC speaker on this machine!"
END IF
END IF
END SUB
GOTO beep_END
LABEL beep_print_message
PRINT "IOCTL is not available on this platform! Check if 'libc.so' exists."
END
LABEL beep_No_X_Environment
beep_NoUseX = 1
PRINT "No X"
RESUME
LABEL beep_END
TRAP SYSTEM
CATCH RESET