frno7 / linux

Linux 2.2, 2.6, 3.x, 4.x and 5.x kernels for the PlayStation 2.
Other
84 stars 5 forks source link

Enable cursor for the frame buffer console #79

Open frno7 opened 2 years ago

frno7 commented 2 years ago

Do

For details, see https://github.com/frno7/linux/issues/10#issuecomment-1122798803.

frno7 commented 2 years ago

We’ve now got a XOR cursor in the console. @rickgaiser, setting up the ALPHA register was simple:

        GIF_PACKAGE_AD(package) {
                .addr = gs_addr_alpha_1,
                .data.alpha_1 = {
                        .a = gs_alpha_a_cs,
                        .b = gs_alpha_b_cd,
                        .c = gs_alpha_c_fix,
                        .d = gs_alpha_d_0,
                        .fix = GS_ALPHA_ONE
                }
        };

Then it was only a matter of sending four GS packages for a sprite with the abe field set to gs_blendning_on:

        GIF_PACKAGE_TAG(package) {
                .flg = gif_reglist_mode,
                .reg0 = gif_reg_prim,
                .reg1 = gif_reg_rgbaq,
                .reg2 = gif_reg_xyz2,
                .reg3 = gif_reg_xyz2,
                .nreg = 4,
                .nloop = 1,
                .eop = 1
        };
        GIF_PACKAGE_REG(package) {
                .lo.prim = {
                        .abe = gs_blendning_on,
                        .prim = gs_sprite
                },
                .hi.rgbaq = c->fg_rgbaq
        };
        GIF_PACKAGE_REG(package) {
                .lo.xyz2 = {
                        .x = gs_fbcs_to_pcs(c->sx),
                        .y = gs_fbcs_to_pcs(c->sy + c->th - c->dy)
                },
                .hi.xyz2 = {
                        .x = gs_fbcs_to_pcs(c->sx + c->tw),
                        .y = gs_fbcs_to_pcs(c->sy + c->th)
                }
        };

The cursor shape FB_TILE_CURSOR_UNDERLINE seems hardwired by the kernel, but all shapes are available in ps2fb.c:

    const u32 ch =
        cursor->shape == FB_TILE_CURSOR_NONE        ? 0 :
        cursor->shape == FB_TILE_CURSOR_UNDERLINE   ? 1 :
        cursor->shape == FB_TILE_CURSOR_LOWER_THIRD ? th / 3 :
        cursor->shape == FB_TILE_CURSOR_LOWER_HALF  ? th / 2 :
        cursor->shape == FB_TILE_CURSOR_TWO_THIRDS  ? (2 * th) / 3 :
        cursor->shape == FB_TILE_CURSOR_BLOCK       ? th : th;

Also, the cursor isn’t blinking but it remains unclear by which logic it would. Anyhow, a reasonable cursor is displayed now. :-)

frno7 commented 2 years ago

@rickgaiser, in addition, I think the alpha blending function, with similarities to a blitter, will be highly useful for a fully GS-accelerated X window system, eventually. :-)

Arch91 commented 2 years ago

@rickgaiser, thank you very much for that! @frno7, way to go! @frno7, how about also to fit the GNU linux cursor tune standard? As I previously noted in the issue #10, there (in GNU standardized linux) is possible to change the background color of the cursor, the speed of it's flashing and the times after those flashing stops - on the way, by directing the value into some parameter which is/are mounted in /sys/ folder. As an example what I mean, for the first one, the cursor color, it can be changed using this command: echo N > /sys/module/vt/parameters/cur_default where N is the integer value from 0 to 15. And each this value corresponds to the appropriate color. Those colors should be the same as in GNU standard. And same parameter tunes availability for the speed of flashing/blinking and for the 'times after those flashings/blinkings stops'.

frno7 commented 2 years ago

@Arch91, I figured out how to manipulate the shape of the cursor. Amusingly, it works already: try echo -e "\e[?6c", with 6 meaning a CUR_BLOCK shape as per

