Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Discussion & Documentation Documentation, Tips & Tricks
  • Search

[HOWTO] Sony Vaio FS series FN keys

Unofficial documentation for various parts of Gentoo Linux. Note: This is not a support forum.
Post Reply
Advanced search
221 posts
  • Page 1 of 9
    • Jump to page:
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 9
  • Next
Author
Message
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

[HOWTO] Sony Vaio FS series FN keys

  • Quote

Post by pijalu » Tue May 10, 2005 2:39 am

EDIT: a easiest way to get it working is available here

After searching a while i found out a way to change brightness... a little tricky but works fine on my FS-115M:

First, download the sony_acpi module from sonypi here
untar it

Code: Select all

tar xzvf sony_acpi.tar.gz
Copy the following in a file (in the extracted dir, as sony_acpi.patch to keep simple)

Code: Select all

--- sony_acpi_old/sony_acpi.c   2005-03-01 11:10:33.000000000 +0100
+++ sony_acpi/sony_acpi.c       2005-05-09 19:13:22.000000000 +0200
@@ -80,6 +80,11 @@
                .debug          = 0,
        },
        {
+               .name           = "fnkey",
+               .acpiget        = "GHKE",
+               .debug          = 0,
+       },
+       {
                .name           = "brightness_default",
                .acpiget        = "GPBR",
                .acpiset        = "SPBR",
If you copy the patch in the untared sony_acpi dir as sony_acpi.patch (you are a nice person if you follow my advice), patch the sony acpi ext (this will include the functions keys handling using acpi)

Code: Select all

patch < sony_acpi.patch
Compile the patched sony_acpi

Code: Select all

make
and move it your modules dir and update dep

Code: Select all

cp sony_acpi.ko /lib/modules/`uname -r`/kernel/drivers/acpi
depmod -a
Modprobe it to check if fine

Code: Select all

modprobe sony_acpi
Check in /proc/acpi/sony that you see 3 files

Code: Select all

muaddib@vaio ~ $ ls /proc/acpi/sony/
brightness  brightness_default  fnkey
Add it to your autoload modules (if fine - otherwise check kernel messages)

Code: Select all

echo "sony_acpi" >> /etc/modules.autoload.d/kernel-2.6
Now copy this content to a file called sonyfn.c somewhere

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

// sound stuff
#include <linux/soundcard.h>

// keys
#define  FN_F2  1       // cut sound
#define  FN_F3  2       // volume -
#define  FN_F4  4       // volume +
#define  FN_F5  8       // Brightness -
#define  FN_F6  16      // Brightness +
#define  FN_F7  32      // LCD/SCREEN
#define  FN_F10 128     // Zoom in
#define  FN_F12 64      // Suspend
#define  S1_BTN 4096    // S1 custom button
#define  S2_BTN 8192    // S2 custom button

// config hard coded :p
#define  MIXER_DEV      "/dev/mixer"

// SOUND HANDLER
int get_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDONLY);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_READ_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int set_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDWR);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int volume_up()
{
    int value = 0;

    get_volume(&value);

    if (value < 0x5a5a)
        value += 0x0a0a;
    else
        value = 0x6464;

    set_volume(&value);

    return 0;
}

int volume_down()
{
    int value = 0;

    get_volume(&value);

    if (value > 0x0a0a)
        value -= 0x0a0a;
    else
        value = 0;

    set_volume(&value);

    return 0;
}

int oldvalue;
int mute()
{
    int value;

    get_volume(&value);

    if (value) {
            oldvalue=value;
            value=0;
            set_volume(&value);
    }
    else {
            if (!oldvalue) {
                volume_up();
            }
            else {
                set_volume(&oldvalue);
            }
    }

    return 0;
}
// END OF SOUND

/* Return current brightness of the screen */
int getBrightness() {
        FILE* handle;
        char buffer[2];
        int ret;

        if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
                perror("Error opening /proc/acpi/sony/brightness");
                exit(-1);
        }
        if (fscanf(handle,"%d",&ret)!=1) {
                perror("Error reading /proc/acpi/sony/brightness");
                exit(-1);
        }
        fclose(handle);
        return ret;

}

/* Set the current brightness of the screen */
void setBrightness(int b) {
        FILE* handle;
        char buffer[2];

        // validate values
        if (b>8) {
                b=8;
        }
        else if (b<1) {
                b=1;
        }

        if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
                perror("Error opening /proc/acpi/sony/brightness");
                exit(-1);
        }
        if (fprintf(handle,"%d",b)!=1) {
                perror("Error writing /proc/acpi/sony/brightness");
                exit(-1);
        }
        fclose(handle);
}

