X11: ディスプレイの情報

ディスプレイの情報
XOpenDisplay() から返された Display 構造体には、X サーバーの情報が入っています。

X11/Xlib.h には、Display 構造体の中身が定義されているので、直接値を参照しようと思えばできますが、通常は Xlib.h で定義されたマクロか関数を使ってください。
プログラム
ディスプレイ、スクリーン、イメージに関する情報を表示するプログラムです。

<02-dispinfo.c>
#include <stdio.h>
#include <X11/Xlib.h>

int main(int argc,char **argv)
{
    Display *d;
    Screen *s;
    XPixmapFormatValues *pixf;
    int i,cnt,*narr;
    
    d = XOpenDisplay(NULL);
    if(!d) return 1;

    printf("ConnectionNumber: %d\n", ConnectionNumber(d));
    printf("DefaultRootWindow(XID): %lu\n", DefaultRootWindow(d));
    printf("DefaultScreen: %d\n", DefaultScreen(d));
    printf("DisplayString: '%s'\n", DisplayString(d));
    printf("LastKnownRequestProcessed: %lu\n", LastKnownRequestProcessed(d));
    printf("NextRequest: %lu\n", NextRequest(d));
    printf("ProtocolVersion: %d\n", ProtocolVersion(d));
    printf("ProtocolRevision: %d\n", ProtocolRevision(d));
    printf("QLength: %d\n", QLength(d));
    printf("ScreenCount: %d\n", ScreenCount(d));
    printf("ServerVendor: '%s'\n", ServerVendor(d));
    printf("VendorRelease: 0x%x\n", VendorRelease(d));

    //screen

    s = DefaultScreenOfDisplay(d);

    printf("\n[screen]\n");
    printf("BlackPixelOfScreen: 0x%lx\n", BlackPixelOfScreen(s));
    printf("WhitePixelOfScreen: 0x%lx\n", WhitePixelOfScreen(s));
    printf("CellsOfScreen: %d\n", CellsOfScreen(s));
    printf("DefaultColormapOfScreen(XID): %lu\n", DefaultColormapOfScreen(s));
    printf("DefaultDepthOfScreen: %d\n", DefaultDepthOfScreen(s));
    printf("DoesBackingStore: %d\n", DoesBackingStore(s));
    printf("DoesSaveUnders: %d\n", DoesSaveUnders(s));
    printf("EventMaskOfScreen: 0x%lx\n", EventMaskOfScreen(s));
    printf("WidthOfScreen: %d\n", WidthOfScreen(s));
    printf("HeightOfScreen: %d\n", HeightOfScreen(s));
    printf("WidthMMOfScreen: %d\n", WidthMMOfScreen(s));
    printf("HeightMMOfScreen: %d\n", HeightMMOfScreen(s));
    printf("MaxCmapsOfScreen: %d\n", MaxCmapsOfScreen(s));
    printf("MinCmapsOfScreen: %d\n", MinCmapsOfScreen(s));
    printf("PlanesOfScreen: %d\n", PlanesOfScreen(s));
    printf("RootWindowOfScreen(XID): %lu\n", RootWindowOfScreen(s));

    //使用可能な深さ

    narr = XListDepths(d, DefaultScreen(d), &cnt);
    if(narr)
    {
        printf("\n[depths]\n");
        
        for(i = 0; i < cnt; i++)
            printf("%d,", narr[i]);

        printf("\n");
        
        XFree(narr);
    }

    //イメージフォーマット

    printf("\n[image]\n");

    printf("ImageByteOrder: %d\n", ImageByteOrder(d));
    printf("BitmapUnit: %d\n", BitmapUnit(d));
    printf("BitmapBitOrder: %d\n", BitmapBitOrder(d));
    printf("BitmapPad: %d\n", BitmapPad(d));

    pixf = XListPixmapFormats(d, &cnt);
    if(pixf)
    {
        printf("\n[ListPixmapFormats]\n");
        
        for(i = 0; i < cnt; i++)
        {
            printf("depth: %d, bits_per_pixel:%d, scanline_pad:%d\n",
                pixf[i].depth, pixf[i].bits_per_pixel, pixf[i].scanline_pad);
        }

        printf("\n");
    
        XFree(pixf);
    }

    //閉じる

    XCloseDisplay(d);

    return 0;
}
実行結果
ConnectionNumber: 3
DefaultRootWindow(XID): 1892
DefaultScreen: 0
DisplayString: ':0'
LastKnownRequestProcessed: 6
NextRequest: 7
ProtocolVersion: 11
ProtocolRevision: 0
QLength: 0
ScreenCount: 1
ServerVendor: 'The X.Org Foundation'
VendorRelease: 0xb8a590

[screen]
BlackPixelOfScreen: 0x0
WhitePixelOfScreen: 0xffffff
CellsOfScreen: 256
DefaultColormapOfScreen(XID): 32
DefaultDepthOfScreen: 24
DoesBackingStore: 1
DoesSaveUnders: 0
EventMaskOfScreen: 0x7a003f
WidthOfScreen: 1920
HeightOfScreen: 1080
WidthMMOfScreen: 508
HeightMMOfScreen: 285
MaxCmapsOfScreen: 1
MinCmapsOfScreen: 1
PlanesOfScreen: 24
RootWindowOfScreen(XID): 1892

[depths]
24,1,4,8,15,16,32,

[image]
ImageByteOrder: 0
BitmapUnit: 32
BitmapBitOrder: 0
BitmapPad: 32

