xmonad / X11

A Haskell binding to the X11 graphics library.

Home Page:http://hackage.haskell.org/package/X11

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

XF86XK_AudioForward is not exported

nagisa opened this issue · comments

XF86XK_AudioForward is not exported from Graphics.X11.ExtraTypes.XF86 even though a similar XF86XK_AudioRewind is.

Okay. There's actually a lot of symbols missing. It's a generated file, and the script that generated it seems not to be in revision control. I've emailed the guy who added XF86.hsc to the repository to see if he still has the script lying around. If not, or I don't hear from him, I'll take a stab at writing a new script.

Just got an email from zythmer. The relevant files, which he placed in the public domain, follow.

HsAllKeySyms.h:

#ifndef HSALLKEYSYMS_H
#define HSALLKEYSYMS_H 1

/* Defaults */
#include <X11/keysym.h>

/* Vendor specific */
#include <X11/DECkeysym.h>
#include <X11/Sunkeysym.h>
#include <X11/ap_keysym.h>
#include <X11/HPkeysym.h>
#include <X11/XF86keysym.h>

#endif /* HSALLKEYSYMS_H */

gen.sh:

#!/bin/sh

echo "Regenerating all of the keysym files..."

rm -f *.hsc

perl create_hsc_keysym.pl XorgDefault  /usr/include/X11/keysymdef.h    > XorgDefault.hsc
perl create_hsc_keysym.pl DEC  /usr/include/X11/DECkeysym.h  > DEC.hsc
perl create_hsc_keysym.pl HP   /usr/include/X11/HPkeysym.h   > HP.hsc
perl create_hsc_keysym.pl Sun  /usr/include/X11/Sunkeysym.h  > Sun.hsc
perl create_hsc_keysym.pl XF86 /usr/include/X11/XF86keysym.h > XF86.hsc
perl create_hsc_keysym.pl AP   /usr/include/X11/ap_keysym.h  > AP.hsc

for file in $(ls *.hsc); do
    echo "Running hsc2hs on $file"
    hsc2hs $file
done

check.sh:

    #!/bin/sh

# Generate the hs files and check that it appears the number of entries
# are the same.