// Pool the fnkey status
int getCodes() {
        FILE* handle;
        char buffer[10];
        int ret;

        if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
                perror("Error opening /proc/acpi/sony/fnkey");
                exit(-1);
        }
        if (fscanf(handle,"%d",&ret)!=1) {
                perror("Error reading /proc/acpi/sony/fnkey");
                exit(-1);
        }
        fclose(handle);
        return ret;
}

// main and loop
int main(void) {
        int key;

        nice(10); // be a nice dirty code

        printf("SonyFN loaded\n");
        while(1) { // loop
                if (key=getCodes()) { // get Fn status
                        if ((key & FN_F5)==FN_F5) { // lower brightness
                                setBrightness(getBrightness()-1);
                        }
                        if ((key & FN_F6)==FN_F6) { // higher brightness
                                setBrightness(getBrightness()+1);
                        }
                        if ((key & FN_F2)==FN_F2){
                                mute();
                        }
                        if ((key & FN_F3)==FN_F3) {
                                volume_down();
                        }
                        if ((key & FN_F4)==FN_F4) {
                                volume_up();
                        }
                        // rest i don't care
                }
                usleep(300000);
        }
        return 0;
}
now, compile it and move it to your /usr/bin

Code: Select all

gcc sonyfn.c -o sonyfn
mv sonyfn /usr/bin
As root, launch it (since it's a dirty handler, you need to put it in bg with & ;) )

Code: Select all

sonyfn &
Check, normally, mute volume, volumes and brightness keys should works...
If works fine, add the handler to your local.start

Code: Select all

echo "/usr/bin/sonyfn 1>&2 >>/var/log/sonyfn.log &" >>/etc/conf.d/local.start
Have fun
Last edited by pijalu on Thu Sep 15, 2005 5:36 pm, edited 2 times in total.
Top
UB|K
l33t
l33t
User avatar
Posts: 786
Joined: Thu May 27, 2004 6:11 pm
Location: Villeurbanne, France

  • Quote

Post by UB|K » Sat Jun 11, 2005 11:50 am

waooo!! i missed this great tip while i was on holidays... so thank you for this, it works great on my vaio (FS115E).

Looking quickly into the code of sonyfn.c showed my that a shortcut was already defined for "fn+F12 --> suspend" but i also noticed:

Code: Select all

}
                        // rest i don't care
                } 
:(
so it's not implemented in sonyfn...
Since i don't have any knowledge in programming (not even a litlle), i didn't succeeded to get this working. I've tried something like this:

Code: Select all

                        if ((key & FN_F12)==FN_F12) {
                                hibernate();
                        } 
but compilling fails (cause "hibernate" is an external prog and isn't defined :oops: ).
How could i do that??
thx in advance
Reality is that which, when you stop believing in it, doesn't go away.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Sat Jun 11, 2005 12:27 pm

If the program you want to call is, for eg /bin/hibernate , this should to the trick....
if not, change the "/bin/hibernate" to the command/script you want to use
Just take care, no args...

Code: Select all

...
if ((key & FN_F12)==FN_F12) {
				if (fork()==0) { 
					if (execv("/bin/hibernate",NULL)==-1) {
						perror("Cannot run hibernate");	
					}
				}
			}
...
If ok/not ok, let me know :-)
Top
UB|K
l33t
l33t
User avatar
Posts: 786
Joined: Thu May 27, 2004 6:11 pm
Location: Villeurbanne, France

  • Quote

Post by UB|K » Sat Jun 11, 2005 1:44 pm

Thank you, it works perfectly and as sonyfn is runned as root, there no need to use sudo to launch the hibernate script.
Here is the correct patch:

Code: Select all

--- sonyfn.c         2005-06-11 15:09:28.000000000 +0200
+++ sonyfn_susp.c    2005-06-11 15:11:42.000000000 +0200
@@ -192,6 +192,14 @@
                         if ((key & FN_F4)==FN_F4) {
                                 volume_up();
                         }
+
+                       if ((key & FN_F12)==FN_F12) {
+                               if (fork()==0) {
+                                       if (execv("/usr/sbin/hibernate",NULL)==-1) {
+                               perror("Cannot run hibernate");
+                                               }
+                               }
+                       }
                         // rest i don't care
                 }
                 usleep(300000);
Reality is that which, when you stop believing in it, doesn't go away.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Sat Jun 11, 2005 2:46 pm

Cool, thanks for correcting the path :-)
I guess I really should take a look at the hibernate thing one of this day :lol:

For the note, you can add the same kind of code to map S1 and S2 buttons to some scripted actions... And as you already knows, they will be runned as root... this means this could be a security issue as well...

To finish, i made a dirty init script for sonyfn, so feel free to "c/p" it

Code: Select all

#!/sbin/runscript
# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

