MIT-SHM

XShmQueryExtension拡張機能が使用できるか
XShmQueryVersion拡張機能のバージョンを取得
XShmGetEventBase拡張機能のイベントのベース値を取得
ShmCompletion イベントXShmPutImage で書き込みが完了した
共有メモリ XImage
XShmCreateImage共有メモリ XImage を作成
XShmAttach共有メモリセグメントをアタッチ
XShmDetach共有メモリセグメントをデタッチ
XShmPutImage共有メモリ XImage を Drawable に書き込み
XShmGetImageDrawable のイメージを取得
共有メモリ Pixmap
XShmPixmapFormat共有メモリ Pixmap の形式を返す
XShmCreatePixmap共有メモリ Pixmap を作成
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>

-lXext
Bool XShmQueryExtension(Display *display);
拡張機能が使用できるか
Bool XShmQueryVersion(Display *display, int *major, int *minor, Bool *pixmaps);
拡張機能のバージョンを取得
major,minor
実際に使用できるバージョンを返す
pixmaps
共有メモリ Pixmap がサポートされているかを返す
戻り値
拡張機能が使用できる場合 True
int XShmGetEventBase(Display *dpy);
拡張機能のイベントのベース値を取得。

返った値 + ShmCompletion が、イメージを書き込んだ後の完了イベント。
typedef struct {
    int type;
    unsigned long serial;
    Bool send_event;
    Display *display;
    Drawable drawable;     /* 描画先 */
    int major_code;        /* ShmReqCode */
    int minor_code;        /* X_ShmPutImage */
    ShmSeg shmseg;         /* リソースID */
    unsigned long offset;  /* 使用される ShmSeg へのオフセット */
} XShmCompletionEvent;
XShmPutImage で書き込みが完了した時に来る。
共有メモリ XImage
XImage *XShmCreateImage(Display *display, Visual *visual, unsigned int depth, int format,
    char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);

typedef struct {
    ShmSeg shmseg;    /* リソースID */
    int shmid;        /* 共有メモリID */
    char *shmaddr;    /* アドレス */
    Bool readOnly;    /* 読み込み専用 */
} XShmSegmentInfo;
共有メモリ XImage を作成。

  1. XShmCreateImage で XImage 構造体を作成
  2. 画像データを保存するための共有メモリセグメントを作成。

    //共有メモリを作り、識別子を取得。負の値で失敗
    shminfo.shmid = shmget(IPC_PRIVATE,
        image->bytes_per_line * image->height, IPC_CREAT|0777);
    
    //共有メモリをプロセスのアドレス空間にアタッチ
    shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
    //書き込み可にする
    shminfo.readOnly = False;
  3. XShmAttach で、共有メモリセグメントに接続するよう X サーバーに通知
  4. 通常の XImage と同じように、共有メモリ XImage を使用する

削除する時は以下の順で行う。

XShmDetach(display, shminfo);
XDestroyImage(image);
//共有メモリをプロセスのアドレス空間から切り離す
shmdt(shminfo.shmaddr);
//共有メモリの解放
shmctl(shminfo.shmid, IPC_RMID, 0);
format
XYBitmap, XYPixmap, ZPixmap
data
共有メモリセグメントをあらかじめ割り当てている場合は、そのポインタ。通常は NULL で良い。
shminfo
構造体を用意してポインタを渡す。
XImage の obdata にポインタがセットされるだけなので、この構造体は初期化しておく必要はない。
Bool XShmAttach(Display *dpy, XShmSegmentInfo *shminfo);
共有メモリセグメントをアタッチ
Bool XShmDetach(Display *dpy, XShmSegmentInfo *shminfo);
共有メモリセグメントをデタッチ
Bool XShmPutImage(Display *display, Drawable d, GC gc, XImage *image,
    int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, Bool send_event);
共有メモリ XImage を Drawable に書き込み
send_event
True の場合、X サーバーはイメージの書き込みが完了したときに完了イベントを生成します。
このイベントを受け取った後なら、プログラムは共有メモリセグメントを操作しても安全である。
Status XShmGetImage(Display *display, Drawable d, XImage *image, int x, int y, unsigned long plane_mask);
Drawable のイメージを取得する。
d の (x,y) から image のサイズ分の範囲を取得する。
x,y
d のオフセット位置
plane_mask
対象のプレーン
共有メモリ Pixmap
int XShmPixmapFormat(Display *display);
共有メモリ Pixmap は、XYPixmap または ZPixmap の形式のみをサポートします。
スクリーンの深さには依存せず、スクリーンにも依存しません。
X サーバーがサポートしている形式を返します。
Pixmap XShmCreatePixmap(Display *display, Drawable d, char *data, XShmSegmentInfo *shminfo,
    unsigned int width, unsigned int height, unsigned int depth);
共有メモリ Pixmap を作成する。

ZPixmap の場合、Y1行のバイトサイズは、BitmapPad(display) で取得したビット単位にすること。
data
共有メモリセグメントへのポインタ。
shminfo.shmaddr フィールドと同じであること。
戻り値
共有メモリセグメントを切り離した後、XFreePixmap で解放する。