NAME
X11::Protocol::Ext::MIT_SHM - ...
SYNOPSIS
use X11::Protocol;
my $X = X11::Protocol->new;
$X->init_extension('MIT-SHM')
or print "MIT-SHM extension not available";
use IPC::SysV;
my $shmid = shmget (IPC::SysV::IPC_PRIVATE(),
100000, # bytes
IPC::SysV::IPC_CREAT() | 0666);
my $shmseg = $X->new_rsrc;
$X->MitShmAttach ($shmseg, $shmid, 0);
my ($depth, $visual, $size) = $X->MitShmGetImage
($window, 0,0, 16,16, ~0, 'ZPixmap', $shmseg, 0);
my $image_bytes;
shmread ($shmid, $image_bytes, 0, 16*16*$bpp) || die "$!";
# $image_bytes is the top-left 16x16 pixels of the screen
DESCRIPTION
The MIT-SHM extension allows a client and server running on the same machine to transfer image data through System-V shared memory segments.
The client creates a memory segment with shmget()
(see "shmget" in perlfunc and "SysV IPC" in perlipc) and asks the server to attach to it and then read or write with equivalents to the core GetImage and PutImage.
The aim is to avoid sending large images through the I/O connection when on the same machine. Memory is faster, and may help avoid request size limits for very big images.
Byte order, padding, etc, required or generated in images is specified by the server $X->{'image_byte_order'}
, $X->{'pixmap_formats'}
, etc, the same as for the core GetImage
and PutImage
. It's up to the client to adapt to the server's layout, which can be a bit of a chore.
Shm Permissions
A SysV shared memory segment has owner/group/other permission bits similar to a file. The server will only attach to segments which the requesting client UID/GID has permission to read or write.
The server can usually determine a client's UID/GID for local I/O such as Unix sockets (see X11::Protocol::Connection::UNIXSocket, and SO_PEERCRED
in socket(7)), and perhaps TCP localhost loopback. Failing that the server treats the client as an "other" and will only attach to world-readable (or read-writable) segments.
If a PutImage comes from a world-readable file or is public anyway then permissions 0644 on the memory segment will guarantee the server can read it, no matter what UID/GID it can identify. Remember to ask for read-only in the MitShmAttach
in that case so the server doesn't demand writable too. But chances are if the connection is not a local transport with identifiable UID/GID then the server is probably on a different machine anyway and shared memory can't be used.
Shm from Perl
A shared memory segment can be created from Perl with shmget()
then read or write its contents with shmread()
and shmwrite()
. Those functions attach and detach it each time with shmat()
and shmdt()
system calls, which is fine for grabbing the lot, but will be a bit slow for lots of little accesses.
IPC::SysV
offers a shmat()
to keep the block attached and memread()
and memwrite()
to access it (see IPC::SysV). See IPC::SharedMem for an object-oriented wrapper around this too.
Incidentally, if shmget
is not available on the system then Perl's shmget()
croaks, and it's always possible for it to return undef
when not enough memory etc. Between that, not being on the same machine, not having identifiable perms, etc, there's a quite a few cases where a fallback to plain I/O will be necessary.
REQUESTS
The following requests are made available with an init_extension()
per "EXTENSIONS" in X11::Protocol.
my $bool = $X->init_extension('MIT-SHM');
In the following $shmid
is the shared memory ID as obtained from the kernel with shmget()
. $shmseg
is an XID, allocated as usual by client $X->new_rsrc()
, on the server representing the server attachment to the block.
-
Return information about the MIT-SHM extension. Unlike other extensions there's no client version vs server version negotiation.
$server_major
and$server_minor
are the extension version number implemented by the server.$uid
and$gid
(integers) are the server's effective user ID and group ID (geteuid()
andgetegid()
). Zero means root.$shared_pixmaps
is non-zero if pixmaps in shared memory are supported (seeMitShmCreatePixmap
below).$pixmap_format
(an ImageFormat) is "XYPixmap" or "ZPixmap" for the layout required in a shared memory pixmap. $X->MitShmAttach ($shmseg, $shmid, $readonly)
-
Attach the server to a given shared memory segment.
$shmseg
is a new XID representing the attached memory.my $shmseg = $X->new_rsrc; $X->MitShmAttach ($shmseg, $shmid, 0); # read/write
$shmid
is the shared memory ID to attach, as obtained fromshmget()
(see "shmget" in perlfunc).$readonly
is 1 to have the server attach read-only, or 0 for read-write. Read-only suffices forMitShmPutImage
, or read-write is needed forMitShmGetImage
andMitShmCreatePixmap
. $X->MitShmDetach ($shmseg)
-
Detach the server from shared memory
$shmseg
(an XID) and release that XID.$X->MitShmDetach ($shmseg);
$X->MitShmPutImage ($drawable, $gc, $depth, $total_width, $total_height, $src_x, $src_y, $src_width, $src_height, $dst_x, $dst_y, $format, $send_event, $shmseg, $offset)
-
Draw an image from
$shmseg
(an XID) into$drawable
. The parameters are similar to the corePutImage
.$depth
is the depth of the image. For$format
"Bitmap" it must be 1 and the foreground and background colours of$gc
are then drawn. For$format
"XYPixmap" and "ZPixmap" it must be the depth of$drawable
.$total_width
,$total_height
is the full size of the image in the shared memory.$src_x
,$src_y
and$src_width
,$src_height
are the portion of it to draw.$dst_x
,$dst_y
is where in$drawable
to put it.$format
is "Bitmap", "XYPixmap" or "ZPixmap" (an ImageFormat).$send_event
is 1 to have anMitShmCompletionEvent
sent to the client when drawing is finished (see "EVENTS" below), or 0 if that's not wanted.$offset
is a byte offset into the shared memory where the image starts. ($depth, $visual, $size) = $X->MitShmGetImage ($drawable, $x, $y, $width, $height, $planemask, $format, $shmseg, $offset)
-
Copy an image from
$drawable
to shared memory$shmseg
(an XID). The parameters are similar to the coreGetImage
.$x
,$y
,$width
,$height
are the part of$drawable
to get.$planemask
is a bit mask for which bit planes of the pixels are wanted.$format
is "XYPixmap" or "ZPixmap" for the layout to be written to the shared memory, and$offset
is a byte offset into the memory where the image should start.The returned
$depth
(an integer) is the depth of$drawable
.$visual
(integer ID) is its visual for a window, or "None" for a pixmap.$size
is how many bytes were written.$shmseg
must be attached read-write inMitShmAttach
or an Access error results. $X->MitShmCreatePixmap ($pixmap, $drawable, $depth, $width, $height, $shmseg, $offset)
-
Create
$pixmap
(a new XID) as a pixmap with contents in shared memory$shmseg
(an XID). When the client reads or writes that memory it changes the pixmap contents. The parameters are similar to the coreCreatePixmap
.my $pixmap = $X->new_rsrc; $X->MitShmCreatePixmap ($pixmap, # new XID $X->root, # for the screen $X->root_depth, # depth 10,10, # width,height $shmseg, 0); # byte offset into shm
MitShmQueryVersion
above reports whether shared memory pixmaps are supported, and if so whether they're "XYPixmap" or "ZPixmap" layout.$drawable
is used to determine the screen for$pixmap
and can be any drawable on the screen.$offset
is a byte offset into the shared memory where the pixmap data will begin.If any damage objects from the DAMAGE extension (see X11::Protocol::Ext::DAMAGE) monitoring the shared
$pixmap
then changes made through the shared memory generally don't produceDamageNotify
events from those objects. Listening for damage on a shared pixmap might be unlikely, but explicitDamageAdd
(in Damage version 1.1) requests can tell the server about changes, when ready, and if necessary.
EVENTS
MitShmCompletionEvent
is sent to the client when requested in an MitShmPutImage
, to say memory access for the put is finished. The event has the usual fields
name "MitShmCompletionEvent"
synthetic true if from a SendEvent
code integer opcode
sequence_number integer
and event-specific fields
drawable XID, target as from request
shmseg XID, source as from request
offset integer, byte offset as from request
major_opcode integer, MIT-SHM extension start
minor_opcode integer, 3==MitShmPutImage
major_opcode
and minor_opcode
are the codes of the originating MitShmPutImage
. They're similar to the core GraphicsExposure
and NoExposure
events, though here there's only one request (MitShmPutImage
) which gives a completion event so they're hardly needed.
ERRORS
Error type "ShmSeg" is a bad $shmseg
resource XID in a request.
SEE ALSO
X11::Protocol, "shmget" in perlfunc, "SysV IPC" in perlipc), IPC::SysV, IPC::SharedMem
HOME PAGE
http://user42.tuxfamily.org/x11-protocol-other/index.html
LICENSE
Copyright 2011 Kevin Ryde
X11-Protocol-Other is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
X11-Protocol-Other is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with X11-Protocol-Other. If not, see <http://www.gnu.org/licenses/>.