depend() {
	need localmount
}

checkconfig() {
	if [ ! -e /proc/acpi/sony/fnkey ] ; then
		eerror "Sony key handler not found"
		return 1
	fi
}

start() {
	ebegin "Starting SonyFN key handler"
	/usr/bin/sonyfn 1>&2 >>/var/log/sonyfn.log &
	eend $?
}

stop() {
	ebegin "Stopping SonyFN key handler"
	killall sonyfn 1>&2 >/dev/null
	eend 0
}
For eg, save it as sonyfn in /etc/init.d/ and do a

Code: Select all

rc-update add sonyfn default
You can now remove the call to sonyfn in local.start

Note: if the sonyfn code is not /usr/bin/sonyfn , change the start() and/or stop() path/name to reflect your own installation
Top
max.bl
n00b
n00b
User avatar
Posts: 1
Joined: Mon Jul 18, 2005 8:22 am

video out ??

  • Quote

Post by max.bl » Mon Jul 18, 2005 8:27 am

Hi guys,
have you got any idea about how to make video out switch (Fn-F7) working ?
I've a vaio fs-115s laptop with nvidia video card.
I'm using sony_acpi kernel module and sonyfn program (thanks for it !!).
Top
blinksilver
n00b
n00b
Posts: 13
Joined: Sat Jul 23, 2005 8:25 pm

  • Quote

Post by blinksilver » Sat Jul 23, 2005 9:14 pm

Hey all, I maybe alittle late to post, but I just bought a Sony S460. Its very close to the FS (pretty much identical except for screen size) and I suspect that this will work.

When I try to patch the driver it give me an error, and refuse to patch one hunk out of one, I think that the driver has been updated(it is dated the 28 of june), and the patch no longer works. so I tried to hand patch it, just copied and pasted the 5 lines over (took out the +s) then compiled modprobed but " Fnkey" does not show up (the other two do). Could someone pm a patched version of sony_acpi.c?

It would really me out thanks.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Sun Jul 24, 2005 1:51 am

I guess the patch problem must be due to a typo made when c/p the patch, but since i don't have any backup of the original sony_acpi.c i used, here come a patch done on the newly d/l sony_acpi.tar.gz

Code: Select all

--- sony_acpi.c.old     2005-07-24 03:10:14.000000000 +0200
+++ sony_acpi.c 2005-07-24 03:40:03.000000000 +0200
@@ -33,7 +33,7 @@

 #define ACPI_SNC_CLASS         "sony"
 #define ACPI_SNC_HID           "SNY5001"
-#define ACPI_SNC_DRIVER_NAME   "ACPI Sony Notebook Control Driver v0.2"
+#define ACPI_SNC_DRIVER_NAME   "ACPI Sony Notebook Control Driver v0.2-PP"

 #define LOG_PFX                        KERN_WARNING "sony_acpi: "

@@ -88,6 +88,11 @@
                .debug          = 0,
        },
        {
+               .name           = "fnkey",
+               .acpiget        = "GHKE",
+               .debug          = 0,
+       },
+       {
                .name           = "cdpower",
                .acpiget        = "GCDP",
                .acpiset        = "SCDP",
Compile and copy to your kernel and give a try to

Code: Select all

rmmod sony_acpi
modprobe sony_acpi
Now, check if the "patched" version of the modules loaded fine:

Code: Select all

grep "Sony Notebook Control Driver v0.2-PP" /var/log/messages
(This last patch add -PP to the original version, so it should be easier to check if loaded fine)
You should get something like

Code: Select all

Jul 24 03:41:06 vaio ACPI Sony Notebook Control Driver v0.2-PP successfully installed
Hope this will help...
Keep me uptodate about that :)