https://github.com/frno7/linux/blob/59a11ab94a4020408c7dfbf92bd55778e17b43f1/include/linux/console_struct.h#L161-L167

frno7 commented 2 years ago

Haha, try echo -e '\033[?17;0;64c' for a big red block of a cursor! :-) See some details in Documentation/admin-guide/vga-softcursor.rst.

frno7 commented 2 years ago

@Arch91, a cursor blinking like a Christmas tree could be a real crowd-pleaser. We should make a test suite to cover the combinations of settings. It seems most if not all settings can be applied using the echo command with various escape sequences.

Arch91 commented 2 years ago

We should make a test suite to cover the combinations of settings. It seems most if not all settings can be applied using the echo command with various escape sequences.

Yes, and there should be a tutotial which describes the all available values for the all parameters, with an examples (4 high bits - background, 4 low bits - foreground, and for the both - the first cipher turns blinking/highliting, and the last three ciphers sets the color code (what are high/low bits, where they are in the examples, where to get the color code combos appropriate the colors)). Though, I see there is not described what need to be done to certainly achieve the blinking cursor, to set the times it will blink and after that times and moments of blinkings passed it will not blinks until cursor moving, and the speed between the moments of those blinkings. From the other side... it might be that blinking times/moments related things I described are available in Xes, not in the main terminal/console...

frno7 commented 2 years ago

The article Cursor Appearance in the Linux Console is apparently an interpretation of Documentation/admin-guide/vga-softcursor.rst. The Wikipedia article on VGA text mode also says some things about the cursor, for example that

the VGA standard does not provide a way to alter the blink rate, although common workarounds involve hiding the cursor and using a normal character glyph to provide a so-called software cursor.

I could imagine that the kernel console would emulate blinking in software, either by periodically alternating the shape of the cursor with FB_TILE_CURSOR_NONE (to have it temporarily vanish) as in

https://github.com/frno7/linux/blob/74551883ae787c450910efe9807a6629a5637171/drivers/video/fbdev/ps2fb.c#L1339

or by setting mode to 0 meaning erase as in

https://github.com/frno7/linux/blob/74551883ae787c450910efe9807a6629a5637171/include/linux/fb.h#L349

but the kernel console doesn’t seem to do any of those two alternatives for a blinking cursor effect.

Also, the ps2fb driver already makes use of foreground fg cursor colour in

https://github.com/frno7/linux/blob/74551883ae787c450910efe9807a6629a5637171/drivers/video/fbdev/ps2fb.c#L1352

(which can be observed with echo -e '\033[?17;0;64c' for a red block cursor), but there’s also an background bg cursor colour setting in

https://github.com/frno7/linux/blob/74551883ae787c450910efe9807a6629a5637171/include/linux/fb.h#L352

that’s maybe the colour of the upper part of the cursor?

frno7 commented 2 years ago

Cursor blinking is on a timer function fb_flashcursor in

https://github.com/frno7/linux/blob/59a11ab94a4020408c7dfbf92bd55778e17b43f1/drivers/video/fbdev/core/fbcon.c#L388-L420

and it calls tile_cursor in

https://github.com/frno7/linux/blob/59a11ab94a4020408c7dfbf92bd55778e17b43f1/drivers/video/fbdev/core/tileblit.c#L82-L117

but it’s not entirely clear what, if anything, is controlling a blinking effect.

frno7 commented 2 years ago

