 2008/07/04
|
Last update 1999/02/20
TPJ: Issue_05_X
- README
- Xproto2.perl
- clickwindow.pl
- xhello.pl
- extra-Xproto.h
- xatomhash.pl
- names
- parse-xheader.pl
- reqs
- wmm.pl
- xauth.pl
- xbase.pl
- xbeep.pl
- xdpyinfo.pl
- xerror.pl
- xint.perl
- xlsfont.pl
- xwdhead.pl
- xwininfo.c
- xwininfo.pl
- More Samples on X
Download README
|
Back in late 1991, I wrote an X library for perl. This wasn't a bindi\
|
|
ng
|
|
to the C Xlib; this was a raw implementation of the X protocol.
|
|
|
|
It got some small amount of use around MIT; I never got around to
|
|
posting it widely, but got feedback from a few people.
|
|
perl5 has some clever new features, which should make it easier to
|
|
provide a clean "interface" than the old code had, and easier to
|
|
set up good abstractions internally.
|
|
Now that I've had time to read through the Perl5 edition of the Camel
|
|
Book, it's time to begin... [eichin:19961101.0337EST]
|
|
|
|
discoveries:
|
|
* attempted to speed up the load of the converted Xproto.
|
|
perl *without* -w, user time:
|
|
.cooked file: 0.5s [original mechanism]
|
|
indiv. assign: 1.1s [first modification]
|
|
flattened assign: 0.52s, but more variance(?) [optimized a bit]
|
|
Note, however, that this *appears* to be *slower* than
|
|
parsing the proto file. Perhaps that shouldn't be a surprise...
|
|
So a win might be to store a binary format instead?
|
|
Problem is that these are all variable length strings; switching to a
|
|
split on ^@ gave about the same time range.
|
|
|
|
in perl5, we should be able to say:
|
|
my($output) = &xlibconvert("xConnSetupPrefix",$reply)
|
|
$success = $output->{"success"};
|
|
this would make $output blessed? or perhaps we say
|
|
my($output) = Xlib->new(type=>"xConnSetupPrefix",data=>$repl\
|
|
y);
|
|
all output needs to be, though, is a hash... ie. convert can
|
|
do the unpack *and* stuff the fields into the hash (and perl4 could
|
|
have probably handled this too, if &xlibconvert explicitly returned
|
|
a hash...) so xlibconvert just returns a hashref, which also happens
|
|
to contain the "packof" and "sizeof" fields. However, this only helps
|
|
with the few cases where we read now, though it would make it easier
|
|
to write more of them (as we'd need to for event handling.) We need a
|
|
better syntax for generating protocol messages, if we can...
|
|
|
|
x_beep just does:
|
|
print XFD pack($xpackof{"xBellReq"},$defines{"X_Bell"},$percentage,1\
|
|
);
|
|
we could put the $defines into a namespace directly; in fact, the X
|
|
defines are a useful set themselves, and could just become X::Bell and
|
|
the like. (maybe def:: for the others? or just make them raw values?)
|
|
so, step 1:
|
|
print XFD pack($xpackof{"xBellReq"},X::Bell,$percentage,1);
|
|
we can also, at least, define xpack as
|
|
sub xpack { my $typ=shift; pack($packof{$typ},@_); }
|
|
and then say
|
|
print XFD &xpack("xBellReq",X::Bell,$percentage,1);
|
|
which, with a name space and actual functions, could instead become
|
|
print XFD X::xBellReq(X::Bell,$percentage,1);
|
|
Then note that most of these include their *own* verb at the
|
|
beginning, there should be a clever way to instead say
|
|
print XFD X::xBellReq($percentage,1);
|
|
and now we're getting somewhere.
|
|
|
|
[eichin:19961105.0458EST]
|
|
[done] All uses of xsizeof/sizeof are in bytes -- so drop the *8 /8 al\
|
|
together.
|
|
Many use the $lll self-measuring trick, which could be generalized?
|
|
|
|
[eichin:19961106.1304EST]
|
|
[done] auth is way simple - perhaps we can just implement it next?
|
|
should fix "mismatch" code so it doesn't complain as much gratuitously
|
|
add more synonyms
|
|
[done] implement something like GetResReq/GetEmptyReq (for one arg/no \
|
|
args)
|
|
instead of forcing stuff into extra-Xproto.h?
|
|
[eichin:19961108.0113EST]
|
|
[done] finish off "xdpyinfo" features -- store xopendisplay output, an\
|
|
d then
|
|
parse it seperately...
|
|
perhaps a master data queue? or at least *some* way to handle events? \
|
|
[done]
|
|
(maybe just a hook that prints them at first...)
|
|
[eichin:19961109.1630EST]
|
|
milestones:
|
|
hello world (createwindow, gc, font) [done]
|
|
query-tree (start on wmm!) [done]
|
|
|
|
[eichin:19961117.1841EST]
|
|
request list: determine full protocol coverage based on request names
|
|
(up to 1/3 by morning...)
|
|
|
|
[eichin:19961118.1349EST]
|
|
idea from ken: calculate the length in Req subs directly? we *can*...[\
|
|
done]
|
|
[eichin:19961119.0351EST]
|
|
what about elisp, anyway? :-)
|
|
|
|
[eichin:19961120.0102EST]
|
|
how about a tie'd hash for atom name lookups? [done]
|
|
[eichin:19961120.1221EST]
|
|
now do the *reverse* as well -- what's a perl "isnumber"? that way we
|
|
can use the same data to go both ways... [done]
|
|
[eichin:19970227.0155EST]
|
|
Renamed .perl files to .pl since emacs handles that extension consiste\
|
|
ntly
|
|
now. Leave .perl for generated files for now. Add Makefile for relea\
|
|
se.
|
| Issue_05_X2. Xproto2.perl
|
Xproto2.perl
| Issue_05_X3. clickwindow.pl
|
Download clickwindow.pl
|
#!perl
|
|
#$xlib::debug = 1;
|
|
#$xlib::debugpkt = 1;
|
|
require "./xbase.pl";
|
|
# require "./xatomhash.pl";
|
|
$xopen = xlib::x_open_display($ENV{"DISPLAY"});
|
|
$fc = xlib::joincolor(65535,0,0);
|
|
$bc = xlib::joincolor(0,0,0);
|
|
$curs = xlib::x_createfontcursor($xopen, $XC::crosshair, $fc, $bc);
|
|
sub xx {
|
|
# $stat = xlib::xungrabpointer($xopen, 0); # time now
|
|
$stat = xlib::xgrabpointer($xopen,
|
|
0, # owner-events false
|
|
&xlib::defaultroot($xopen), # grabw
|
|
$X::defines{"ButtonPressMask"} |
|
|
$X::defines{"ButtonReleaseMask"},
|
|
$X::defines{"GrabModeSync"},
|
|
$X::defines{"GrabModeAsync"},
|
|
&xlib::defaultroot($xopen),
|
|
# conf window none (vs root?)
|
|
$curs, # cursor none
|
|
$X::defines{"CurrentTime"} # time now
|
|
);
|
|
# print "grabstat: $stat\n";
|
|
&xlib::xallowevents($xopen,
|
|
$X::defines{"SyncPointer"},
|
|
$X::defines{"CurrentTime"});
|
|
}
|
|
xx();
|
|
$SIG{"ALRM"} = $SIG{"INT"} = sub {
|
|
xlib::x_closedisplay($xopen);
|
|
exit;
|
|
};
|
|
alarm(30);
|
|
#print "waiting (30s)... $stat\n";
|
|
print "click on a window to toggle backing store...\n";
|
|
$xlib::handler{"ButtonRelease"} =
|
|
$xlib::handler{"ButtonPress"} = sub {
|
|
my $rep = xlib::xlibconvert("keyButtonPointer", $xopen->{"readq\
|
|
ueue"});
|
|
# xlib::debugxlib($rep);
|
|
# printf "child: 0x%x\n", $xchild = $rep->{"child"};
|
|
$xchild = $rep->{"child"};
|
|
};
|
|
$st = xlib::handle_event($xopen);
|
|
$ch1 = $xchild;
|
|
#print "event: $st, child $xchild\n";
|
|
xx();
|
|
$st = xlib::handle_event($xopen);
|
|
$ch2 = $xchild;
|
|
#print "event: $st, child $xchild\n";
|
|
# button press, button release, double check that they have the same c\
|
|
hild...
|
|
$stat = xlib::xungrabpointer($xopen, 0); # time now
|
|
if ($ch1 != $ch2) {
|
|
die "different windows, aborting on user request";
|
|
}
|
|
|
|
sub query_eval {
|
|
my ($d,$w,$sub)=@_;
|
|
&$sub($d,$w);
|
|
my @lf = &xlib::x_querytree($d, $w);
|
|
shift @lf; # lose the rep, we just want the\
|
|
kids
|
|
my $i;
|
|
for $i (@lf) {
|
|
query_eval($d,$i,$sub);
|
|
}
|
|
}
|
|
sub toggle_backingstore { # disp, win
|
|
my ($d,$w) = @_;
|
|
printf "toggling 0x%x (%d):", $w, $w;
|
|
my $attrs = xlib::x_get_window_attributes($d,$w);
|
|
if ($attrs->{"backingStore"} == $X::defines{"NotUseful"}) {
|
|
print "setting to Always\n";
|
|
$stat = xlib::x_change_window_attributes($d, $w,
|
|
$X::defines{"CWBackingSto\
|
|
re"},
|
|
$X::defines{"Always"});
|
|
} else {
|
|
print "setting to NotUseful\n";
|
|
$stat = xlib::x_change_window_attributes($d, $w,
|
|
$X::defines{"CWBackingSto\
|
|
re"},
|
|
$X::defines{"NotUseful"})\
|
|
;
|
|
}
|
|
}
|
|
query_eval($xopen,$ch1,\&toggle_backingstore);
|
Download xhello.pl
|
#!/usr/bin/perl
|
|
require "./xbase.pl";
|
|
$xopen = &xlib::x_open_display($ENV{"DISPLAY"});
|
|
die $xlib::status if not defined $xopen;
|
|
|
|
$fnt = xlib::x_openfont($xopen, "fixed");
|
|
$win = xlib::x_create_window($xopen, 8,
|
|
xlib::defaultroot($xopen),
|
|
100, 200, 300, 400, 5,
|
|
$X::defines{"InputOutput"},
|
|
$X::defines{"CopyFromParent"},
|
|
$X::defines{"CWBackPixel"}
|
|
| $X::defines{"CWEventMask"},
|
|
$xlib::root_white,
|
|
$X::defines{"ButtonPressMask"}
|
|
|$X::defines{"ButtonReleaseMask"}
|
|
|$X::defines{"ExposureMask"}
|
|
|$X::defines{"KeyPressMask"}
|
|
);
|
|
$gc = xlib::x_create_gc($xopen, $win,
|
|
$X::defines{"GCForeground"}
|
|
| $X::defines{"GCBackground"}
|
|
| $X::defines{"GCFont"},
|
|
$xlib::root_black, $xlib::root_white, $fnt);
|
|
#printf "fnt %x win %x gc %x\n", $fnt,$win,$gc;
|
|
#sleep 1;
|
|
$st = xlib::x_clear_area($xopen, $win, 0, 0,0,0,0);
|
|
$xlib::handler{"Expose"} = sub {
|
|
xlib::x_imagetext8($xopen, $win, $gc, 50, 75, "hello world");
|
|
};
|
|
$xlib::handler{"KeyPress"} = sub {
|
|
my $rep = xlib::xlibconvert("keyButtonPointer", $xopen->{"readq\
|
|
ueue"});
|
|
xlib::debugxlib($rep);
|
|
};
|
|
|
|
xlib::x_mapwindow($xopen, $win);
|
|
while(defined($st = xlib::handle_event($xopen))) { # assume error for \
|
|
now?
|
|
print "event: $st\n";
|
|
}
|
|
xlib::x_closedisplay($xopen);
|
| Issue_05_X5. extra-Xproto.h
|
extra-Xproto.h
| Issue_05_X6. xatomhash.pl
|
Download xatomhash.pl
|
#
|
|
# use getatomname or internatom depending on the value looked up, but
|
|
# cache both
|
|
package XATOM;
|
|
use Tie::Hash;
|
|
|
|
sub TIEHASH {
|
|
my ($name, $d) = @_;
|
|
my $self={}; bless $self;
|
|
$self->{"display"} = $d;
|
|
$self->{"cache"} = {};
|
|
return $self;
|
|
}
|
|
|
|
sub FETCH {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
my $r = $self->{"cache"}->{$key};
|
|
if (! defined($r)) {
|
|
if ($key =~ /^\d*$/) {
|
|
$r = xlib::x_getatomname($self->{"display"},$key);
|
|
} else {
|
|
$r = xlib::x_internatom($self->{"display"},
|
|
$X::defines{"xTrue"},$key);
|
|
}
|
|
|
|
$self->{"cache"}->{$key} = $r;
|
|
$self->{"cache"}->{$r} = $key;
|
|
}
|
|
return $r;
|
|
}
|
|
sub EXISTS {
|
|
my $self = shift;
|
|
my $key = shift;
|
|
return exists $self->{"cache"}->{$key};
|
|
}
|
|
sub STORE {
|
|
my $self = shift;
|
|
my ($key, $value) = @_; # value irrelevant
|
|
my $a = xlib::x_internatom($self->{"display"},$X::defines{"xFal\
|
|
se"}, $key);
|
|
$self->{"cache"}->{$a} = $key;
|
|
return $self->{"cache"}->{$key} = $a;
|
|
}
|
|
sub DELETE {
|
|
my $self = shift;
|
|
my ($key, $value) = @_;
|
|
# delete $self->{"refs"}->{$key};
|
|
# can't actually delete something...
|
|
-1;
|
|
}
|
|
sub FIRSTKEY {
|
|
my $self = shift;
|
|
my $a = scalar keys %{$self->{"cache"}};
|
|
return each %{$self->{"cache"}};
|
|
}
|
|
sub NEXTKEY {
|
|
my $self = shift;
|
|
my $lastkey = shift;
|
|
return each %{$self->{"cache"}};
|
|
}
|
|
sub DESTROY {
|
|
my $self = shift;
|
|
}
|
|
1;
|
Download names
|
internal:
|
|
xlibconvert
|
|
debugxlib [ but exported anyway ]
|
|
xpack [ only used in x_open_display ]
|
|
split_display [ could export... ]
|
|
next_resource_id
|
|
extend_queue
|
|
skipevent
|
|
xqueueconvert
|
|
x_real_put_image
|
|
network:
|
|
mkport
|
|
mkport_unix
|
|
serverprint
|
|
other:
|
|
min
|
|
meta:
|
|
x_washwindow
|
|
x_get_one
|
|
x_reply
|
|
x_iter_raw
|
|
x_iter
|
|
genvec
|
|
genvec2
|
|
genvecstr
|
|
xpoly1
|
|
xpoly2
|
|
x_ungrab
|
|
exported:
|
|
handle_event
|
|
xdebugdisplay [but only for xdpyinfo?]
|
|
xlib::
|
|
default::
|
|
root defaultroot
|
|
rootdepth defaultrootdepth
|
|
window::
|
|
destroy x_destroywindow
|
|
destroysubs x_destroysubwindows
|
|
map x_mapwindow
|
|
mapsubs x_mapsubwindows
|
|
unmap x_unmapwindow
|
|
unmapsubs x_unmapsubwindows
|
|
configure x_configurewindow
|
|
getgeometry x_get_geometry
|
|
reparent x_reparentwindow
|
|
circulate x_circulatewindow
|
|
create x_create_window
|
|
list x_querytree
|
|
set_background_pixmap x_set_window_background_p\
|
|
ixmap
|
|
attributes::
|
|
get x_get_window_attributes
|
|
change x_change_window_attribut\
|
|
es
|
|
clear x_clear_area
|
|
saveset x_changesaveset
|
|
translate TranslateCoords [pending]
|
|
pixmap::
|
|
create x_create_pixmap
|
|
copyarea CopyArea [pending]
|
|
copyplane CopyPlane [pending]
|
|
image::
|
|
put x_put_image
|
|
get GetImage [pending]
|
|
free FreePixmap [pending]
|
|
poly::
|
|
arcs xpolyarcs
|
|
fillarcs xpolyfillarcs
|
|
rects xpolyrects
|
|
fillrects xpolyfillrects
|
|
segments xpolysegments
|
|
points xpolypoints
|
|
lines xpolylines
|
|
fill FillPoly [pending]
|
|
selection::
|
|
setowner xsetselectionowner
|
|
getowner xgetselectionowner
|
|
convert xconvertselection
|
|
property::
|
|
change x_changeproperty
|
|
delete x_deleteproperty
|
|
get x_getproperty
|
|
list x_listproperties
|
|
rotate RotateProperties [pending]
|
|
font::
|
|
getpath x_getfontpath
|
|
setpath SetFontPath [pending]
|
|
list x_listfonts
|
|
close CloseFont [pending]
|
|
query QueryFont [pending]
|
|
queryextents QueryTextExtents [pending]
|
|
open x_openfont
|
|
text::
|
|
poly8 PolyText8 [pending]
|
|
poly16 PolyText16 [pending]
|
|
image8 x_imagetext8
|
|
image16 ImageText16 [pending]
|
|
atom::
|
|
getname x_getatomname
|
|
intern x_internatom
|
|
pointer::
|
|
grab xgrabpointer
|
|
ungrab xungrabpointer
|
|
changegrab xchangeactivepointergrab
|
|
query xquerypointer
|
|
getmapping x_get_pointer_mapping
|
|
setmapping SetPointerMapping [pending]
|
|
warp WarpPointer [pending]
|
|
getcontrol GetPointerControl [pending]
|
|
changecontrol ChangePointerControl [pending]
|
|
GC::
|
|
free FreeGC [pending]
|
|
change ChangeGC [pending]
|
|
copy CopyGC [pending]
|
|
create x_create_gc
|
|
setdashes SetDashes [pending]
|
|
setcliprects SetClipRectangles [pending]
|
|
colormap::
|
|
create CreateColormap [pending]
|
|
free FreeColormap [pending]
|
|
copyandfree CopyColormapAndFree [pending]
|
|
install InstallColormap [pending]
|
|
uninstall UninstallColormap [pending]
|
|
listinstalled ListInstalledColormaps [pending]
|
|
color::
|
|
# may use a hash, or at least combine allocs
|
|
alloc AllocColor [pending]
|
|
allocnamed AllocNamedColor [pending]
|
|
alloccells AllocColorCells [pending]
|
|
allocplanes AllocColorPlanes [pending]
|
|
free FreeColors [pending]
|
|
store StoreColors [pending]
|
|
storenamed StoreNamedColor [pending]
|
|
query QueryColors [pending]
|
|
lookup LookupColor [pending]
|
|
cursor::
|
|
create CreateCursor [pending]
|
|
createglyph CreateGlyphCursor [pending]
|
|
free FreeCursor [pending]
|
|
recolor RecolorCursor [pending]
|
|
bestize QueryBestSize [pending]
|
|
access::
|
|
change ChangeHosts [pending]
|
|
list ListHosts [pending]
|
|
set SetAccessControl [pending]
|
|
screensaver::
|
|
set SetScreenSaver [pending]
|
|
get GetScreenSaver [pending]
|
|
force ForceScreenSaver [pending]
|
|
key::
|
|
grab xgrabkeyboard
|
|
grab xgrabkey
|
|
grab xgrabbutton
|
|
ungrab xungrabkeyboard
|
|
ungrab xungrabbutton
|
|
ungrab xungrabkey
|
|
getmapping x_get_keyboard_mapping
|
|
getmapping x_get_modifier_mapping
|
|
setmapping SetModifierMapping [pending]
|
|
getcontrol x_get_keyboard_control
|
|
getfocus x_get_input_focus
|
|
setfocus SetInputFocus [pending]
|
|
getmotion GetMotionEvents [pending]
|
|
changemapping ChangeKeyboardMapping [pending]
|
|
changecontrol ChangeKeyboardControl [pending]
|
|
query QueryKeymap [pending]
|
|
beep x_beep
|
|
connection::
|
|
setmode SetCloseDownMode [pending]
|
|
kill KillClient [pending]
|
|
open x_open_display
|
|
close x_closedisplay
|
|
grab xgrabserver
|
|
ungrab xungrabserver
|
|
extensions::
|
|
list x_listextensions
|
|
query QueryExtension [pending]
|
|
event::
|
|
xsendevent
|
|
xallowevents
|
| Issue_05_X8. parse-xheader.pl
|
Download parse-xheader.pl
|
#!perl
|
|
$xsizeof{"int"} = 4;
|
|
$xsizeof{"char"} = 1;
|
|
$xsizeof{"BYTE"} = 1;
|
|
$xsizeof{"BOOL"} = 1;
|
|
$xsizeof{"long"} = 4;
|
|
$xsizeof{"CARD8"} = 1;
|
|
$xsizeof{"CARD16"} = 2;
|
|
$xsizeof{"CARD32"} = 4;
|
|
$xsizeof{"INT8"} = 1;
|
|
$xsizeof{"INT16"} = 2;
|
|
$xsizeof{"INT32"} = 4;
|
|
# oops, X11R4 is missing one...
|
|
# X11R6 has it though.
|
|
# $xsizeof{"xGetModifierMappingReply"} = 256;
|
|
$xpackof{"int"} = "L";
|
|
$xpackof{"char"} = "C";
|
|
$xpackof{"BYTE"} = "C";
|
|
$xpackof{"BOOL"} = "C";
|
|
$xpackof{"long"} = "L";
|
|
$xpackof{"CARD8"} = "C";
|
|
$xpackof{"CARD16"} = "S";
|
|
$xpackof{"CARD32"} = "L";
|
|
$xpackof{"INT8"} = "C";
|
|
$xpackof{"INT16"} = "S";
|
|
$xpackof{"INT32"} = "L";
|
|
# these are stored in %xpad in case we decide we want to be general la\
|
|
ter on
|
|
# but for now we copy it all into %xpackof anyhow.
|
|
for $i ("", 1..3) {
|
|
$xpad{"BYTE pad$i"} = "x";
|
|
}
|
|
$xpad{"BYTE bpad"} = "x";
|
|
$xpad{"CARD8 pad"} = "x";
|
|
$xpad{"CARD8 pad1"} = "x";
|
|
$xpad{"CARD16 pad"} = "x2";
|
|
$xpad{"CARD16 pad1"} = "x2";
|
|
$xpad{"CARD16 pad2"} = "x2";
|
|
# these are mostly Xevent subfields...
|
|
for $i ("", "00", 1..7) {
|
|
$xpad{"CARD32 pad$i"} = "x4";
|
|
}
|
|
for $i (keys %xpad) { $xpackof{$i} = $xpad{$i}; }
|
|
$incomment = 0;
|
|
sub fropcomment { # $incomment
|
|
my($incomment) = @_;
|
|
s/\/\*.*\*\///g;
|
|
if(/\*\//) {
|
|
$incomment = 0;
|
|
s/^.*\*\///;
|
|
}
|
|
next if $incomment;
|
|
if(/\/\*/) {
|
|
$incomment = 1;
|
|
s/\/\*.*//;
|
|
}
|
|
}
|
|
|
|
# walk XPROTO file and fill in any defines, xsizeof, xtypeof, requests
|
|
# we come across, sometimes calling process_struct to help
|
|
sub munchproto {
|
|
while(<XPROTO>) {
|
|
$incomment = &fropcomment($incomment);
|
|
|
|
if(/\#if defined\(\_\_cplusplus\) \|\| defined\(c\_plusplus\)/\
|
|
) {
|
|
while(<XPROTO>) {
|
|
last if (/\#else/);
|
|
}
|
|
}
|
|
next if(/\#else/);
|
|
next if(/\#endif/);
|
|
next if(/\#undef/);
|
|
next if(/\#ifdef NEED_EVENTS/);
|
|
next if(/\#ifdef NEED_REPLIES/);
|
|
next if(/\#ifndef XPROTO_H/);
|
|
next if(/\#include/); # maybe do these some other time.
|
|
$eventing=1 if(/^\#define KeyPress/);
|
|
$eventing=0 if(/^\#define LASTEvent/);
|
|
|
|
if(/^\#define (\w+)$/) {
|
|
$defines{$1} = 1;
|
|
print "# defined flag $1\n";
|
|
next;
|
|
}
|
|
|
|
if(/^\#define sz_(\w+) (\d+)$/) {
|
|
$xsizeof{$1} = $2;
|
|
print "# processed size $1\n";
|
|
next;
|
|
}
|
|
|
|
if(/^\#define (\w+) CARD(\d+)$/) {
|
|
$xtypeof{$1} = "CARD".$2;
|
|
$xsizeof{$1} = $2/8;
|
|
print "# processed type $1\n";
|
|
next;
|
|
}
|
|
if(/^\#define (\w+)\s+(\d+)L?\s*$/) {
|
|
$defines{$1} = $2;
|
|
print "# defined flag $1 = $2\n";
|
|
my ($s,$t) = ($1,$2);
|
|
if(/^\#define X\_/) {
|
|
$requests[$t] = $s;
|
|
print "# request $t maps to $s\n";
|
|
}
|
|
if ($eventing) {
|
|
$events[$t] = $s;
|
|
print "# event code $t maps to $s\n";
|
|
}
|
|
$eventing=0 if(/^\#define LASTEvent/);
|
|
next;
|
|
}
|
|
if(/^\#define (\w+)\s+(0x[0-9a-fA-F]+)\s*$/) {
|
|
$defines{$1} = oct($2);
|
|
print "# defined flag $1 = $2\n";
|
|
next;
|
|
}
|
|
if(/^\#define (\w+)\s+\(1L?<<(\d+)\)\s*$/) {
|
|
$defines{$1} = 2**$2;
|
|
print "# defined flag $1 = $defines{$1} (2**$2)\n";
|
|
next;
|
|
}
|
|
if(/^typedef CARD(\d+) (\w+);/) {
|
|
$xtypeof{$2} = "CARD".$1;
|
|
$xsizeof{$2} = $1/8;
|
|
print "# processed type $2\n";
|
|
next;
|
|
}
|
|
|
|
if(/^typedef struct \{/) {
|
|
&process_struct();
|
|
next;
|
|
}
|
|
if(/^typedef struct _(\w+) \{/) {
|
|
&process_struct();
|
|
next;
|
|
}
|
|
|
|
if(/^typedef (\w+) (\w+);/) {
|
|
$xtypeof{$2} = $xtypeof{$1};
|
|
$xsizeof{$2} = $xsizeof{$1};
|
|
print "# processed type $2 (alias of $1)\n";
|
|
$xalias{$2} = $1;
|
|
next;
|
|
}
|
|
|
|
# print;
|
|
}
|
|
}
|
|
|
|
# process_struct: walk XPROTO when we've got a typedef struct to work \
|
|
on
|
|
# handle some unions, filling in xsizeof and xtypeof only. skip comme\
|
|
nts
|
|
# and WORD64 code.
|
|
sub process_struct {
|
|
my($typ,$siz) = ([],0);
|
|
while(<XPROTO>) {
|
|
$incomment = &fropcomment($incomment);
|
|
if(/\#if defined\(\_\_cplusplus\) \|\| defined\(c\_plusplus\)/\
|
|
) {
|
|
while(<XPROTO>) {
|
|
last if (/\#else/);
|
|
}
|
|
}
|
|
if(/\#ifdef WORD64/) {
|
|
while(<XPROTO>) {
|
|
last if (/\#else/);
|
|
}
|
|
}
|
|
next if(/\#else/);
|
|
next if(/\#endif/);
|
|
s/ +B16//g;
|
|
s/ B32//g;
|
|
last if(/\} (\w+)\;/);
|
|
if(/union \{/) {
|
|
my($utt);
|
|
print "# handling Union\n";
|
|
while(<XPROTO>) {
|
|
local($in_union) = !defined($xtypeof{"mappingNotify"})\
|
|
;
|
|
$utt = $_;
|
|
if(/struct \{/) {
|
|
&process_struct();
|
|
}
|
|
last if($utt =~ /\} u\;/);
|
|
}
|
|
}
|
|
|
|
while(/(\w+)\s+(\w*)\,/) {
|
|
while(/(\w+)\s+(\w+)\,/) {
|
|
push(@$typ,"$1 $2");
|
|
$siz += $xsizeof{$1};
|
|
s/$2\,//;
|
|
}
|
|
last if (/(\w+)\s+(\w+)\;/);
|
|
$_ .= <XPROTO>;
|
|
s/\/\*.*\*\///g;
|
|
s/ +B16//g;
|
|
s/ B32//g;
|
|
}
|
|
if(/(\w+)\s+(\w+)\[(\d+)\]\;/) {
|
|
push(@$typ,"$1 $2 $3");
|
|
$siz += $xsizeof{$1}*$3;
|
|
}
|
|
if(/(\w+)\s+(\w+)\;/) {
|
|
push(@$typ,"$1 $2");
|
|
$siz += $xsizeof{$1};
|
|
}
|
|
}
|
|
m/\} (\w+);/;
|
|
my $t = $1;
|
|
print "# processed type $t\n";
|
|
|
|
if($t eq "xEvent") {
|
|
# xEvent is a "special" case...
|
|
# xsizeof is already set...
|
|
# and we don't really need xtypeof...
|
|
$typ = ["BYTE raw_bits 32"];
|
|
$siz = 32;
|
|
}
|
|
if($siz != $xsizeof{$t}) {
|
|
print "### mismatch: @$typ, $siz, $t, $xsizeof{$t}\n";
|
|
}
|
|
if ($in_union == 1) {
|
|
if ($t eq "u") {
|
|
if (!defined($xtypeof{"mappingNotify"})) {
|
|
print "SETTING union_u to @$typ/$siz\n";
|
|
& |
|