Thursday 5 October 2023

Extra monitor won't sync under kernel 6.2 but OK on 5.19

I have a Dell XPS 17 9700 with dock driving 3 monitors:

  Monitor-1: 1366x768 (old viewsonic LCD)
  Monitor-2: 5120x1440 (big and wiiide)
  Monitor-3: 1920x1200 (laptop LCD)

Under kernel 5.19 all is well, but under kernel 6.2 (under Mint Vera or Victoria) the Monitor-1 viewsonic won't sync properly:


I think the whole image is there, but just squashed up with trailing junk.

I still have my 5.19 kernel available since before upgrade so I can still work, but I'm not sure where to look to find what to blame for this. Do I need to manually specify a modeline?

Ubuntu 22.04.03 booted from USB has the same problem:


Ubuntu 23.10 with kernel 6.5 below works just fine:



And so fixed on Linuxmint 21.2 with:
sudo apt install linux-oem-22.04d

https://ubuntuhandbook.org/index.php/2023/08/linux-kernel-6-5-released-how-to-install-it-in-ubuntu/


Monday 31 July 2023

More on attachable scopes

I previously called these braceless scopes, and ended up writing more in discussion with Jens that I did on my blog - but now I come to needed it, and further back in time than I expected I find this gem carbuncle below.

(By attachable-scope I mean a braced-scope that get's attached to the expansion of previous macro, perhaps as the body of a function definition, or a for loop, or even an else clause).

Hah! Your example there was the clue to propagating breaks.

Thanks to your tip on the gcc equivalence using BREAKOUT and BREAKIN I can contrive a bunch of macros that expand to this:

1
2
3
4
5
6
7
8
9
main() {
  int a;
  for (a=1; a<=2; a++) {
    printf("Main context a=%d\n", a);
 
    if (0) { break_line_6: break ; } else for (int o = 0; o >=0; ) if (o == 1) { printf("Detected break\n"); goto break_line_6; } else
      for (int i=0; !o && (o=1), i==0; o=-1, i=-1 ) { printf("Inner context\n"); break; }
  }
}

it does not require gcc-isms – sadly the C style is lacking but it functions as desired

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define GENSYM_CONCAT(name, salt) name ## salt
#define GENSYM2(name, salt) GENSYM_CONCAT(name, salt)
#define GENSYM(name) GENSYM2(name, __LINE__)
 
#define _BRACELESS_SCOPE(__label__, _declaration_) \
    if (0) { __label__: break ; } else for (int _o = 0; _o >=0; ) if (_o == 1) goto __label__; else \
      for (_declaration_; !_o && (_o=1); _o=-1) \
 
#define BRACELESS_SCOPE(_declaration_) _BRACELESS_SCOPE(GENSYM(break_line_) , _declaration_)
 
main() {
  int a;
  for (a=1; a<=2; a++) {
    printf("Main context a=%d\n", a);
 
    BRACELESS_SCOPE(char* message="hello") { printf("Inner context: %s\n", message); break; }
  }
}

The main deficiency is that a single macro cannot cannot ultimately expand to more than one of these constructs, nor can it be used twice on the same line, or the generated labels will conflict. __COUNTER__ where supported could be passed instead of __LINE__. I guess this is something you already addressed in P99 if I look again…

It's just what I needed as I convert a narrating block logger (that annotates progress through a block scope) from gcc-isms to clang-isms.


It originally expanded to a nested function forward definition, a setup block, a nested function invocation, a clean-up block, followed by a the first half of a nested function definition which sticks onto a following scope that becomes the body.


clang won't take nested functions (even without arguments) and clang's objective-C style blocks is no help as it can't access the variables in the calling scope as gcc does.


Knowing that I've passed this way before I look at this and this, before finally recovering the carbuncle above which is to be pressed into service.

Saturday 8 July 2023

Fixing Linuxmint Audio on HP Envy x360

 Install Linuxmint 21.1 with secure boot turned off and wifi turned off

On first boot turn on secure boot

Join wifi, get all updates

sudo apt install linux-oem-22.04c [https://wiki.ubuntu.com/Kernel/OEMKernel]

git clone https://github.com/xoocoon/hp-15-ew0xxx-snd-fix # see https://h30434.www3.hp.com/t5/Notebook-Audio/No-sound-from-internal-speakers-using-Linux/m-p/8678403/highlight/true#M121500

cat /sys/class/sound/hwC0D0/subsystem_id

0x103c8a28

edit setup_snd-hda-codec-realtek.sh to remove this line
+  SND_PCI_QUIRK(0x103c, 0x8a29, "HP Envy x360 15-ew0xxx", ALC287_FIXUP_CS35L41_I2C_2),
and add this line
+   SND_PCI_QUIRK(0x103c, 0x8a28, "HP ENVY x360 2-in-1 Laptop", ALC287_FIXUP_CS35L41_I2C_2),

bash setup_snd-hda-scodec-cs35l41.sh
bash setup_snd-hda-codec-realtek.sh


Thursday 25 May 2023

Run time detection: Does the terminal emulator support unicode?

You can test the terminal by setting the cursor position to column 1 and outputing a multibyte unicode character. If the cursor moves by more than 1 position then the terminal does not support unicode.

On in this case we emit a 3 byte sequence which is a zero width space, so if the cursor moves at all, the terminal cannot process unicode

IFS=$';\x1B[' read -p $'\r\xE2\x80\x8B\x1B[6n\r   \r' -d R -rst 1 _ _ _ X _ </dev/tty 2>/dev/tty && test "$X" = 1

Here we output \r to get to position 1 and then emit a 3 byte sequence which is a zero width space, and then emit ESC [ 6n which asks the cursor position, followed by \r \r to overwrite any junk that will have appeared if the terminal handled each byte as a separate character.

Then we read the cusor position with a 1 second timeout and check whether the X position is position 1 which it will be if the terminal can process unicode.

A better function is:

is-tty-unicode() {
  local X

  test -c /dev/tty &&
  if test -t 0
  then IFS=$';\x1B[' read -p $'\r\xE2\x80\x8B\x1B[6n\r   \r' -d R -rst 1 _ _ _ X _ 2>&1
  fi <>/dev/tty && test "$X" = 1
}