@Arch91, if you’re satisfied with a dirty blinker, try this 3-line piece of hack (having the new blink variable as indicated by <<<----) for the write_cb_tilecursor function:

        static bool blink;    // <<<----
        union package * const base_package = par->package.buffer;
        union package *package = base_package;
        const u32 tw = par->cb.tile.width;
        const u32 th = par->cb.tile.height;
        const u32 dy =
                blink                                       ? 0 :    // <<<----
                cursor->shape == FB_TILE_CURSOR_NONE        ? 0 :
                cursor->shape == FB_TILE_CURSOR_UNDERLINE   ? 1 :
                cursor->shape == FB_TILE_CURSOR_LOWER_THIRD ? th / 3 :
                cursor->shape == FB_TILE_CURSOR_LOWER_HALF  ? th / 2 :
                cursor->shape == FB_TILE_CURSOR_TWO_THIRDS  ? (2 * th) / 3 :
                cursor->shape == FB_TILE_CURSOR_BLOCK       ? th : th;
        const struct cb_cursor c = {
                .sx = (var->xoffset + tw * cursor->sx) % var->xres_virtual,
                .sy = (var->yoffset + th * cursor->sy) % var->yres_virtual,
                .dy = dy,
                .tw = tw,
                .th = th,
                .draw = cursor->mode,
                .fg_rgbaq = console_pseudo_palette(cursor->fg, par)
        };

        blink = !blink;    // <<<----

Then do echo -e "\e[?6c", as previously mentioned, for a big block of blinking awesomeness. :-)

Arch91 commented 2 years ago

The nearest time I only was reading your posts, guys, but today I redownloaded the source code from the main branch of the linux repository, recompiled the kernel and updated the modules in the appropriate places. Also changed to modprobe ps2fb instead of gs (the new cursor codes are not applied to the drm driver yet?..) in the initramfs init script. @frno7, you forced me to search the place where to apply those blink inlines!) That's the kernel_source/drivers/video/fbdev/ps2fb.c file. I wrote those three places you marked with <<<---- by looking to your post. I loaded the kernel and obtained that the cursor is not blinking. Isn't there a chance that it is blinking SO FAST so I can't notice the blinking? I used mode_option=1920x1080p@50 mode_margin=+13+0 addition for the modprobe ps2fb inline, if that matters as to be noted for my videomode choosed.

Then do echo -e "\e[?6c"

I saw just a white rectangle/block. I tried them all from 0 to 6)

try echo -e '\033[?17;0;64c' for a big red block of a cursor!

Red. Nice.

satisfied with a dirty blinker

Well, I described the perfect) Adjustable cursor blink times and after these times and moments of blinkings passed it will not blinks until cursor moving; adjustable speed between the moments of those blinkings - both of GNU standards, which means that if there could be an app which tweaks those things, then that app will be working without any edits/additions in it's source code. But as I noted, maybe those things are not related to main terminal console. And in the console there is a non-blinking cursor only. I'm not sure about that.

And a side question. Is ps2fb driver ready for to be launched through Xvfb X-server?

frno7 commented 2 years ago

(the new cursor codes are not applied to the non-drm driver yet?..)

No, the DRM driver is likely to become deprecated.

I loaded the kernel and obtained that the cursor is not blinking.

Did you rerun make modules_install and so on after adding the blinker?

I loaded the kernel and obtained that the cursor is not blinking. Isn't there a chance that it is blinking SO FAST so I can't notice the blinking?

Probably not too fast, no.

Then do echo -e "\e[?6c"

I saw just a white rectangle/block. I tried them all from 0 to 6)

This one should blink. Check that /sys/class/graphics/fbcon/cursor_blink is 1 also.

try echo -e '\033[?17;0;64c' for a big red block of a cursor!

Red. Nice.

This one turns off blinking, though...

Well, I described the perfect) Adjustable cursor blink times and after these times and moments of blinkings passed it will not blinks until cursor moving; adjustable speed between the moments of those blinkings - both of GNU standards, which means that if there could be an app which tweaks those things, then that app will be working without any edits/additions in it's source code. But as I noted, maybe those things are not related to main terminal console. And in the console there is a non-blinking cursor only. I'm not sure about that.

Moving the cursor should not be necessary. It should blink by itself, and at least it does for me.

And a side question. Is ps2fb driver ready for to be launched through Xvfb X-server?

Not yet, it only does text at the moment. But it's pretty effective at that. :-)

Arch91 commented 2 years ago

Did you rerun make modules_install and so on after adding the blinker?