echo "Finding the count for X11 includes..."
for file in $(ls /usr/include/X11/*keysym* | grep -v "/keysym\.h$" | sort); do
    count=$(grep "^ *#define.*XK_" $file  | wc -l);
    haskell_count=$(echo "$count * 2" | bc);
    echo "$file has $count defines (hsc should have $haskell_count)";
done

# Generating Haskell files
sh gen.sh

echo "Finding the count from generated Haskell..."
for file in $(ls *.hsc | sort); do
    count=$(egrep -v "^ *(--|#)" $file | grep "[xX]K_" | wc -l);
    echo "$file has $count symbols";
done

create_hsc_keysym.pl, the real workhorse:

# NOTE: I have to manually remove VoidSymbol, MISCELLANY and LATIN1
# because Graphics.X11.Types already includes those.

use strict;
use warnings;
use Carp;
use Data::Dumper;

if ($#ARGV != 1) {
    confess qq{Must pass in a name and file for this module};
}

my $debug = 0;

my $name = $ARGV[0];
my $file = $ARGV[1];

print<<"EOF";
-- Generated from $file
--

EOF

my @entries = get_entries($file);
print_hsc($name, @entries);

# Haskell reserves names that start with a capital for classes/types.
sub get_haskell_name {
    my ($current) = @_;

    # It doesn't matter if the Haskell name and X name are the same
    # in the enum statements.
    return lcfirst($current);
}

sub print_hsc {
    my ($name, @entries) = @_;

    # Print the assumed copyright section.
    foreach my $entry (@entries) {
        if (ref($entry) ne 'HASH') {
            confess qq{Shouldn't be here: $!};
        }
        if (exists($entry->{copyright})) {
            print "-- " . $entry->{copyright} . "\n";
        }
    }

    print<<"EOF";

module XMonad.Contrib.Keysyms.$name
        (
EOF

    # Find the longest entry so we can properly print this.
    my $longest = 0;
    foreach my $entry (@entries) {
        if (exists($entry->{key})) {
            if (length($entry->{key}) > $longest) {
                $longest = length($entry->{key});
            }
        }
    }

    # +1 for comma and +2 for room.
    $longest += 3;

    # We need to print the module export list.
    foreach my $entry (@entries) {
        if (ref($entry) ne 'HASH') {
            confess qq{Shouldn't be here: $!};
        }

        if (exists($entry->{key}) && defined($entry->{comment})) {
            printf("%9s%-${longest}s -- %s\n", " ",
                   get_haskell_name($entry->{key}) . ",", $entry->{comment});

        } elsif (exists($entry->{key})) {
            printf("%9s%-${longest}s\n", " ",
                   get_haskell_name($entry->{key}) . ",");

        } elsif (exists($entry->{ifdef})) {
            print "#ifdef " . $entry->{ifdef} . "\n";
            print "\n         -- " . $entry->{ifdef} . "\n";

        } elsif (exists($entry->{endif})) {
            print "#else\n";
            print "         -- Skipped " . $entry->{endif} . " because your X does not support it\n";
            print "#endif\n";

        } elsif (exists($entry->{comment})) {
            print "\n         -- " . $entry->{comment} . "\n";

        }
    }

    print<<"EOF";
        ) where

import Graphics.X11.Types

#include "HsAllKeysyms.h"

#{enum KeySym,
EOF

    # Note: Do not print comments in the enum section.
    my $need_close = 0;
    foreach my $entry (@entries) {
        if (exists($entry->{key})) {
            printf(" , %-${longest}s = %s\n",
                   get_haskell_name($entry->{key}), $entry->{key});
            $need_close = 1;

        } elsif (exists($entry->{ifdef})) {
            print " }\n\n"   if ($need_close);
            print "#ifdef " . $entry->{ifdef} . "\n";
            print "#{enum KeySym,\n";

        } elsif (exists($entry->{endif})) {
            print " }\n";
            print "#else\n";
            print "-- Skipped " . $entry->{endif} . " because your X does not support it.\n";
            print "#endif\n\n";
            $need_close = 0;
        }
    }
    print " }\n\n"  if ($need_close);
}

sub get_entries {
    my ($file) = @_;

    open(my $fh, $file) || confess qq{Couldn't open: $!};

    my $state = 0;

    my @entries;
    my @ifdefs;
    my ($found_blank_line, $can_check) = (0,0);
    while (my $line = <$fh>) {
        chomp($line);

        # Check for the copyright.  It's assumed that the copyright is
        # a series of commented out lines.  A blank line after '*/' is
    # assumed to start the code.
        if (! $found_blank_line) {
            if ($line =~ m{^\s*
                           /\*{1,}(.*)
                           $}mix) {
                push(@entries, { copyright => $1 });
                $state = 1;
                print "-- start copyright\n"  if $debug;
                $can_check = 0;

            } elsif ($line =~ m{^\s*
                               (.*?)\*+/\s*
                               $}mix) {
                push(@entries, { copyright => $1 });
                print "-- end copyright\n"   if $debug;
                $can_check = 1;

            } elsif ($can_check && $line =~ m{^\s*$}) {
                $found_blank_line = 1;

            } else {
                $line =~ s{^\s+}{};
                push(@entries, { copyright => $line });
            }
        }

        print "-- \t$line\n"  if $debug;
        if ($line =~ m{^\s*
                       /\*+(.*)\*+/
                       \s*$}mix) {
            push(@entries, { comment =>  $1 });
            print "-- Found comment\n"  if $debug;

        } elsif ($line =~ m{^\s*
                       /\*{1,}.*
                       $}mix) {
            $state = 1;
            print "-- Found start_comment\n"  if $debug;

        } elsif ($state == 1
                 && $line =~ m{^\s*
                               .*\*/.*
                               $}mix) {
            $state = 0;
            print "-- end start_comment\n"   if $debug;

        } elsif ($state == 0) {
            if ($line =~ m{^\s*
                           \#define\s+
                           (\S*K_\S+)       # $1 = keysym
                           \s+
                           (0x[0-9A-Fa-f]+) # $2 = value
                           \s*
                           (?:
                             /\*(.+)\*/       # $3 = comment
                           )?
                           \s*
                         $}mix) {
                push(@entries,
                     { key => $1, value => $2, comment => $3 });
                print "-- define\n"   if $debug;

            } elsif ($line =~ m{^\s*
                                \#ifdef\s+
                                (\S*K_\S+)  # $1 = keysym type
                                \s*$}mix) {

                push(@entries, { ifdef => $1 });
                push(@ifdefs, $1);
                print "-- ifdef\n"   if $debug;

            } elsif (scalar(@ifdefs) > 0
                     && $line =~ m{^\s*
                                    \#endif
                                    .*$}mix) {
                push(@entries, { endif => pop(@ifdefs) });
                print "-- endif\n"  if $debug;
            }
        }
    }

    close($fh) || confess qq{Couldn't close: $!};

    return @entries;
}

Shouldn't these files be put in the repository?
And by the way, there is a bug in {gen,check}.sh.

for file in $(ls *.hsc); do

is unsafe. It should be:

for file in *.hsc; do

How do we want to maintain the hsc file going forward? Accept patches or take ownership of these perl scripts and put them in the repo?

Any update?

@sboosali I took a brief look today. These scripts appear to work, but the files they generate are waaaay too different from the files that are currently in the repository for my taste. As far as I can tell I would have to manually review each updated hsc file to check that nothing important has been lost; I'm not going to do that.

If somebody wants to update the scripts to make the diffs more manageable, I'll reconsider.