To finish: If not working, did you give a try to the sonypi thing ?
(cf http://popies.net/sonypi/
@max.bl: Sorry, i don't have the time to look for the crt out yet... If i find out how to make it work, i will post it here ;)
Top
blinksilver
n00b
n00b
Posts: 13
Joined: Sat Jul 23, 2005 8:25 pm

  • Quote

Post by blinksilver » Mon Jul 25, 2005 3:24 am

i dumped linux off because, as is, its not doing me any good, I am too mobile to loss that much battery life, but i have a knoppix cd sitting around, will give it a shot with that.

will report back, but from what i have been reading it does not look good
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Thu Aug 25, 2005 2:01 am

Hi,

here comes a new sonyfn handler, who should eat less cpu...

This version uses the event interface to check for a possible hit to the Fn key and then try to figure out what happend...
The side effect is a faster handling....

Short note: the kernel MUST be compiled with event interface (in Input Device support , check "Event Interface") [this should be already done for the touchpad thing]

Anyway, check with something like

Code: Select all

grep "INPUT_EVDEV" /usr/src/linux/.config
This should return

Code: Select all

CONFIG_INPUT_EVDEV=y
and a

Code: Select all

ls /dev/input/
should returns (something like this)

Code: Select all

event0  event1  event2  event3  mice  mouse0  mouse1  mouse2
Your keyboard should be event0 , but you can do

Code: Select all

sudo cat /dev/input/eventX
(with X the nb to check) and if you got "garbage" when hitting keyboard, then you know your keyboard exact eventX

Now, compile the following code (cf first post, just use this code for the handler)

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

// input thing
#include <linux/input.h>

// sound stuff
#include <linux/soundcard.h>

// keys 
#define  FN_F2	1	// cut sound
#define  FN_F3  2	// volume -
#define  FN_F4  4	// volume +
#define  FN_F5	8	// Brightness -
#define  FN_F6	16	// Brightness +
#define  FN_F7  32	// LCD/SCREEN
#define  FN_F10 128	// Zoom in
#define	 FN_F12 64	// Suspend
#define  S1_BTN 4096	// S1 custom button
#define	 S2_BTN 8192	// S2 custom button

#define  FN_INPUT_VALUE	245	// Fn key generate a 245 value
#define  FN_INPUT_TYPE	4	// a 4 type
#define  FN_INPUT_CODE	4	// and a 4 code 

// config hard coded :p
#define  MIXER_DEV	"/dev/mixer"

// SOUND HANDLER
int get_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDONLY);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_READ_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int set_volume(int *value)
{
    int mixer = open(MIXER_DEV, O_RDWR);

    if (mixer) {
        ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
        close(mixer);
        return 0;
    }
    else
        return 1;
}

int volume_up()
{
    int value = 0;

    get_volume(&value);

    if (value < 0x5a5a)
        value += 0x0a0a;
    else
        value = 0x6464;

    set_volume(&value);

    return 0;
}

int volume_down()
{
    int value = 0;

    get_volume(&value);

    if (value > 0x0a0a)
        value -= 0x0a0a;
    else
        value = 0;

    set_volume(&value);

    return 0;
}

int oldvalue;
int mute()
{
    int value;
    
    get_volume(&value);
    
    if (value) {
	    oldvalue=value;
	    value=0;
	    set_volume(&value);
    }
    else {
	    if (!oldvalue) {
		volume_up();    	
	    }
	    else {
	    	set_volume(&oldvalue);
	    }
    }

    return 0;
}
// END OF SOUND

/* Return current brightness of the screen */
int getBrightness() {
	FILE* handle;
	char buffer[2];
	int ret;
	
	if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
		perror("Error opening /proc/acpi/sony/brightness");
		exit(-1);
	}
	if (fscanf(handle,"%d",&ret)!=1) {
		perror("Error reading /proc/acpi/sony/brightness");
		exit(-1);
	}
	fclose(handle);
	return ret;
	
}

/* Set the current brightness of the screen */
void setBrightness(int b) {
	FILE* handle;
	char buffer[2];

	// validate values
	if (b>8) { 
		b=8;
	}
	else if (b<1) {
		b=1;
	}
	
	if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
		perror("Error opening /proc/acpi/sony/brightness");
		exit(-1);
	}
	if (fprintf(handle,"%d",b)!=1) {
		perror("Error writing /proc/acpi/sony/brightness");
		exit(-1);
	}
	fclose(handle);
}

// Pool the fnkey status
int getCodes() {
	FILE* handle;
	char buffer[10];
	int ret;
	if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
		perror("Error opening /proc/acpi/sony/fnkey");
		exit(-1);
	}
	if (fscanf(handle,"%d",&ret)!=1) {
		perror("Error reading /proc/acpi/sony/fnkey");
		exit(-1);
	}
	fclose(handle);
	return ret;	
}