Well, yes, that was the place where I made a mistake - my old modules were placed in initramfs(and in my target system too)/lib/modules/5.4.169 while the modules from the new kernel are now placed in initramfs/lib/modules/5.4.169+ (with plus). I removed that 5.4.169 folder before the kernel recompiling. And that blinds my eyes, I thought that after the ps2fb.c is edited, the kernel rebuilding is enough. I did not mind about that modules must be rebuilt either. Exactly that ps2fb.c related edits are for the appropriate module. Now I saw the blinking. About 2.5-3 times in second.

By the way, if to change the cursor shape to rectangle with echo -e "\e[?6c" and then to use a nano text editor with a further quit from the editing screen - the cursor shape changes back to the underline. In different from the vi text editor - the cursor stays unchanged before, while and after the vi using.

Moving the cursor should not be necessary. It should blink by itself, and at least it does for me.

after these times and moments of blinkings passed it will not blinks until cursor moving

I mean... other. Here is the example of the cursor behaviour in the terminal with Xes in my Fedora 30: The time before the blinkings is 1 second - visible->half_of_sec_passed->not_visible->half_of_sec_passed->visible->... If to do nothing/not doing the cursor moves - it blinks 10 times and becomes constantly visible UNTIL you'll push some keyboard button or escape-return to the window of that terminal.

Not yet

I dare myself an unwary question of inquire - what is insufficient in ps2fb to become a serious linux videodriver?) I'm just in curious, I beleive whatever the answer I can't influence for that driver upgradation in any imaginable by me way :/

frno7 commented 2 years ago

Now I saw the blinking. About 2.5-3 times in second.

Nice! I made the dirty blinker default in the latest precompiled actions download. If people are annoyed, we can turn blinking off again...

By the way, if to change the cursor shape to rectangle with echo -e "\e[?6c" and then to use a nano text editor with a further quit from the editing screen - the cursor shape changes back to the underline. In different from the vi text editor - the cursor stays unchanged before, while and after the vi using.

Maybe the Nano editor is being naughty with the cursor settings? Resetting it perhaps? Bad, bad, editor.

I mean... other. Here is the example of the cursor behaviour in the terminal with Xes in my Fedora 30: The time before the blinkings is 1 second - visible->half_of_sec_passed->not_visible->half_of_sec_passed->visible->... If to do nothing/not doing the cursor moves - it blinks 10 times and becomes constantly visible UNTIL you'll push some keyboard button or escape-return to the window of that terminal.

The blinking we have now is a dirty piece of hack. As mentioned, it’s a bit of a mystery how the cursor actually is going to blink properly...

I dare myself an unwary question of inquire - what is insufficient in ps2fb to become a serious linux videodriver?) I'm just in curious, I beleive whatever the answer I can't influence for that driver upgradation in any imaginable by me way :/

The two main alternatives to the current text console, as I see it, are

A virtual frame buffer is best for compatibility with existing application software, but generally has poor performance, both in terms of speed and memory usage. For simple applications, performance may not matter, though. They may be fast enough anyway. A Graphics Synthesizer device can have excellent performance and memory usage, and make really good use of the hardware acceleration resources of the PlayStation 2, but it requires application software adjustments, which may be difficult to do.

Arch91 commented 2 years ago

Well, totally the only info I found is that

echo -e "\e[?6c"

all these seven (six and invisible) shapes are blinking by default. The blinking can be disabled by setting 0 to /sys/class/graphics/fbcon/cursor_blink so it seems that _cursorblink is 1 by default.

Adjustable cursor blink times

It is called "cursor blink rate". It someway controlled by an escape sequence, the example of the setting it to 600milliseconds: echo '\e[16;600]'

I did not find the info about the adjusting of "when the times and moments of blinkings passed it will not blinks until cursor moving". I consider this feature is controllable by some side libraries such as terminfo or else, and maybe even when the cursor is choosed as softwared.

I may assume that the "serenity" (not what is dirty for now) cursor was not blinking because of the absent blinking rate feature. If to assume that the blinking rate is 0 while the blinking is enabled (1) then it would happy to blink, but the blinking rate is momental, so no blinking)