137 lines
3.8 KiB
C
137 lines
3.8 KiB
C
/*
|
|
* A small but pointer-heavy Xlib client, used only to measure what
|
|
* bit-addressed pointers do to LLVM IR.
|
|
*
|
|
* It deliberately touches:
|
|
* - Display->screens[] and Screen->root_visual, root, default_gc
|
|
* - XImage->data and the XImage->f.put_pixel function pointer
|
|
* - XEvent->xkey.display and XEvent->xkey.keycode
|
|
* - XTextProperty.value and XClassHint.res_name/res_class
|
|
* - char * arithmetic over a scanline
|
|
* - a struct copy (llvm.memcpy) and an indirect call
|
|
*/
|
|
#include "xlib_min.h"
|
|
|
|
_Static_assert(sizeof(void *) == 4, "spike wants 32-bit pointers");
|
|
_Static_assert(sizeof(long) == 4, "TI long is 32 bits");
|
|
_Static_assert(sizeof(int) == 4, "TI int is 32 bits");
|
|
_Static_assert(sizeof(char) == 1, "TI char is 8 bits");
|
|
|
|
static void pattern(char *data, int bpl, int w, int h)
|
|
{
|
|
int x, y;
|
|
|
|
memset(data, 0, (unsigned long)bpl * h);
|
|
for (y = 0; y < h; y++) {
|
|
char *row = data + y * bpl;
|
|
for (x = 0; x < w; x++)
|
|
row[x >> 3] |= (char)(1 << (x & 7));
|
|
}
|
|
}
|
|
|
|
static int handle(Display *dpy, XEvent *ev)
|
|
{
|
|
char buf[8];
|
|
KeySym ks;
|
|
|
|
switch (ev->type) {
|
|
case Expose:
|
|
return ev->xexpose.width * ev->xexpose.height;
|
|
case KeyPress:
|
|
XLookupString(&ev->xkey, buf, sizeof buf, &ks, 0);
|
|
if (ev->xkey.display != dpy)
|
|
return -1;
|
|
return (int)ev->xkey.keycode + buf[0] + (int)ks;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
Display *dpy;
|
|
int scr, w = 640, h = 480, bpl;
|
|
Window root, win;
|
|
Visual *vis;
|
|
GContext gc;
|
|
XImage *img;
|
|
XEvent ev, copy;
|
|
XTextProperty tp;
|
|
XClassHint ch;
|
|
XSizeHints hints;
|
|
XSetWindowAttributes attrs;
|
|
char *data;
|
|
char **list;
|
|
int count, i;
|
|
|
|
dpy = XOpenDisplay(argc > 1 ? argv[1] : "0:0");
|
|
if (!dpy)
|
|
return 1;
|
|
|
|
scr = DefaultScreen(dpy);
|
|
root = RootWindow(dpy, scr);
|
|
vis = DefaultVisual(dpy, scr);
|
|
gc = DefaultGC(dpy, scr);
|
|
|
|
attrs.background_pixel = WhitePixel(dpy, scr);
|
|
attrs.border_pixel = BlackPixel(dpy, scr);
|
|
attrs.colormap = 0;
|
|
win = XCreateWindow(dpy, root, 20, 20, (unsigned)w, (unsigned)h, 0,
|
|
DefaultDepth(dpy, scr), 1, vis, 0L, &attrs);
|
|
win = XCreateSimpleWindow(dpy, root, 20, 20, (unsigned)w, (unsigned)h, 0,
|
|
BlackPixel(dpy, scr), WhitePixel(dpy, scr));
|
|
XStoreName(dpy, win, "bit-address spike");
|
|
XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask);
|
|
XMapWindow(dpy, win);
|
|
|
|
bpl = ((w + 31) / 32) * 4;
|
|
data = malloc((unsigned long)bpl * h);
|
|
if (!data)
|
|
return 1;
|
|
pattern(data, bpl, w, h);
|
|
|
|
img = XCreateImage(dpy, vis, (unsigned)DefaultDepth(dpy, scr), ZPixmap, 0,
|
|
data, (unsigned)w, (unsigned)h, 32, bpl);
|
|
if (!img)
|
|
return 1;
|
|
img->byte_order = LSBFirst;
|
|
img->bitmap_bit_order = LSBFirst;
|
|
img->f.put_pixel(img, 3, 4, 1);
|
|
XPutImage(dpy, win, gc, img, 0, 0, 0, 0, (unsigned)w, (unsigned)h);
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
XNextEvent(dpy, &ev);
|
|
copy = ev;
|
|
count = handle(dpy, ©);
|
|
if (count < 0)
|
|
break;
|
|
}
|
|
|
|
if (XGetWMName(dpy, win, &tp) == 0) {
|
|
list = 0;
|
|
count = 0;
|
|
if (XmbTextPropertyToTextList(dpy, &tp, &list, &count) >= 0) {
|
|
for (i = 0; i < count; i++)
|
|
list[i][0] = 'x';
|
|
XFreeStringList(list);
|
|
}
|
|
XFree(tp.value);
|
|
}
|
|
|
|
ch.res_name = argv[0];
|
|
ch.res_class = "Spike";
|
|
hints.flags = 0;
|
|
hints.x = 20;
|
|
hints.y = 20;
|
|
hints.width = w;
|
|
hints.height = h;
|
|
XSetClassHint(dpy, win, &ch);
|
|
XSetWMProperties(dpy, win, &tp, &tp, argv, argc, &hints, 0, &ch);
|
|
|
|
XSetForeground(dpy, gc, BlackPixel(dpy, scr));
|
|
XSetBackground(dpy, gc, WhitePixel(dpy, scr));
|
|
XSync(dpy, 0);
|
|
XCloseDisplay(dpy);
|
|
return 0;
|
|
}
|