+ int xtest= XTestQueryExtension(disp, &evbase,&errbase,&majver,&minver);
+ if (!xtest) fatal("X server does not support the XTEST extension.");
+
+ xassert( XRaiseWindow(disp, id) );
+ /* in case VisibilityNotify triggers right away before we have had a
+ * change to raise; to avoid falsely detecting lowering in that case */
+
+ xassert( XSelectInput(disp, id,
+ StructureNotifyMask|
+ VisibilityChangeMask
+ ) );
+
+ xassert( XRaiseWindow(disp, id) );
+ /* in case the window was lowered between our Raise and our SelectInput;
+ * to avoid failing to detect that lowering */
+
+ xassert( XGetWindowAttributes(disp, id, &attr) );
+ xassert( XGetGeometry(disp,id, &attr.root,
+ &wxpos,&wypos, &wwidth,&wheight,
+ &bd,&depth) );
+
+ if (!(wwidth >= 320 && wheight >= 320))
+ fatal("YPP client window is implausibly small?");
+
+ check_client_window_all_on_screen();
+
+ Bool shmpixmaps=0;
+ int major=0,minor=0;
+ int shm= XShmQueryVersion(disp, &major,&minor,&shmpixmaps);
+ debugf("PAGING shm=%d %d.%d pixmaps=%d\n",shm,major,minor,shmpixmaps);
+ if (shm) {
+ xassert( shmim= XShmCreateImage(disp, attr.visual, attr.depth, ZPixmap,
+ 0,&shminfo, wwidth,wheight) );
+
+ sigset_t oldset, all;
+ sigfillset(&all);
+ sysassert(! sigprocmask(SIG_BLOCK,&all,&oldset) );
+
+ int pfd[2];
+ pid_t cleaner;
+ sysassert(! pipe(pfd) );
+ sysassert( (cleaner= fork()) != -1 );
+ if (!cleaner) {
+ sysassert(! close(pfd[1]) );
+ for (;;) {
+ int r= read(pfd[0], &shminfo.shmid, sizeof(shminfo.shmid));
+ if (!r) exit(0);
+ if (r==sizeof(shminfo.shmid)) break;
+ assert(r==-1 && errno==EINTR);
+ }
+ for (;;) {
+ char bc;
+ int r= read(pfd[0],&bc,1);
+ if (r>=0) break;
+ assert(r==-1 && errno==EINTR);
+ }
+ sysassert(! shmctl(shminfo.shmid,IPC_RMID,0) );
+ exit(0);
+ }
+ sysassert(! close(pfd[0]) );