[ListPixmapFormats]
depth: 1, bits_per_pixel:1, scanline_pad:32
depth: 4, bits_per_pixel:8, scanline_pad:32
depth: 8, bits_per_pixel:8, scanline_pad:32
depth: 15, bits_per_pixel:16, scanline_pad:32
depth: 16, bits_per_pixel:16, scanline_pad:32
depth: 24, bits_per_pixel:32, scanline_pad:32
depth: 32, bits_per_pixel:32, scanline_pad:32
ディスプレイ情報
基本的なディスプレイ情報を取得するためのマクロです。

ConnectionNumber(disp)ディスプレイの接続番号。
Linux などでは、ファイルディスクリプタです。
DefaultRootWindow(disp)デフォルトのスクリーンのルートウィンドウ ID
DefaultScreen(disp)XOpenDisplay() によって指定された、デフォルトのスクリーン番号
DisplayString(disp)XOpenDisplay() に渡された文字列
LastKnownRequestProcessed(disp)X サーバーによって処理された最後のリクエスト (クライアントから送られてきた要求) の、シリアル番号。
リクエストを受け取るごとに加算される。
NextRequest(disp)次に来るリクエストに使用されるシリアル番号
ProtocolVersion(disp)X プロトコルの、メジャーバージョン番号
ProtocolRevision(disp)X サーバーのマイナーリビジョン番号
QLength(disp)現在のイベントキューの長さ
ScreenCount(disp)利用可能なスクリーンの数
ServerVendor(disp)X サーバー実装の所有者の文字列
VendorRelease(disp)X サーバーのベンダーのリリースに関連する番号
スクリーン情報
X における「スクリーン」とは、モニタの画面のことです。
一つの X ディスプレイに対して、複数のスクリーンを含めることができます。

スクリーンの情報は、Screen 構造体で定義されています。
Display 構造体の中に、Screen 構造体の配列のポインタがあるので、そこから、スクリーンのインデックス番号を使って参照することができます。

デフォルトのスクリーン番号は、XOpenDisplay() 時に指定でき、DefaultScreen マクロまたは XDefaultScreen 関数で取得できます。
モニタが1つしかない場合は、スクリーンは1つなので、スクリーン番号は 0 のみ使用できます。

Xlib では、Display とスクリーン番号から情報を取得する関数/マクロと、Screen 構造体のポインタから情報を取得する関数/マクロがあります。

以下は、Screen 構造体から値を取得するマクロです。

BlackPixelOfScreen(screen)黒を示すピクセル値
WhitePixelOfScreen(screen)白を示すピクセル値
CellsOfScreen(screen)デフォルトのカラーマップ内のカラーマップセルの数
DefaultColormapOfScreen(screen)デフォルトのカラーマップ ID
DefaultDepthOfScreen(screen)ルートウィンドウの深さ (ビット数)
DoesBackingStore(screen)スクリーンがバッキングストアをサポートしているかどうか。
(ウィンドウの描画内容を保持する機能をサポートしているか)。
NotUseful (0), WhenMapped (1), Always (2)
DoesSaveUnders(screen)セーブアンダーをサポートしているか (Bool)。
ウィンドウが他のウィンドウの下に隠れた時、描画内容を保持する機能をサポートしているか。
EventMaskOfScreen(screen)X サーバーに接続された時の、ルートウィンドウのイベントマスク
WidthOfScreen(screen)画面の幅 (px)
HeightOfScreen(screen)画面の高さ (px)
WidthMMOfScreen(screen)画面の幅 (mm)
HeightMMOfScreen(screen)画面の高さ (mm)
MaxCmapsOfScreen(screen)スクリーンがインストールできるカラーマップの最大数
MinCmapsOfScreen(screen)スクリーンがインストールできるカラーマップの最小数
PlanesOfScreen(screen)ルートウィンドウのプレーン数
RootWindowOfScreen(screen)ルートウィンドウの ID
ルートウィンドウ
X サーバーによって、各スクリーンごとに、1つのルートウィンドウが作成されています。

ルートウィンドウは、最上位のウィンドウにあたり、画面全体を覆っているウィンドウです。一番背面に表示されます。

通常のウィンドウ (トップレベルウィンドウ) は、ルートウィンドウの子として作成します。
XListDepths 関数
XListDepths 関数を使うと、指定したスクリーンで利用できる、イメージの深さのリストを取得できます。

int *XListDepths(Display *display, int screen_number, int *count_return);

戻り値の配列は、XFree() で解放します。

24,1,4,8,15,16,32

深さはビット数と同じなので、上記の結果であれば、24bit, 1bit, ... 32bit の深さを使用できることになります。
XImage 情報
XImage は、直接バッファを操作できるイメージです。
XImage のフォーマットに関する値を取得できます。

ImageByteOrder(disp)複数バイトの整数値におけるバイト並び。
LSBFirst (0) : 下位バイトから順
MSBFirst (1) : 上位バイトから順
BitmapUnit(disp)XYBitmap 形式において、各 1bit のピクセルが、このビット単位の整数値でパックされる。
BitmapBitOrder(disp)整数値内のビット並び。
LSBFirst または MSBFirst
BitmapPad(disp)スキャンラインのビット単位 (8, 16, 32)
XListPixmapFormats 関数
XListPixmapFormats 関数を使うと、指定されたディスプレイでサポートされている、ZPixmap 形式のイメージの情報を配列で取得できます。

XPixmapFormatValues *XListPixmapFormats(Display *display, int *count_return);

typedef struct {
  int depth; //実際に色として使われるビット数
  int bits_per_pixel; //1px あたりのバッファ上のビット数
  int scanline_pad;   //スキャンラインのビット単位
} XPixmapFormatValues;

戻り値の配列は、XFree() で解放します。