Recent

Author Topic: [CLOSED] Why works sysutils.beep() in GUI-programs and not in console-programs?  (Read 6696 times)

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
I hope I found the correct forum...

In a small GUI program, when I call sysutils.beep(), then the OS (Linux Ubuntu 18.04) shows a small dialog window to inform me about that sound (my computer has no loudspeaker):
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.    begin
  3.    sysutils.beep;
  4.    end;
This small dialog window appears only, when I call the GUI program from a terminal and not if I start it within Lazarus (which is no problem). But this small dialog window does not appear, when I call sysutils.beep() in a small console program (started from a terminal):
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses sysutils;
  4.  
  5. begin {main}
  6. sysutils.beep;
  7. end.

I want this small dialog window in a console program.

What I found out:
sysutils.beep() is defined in <installdir>/fpcsrc/rtl/objpas/sysutils/sysutils.inc as
Code: Pascal  [Select][+][-]
  1. procedure Beep;
  2. begin
  3.   If Assigned(OnBeep) then OnBeep;
  4. end;
  5.  
  6. // with:
  7. Var OnBeep : TBeephandler = Nil;
and in <installdir>/fpcsrc/rtl/unix/sysutils.pp I found that var 'OnBeep' is initialized with:
Code: Pascal  [Select][+][-]
  1. Procedure SysBeep;
  2. begin
  3.   Write(#7);
  4.   Flush(Output);
  5. end;

I replaced my calls for sysutils.beep() with "Write(#7); Flush(Output);" and got the same results as before.

In my GUI program I found out, that sysutils.beep() in TForm1.FormCreate() and earlier does not work, but it works in TForm1.FormActivate() and later. So what is "changed" between those 2 calls?

Can it be, that var 'Output' is "manipulated" in GUI programs?

Version: Lazarus 2.0.10 with FPC 3.2.0

What I want is to get this small dialog window from the OS, when I call sysutils.beep() in a console program. Thanks in advance.
« Last Edit: September 01, 2021, 06:34:55 pm by Hartmut »

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #1 on: September 01, 2021, 01:10:54 pm »
Hello.

There was a a topic about beep on Linux.

If you want a working Linux beep you may try alsa_sound:
There is a "alsa_beep" included.

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #2 on: September 01, 2021, 01:16:39 pm »
The dialogue window is implemented by the wrapper around your shell, e.g. classically this would be xterm but these days there's plenty of alternatives.

You can't rely on this behaviour, and I strongly recommend explicitly displaying a dialogue (or a small form that looks like a dialogue, which hides itself after a brief time).

You can't rely on a computer being able to sound a bell, even if requested directly by X-Windows. As you've discovered, the response to a #$07 is variable: you can usually rely on it resulting in a beep only if working to a non-GUI console (i.e. no GUI installed on the system, or you get to a non-GUI console using <Ctrl><Alt><F1> etc.)

Most computers these days have a soundcard, so you can usually use low-level ALSA calls to emit a wave sequence or sometimes MIDI. They don't, however, predictably have software installed that would allow that to be a simple TProcess call.

This was discussed in detail some months ago. I argued that it would be desirable to have SysUtils.Beep talking to ALSA, but the core developers stated flatly that that was out of the question.

https://forum.lazarus.freepascal.org/index.php/topic,49502.msg358923.html#msg358923 and others via the forum's Advanced Search.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #3 on: September 01, 2021, 03:28:32 pm »
Thank you Fred vS and MarkMLl for your posts and explanations.

I'm only interested in seeing that small dialog window (which comes from the wrapper around my shell, as MarkMLl wrote). I'm not interested in hearing any sound (because this computer has no sound). The purpose is, that my console program, if it detects a problem, shall be able to catch my attention, even if it's minimized or hidden by something another. The "solution" must run only on my computer and on Linux (Ubuntu 18.04).

I tried "alsa_beep" from Fred vS, but unfortunately it does not arise that small dialog window.

So I want to come back to a former question:
What ist done in the initialization of a GUI program between TForm1.FormCreate() and TForm1.FormActivate(), so that sysutils.beep() works as desired in TForm1.FormActivate() (and later), but not in TForm1.FormCreate() (and before)?

Can it be, that var 'Output' is "manipulated" in between?

If possible, I want to "copy" that, what is neccessary, that it works in a console program.

Thanks for any help.

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #4 on: September 01, 2021, 03:47:37 pm »
I tried "alsa_beep" from Fred vS, but unfortunately it does not arise that small dialog window.

Why not simply do:

Code: Pascal  [Select][+][-]
  1. If ALSAbeep1() = false then ShowMessage('No sound can be produced');

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #5 on: September 01, 2021, 04:11:46 pm »

So I want to come back to a former question:
What ist done in the initialization of a GUI program between TForm1.FormCreate() and TForm1.FormActivate(), so that sysutils.beep() works as desired in TForm1.FormActivate() (and later), but not in TForm1.FormCreate() (and before)?

Hello.

I think it is because fpc use XBell() from X11 library to do beep().

It could be that after form.create(), XBell is not yet assigned or initialized.

But after Form.ativate XBell is ready to be used.

My 0.00001 cent, of course.

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #6 on: September 01, 2021, 04:12:57 pm »
Hello Fred vS,

The purpose is, that my console program, if it detects a problem, shall be able to catch my attention, even if it's minimized or hidden by something another.

Linux shows the mentioned small dialog window above all other windows. That's why I want to "use" it.
How shall that work with ShowMessage()?
And does ShowMessage() work in a console program?

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #7 on: September 01, 2021, 04:23:20 pm »
Hello Fred vS,

The purpose is, that my console program, if it detects a problem, shall be able to catch my attention, even if it's minimized or hidden by something another.

Linux shows the mentioned small dialog window above all other windows. That's why I want to "use" it.
How shall that work with ShowMessage()?
And does ShowMessage() work in a console program?

Hum, tricky to do GUI message for a console program.
You may uses fpGUIlib (the library version of fpGUI) and uses that library to raise the error message.

There are also solution with LCL, you will need to use search in forum.

Why would you prefer a gui message for console application?

You can do nice error message with the console!

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #8 on: September 01, 2021, 04:44:00 pm »
I think it is because fpc use XBell() from X11 library to do beep().

That sounds very interesting.
I found XBell() in unit xlib. It's declared as
Code: Pascal  [Select][+][-]
  1. function XBell(para1:PDisplay; para2:cint):cint;cdecl;external libX11;

I have problems to give it the 1st parameter. 'PDisplay' is declared as:
Code: Pascal  [Select][+][-]
  1. type
  2.    PDisplay = ^TDisplay;
  3.    TDisplay = TXDisplay;
  4.  
  5.    PXDisplay = ^TXDisplay;
  6.    TXDisplay = record
  7.      end;
  8.  
So I see a pointer to an empty record...
Does anybody know how I must send the 1st parameter?

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #9 on: September 01, 2021, 04:45:41 pm »
Hum, tricky to do GUI message for a console program.
You may uses fpGUIlib (the library version of fpGUI) and uses that library to raise the error message.

There's various dialog(ue) etc. programs e.g. https://linux.die.net/man/1/xdialog

I'd suggest that this is related to the question of whether a program can display a graphical splash box and then decide that it's going to run entirely using stdin/stdout (i.e. no forms).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #10 on: September 01, 2021, 04:47:19 pm »
Does anybody know how I must send the 1st parameter?

Yes, see the thread I pointed you at earlier. Also see the specific warning that I gave you that it doesn't always work.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #11 on: September 01, 2021, 04:55:13 pm »
So I see a pointer to an empty record...
Does anybody know how I must send the 1st parameter?

https://forum.lazarus.freepascal.org/index.php/topic,49502.msg381914.html#msg381914
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #12 on: September 01, 2021, 05:08:46 pm »
Thank you Fred vS and MarkMLl for your new posts.

Code: Pascal  [Select][+][-]
  1. uses xlib;
  2.  
  3. var dpy: PDisplay;
  4.  
  5. begin
  6.  dpy := XOpenDisplay(nil);
  7.  XSynchronize(dpy, 1);
  8.  xbell(dpy,0);
  9.  xflush(dpy);
  10.  XCloseDisplay(dpy);
  11. end.
This compiles but unfortunately it does NOT arise that small dialog window :-((

Fred vS

  • Hero Member
  • *****
  • Posts: 3783
    • StrumPract is the musicians best friend
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #13 on: September 01, 2021, 05:13:36 pm »
This compiles but unfortunately it does NOT arise that small dialog window :-((

Could you give, as attachment, a screenshot of that mysterious small  dialog window?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Hartmut

  • Hero Member
  • *****
  • Posts: 1076
Re: Why works sysutils.beep() in GUI-programs and not in console-programs?
« Reply #14 on: September 01, 2021, 05:47:50 pm »
attached is a screenshot. This small dialog is displayed for about 5 seconds in the lower right corner of my main monitor.

 

TinyPortal © 2005-2018