From 44eacabbffe8127f528a9f09593910233d55cd86 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Fri, 6 Jan 2006 11:21:23 +0000 Subject: - monitor-get-edid is now a perl script able to probe /proc/acpi/video (or /proc/device-tree on PPC) - binary monitor-get-edid is now monitor-get-edid-using-vbe - monitor-edid is able to get more than one head --- .cvsignore | 2 +- Makefile | 22 ++-------- minifind.c | 77 --------------------------------- minifind.h | 42 ------------------ monitor-edid | 100 ++++++++++++++++++++++++++++++++++++++++++- monitor-edid.spec | 12 +++++- monitor-get-edid-using-vbe.c | 56 ++++++++++++++++++++++++ monitor-get-edid.c | 56 ------------------------ monitor-parse-edid | 2 +- open_firmware.c | 55 ------------------------ 10 files changed, 169 insertions(+), 255 deletions(-) delete mode 100644 minifind.c delete mode 100644 minifind.h create mode 100644 monitor-get-edid-using-vbe.c delete mode 100644 monitor-get-edid.c delete mode 100644 open_firmware.c diff --git a/.cvsignore b/.cvsignore index 51d02a7..df171d6 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,3 +1,3 @@ -monitor-get-edid +monitor-get-edid-using-vbe cvt cvs diff --git a/Makefile b/Makefile index 571e61d..ac91239 100644 --- a/Makefile +++ b/Makefile @@ -15,37 +15,21 @@ endif ifeq (ia64,$(ARCH)) HAS_VBE = y endif -ifeq (ppc,$(ARCH)) -HAS_OPEN_FIRMWARE = y -endif -ifeq (ppc64,$(ARCH)) -HAS_OPEN_FIRMWARE = y -endif -TARGETS = monitor-get-edid cvt +TARGETS = monitor-get-edid-using-vbe cvt CFLAGS = -O -Wall -g -OBJS = monitor-get-edid.c +OBJS = monitor-get-edid-using-vbe.c vbe.o libint10.a libx86emu.a ifeq (i386,$(ARCH)) OBJS += lrmi.o endif -ifeq (y,$(HAS_VBE)) -OBJS += vbe.o libint10.a libx86emu.a -else -ifeq (y,$(HAS_OPEN_FIRMWARE)) -OBJS += open_firmware.o minifind.o -else -$(error "can't access EDID since neither VBE nor open firmware supported") -endif -endif - all: $(TARGETS) cvt: LDFLAGS += -lm -monitor-get-edid: $(OBJS) +monitor-get-edid-using-vbe: $(OBJS) libx86emu.a: x86emu/*.c $(MAKE) -C x86emu diff --git a/minifind.c b/minifind.c deleted file mode 100644 index 487e18c..0000000 --- a/minifind.c +++ /dev/null @@ -1,77 +0,0 @@ -/* minifind.c -- simple find library - * - * Copyright (c) 2002 Terra Soft Solutions, Inc. - * Written by Dan Burcaw - * - * This software may be freely redistributed under the terms of the GNU - * library public license. - * - * You should have received a copy of the GNU Library Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "minifind.h" - -// insert a node at head of linked-list -void insert_node(struct pathNode *n, char *path) -{ - struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode)); - new->path = path; - new->next = n->next; - n->next = new; -} - -// return input strip less last character -char *stripLastChar(char *in) -{ - char *out = malloc(sizeof(char)*strlen(in)); - snprintf(out, strlen(in) - 1, "%s", in); - return out; -} - -// do the work -char *minifind(char *dir, char *search, struct findNode *list) -{ - char *d = NULL; - int n; - struct dirent **namelist; - struct stat buf; - - if (dir[strlen(dir)-1] == '/') - dir = stripLastChar(dir); - - // check is there is an exact filematch to dir - // when search is not specified - if (search == NULL) - { - if (lstat(dir, &buf) == 0) - insert_node(list->result, dir); - return 0; - } - - n = scandir(dir, &namelist, 0, alphasort); - if (n >= 0) - { - while (n--) - { - d = malloc(sizeof(char) * (strlen(dir) \ - + strlen(namelist[n]->d_name)+2)); - sprintf(d, "%s/%s", dir, namelist[n]->d_name); - if (strstr(namelist[n]->d_name, search)) - insert_node(list->result, d); - - if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode)) - { - if (strcmp(namelist[n]->d_name, ".") && - strcmp(namelist[n]->d_name, "..")) - d = minifind(d, search, list); - } - free(namelist[n]); - } - free(namelist); - return d; - } - return 0; -} diff --git a/minifind.h b/minifind.h deleted file mode 100644 index 4f72525..0000000 --- a/minifind.h +++ /dev/null @@ -1,42 +0,0 @@ -/* minifind.h - * - * Copyright (c) 2002 Terra Soft Solutions, Inc. - * Written by Dan Burcaw - * - * This software may be freely redistributed under the terms of the GNU - * library public license. - * - * You should have received a copy of the GNU Library Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef MINIFIND_H -#define MINIFIND_H - -#include -#include -#include -#include -#include -#include -#include - -struct pathNode -{ - char *path; - struct pathNode *next; -}; - -struct findNode -{ - struct pathNode *result; - struct pathNode *exclude; -}; - -void insert_node(struct pathNode *n, char *path); -char *stripLastChar(char *in); -char *minifind(char *dir, char *search, struct findNode *list); - -#endif /* MINIFIND_H */ diff --git a/monitor-edid b/monitor-edid index de3ce0c..5bc0bea 100755 --- a/monitor-edid +++ b/monitor-edid @@ -1,2 +1,98 @@ -#!/bin/sh -monitor-get-edid "$@" | monitor-parse-edid "$@" +#!/usr/bin/perl + +use Getopt::Long; + +my %opt = ('acpi-dir' => "/proc/acpi/video"); +my @common_options = ('verbose', 'try-in-console', 'no-vbe', 'acpi-dir=s'); + +if ($0 =~ /monitor-get-edid/) { + GetOptions_(@common_options) or die "usage: monitor-get-edid [-v] [--acpi-dir ] [--try-in-console]\n"; + + if (my @edids = get_edids(1)) { + print $edids[0][1]; + exit 0; + } else { + exit 1; + } +} else { + GetOptions_(@common_options, 'MonitorsDB', 'perl') + or die "usage: monitor-edid [-v] [--acpi-dir ] [--perl] [--MonitorsDB] [--try-in-console]\n"; + + my $err = 1; + + if (my @edids = get_edids()) { + print "(\n" if $opt{perl}; + foreach (@edids) { + my ($f, $edid) = @$_; + warn "parsing EDID from $f\n" if $opt{verbose}; + open(my $F, '|' . parse_edid()); + print $F $edid; + close $F and $err = 0; + print ",\n" if $opt{perl}; + } + print ")\n" if $opt{perl}; + } + exit $err; +} + +sub GetOptions_ { + my (@l) = @_; + GetOptions('v' => \$opt{verbose}, map { $_ => \$opt{/([^=]*)/ && $1} } @l); +} + +sub propagate_options { + my (@l) = @_; + map { $_ eq 'verbose' ? '-v' : "--$_" } grep { $opt{$_} } @l; +} + +sub get_using_vbe() { + my $prog = '/usr/sbin/monitor-get-edid-using-vbe'; + -x $prog && join(' ', $prog, propagate_options('verbose', 'try-in-console')); +} + +sub parse_edid() { + join(' ', './monitor-parse-edid', propagate_options('verbose', 'MonitorsDB', 'perl')); +} + +sub get_edids { + my ($b_get_first) = @_; + my @l = map { my $s = slurp($_); $s ? [ $_ => $s ] : () } get_edid_files(); + + if (!@l || !$b_get_first && $< == 0) { + if (my $cmd = get_using_vbe()) { + warn "probind EDID using VBE\n" if $opt{verbose}; + my $edid = `$cmd`; + if (grep { $_->[1] eq $edid } @l) { + # already found, forget it + } else { + push @l, [ vbe => $edid ]; + } + } + } + @l; +} + +sub get_edid_files() { + my @l1 = find_EDID("/proc/device-tree"); + my @l2 = grep { + (my $state_f = $_) =~ s/EDID$/state/; + my ($state) = slurp($state_f) =~ /state:\s*0x(\w+)/; + hex($state) & 2; # bit 1 is "Output is activated" + } find_EDID($opt{'acpi-dir'}); + (@l1, @l2); +} + +sub find_EDID { + my ($dir) = @_; + my @l; + require File::Find; + File::Find::find(sub { $_ eq 'EDID' and push @l, $File::Find::name }, $dir); + @l; +} + +sub slurp { + my ($f) = @_; + open(my $F, '<', $f) or return; + local $/; + scalar <$F>; +} diff --git a/monitor-edid.spec b/monitor-edid.spec index 8b36789..1d56206 100644 --- a/monitor-edid.spec +++ b/monitor-edid.spec @@ -1,5 +1,5 @@ %define name monitor-edid -%define version 1.5 +%define version 1.9 %define release 1mdk Summary: Get monitor details @@ -26,10 +26,12 @@ make rm -rf $RPM_BUILD_ROOT install -d $RPM_BUILD_ROOT%_bindir install -d $RPM_BUILD_ROOT%_sbindir -install monitor-edid monitor-get-edid monitor-probe monitor-probe-using-X $RPM_BUILD_ROOT%_sbindir +install monitor-edid monitor-get-edid monitor-get-edid-using-vbe monitor-probe monitor-probe-using-X $RPM_BUILD_ROOT%_sbindir install monitor-parse-edid $RPM_BUILD_ROOT%_bindir install cvt $RPM_BUILD_ROOT%_bindir/vesa-cvt +ln -s monitor-get-edid monitor-edid + %clean rm -rf $RPM_BUILD_ROOT @@ -40,6 +42,12 @@ rm -rf $RPM_BUILD_ROOT %_sbindir/* %changelog +* Thu Jan 5 2006 Pixel 1.9-1mdk +- monitor-get-edid is now a perl script able to probe /proc/acpi/video + (or /proc/device-tree on PPC) +- binary monitor-get-edid is now monitor-get-edid-using-vbe +- monitor-edid is able to get more than one head + * Mon Aug 8 2005 Pixel 1.5-1mdk - add option --try-in-console when probing edid since probing edid sometimes only work in console diff --git a/monitor-get-edid-using-vbe.c b/monitor-get-edid-using-vbe.c new file mode 100644 index 0000000..50366f2 --- /dev/null +++ b/monitor-get-edid-using-vbe.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "get-edid.h" + +int verbose = 0; + +int main(int argc, char **argv) +{ + char edid[256]; + int try_in_console = 0; + int i; + + for (i = 1; i < argc; i++) + if (strcmp(argv[i], "-v") == 0) verbose = 1; + else if (strcmp(argv[i], "--try-in-console") == 0) try_in_console = 1; + else if (strcmp(argv[i], "-h") == 0 || + strcmp(argv[i], "--help") == 0) { + printf("usage: monitor-get-edid [-v]\n"); + exit(1); + } + + int size = get_edid(edid); + + if (!size && try_in_console) { + int non_X_console = 1; + int first_X_console = 7; + struct vt_stat current; + int fd = open("/dev/console", O_RDWR); + + if (ioctl(fd, VT_GETSTATE, ¤t) == 0 && + current.v_state >= first_X_console && + ioctl(fd, VT_ACTIVATE, non_X_console) == 0 && + ioctl(fd, VT_WAITACTIVE, non_X_console) == 0) { + /* retrying */ + size = get_edid(edid); + + /* restore */ + ioctl(fd, VT_ACTIVATE, current.v_active) == 0 && + ioctl(fd, VT_WAITACTIVE, current.v_active) == 0; + } + close(fd); + } + + if (size) write(1, edid, size); + + return size ? 0 : 1; +} diff --git a/monitor-get-edid.c b/monitor-get-edid.c deleted file mode 100644 index 50366f2..0000000 --- a/monitor-get-edid.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "get-edid.h" - -int verbose = 0; - -int main(int argc, char **argv) -{ - char edid[256]; - int try_in_console = 0; - int i; - - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-v") == 0) verbose = 1; - else if (strcmp(argv[i], "--try-in-console") == 0) try_in_console = 1; - else if (strcmp(argv[i], "-h") == 0 || - strcmp(argv[i], "--help") == 0) { - printf("usage: monitor-get-edid [-v]\n"); - exit(1); - } - - int size = get_edid(edid); - - if (!size && try_in_console) { - int non_X_console = 1; - int first_X_console = 7; - struct vt_stat current; - int fd = open("/dev/console", O_RDWR); - - if (ioctl(fd, VT_GETSTATE, ¤t) == 0 && - current.v_state >= first_X_console && - ioctl(fd, VT_ACTIVATE, non_X_console) == 0 && - ioctl(fd, VT_WAITACTIVE, non_X_console) == 0) { - /* retrying */ - size = get_edid(edid); - - /* restore */ - ioctl(fd, VT_ACTIVATE, current.v_active) == 0 && - ioctl(fd, VT_WAITACTIVE, current.v_active) == 0; - } - close(fd); - } - - if (size) write(1, edid, size); - - return size ? 0 : 1; -} diff --git a/monitor-parse-edid b/monitor-parse-edid index dc8cead..3d63b79 100755 --- a/monitor-parse-edid +++ b/monitor-parse-edid @@ -449,7 +449,6 @@ GetOptions( 'v' => \ (my $verbose), 'perl' => \ (my $raw_perl), 'MonitorsDB' => \ (my $MonitorsDB), - 'try-in-console' => undef, ) or usage(); my $F; @@ -475,6 +474,7 @@ if ($raw_perl) { $Data::Dumper::Sortkeys = 1; my $s = Dumper($edid); $s =~ s/.*? = {/+{/; # remove variable name we don't want + $s =~ s/};$/}/m; print $s; } elsif ($MonitorsDB) { my $s = to_MonitorsDB($edid); diff --git a/open_firmware.c b/open_firmware.c deleted file mode 100644 index 2170e70..0000000 --- a/open_firmware.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "get-edid.h" -#include "minifind.h" - -int get_edid(char *edid) -{ - struct pathNode *n; - struct findNode *list; - FILE* edid_file = NULL; - char *path = NULL; - - list = (struct findNode *) malloc(sizeof(struct findNode)); - list->result = (struct pathNode *) malloc(sizeof(struct pathNode)); - list->result->path = NULL; - list->result->next = list->result; - - minifind("/proc/device-tree", "EDID", list); - - for (n = list->result->next; n != list->result; n = n->next) - { - path = n->path; - break; - } - - if (path) - edid_file = fopen(path, "rb"); - - if (edid_file) - { - int size = fread(edid, sizeof(unsigned char), 0x80, edid_file); - fclose(edid_file); - return size == 0x80 ? 0x80 : 0; - } else - return 0; - -#if 0 - memcpy(&man, &ret->manufacturer_name, 2); - man = ntohs(man); - memcpy(&ret->manufacturer_name, &man, 2); - - /* byteswap to match the contents of MonitorsDB */ - ret->product_code = ((ret->product_code >> 8) & 0xff) | ((ret->product_code & 0xff) << 8); -#endif -} -- cgit v1.2.1