// main and loop
int main(int argc, char **argv) {
	// event interface
        int fd = -1;        /* the file descriptor for the device */
    	int i;           /* loop counter */
    	size_t read_bytes;  /* how many bytes were read */
    	struct input_event ev[64]; /* the events (up to 64 at once) */
		
	/* key code */
	int key;

	/* used if event hit fn */
	int hasSomething;
	
 	/* open event interface*/
    	if (argc != 2) {
		/* i don't like outputs...
		fprintf(stderr, "Using /dev/input/event0 for input\n");
		fprintf(stderr, "Overide with %s event-device\n", argv[0]);
		*/
		if ((fd = open("/dev/input/event0", O_RDONLY)) < 0) {
			perror("event interface open failed");
			exit(1);
    		}
    	}
	else {	
    		if ((fd = open(argv[1], O_RDONLY)) < 0) {
			perror("event interface open failed");
			exit(1);
    		}
	}

	nice(10); // be a nice dirty code (less dirty but keep nice)

	
	while(1) { /* loop */
		hasSomething=0; /* nothing yet */
		
		/* read the event interface */
		read_bytes = read(fd, ev, sizeof(struct input_event) * 64);
		
		if (read_bytes < (int) sizeof(struct input_event)) {
	    		perror("sonyfn: short read");
	    		exit (1);
		}

		/* Loop for all readed events until we have something interesting.. */
		for (i = 0;! hasSomething && ( i < (int) (read_bytes / sizeof(struct input_event)) ); i++) {
			hasSomething= (ev[i].type == FN_INPUT_TYPE)
				   && (ev[i].code == FN_INPUT_CODE)
				   && (ev[i].value == FN_INPUT_VALUE);
	    	}	
		
		/* If we got a FN event, plz do something...*/
		if ( hasSomething && (key=getCodes()) ) { 
			if ((key & FN_F5)==FN_F5) { // lower brightness
				setBrightness(getBrightness()-1);
			}
			if ((key & FN_F6)==FN_F6) { // higher brightness
				setBrightness(getBrightness()+1);
			}
			if ((key & FN_F2)==FN_F2){
				mute();
			}
			if ((key & FN_F3)==FN_F3) {
				volume_down();
			}
			if ((key & FN_F4)==FN_F4) {
				volume_up();
			}
			if ((key & FN_F12)==FN_F12) {
				if (fork()==0) { 
					/* that's my home made script for swsusp
					 #!/bin/sh
					 sync
					 echo "disk" > /sys/power/state
					*/
					if (execv("/bin/hibernate",NULL)==-1) {
						perror("Cannot run hibernate");	
					}
				}
			}
			/* rest i still don't care */		
		}
	}// while
	
	close(fd);
	return 0;
}
If your keyboard is /dev/input/event0 then you can just copy this handler on the "old" one , if the event handler is different, then it must me lauch using this synthax

Code: Select all

sonyfn /dev/input/eventX
with X the right number...
Please update the exact call in previous post (init.d thing or local.start)

Have phun
Top
sound-mind
n00b
n00b
Posts: 21
Joined: Sun Jan 30, 2005 5:14 am

  • Quote

Post by sound-mind » Thu Aug 25, 2005 12:33 pm

pijalu wrote:Hi,

here comes a new sonyfn handler, who should eat less cpu...
<snip...>
Have phun
That last version works great pijalu :D No cpu cycles used unless a user is typing. Just what the FS users needed!
Top
sound-mind
n00b
n00b
Posts: 21
Joined: Sun Jan 30, 2005 5:14 am

  • Quote

Post by sound-mind » Sun Aug 28, 2005 5:57 pm

Here's a diff against pijalu's latest post to add xosd support.

Compile:

Code: Select all

gcc -Wall -o sonyfn sonyfn.c -lxosd -lX11
Patch:

Code: Select all

--- sonyfn.c.old        2005-08-28 18:45:14.168313208 -0400
+++ sonyfn.c    2005-08-29 08:11:37.727686824 -0400
@@ -5,6 +5,11 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>

+// osd stuff
+#include <xosd.h>
+#include <locale.h>
+#include <X11/Xlib.h>
+
 // input thing
 #include <linux/input.h>

@@ -30,6 +35,88 @@
 // config hard coded :p
 #define  MIXER_DEV   "/dev/mixer"

