.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "X11::Protocol::Ext::MIT_SHM 3pm" .TH X11::Protocol::Ext::MIT_SHM 3pm "2019-08-26" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" X11::Protocol::Ext::MIT_SHM \- images in SysV style shared memory .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use X11::Protocol; \& my $X = X11::Protocol\->new; \& $X\->init_extension(\*(AqMIT\-SHM\*(Aq) \& 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, \*(AqZPixmap\*(Aq, $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 .Ve .SH "DESCRIPTION" .IX Header "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. .PP The client creates a memory segment with \f(CW\*(C`shmget()\*(C'\fR (see \*(L"shmget\*(R" in perlfunc and \*(L"SysV \s-1IPC\*(R"\s0 in perlipc) and asks the server to attach to it and then read or write with equivalents to the core GetImage and PutImage. .PP 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. .PP Byte order, padding, etc, required or generated in images is specified by the server \f(CW\*(C`$X\->{\*(Aqimage_byte_order\*(Aq}\*(C'\fR, \f(CW\*(C`$X\->{\*(Aqpixmap_formats\*(Aq}\*(C'\fR, etc, the same as for the core \f(CW\*(C`GetImage()\*(C'\fR and \f(CW\*(C`PutImage()\*(C'\fR. It's up to the client to adapt to the server's layout, which can be a bit of a chore. .SS "Shm from Perl" .IX Subsection "Shm from Perl" A shared memory segment can be created from Perl with \f(CW\*(C`shmget()\*(C'\fR, then read or write its contents with \f(CW\*(C`shmread()\*(C'\fR and \f(CW\*(C`shmwrite()\*(C'\fR. Those functions attach and detach it each time with \f(CW\*(C`shmat()\*(C'\fR and \f(CW\*(C`shmdt()\*(C'\fR system calls, which is fine for grabbing the lot but will be a bit slow for lots of little accesses. .PP \&\f(CW\*(C`IPC::SysV\*(C'\fR (version 2 up) offers a \f(CW\*(C`shmat()\*(C'\fR to keep the block attached and \f(CW\*(C`memread()\*(C'\fR and \f(CW\*(C`memwrite()\*(C'\fR to access it (see IPC::SysV). See IPC::SharedMem for an object-oriented wrapper around this too. .PP Incidentally, if \f(CW\*(C`shmget()\*(C'\fR is not available on the system then Perl's \&\f(CW\*(C`shmget()\*(C'\fR croaks. It's always possible for it to return \f(CW\*(C`undef\*(C'\fR too for not enough memory etc. With that, not being on the same machine, not having identifiable permissions, etc, there's several cases where a fallback to plain I/O will be necessary. .SS "Shm Permissions" .IX Subsection "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 \s-1UID/GID\s0 has permission to read or write. .PP The server can usually determine a client's \s-1UID/GID\s0 on a local connection such as Unix socket (X11::Protocol::Connection::UNIXSocket, and \&\f(CW\*(C`SO_PEERCRED\*(C'\fR in \fBsocket\fR\|(7)), and perhaps on a \s-1TCP\s0 localhost loopback. Failing that the server treats the client as \*(L"other\*(R" and will only attach to world-readable (or world read-writable) segments. .PP You can make a shm segment world-readable to ensure the server can read it. If the data for a PutImage etc is already from a world-readable file or is public then it shouldn't matter much who else reads the segment. Remember to ask for read-only in the \f(CW\*(C`MitShmAttach()\*(C'\fR so the server doesn't want writable too. .PP There's probably no need to risk relaxing permissions for segment writing. Chances are that if client \s-1UID/GID\s0 can't be identified then it's because the connection is not local and the server is on a different machine so shared memory can't be used anyway. .PP It's usual for the server to run as root, hence it's own permission checks, but it's also possible for the server to be an ordinary user. In that case the shm segments it can access will be limited in the usual way for the user it's running as. .SH "REQUESTS" .IX Header "REQUESTS" The following requests are available after an \f(CW\*(C`init_extension()\*(C'\fR per \&\*(L"\s-1EXTENSIONS\*(R"\s0 in X11::Protocol. .PP .Vb 1 \& my $bool = $X\->init_extension(\*(AqMIT\-SHM\*(Aq); .Ve .PP In the following \f(CW$shmid\fR is the shared memory \s-1ID\s0 (an integer) as obtained from the kernel with \f(CW\*(C`shmget()\*(C'\fR. \f(CW$shmseg\fR is an \s-1XID\s0 (allocated as usual by client \f(CW\*(C`$X\->new_rsrc()\*(C'\fR) on the server representing the server attachment to the block. .ie n .IP """($server_major, $server_minor, $uid, $gid, $shared_pixmaps, $pixmap_format) = $X\->MitShmQueryVersion ()""" 4 .el .IP "\f(CW($server_major, $server_minor, $uid, $gid, $shared_pixmaps, $pixmap_format) = $X\->MitShmQueryVersion ()\fR" 4 .IX Item "($server_major, $server_minor, $uid, $gid, $shared_pixmaps, $pixmap_format) = $X->MitShmQueryVersion ()" Return information about the MIT-SHM extension. Unlike other extensions there's no client version / server version negotiation. .Sp \&\f(CW$server_major\fR and \f(CW$server_minor\fR are the extension version number implemented by the server. .Sp \&\f(CW$uid\fR and \f(CW$gid\fR (integers) are the server's effective user \s-1ID\s0 and group \&\s-1ID\s0 (\f(CW\*(C`geteuid()\*(C'\fR and \f(CW\*(C`getegid()\*(C'\fR). Zero means root. .Sp \&\f(CW$shared_pixmaps\fR is non-zero if pixmaps in shared memory are supported (see \f(CW\*(C`MitShmCreatePixmap()\*(C'\fR below). \f(CW$pixmap_format\fR (an ImageFormat) is \&\*(L"XYPixmap\*(R" or \*(L"ZPixmap\*(R" for the layout required in such a pixmap. .ie n .IP """$X\->MitShmAttach ($shmseg, $shmid, $readonly)""" 4 .el .IP "\f(CW$X\->MitShmAttach ($shmseg, $shmid, $readonly)\fR" 4 .IX Item "$X->MitShmAttach ($shmseg, $shmid, $readonly)" Attach the server to a given shared memory segment. \f(CW$shmseg\fR is a new \s-1XID\s0 to represent the attached memory. .Sp .Vb 2 \& my $shmseg = $X\->new_rsrc; \& $X\->MitShmAttach ($shmseg, $shmid, 0); # read/write .Ve .Sp \&\f(CW$shmid\fR is the shared memory \s-1ID\s0 to attach, as obtained from \f(CW\*(C`shmget()\*(C'\fR (see \*(L"shmget\*(R" in perlfunc). .Sp \&\f(CW$readonly\fR is 1 to have the server attach read-only, or 0 for read-write. Read-only suffices for \f(CW\*(C`MitShmPutImage()\*(C'\fR, but read-write is needed for \&\f(CW\*(C`MitShmGetImage()\*(C'\fR and \f(CW\*(C`MitShmCreatePixmap()\*(C'\fR. .ie n .IP """$X\->MitShmDetach ($shmseg)""" 4 .el .IP "\f(CW$X\->MitShmDetach ($shmseg)\fR" 4 .IX Item "$X->MitShmDetach ($shmseg)" Detach the server from shared memory \f(CW$shmseg\fR (an \s-1XID\s0) and release that \&\s-1XID.\s0 .Sp .Vb 1 \& $X\->MitShmDetach ($shmseg); .Ve .ie n .IP """$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)""" 4 .el .IP "\f(CW$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)\fR" 4 .IX Item "$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)" Put image data from \f(CW$shmseg\fR (an \s-1XID\s0) to \f(CW$drawable\fR. The parameters are similar to the core \f(CW\*(C`PutImage()\*(C'\fR. .Sp \&\f(CW$depth\fR is the depth of the image. For \f(CW$format\fR \*(L"Bitmap\*(R" this must be 1 and the foreground and background colours of \f(CW$gc\fR are then drawn. For \&\f(CW$format\fR \*(L"XYPixmap\*(R" and \*(L"ZPixmap\*(R" \f(CW$depth\fR must be the depth of \&\f(CW$drawable\fR. .Sp \&\f(CW$total_width\fR,\f(CW$total_height\fR is the full size of the image in the shared memory. \f(CW$src_x\fR,\f(CW$src_y\fR and \f(CW$src_width\fR,\f(CW$src_height\fR are the portion of it to draw. \f(CW$dst_x\fR,\f(CW$dst_y\fR is where in \f(CW$drawable\fR to put it. .Sp \&\f(CW$format\fR is \*(L"Bitmap\*(R", \*(L"XYPixmap\*(R" or \*(L"ZPixmap\*(R" (an ImageFormat). .Sp \&\f(CW$send_event\fR is 1 to have an \f(CW\*(C`MitShmCompletionEvent\*(C'\fR sent to the client when drawing is finished (see \*(L"\s-1EVENTS\*(R"\s0 below), or 0 if that's not wanted. .Sp \&\f(CW$offset\fR is a byte offset into the shared memory where the image starts. .ie n .IP """($depth, $visual, $size) = $X\->MitShmGetImage ($drawable, $x, $y, $width, $height, $planemask, $format, $shmseg, $offset)""" 4 .el .IP "\f(CW($depth, $visual, $size) = $X\->MitShmGetImage ($drawable, $x, $y, $width, $height, $planemask, $format, $shmseg, $offset)\fR" 4 .IX Item "($depth, $visual, $size) = $X->MitShmGetImage ($drawable, $x, $y, $width, $height, $planemask, $format, $shmseg, $offset)" Copy an image from \f(CW$drawable\fR to shared memory \f(CW$shmseg\fR (an \s-1XID\s0). The parameters are similar to the core \f(CW\*(C`GetImage()\*(C'\fR. .Sp \&\f(CW$x\fR,\f(CW$y\fR, \f(CW$width\fR,\f(CW$height\fR are the part of \f(CW$drawable\fR to get. \&\f(CW$planemask\fR is a bit mask for which bit planes of the pixels are wanted. .Sp \&\f(CW$format\fR is \*(L"XYPixmap\*(R" or \*(L"ZPixmap\*(R" for the layout to be written to the shared memory, and \f(CW$offset\fR is a byte offset into the memory where the image should start. .Sp The returned \f(CW$depth\fR (an integer) is the depth of \f(CW$drawable\fR. \&\f(CW$visual\fR (integer \s-1ID\s0) is its visual for a window, or \*(L"None\*(R" for a pixmap. \&\f(CW$size\fR is how many bytes were written. .Sp \&\f(CW$shmseg\fR must be attached read-write in the \f(CW\*(C`MitShmAttach()\*(C'\fR or an \&\f(CW\*(C`Access\*(C'\fR error results. .ie n .IP """$X\->MitShmCreatePixmap ($pixmap, $drawable, $depth, $width, $height, $shmseg, $offset)""" 4 .el .IP "\f(CW$X\->MitShmCreatePixmap ($pixmap, $drawable, $depth, $width, $height, $shmseg, $offset)\fR" 4 .IX Item "$X->MitShmCreatePixmap ($pixmap, $drawable, $depth, $width, $height, $shmseg, $offset)" Create \f(CW$pixmap\fR (a new \s-1XID\s0) as a pixmap with contents in shared memory \&\f(CW$shmseg\fR (an \s-1XID\s0). When the client reads or writes that memory it changes the pixmap contents. The parameters are similar to the core \&\f(CW\*(C`CreatePixmap()\*(C'\fR. .Sp .Vb 7 \& 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 .Ve .Sp The \f(CW\*(C`MitShmQueryVersion()\*(C'\fR request above reports whether shared memory pixmaps are supported, and if so whether they're \*(L"XYPixmap\*(R" or \*(L"ZPixmap\*(R" layout. .Sp \&\f(CW$drawable\fR is used to determine the screen for the new \f(CW$pixmap\fR. \&\f(CW$offset\fR is a byte offset into the shared memory where the pixmap data will begin. .Sp If damage objects from the \s-1DAMAGE\s0 extension (see X11::Protocol::Ext::DAMAGE) are monitoring a shared \f(CW$pixmap\fR then client writes to the shared memory generally don't produce \f(CW\*(C`DamageNotify\*(C'\fR events. The client can use \f(CW\*(C`DamageAdd()\*(C'\fR requests (in Damage version 1.1) to tell the server about changes made, which it will broadcast to interested damage objects. It's probably unusual to have damage objects listening to a shared pixmap though. .SH "EVENTS" .IX Header "EVENTS" \&\f(CW\*(C`MitShmCompletionEvent\*(C'\fR is sent to the client when requested in an \&\f(CW\*(C`MitShmPutImage()\*(C'\fR. It says the server has finished reading the memory. The event has the usual fields .PP .Vb 4 \& name "MitShmCompletionEvent" \& synthetic true if from a SendEvent \& code integer opcode \& sequence_number integer .Ve .PP and event-specific fields .PP .Vb 5 \& 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 code \& minor_opcode integer, 3 for MitShmPutImage .Ve .PP \&\f(CW\*(C`major_opcode\*(C'\fR and \f(CW\*(C`minor_opcode\*(C'\fR are the codes of the originating \&\f(CW\*(C`MitShmPutImage()\*(C'\fR. These fields are similar to the core \&\f(CW\*(C`GraphicsExposure\*(C'\fR and \f(CW\*(C`NoExposure\*(C'\fR events, but here there's only one request (\f(CW\*(C`MitShmPutImage()\*(C'\fR) which gives a completion event. .SH "ERRORS" .IX Header "ERRORS" Error type \*(L"ShmSeg\*(R" is a bad \f(CW$shmseg\fR resource \s-1XID\s0 in a request. .SH "SEE ALSO" .IX Header "SEE ALSO" X11::Protocol, \&\*(L"shmget\*(R" in perlfunc, \&\*(L"SysV \s-1IPC\*(R"\s0 in perlipc, IPC::SysV, IPC::SharedMem .PP X11::Protocol::Ext::Damage .PP \&\fI/usr/share/doc/x11proto\-xext\-dev/shm.txt.gz\fR, \&\fI/usr/share/X11/doc/hardcopy/Xext/mit\-shm.PS.gz\fR, \&\fIftp://ftp.xfree86.org/pub/mirror/X.Org/pub/R6.6/xc/doc/hardcopy/Xext/mit\-shm.PS.gz\fR .SH "HOME PAGE" .IX Header "HOME PAGE" .SH "LICENSE" .IX Header "LICENSE" Copyright 2011 Kevin Ryde .PP X11\-Protocol\-Other is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP X11\-Protocol\-Other is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with X11\-Protocol\-Other. If not, see .