+// The FS series seems to support 8 brightness levels
+#define MAX_BRIGHT 8
+#define MIN_BRIGHT 1
+
+// the volume osd color
+#define OSD_VCOLOR "red"
+// the brightness osd color
+#define OSD_BCOLOR "blue"
+// the osd font... change the 7th position for size
+// or use xfontsel to explore the options
+#define OSD_FONT "-*-*-*-*-*-*-20-*-*-*-*-*-*-*"
+// the length of time the osd is shown
+#define OSD_TIME 3
+
+// volume scaling factor for OSD
+#define OSD_VSCALE 250
+
+// the onscreen display
+static xosd *disp_obj = '\0';
+
+int osd_brightness(int level){
+       // the size of the increment
+       static int inc_size = 100.0 / (MAX_BRIGHT - 1);
+        int retval = 0;
+       int pos;
+
+        retval &= xosd_set_bar_length(disp_obj, 100);
+        retval &= xosd_set_pos(disp_obj, XOSD_bottom);
+        retval &= xosd_set_align(disp_obj, XOSD_center);
+        retval &= xosd_set_shadow_offset(disp_obj, 1);
+        retval &= xosd_set_outline_offset(disp_obj, 1);
+        retval &= xosd_set_vertical_offset(disp_obj, 30);
+        retval &= xosd_set_colour(disp_obj, OSD_BCOLOR);
+        retval &= xosd_set_timeout(disp_obj, OSD_TIME);
+        retval &= xosd_set_font(disp_obj, OSD_FONT);
+
+        if (retval){
+                fprintf(stderr,"Failed setup onscreen display: %s\n", xosd_error);
+        } else {
+               if (level == MAX_BRIGHT){
+                       pos = 100;
+               } else {
+                       pos = level * inc_size - inc_size;
+               }
+                retval = xosd_display(disp_obj, 0, XOSD_slider, pos);
+                retval = xosd_display(disp_obj, 1, XOSD_string, "Brightness");
+                if (retval == -1){
+                        fprintf(stderr,"Failed to display information onscreen: %s\nAre you running X?\n",
+                                       xosd_error);
+                }
+        }
+
+        return 1;
+}
+
+int osd_volume(int level){
+        int retval = 0;
+
+        retval &= xosd_set_bar_length(disp_obj, 100);
+        retval &= xosd_set_pos(disp_obj, XOSD_bottom);
+        retval &= xosd_set_align(disp_obj, XOSD_center);
+        retval &= xosd_set_shadow_offset(disp_obj, 1);
+        retval &= xosd_set_outline_offset(disp_obj, 1);
+        retval &= xosd_set_vertical_offset(disp_obj, 30);
+        retval &= xosd_set_colour(disp_obj, OSD_VCOLOR);
+        retval &= xosd_set_timeout(disp_obj, OSD_TIME);
+        retval &= xosd_set_font(disp_obj, OSD_FONT);
+
+        if (retval){
+                fprintf(stderr,"Failed setup onscreen display: %s\n", xosd_error);
+        } else {
+                retval = xosd_display(disp_obj, 0, XOSD_slider, level / OSD_VSCALE);
+                retval = xosd_display(disp_obj, 1, XOSD_string, "Volume");
+                if (retval == -1){
+                        fprintf(stderr,"Failed to display information onscreen: %s\nAre you running X?\n",
+                                       xosd_error);
+                }
+        }
+
+        return 1;
+}
+
 // SOUND HANDLER
 int get_volume(int *value)
 {
@@ -51,6 +138,7 @@
     if (mixer) {
         ioctl(mixer, SOUND_MIXER_WRITE_VOLUME, value);
         close(mixer);
+       osd_volume(*value);
         return 0;
     }
     else
@@ -117,7 +205,6 @@
 /* Return current brightness of the screen */
 int getBrightness() {
    FILE* handle;
-   char buffer[2];
    int ret;

    if ((handle=fopen("/proc/acpi/sony/brightness","rb"))==NULL) {
@@ -136,14 +223,13 @@
 /* Set the current brightness of the screen */
 void setBrightness(int b) {
    FILE* handle;
-   char buffer[2];

    // validate values
-   if (b>8) {
-      b=8;
+   if (b > MAX_BRIGHT) {
+      b = MAX_BRIGHT;
    }
-   else if (b<1) {
-      b=1;
+   else if (b < MIN_BRIGHT) {
+      b = MIN_BRIGHT;
    }

    if ((handle=fopen("/proc/acpi/sony/brightness","wb"))==NULL) {
@@ -155,12 +241,12 @@
       exit(-1);
    }
    fclose(handle);
+   osd_brightness(b);
 }

 // Pool the fnkey status
 int getCodes() {
    FILE* handle;
-   char buffer[10];
    int ret;
    if ((handle=fopen("/proc/acpi/sony/fnkey","rb"))==NULL) {
       perror("Error opening /proc/acpi/sony/fnkey");
@@ -185,8 +271,16 @@
    /* key code */
    int key;

+
    /* used if event hit fn */
    int hasSomething;
+
+       // initialize the osd
+        disp_obj = xosd_create(2);
+
+       if (setlocale(LC_ALL, "") == NULL || !XSupportsLocale())
+               fprintf(stderr, "Locale not available, expect problems with fonts.\n");
+

     /* open event interface*/
        if (argc != 2) {
@@ -244,7 +338,7 @@
          if ((key & FN_F4)==FN_F4) {
             volume_up();
          }
-         if ((key & FN_F12)==FN_F12) {
+        if ((key & FN_F12)==FN_F12) {
             if (fork()==0) {
                /* that's my home made script for swsusp
                 #!/bin/sh
@@ -255,11 +349,11 @@
                   perror("Cannot run hibernate");
                }
             }
-         }
+         }
          /* rest i still don't care */
       }
    }// while
-
+   xosd_destroy(disp_obj);
    close(fd);
    return 0;
 }
You may have to run this as root once you startx depending on your /proc permissions.

Edit: Code update to fix handling of xosd object (leaky threads :oops:)
Last edited by sound-mind on Mon Aug 29, 2005 12:34 pm, edited 1 time in total.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Sun Aug 28, 2005 6:15 pm

Excellent :-)
This is too sweet :-)

If you want to use it the easy way [avoid perm problem] (example: if the sonyfn is in /usr/bin)

Code: Select all

sudo chown root /usr/bin/sonyfn
sudo chmod 4755 /usr/bin/sonyfn
This will allows any user to launch the handler as root
(it's a sticky bit - sonyfn then execute as it was launched by root - take care about it, it can lead to security issue...)
Top
G2k
l33t
l33t
User avatar
Posts: 672
Joined: Sat Mar 06, 2004 5:58 pm
Location: Rome, Italy

  • Quote

Post by G2k » Sun Aug 28, 2005 11:58 pm

When I try to apply the patch I get the following error

Code: Select all

~/sony_acpi $ patch < fnkey.diff 
patching file sony_acpi.c
Hunk #1 FAILED at 80.
1 out of 1 hunk FAILED -- saving rejects to file sony_acpi.c.rej
How can I fix this?
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Mon Aug 29, 2005 12:13 am

Hum, just to be sure, reextract the sony_acpi.tar.gz content and give a try to

Code: Select all

patch -l --dry-run < fnkey.diff
(this try the patch without really applying it)

If it don't complain, then

Code: Select all

patch -l < fnkey.diff
Otherwise, pm your email/or send me email and i will send it to you asap
Tip: the -l option inform patch to ignore white space during the procedure
Top
G2k
l33t
l33t
User avatar
Posts: 672
Joined: Sat Mar 06, 2004 5:58 pm
Location: Rome, Italy

  • Quote

Post by G2k » Mon Aug 29, 2005 1:14 am

k that worked, thanks
EDIT:
new problem. Modprobing tells me

Code: Select all

FATAL: Module sony_acpi not found.
although the sony_acpi.ko is in /lib/modules/2.6.12-gentoo-r9/kernel/drivers/acpi/ where `uname -r` is 2.6.12-gentoo-r9. I have module loading enabled in my kernel.
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Top
sound-mind
n00b
n00b
Posts: 21
Joined: Sun Jan 30, 2005 5:14 am

  • Quote

Post by sound-mind » Mon Aug 29, 2005 12:42 pm

I just updated the patch above. I mishandled the threaded xosd object and ended up leaking threads all over the floor :oops:

Now you should see a total of 3 processes reported by ps. Two of these are really just GUI handling threads used by the xosd libs that should sleep most of
the time. These could be avoided by creating and destroying the xosd object at each fnkey press. It is a tradeoff, two lightweight threads sleeping in the background vs. dynamically creating and destroying the threads each time a fnkey is pressed.

G2k: Have you run depmod -a?
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Mon Aug 29, 2005 2:44 pm

For me, 2 sleeping treads are way better than the overhead of recreating objects :-)

FYI: I totally forgot the depmod thing in the very first post...my fault...I just corrected that now...

Btw G2k, if still troubles, give a try to

Code: Select all

insmod /path/to/sony_acpi.ko
This should force the load ;-)
Top
G2k
l33t
l33t
User avatar
Posts: 672
Joined: Sat Mar 06, 2004 5:58 pm
Location: Rome, Italy

  • Quote

Post by G2k » Mon Aug 29, 2005 3:43 pm

gah!

Code: Select all

 gcc -Wall -o sonyfn sonyfn.c -lxosd -lX11
sonyfn.c:9:18: xosd.h: No such file or directory
sonyfn.c:56: error: syntax error before '*' token
sonyfn.c:56: warning: type defaults to `int' in declaration of `disp_obj'
sonyfn.c:56: warning: data definition has no type or storage class
sonyfn.c: In function `osd_brightness':
sonyfn.c:64: warning: implicit declaration of function `xosd_set_bar_length'
sonyfn.c:65: warning: implicit declaration of function `xosd_set_pos'
sonyfn.c:65: error: `XOSD_bottom' undeclared (first use in this function)
sonyfn.c:65: error: (Each undeclared identifier is reported only once
sonyfn.c:65: error: for each function it appears in.)
sonyfn.c:66: warning: implicit declaration of function `xosd_set_align'
sonyfn.c:66: error: `XOSD_center' undeclared (first use in this function)
sonyfn.c:67: warning: implicit declaration of function `xosd_set_shadow_offset'
sonyfn.c:68: warning: implicit declaration of function `xosd_set_outline_offset'
sonyfn.c:69: warning: implicit declaration of function `xosd_set_vertical_offset'
sonyfn.c:70: warning: implicit declaration of function `xosd_set_colour'
sonyfn.c:71: warning: implicit declaration of function `xosd_set_timeout'
sonyfn.c:72: warning: implicit declaration of function `xosd_set_font'
sonyfn.c:75: error: `xosd_error' undeclared (first use in this function)
sonyfn.c:82: warning: implicit declaration of function `xosd_display'
sonyfn.c:82: error: `XOSD_slider' undeclared (first use in this function)
sonyfn.c:83: error: `XOSD_string' undeclared (first use in this function)
sonyfn.c: In function `osd_volume':
sonyfn.c:97: error: `XOSD_bottom' undeclared (first use in this function)
sonyfn.c:98: error: `XOSD_center' undeclared (first use in this function)
sonyfn.c:107: error: `xosd_error' undeclared (first use in this function)
sonyfn.c:109: error: `XOSD_slider' undeclared (first use in this function)
sonyfn.c:110: error: `XOSD_string' undeclared (first use in this function)
sonyfn.c: In function `main':
sonyfn.c:279: warning: implicit declaration of function `xosd_create'
sonyfn.c:279: warning: assignment makes pointer from integer without a cast
sonyfn.c:356: warning: implicit declaration of function `xosd_destroy'
wouldn't it be easier if all the steps were in the right order on the first post on this page?? I'm not good at this kind of stuff :cry:
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Top
sound-mind
n00b
n00b
Posts: 21
Joined: Sun Jan 30, 2005 5:14 am

  • Quote

Post by sound-mind » Mon Aug 29, 2005 3:52 pm

G2k: emerge xosd

I'll try to make an ebuild when I get some free time.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Mon Aug 29, 2005 3:57 pm

G2k wrote:gah!

Code: Select all

emerge xosd
should help you...
edit: to slow

Actually, yap, but the things is i like the incremental way to do it... there is still one trade off... Or you use the nice X one or the other one with the init.d - but both of them is a not go...
(...I guess, didn't try this ;-)...)

Actually i think making a nice ebuild should be the thing to do and host it somewhere...
(and use nice #IFDEF thing to allows with/without xosd on one src...)
If someone is interested go ahead... I am quite in a buzz now... if not, will do that next week... ;-)
edit: LOL
Top
sound-mind
n00b
n00b
Posts: 21
Joined: Sun Jan 30, 2005 5:14 am

  • Quote

Post by sound-mind » Mon Aug 29, 2005 4:10 pm

pijalu wrote:
Actually, yap, but the things is i like the incremental way to do it... there is still one trade off... Or you use the nice X one or the other one with the init.d - but both of them is a not go...
(...I guess, didn't try this ;-)...)

Actually i think making a nice ebuild should be the thing to do and host it somewhere...
(and use nice #IFDEF thing to allows with/without xosd on one src...)
If someone is interested go ahead... I am quite in a buzz now... if not, will do that next week... ;-)
edit: LOL
Yup... I thought wrapping the functions and their calls in IFDEF's but didn't want to complicate things. I guess I could update this and make an ebuild... So whoever has free time first ;)

Actually I'll try to post an IFDEF'd wrapped version later today and you can just compile it with -DUSE_XOSD to make it easy.
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Mon Aug 29, 2005 4:22 pm

sound-mind wrote: Yup... I thought wrapping the functions and their calls in IFDEF's but didn't want to complicate things. I guess I could update this and make an ebuild... So whoever has free time first ;)

Actually I'll try to post an IFDEF'd wrapped version later today and you can just compile it with -DUSE_XOSD to make it easy.
Ho, for the ifdef i thought the same way as you :), just telling that for the ebuild...Currently, Users decide a super ifdef : using patch or not using patch... :lol:

Don't bother with it, it will be a job for the ebuilder ;-)
Top
G2k
l33t
l33t
User avatar
Posts: 672
Joined: Sat Mar 06, 2004 5:58 pm
Location: Rome, Italy

  • Quote

Post by G2k » Mon Aug 29, 2005 8:05 pm

lol...uhm...I'm lazy. do you guys mind if I sit here and just wait for an e-build? :P
Animula vagula blandula,
Hospes comesque corporis,
Quae nunc abibis in loca
Pallidula rigida nudula,
Nec ut soles dabis iocos...
- Imp. Caesar Hadrianus
Top
pijalu
Guru
Guru
User avatar
Posts: 365
Joined: Mon Oct 04, 2004 10:43 am

  • Quote

Post by pijalu » Mon Aug 29, 2005 9:17 pm

:lol:
Top
Post Reply

221 posts
  • Page 1 of 9
    • Jump to page:
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 9
  • Next

Return to “Documentation, Tips & Tricks”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy